diff --git a/README.md b/README.md index 1111f0ca5..b906a0503 100755 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ List of Definitions * [Chrome App](http://developer.chrome.com/apps/) (by [Adam Lay](https://github.com/AdamLay)) * [CodeMirror](http://codemirror.net) (by [François de Campredon](https://github.com/fdecampredon)) * [Commander](http://github.com/visionmedia/commander.js) (by [Marcelo Dezem](https://github.com/mdezem)) +* [Couchbase / Couchnode](https://github.com/couchbase/couchnode) (by [Basarat Ali Syed](https://github.com/basarat)) * [Crossfilter](https://github.com/square/crossfilter) (by [Schmulik Raskin](https://github.com/schmuli)) * [d3.js](http://d3js.org/) (from TypeScript samples) * [dhtmlxGantt](http://dhtmlx.com/docs/products/dhtmlxGantt) (by [Maksim Kozhukh](http://github.com/mkozhukh)) diff --git a/couchbase/couchbase-tests.ts b/couchbase/couchbase-tests.ts new file mode 100644 index 000000000..f4d1b1061 --- /dev/null +++ b/couchbase/couchbase-tests.ts @@ -0,0 +1,17 @@ +/// + +import couchbase = require('couchbase'); +var db = new couchbase.Connection({ bucket: "default" }, function (err) { + if (err) throw err; + + db.set('testdoc', { name: 'Frank' }, function (err, result) { + if (err) throw err; + + db.get('testdoc', function (err, result) { + if (err) throw err; + + console.log(result.value); + // {name: Frank} + }); + }); +}); \ No newline at end of file diff --git a/couchbase/couchbase.d.ts b/couchbase/couchbase.d.ts new file mode 100644 index 000000000..2b0a720a9 --- /dev/null +++ b/couchbase/couchbase.d.ts @@ -0,0 +1,729 @@ +// Type definitions for Couchbase Couchnode +// Project: https://github.com/couchbase/couchnode +// Definitions by: Basarat Ali Syed +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module 'couchbase' { + + /** + * Enumeration of all error codes. See libcouchbase documentation + * for more details on what these errors represent. + * + * @global + * @readonly + * @enum {number} + */ + export var errors: { + /** Operation was successful **/ + success: number; + + /** Authentication should continue. **/ + authContinue: number; + + /** Error authenticating. **/ + authError: number; + + /** The passed incr/decr delta was invalid. **/ + deltaBadVal: number; + + /** Object is too large to be stored on the cluster. **/ + objectTooBig: number; + + /** Server is too busy to handle your request right now. **/ + serverBusy: number; + + /** Internal libcouchbase error. **/ + cLibInternal: number; + + /** An invalid arguement was passed. **/ + cLibInvalidArgument: number; + + /** The server is out of memory. **/ + cLibOutOfMemory: number; + + /** An invalid range was specified. **/ + invalidRange: number; + + /** An unknown error occured within libcouchbase. **/ + cLibGenericError: number; + + /** A temporary error occured. Try again. **/ + temporaryError: number; + + /** The key already exists on the server. **/ + keyAlreadyExists: number; + + /** The key does not exist on the server. **/ + keyNotFound: number; + + /** Failed to open library. **/ + failedToOpenLibrary: number; + + /** Failed to find expected symbol in library. **/ + failedToFindSymbol: number; + + /** A network error occured. **/ + networkError: number; + + /** Operations were performed on the incorrect server. **/ + wrongServer: number; + + /** Operations were performed on the incorrect server. **/ + notMyVBucket: number; + + /** The document was not stored. */ + notStored: number; + + /** An unsupported operation was sent to the server. **/ + notSupported: number; + + /** An unknown command was sent to the server. **/ + unknownCommand: number; + + /** An unknown host was specified. **/ + unknownHost: number; + + /** A protocol error occured. **/ + protocolError: number; + + /** The operation timed out. **/ + timedOut: number; + + /** Error connecting to the server. **/ + connectError: number; + + /** The bucket you request was not found. **/ + bucketNotFound: number; + + /** libcouchbase is out of memory. **/ + clientOutOfMemory: number; + + /** A temporary error occured in libcouchbase. Try again. **/ + clientTemporaryError: number; + + /** A bad handle was passed. */ + badHandle: number; + + /** A server bug caused the operation to fail. **/ + serverBug: number; + + /** The host format specified is invalid. **/ + invalidHostFormat: number; + + /** Not enough nodes to meet the operations durability requirements. **/ + notEnoughNodes: number; + + /** Duplicate items. **/ + duplicateItems: number; + + /** Key mapping failed and could not match a server. **/ + noMatchingServerForKey: number; + + /** A bad environment variable was specified. **/ + badEnvironmentVariable: number; + /** Couchnode is out of memory. **/ + outOfMemory: number; + + /** Invalid arguements were passed. **/ + invalidArguments: number; + + /** An error occured while trying to schedule the operation. **/ + schedulingError: number; + + /** Not all operations completed successfully. **/ + checkResults: number; + + /** A generic error occured in Couchnode. **/ + genericError: number; + + /** The specified durability requirements could not be satisfied. **/ + durabilityFailed: number; + + /** An error occured during a RESTful operation. **/ + restError: number; + } + + /** + * Enumeration of all value encoding formats. + * + * @global + * @readonly + * @enum {number} + */ + export var format: { + /** Store as raw bytes. **/ + raw: number; + + /** Store as JSON encoded string. **/ + json: number; + + /** Store as UTF-8 encoded string. **/ + utf8: number; + + /** Automatically determine best storage format. **/ + auto: number; + }; + + /** + * The *CAS* value is a special object which indicates the current state + * of the item on the server. Each time an object is mutated on the server, the + * value is changed. CAS objects can be used in conjunction with + * mutation operations to ensure that the value on the server matches the local + * value retrieved by the client. This is useful when doing document updates + * on the server as you can ensure no changes were applied by other clients + * while you were in the process of mutating the document locally. + * + * In Couchnode, this is an opaque value. As such, you cannot generate + * CAS objects, but should rather use the values returned from a + * {@link KeyCallback}. + * + * @typedef {object} CAS + */ + export interface CAS extends Object { + } + + /** + * @class Result + * @classdesc + * The virtual class used for results of various operations. + * @private + */ + export class Result { + /** + * The CAS value for the document that was affected by the operation. + * @var {CAS} Result#cas + */ + cas: CAS; + /** + * The flags associate with the document. + * @var {integer} Result#flags + */ + flags: number; + /** + * The resulting document from the retrieval operation that was executed. + * @var {Mixed} Result#value + */ + value: any; + } + + /** + * @class CouchbaseError + * @classdesc + * The virtual class thrown for all Couchnode errors. + * @private + * @extends node#Error + */ + export interface CouchbaseError extends Error { + /** + * The error code for this error. + * @var {errors} Error#code + */ + code: number; + + /** + * The internal error that occured to cause this one. This is used to wrap + * low-level errors before throwing them from couchnode to simplify error + * handling. + * @var {(node#Error)} Error#innerError + */ + innerError: Error; + + /** + * A reason string describing the reason this error occured. This value is + * almost exclusively used for REST request errors. + * @var {string} Error#reason + */ + reason: string; + } + + /** + * Connect callback + * This callback is invoked when a connection is successfully established. + * + * @typedef {function} ConnectCallback + * + * @param {undefined|Error} error + * The error that occurred while trying to connect to the cluster. + */ + export interface ConnectCallback { + (error: CouchbaseError): any; + } + + /** + * Design Document Management callbacks + * This callback is invoked by the *DesignDoc operations. + * + * @typedef {function} DDocCallback + * + * @param {undefined|Error} error + * An error indicator. Note that this error value may be ignored, but its + * absence is indicative that the response in the *result* parameter is ok. + * If it is set, then the request likely failed. + * @param {object} result + * The result returned from the server + */ + export interface DDocCallback { + (error: CouchbaseError, result: any): any; + } + + /** + * Single-Key callbacks. + * This callback is passed to all of the single key functions. + * + * A typical use pattern is to pass the result> parameter from the + * callback as the options parameter to one of the next operations. + * + * @typedef {function} KeyCallback + * + * @param {undefined|Error} error + * The error for the operation. This can either be an Error object + * or a false value. The error contains the following fields: + * @param {Result} result + * The result of the operation that was executed. + */ + export interface KeyCallback { + (error: CouchbaseError, result: Result): any; + } + + /** + * Multi-Key callbacks + * This callback is invoked by the *Multi operations. + * It differs from the in {@linkcode KeyCallback} that the + * response object is an object of {key: response} + * where each response object contains the response for that particular + * key. + * + * @typedef {function} MultiCallback + * + * @param {undefined|Error} error + * An error indicator. Note that this error + * value may be ignored, but its absence is indicative that each + * response in the results parameter is ok. If it + * is set, then at least one of the result objects failed + * @param {Object.} results + * The results of the operation as a dictionary of keys mapped to Result + * objects. + */ + export interface MultiCallback { + (error: CouchbaseError, result: { [key: string]: Result }): any; + } + + /** + * Query callback. + * This callback is invoked by the query operations. + * + * @typedef {function} QueryCallback + * + * @param {undefined|Error} error + * An error indicator. Note that this error + * value may be ignored, but its absence is indicative that the + * response in the results parameter is ok. If it + * is set, then the request failed. + * @param {object} results + * The results returned from the server + */ + export interface QueryCallback { + (error: CouchbaseError, result: any): any; + } + + /** + * @typedef {function} StatsCallback + * + * @param {Error} error + * @param {Object.} results + * An object containing per-server, per key entries + * + * @see Connection#stats + */ + export interface StatsCallback { + (error: CouchbaseError, result: any): any; + } + + + ///////////////////////// + // Various options structures + ///////////////////////// + + export interface ConnectionOptions { + host?: any; // string | string[] + bucket?: string; + password?: string; + } + + // Not comming up with a base interface system as that is not how the original code is written. + // Use a custom base interface system has the potential to become difficult to keep up to date. + + export interface AddOptions { + expiry?: number; + flags?: number; + format?: number + persist_to?: number; + replicate_to?: number; + } + + export interface AddMultiOptionsForValue { + value: any; + expiry?: number; + flags?: number; + format?: number; + } + + export interface AddMultiOptions { + expiry?: number; + flags?: number; + format?: number + persist_to?: number; + replicate_to?: number; + + spooled?: boolean; + } + + export interface AppendOptions { + expiry?: number; + flags?: number; + format?: number; + persist_to?: number; + replicate_to?: number; + + cas: CAS; + } + + export interface AppendMultiOptionsForValue { + value: any; + cas?: CAS; + expiry?: number; + } + + export interface AppendMultiOptions { + expiry?: number; + persist_to?: number; + replicate_to?: number; + + spooled?: boolean; + } + + export interface DecrOptions { + offset?: number; + initial?: number; + + expiry?: number; + persist_to?: number; + replicate_to?: number; + } + + export interface DecrMultiOptionsForValue { + offset?: number; + initial?: number; + + expiry?: number; + } + + export interface DecrMultiOptions { + spooled?: boolean; + } + + export interface GetOptions { + expiry?: number; + format?: number; + } + + export interface GetMultiOptions { + spooled?: boolean; + format?: number; + } + + export interface GetReplicaOptions { + index?: number; + format?: number; + } + + export interface GetReplicaMultiOptions { + spooled?: boolean; + format?: number; + } + + export interface IncrOptions extends DecrOptions { } + + export interface IncrMultiOptionsForValue extends DecrMultiOptionsForValue { } + + export interface IncrMultiOptions extends DecrMultiOptions { } + + export interface LockOptions { + lockTime?: number + } + + export interface LockMultiOptions { + spooled?: boolean; + format?: number; + } + + export interface ObserveOptions { + cas: CAS; // verified not optional + } + + export interface ObserveMultiOptionsForValue { + cas: CAS; // verified not optional + } + + export interface ObserveMultiOptions { + spooled?: boolean; + } + + export interface PrependOptions { + expiry?: number; + flags?: number; + format?: number; + persist_to?: number; + replicate_to?: number; + + cas?: CAS; + } + + export interface PrependMultiOptionsFoValue { + value: any; + cas: CAS; + expiry?: number; + } + + export interface PrependMultiOptions { + spooled?: boolean; + + expiry?: number; + persist_to?: number; + replicate_to?: number; + } + + export interface RemoveOptions { + cas?: CAS; + persist_to?: number; + replicate_to?: number; + } + + export interface RemoveMultiOptionsForValue { + cas?: CAS; + } + + export interface RemoveMultiOptions { + spooled?: boolean; + + persist_to?: number; + replicate_to?: number; + } + + // Options for Replace functions follow Set Options and this is mentioned explicitly in the documentation + + export interface ReplaceOptions extends SetOptions { } + + export interface ReplaceMultiOptionsForValue extends SetMultiOptionsForValue { } + + export interface ReplaceMultiOptions extends SetMultiOptions { } + + export interface SetOptions { + expiry?: number; + flags?: number; + format?: number; + persist_to?: number; + replicate_to?: number; + + cas?: CAS; + } + + export interface SetMultiOptionsForValue { + value: any; + cas?: CAS; + expiry?: number; + flags?: number; + format?: number; + } + + export interface SetMultiOptions { + expiry?: number; + flags?: number; + format?: number + persist_to?: number; + replicate_to?: number; + + spooled?: boolean; + } + + export interface TouchOptions { + expiry?: number; + persist_to?: number; + replicate_to?: number; + + cas?: CAS; + } + + export interface UnlockOptions { + cas: CAS; // verified not optional + } + + export interface UnlockMultiOptionsForValue { + cas: CAS; // verified not optional + } + + export interface UnlockMultiOptions { + spooled?: boolean; + } + + /** + * @class + * A class representing a connection to a Couchbase cluster. + * Normally, your application should only need to create one of these per + * bucket and use it continuously. Operations are executed asynchronously + * and pipelined when possible. + * + * @desc + * Instantiate a new Connection object. Note that it is safe to perform + * operations before the connect callback is invoked. In this case, the + * operations are queued until the connection is ready (or an unrecoverable + * error has taken place). + * + * @param {Object} [options] + * A dictionary of options to use. You may pass + * other options than those defined below which correspond to the various + * options available on the Connection object (see their documentation). + * For example, it may be helpful to set timeout properties before connecting. + * @param {string|string[]} [options.host="localhost:8091"] + * A string or array of strings indicating the hosts to connect to. If the + * value is an array, all the hosts in the array will be tried until one of + * them succeeds. + * @param {string} [options.bucket="default"] + * The bucket to connect to. If not specified, the default is + * 'default'. + * @param {string} [options.password=""] + * The password for a password protected bucket. + * @param {ConnectCallback} callback + * A callback that will be invoked when the instance has completed connecting + * to the server. Note that this isn't required - however if the connection + * fails, an exception will be thrown if the callback is not provided. + * + * @example + * var couchbase = require('couchbase'); + * var db = new couchbase.Connection({}, function(err) { + * if (err) { + * console.log('Connection Error', err); + * } else { + * console.log('Connected!'); + * } + * }); + */ + export class Connection { + constructor(callback: ConnectCallback); + constructor(options: ConnectionOptions, callback: ConnectCallback); + + ///////////////////////// + // Members + ///////////////////////// + + /** + * Get information about the Couchnode version (i.e. this library) as an array + * of [versionNumber, versionString]. + * + * @member {Mixed[]} Connection#clientVersion + */ + clientVersion: any[]; + + connectionTimeout: number; + + lcbVersion: any[]; + + operationTimeout: number; + + serverNodes: string[]; + + ///////////////////////// + // Methods + ///////////////////////// + + // TODO: not sure if these methods return void. Docmentation mentions nothing. + // TODO: For "multi" key methods the documentation says callback can be either KeyCallback | MultiCallback. Sticking with MultiCallback. + // TODO: Verify that kv is not a key value and indeed is string[] e.g. getMulti , getReplicaMulti, lockMulti + + add(key: string, value: any, callback: KeyCallback): void; + add(key: string, value: any, options: AddOptions, callback: KeyCallback): void; + addMulti(kv: { [key: string]: AddMultiOptionsForValue }, options: AddMultiOptions, callback: MultiCallback): void; + + append(key: string, fragment: string, callback: KeyCallback): void; + append(key: string, fragment: string, options: AppendOptions, callback: KeyCallback): void; + append(key: string, fragment: NodeBuffer, callback: KeyCallback): void; + append(key: string, fragment: NodeBuffer, options: AppendOptions, callback: KeyCallback): void; + appendMulti(kv: { [key: string]: AppendMultiOptionsForValue }, options: AppendMultiOptions, callback: MultiCallback): void; + + decr(key: string, callback: KeyCallback): void; + decr(key: string, options: DecrOptions, callback: KeyCallback): void; + decrMulti(kv: { [key: string]: DecrMultiOptionsForValue }, options: DecrMultiOptions, callback: MultiCallback): void; + + get(key: string, callback: KeyCallback): void; + get(key: string, options: GetOptions, callback: KeyCallback): void; + getMulti(kv: string[], options: { [key: string]: GetMultiOptions }, callback:MultiCallback): void; + + getDesignDoc(name: string, callback: DDocCallback): void; + + getReplica(key: string, callback: KeyCallback): void; + getReplica(key: string, options: GetReplicaOptions, callback: KeyCallback): void; + getReplicaMulti(kv: string[], options: GetReplicaMultiOptions, callback: MultiCallback): void; + + incr(key: string, callback: KeyCallback): void; + incr(key: string, options: IncrOptions, callback: KeyCallback): void; + incrMulti(kv: { [key: string]: IncrMultiOptionsForValue }, options: IncrMultiOptions, callback: MultiCallback): void; + + lock(key: string, callback: KeyCallback): void; + lock(key: string, options: LockOptions, callback: KeyCallback): void; + lockMulti(kv: string[], options: { [key: string]: LockMultiOptions }, callback: MultiCallback): void; + + observe(key: string, options: ObserveOptions, callback: KeyCallback): void; + observeMulti(kv: { [key: string]: ObserveMultiOptionsForValue }, options: { [key: string]: ObserveMultiOptions }, callback: MultiCallback): void; + + on(event: string, listener: Function): void; + on(event: 'connect', listener: (err: Error) => any): void; + on(event: 'error', listener: (err: Error) => any): void; + + prepend(key: string, fragment: string, callback: KeyCallback): void; + prepend(key: string, fragment: string, options: PrependOptions, callback: KeyCallback): void; + prepend(key: string, fragment: NodeBuffer, callback: KeyCallback): void; + prepend(key: string, fragment: NodeBuffer, options: PrependOptions, callback: KeyCallback): void; + prependMulti(kv: { [key: string]: PrependMultiOptionsFoValue }, options: { [key: string]: PrependMultiOptions }, callback: MultiCallback): void; + + remove(key: string, callback: KeyCallback): void; + remove(key: string, options: RemoveOptions, callback: KeyCallback): void; + removeMulti(kv: { [key: string]: RemoveMultiOptionsForValue }, options: RemoveMultiOptions, callback: MultiCallback): void; + removeMulti(kv: string[], options: RemoveMultiOptions, callback: MultiCallback): void; + + removeDesignDoc(name: string, callback: DDocCallback): void; + + replace(key: string, value: any, callback: KeyCallback): void; + replace(key: string, value: any, options: ReplaceOptions, callback: KeyCallback): void; + replaceMulti(kv: { [key: string]: ReplaceMultiOptionsForValue }, options: ReplaceMultiOptions, callback: MultiCallback): void; + + set(key: string, value: any, callback: KeyCallback): void; + set(key: string, value: any, options: SetOptions, callback: KeyCallback): void; + setMulti(kv: { [key: string]: SetMultiOptionsForValue }, options: SetMultiOptions, callback: MultiCallback): void; + + setDesignDoc(name: string, data: any, callback: DDocCallback): void; + + shutdown(): void; + + stats(callback: StatsCallback): void; + stats(key: string, callback: StatsCallback): void; + + strError(code: number): string; + + touch(key: string, callback: KeyCallback): void; + touch(key: string, options: TouchOptions, callback: KeyCallback): void; + + unlock(key: string, options: UnlockOptions, callback: KeyCallback): void; + unlockMulti(kv: { [key: string]: UnlockMultiOptionsForValue }, options: { [key: string]: UnlockMultiOptions }, callback: UnlockMultiOptions): void; + + view(ddoc: string, name: string): ViewQuery; + view(ddoc: string, name: string, query: any): ViewQuery; + } + + export class ViewQuery { + firstPage(q: any, callback: Function): void; + query(q: any, callback: Function): void; + } + +}