From a664bb725aa569bdb141d3e8bb3c6de0fa04b07c Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 02:06:49 +0000 Subject: [PATCH 1/6] Added type definitions for Ably realtime See https://www.ably.io and https://github.com/ably/ably-js --- ably/ably-tests.ts | 239 ++++++++++++++++++++++++ ably/index.d.ts | 443 +++++++++++++++++++++++++++++++++++++++++++++ ably/tsconfig.json | 20 ++ 3 files changed, 702 insertions(+) create mode 100644 ably/ably-tests.ts create mode 100644 ably/index.d.ts create mode 100644 ably/tsconfig.json diff --git a/ably/ably-tests.ts b/ably/ably-tests.ts new file mode 100644 index 0000000000..dbe82bc054 --- /dev/null +++ b/ably/ably-tests.ts @@ -0,0 +1,239 @@ +import * as Ably from 'ably'; + +const ApiKey = 'appId.keyId:secret'; +const client = Ably.Realtime; +const restClient = Ably.Rest; + +// Connection +// Successful connection: + +client.connection.on('connected', function() { + // successful connection +}); + +// Failed connection: + +client.connection.on('failed', function() { + // failed connection +}); + + +// Subscribing to a channel + +var channel = client.channels.get('test'); +channel.subscribe(function(message) { + message.name; // 'greeting' + message.data; // 'Hello World!' +}); + +// Only certain events: + +channel.subscribe('myEvent', function(message) { + message.name; // 'myEvent' + message.data; // 'myData' +}); + +// Publishing to a channel + +// Publish a single message with name and data +channel.publish('greeting', 'Hello World!'); + +// Optionally, you can use a callback to be notified of success or failure +channel.publish('greeting', 'Hello World!', function(err) { + if(err) { + console.log('publish failed with error ' + err); + } else { + console.log('publish succeeded'); + } +}) + +// Publish several messages at once +channel.publish([{name: 'greeting', data: 'Hello World!'}], function() { }); + +// Querying the History + +channel.history(function(err, messagesPage) { + messagesPage.items; // array of Message + messagesPage.items[0].data; // payload for first message + messagesPage.items.length; // number of messages in the current page of history + messagesPage.hasNext(); // true if there are further pages + messagesPage.isLast(); // true if this page is the last page + messagesPage.next(function(nextPage) { nextPage; }); // retrieves the next page as PaginatedResult +}); + +// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history +channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards'}, function(err, messagesPage) { + console.log(messagesPage.items.length); +}); + + +// Presence on a channel +// Getting presence: + +channel.presence.get(function(err, presenceSet) { + presenceSet; // array of PresenceMessages +}); + +// Note that presence#get on a realtime channel does not return a PaginatedResult, as the library maintains a local copy of the presence set. + +// Entering (and leaving) the presence set: + +channel.presence.enter('my status', function(err) { + // now I am entered +}); + +channel.presence.update('new status', function(err) { + // my presence data is updated +}); + +channel.presence.leave(function(err) { + // I've left the presence set +}); + +channel.presence.enterClient('myClientId', 'status', function(err) { +}); + +// and similiarly, updateClient and leaveClient +// Querying the Presence History + +channel.presence.history(function(err, messagesPage) { // PaginatedResult + messagesPage.items; // array of PresenceMessage + messagesPage.items[0].data; // payload for first message + messagesPage.items.length; // number of messages in the current page of history + messagesPage.hasNext(); // true if there are further pages + messagesPage.isLast(); // true if this page is the last page + messagesPage.next(function(nextPage) { }); // retrieves the next page as PaginatedResult +}); + +// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history +channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); + +// Symmetrical end-to-end encrypted payloads on a channel + +// When a 128 bit or 256 bit key is provided to the library, the data attributes of all messages are encrypted and decrypted automatically using that key. The secret key is never transmitted to Ably. See https://www.ably.io/documentation/realtime/encryption + +// Generate a random 256-bit key for demonstration purposes (in +// practice you need to create one and distribute it to clients yourselves) +Ably.Realtime.Crypto.generateRandomKey(function(err, key) { + var channel = client.channels.get('channelName', { cipher: { key: key } }); + + channel.subscribe(function(message) { + message.name; // 'name is not encrypted' + message.data; // 'sensitive data is encrypted' + }); + + channel.publish('name is not encrypted', 'sensitive data is encrypted'); +}) + +// You can also change the key on an existing channel using setOptions (which takes a callback which is called after the new encryption settings have taken effect): + +channel.setOptions({cipher: {key: ''}}, function() { + // New encryption settings are in effect +}); + +// Using the REST API + +var channel = restClient.channels.get('test'); + +// Publishing to a channel + +// Publish a single message with name and data +channel.publish('greeting', 'Hello World!'); + +// Optionally, you can use a callback to be notified of success or failure +channel.publish('greeting', 'Hello World!', function(err) { + if(err) { + console.log('publish failed with error ' + err); + } else { + console.log('publish succeeded'); + } +}) + +// Publish several messages at once +channel.publish([{name: 'greeting', data: 'Hello World!'}], function() {}); + +// Querying the History + +channel.history(function(err, messagesPage) { + messagesPage; // PaginatedResult + messagesPage.items; // array of Message + messagesPage.items[0].data; // payload for first message + messagesPage.items.length; // number of messages in the current page of history + messagesPage.hasNext(); // true if there are further pages + messagesPage.isLast(); // true if this page is the last page + messagesPage.next(function(nextPage) {}); // retrieves the next page as PaginatedResult +}); + +// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history +channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); + +// Presence on a channel + +channel.presence.get(function(err, presencePage) { // PaginatedResult + presencePage.items; // array of PresenceMessage + presencePage.items[0].data; // payload for first message + presencePage.items.length; // number of messages in the current page of members + presencePage.hasNext(); // true if there are further pages + presencePage.isLast(); // true if this page is the last page + presencePage.next(function(nextPage) {}); // retrieves the next page as PaginatedResult +}); + +// Querying the Presence History + +channel.presence.history(function(err, messagesPage) { // PaginatedResult + messagesPage.items; // array of PresenceMessage + messagesPage.items[0].data; // payload for first message + messagesPage.items.length; // number of messages in the current page of history + messagesPage.hasNext(); // true if there are further pages + messagesPage.isLast(); // true if this page is the last page + messagesPage.next(function(nextPage) { }); // retrieves the next page as PaginatedResult +}); + +// Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history +channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); + + +// Generate Token and Token Request +// See https://www.ably.io/documentation/general/authentication for an explanation of Ably's authentication mechanism. + +// Requesting a token: + +client.auth.requestToken(function(err, tokenDetails) { + // tokenDetails is instance of TokenDetails + // see https://www.ably.io/documentation/rest/authentication/#token-details for its properties + + // Now we have the token, we can send it to someone who can instantiate a client with it: + var clientUsingToken = new Ably.Realtime(tokenDetails.token); +}); + +// requestToken can take two optional params +// tokenParams: https://www.ably.io/documentation/rest/authentication/#token-params +// authOptions: https://www.ably.io/documentation/rest/authentication/#auth-options +client.auth.requestToken({}, {}, function(err, tokenDetails) { }); + +// Creating a token request (for example, on a server in response to a request by a client using the authCallback or authUrl mechanisms): + +client.auth.createTokenRequest(function(err, tokenRequest) { + // now send the tokenRequest back to the client, which will + // use it to request a token and connect to Ably +}); + +// createTokenRequest can take two optional params +// tokenParams: https://www.ably.io/documentation/rest/authentication/#token-params +// authOptions: https://www.ably.io/documentation/rest/authentication/#auth-options +client.auth.createTokenRequest({}, {}, function(err, tokenRequest) { }); + +// Fetching your application's stats + +client.stats(function(err, statsPage) { // statsPage as PaginatedResult + statsPage.items; // array of Stats + statsPage.items[0].data; // payload for first message + statsPage.items.length; // number of messages in the current page of history + statsPage.hasNext(); // true if there are further pages + statsPage.isLast(); // true if this page is the last page + statsPage.next(function(nextPage) {}); // retrieves the next page as PaginatedResult +}); + +// Fetching the Ably service time + +client.time(function(err, time) {}); // time is in ms since epoch diff --git a/ably/index.d.ts b/ably/index.d.ts new file mode 100644 index 0000000000..e42b65d199 --- /dev/null +++ b/ably/index.d.ts @@ -0,0 +1,443 @@ +// Type definitions for Ably Realtime and Rest client library v0.9.0 +// Project: https://www.ably.io/ +// Definitions by: Ably +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare namespace ChannelState { + export type INITIALIZED = 'initialized'; + export type ATTACHING = 'attaching'; + export type ATTACHED = "attached"; + export type DETACHING = "detaching"; + export type DETACHED = "detached"; + export type SUSPENDED = "suspended"; + export type FAILED = "failed"; +} +type ChannelState = ChannelState.FAILED | ChannelState.INITIALIZED | ChannelState.SUSPENDED | ChannelState.ATTACHED | ChannelState.ATTACHING | ChannelState.DETACHED | ChannelState.DETACHING; + +declare namespace ConnectionState { + export type INITIALIZED = "initialized"; + export type CONNECTING = "connecting"; + export type CONNECTED = "connected"; + export type DISCONNECTED = "disconnected"; + export type SUSPENDED = "suspended"; + export type CLOSING = "closing"; + export type CLOSED = "closed"; + export type FAILED = "failed"; +} +type ConnectionState = ConnectionState.INITIALIZED | ConnectionState.CONNECTED | ConnectionState.CONNECTING | ConnectionState.DISCONNECTED | ConnectionState.SUSPENDED | ConnectionState.CLOSED | ConnectionState.CLOSING | ConnectionState.FAILED; + +declare namespace ConnectionEvent { + export type INITIALIZED = "initialized"; + export type CONNECTING = "connecting"; + export type CONNECTED = "connected"; + export type DISCONNECTED = "disconnected"; + export type SUSPENDED = "suspended"; + export type CLOSING = "closing"; + export type CLOSED = "closed"; + export type FAILED = "failed"; + export type UPDATE = "update"; +} +type ConnectionEvent = ConnectionEvent.INITIALIZED | ConnectionEvent.CONNECTED | ConnectionEvent.CONNECTING | ConnectionEvent.DISCONNECTED | ConnectionEvent.SUSPENDED | ConnectionEvent.CLOSED | ConnectionEvent.CLOSING | ConnectionEvent.FAILED | ConnectionEvent.UPDATE; + +declare namespace PresenceAction { + export type ABSENT = "absent"; + export type PRESENT = "present"; + export type ENTER = "enter"; + export type LEAVE = "leave"; + export type UPDATE = "update"; +} +type PresenceAction = PresenceAction.ABSENT | PresenceAction.PRESENT | PresenceAction.ENTER | PresenceAction.LEAVE | PresenceAction.UPDATE; + +declare namespace StatsIntervalGranularity { + export type MINUTE = "minute"; + export type HOUR = "hour"; + export type DAY = "day"; + export type MONTH = "month"; +} +type StatsIntervalGranularity = StatsIntervalGranularity.MINUTE | StatsIntervalGranularity.HOUR | StatsIntervalGranularity.DAY | StatsIntervalGranularity.MONTH; + +declare namespace HTTPMethods { + export type POST = "POST"; + export type GET = "GET"; +} +type HTTPMethods = HTTPMethods.GET | HTTPMethods.POST; + +// Interfaces +declare interface ClientOptions extends AuthOptions { + /** + * When true will automatically connect to Ably when library is instanced. This is true by default + */ + autoConnect?: boolean; + + /** + * Optional clientId that can be used to specify the identity for this client. In most cases + * it is preferable to instead specift a clientId in the token issued to this client. + */ + clientId?: string; + + defaultTokenParams?: TokenParams; + + /** + * When true, messages published on channels by this client will be echoed back to this client. + * This is true by default + */ + echoMessages?: boolean; + + /** + * Use this only if you have been provided a dedicated environment by Ably + */ + environment?: string; + + /** + * Logger configuration + */ + log?: LogInfo; + port?: number; + + /** + * When true, messages will be queued whilst the connection is disconnected. True by default. + */ + queueMessages?: boolean; + + restHost?: string; + realtimeHost?: string; + fallbackHosts?: Array; + + /** + * Can be used to explicitly recover a connection. + * See https://www.ably.io/documentation/realtime/connection#connection-state-recovery + */ + recover?: standardCallback | string; + + /** + * Use a non-secure connection connection. By default, a TLS connection is used to connect to Ably + */ + tls?: boolean; + tlsPort?: number; + + /** + * When true, the more efficient MsgPack binary encoding is used. + * When false, JSON text encoding is used. + */ + useBinaryProtocol?: boolean; +} + +declare interface AuthOptions { + /** + * A function which is called when a new token is required. + * The role of the callback is to either generate a signed TokenRequest which may then be submitted automatically + * by the library to the Ably REST API requestToken; or to provide a valid token in as a TokenDetails object. + **/ + authCallback?: (data: TokenParams,callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void) => void; + authHeaders?: { [index: string]: string }; + authMethod?: HTTPMethods; + authParams?: { [index: string]: string }; + + /** + * A URL that the library may use to obtain a token string (in plain text format), or a signed TokenRequest or TokenDetails (in JSON format). + **/ + authUrl?: string; + key?: string; + queryTime?: boolean; + token?: TokenDetails | string; + tokenDetails?: TokenDetails; + useTokenAuth?: boolean; +} + +declare interface TokenParams { + capability?: string; + clientId?: string; + nonce?: string; + timestamp?: number; + ttl?: number; +} + +declare interface CipherParams { + algorithm: string; + key: any; + keyLength: number; + mode: string; +} + +declare interface ErrorInfo { + code: number; + message: string; + statusCode: number; +} + +declare interface StatsMessageCount { + count: number; + data: number; +} + +declare interface StatsMessageTypes { + all: StatsMessageCount; + messages: StatsMessageCount; + presence: StatsMessageCount; +} + +declare interface StatsRequestCount { + failed: number; + refused: number; + succeeded: number; +} + +declare interface StatsResourceCount { + mean: number; + min: number; + opened: number; + peak: number; + refused: number; +} + +declare interface StatsConnectionTypes { + all: StatsResourceCount; + plain: StatsResourceCount; + tls: StatsResourceCount; +} + +declare interface StatsMessageTraffic { + all: StatsMessageTypes, + realtime: StatsMessageTypes, + rest: StatsMessageTypes, + webhook: StatsMessageTypes +} + +declare interface TokenDetails { + capability: string; + clientId?: string; + expires: number; + issued: number; + token: string; +} + +declare interface TokenRequest { + capability: string; + clientId?: string; + keyName: string; + mac: string; + nonce: string; + timestamp: number; + ttl?: number; +} + +declare interface ChannelOptions { + cipher: any; +} + +declare interface RestPresenceHistoryParams { + start?: number; + end?: number; + direction?: string; + limit?: number; +} + +declare interface RestPresenceParams { + limit?: number; + clientId?: string; + connectionId?: string; +} + +declare interface RealtimePresenceParams { + waitForSync?: boolean; + clientId?: string; + connectionId?: string; +} + +declare interface RealtimePresenceHistoryParams { + start?: number; + end?: number; + direction?: string; + limit?: number; + untilAttach?: boolean +} + +declare interface LogInfo { + /** + * A number controlling the verbosity of the output. Valid values are: 0 (no logs), 1 (errors only), + * 2 (errors plus connection and channel state changes), 3 (high-level debug output), and 4 (full debug output). + **/ + level?: number; + + /** + * A function to handle each line of log output. If handler is not specified, console.log is used. + **/ + handler?: (...args) => void; +} + +declare interface ChannelEvent { + state: ChannelState; +} + +declare interface ChannelStateChange { + current: ChannelState; + previous: ChannelState; + reason?: ErrorInfo; + resumed: boolean; +} + +declare interface ConnectionStateChange { + current: ConnectionState; + previous: ConnectionState; + reason?: ErrorInfo; + retryIn?: number; +} + +// Common Listeners +type PaginatedResultCallback = (error: ErrorInfo, results: PaginatedResult ) => void; +type standardCallback = (error: ErrorInfo, results: any) => void; +type messageCallback = (message: T) => void; +type errorCallback = (error: ErrorInfo) => void; +type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void; +type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void; +type timeCallback = (error: ErrorInfo, time: number) => void; + + +// Internal Classes +declare class EventEmitter { + on: (eventOrCallback: string | T, callback?: T) => void; + once: (eventOrCallback: string | T, callback?: T) => void; + off: (eventOrCallback?: string | T, callback?: T) => void; +} + +// Classes +export declare class Auth { + clientId: string; + authorize: (tokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenDetails) => void) => void; + createTokenRequest: (tokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenRequest) => void) => void; + requestToken: (TokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenDetails) => void) => void; +} + +export declare class Presence { + get: (params: RestPresenceParams, callback: PaginatedResultCallback) => void; + history: (params: RestPresenceHistoryParams, callback: PaginatedResultCallback) => void; +} + +export declare class RealtimePresence { + syncComplete: () => boolean; + get: (Params: RealtimePresenceParams, callback?: (error: ErrorInfo, messages: Array) => void) => void; + history: (ParamsOrCallback: RealtimePresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + subscribe: (presenceOrCallback: PresenceAction | messageCallback, listener?: messageCallback) => void; + unsubscribe: (presence?: PresenceAction, listener?: messageCallback) => void; + enter: (data: any, callback?: errorCallback) => void; + update: (data: any, callback?: errorCallback) => void; + leave: (data: any, callback?: errorCallback) => void; + enterClient: (clientId: string, data: any, callback?: errorCallback) => void; + updateClient: (clientId: string, data: any, callback?: errorCallback) => void; + leaveClient: (clientId: string, data: any, callback?: errorCallback) => void; +} + +export declare class Channel { + name: string; + presence: Presence; + history: (paramsOrCallback?: RestPresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + publish: (messagesOrName: any, messagedataOrCallback?: errorCallback | any, callback?: errorCallback) => void; +} + +export declare class RealtimeChannel extends EventEmitter { + name: string; + errorReason: ErrorInfo; + state: ChannelState; + presence: RealtimePresence; + attach: (callback?: standardCallback) => void; + detach:(callback?: standardCallback) => void; + history: (paramsOrCallback?: RealtimePresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + subscribe: (eventOrCallback: messageCallback | string, listener?: messageCallback) => void; + unsubscribe: (eventOrCallback?: messageCallback | string, listener?: messageCallback) => void; + publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void; +} + +export declare class Channels { + get: (name: string, channelOptions?: ChannelOptions) => T; + release: (name: string) => void; +} + +export declare class Message { + constructor(); + fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; + fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Array; + clientId: string; + connectionId: string; + data: any; + encoding: string; + extras: any; + id: string; + name: string; + timestamp: number; +} + +export declare class PresenceMessage { + fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; + fromEncodedArray: (JsonArray: Array, channelOptions?: ChannelOptions) => Array; + action: PresenceAction; + clientId: string; + connectionId: string; + data: any; + encoding: string; + id: string; + timestamp: number; +} + +export declare class Rest { + constructor(options: ClientOptions | string); + auth: Auth; + channels: Channels; + request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; + stats: (paramsOrCallback?: PaginatedResultCallback | any, callback?: PaginatedResultCallback) => void; + time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; +} + +export declare class Realtime { + constructor(options: ClientOptions | string); + auth: Auth; + channels: Channels; + clientId: string; + connection: Connection; + request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; + stats: (paramsOrCallback?: PaginatedResultCallback | any, callback?: PaginatedResultCallback) => void; + close: () => void; + connect: () => void; + time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; +} + +export declare class Connection extends EventEmitter { + errorReason: ErrorInfo; + id: string; + key: string; + recoveryKey: string; + serial: number; + state: ConnectionState; + close: () => void; + connect: () => void; + ping: (callback?: (error: ErrorInfo, responseTime: number ) => void ) => void; +} + +export declare class Stats { + all: StatsMessageTypes; + apiRequests: StatsRequestCount; + channels: StatsResourceCount; + connections: StatsConnectionTypes; + inbound: StatsMessageTraffic; + intervalId: string; + outbound: StatsMessageTraffic; + persisted: StatsMessageTypes; + tokenRequests: StatsRequestCount; +} + +export declare class PaginatedResult { + items: Array; + first: (results: PaginatedResultCallback) => void; + next: (results: PaginatedResultCallback) => void; + current: (results: PaginatedResultCallback) => void; + hasNext: () => boolean; + isLast: () => boolean; +} + +export declare class HttpPaginatedResponse extends PaginatedResult { + items: Array; + statusCode: number; + success: boolean; + errorCode: number; + errorMessage: string; + headers: any; +} diff --git a/ably/tsconfig.json b/ably/tsconfig.json new file mode 100644 index 0000000000..b13a7a2ea5 --- /dev/null +++ b/ably/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "ably-test.ts" + ] +} From d5d9afb13d3992d184106e489370129726cd7a59 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 02:13:57 +0000 Subject: [PATCH 2/6] Fix typo in tsconfig.json --- ably/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ably/tsconfig.json b/ably/tsconfig.json index b13a7a2ea5..0dce6c6c1d 100644 --- a/ably/tsconfig.json +++ b/ably/tsconfig.json @@ -15,6 +15,6 @@ }, "files": [ "index.d.ts", - "ably-test.ts" + "ably-tests.ts" ] } From 2f30af5cff078fc4c5c3cedcb30a267bffbb3060 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 03:42:59 +0000 Subject: [PATCH 3/6] Various changes to get DefinitelyTyped passing --- ably/ably-tests.ts | 44 ++++++------- ably/index.d.ts | 155 ++++++++++++++++++++++++--------------------- ably/tslint.json | 1 + 3 files changed, 105 insertions(+), 95 deletions(-) create mode 100644 ably/tslint.json diff --git a/ably/ably-tests.ts b/ably/ably-tests.ts index dbe82bc054..99de6d6578 100644 --- a/ably/ably-tests.ts +++ b/ably/ably-tests.ts @@ -1,8 +1,8 @@ -import * as Ably from 'ably'; +/// const ApiKey = 'appId.keyId:secret'; -const client = Ably.Realtime; -const restClient = Ably.Rest; +const client = new Realtime(ApiKey); +const restClient = new Rest(ApiKey); // Connection // Successful connection: @@ -70,8 +70,8 @@ channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, directio // Presence on a channel // Getting presence: -channel.presence.get(function(err, presenceSet) { - presenceSet; // array of PresenceMessages +channel.presence.get(function(presenceSet) { + presenceSet; // array of PresenceMessages }); // Note that presence#get on a realtime channel does not return a PaginatedResult, as the library maintains a local copy of the presence set. @@ -86,7 +86,7 @@ channel.presence.update('new status', function(err) { // my presence data is updated }); -channel.presence.leave(function(err) { +channel.presence.leave(null, function(err) { // I've left the presence set }); @@ -114,7 +114,7 @@ channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, directio // Generate a random 256-bit key for demonstration purposes (in // practice you need to create one and distribute it to clients yourselves) -Ably.Realtime.Crypto.generateRandomKey(function(err, key) { +Realtime.Crypto.generateRandomKey(function(err, key) { var channel = client.channels.get('channelName', { cipher: { key: key } }); channel.subscribe(function(message) { @@ -123,7 +123,7 @@ Ably.Realtime.Crypto.generateRandomKey(function(err, key) { }); channel.publish('name is not encrypted', 'sensitive data is encrypted'); -}) +}); // You can also change the key on an existing channel using setOptions (which takes a callback which is called after the new encryption settings have taken effect): @@ -133,15 +133,15 @@ channel.setOptions({cipher: {key: ''}}, function() { // Using the REST API -var channel = restClient.channels.get('test'); +var restChannel = restClient.channels.get('test'); // Publishing to a channel // Publish a single message with name and data -channel.publish('greeting', 'Hello World!'); +restChannel.publish('greeting', 'Hello World!'); // Optionally, you can use a callback to be notified of success or failure -channel.publish('greeting', 'Hello World!', function(err) { +restChannel.publish('greeting', 'Hello World!', function(err) { if(err) { console.log('publish failed with error ' + err); } else { @@ -150,11 +150,11 @@ channel.publish('greeting', 'Hello World!', function(err) { }) // Publish several messages at once -channel.publish([{name: 'greeting', data: 'Hello World!'}], function() {}); +restChannel.publish([{name: 'greeting', data: 'Hello World!'}], function() {}); // Querying the History -channel.history(function(err, messagesPage) { +restChannel.history(function(err, messagesPage) { messagesPage; // PaginatedResult messagesPage.items; // array of Message messagesPage.items[0].data; // payload for first message @@ -165,11 +165,11 @@ channel.history(function(err, messagesPage) { }); // Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history -channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); +restChannel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); // Presence on a channel -channel.presence.get(function(err, presencePage) { // PaginatedResult +restChannel.presence.get(function(err, presencePage) { // PaginatedResult presencePage.items; // array of PresenceMessage presencePage.items[0].data; // payload for first message presencePage.items.length; // number of messages in the current page of members @@ -180,7 +180,7 @@ channel.presence.get(function(err, presencePage) { // PaginatedResult // Querying the Presence History -channel.presence.history(function(err, messagesPage) { // PaginatedResult +restChannel.presence.history(function(err, messagesPage) { // PaginatedResult messagesPage.items; // array of PresenceMessage messagesPage.items[0].data; // payload for first message messagesPage.items.length; // number of messages in the current page of history @@ -190,7 +190,7 @@ channel.presence.history(function(err, messagesPage) { // PaginatedResult }); // Can optionally take an options param, see https://www.ably.io/documentation/rest-api/#message-history -channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); +restChannel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, direction: 'forwards' }, function(err, messagesPage) {}); // Generate Token and Token Request @@ -203,7 +203,7 @@ client.auth.requestToken(function(err, tokenDetails) { // see https://www.ably.io/documentation/rest/authentication/#token-details for its properties // Now we have the token, we can send it to someone who can instantiate a client with it: - var clientUsingToken = new Ably.Realtime(tokenDetails.token); + var clientUsingToken = new Realtime(tokenDetails.token); }); // requestToken can take two optional params @@ -225,10 +225,10 @@ client.auth.createTokenRequest({}, {}, function(err, tokenRequest) { }); // Fetching your application's stats -client.stats(function(err, statsPage) { // statsPage as PaginatedResult +client.stats({ limit: 50 }, function(err, statsPage) { // statsPage as PaginatedResult statsPage.items; // array of Stats - statsPage.items[0].data; // payload for first message - statsPage.items.length; // number of messages in the current page of history + statsPage.items[0].inbound.rest.messages.count; // total messages published over REST + statsPage.items.length; // number of stats in the current page of history statsPage.hasNext(); // true if there are further pages statsPage.isLast(); // true if this page is the last page statsPage.next(function(nextPage) {}); // retrieves the next page as PaginatedResult @@ -236,4 +236,4 @@ client.stats(function(err, statsPage) { // statsPage as PaginatedResult // Fetching the Ably service time -client.time(function(err, time) {}); // time is in ms since epoch +client.time({}, function(err, time) {}); // time is in ms since epoch diff --git a/ably/index.d.ts b/ably/index.d.ts index e42b65d199..56a6064290 100644 --- a/ably/index.d.ts +++ b/ably/index.d.ts @@ -4,61 +4,61 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare namespace ChannelState { - export type INITIALIZED = 'initialized'; - export type ATTACHING = 'attaching'; - export type ATTACHED = "attached"; - export type DETACHING = "detaching"; - export type DETACHED = "detached"; - export type SUSPENDED = "suspended"; - export type FAILED = "failed"; + type INITIALIZED = 'initialized'; + type ATTACHING = 'attaching'; + type ATTACHED = "attached"; + type DETACHING = "detaching"; + type DETACHED = "detached"; + type SUSPENDED = "suspended"; + type FAILED = "failed"; } type ChannelState = ChannelState.FAILED | ChannelState.INITIALIZED | ChannelState.SUSPENDED | ChannelState.ATTACHED | ChannelState.ATTACHING | ChannelState.DETACHED | ChannelState.DETACHING; declare namespace ConnectionState { - export type INITIALIZED = "initialized"; - export type CONNECTING = "connecting"; - export type CONNECTED = "connected"; - export type DISCONNECTED = "disconnected"; - export type SUSPENDED = "suspended"; - export type CLOSING = "closing"; - export type CLOSED = "closed"; - export type FAILED = "failed"; + type INITIALIZED = "initialized"; + type CONNECTING = "connecting"; + type CONNECTED = "connected"; + type DISCONNECTED = "disconnected"; + type SUSPENDED = "suspended"; + type CLOSING = "closing"; + type CLOSED = "closed"; + type FAILED = "failed"; } type ConnectionState = ConnectionState.INITIALIZED | ConnectionState.CONNECTED | ConnectionState.CONNECTING | ConnectionState.DISCONNECTED | ConnectionState.SUSPENDED | ConnectionState.CLOSED | ConnectionState.CLOSING | ConnectionState.FAILED; declare namespace ConnectionEvent { - export type INITIALIZED = "initialized"; - export type CONNECTING = "connecting"; - export type CONNECTED = "connected"; - export type DISCONNECTED = "disconnected"; - export type SUSPENDED = "suspended"; - export type CLOSING = "closing"; - export type CLOSED = "closed"; - export type FAILED = "failed"; - export type UPDATE = "update"; + type INITIALIZED = "initialized"; + type CONNECTING = "connecting"; + type CONNECTED = "connected"; + type DISCONNECTED = "disconnected"; + type SUSPENDED = "suspended"; + type CLOSING = "closing"; + type CLOSED = "closed"; + type FAILED = "failed"; + type UPDATE = "update"; } type ConnectionEvent = ConnectionEvent.INITIALIZED | ConnectionEvent.CONNECTED | ConnectionEvent.CONNECTING | ConnectionEvent.DISCONNECTED | ConnectionEvent.SUSPENDED | ConnectionEvent.CLOSED | ConnectionEvent.CLOSING | ConnectionEvent.FAILED | ConnectionEvent.UPDATE; declare namespace PresenceAction { - export type ABSENT = "absent"; - export type PRESENT = "present"; - export type ENTER = "enter"; - export type LEAVE = "leave"; - export type UPDATE = "update"; + type ABSENT = "absent"; + type PRESENT = "present"; + type ENTER = "enter"; + type LEAVE = "leave"; + type UPDATE = "update"; } type PresenceAction = PresenceAction.ABSENT | PresenceAction.PRESENT | PresenceAction.ENTER | PresenceAction.LEAVE | PresenceAction.UPDATE; declare namespace StatsIntervalGranularity { - export type MINUTE = "minute"; - export type HOUR = "hour"; - export type DAY = "day"; - export type MONTH = "month"; + type MINUTE = "minute"; + type HOUR = "hour"; + type DAY = "day"; + type MONTH = "month"; } type StatsIntervalGranularity = StatsIntervalGranularity.MINUTE | StatsIntervalGranularity.HOUR | StatsIntervalGranularity.DAY | StatsIntervalGranularity.MONTH; declare namespace HTTPMethods { - export type POST = "POST"; - export type GET = "GET"; + type POST = "POST"; + type GET = "GET"; } type HTTPMethods = HTTPMethods.GET | HTTPMethods.POST; @@ -262,7 +262,7 @@ declare interface LogInfo { /** * A function to handle each line of log output. If handler is not specified, console.log is used. **/ - handler?: (...args) => void; + handler?: (...args: Array) => void; } declare interface ChannelEvent { @@ -284,14 +284,16 @@ declare interface ConnectionStateChange { } // Common Listeners -type PaginatedResultCallback = (error: ErrorInfo, results: PaginatedResult ) => void; +type paginatedResultCallback = (error: ErrorInfo, results: PaginatedResult ) => void; type standardCallback = (error: ErrorInfo, results: any) => void; type messageCallback = (message: T) => void; type errorCallback = (error: ErrorInfo) => void; type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void; type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void; type timeCallback = (error: ErrorInfo, time: number) => void; - +type realtimePresenceGetCallback = (error: ErrorInfo, messages: Array) => void; +type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void +type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void // Internal Classes declare class EventEmitter { @@ -301,58 +303,59 @@ declare class EventEmitter { } // Classes -export declare class Auth { +declare class Auth { clientId: string; - authorize: (tokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenDetails) => void) => void; - createTokenRequest: (tokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenRequest) => void) => void; - requestToken: (TokenParams?: TokenParams, authOptions?: AuthOptions, callback?: (error: ErrorInfo, Results: TokenDetails) => void) => void; + authorize: (tokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; + createTokenRequest: (tokenParams?: TokenParams | tokenRequestCallback, authOptions?: AuthOptions | tokenRequestCallback, callback?: tokenRequestCallback) => void; + requestToken: (TokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; } -export declare class Presence { - get: (params: RestPresenceParams, callback: PaginatedResultCallback) => void; - history: (params: RestPresenceHistoryParams, callback: PaginatedResultCallback) => void; +declare class Presence { + get: (params: RestPresenceParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + history: (params: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; } -export declare class RealtimePresence { +declare class RealtimePresence { syncComplete: () => boolean; - get: (Params: RealtimePresenceParams, callback?: (error: ErrorInfo, messages: Array) => void) => void; - history: (ParamsOrCallback: RealtimePresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + get: (Params: realtimePresenceGetCallback | RealtimePresenceParams, callback?: realtimePresenceGetCallback) => void; + history: (ParamsOrCallback: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; subscribe: (presenceOrCallback: PresenceAction | messageCallback, listener?: messageCallback) => void; unsubscribe: (presence?: PresenceAction, listener?: messageCallback) => void; - enter: (data: any, callback?: errorCallback) => void; - update: (data: any, callback?: errorCallback) => void; - leave: (data: any, callback?: errorCallback) => void; - enterClient: (clientId: string, data: any, callback?: errorCallback) => void; - updateClient: (clientId: string, data: any, callback?: errorCallback) => void; - leaveClient: (clientId: string, data: any, callback?: errorCallback) => void; + enter: (data?: errorCallback | any, callback?: errorCallback) => void; + update: (data?: errorCallback | any, callback?: errorCallback) => void; + leave: (data?: errorCallback | any, callback?: errorCallback) => void; + enterClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; + updateClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; + leaveClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; } -export declare class Channel { +declare class Channel { name: string; presence: Presence; - history: (paramsOrCallback?: RestPresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + history: (paramsOrCallback?: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; publish: (messagesOrName: any, messagedataOrCallback?: errorCallback | any, callback?: errorCallback) => void; } -export declare class RealtimeChannel extends EventEmitter { +declare class RealtimeChannel extends EventEmitter { name: string; errorReason: ErrorInfo; state: ChannelState; presence: RealtimePresence; attach: (callback?: standardCallback) => void; detach:(callback?: standardCallback) => void; - history: (paramsOrCallback?: RealtimePresenceHistoryParams | PaginatedResultCallback, callback?: PaginatedResultCallback) => void; + history: (paramsOrCallback?: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; subscribe: (eventOrCallback: messageCallback | string, listener?: messageCallback) => void; unsubscribe: (eventOrCallback?: messageCallback | string, listener?: messageCallback) => void; publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void; + setOptions: (options: Object, callback?: errorCallback) => void; } -export declare class Channels { +declare class Channels { get: (name: string, channelOptions?: ChannelOptions) => T; release: (name: string) => void; } -export declare class Message { +declare class Message { constructor(); fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Array; @@ -366,7 +369,7 @@ export declare class Message { timestamp: number; } -export declare class PresenceMessage { +declare class PresenceMessage { fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; fromEncodedArray: (JsonArray: Array, channelOptions?: ChannelOptions) => Array; action: PresenceAction; @@ -378,29 +381,35 @@ export declare class PresenceMessage { timestamp: number; } -export declare class Rest { +declare interface Crypto { + generateRandomKey: (callback: (error: ErrorInfo, key: string) => void) => void; +} + +declare class Rest { constructor(options: ClientOptions | string); + static Crypto: Crypto; auth: Auth; channels: Channels; request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; - stats: (paramsOrCallback?: PaginatedResultCallback | any, callback?: PaginatedResultCallback) => void; - time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; + stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; + time: (paramsOrCallback?: timeCallback | Object, callback?: timeCallback) => void; } -export declare class Realtime { +declare class Realtime { constructor(options: ClientOptions | string); + static Crypto: Crypto; auth: Auth; channels: Channels; clientId: string; connection: Connection; request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; - stats: (paramsOrCallback?: PaginatedResultCallback | any, callback?: PaginatedResultCallback) => void; + stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; close: () => void; connect: () => void; time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; } -export declare class Connection extends EventEmitter { +declare class Connection extends EventEmitter { errorReason: ErrorInfo; id: string; key: string; @@ -412,7 +421,7 @@ export declare class Connection extends EventEmitter { ping: (callback?: (error: ErrorInfo, responseTime: number ) => void ) => void; } -export declare class Stats { +declare class Stats { all: StatsMessageTypes; apiRequests: StatsRequestCount; channels: StatsResourceCount; @@ -424,16 +433,16 @@ export declare class Stats { tokenRequests: StatsRequestCount; } -export declare class PaginatedResult { +declare class PaginatedResult { items: Array; - first: (results: PaginatedResultCallback) => void; - next: (results: PaginatedResultCallback) => void; - current: (results: PaginatedResultCallback) => void; + first: (results: paginatedResultCallback) => void; + next: (results: paginatedResultCallback) => void; + current: (results: paginatedResultCallback) => void; hasNext: () => boolean; isLast: () => boolean; } -export declare class HttpPaginatedResponse extends PaginatedResult { +declare class HttpPaginatedResponse extends PaginatedResult { items: Array; statusCode: number; success: boolean; diff --git a/ably/tslint.json b/ably/tslint.json new file mode 100644 index 0000000000..377cc837d4 --- /dev/null +++ b/ably/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" } From 623a761603e62530f3173d015deda9038cee5323 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 03:54:00 +0000 Subject: [PATCH 4/6] Lots of lint driven fixes --- ably/index.d.ts | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/ably/index.d.ts b/ably/index.d.ts index 56a6064290..0452feea26 100644 --- a/ably/index.d.ts +++ b/ably/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Ably Realtime and Rest client library v0.9.0 +// Type definitions for Ably Realtime and Rest client library 0.9 // Project: https://www.ably.io/ // Definitions by: Ably // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped @@ -101,7 +101,7 @@ declare interface ClientOptions extends AuthOptions { restHost?: string; realtimeHost?: string; - fallbackHosts?: Array; + fallbackHosts?: string[]; /** * Can be used to explicitly recover a connection. @@ -128,7 +128,7 @@ declare interface AuthOptions { * The role of the callback is to either generate a signed TokenRequest which may then be submitted automatically * by the library to the Ably REST API requestToken; or to provide a valid token in as a TokenDetails object. **/ - authCallback?: (data: TokenParams,callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void) => void; + authCallback?: (data: TokenParams, callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void) => void; authHeaders?: { [index: string]: string }; authMethod?: HTTPMethods; authParams?: { [index: string]: string }; @@ -197,10 +197,10 @@ declare interface StatsConnectionTypes { } declare interface StatsMessageTraffic { - all: StatsMessageTypes, - realtime: StatsMessageTypes, - rest: StatsMessageTypes, - webhook: StatsMessageTypes + all: StatsMessageTypes; + realtime: StatsMessageTypes; + rest: StatsMessageTypes; + webhook: StatsMessageTypes; } declare interface TokenDetails { @@ -249,7 +249,7 @@ declare interface RealtimePresenceHistoryParams { end?: number; direction?: string; limit?: number; - untilAttach?: boolean + untilAttach?: boolean; } declare interface LogInfo { @@ -262,7 +262,7 @@ declare interface LogInfo { /** * A function to handle each line of log output. If handler is not specified, console.log is used. **/ - handler?: (...args: Array) => void; + handler?: (...args: any[]) => void; } declare interface ChannelEvent { @@ -291,9 +291,9 @@ type errorCallback = (error: ErrorInfo) => void; type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void; type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void; type timeCallback = (error: ErrorInfo, time: number) => void; -type realtimePresenceGetCallback = (error: ErrorInfo, messages: Array) => void; -type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void -type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void +type realtimePresenceGetCallback = (error: ErrorInfo, messages: PresenceMessage[]) => void; +type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void; +type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void; // Internal Classes declare class EventEmitter { @@ -342,12 +342,12 @@ declare class RealtimeChannel extends EventEmitter { state: ChannelState; presence: RealtimePresence; attach: (callback?: standardCallback) => void; - detach:(callback?: standardCallback) => void; + detach: (callback?: standardCallback) => void; history: (paramsOrCallback?: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; subscribe: (eventOrCallback: messageCallback | string, listener?: messageCallback) => void; unsubscribe: (eventOrCallback?: messageCallback | string, listener?: messageCallback) => void; publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void; - setOptions: (options: Object, callback?: errorCallback) => void; + setOptions: (options: any, callback?: errorCallback) => void; } declare class Channels { @@ -358,7 +358,7 @@ declare class Channels { declare class Message { constructor(); fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; - fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Array; + fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Message[]; clientId: string; connectionId: string; data: any; @@ -371,7 +371,7 @@ declare class Message { declare class PresenceMessage { fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; - fromEncodedArray: (JsonArray: Array, channelOptions?: ChannelOptions) => Array; + fromEncodedArray: (JsonArray: any[], channelOptions?: ChannelOptions) => PresenceMessage[]; action: PresenceAction; clientId: string; connectionId: string; @@ -390,9 +390,9 @@ declare class Rest { static Crypto: Crypto; auth: Auth; channels: Channels; - request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; + request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; - time: (paramsOrCallback?: timeCallback | Object, callback?: timeCallback) => void; + time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; } declare class Realtime { @@ -402,7 +402,7 @@ declare class Realtime { channels: Channels; clientId: string; connection: Connection; - request: (method: string, path: string, params?: any, body?: Array | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; + request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; close: () => void; connect: () => void; @@ -434,7 +434,7 @@ declare class Stats { } declare class PaginatedResult { - items: Array; + items: T[]; first: (results: paginatedResultCallback) => void; next: (results: paginatedResultCallback) => void; current: (results: paginatedResultCallback) => void; @@ -443,7 +443,7 @@ declare class PaginatedResult { } declare class HttpPaginatedResponse extends PaginatedResult { - items: Array; + items: string[]; statusCode: number; success: boolean; errorCode: number; From c27f7a1656056c54ef031f811a8a1fa9fa6b1889 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 04:37:07 +0000 Subject: [PATCH 5/6] Correctly use namespaces --- ably/ably-tests.ts | 10 +- ably/index.d.ts | 848 +++++++++++++++++++++++---------------------- 2 files changed, 430 insertions(+), 428 deletions(-) diff --git a/ably/ably-tests.ts b/ably/ably-tests.ts index 99de6d6578..aa08ca226e 100644 --- a/ably/ably-tests.ts +++ b/ably/ably-tests.ts @@ -1,8 +1,8 @@ -/// +import * as Ably from 'ably'; const ApiKey = 'appId.keyId:secret'; -const client = new Realtime(ApiKey); -const restClient = new Rest(ApiKey); +const client = new Ably.Realtime(ApiKey); +const restClient = new Ably.Rest(ApiKey); // Connection // Successful connection: @@ -114,7 +114,7 @@ channel.history({ start: Date.now()-10000, end: Date.now(), limit: 100, directio // Generate a random 256-bit key for demonstration purposes (in // practice you need to create one and distribute it to clients yourselves) -Realtime.Crypto.generateRandomKey(function(err, key) { +Ably.Realtime.Crypto.generateRandomKey(function(err, key) { var channel = client.channels.get('channelName', { cipher: { key: key } }); channel.subscribe(function(message) { @@ -203,7 +203,7 @@ client.auth.requestToken(function(err, tokenDetails) { // see https://www.ably.io/documentation/rest/authentication/#token-details for its properties // Now we have the token, we can send it to someone who can instantiate a client with it: - var clientUsingToken = new Realtime(tokenDetails.token); + var clientUsingToken = new Ably.Realtime(tokenDetails.token); }); // requestToken can take two optional params diff --git a/ably/index.d.ts b/ably/index.d.ts index 0452feea26..b8cad7ae69 100644 --- a/ably/index.d.ts +++ b/ably/index.d.ts @@ -3,450 +3,452 @@ // Definitions by: Ably // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare namespace ChannelState { - type INITIALIZED = 'initialized'; - type ATTACHING = 'attaching'; - type ATTACHED = "attached"; - type DETACHING = "detaching"; - type DETACHED = "detached"; - type SUSPENDED = "suspended"; - type FAILED = "failed"; -} -type ChannelState = ChannelState.FAILED | ChannelState.INITIALIZED | ChannelState.SUSPENDED | ChannelState.ATTACHED | ChannelState.ATTACHING | ChannelState.DETACHED | ChannelState.DETACHING; +declare namespace ablyLib { + namespace ChannelState { + type INITIALIZED = 'initialized'; + type ATTACHING = 'attaching'; + type ATTACHED = "attached"; + type DETACHING = "detaching"; + type DETACHED = "detached"; + type SUSPENDED = "suspended"; + type FAILED = "failed"; + } + type ChannelState = ChannelState.FAILED | ChannelState.INITIALIZED | ChannelState.SUSPENDED | ChannelState.ATTACHED | ChannelState.ATTACHING | ChannelState.DETACHED | ChannelState.DETACHING; -declare namespace ConnectionState { - type INITIALIZED = "initialized"; - type CONNECTING = "connecting"; - type CONNECTED = "connected"; - type DISCONNECTED = "disconnected"; - type SUSPENDED = "suspended"; - type CLOSING = "closing"; - type CLOSED = "closed"; - type FAILED = "failed"; -} -type ConnectionState = ConnectionState.INITIALIZED | ConnectionState.CONNECTED | ConnectionState.CONNECTING | ConnectionState.DISCONNECTED | ConnectionState.SUSPENDED | ConnectionState.CLOSED | ConnectionState.CLOSING | ConnectionState.FAILED; + namespace ConnectionState { + type INITIALIZED = "initialized"; + type CONNECTING = "connecting"; + type CONNECTED = "connected"; + type DISCONNECTED = "disconnected"; + type SUSPENDED = "suspended"; + type CLOSING = "closing"; + type CLOSED = "closed"; + type FAILED = "failed"; + } + type ConnectionState = ConnectionState.INITIALIZED | ConnectionState.CONNECTED | ConnectionState.CONNECTING | ConnectionState.DISCONNECTED | ConnectionState.SUSPENDED | ConnectionState.CLOSED | ConnectionState.CLOSING | ConnectionState.FAILED; -declare namespace ConnectionEvent { - type INITIALIZED = "initialized"; - type CONNECTING = "connecting"; - type CONNECTED = "connected"; - type DISCONNECTED = "disconnected"; - type SUSPENDED = "suspended"; - type CLOSING = "closing"; - type CLOSED = "closed"; - type FAILED = "failed"; - type UPDATE = "update"; -} -type ConnectionEvent = ConnectionEvent.INITIALIZED | ConnectionEvent.CONNECTED | ConnectionEvent.CONNECTING | ConnectionEvent.DISCONNECTED | ConnectionEvent.SUSPENDED | ConnectionEvent.CLOSED | ConnectionEvent.CLOSING | ConnectionEvent.FAILED | ConnectionEvent.UPDATE; + namespace ConnectionEvent { + type INITIALIZED = "initialized"; + type CONNECTING = "connecting"; + type CONNECTED = "connected"; + type DISCONNECTED = "disconnected"; + type SUSPENDED = "suspended"; + type CLOSING = "closing"; + type CLOSED = "closed"; + type FAILED = "failed"; + type UPDATE = "update"; + } + type ConnectionEvent = ConnectionEvent.INITIALIZED | ConnectionEvent.CONNECTED | ConnectionEvent.CONNECTING | ConnectionEvent.DISCONNECTED | ConnectionEvent.SUSPENDED | ConnectionEvent.CLOSED | ConnectionEvent.CLOSING | ConnectionEvent.FAILED | ConnectionEvent.UPDATE; -declare namespace PresenceAction { - type ABSENT = "absent"; - type PRESENT = "present"; - type ENTER = "enter"; - type LEAVE = "leave"; - type UPDATE = "update"; -} -type PresenceAction = PresenceAction.ABSENT | PresenceAction.PRESENT | PresenceAction.ENTER | PresenceAction.LEAVE | PresenceAction.UPDATE; + namespace PresenceAction { + type ABSENT = "absent"; + type PRESENT = "present"; + type ENTER = "enter"; + type LEAVE = "leave"; + type UPDATE = "update"; + } + type PresenceAction = PresenceAction.ABSENT | PresenceAction.PRESENT | PresenceAction.ENTER | PresenceAction.LEAVE | PresenceAction.UPDATE; -declare namespace StatsIntervalGranularity { - type MINUTE = "minute"; - type HOUR = "hour"; - type DAY = "day"; - type MONTH = "month"; -} -type StatsIntervalGranularity = StatsIntervalGranularity.MINUTE | StatsIntervalGranularity.HOUR | StatsIntervalGranularity.DAY | StatsIntervalGranularity.MONTH; + namespace StatsIntervalGranularity { + type MINUTE = "minute"; + type HOUR = "hour"; + type DAY = "day"; + type MONTH = "month"; + } + type StatsIntervalGranularity = StatsIntervalGranularity.MINUTE | StatsIntervalGranularity.HOUR | StatsIntervalGranularity.DAY | StatsIntervalGranularity.MONTH; -declare namespace HTTPMethods { - type POST = "POST"; - type GET = "GET"; -} -type HTTPMethods = HTTPMethods.GET | HTTPMethods.POST; + namespace HTTPMethods { + type POST = "POST"; + type GET = "GET"; + } + type HTTPMethods = HTTPMethods.GET | HTTPMethods.POST; -// Interfaces -declare interface ClientOptions extends AuthOptions { - /** - * When true will automatically connect to Ably when library is instanced. This is true by default - */ - autoConnect?: boolean; + // Interfaces + interface ClientOptions extends AuthOptions { + /** + * When true will automatically connect to Ably when library is instanced. This is true by default + */ + autoConnect?: boolean; - /** - * Optional clientId that can be used to specify the identity for this client. In most cases - * it is preferable to instead specift a clientId in the token issued to this client. - */ - clientId?: string; + /** + * Optional clientId that can be used to specify the identity for this client. In most cases + * it is preferable to instead specift a clientId in the token issued to this client. + */ + clientId?: string; - defaultTokenParams?: TokenParams; + defaultTokenParams?: TokenParams; - /** - * When true, messages published on channels by this client will be echoed back to this client. - * This is true by default - */ - echoMessages?: boolean; + /** + * When true, messages published on channels by this client will be echoed back to this client. + * This is true by default + */ + echoMessages?: boolean; - /** - * Use this only if you have been provided a dedicated environment by Ably - */ - environment?: string; + /** + * Use this only if you have been provided a dedicated environment by Ably + */ + environment?: string; - /** - * Logger configuration - */ - log?: LogInfo; - port?: number; + /** + * Logger configuration + */ + log?: LogInfo; + port?: number; - /** - * When true, messages will be queued whilst the connection is disconnected. True by default. - */ - queueMessages?: boolean; + /** + * When true, messages will be queued whilst the connection is disconnected. True by default. + */ + queueMessages?: boolean; - restHost?: string; - realtimeHost?: string; - fallbackHosts?: string[]; + restHost?: string; + realtimeHost?: string; + fallbackHosts?: string[]; - /** - * Can be used to explicitly recover a connection. - * See https://www.ably.io/documentation/realtime/connection#connection-state-recovery - */ - recover?: standardCallback | string; + /** + * Can be used to explicitly recover a connection. + * See https://www.ably.io/documentation/realtime/connection#connection-state-recovery + */ + recover?: standardCallback | string; - /** - * Use a non-secure connection connection. By default, a TLS connection is used to connect to Ably - */ - tls?: boolean; - tlsPort?: number; + /** + * Use a non-secure connection connection. By default, a TLS connection is used to connect to Ably + */ + tls?: boolean; + tlsPort?: number; - /** - * When true, the more efficient MsgPack binary encoding is used. - * When false, JSON text encoding is used. - */ - useBinaryProtocol?: boolean; + /** + * When true, the more efficient MsgPack binary encoding is used. + * When false, JSON text encoding is used. + */ + useBinaryProtocol?: boolean; + } + + interface AuthOptions { + /** + * A function which is called when a new token is required. + * The role of the callback is to either generate a signed TokenRequest which may then be submitted automatically + * by the library to the Ably REST API requestToken; or to provide a valid token in as a TokenDetails object. + **/ + authCallback?: (data: TokenParams, callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void) => void; + authHeaders?: { [index: string]: string }; + authMethod?: HTTPMethods; + authParams?: { [index: string]: string }; + + /** + * A URL that the library may use to obtain a token string (in plain text format), or a signed TokenRequest or TokenDetails (in JSON format). + **/ + authUrl?: string; + key?: string; + queryTime?: boolean; + token?: TokenDetails | string; + tokenDetails?: TokenDetails; + useTokenAuth?: boolean; + } + + interface TokenParams { + capability?: string; + clientId?: string; + nonce?: string; + timestamp?: number; + ttl?: number; + } + + interface CipherParams { + algorithm: string; + key: any; + keyLength: number; + mode: string; + } + + interface ErrorInfo { + code: number; + message: string; + statusCode: number; + } + + interface StatsMessageCount { + count: number; + data: number; + } + + interface StatsMessageTypes { + all: StatsMessageCount; + messages: StatsMessageCount; + presence: StatsMessageCount; + } + + interface StatsRequestCount { + failed: number; + refused: number; + succeeded: number; + } + + interface StatsResourceCount { + mean: number; + min: number; + opened: number; + peak: number; + refused: number; + } + + interface StatsConnectionTypes { + all: StatsResourceCount; + plain: StatsResourceCount; + tls: StatsResourceCount; + } + + interface StatsMessageTraffic { + all: StatsMessageTypes; + realtime: StatsMessageTypes; + rest: StatsMessageTypes; + webhook: StatsMessageTypes; + } + + interface TokenDetails { + capability: string; + clientId?: string; + expires: number; + issued: number; + token: string; + } + + interface TokenRequest { + capability: string; + clientId?: string; + keyName: string; + mac: string; + nonce: string; + timestamp: number; + ttl?: number; + } + + interface ChannelOptions { + cipher: any; + } + + interface RestPresenceHistoryParams { + start?: number; + end?: number; + direction?: string; + limit?: number; + } + + interface RestPresenceParams { + limit?: number; + clientId?: string; + connectionId?: string; + } + + interface RealtimePresenceParams { + waitForSync?: boolean; + clientId?: string; + connectionId?: string; + } + + interface RealtimePresenceHistoryParams { + start?: number; + end?: number; + direction?: string; + limit?: number; + untilAttach?: boolean; + } + + interface LogInfo { + /** + * A number controlling the verbosity of the output. Valid values are: 0 (no logs), 1 (errors only), + * 2 (errors plus connection and channel state changes), 3 (high-level debug output), and 4 (full debug output). + **/ + level?: number; + + /** + * A function to handle each line of log output. If handler is not specified, console.log is used. + **/ + handler?: (...args: any[]) => void; + } + + interface ChannelEvent { + state: ChannelState; + } + + interface ChannelStateChange { + current: ChannelState; + previous: ChannelState; + reason?: ErrorInfo; + resumed: boolean; + } + + interface ConnectionStateChange { + current: ConnectionState; + previous: ConnectionState; + reason?: ErrorInfo; + retryIn?: number; + } + + // Common Listeners + type paginatedResultCallback = (error: ErrorInfo, results: PaginatedResult ) => void; + type standardCallback = (error: ErrorInfo, results: any) => void; + type messageCallback = (message: T) => void; + type errorCallback = (error: ErrorInfo) => void; + type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void; + type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void; + type timeCallback = (error: ErrorInfo, time: number) => void; + type realtimePresenceGetCallback = (error: ErrorInfo, messages: PresenceMessage[]) => void; + type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void; + type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void; + + // Internal Classes + class EventEmitter { + on: (eventOrCallback: string | T, callback?: T) => void; + once: (eventOrCallback: string | T, callback?: T) => void; + off: (eventOrCallback?: string | T, callback?: T) => void; + } + + // Classes + class Auth { + clientId: string; + authorize: (tokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; + createTokenRequest: (tokenParams?: TokenParams | tokenRequestCallback, authOptions?: AuthOptions | tokenRequestCallback, callback?: tokenRequestCallback) => void; + requestToken: (TokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; + } + + class Presence { + get: (params: RestPresenceParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + history: (params: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + } + + class RealtimePresence { + syncComplete: () => boolean; + get: (Params: realtimePresenceGetCallback | RealtimePresenceParams, callback?: realtimePresenceGetCallback) => void; + history: (ParamsOrCallback: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + subscribe: (presenceOrCallback: PresenceAction | messageCallback, listener?: messageCallback) => void; + unsubscribe: (presence?: PresenceAction, listener?: messageCallback) => void; + enter: (data?: errorCallback | any, callback?: errorCallback) => void; + update: (data?: errorCallback | any, callback?: errorCallback) => void; + leave: (data?: errorCallback | any, callback?: errorCallback) => void; + enterClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; + updateClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; + leaveClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; + } + + class Channel { + name: string; + presence: Presence; + history: (paramsOrCallback?: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + publish: (messagesOrName: any, messagedataOrCallback?: errorCallback | any, callback?: errorCallback) => void; + } + + class RealtimeChannel extends EventEmitter { + name: string; + errorReason: ErrorInfo; + state: ChannelState; + presence: RealtimePresence; + attach: (callback?: standardCallback) => void; + detach: (callback?: standardCallback) => void; + history: (paramsOrCallback?: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; + subscribe: (eventOrCallback: messageCallback | string, listener?: messageCallback) => void; + unsubscribe: (eventOrCallback?: messageCallback | string, listener?: messageCallback) => void; + publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void; + setOptions: (options: any, callback?: errorCallback) => void; + } + + class Channels { + get: (name: string, channelOptions?: ChannelOptions) => T; + release: (name: string) => void; + } + + class Message { + constructor(); + fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; + fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Message[]; + clientId: string; + connectionId: string; + data: any; + encoding: string; + extras: any; + id: string; + name: string; + timestamp: number; + } + + class PresenceMessage { + fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; + fromEncodedArray: (JsonArray: any[], channelOptions?: ChannelOptions) => PresenceMessage[]; + action: PresenceAction; + clientId: string; + connectionId: string; + data: any; + encoding: string; + id: string; + timestamp: number; + } + + interface Crypto { + generateRandomKey: (callback: (error: ErrorInfo, key: string) => void) => void; + } + + class Connection extends EventEmitter { + errorReason: ErrorInfo; + id: string; + key: string; + recoveryKey: string; + serial: number; + state: ConnectionState; + close: () => void; + connect: () => void; + ping: (callback?: (error: ErrorInfo, responseTime: number ) => void ) => void; + } + + class Stats { + all: StatsMessageTypes; + apiRequests: StatsRequestCount; + channels: StatsResourceCount; + connections: StatsConnectionTypes; + inbound: StatsMessageTraffic; + intervalId: string; + outbound: StatsMessageTraffic; + persisted: StatsMessageTypes; + tokenRequests: StatsRequestCount; + } + + class PaginatedResult { + items: T[]; + first: (results: paginatedResultCallback) => void; + next: (results: paginatedResultCallback) => void; + current: (results: paginatedResultCallback) => void; + hasNext: () => boolean; + isLast: () => boolean; + } + + class HttpPaginatedResponse extends PaginatedResult { + items: string[]; + statusCode: number; + success: boolean; + errorCode: number; + errorMessage: string; + headers: any; + } } -declare interface AuthOptions { - /** - * A function which is called when a new token is required. - * The role of the callback is to either generate a signed TokenRequest which may then be submitted automatically - * by the library to the Ably REST API requestToken; or to provide a valid token in as a TokenDetails object. - **/ - authCallback?: (data: TokenParams, callback: (error: ErrorInfo | string, tokenRequestOrDetails: TokenDetails | TokenRequest | string) => void) => void; - authHeaders?: { [index: string]: string }; - authMethod?: HTTPMethods; - authParams?: { [index: string]: string }; - - /** - * A URL that the library may use to obtain a token string (in plain text format), or a signed TokenRequest or TokenDetails (in JSON format). - **/ - authUrl?: string; - key?: string; - queryTime?: boolean; - token?: TokenDetails | string; - tokenDetails?: TokenDetails; - useTokenAuth?: boolean; +export declare class Rest { + constructor(options: ablyLib.ClientOptions | string); + static Crypto: ablyLib.Crypto; + auth: ablyLib.Auth; + channels: ablyLib.Channels; + request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ablyLib.ErrorInfo, response: ablyLib.HttpPaginatedResponse) => void) => void; + stats: (paramsOrCallback?: ablyLib.paginatedResultCallback | any, callback?: ablyLib.paginatedResultCallback) => void; + time: (paramsOrCallback?: ablyLib.timeCallback | any, callback?: ablyLib.timeCallback) => void; } -declare interface TokenParams { - capability?: string; - clientId?: string; - nonce?: string; - timestamp?: number; - ttl?: number; -} - -declare interface CipherParams { - algorithm: string; - key: any; - keyLength: number; - mode: string; -} - -declare interface ErrorInfo { - code: number; - message: string; - statusCode: number; -} - -declare interface StatsMessageCount { - count: number; - data: number; -} - -declare interface StatsMessageTypes { - all: StatsMessageCount; - messages: StatsMessageCount; - presence: StatsMessageCount; -} - -declare interface StatsRequestCount { - failed: number; - refused: number; - succeeded: number; -} - -declare interface StatsResourceCount { - mean: number; - min: number; - opened: number; - peak: number; - refused: number; -} - -declare interface StatsConnectionTypes { - all: StatsResourceCount; - plain: StatsResourceCount; - tls: StatsResourceCount; -} - -declare interface StatsMessageTraffic { - all: StatsMessageTypes; - realtime: StatsMessageTypes; - rest: StatsMessageTypes; - webhook: StatsMessageTypes; -} - -declare interface TokenDetails { - capability: string; - clientId?: string; - expires: number; - issued: number; - token: string; -} - -declare interface TokenRequest { - capability: string; - clientId?: string; - keyName: string; - mac: string; - nonce: string; - timestamp: number; - ttl?: number; -} - -declare interface ChannelOptions { - cipher: any; -} - -declare interface RestPresenceHistoryParams { - start?: number; - end?: number; - direction?: string; - limit?: number; -} - -declare interface RestPresenceParams { - limit?: number; - clientId?: string; - connectionId?: string; -} - -declare interface RealtimePresenceParams { - waitForSync?: boolean; - clientId?: string; - connectionId?: string; -} - -declare interface RealtimePresenceHistoryParams { - start?: number; - end?: number; - direction?: string; - limit?: number; - untilAttach?: boolean; -} - -declare interface LogInfo { - /** - * A number controlling the verbosity of the output. Valid values are: 0 (no logs), 1 (errors only), - * 2 (errors plus connection and channel state changes), 3 (high-level debug output), and 4 (full debug output). - **/ - level?: number; - - /** - * A function to handle each line of log output. If handler is not specified, console.log is used. - **/ - handler?: (...args: any[]) => void; -} - -declare interface ChannelEvent { - state: ChannelState; -} - -declare interface ChannelStateChange { - current: ChannelState; - previous: ChannelState; - reason?: ErrorInfo; - resumed: boolean; -} - -declare interface ConnectionStateChange { - current: ConnectionState; - previous: ConnectionState; - reason?: ErrorInfo; - retryIn?: number; -} - -// Common Listeners -type paginatedResultCallback = (error: ErrorInfo, results: PaginatedResult ) => void; -type standardCallback = (error: ErrorInfo, results: any) => void; -type messageCallback = (message: T) => void; -type errorCallback = (error: ErrorInfo) => void; -type channelEventCallback = (channelEvent: ChannelEvent, changeStateChange: ChannelStateChange) => void; -type connectionEventCallback = (connectionEvent: ConnectionEvent, connectionStateChange: ConnectionStateChange) => void; -type timeCallback = (error: ErrorInfo, time: number) => void; -type realtimePresenceGetCallback = (error: ErrorInfo, messages: PresenceMessage[]) => void; -type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void; -type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void; - -// Internal Classes -declare class EventEmitter { - on: (eventOrCallback: string | T, callback?: T) => void; - once: (eventOrCallback: string | T, callback?: T) => void; - off: (eventOrCallback?: string | T, callback?: T) => void; -} - -// Classes -declare class Auth { +export declare class Realtime { + constructor(options: ablyLib.ClientOptions | string); + static Crypto: ablyLib.Crypto; + auth: ablyLib.Auth; + channels: ablyLib.Channels; clientId: string; - authorize: (tokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; - createTokenRequest: (tokenParams?: TokenParams | tokenRequestCallback, authOptions?: AuthOptions | tokenRequestCallback, callback?: tokenRequestCallback) => void; - requestToken: (TokenParams?: TokenParams | tokenDetailsCallback, authOptions?: AuthOptions | tokenDetailsCallback, callback?: tokenDetailsCallback) => void; -} - -declare class Presence { - get: (params: RestPresenceParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; - history: (params: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; -} - -declare class RealtimePresence { - syncComplete: () => boolean; - get: (Params: realtimePresenceGetCallback | RealtimePresenceParams, callback?: realtimePresenceGetCallback) => void; - history: (ParamsOrCallback: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; - subscribe: (presenceOrCallback: PresenceAction | messageCallback, listener?: messageCallback) => void; - unsubscribe: (presence?: PresenceAction, listener?: messageCallback) => void; - enter: (data?: errorCallback | any, callback?: errorCallback) => void; - update: (data?: errorCallback | any, callback?: errorCallback) => void; - leave: (data?: errorCallback | any, callback?: errorCallback) => void; - enterClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; - updateClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; - leaveClient: (clientId: string, data?: errorCallback | any, callback?: errorCallback) => void; -} - -declare class Channel { - name: string; - presence: Presence; - history: (paramsOrCallback?: RestPresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; - publish: (messagesOrName: any, messagedataOrCallback?: errorCallback | any, callback?: errorCallback) => void; -} - -declare class RealtimeChannel extends EventEmitter { - name: string; - errorReason: ErrorInfo; - state: ChannelState; - presence: RealtimePresence; - attach: (callback?: standardCallback) => void; - detach: (callback?: standardCallback) => void; - history: (paramsOrCallback?: RealtimePresenceHistoryParams | paginatedResultCallback, callback?: paginatedResultCallback) => void; - subscribe: (eventOrCallback: messageCallback | string, listener?: messageCallback) => void; - unsubscribe: (eventOrCallback?: messageCallback | string, listener?: messageCallback) => void; - publish: (messagesOrName: any, messageDataOrCallback?: errorCallback | any, callback?: errorCallback) => void; - setOptions: (options: any, callback?: errorCallback) => void; -} - -declare class Channels { - get: (name: string, channelOptions?: ChannelOptions) => T; - release: (name: string) => void; -} - -declare class Message { - constructor(); - fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; - fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Message[]; - clientId: string; - connectionId: string; - data: any; - encoding: string; - extras: any; - id: string; - name: string; - timestamp: number; -} - -declare class PresenceMessage { - fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; - fromEncodedArray: (JsonArray: any[], channelOptions?: ChannelOptions) => PresenceMessage[]; - action: PresenceAction; - clientId: string; - connectionId: string; - data: any; - encoding: string; - id: string; - timestamp: number; -} - -declare interface Crypto { - generateRandomKey: (callback: (error: ErrorInfo, key: string) => void) => void; -} - -declare class Rest { - constructor(options: ClientOptions | string); - static Crypto: Crypto; - auth: Auth; - channels: Channels; - request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; - stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; - time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; -} - -declare class Realtime { - constructor(options: ClientOptions | string); - static Crypto: Crypto; - auth: Auth; - channels: Channels; - clientId: string; - connection: Connection; - request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ErrorInfo, response: HttpPaginatedResponse) => void) => void; - stats: (paramsOrCallback?: paginatedResultCallback | any, callback?: paginatedResultCallback) => void; + connection: ablyLib.Connection; + request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ablyLib.ErrorInfo, response: ablyLib.HttpPaginatedResponse) => void) => void; + stats: (paramsOrCallback?: ablyLib.paginatedResultCallback | any, callback?: ablyLib.paginatedResultCallback) => void; close: () => void; connect: () => void; - time: (paramsOrCallback?: timeCallback | any, callback?: timeCallback) => void; -} - -declare class Connection extends EventEmitter { - errorReason: ErrorInfo; - id: string; - key: string; - recoveryKey: string; - serial: number; - state: ConnectionState; - close: () => void; - connect: () => void; - ping: (callback?: (error: ErrorInfo, responseTime: number ) => void ) => void; -} - -declare class Stats { - all: StatsMessageTypes; - apiRequests: StatsRequestCount; - channels: StatsResourceCount; - connections: StatsConnectionTypes; - inbound: StatsMessageTraffic; - intervalId: string; - outbound: StatsMessageTraffic; - persisted: StatsMessageTypes; - tokenRequests: StatsRequestCount; -} - -declare class PaginatedResult { - items: T[]; - first: (results: paginatedResultCallback) => void; - next: (results: paginatedResultCallback) => void; - current: (results: paginatedResultCallback) => void; - hasNext: () => boolean; - isLast: () => boolean; -} - -declare class HttpPaginatedResponse extends PaginatedResult { - items: string[]; - statusCode: number; - success: boolean; - errorCode: number; - errorMessage: string; - headers: any; + time: (paramsOrCallback?: ablyLib.timeCallback | any, callback?: ablyLib.timeCallback) => void; } From 3be165a66ee749f7bfbe1975b2ea4eeecc58b95f Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 9 Feb 2017 13:01:45 +0000 Subject: [PATCH 6/6] Add support for fromEncoded methods and Message objects --- ably/ably-tests.ts | 14 ++++++++++++++ ably/index.d.ts | 25 +++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ably/ably-tests.ts b/ably/ably-tests.ts index aa08ca226e..da4714d21a 100644 --- a/ably/ably-tests.ts +++ b/ably/ably-tests.ts @@ -237,3 +237,17 @@ client.stats({ limit: 50 }, function(err, statsPage) { // statsPage as Pa // Fetching the Ably service time client.time({}, function(err, time) {}); // time is in ms since epoch + +// Getting decoded Message objects from JSON +var messages = Ably.Realtime.Message.fromEncodedArray([{ id: 'foo' }]); +console.log(messages[0].id); + +var message = Ably.Rest.Message.fromEncoded({ id: 'foo' }); +console.log(message.id); + +// Getting decoded PresenceMessage objects from JSON +var presenceMessages = Ably.Realtime.PresenceMessage.fromEncodedArray([{ id: 'foo' }]); +console.log(presenceMessages[0].action); + +var presenceMessage = Ably.Rest.PresenceMessage.fromEncoded({ id: 'foo' }); +console.log(presenceMessage.action); diff --git a/ably/index.d.ts b/ably/index.d.ts index b8cad7ae69..bf69daafc3 100644 --- a/ably/index.d.ts +++ b/ably/index.d.ts @@ -295,6 +295,8 @@ declare namespace ablyLib { type realtimePresenceGetCallback = (error: ErrorInfo, messages: PresenceMessage[]) => void; type tokenDetailsCallback = (error: ErrorInfo, Results: TokenDetails) => void; type tokenRequestCallback = (error: ErrorInfo, Results: TokenRequest) => void; + type fromEncoded = (JsonObject: any, channelOptions?: ChannelOptions) => T; + type fromEncodedArray = (JsonArray: any[], channelOptions?: ChannelOptions) => T[]; // Internal Classes class EventEmitter { @@ -358,8 +360,8 @@ declare namespace ablyLib { class Message { constructor(); - fromEncoded: (JsonObject: string, channelOptions: ChannelOptions) => Message; - fromEncodedArray: (JsonArray: string, channelOptions: ChannelOptions) => Message[]; + static fromEncoded: fromEncoded; + static fromEncodedArray: fromEncodedArray; clientId: string; connectionId: string; data: any; @@ -370,9 +372,15 @@ declare namespace ablyLib { timestamp: number; } + interface MessageStatic { + fromEncoded: fromEncoded; + fromEncodedArray: fromEncodedArray; + } + class PresenceMessage { - fromEncoded: (JsonObject: any, channelOptions?: ChannelOptions) => PresenceMessage; - fromEncodedArray: (JsonArray: any[], channelOptions?: ChannelOptions) => PresenceMessage[]; + constructor(); + static fromEncoded: fromEncoded; + static fromEncodedArray: fromEncodedArray; action: PresenceAction; clientId: string; connectionId: string; @@ -382,6 +390,11 @@ declare namespace ablyLib { timestamp: number; } + interface PresenceMessageStatic { + fromEncoded: fromEncoded; + fromEncodedArray: fromEncodedArray; + } + interface Crypto { generateRandomKey: (callback: (error: ErrorInfo, key: string) => void) => void; } @@ -432,6 +445,8 @@ declare namespace ablyLib { export declare class Rest { constructor(options: ablyLib.ClientOptions | string); static Crypto: ablyLib.Crypto; + static Message: ablyLib.MessageStatic; + static PresenceMessage: ablyLib.PresenceMessageStatic; auth: ablyLib.Auth; channels: ablyLib.Channels; request: (method: string, path: string, params?: any, body?: any[] | any, headers?: any, callback?: (error: ablyLib.ErrorInfo, response: ablyLib.HttpPaginatedResponse) => void) => void; @@ -442,6 +457,8 @@ export declare class Rest { export declare class Realtime { constructor(options: ablyLib.ClientOptions | string); static Crypto: ablyLib.Crypto; + static Message: ablyLib.MessageStatic; + static PresenceMessage: ablyLib.PresenceMessageStatic; auth: ablyLib.Auth; channels: ablyLib.Channels; clientId: string;