Update socketcluster-client, add sc-errors (#35311)

* Implement all overloads from Emitter.

* Mark the constants as readonly.

* Add type definitions for sc-errors.

* Add missing fields.
This commit is contained in:
Daniel Rose 2019-05-14 01:49:57 +02:00 committed by Nathan Shively-Sanders
parent 9e80f459ec
commit 1e93d62050
6 changed files with 323 additions and 34 deletions

141
types/sc-errors/index.d.ts vendored Normal file
View File

@ -0,0 +1,141 @@
// Type definitions for sc-errors 1.4
// Project: https://github.com/SocketCluster/sc-errors
// Definitions by: Daniel Rose <https://github.com/DanielRose>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.4
export class AuthTokenExpiredError extends Error {
expiry: Date;
constructor(message: string, expiry: Date);
}
export class AuthTokenInvalidError extends Error {
constructor(message: string);
}
export class AuthTokenNotBeforeError extends Error {
date: Date;
constructor(message: string, date: Date);
}
export class AuthTokenError extends Error {
constructor(message: string);
}
export class SilentMiddlewareBlockedError extends Error {
type: string;
constructor(message: string, type: string);
}
export class InvalidActionError extends Error {
constructor(message: string);
}
export class InvalidArgumentsError extends Error {
constructor(message: string);
}
export class InvalidOptionsError extends Error {
constructor(message: string);
}
export class InvalidMessageError extends Error {
constructor(message: string);
}
export class SocketProtocolError extends Error {
code: number;
constructor(message: string, code: number);
}
export class ServerProtocolError extends Error {
constructor(message: string);
}
export class HTTPServerError extends Error {
constructor(message: string);
}
export class ResourceLimitError extends Error {
constructor(message: string);
}
export class TimeoutError extends Error {
constructor(message: string);
}
export class BadConnectionError extends Error {
type: string;
constructor(message: string, type: string);
}
export class BrokerError extends Error {
constructor(message: string);
}
export class ProcessExitError extends Error {
code?: number;
constructor(message: string, code?: number);
}
export class UnknownError extends Error {
constructor(message: string);
}
export interface SocketProtocolErrorStatuses {
1001: string;
1002: string;
1003: string;
1005: string;
1006: string;
1007: string;
1008: string;
1009: string;
1010: string;
1011: string;
4000: string;
4001: string;
4002: string;
4003: string;
4004: string;
4005: string;
4006: string;
4007: string;
4008: string;
}
export const socketProtocolErrorStatuses: SocketProtocolErrorStatuses;
export interface SocketProtocolIgnoreStatuses {
1000: string;
1001: string;
}
export const socketProtocolIgnoreStatuses: SocketProtocolIgnoreStatuses;
/**
* Convert an error into a JSON-compatible type which can later be hydrated
* back to its *original* form.
*/
export function dehydrateError(error: any, includeStackTrace?: boolean): DehydratedError;
/**
* Convert a dehydrated error back to its *original* form.
*/
export function hydrateError(error: DehydratedError): any;
export type DehydratedError = any;
/**
* Make a deep copy of an object or array, assuring that there is at most
* one instance of each object or array in the resulting structure. The
* duplicate references (which might be forming cycles) are replaced with
* an object of the form
* {$ref: PATH}
* where the PATH is a JSONPath string that locates the first occurance.
*/
export function decycle(object: any): any;

View File

@ -0,0 +1,55 @@
import * as scErrors from "sc-errors";
import http = require("http");
import * as socketClusterServer from "socketcluster-server";
const httpServer = http.createServer();
const scServer = socketClusterServer.attach(httpServer);
// Create the various errors.
const authTokenExpiredError = new scErrors.AuthTokenExpiredError("error", new Date());
const authTokenInvalidError = new scErrors.AuthTokenInvalidError("error");
const authTokenNotBeforeError = new scErrors.AuthTokenNotBeforeError("error", new Date());
const authTokenError = new scErrors.AuthTokenError("error");
const silentMiddlewareBlockedError = new scErrors.SilentMiddlewareBlockedError("error", scServer.MIDDLEWARE_AUTHENTICATE);
const invalidActionError = new scErrors.InvalidActionError("error");
const invalidArgumentsError = new scErrors.InvalidArgumentsError("error");
const invalidOptionsError = new scErrors.InvalidOptionsError("error");
const invalidMessageError = new scErrors.InvalidMessageError("error");
const socketProtocolError = new scErrors.SocketProtocolError("error", 1001);
const serverProtocolError = new scErrors.ServerProtocolError("error");
const httpServerError = new scErrors.HTTPServerError("error");
const resourceLimitError = new scErrors.ResourceLimitError("error");
const timeoutError = new scErrors.TimeoutError("error");
const badConnectionError = new scErrors.BadConnectionError("error", "connectAbort");
const brokerError = new scErrors.BrokerError("error");
const processExitError = new scErrors.ProcessExitError("error");
const unknownError = new scErrors.UnknownError("error");
// Check some of the error and ignore statusses
console.log(scErrors.socketProtocolErrorStatuses[1001]);
console.log(scErrors.socketProtocolErrorStatuses[4000]);
console.log(scErrors.socketProtocolIgnoreStatuses[1000]);
// Dehydrate and hydrate an error
const err = new Error();
let dehydratedError = scErrors.dehydrateError(err);
let hydratedError = scErrors.hydrateError(dehydratedError);
dehydratedError = scErrors.dehydrateError(err, true);
hydratedError = scErrors.hydrateError(dehydratedError);
// decycle
const foo = {
bar: 5
};
const baz = {
a: 1,
b: "test",
c: foo,
d: {
d1: foo
}
};
const decycledBaz = scErrors.decycle(baz);

View File

@ -0,0 +1,23 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"sc-errors-tests.ts"
]
}

View File

@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}

View File

@ -1,6 +1,7 @@
import Emitter = require("component-emitter");
import { SCServer } from "socketcluster-server";
import { SCAuthEngine } from "sc-auth";
import { SocketProtocolIgnoreStatuses, SocketProtocolErrorStatuses } from "sc-errors";
import { SCChannel, SCChannelOptions, ChannelState } from "sc-channel";
import WebSocket = require("ws");
@ -8,28 +9,50 @@ declare class SCClientSocket extends Emitter {
constructor(opts: SCClientSocket.ClientOptions);
id: string;
clientId: string;
channels: {
[channelName: string]: SCChannel;
};
CONNECTING: "connecting";
OPEN: "open";
CLOSED: "closed";
readonly CONNECTING: "connecting";
readonly OPEN: "open";
readonly CLOSED: "closed";
state: SCClientSocket.States;
getState(): SCClientSocket.States;
AUTHENTICATED: "authenticated";
UNAUTHENTICATED: "unauthenticated";
readonly AUTHENTICATED: "authenticated";
readonly UNAUTHENTICATED: "unauthenticated";
authState: SCClientSocket.AuthStates;
PENDING: "pending";
readonly PENDING: "pending";
pendingReconnect: boolean;
pendingReconnectTimeout: number;
ackTimeout: number;
connectTimeout: number;
pingTimeout: number;
pingTimeoutDisabled: boolean;
channelPrefix: string | null;
disconnectOnUnload: boolean;
authTokenName: string;
connectAttempts: number;
options: SCClientSocket.ClientOptions;
authEngine: SCAuthEngine;
codecEngine: SCServer.SCCodecEngine;
readonly ignoreStatuses: SocketProtocolIgnoreStatuses;
readonly errorStatuses: SocketProtocolErrorStatuses;
getBytesReceived(): number;
deauthenticate(callback?: (err: Error) => void): void;
@ -57,6 +80,7 @@ declare class SCClientSocket extends Emitter {
send(data: any): void;
emit(event: string, ...args: any[]): this;
emit(event: string, data: any, callback?: (err: Error, responseData: any) => void): void;
publish(channelName: string, data: any, callback?: (err: Error, ackData: any) => void): void;
@ -77,44 +101,63 @@ declare class SCClientSocket extends Emitter {
unwatch(channelName: string, handler?: SCClientSocket.WatcherFunction): void;
watchers(channelName: string): SCClientSocket.WatcherFunction[];
on(event: string, listener: SCClientSocket.AnyFunction): this;
on(event: "connecting", listener: () => void): this;
on(event: "connect", listener: (status: SCClientSocket.ConnectStatus, processSubscriptions: () => void) => void): this;
on(event: "connectAbort" | "disconnect" | "close", listener: (code: number, data: string | object) => void): this;
on(event: "kickOut", listener: (message: string, channelName: string) => void): this;
on(event: "authenticate", listener: (signedAuthToken: string | null) => void): this;
on(event: "deauthenticate", listener: (oldSignedToken: string | null) => void): this;
on(event: "authStateChange", listener: (stateChangeData: SCClientSocket.AuthStateChangeData) => void): this;
on(event: "removeAuthToken", listener: (oldToken: object | null) => void): this;
on(event: "subscribe" | "subscribeRequest", listener: (channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
on(event: "subscribeStateChange", listener: (stateChangeData: SCClientSocket.SubscribeStateChangeData) => void): this;
on(event: "subscribeFail", listener: (err: Error, channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
on(event: "unsubscribe", listener: (channelName: string) => void): this;
on(event: "error", listener: (err: Error) => void): this;
on(event: "raw", listener: (data: any) => void): this;
on(event: "message", listener: (message: WebSocket.Data) => void): this;
// Implements Emitter interface
once(event: string, listener: SCClientSocket.AnyFunction): this;
once(event: "connecting", listener: () => void): this;
once(event: "connect", listener: (status: SCClientSocket.ConnectStatus, processSubscriptions: () => void) => void): this;
once(event: "connectAbort" | "disconnect" | "close", listener: (code: number, data: string | object) => void): this;
once(event: "kickOut", listener: (message: string, channelName: string) => void): this;
once(event: "authenticate", listener: (signedAuthToken: string | null) => void): this;
once(event: "deauthenticate", listener: (oldSignedToken: string | null) => void): this;
once(event: "authStateChange", listener: (stateChangeData: SCClientSocket.AuthStateChangeData) => void): this;
once(event: "removeAuthToken", listener: (oldToken: object | null) => void): this;
once(event: "subscribe" | "subscribeRequest", listener: (channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
once(event: "subscribeStateChange", listener: (stateChangeData: SCClientSocket.SubscribeStateChangeData) => void): this;
once(event: "subscribeFail", listener: (err: Error, channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
once(event: "unsubscribe", listener: (channelName: string) => void): this;
once(event: "error", listener: (err: Error) => void): this;
once(event: "raw", listener: (data: any) => void): this;
once(event: "message", listener: (message: WebSocket.Data) => void): this;
// tslint:disable:ban-types
// tslint:disable:adjacent-overload-signatures
on(event: string, listener: Function): this;
once(event: string, listener: Function): this;
off(event?: string, listener?: Function): this;
emit(event: string, ...args: any[]): this;
listeners(event: string): Function[];
hasListeners(event: string): boolean;
// tslint:enable:adjacent-overload-signatures
// tslint:enable:ban-types
off(event?: string, listener?: SCClientSocket.AnyFunction): this;
off(event: "connecting", listener?: () => void): this;
off(event: "connect", listener?: (status: SCClientSocket.ConnectStatus, processSubscriptions: () => void) => void): this;
off(event: "connectAbort" | "disconnect" | "close", listener?: (code: number, data: string | object) => void): this;
off(event: "kickOut", listener?: (message: string, channelName: string) => void): this;
off(event: "authenticate", listener?: (signedAuthToken: string | null) => void): this;
off(event: "deauthenticate", listener?: (oldSignedToken: string | null) => void): this;
off(event: "authStateChange", listener?: (stateChangeData: SCClientSocket.AuthStateChangeData) => void): this;
off(event: "removeAuthToken", listener?: (oldToken: object | null) => void): this;
off(event: "subscribe" | "subscribeRequest", listener?: (channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
off(event: "subscribeStateChange", listener?: (stateChangeData: SCClientSocket.SubscribeStateChangeData) => void): this;
off(event: "subscribeFail", listener?: (err: Error, channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
off(event: "unsubscribe", listener?: (channelName: string) => void): this;
off(event: "error", listener?: (err: Error) => void): this;
off(event: "raw", listener?: (data: any) => void): this;
off(event: "message", listener?: (message: WebSocket.Data) => void): this;
}
export = SCClientSocket;
declare namespace SCClientSocket {
type AnyFunction = (...args: any[]) => any;
interface ClientOptions {
host?: string;

View File

@ -1,7 +1,9 @@
// Adapted from README
import { create, destroy } from "socketcluster-client";
import { ClientOptions } from "socketcluster-client/lib/scclientsocket";
import { ClientOptions, SubscribeStateChangeData } from "socketcluster-client/lib/scclientsocket";
import { SCChannelOptions } from "sc-channel";
import WebSocket = require("ws");
const secureClientOptions: ClientOptions = {
hostname: "securedomain.com",
@ -48,28 +50,50 @@ const options: ClientOptions = {
};
socket = create(options);
socket.on("subscribe", channelname => {
// Check some of the standard events, with normal subscription,
// one-time subscription and unsubscription.
const subscribeListener: (channelName: string, subscriptionOptions: SCChannelOptions) => void = channelname => {
console.log("subscribe:" + channelname);
});
};
socket.on("subscribe", subscribeListener);
socket.once("subscribe", subscribeListener);
socket.off("subscribe", subscribeListener);
socket.off("subscribe");
socket.on("subscribeFail", channelname => {
const subscribeFailListener: (err: Error, channelName: string, subscriptionOptions: SCChannelOptions) => void = channelname => {
console.log("subscribeFail:" + channelname);
});
};
socket.on("subscribeFail", subscribeFailListener);
socket.once("subscribeFail", subscribeFailListener);
socket.off("subscribeFail", subscribeFailListener);
socket.off("subscribeFail");
socket.on("unsubscribe", channelname => {
const unsubscribeListener: (channelName: string) => void = channelname => {
console.log("unsubscribe:" + channelname);
});
};
socket.on("unsubscribe", unsubscribeListener);
socket.once("unsubscribe", unsubscribeListener);
socket.off("unsubscribe", unsubscribeListener);
socket.off("unsubscribe");
socket.on("subscribeStateChange", data => {
const subscribeStateChangeListener: (stateChangeData: SubscribeStateChangeData) => void = data => {
console.log("subscribeStateChange:" + JSON.stringify(data));
});
};
socket.on("subscribeStateChange", subscribeStateChangeListener);
socket.once("subscribeStateChange", subscribeStateChangeListener);
socket.off("subscribeStateChange", subscribeStateChangeListener);
socket.off("subscribeStateChange");
socket.on("message", data => {
const messageListener: (message: WebSocket.Data) => void = data => {
console.log("message:" + data);
});
};
socket.on("message", messageListener);
socket.once("message", messageListener);
socket.off("message", messageListener);
socket.off("message");
const channels = socket.channels;
const testChannel = channels["test"];
const state = testChannel.getState();
const channelState = testChannel.getState();
destroy(socket);