airdcpp-apisocket 3.0.0-beta.3 → 3.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ApiConstants.d.ts +6 -0
- package/dist/ApiConstants.js +6 -0
- package/dist/ApiConstants.js.map +1 -0
- package/dist/NodeSocket.d.ts +4 -0
- package/dist/NodeSocket.js +5 -0
- package/dist/NodeSocket.js.map +1 -0
- package/dist/Promise.d.ts +8 -0
- package/dist/Promise.js +25 -0
- package/dist/Promise.js.map +1 -0
- package/dist/PublicHelpers.d.ts +2 -0
- package/dist/PublicHelpers.js +108 -0
- package/dist/PublicHelpers.js.map +1 -0
- package/dist/SocketBase.d.ts +4 -0
- package/dist/SocketBase.js +347 -0
- package/dist/SocketBase.js.map +1 -0
- package/dist/SocketLogger.d.ts +9 -0
- package/dist/SocketLogger.js +69 -0
- package/dist/SocketLogger.js.map +1 -0
- package/dist/SocketRequestHandler.d.ts +14 -0
- package/dist/SocketRequestHandler.js +164 -0
- package/dist/SocketRequestHandler.js.map +1 -0
- package/dist/SocketSubscriptionHandler.d.ts +11 -0
- package/dist/SocketSubscriptionHandler.js +157 -0
- package/dist/SocketSubscriptionHandler.js.map +1 -0
- package/dist/tests/helpers.d.ts +57 -0
- package/dist/tests/helpers.js +127 -0
- package/dist/tests/helpers.js.map +1 -0
- package/dist/types/api.d.ts +30 -0
- package/dist/types/api.js +3 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/api_internal.d.ts +24 -0
- package/dist/types/api_internal.js +2 -0
- package/dist/types/api_internal.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logger.d.ts +6 -0
- package/dist/types/logger.js +2 -0
- package/dist/types/logger.js.map +1 -0
- package/dist/types/options.d.ts +31 -0
- package/dist/types/options.js +3 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/public_helpers.d.ts +28 -0
- package/dist/types/public_helpers.js +2 -0
- package/dist/types/public_helpers.js.map +1 -0
- package/dist/types/public_helpers_internal.d.ts +27 -0
- package/dist/types/public_helpers_internal.js +2 -0
- package/dist/types/public_helpers_internal.js.map +1 -0
- package/dist/types/requests.d.ts +14 -0
- package/dist/types/requests.js +2 -0
- package/dist/types/requests.js.map +1 -0
- package/dist/types/socket.d.ts +23 -0
- package/dist/types/socket.js +2 -0
- package/dist/types/socket.js.map +1 -0
- package/dist/types/subscriptions.d.ts +20 -0
- package/dist/types/subscriptions.js +2 -0
- package/dist/types/subscriptions.js.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -0
- package/dist-es/tests/helpers.d.ts +75 -0
- package/dist-es/tests/helpers.js +135 -0
- package/dist-es/tests/helpers.js.map +1 -0
- package/package.json +6 -3
- package/src/tests/Socket.test.ts +14 -12
- package/src/tests/helpers.ts +29 -13
- package/tsconfig.json +1 -1
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AAEzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AAEnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAE7B,cAAc,qBAAqB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/types/logger.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
export type PrintHandler = (...optionalParams: any[]) => void;
|
2
|
+
export interface LogOutput {
|
3
|
+
log: PrintHandler;
|
4
|
+
info: PrintHandler;
|
5
|
+
warn: PrintHandler;
|
6
|
+
error: PrintHandler;
|
7
|
+
}
|
8
|
+
export type IgnoreMatcher = string[] | RegExp;
|
9
|
+
export interface SocketRequestOptions {
|
10
|
+
ignoredRequestPaths?: IgnoreMatcher;
|
11
|
+
requestTimeout?: number;
|
12
|
+
}
|
13
|
+
export interface SocketSubscriptionOptions {
|
14
|
+
ignoredListenerEvents?: IgnoreMatcher;
|
15
|
+
}
|
16
|
+
export interface RequiredSocketOptions {
|
17
|
+
url: string;
|
18
|
+
username?: string;
|
19
|
+
password?: string;
|
20
|
+
}
|
21
|
+
export interface AdvancedSocketOptions {
|
22
|
+
autoReconnect: boolean;
|
23
|
+
reconnectInterval: number;
|
24
|
+
userSession: boolean;
|
25
|
+
}
|
26
|
+
export interface LoggerOptions {
|
27
|
+
logLevel?: string;
|
28
|
+
logOutput?: LogOutput;
|
29
|
+
}
|
30
|
+
type UserOptions = RequiredSocketOptions & Partial<AdvancedSocketOptions> & LoggerOptions & SocketSubscriptionOptions & SocketRequestOptions;
|
31
|
+
export { UserOptions as APISocketOptions };
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/types/options.ts"],"names":[],"mappings":"AAAA,UAAU"}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { HookSubscriberInfo } from './subscriptions.js';
|
2
|
+
export interface MenuCallbackProperties<IdT, EntityIdT> {
|
3
|
+
selectedIds: IdT[];
|
4
|
+
entityId: EntityIdT;
|
5
|
+
permissions: string[];
|
6
|
+
supports: string[];
|
7
|
+
}
|
8
|
+
export interface MenuClickHandlerProperties<IdT, EntityIdT, FormValueT extends object = object> extends MenuCallbackProperties<IdT, EntityIdT> {
|
9
|
+
formValues: FormValueT;
|
10
|
+
}
|
11
|
+
type AsyncCallbackProperty<IdT, EntityIdT, ReturnT> = (props: MenuCallbackProperties<IdT, EntityIdT>) => ReturnT | Promise<ReturnT>;
|
12
|
+
export type ContextMenuIcon = {
|
13
|
+
[key in string]: string;
|
14
|
+
};
|
15
|
+
export interface ContextMenu extends HookSubscriberInfo {
|
16
|
+
icon?: ContextMenuIcon;
|
17
|
+
}
|
18
|
+
export interface ContextMenuItem<IdT, EntityIdT, FormValueT extends object = object> {
|
19
|
+
id: string;
|
20
|
+
title: string;
|
21
|
+
icon?: ContextMenuIcon;
|
22
|
+
urls?: string[] | AsyncCallbackProperty<IdT, EntityIdT, string[] | undefined>;
|
23
|
+
onClick?: (props: MenuClickHandlerProperties<IdT, EntityIdT, FormValueT>) => void;
|
24
|
+
filter?: AsyncCallbackProperty<IdT, EntityIdT, boolean>;
|
25
|
+
access?: string;
|
26
|
+
formDefinitions?: object[] | AsyncCallbackProperty<IdT, EntityIdT, object[]>;
|
27
|
+
}
|
28
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"public_helpers.js","sourceRoot":"","sources":["../../src/types/public_helpers.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { ContextMenuIcon, ContextMenuItem } from './public_helpers.js';
|
2
|
+
export interface SelectedMenuItemListenerData<IdT, EntityIdT> {
|
3
|
+
hook_id: string;
|
4
|
+
menu_id: string;
|
5
|
+
menuitem_id: string;
|
6
|
+
selected_ids: IdT[];
|
7
|
+
entity_id: EntityIdT;
|
8
|
+
permissions: string[];
|
9
|
+
supports: string[];
|
10
|
+
form_values: object;
|
11
|
+
}
|
12
|
+
export interface MenuItemListHookData<IdT, EntityIdT> {
|
13
|
+
selected_ids: IdT[];
|
14
|
+
entity_id: EntityIdT;
|
15
|
+
permissions: string[];
|
16
|
+
supports: string[];
|
17
|
+
}
|
18
|
+
export interface ResponseMenuItemCallbackFields {
|
19
|
+
urls?: string[] | undefined;
|
20
|
+
form_definitions?: object[] | undefined;
|
21
|
+
}
|
22
|
+
export type ResponseMenuItem<IdT, EntityIdT> = Omit<ContextMenuItem<IdT, EntityIdT>, 'onClick' | 'filter' | 'urls' | 'form_definitions'> & ResponseMenuItemCallbackFields;
|
23
|
+
export interface MenuItemListHookAcceptData<IdT, EntityIdT> {
|
24
|
+
menuitems: ResponseMenuItem<IdT, EntityIdT>[];
|
25
|
+
icon?: ContextMenuIcon;
|
26
|
+
title?: string;
|
27
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"public_helpers_internal.js","sourceRoot":"","sources":["../../src/types/public_helpers_internal.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import * as API from './api.js';
|
2
|
+
export interface SocketRequestMethods {
|
3
|
+
put: <ResponseT extends object | void>(path: string, data?: object) => Promise<ResponseT>;
|
4
|
+
patch: <ResponseT extends object | void>(path: string, data?: object) => Promise<ResponseT>;
|
5
|
+
post: <ResponseT extends object | void>(path: string, data?: object) => Promise<ResponseT>;
|
6
|
+
delete: <ResponseT extends object | void>(path: string) => Promise<ResponseT>;
|
7
|
+
get: <ResponseT extends object | void>(path: string) => Promise<ResponseT>;
|
8
|
+
getPendingRequestCount: () => number;
|
9
|
+
}
|
10
|
+
export interface ErrorResponse {
|
11
|
+
message: string;
|
12
|
+
code: number;
|
13
|
+
json: API.FieldError | API.ErrorBase;
|
14
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { AuthTokenType, LogoutResponse, AuthenticationResponse } from './api.js';
|
2
|
+
import { Logger } from './logger.js';
|
3
|
+
import { SocketRequestMethods } from './requests.js';
|
4
|
+
import { SocketSubscriptions } from './subscriptions.js';
|
5
|
+
export type ConnectedCallback = (data: AuthenticationResponse) => void;
|
6
|
+
export type SessionResetCallback = () => void;
|
7
|
+
export type DisconnectedCallback = (reason: string, code: number, wasClean: boolean) => void;
|
8
|
+
export interface APISocket extends SocketRequestMethods, SocketSubscriptions {
|
9
|
+
connect: (username?: string, password?: string, reconnectOnFailure?: boolean) => Promise<AuthenticationResponse>;
|
10
|
+
connectRefreshToken: (refreshToken: string, reconnectOnFailure?: boolean) => Promise<AuthenticationResponse>;
|
11
|
+
disconnect: (autoConnect?: boolean, reason?: string) => void;
|
12
|
+
waitDisconnected: (timeoutMs?: number) => Promise<void>;
|
13
|
+
reconnect: (token?: AuthTokenType, reconnectOnFailure?: boolean) => Promise<AuthenticationResponse>;
|
14
|
+
logout: () => Promise<LogoutResponse>;
|
15
|
+
isConnecting: () => boolean;
|
16
|
+
isConnected: () => boolean;
|
17
|
+
isActive: () => boolean;
|
18
|
+
logger: Logger;
|
19
|
+
onConnected: ConnectedCallback | null;
|
20
|
+
onSessionReset: SessionResetCallback | null;
|
21
|
+
onDisconnected: DisconnectedCallback | null;
|
22
|
+
readonly nativeSocket: WebSocket | null;
|
23
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../../src/types/socket.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import * as API from './api.js';
|
2
|
+
export type SubscriptionRemoveHandler = (sendApi?: boolean) => void;
|
3
|
+
export type SubscriptionCallback<DataT extends object | void = object, EntityIdT = API.EntityId | undefined> = (data: DataT, entityId: EntityIdT) => void;
|
4
|
+
export interface HookSubscriberInfo {
|
5
|
+
id: string;
|
6
|
+
name: string;
|
7
|
+
}
|
8
|
+
export type HookRejectHandler = (rejectId: string, rejectMessage: string) => void;
|
9
|
+
export type HookAcceptHandler<DataT extends object | undefined> = (data: DataT) => void;
|
10
|
+
export type HookCallback<DataT extends object = object, CompletionDataT extends object | undefined = object | undefined> = (data: DataT, accept: HookAcceptHandler<CompletionDataT>, reject: HookRejectHandler) => void;
|
11
|
+
export interface SocketSubscriptions {
|
12
|
+
addHook: <DataT extends object, CompletionDataT extends object | undefined>(apiModule: string, event: string, callback: HookCallback<DataT, CompletionDataT>, subscriberInfo: HookSubscriberInfo) => Promise<SubscriptionRemoveHandler>;
|
13
|
+
addListener: <DataT extends object | void, EntityIdT extends API.EntityId | undefined = undefined>(apiModule: string, event: string, callback: SubscriptionCallback<DataT, EntityIdT>, entityId?: API.EntityId) => Promise<SubscriptionRemoveHandler>;
|
14
|
+
addViewUpdateListener: <DataT extends object | void, EntityIdT extends API.EntityId | undefined = undefined>(viewName: string, callback: SubscriptionCallback<DataT, EntityIdT>, entityId?: API.EntityId) => () => void;
|
15
|
+
hasListeners: () => boolean;
|
16
|
+
getPendingSubscriptionCount: () => number;
|
17
|
+
}
|
18
|
+
export type AddHook = SocketSubscriptions['addHook'];
|
19
|
+
export type AddListener = SocketSubscriptions['addListener'];
|
20
|
+
export type AddViewUpdateListener = SocketSubscriptions['addViewUpdateListener'];
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../../src/types/subscriptions.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
export const eventIgnored = (path, ignoredEvents) => {
|
2
|
+
if (!ignoredEvents) {
|
3
|
+
return false;
|
4
|
+
}
|
5
|
+
// Array?
|
6
|
+
if (Array.isArray(ignoredEvents)) {
|
7
|
+
return ignoredEvents.indexOf(path) !== -1;
|
8
|
+
}
|
9
|
+
// Regexp
|
10
|
+
return ignoredEvents.test(path);
|
11
|
+
};
|
12
|
+
//# sourceMappingURL=utils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,aAAqC,EAAE,EAAE;IAClF,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS;IACT,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,OAAO,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,SAAS;IACT,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC"}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import * as Options from '../types/options.js';
|
2
|
+
export declare const waitForExpect: (func: () => void | Promise<void>) => Promise<{}>;
|
3
|
+
declare const getMockConsole: () => {
|
4
|
+
log: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
5
|
+
info: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
6
|
+
warn: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
7
|
+
error: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
8
|
+
};
|
9
|
+
declare const DEFAULT_CONNECT_PARAMS: {
|
10
|
+
username: string;
|
11
|
+
password: string;
|
12
|
+
url: string;
|
13
|
+
};
|
14
|
+
declare const DEFAULT_AUTH_RESPONSE: {
|
15
|
+
auth_token: string;
|
16
|
+
refresh_token: string;
|
17
|
+
user: {
|
18
|
+
permissions: string[];
|
19
|
+
username: string;
|
20
|
+
active_sessions: number;
|
21
|
+
last_login: number;
|
22
|
+
};
|
23
|
+
system: {
|
24
|
+
cid: string;
|
25
|
+
hostname: string;
|
26
|
+
network_type: string;
|
27
|
+
path_separator: string;
|
28
|
+
platform: string;
|
29
|
+
language: string;
|
30
|
+
};
|
31
|
+
wizard_pending: boolean;
|
32
|
+
};
|
33
|
+
export type MockSocketOptions = Omit<Options.APISocketOptions, 'username' | 'password' | 'url'> & {
|
34
|
+
username?: string;
|
35
|
+
password?: string;
|
36
|
+
url?: string;
|
37
|
+
};
|
38
|
+
declare const getSocket: (socketOptions?: MockSocketOptions, mockConsole?: {
|
39
|
+
log: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
40
|
+
info: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
41
|
+
warn: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
42
|
+
error: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
43
|
+
}) => {
|
44
|
+
socket: import("../NodeSocket.js").APISocket;
|
45
|
+
mockConsole: {
|
46
|
+
log: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
47
|
+
info: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
48
|
+
warn: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
49
|
+
error: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
50
|
+
};
|
51
|
+
};
|
52
|
+
type Callback = (requestData: object) => void;
|
53
|
+
interface ConnectOptions {
|
54
|
+
socketOptions?: MockSocketOptions;
|
55
|
+
authCallback?: Callback;
|
56
|
+
authResponse?: object;
|
57
|
+
console?: ReturnType<typeof getMockConsole>;
|
58
|
+
}
|
59
|
+
declare const getConnectedSocket: (server: ReturnType<typeof getMockServer>, userOptions?: ConnectOptions) => Promise<{
|
60
|
+
socket: import("../NodeSocket.js").APISocket;
|
61
|
+
mockConsole: {
|
62
|
+
log: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
63
|
+
info: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
64
|
+
warn: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
65
|
+
error: import("jest-mock").Mock<(a1: any, a2: any, a3: any, a4: any) => void>;
|
66
|
+
};
|
67
|
+
}>;
|
68
|
+
declare const getMockServer: (url?: string) => {
|
69
|
+
addDataHandler: <DataT extends object | undefined>(method: string, path: string, data?: DataT, subscriptionCallback?: Callback) => void;
|
70
|
+
addErrorHandler: (method: string, path: string, errorStr: string | null, errorCode: number, subscriptionCallback?: Callback) => void;
|
71
|
+
stop: () => void;
|
72
|
+
send: (data: object) => void;
|
73
|
+
url: string;
|
74
|
+
};
|
75
|
+
export { getMockServer, getSocket, getConnectedSocket, DEFAULT_CONNECT_PARAMS, DEFAULT_AUTH_RESPONSE };
|
@@ -0,0 +1,135 @@
|
|
1
|
+
import { Socket } from '../NodeSocket.js';
|
2
|
+
import { Server, WebSocket } from 'mock-socket';
|
3
|
+
import { jest } from '@jest/globals';
|
4
|
+
import ApiConstants from '../ApiConstants.js';
|
5
|
+
import { EventEmitter } from 'events';
|
6
|
+
import waitForExpectOriginal from 'wait-for-expect';
|
7
|
+
const EXCEPT_TIMEOUT = 1000;
|
8
|
+
//@ts-ignore
|
9
|
+
export const waitForExpect = (func) => waitForExpectOriginal.default(func, EXCEPT_TIMEOUT);
|
10
|
+
const VERBOSE = false;
|
11
|
+
const getMockConsole = () => ({
|
12
|
+
log: jest.fn((a1, a2, a3, a4) => {
|
13
|
+
if (VERBOSE) {
|
14
|
+
console.log(a1, a2, a3, a4);
|
15
|
+
}
|
16
|
+
}),
|
17
|
+
info: jest.fn((a1, a2, a3, a4) => {
|
18
|
+
if (VERBOSE) {
|
19
|
+
console.info(a1, a2, a3, a4);
|
20
|
+
}
|
21
|
+
}),
|
22
|
+
warn: jest.fn((a1, a2, a3, a4) => {
|
23
|
+
console.warn(a1, a2, a3, a4);
|
24
|
+
}),
|
25
|
+
error: jest.fn((a1, a2, a3, a4) => {
|
26
|
+
console.error(a1, a2, a3, a4);
|
27
|
+
}),
|
28
|
+
});
|
29
|
+
const DEFAULT_CONNECT_PARAMS = {
|
30
|
+
username: 'test',
|
31
|
+
password: 'test',
|
32
|
+
url: 'ws://localhost:7171/api/v1/',
|
33
|
+
};
|
34
|
+
const getDefaultSocketOptions = (mockConsole) => ({
|
35
|
+
...DEFAULT_CONNECT_PARAMS,
|
36
|
+
logOutput: mockConsole,
|
37
|
+
logLevel: VERBOSE ? 'verbose' : 'warn',
|
38
|
+
});
|
39
|
+
const DEFAULT_AUTH_RESPONSE = {
|
40
|
+
auth_token: 'b823187f-4aab-4b71-9764-e63e88401a26',
|
41
|
+
refresh_token: '5124faasf-4aab-4b71-9764-e63e88401a26',
|
42
|
+
user: {
|
43
|
+
permissions: ['admin'],
|
44
|
+
username: 'test',
|
45
|
+
active_sessions: 1,
|
46
|
+
last_login: 0,
|
47
|
+
},
|
48
|
+
system: {
|
49
|
+
cid: 'AHLUODI2YZ2U7FDWMHFNJU65ERGKUN4MH7GW5LY',
|
50
|
+
hostname: 'ubuntu-htpc',
|
51
|
+
network_type: 'private',
|
52
|
+
path_separator: '/',
|
53
|
+
platform: 'other',
|
54
|
+
language: 'fi',
|
55
|
+
},
|
56
|
+
wizard_pending: false,
|
57
|
+
};
|
58
|
+
const getSocket = (socketOptions = {}, mockConsole = getMockConsole()) => {
|
59
|
+
const socket = Socket({
|
60
|
+
...getDefaultSocketOptions(mockConsole),
|
61
|
+
...socketOptions,
|
62
|
+
}, WebSocket);
|
63
|
+
return { socket, mockConsole };
|
64
|
+
};
|
65
|
+
const getDefaultConnectOptions = () => ({
|
66
|
+
console: getMockConsole(),
|
67
|
+
authResponse: DEFAULT_AUTH_RESPONSE,
|
68
|
+
});
|
69
|
+
const getConnectedSocket = async (server, userOptions) => {
|
70
|
+
const options = {
|
71
|
+
...getDefaultConnectOptions(),
|
72
|
+
...userOptions,
|
73
|
+
};
|
74
|
+
server.addDataHandler('POST', ApiConstants.LOGIN_URL, options.authResponse, options.authCallback);
|
75
|
+
const { socket, mockConsole } = getSocket(options.socketOptions, options.console);
|
76
|
+
await socket.connect();
|
77
|
+
return { socket, mockConsole };
|
78
|
+
};
|
79
|
+
const toEmitId = (path, method) => {
|
80
|
+
return `${path}_${method}`;
|
81
|
+
};
|
82
|
+
const getMockServer = (url = DEFAULT_CONNECT_PARAMS.url) => {
|
83
|
+
const mockServer = new Server(url);
|
84
|
+
let socket;
|
85
|
+
const emitter = new EventEmitter();
|
86
|
+
const addServerHandler = (method, path, responseData, subscriptionCallback) => {
|
87
|
+
emitter.addListener(toEmitId(path, method), (request, s) => {
|
88
|
+
if (subscriptionCallback) {
|
89
|
+
subscriptionCallback(request);
|
90
|
+
}
|
91
|
+
const response = {
|
92
|
+
callback_id: request.callback_id,
|
93
|
+
...responseData,
|
94
|
+
};
|
95
|
+
s.send(JSON.stringify(response));
|
96
|
+
});
|
97
|
+
};
|
98
|
+
mockServer.on('connection', s => {
|
99
|
+
socket = s;
|
100
|
+
socket.on('message', (messageObj) => {
|
101
|
+
const request = JSON.parse(messageObj);
|
102
|
+
emitter.emit(toEmitId(request.path, request.method), request, s);
|
103
|
+
});
|
104
|
+
});
|
105
|
+
mockServer.on('close', () => {
|
106
|
+
emitter.removeAllListeners();
|
107
|
+
});
|
108
|
+
return {
|
109
|
+
addDataHandler: (method, path, data, subscriptionCallback) => {
|
110
|
+
addServerHandler(method, path, {
|
111
|
+
data,
|
112
|
+
code: 200,
|
113
|
+
}, subscriptionCallback);
|
114
|
+
},
|
115
|
+
addErrorHandler: (method, path, errorStr, errorCode, subscriptionCallback) => {
|
116
|
+
addServerHandler(method, path, {
|
117
|
+
error: !errorStr ? null : {
|
118
|
+
message: errorStr,
|
119
|
+
},
|
120
|
+
code: errorCode,
|
121
|
+
}, subscriptionCallback);
|
122
|
+
},
|
123
|
+
stop: () => {
|
124
|
+
mockServer.stop(() => {
|
125
|
+
// ...
|
126
|
+
});
|
127
|
+
},
|
128
|
+
send: (data) => {
|
129
|
+
socket.send(JSON.stringify(data));
|
130
|
+
},
|
131
|
+
url,
|
132
|
+
};
|
133
|
+
};
|
134
|
+
export { getMockServer, getSocket, getConnectedSocket, DEFAULT_CONNECT_PARAMS, DEFAULT_AUTH_RESPONSE };
|
135
|
+
//# sourceMappingURL=helpers.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tests/helpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "airdcpp-apisocket",
|
3
|
-
"version": "3.0.0-beta.
|
3
|
+
"version": "3.0.0-beta.5",
|
4
4
|
"description": "Javascript connector for AirDC++ Web API",
|
5
5
|
"license": "MIT",
|
6
6
|
"authors": [
|
@@ -42,7 +42,7 @@
|
|
42
42
|
"@babel/preset-env": "^7.20.2",
|
43
43
|
"@types/invariant": "^2.2.35",
|
44
44
|
"@types/jest": "^29.5.12",
|
45
|
-
"@types/node": "^
|
45
|
+
"@types/node": "^22.10.2",
|
46
46
|
"jest": "^29.7.0",
|
47
47
|
"jest-cli": "^29.7.0",
|
48
48
|
"jest-environment-node-debug": "^2.0.0",
|
@@ -57,6 +57,9 @@
|
|
57
57
|
"websocket": "^1.0.34"
|
58
58
|
},
|
59
59
|
"main": "./dist/NodeSocket.js",
|
60
|
-
"exports":
|
60
|
+
"exports": {
|
61
|
+
".": "./dist-es/NodeSocket.js",
|
62
|
+
"./tests/": "./dist-es/tests/"
|
63
|
+
},
|
61
64
|
"type": "module"
|
62
65
|
}
|
package/src/tests/Socket.test.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import {
|
2
|
-
|
2
|
+
DEFAULT_AUTH_RESPONSE, DEFAULT_CONNECT_PARAMS,
|
3
3
|
getConnectedSocket, getMockServer, getSocket, waitForExpect
|
4
4
|
} from './helpers.js';
|
5
5
|
|
@@ -29,15 +29,15 @@ describe('socket', () => {
|
|
29
29
|
|
30
30
|
describe('auth', () => {
|
31
31
|
test('should handle valid credentials', async () => {
|
32
|
-
server.addDataHandler('POST', ApiConstants.LOGIN_URL,
|
32
|
+
server.addDataHandler('POST', ApiConstants.LOGIN_URL, DEFAULT_AUTH_RESPONSE);
|
33
33
|
const connectedCallback = jest.fn();
|
34
34
|
|
35
35
|
const { socket, mockConsole } = getSocket();
|
36
36
|
socket.onConnected = connectedCallback;
|
37
37
|
const response = await socket.connect();
|
38
38
|
|
39
|
-
expect(connectedCallback).toHaveBeenCalledWith(
|
40
|
-
expect(response).toEqual(
|
39
|
+
expect(connectedCallback).toHaveBeenCalledWith(DEFAULT_AUTH_RESPONSE);
|
40
|
+
expect(response).toEqual(DEFAULT_AUTH_RESPONSE);
|
41
41
|
expect(socket.isConnected()).toEqual(true);
|
42
42
|
|
43
43
|
expect(mockConsole.warn.mock.calls.length).toBe(0);
|
@@ -48,15 +48,15 @@ describe('socket', () => {
|
|
48
48
|
});
|
49
49
|
|
50
50
|
test('should handle valid refresh token', async () => {
|
51
|
-
server.addDataHandler('POST', ApiConstants.LOGIN_URL,
|
51
|
+
server.addDataHandler('POST', ApiConstants.LOGIN_URL, DEFAULT_AUTH_RESPONSE);
|
52
52
|
const connectedCallback = jest.fn();
|
53
53
|
|
54
54
|
const { socket, mockConsole } = getSocket();
|
55
55
|
socket.onConnected = connectedCallback;
|
56
56
|
const response = await socket.connectRefreshToken('refresh token');
|
57
57
|
|
58
|
-
expect(connectedCallback).toHaveBeenCalledWith(
|
59
|
-
expect(response).toEqual(
|
58
|
+
expect(connectedCallback).toHaveBeenCalledWith(DEFAULT_AUTH_RESPONSE);
|
59
|
+
expect(response).toEqual(DEFAULT_AUTH_RESPONSE);
|
60
60
|
expect(socket.isConnected()).toEqual(true);
|
61
61
|
|
62
62
|
expect(mockConsole.warn.mock.calls.length).toBe(0);
|
@@ -96,7 +96,7 @@ describe('socket', () => {
|
|
96
96
|
// Fail without a server handler with auto reconnect disabled
|
97
97
|
let error;
|
98
98
|
try {
|
99
|
-
await socket.connect(
|
99
|
+
await socket.connect(DEFAULT_CONNECT_PARAMS.username, DEFAULT_CONNECT_PARAMS.password, false);
|
100
100
|
} catch (e) {
|
101
101
|
error = e;
|
102
102
|
}
|
@@ -106,9 +106,9 @@ describe('socket', () => {
|
|
106
106
|
|
107
107
|
// Valid connect attempt
|
108
108
|
server = getMockServer();
|
109
|
-
server.addDataHandler('POST', ApiConstants.LOGIN_URL,
|
109
|
+
server.addDataHandler('POST', ApiConstants.LOGIN_URL, DEFAULT_AUTH_RESPONSE);
|
110
110
|
|
111
|
-
await socket.connect(
|
111
|
+
await socket.connect(DEFAULT_CONNECT_PARAMS.username, DEFAULT_CONNECT_PARAMS.password, false);
|
112
112
|
|
113
113
|
expect(socket.isConnected()).toEqual(true);
|
114
114
|
|
@@ -285,7 +285,7 @@ describe('socket', () => {
|
|
285
285
|
server.addErrorHandler('POST', ApiConstants.CONNECT_URL, ErrorResponse, 400);
|
286
286
|
|
287
287
|
const authCallback = jest.fn();
|
288
|
-
server.addDataHandler('POST', ApiConstants.LOGIN_URL,
|
288
|
+
server.addDataHandler('POST', ApiConstants.LOGIN_URL, DEFAULT_AUTH_RESPONSE, authCallback);
|
289
289
|
|
290
290
|
jest.runOnlyPendingTimers();
|
291
291
|
socket.reconnect();
|
@@ -525,7 +525,9 @@ describe('socket', () => {
|
|
525
525
|
describe('logging', () => {
|
526
526
|
const connect = async (logLevel: string) => {
|
527
527
|
const { socket, mockConsole } = await getConnectedSocket(server, {
|
528
|
-
|
528
|
+
socketOptions: {
|
529
|
+
logLevel,
|
530
|
+
},
|
529
531
|
});
|
530
532
|
|
531
533
|
socket.disconnect(true);
|