diff --git a/types/nes/index.d.ts b/types/nes/index.d.ts index 6ebc9ee1c0..95c3dd0835 100644 --- a/types/nes/index.d.ts +++ b/types/nes/index.d.ts @@ -3,38 +3,70 @@ // Definitions by: Ivo Stratev // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/// +import * as Hapi from 'hapi'; -declare module 'nes' { - import Hapi = require('hapi'); +declare module 'hapi' { + interface Server { + broadcast(message: any, options?: nes.ServerBroadcastOptions): void; + subscription(path: string, options?: nes.ServerSubscriptionOptions): void; + publish(path: string, message: any, options?: nes.ServerPublishOptions): void; + eachSocket(each: (socket: SocketClass) => void, options?: nes.ServerEachSocketOptions): void; + } +} - export interface SocketAuthObject { +declare class SocketClass { + id: any; + app: Object; + auth: nes.SocketAuthObject; + disconect(callback?: () => void): void; + send(message: any, callback?: (err?: any) => void): void; + publish(path: string, message: any, callback?: (err?: any) => void): void; + revoke(path: string, message: any, callback?: (err?: any) => void): void; +} + +declare class RequestClass extends Hapi.Request { + socket: SocketClass; +} + +declare class ClientClass { + onError: (err: any) => void; + onConnect: () => void; + onDisconnect: () => void; + onUpdate: (message: any) => void; + connect(options: nes.ClientConnectOptions, callback: (err?: any) => void): void; + connect(callback: (err?: any) => void): void; + disconnect(): void; + id: any; + request(options: string | nes.ClientRequestOptions, callback: (err: any, payload: any, statusCode?: number, headers?: Object) => void): void; + message(message: any, callback: (err: any, message: any) => void): void; + subscribe(path: string, handler: nes.Handler, callback: (err?: any) => void): void; + unsubscribe(path: string, handler: nes.Handler, callback: (err?: any) => void): void; + subscriptions(): string[]; + overrideReconnectionAuth(auth: any): void; +} + +declare module nes { + interface Handler { + (message: any, flags: nes.ClientSubscribeFlags): void; + } + + interface SocketAuthObject { isAuthenticated: boolean; credentials: any; artifacts: any; } - export class Socket { - id: any; - app: Object; - auth: SocketAuthObject; - disconect(callback?: () => void): void; - send(message: any, callback?: (err?: any) => void): void; - publish(path: string, message: any, callback?: (err?: any) => void): void; - revoke(path: string, message: any, callback?: (err?: any) => void): void; - } - - export interface ServerBroadcastOptions { + interface ServerBroadcastOptions { user: any } - export interface ServerSubscriptionOptionsFilterOptions { + interface ServerSubscriptionOptionsFilterOptions { socket: Socket; credentials?: any; params?: any; } - export interface ServerSubscriptionOptionsAuthOptions { + interface ServerSubscriptionOptionsAuthOptions { mode?: 'required' | 'optional'; scope?: string | string[]; entity?: 'user' | 'app' | 'any'; @@ -49,40 +81,29 @@ declare module 'nes' { export type ServerOnUnSubscribeWithoutParams = (socket: Socket, path: string, next: () => void) => void; export type ServerOnUnSubscribe = ServerOnUnSubscribeWithParams | ServerOnUnSubscribeWithoutParams; - export interface ServerSubscriptionOptions { - filter?: (path: string, message: any, options: ServerSubscriptionOptionsFilterOptions, next: (isMatch: boolean, override: any) => void) => void; + interface ServerSubscriptionOptions { + filter?: (path: string, message: any, options: ServerSubscriptionOptionsFilterOptions, next: (isMatch: boolean, override?: any) => void) => void; auth?: boolean | ServerSubscriptionOptionsAuthOptions; onSubscribe?: ServerOnSubscribe; onUnsubscribe?: ServerOnUnSubscribe; } - export interface ServerPublishOptions { + interface ServerPublishOptions { internal?: any; user?: any; } - export interface ServerEachSocketOptions { + interface ServerEachSocketOptions { subscription?: string; user?: any; } - export class Server extends Hapi.Server { - broadcast(message: any, options?: ServerBroadcastOptions): void; - subscription(path: string, options?: ServerSubscriptionOptions): void; - publish(path: string, message: any, options?: ServerPublishOptions): void; - eachSocket(each: (socket: Socket) => void, options?: ServerEachSocketOptions): void; - } - - export class Request extends Hapi.Request { - socket: Socket; - } - - export interface ClientOptions { + interface ClientOptions { ws?: any; timeout?: number | boolean; } - export interface ClientConnectOptions { + interface ClientConnectOptions { auth?: any; delay?: number; maxDelay?: number; @@ -90,41 +111,64 @@ declare module 'nes' { timeout?: number; } - export interface ClientRequestOptions { + interface ClientRequestOptions { path: string; method?: string; headers?: Object; payload?: any; } - export interface ClientSubscribeFlags { + interface ClientSubscribeFlags { revoked?: boolean; } - export class Client { - constructor(url: string, options?: ClientOptions); - onError: (err: any) => void; - onConnect: () => void; - onDisconnect: () => void; - onUpdate: (message: any) => void; - connect(options: ClientConnectOptions, callback: (err?: any) => void): void; - connect(callback: (err?: any) => void): void; - disconnect(): void; - id: any; - request(options: string | ClientRequestOptions, callback: (err: any, payload: any, statusCode?: number, headers?: Object) => void): void; - message(message: any, callback: (err: any, message: any) => void): void; - subscribe(path: string, handler: (message: any, flags: ClientSubscribeFlags) => void, callback: (err?: any) => void): void; - unsubscribe(path: string, handler: (message: any, flags: ClientSubscribeFlags) => void, callback: (err?: any) => void): void; - subscriptions(): string[]; - overrideReconnectionAuth(auth: any): void; + interface Socket extends SocketClass { + } + + interface Server extends Hapi.Server { + } + + interface Request extends RequestClass { + } + + interface Client extends ClientClass { } } -declare module 'nes/client' { - export { - Client, - ClientConnectOptions, - ClientRequestOptions, - ClientSubscribeFlags - } from 'nes'; +interface NesResources { + Socket: { + new(): SocketClass; + }; + + Server: { + new(): Hapi.Server; + }; + + Request: { + new(): RequestClass; + }; + + Client: { + new(url: string, options?: nes.ClientOptions): ClientClass; + }; } + +// TODO fix this. See test/client-require.ts test case. +declare module 'nes/client' { + var nesClient: NesResources; + + export = nesClient; + + // export { + // ClientClass, + // // ClientConnectOptions, + // // ClientRequestOptions, + // // ClientSubscribeFlags + // }; +} + +interface NesExports extends NesResources, Hapi.PluginFunction<{}> {} + +declare var nes: NesExports; + +export = nes; diff --git a/types/nes/test/broadcast-client.ts b/types/nes/test/broadcast-client.ts new file mode 100644 index 0000000000..1cf8797365 --- /dev/null +++ b/types/nes/test/broadcast-client.ts @@ -0,0 +1,12 @@ +// from https://github.com/hapijs/nes#broadcast + +import Nes = require('nes'); + +var client = new Nes.Client('ws://localhost'); +client.connect(function (err) { + + client.onUpdate = function (update) { + + // update -> 'welcome!' + }; +}); diff --git a/types/nes/test/broadcast-server.ts b/types/nes/test/broadcast-server.ts new file mode 100644 index 0000000000..dcfcb3400e --- /dev/null +++ b/types/nes/test/broadcast-server.ts @@ -0,0 +1,15 @@ +// from https://github.com/hapijs/nes#broadcast + +import Hapi = require('hapi'); +import Nes = require('nes'); + +var server = new Hapi.Server(); +server.connection(); + +server.register(Nes, function (err) { + + server.start(function (err) { + + server.broadcast('welcome!'); + }); +}); diff --git a/types/nes/test/client-require.ts b/types/nes/test/client-require.ts new file mode 100644 index 0000000000..90bce07d33 --- /dev/null +++ b/types/nes/test/client-require.ts @@ -0,0 +1,7 @@ +// from https://github.com/hapijs/nes/#browser-client +// When you require('nes') it loads the full module and adds a lot of extra code +// that is not needed for the browser. The browser will only need the nes client. +// If you are using CommonJS you can load the client with require('nes/client'). + +// TODO fix this +// import nes = require('nes/client'); diff --git a/types/nes/nes-tests.ts b/types/nes/test/nes-tests.ts similarity index 93% rename from types/nes/nes-tests.ts rename to types/nes/test/nes-tests.ts index effe4e6c94..9dd12ae99a 100644 --- a/types/nes/nes-tests.ts +++ b/types/nes/test/nes-tests.ts @@ -1,7 +1,7 @@ import Hapi = require('hapi'); import Nes = require('nes'); -let server: Hapi.Server = new Hapi.Server(); +var server: Hapi.Server = new Hapi.Server(); server.connection({port: 8080}); server.register(Nes, (regErr: any) => { @@ -15,7 +15,7 @@ server.register(Nes, (regErr: any) => { method: 'GET', path: '/test', config: { - handler: (request: Hapi.Request, reply: Hapi.IReply) => { + handler: (request: Hapi.Request, reply: Hapi.ReplyNoContinue) => { reply({test: 'passes'}); } } diff --git a/types/nes/test/route-authentication-client.ts b/types/nes/test/route-authentication-client.ts new file mode 100644 index 0000000000..b3fd33fe95 --- /dev/null +++ b/types/nes/test/route-authentication-client.ts @@ -0,0 +1,12 @@ +// from https://github.com/hapijs/nes#route-authentication + +import Nes = require('nes'); + +var client = new Nes.Client('ws://localhost'); +client.connect({ auth: { headers: { authorization: 'Basic am9objpzZWNyZXQ=' } } }, function (err) { + + client.request('hello', function (err, payload) { // Can also request '/h' + + // payload -> 'Hello John Doe' + }); +}); diff --git a/types/nes/test/route-authentication-server.ts b/types/nes/test/route-authentication-server.ts new file mode 100644 index 0000000000..5b4634d77d --- /dev/null +++ b/types/nes/test/route-authentication-server.ts @@ -0,0 +1,61 @@ +// from https://github.com/hapijs/nes#route-authentication + +import Hapi = require('hapi'); +import Basic = require('hapi-auth-basic'); +import Bcrypt = require('bcrypt'); +import Nes = require('nes'); + +var server = new Hapi.Server(); +server.connection(); + +server.register([Basic, Nes], function (err) { + + // Set up HTTP Basic authentication + + interface User { + username: string; + password: string; + name: string; + id: string; + } + + var users: {[index: string]: User} = { + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a' + } + }; + + var validate: Basic.ValidateFunc = function (request, username, password, callback) { + + var user = users[username]; + if (!user) { + return callback(null, false); + } + + Bcrypt.compare(password, user.password, function (err, isValid) { + + callback(err, isValid, { id: user.id, name: user.name }); + }); + }; + + server.auth.strategy('simple', 'basic', 'required', { validateFunc: validate }); + + // Configure route with authentication + + server.route({ + method: 'GET', + path: '/h', + config: { + id: 'hello', + handler: function (request, reply) { + + return reply('Hello ' + request.auth.credentials.name); + } + } + }); + + server.start(function (err) { /* ... */ }); +}); diff --git a/types/nes/test/route-invocation-client.ts b/types/nes/test/route-invocation-client.ts new file mode 100644 index 0000000000..e25e64e349 --- /dev/null +++ b/types/nes/test/route-invocation-client.ts @@ -0,0 +1,12 @@ +// from https://github.com/hapijs/nes#route-invocation + +import Nes = require('nes'); + +var client = new Nes.Client('ws://localhost'); +client.connect(function (err) { + + client.request('hello', function (err, payload) { // Can also request '/h' + + // payload -> 'world!' + }); +}); diff --git a/types/nes/test/route-invocation-server.ts b/types/nes/test/route-invocation-server.ts new file mode 100644 index 0000000000..c32780baa9 --- /dev/null +++ b/types/nes/test/route-invocation-server.ts @@ -0,0 +1,24 @@ +// from https://github.com/hapijs/nes#route-invocation + +import Hapi = require('hapi'); +import Nes = require('nes'); + +var server = new Hapi.Server(); +server.connection(); + +server.register(Nes, function (err) { + + server.route({ + method: 'GET', + path: '/h', + config: { + id: 'hello', + handler: function (request, reply) { + + return reply('world!'); + } + } + }); + + server.start(function (err) { /* ... */ }); +}); diff --git a/types/nes/test/subscription-filter-client.ts b/types/nes/test/subscription-filter-client.ts new file mode 100644 index 0000000000..bd5c9c88f5 --- /dev/null +++ b/types/nes/test/subscription-filter-client.ts @@ -0,0 +1,18 @@ +// from https://github.com/hapijs/nes#subscription-filter + +import Nes = require('nes'); + +var client = new Nes.Client('ws://localhost'); + +// Authenticate as 'john' + +client.connect({ auth: { headers: { authorization: 'Basic am9objpzZWNyZXQ=' } } }, function (err) { + + var handler: Nes.Handler = function (err, update) { + + // First publish is not received (filtered due to updater key) + // update -> { id: 6, status: 'initial', updater: 'steve' } + }; + + client.subscribe('/items', handler, function (err) { }); +}); diff --git a/types/nes/test/subscription-filter-server.ts b/types/nes/test/subscription-filter-server.ts new file mode 100644 index 0000000000..be2dda8d7f --- /dev/null +++ b/types/nes/test/subscription-filter-server.ts @@ -0,0 +1,60 @@ +// from https://github.com/hapijs/nes#subscription-filter + +import Hapi = require('hapi'); +import Basic = require('hapi-auth-basic'); +import Bcrypt = require('bcrypt'); +import Nes = require('nes'); + +var server = new Hapi.Server(); +server.connection(); + +server.register([Basic, Nes], function (err) { + + // Set up HTTP Basic authentication + + interface User { + username: string; + password: string; + name: string; + id: string; + } + + var users: {[index: string]: User} = { + john: { + username: 'john', + password: '$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm', // 'secret' + name: 'John Doe', + id: '2133d32a' + } + }; + + var validate: Basic.ValidateFunc = function (request, username, password, callback) { + + var user = users[username]; + if (!user) { + return callback(null, false); + } + + Bcrypt.compare(password, user.password, function (err, isValid) { + + callback(err, isValid, { id: user.id, name: user.name, username: user.username }); + }); + }; + + server.auth.strategy('simple', 'basic', 'required', { validateFunc: validate }); + + // Set up subscription + + server.subscription('/items', { + filter: function (path, message, options, next) { + + return next(message.updater !== options.credentials.username); + } + }); + + server.start(function (err) { + + server.publish('/items', { id: 5, status: 'complete', updater: 'john' }); + server.publish('/items', { id: 6, status: 'initial', updater: 'steve' }); + }); +}); diff --git a/types/nes/test/subscriptions-client.ts b/types/nes/test/subscriptions-client.ts new file mode 100644 index 0000000000..1e33eac40f --- /dev/null +++ b/types/nes/test/subscriptions-client.ts @@ -0,0 +1,15 @@ +// from https://github.com/hapijs/nes#subscriptions + +import Nes = require('nes'); + +var client = new Nes.Client('ws://localhost'); +client.connect(function (err) { + + var handler: Nes.Handler = function (update, flags) { + + // update -> { id: 5, status: 'complete' } + // Second publish is not received (doesn't match) + }; + + client.subscribe('/item/5', handler, function (err) { }); +}); diff --git a/types/nes/test/subscriptions-server.ts b/types/nes/test/subscriptions-server.ts new file mode 100644 index 0000000000..23212f21ea --- /dev/null +++ b/types/nes/test/subscriptions-server.ts @@ -0,0 +1,18 @@ +// from https://github.com/hapijs/nes#subscriptions + +import Hapi = require('hapi'); +import Nes = require('nes'); + +var server = new Hapi.Server(); +server.connection(); + +server.register(Nes, function (err) { + + server.subscription('/item/{id}'); + + server.start(function (err) { + + server.publish('/item/5', { id: 5, status: 'complete' }); + server.publish('/item/6', { id: 6, status: 'initial' }); + }); +}); diff --git a/types/nes/tsconfig.json b/types/nes/tsconfig.json index 74c7bfef19..a2cd55a5db 100644 --- a/types/nes/tsconfig.json +++ b/types/nes/tsconfig.json @@ -17,6 +17,17 @@ }, "files": [ "index.d.ts", - "nes-tests.ts" + "test/client-require.ts", + "test/nes-tests.ts", + "test/broadcast-client.ts", + "test/broadcast-server.ts", + "test/route-authentication-client.ts", + "test/route-authentication-server.ts", + "test/route-invocation-client.ts", + "test/route-invocation-server.ts", + "test/subscription-filter-client.ts", + "test/subscription-filter-server.ts", + "test/subscriptions-client.ts", + "test/subscriptions-server.ts" ] } \ No newline at end of file