airdcpp-apisocket 2.4.3 → 2.4.5-beta.1
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/CHANGELOG.md +4 -0
- package/GUIDE.md +16 -13
- package/babel.config.cjs +6 -0
- package/dist/NodeSocket.d.ts +3 -3
- package/dist/NodeSocket.js +9 -5
- package/dist/NodeSocket.js.map +1 -1
- package/dist/Promise.js +6 -6
- package/dist/Promise.js.map +1 -1
- package/dist/PublicHelpers.d.ts +1 -1
- package/dist/PublicHelpers.js +75 -168
- package/dist/PublicHelpers.js.map +1 -1
- package/dist/SocketBase.d.ts +2 -2
- package/dist/SocketBase.js +82 -98
- package/dist/SocketBase.js.map +1 -1
- package/dist/SocketLogger.d.ts +2 -2
- package/dist/SocketLogger.js +29 -35
- package/dist/SocketLogger.js.map +1 -1
- package/dist/SocketRequestHandler.d.ts +6 -6
- package/dist/SocketRequestHandler.js +56 -70
- package/dist/SocketRequestHandler.js.map +1 -1
- package/dist/SocketSubscriptionHandler.d.ts +5 -5
- package/dist/SocketSubscriptionHandler.js +58 -71
- package/dist/SocketSubscriptionHandler.js.map +1 -1
- package/dist/types/api.d.ts +3 -3
- package/dist/types/api_internal.d.ts +2 -2
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.js +12 -8
- package/dist/types/index.js.map +1 -1
- package/dist/types/options.d.ts +3 -3
- package/dist/types/public_helpers.d.ts +1 -1
- package/dist/types/public_helpers_internal.d.ts +2 -2
- package/dist/types/requests.d.ts +1 -1
- package/dist/types/socket.d.ts +7 -7
- package/dist/types/socket.js +0 -1
- package/dist/types/socket.js.map +1 -1
- package/dist/types/subscriptions.d.ts +11 -11
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/dist-es/NodeSocket.d.ts +3 -3
- package/dist-es/NodeSocket.js +3 -3
- package/dist-es/NodeSocket.js.map +1 -1
- package/dist-es/Promise.js +6 -6
- package/dist-es/Promise.js.map +1 -1
- package/dist-es/PublicHelpers.d.ts +1 -1
- package/dist-es/PublicHelpers.js +75 -168
- package/dist-es/PublicHelpers.js.map +1 -1
- package/dist-es/SocketBase.d.ts +2 -2
- package/dist-es/SocketBase.js +76 -92
- package/dist-es/SocketBase.js.map +1 -1
- package/dist-es/SocketLogger.d.ts +2 -2
- package/dist-es/SocketLogger.js +31 -37
- package/dist-es/SocketLogger.js.map +1 -1
- package/dist-es/SocketRequestHandler.d.ts +6 -6
- package/dist-es/SocketRequestHandler.js +51 -65
- package/dist-es/SocketRequestHandler.js.map +1 -1
- package/dist-es/SocketSubscriptionHandler.d.ts +5 -5
- package/dist-es/SocketSubscriptionHandler.js +54 -67
- package/dist-es/SocketSubscriptionHandler.js.map +1 -1
- package/dist-es/types/api.d.ts +3 -3
- package/dist-es/types/api_internal.d.ts +2 -2
- package/dist-es/types/index.d.ts +7 -7
- package/dist-es/types/index.js +7 -7
- package/dist-es/types/index.js.map +1 -1
- package/dist-es/types/options.d.ts +3 -3
- package/dist-es/types/public_helpers.d.ts +1 -1
- package/dist-es/types/public_helpers_internal.d.ts +2 -2
- package/dist-es/types/requests.d.ts +1 -1
- package/dist-es/types/socket.d.ts +7 -7
- package/dist-es/types/socket.js +0 -1
- package/dist-es/types/socket.js.map +1 -1
- package/dist-es/types/subscriptions.d.ts +11 -11
- package/dist-es/utils.d.ts +2 -2
- package/dist-es/utils.js +1 -1
- package/dist-es/utils.js.map +1 -1
- package/jest.config.js +18 -3
- package/package.json +16 -14
- package/src/NodeSocket.ts +3 -3
- package/src/PublicHelpers.ts +2 -2
- package/src/SocketBase.ts +9 -9
- package/src/SocketLogger.ts +5 -5
- package/src/SocketRequestHandler.ts +8 -8
- package/src/SocketSubscriptionHandler.ts +28 -18
- package/src/tests/Socket.test.ts +30 -22
- package/src/tests/helpers.ts +7 -6
- package/src/tests/public_helpers.test.ts +9 -8
- package/src/types/api_internal.ts +1 -1
- package/src/types/index.ts +7 -7
- package/src/types/public_helpers_internal.ts +1 -1
- package/src/types/requests.ts +1 -1
- package/src/types/socket.ts +4 -20
- package/src/types/subscriptions.ts +3 -3
- package/src/utils.ts +1 -1
- package/tsconfig.json +4 -8
- package/dist/tests/Socket.test.d.ts +0 -1
- package/dist/tests/Socket.test.js +0 -758
- package/dist/tests/Socket.test.js.map +0 -1
- package/dist/tests/helpers.d.ts +0 -57
- package/dist/tests/helpers.js +0 -178
- package/dist/tests/helpers.js.map +0 -1
- package/dist/tests/public_helpers.test.d.ts +0 -1
- package/dist/tests/public_helpers.test.js +0 -241
- package/dist/tests/public_helpers.test.js.map +0 -1
- package/dist-es/tests/Socket.test.d.ts +0 -1
- package/dist-es/tests/Socket.test.js +0 -734
- package/dist-es/tests/Socket.test.js.map +0 -1
- package/dist-es/tests/helpers.d.ts +0 -57
- package/dist-es/tests/helpers.js +0 -168
- package/dist-es/tests/helpers.js.map +0 -1
- package/dist-es/tests/public_helpers.test.d.ts +0 -1
- package/dist-es/tests/public_helpers.test.js +0 -236
- package/dist-es/tests/public_helpers.test.js.map +0 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ContextMenuItem } from './public_helpers';
|
1
|
+
import { ContextMenuItem } from './public_helpers.js';
|
2
2
|
export interface SelectedMenuItemListenerData<IdT, EntityIdT> {
|
3
3
|
hook_id: string;
|
4
4
|
menu_id: string;
|
@@ -19,7 +19,7 @@ export interface ResponseMenuItemCallbackFields {
|
|
19
19
|
urls?: string[] | undefined;
|
20
20
|
form_definitions?: object[] | undefined;
|
21
21
|
}
|
22
|
-
export
|
22
|
+
export type ResponseMenuItem<IdT, EntityIdT> = Omit<ContextMenuItem<IdT, EntityIdT>, 'onClick' | 'filter' | 'urls' | 'form_definitions'> & ResponseMenuItemCallbackFields;
|
23
23
|
export interface MenuItemListHookAcceptData<IdT, EntityIdT> {
|
24
24
|
menuitems: ResponseMenuItem<IdT, EntityIdT>[];
|
25
25
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import * as API from './api';
|
1
|
+
import * as API from './api.js';
|
2
2
|
export interface SocketRequestMethods {
|
3
3
|
put: <ResponseT extends object | void>(path: string, data?: object) => Promise<ResponseT>;
|
4
4
|
patch: <ResponseT extends object | void>(path: string, data?: object) => Promise<ResponseT>;
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { AuthTokenType, LogoutResponse, AuthenticationResponse } from './api';
|
2
|
-
import { Logger } from './logger';
|
3
|
-
import { SocketRequestMethods } from './requests';
|
4
|
-
import { SocketSubscriptions } from './subscriptions';
|
5
|
-
export
|
6
|
-
export
|
7
|
-
export
|
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
8
|
export interface APISocket extends SocketRequestMethods, SocketSubscriptions {
|
9
9
|
connect: (username?: string, password?: string, reconnectOnFailure?: boolean) => Promise<AuthenticationResponse>;
|
10
10
|
connectRefreshToken: (refreshToken: string, reconnectOnFailure?: boolean) => Promise<AuthenticationResponse>;
|
package/dist-es/types/socket.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../../src/types/socket.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../../src/types/socket.ts"],"names":[],"mappings":""}
|
@@ -1,20 +1,20 @@
|
|
1
|
-
import * as API from './api';
|
2
|
-
export
|
3
|
-
export
|
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
4
|
export interface HookSubscriberInfo {
|
5
5
|
id: string;
|
6
6
|
name: string;
|
7
7
|
}
|
8
|
-
export
|
9
|
-
export
|
10
|
-
export
|
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
11
|
export interface SocketSubscriptions {
|
12
|
-
addHook: <DataT extends object, CompletionDataT extends object | undefined>(
|
13
|
-
addListener: <DataT extends object | void, EntityIdT extends API.EntityId | undefined = undefined>(
|
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
14
|
addViewUpdateListener: <DataT extends object | void, EntityIdT extends API.EntityId | undefined = undefined>(viewName: string, callback: SubscriptionCallback<DataT, EntityIdT>, entityId?: API.EntityId) => () => void;
|
15
15
|
hasListeners: () => boolean;
|
16
16
|
getPendingSubscriptionCount: () => number;
|
17
17
|
}
|
18
|
-
export
|
19
|
-
export
|
20
|
-
export
|
18
|
+
export type AddHook = SocketSubscriptions['addHook'];
|
19
|
+
export type AddListener = SocketSubscriptions['addListener'];
|
20
|
+
export type AddViewUpdateListener = SocketSubscriptions['addViewUpdateListener'];
|
package/dist-es/utils.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import * as Options from './types/options';
|
2
|
-
export declare const eventIgnored: (path: string, ignoredEvents?: Options.IgnoreMatcher
|
1
|
+
import * as Options from './types/options.js';
|
2
|
+
export declare const eventIgnored: (path: string, ignoredEvents?: Options.IgnoreMatcher) => boolean;
|
package/dist-es/utils.js
CHANGED
package/dist-es/utils.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,
|
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;QAClB,OAAO,KAAK,CAAC;KACd;IAED,SAAS;IACT,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;QAChC,OAAO,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;KAC3C;IAED,SAAS;IACT,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC"}
|
package/jest.config.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
// import type { JestConfigWithTsJest } from 'ts-jest';
|
2
|
+
|
3
|
+
const jestConfig = {
|
2
4
|
preset: 'ts-jest',
|
3
5
|
testEnvironment: 'node',
|
4
6
|
coverageDirectory: './coverage/',
|
@@ -10,5 +12,18 @@ module.exports = {
|
|
10
12
|
collectCoverage: true,
|
11
13
|
roots: [
|
12
14
|
'<rootDir>/src/'
|
13
|
-
]
|
14
|
-
|
15
|
+
],
|
16
|
+
transformIgnorePatterns: [
|
17
|
+
'<rootDir>\/node_modules\/(?!chalk)\/'
|
18
|
+
],
|
19
|
+
moduleNameMapper: {
|
20
|
+
'^(\\.{1,2}/.*)\\.js$': '$1',
|
21
|
+
'#(.*)': '<rootDir>/node_modules/$1',
|
22
|
+
},
|
23
|
+
transform: {
|
24
|
+
'^.+\\.jsx?$': 'babel-jest',
|
25
|
+
'^.+\\.tsx?$': 'ts-jest'
|
26
|
+
},
|
27
|
+
};
|
28
|
+
|
29
|
+
export default jestConfig;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "airdcpp-apisocket",
|
3
|
-
"version": "2.4.
|
3
|
+
"version": "2.4.5-beta.1",
|
4
4
|
"description": "Javascript connector for AirDC++ Web API",
|
5
5
|
"license": "MIT",
|
6
6
|
"authors": [
|
@@ -33,29 +33,31 @@
|
|
33
33
|
"test"
|
34
34
|
],
|
35
35
|
"dependencies": {
|
36
|
-
"chalk": "^
|
36
|
+
"chalk": "^5.1.2",
|
37
37
|
"events": "^3.3.0",
|
38
38
|
"invariant": "^2.2.4",
|
39
39
|
"is-in-browser": "^2.0.0",
|
40
|
-
"promise": "^8.
|
40
|
+
"promise": "^8.3.0"
|
41
41
|
},
|
42
42
|
"devDependencies": {
|
43
|
-
"@
|
44
|
-
"@types/
|
45
|
-
"@types/
|
46
|
-
"
|
47
|
-
"jest
|
43
|
+
"@babel/preset-env": "^7.20.2",
|
44
|
+
"@types/invariant": "^2.2.35",
|
45
|
+
"@types/jest": "^28.1.1",
|
46
|
+
"@types/node": "^18.11.5",
|
47
|
+
"jest": "^28.1.3",
|
48
|
+
"jest-cli": "^28.1.3",
|
48
49
|
"jest-environment-node-debug": "^2.0.0",
|
49
|
-
"mock-socket": "^9.
|
50
|
-
"mockdate": "^3.0.5",
|
50
|
+
"mock-socket": "^9.1.5",
|
51
51
|
"pre-commit": "^1.2.2",
|
52
|
-
"rimraf": "^
|
53
|
-
"ts-jest": "^
|
52
|
+
"rimraf": "^4.1.2",
|
53
|
+
"ts-jest": "^28.0.8",
|
54
|
+
"ts-node": "^10.9.1",
|
54
55
|
"tslint": "^6.1.3",
|
55
|
-
"typescript": "^4.
|
56
|
+
"typescript": "^4.8.4",
|
56
57
|
"wait-for-expect": "^3.0.2",
|
57
58
|
"websocket": "^1.0.34"
|
58
59
|
},
|
59
60
|
"main": "./dist/NodeSocket.js",
|
60
|
-
"module": "./dist-es/NodeSocket.js"
|
61
|
+
"module": "./dist-es/NodeSocket.js",
|
62
|
+
"type": "module"
|
61
63
|
}
|
package/src/NodeSocket.ts
CHANGED
package/src/PublicHelpers.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
import { HookSubscriberInfo, APISocket, ContextMenuItem, EntityId } from './types';
|
1
|
+
import { HookSubscriberInfo, APISocket, ContextMenuItem, EntityId } from './types/index.js';
|
2
2
|
import {
|
3
3
|
SelectedMenuItemListenerData, MenuItemListHookData,
|
4
4
|
MenuItemListHookAcceptData, ResponseMenuItemCallbackFields
|
5
|
-
} from './types/public_helpers_internal';
|
5
|
+
} from './types/public_helpers_internal.js';
|
6
6
|
|
7
7
|
|
8
8
|
const checkAccess = <IdT, EntityIdT>(menuItem: ContextMenuItem<IdT, EntityIdT>, permissions: string[]): boolean => {
|
package/src/SocketBase.ts
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
import ApiConstants from './ApiConstants';
|
1
|
+
import ApiConstants from './ApiConstants.js';
|
2
2
|
|
3
|
-
import SocketLogger from './SocketLogger';
|
4
|
-
import SocketSubscriptionHandler from './SocketSubscriptionHandler';
|
5
|
-
import SocketRequestHandler from './SocketRequestHandler';
|
3
|
+
import SocketLogger from './SocketLogger.js';
|
4
|
+
import SocketSubscriptionHandler from './SocketSubscriptionHandler.js';
|
5
|
+
import SocketRequestHandler from './SocketRequestHandler.js';
|
6
6
|
|
7
7
|
import invariant from 'invariant';
|
8
|
-
import Promise from './Promise';
|
8
|
+
import Promise from './Promise.js';
|
9
9
|
|
10
|
-
import * as API from './types/api';
|
11
|
-
import * as Options from './types/options';
|
12
|
-
import * as Socket from './types/socket';
|
13
|
-
import * as Requests from './types/requests';
|
10
|
+
import * as API from './types/api.js';
|
11
|
+
import * as Options from './types/options.js';
|
12
|
+
import * as Socket from './types/socket.js';
|
13
|
+
import * as Requests from './types/requests.js';
|
14
14
|
|
15
15
|
|
16
16
|
// INTERNAL TYPES
|
package/src/SocketLogger.ts
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import chalk from 'chalk';
|
2
|
-
|
2
|
+
// @ts-ignore
|
3
|
+
import { isBrowser, isJsDom } from 'is-in-browser';
|
3
4
|
import invariant from 'invariant';
|
4
5
|
|
5
|
-
import * as Options from './types/options';
|
6
|
-
import { Logger } from './types/logger';
|
6
|
+
import * as Options from './types/options.js';
|
7
|
+
import { Logger } from './types/logger.js';
|
7
8
|
|
8
9
|
|
9
10
|
export const LOG_NONE = 'none';
|
@@ -23,8 +24,7 @@ const Severities = {
|
|
23
24
|
|
24
25
|
// Should we format the line with timestamp and coloring or let the logger implementation to handle it?
|
25
26
|
// Do this when running in terminal (node.js/tests in browser env)
|
26
|
-
const shouldFormatLine =
|
27
|
-
(!!global.process && !!global.process.env && global.process.env.NODE_ENV === 'test');
|
27
|
+
const shouldFormatLine = isJsDom || !isBrowser;
|
28
28
|
|
29
29
|
const Logger = ({ logLevel: logSetting = LOG_VERBOSE, logOutput = console }: Options.LoggerOptions) => {
|
30
30
|
const logLevel = Severities[logSetting];
|
@@ -1,15 +1,15 @@
|
|
1
1
|
import chalk from 'chalk';
|
2
2
|
import invariant from 'invariant';
|
3
|
-
import Promise, { PendingResult } from './Promise';
|
3
|
+
import Promise, { PendingResult } from './Promise.js';
|
4
4
|
|
5
|
-
import { eventIgnored } from './utils';
|
5
|
+
import { eventIgnored } from './utils.js';
|
6
6
|
|
7
|
-
import * as API from './types/api';
|
8
|
-
import * as APIInternal from './types/api_internal';
|
9
|
-
import * as Options from './types/options';
|
10
|
-
import * as Socket from './types/socket';
|
11
|
-
import { Logger } from './types/logger';
|
12
|
-
import { SocketRequestMethods, ErrorResponse } from './types/requests';
|
7
|
+
import * as API from './types/api.js';
|
8
|
+
import * as APIInternal from './types/api_internal.js';
|
9
|
+
import * as Options from './types/options.js';
|
10
|
+
import * as Socket from './types/socket.js';
|
11
|
+
import { Logger } from './types/logger.js';
|
12
|
+
import { SocketRequestMethods, ErrorResponse } from './types/requests.js';
|
13
13
|
|
14
14
|
|
15
15
|
interface Callback {
|
@@ -1,16 +1,16 @@
|
|
1
1
|
import invariant from 'invariant';
|
2
2
|
import { EventEmitter } from 'events';
|
3
3
|
|
4
|
-
import { eventIgnored } from './utils';
|
5
|
-
import Promise, { PendingResult } from './Promise';
|
4
|
+
import { eventIgnored } from './utils.js';
|
5
|
+
import Promise, { PendingResult } from './Promise.js';
|
6
6
|
|
7
|
-
import { Logger } from './types/logger';
|
8
|
-
import * as API from './types/api';
|
9
|
-
import * as APIInternal from './types/api_internal';
|
10
|
-
import * as Options from './types/options';
|
11
|
-
import * as Requests from './types/requests';
|
12
|
-
import * as Socket from './types/socket';
|
13
|
-
import * as Subscriptions from './types/subscriptions';
|
7
|
+
import { Logger } from './types/logger.js';
|
8
|
+
import * as API from './types/api.js';
|
9
|
+
import * as APIInternal from './types/api_internal.js';
|
10
|
+
import * as Options from './types/options.js';
|
11
|
+
import * as Requests from './types/requests.js';
|
12
|
+
import * as Socket from './types/socket.js';
|
13
|
+
import * as Subscriptions from './types/subscriptions.js';
|
14
14
|
|
15
15
|
|
16
16
|
interface PendingSubscription {
|
@@ -77,7 +77,7 @@ const SocketSubscriptionHandler = (
|
|
77
77
|
};
|
78
78
|
|
79
79
|
const handleHookAction = <DataT extends object, CompletionDataT extends object>(
|
80
|
-
|
80
|
+
subscriptionUrl: string,
|
81
81
|
callback: Subscriptions.HookCallback<DataT, CompletionDataT>,
|
82
82
|
data: DataT,
|
83
83
|
completionId: APIInternal.CompletionIdType
|
@@ -85,14 +85,14 @@ const SocketSubscriptionHandler = (
|
|
85
85
|
callback(
|
86
86
|
data,
|
87
87
|
completionData => {
|
88
|
-
socket().post(`${
|
89
|
-
.catch((error) => logger.error('Failed to complete hook action',
|
88
|
+
socket().post(`${subscriptionUrl}/${completionId}/resolve`, completionData)
|
89
|
+
.catch((error) => logger.error('Failed to complete hook action', subscriptionUrl, error));
|
90
90
|
},
|
91
91
|
(rejectId, rejectMessage) => {
|
92
|
-
socket().post(`${
|
92
|
+
socket().post(`${subscriptionUrl}/${completionId}/reject`, {
|
93
93
|
reject_id: rejectId,
|
94
94
|
message: rejectMessage,
|
95
|
-
}).catch(error => logger.error('Failed to complete failed hook action',
|
95
|
+
}).catch(error => logger.error('Failed to complete failed hook action', subscriptionUrl, error));
|
96
96
|
}
|
97
97
|
);
|
98
98
|
};
|
@@ -160,13 +160,18 @@ const SocketSubscriptionHandler = (
|
|
160
160
|
},
|
161
161
|
|
162
162
|
// Listen to a specific event and manage the API subscription automatically
|
163
|
-
addListener: (
|
163
|
+
addListener: (apiModule, event, callback, entityId) => {
|
164
164
|
if (!socket().isConnected()) {
|
165
165
|
throw 'Listeners can be added only for a connected socket';
|
166
166
|
}
|
167
|
+
|
168
|
+
invariant(
|
169
|
+
apiModule.indexOf('/') === -1,
|
170
|
+
'The first argument should only contain the API section without any path tokens (entity ID should be supplied separately)'
|
171
|
+
);
|
167
172
|
|
168
173
|
const subscriptionId = getEmitId(event, entityId);
|
169
|
-
const subscriptionUrl = getSubscriptionUrl(
|
174
|
+
const subscriptionUrl = getSubscriptionUrl(apiModule, entityId, event);
|
170
175
|
|
171
176
|
emitter.on(subscriptionId, callback);
|
172
177
|
return addPendingEntry(subscriptionUrl, subscriptionId, callback);
|
@@ -177,7 +182,7 @@ const SocketSubscriptionHandler = (
|
|
177
182
|
},
|
178
183
|
|
179
184
|
addHook: <DataT extends object, CompletionDataT extends object | undefined>(
|
180
|
-
|
185
|
+
apiModule: string,
|
181
186
|
event: string,
|
182
187
|
callback: Subscriptions.HookCallback<DataT, CompletionDataT>,
|
183
188
|
subscriberInfo: Subscriptions.HookSubscriberInfo
|
@@ -185,13 +190,18 @@ const SocketSubscriptionHandler = (
|
|
185
190
|
if (!socket().isConnected()) {
|
186
191
|
throw 'Hooks can be added only for a connected socket';
|
187
192
|
}
|
193
|
+
|
194
|
+
invariant(
|
195
|
+
apiModule.indexOf('/') === -1,
|
196
|
+
'The first argument should only contain the API section without any path tokens'
|
197
|
+
);
|
188
198
|
|
189
199
|
const subscriptionId = event;
|
190
200
|
if (subscriptions[subscriptionId] || pendingSubscriptions[subscriptionId]) {
|
191
201
|
throw 'Hook exists';
|
192
202
|
}
|
193
203
|
|
194
|
-
const subscriptionUrl = `${
|
204
|
+
const subscriptionUrl = `${apiModule}/hooks/${event}`;
|
195
205
|
|
196
206
|
callback = handleHookAction.bind(SocketSubscriptionHandler, subscriptionUrl, callback);
|
197
207
|
emitter.on(subscriptionId, callback);
|
package/src/tests/Socket.test.ts
CHANGED
@@ -1,22 +1,31 @@
|
|
1
1
|
import {
|
2
2
|
AUTH_RESPONSE, CONNECT_PARAMS,
|
3
3
|
getConnectedSocket, getMockServer, getSocket
|
4
|
-
} from './helpers';
|
4
|
+
} from './helpers.js';
|
5
5
|
|
6
|
-
import ApiConstants from '../ApiConstants';
|
6
|
+
import ApiConstants from '../ApiConstants.js';
|
7
7
|
|
8
|
-
import { HookCallback, HookSubscriberInfo } from '../types/subscriptions';
|
9
|
-
import { IncomingSubscriptionEvent } from '../types/api_internal';
|
8
|
+
import { HookCallback, HookSubscriberInfo } from '../types/subscriptions.js';
|
9
|
+
import { IncomingSubscriptionEvent } from '../types/api_internal.js';
|
10
10
|
|
11
|
-
import * as MockDate from 'mockdate';
|
12
11
|
import waitForExpectOriginal from 'wait-for-expect';
|
13
|
-
|
12
|
+
import { jest } from '@jest/globals';
|
14
13
|
|
15
14
|
let server: ReturnType<typeof getMockServer>;
|
16
15
|
|
17
16
|
const EXCEPT_TIMEOUT = 1000;
|
18
|
-
const waitForExpect = (func: () => void | Promise<void>) => waitForExpectOriginal(func, EXCEPT_TIMEOUT);
|
17
|
+
const waitForExpect = (func: () => void | Promise<void>) => waitForExpectOriginal.default(func, EXCEPT_TIMEOUT);
|
18
|
+
|
19
|
+
|
20
|
+
const dummyfn = () => {
|
21
|
+
// ..
|
22
|
+
};
|
19
23
|
|
24
|
+
const useFakeTimers = () => {
|
25
|
+
// Mocking performance would cause an error with Node 19, can be removed when using
|
26
|
+
// the latest version of Jest
|
27
|
+
jest.useFakeTimers({doNotFake: ['performance']});
|
28
|
+
};
|
20
29
|
|
21
30
|
// tslint:disable:no-empty
|
22
31
|
describe('socket', () => {
|
@@ -27,7 +36,6 @@ describe('socket', () => {
|
|
27
36
|
afterEach(() => {
|
28
37
|
server.stop();
|
29
38
|
jest.useRealTimers();
|
30
|
-
MockDate.reset();
|
31
39
|
});
|
32
40
|
|
33
41
|
describe('auth', () => {
|
@@ -129,10 +137,10 @@ describe('socket', () => {
|
|
129
137
|
|
130
138
|
// Dummy listener
|
131
139
|
server.addDataHandler('POST', 'hubs/listeners/hub_updated', undefined);
|
132
|
-
await socket.addListener('hubs', 'hub_updated',
|
140
|
+
await socket.addListener('hubs', 'hub_updated', dummyfn);
|
133
141
|
|
134
142
|
// Dummy pending request
|
135
|
-
socket.delete('dummyLogoutDelete').catch(error => {
|
143
|
+
socket.delete('dummyLogoutDelete').catch((error: Error) => {
|
136
144
|
// TODO: fix, too unreliable at the moment (depends on the timings)
|
137
145
|
//expect(error.message).toEqual('Socket disconnected');
|
138
146
|
});
|
@@ -190,7 +198,7 @@ describe('socket', () => {
|
|
190
198
|
test('should handle auto reconnect', async () => {
|
191
199
|
const { socket, mockConsole } = await getConnectedSocket(server);
|
192
200
|
|
193
|
-
|
201
|
+
useFakeTimers();
|
194
202
|
|
195
203
|
socket.disconnect(true);
|
196
204
|
jest.runOnlyPendingTimers();
|
@@ -231,7 +239,7 @@ describe('socket', () => {
|
|
231
239
|
test('should cancel auto reconnect', async () => {
|
232
240
|
const { socket, mockConsole } = await getConnectedSocket(server);
|
233
241
|
|
234
|
-
|
242
|
+
useFakeTimers();
|
235
243
|
|
236
244
|
// Disconnect with auto reconnect
|
237
245
|
socket.disconnect(true);
|
@@ -278,7 +286,7 @@ describe('socket', () => {
|
|
278
286
|
// Connect and disconnect
|
279
287
|
const { socket, mockConsole } = await getConnectedSocket(server);
|
280
288
|
|
281
|
-
|
289
|
+
useFakeTimers();
|
282
290
|
socket.disconnect();
|
283
291
|
jest.runOnlyPendingTimers();
|
284
292
|
expect(socket.isActive()).toEqual(false);
|
@@ -294,7 +302,7 @@ describe('socket', () => {
|
|
294
302
|
socket.reconnect();
|
295
303
|
|
296
304
|
{
|
297
|
-
const waitForExpectTask = waitForExpectOriginal(
|
305
|
+
const waitForExpectTask = waitForExpectOriginal.default(
|
298
306
|
() => {
|
299
307
|
jest.runOnlyPendingTimers();
|
300
308
|
expect(authCallback.mock.calls.length).toBe(1);
|
@@ -331,15 +339,15 @@ describe('socket', () => {
|
|
331
339
|
test('should report request timeouts', async () => {
|
332
340
|
const { socket, mockConsole } = await getConnectedSocket(server);
|
333
341
|
|
334
|
-
|
335
|
-
socket.addListener('hubs', 'hub_updated',
|
342
|
+
useFakeTimers();
|
343
|
+
socket.addListener('hubs', 'hub_updated', dummyfn)
|
336
344
|
.catch(() => {});
|
337
|
-
socket.addListener('hubs', 'hub_added',
|
345
|
+
socket.addListener('hubs', 'hub_added', dummyfn)
|
338
346
|
.catch(() => {});
|
339
347
|
|
340
348
|
jest.advanceTimersByTime(35000);
|
341
349
|
|
342
|
-
|
350
|
+
jest.setSystemTime(new Date(Date.now() + 35000));
|
343
351
|
(socket as any).reportRequestTimeouts();
|
344
352
|
|
345
353
|
expect(mockConsole.warn.mock.calls.length).toBe(2);
|
@@ -422,8 +430,8 @@ describe('socket', () => {
|
|
422
430
|
server.addDataHandler('POST', 'hubs/listeners/hub_updated', undefined, subscribeCallback);
|
423
431
|
|
424
432
|
// Add two simultaneous pending add events
|
425
|
-
const p1 = socket.addListener('hubs', 'hub_updated',
|
426
|
-
const p2 = socket.addListener('hubs', 'hub_updated',
|
433
|
+
const p1 = socket.addListener('hubs', 'hub_updated', dummyfn);
|
434
|
+
const p2 = socket.addListener('hubs', 'hub_updated', dummyfn);
|
427
435
|
|
428
436
|
expect(socket.hasListeners()).toBe(false);
|
429
437
|
expect(socket.getPendingSubscriptionCount()).toBe(1);
|
@@ -500,7 +508,7 @@ describe('socket', () => {
|
|
500
508
|
hookSubscriberInfo
|
501
509
|
);
|
502
510
|
|
503
|
-
expect(hookAddCallback.mock.calls[0][0].data).toEqual(hookSubscriberInfo);
|
511
|
+
expect((hookAddCallback.mock.calls[0][0] as any).data).toEqual(hookSubscriberInfo);
|
504
512
|
expect(hookAddCallback.mock.calls.length).toBe(1);
|
505
513
|
}
|
506
514
|
|
@@ -532,7 +540,7 @@ describe('socket', () => {
|
|
532
540
|
});
|
533
541
|
|
534
542
|
socket.disconnect(true);
|
535
|
-
await socket.delete('dummyLogDeleteWarning').catch(error => {
|
543
|
+
await socket.delete('dummyLogDeleteWarning').catch((error: Error) => {
|
536
544
|
//...
|
537
545
|
});
|
538
546
|
|
package/src/tests/helpers.ts
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
import { Socket } from '../NodeSocket';
|
2
|
-
import {
|
1
|
+
import { Socket } from '../NodeSocket.js';
|
2
|
+
import { Client, Server, WebSocket } from 'mock-socket';
|
3
|
+
import { jest } from '@jest/globals';
|
3
4
|
|
4
|
-
import { OutgoingRequest, RequestSuccessResponse, RequestErrorResponse } from '../types/api_internal';
|
5
|
-
import * as Options from '../types/options';
|
6
|
-
import ApiConstants from '../ApiConstants';
|
5
|
+
import { OutgoingRequest, RequestSuccessResponse, RequestErrorResponse } from '../types/api_internal.js';
|
6
|
+
import * as Options from '../types/options.js';
|
7
|
+
import ApiConstants from '../ApiConstants.js';
|
7
8
|
import { EventEmitter } from 'events';
|
8
9
|
|
9
10
|
|
@@ -101,7 +102,7 @@ const toEmitId = (path: string, method: string) => {
|
|
101
102
|
|
102
103
|
const getMockServer = () => {
|
103
104
|
const mockServer = new Server(CONNECT_PARAMS.url);
|
104
|
-
let socket:
|
105
|
+
let socket: Client;
|
105
106
|
const emitter = new EventEmitter();
|
106
107
|
|
107
108
|
const addServerHandler = <DataT extends object | undefined>(
|
@@ -1,14 +1,15 @@
|
|
1
1
|
import {
|
2
2
|
getMockServer,
|
3
3
|
getConnectedSocket,
|
4
|
-
} from './helpers';
|
4
|
+
} from './helpers.js';
|
5
5
|
|
6
6
|
import waitForExpect from 'wait-for-expect';
|
7
|
+
import { jest } from '@jest/globals';
|
7
8
|
|
8
|
-
import { addContextMenuItems } from '../PublicHelpers';
|
9
|
-
import { SelectedMenuItemListenerData, MenuItemListHookData, MenuItemListHookAcceptData } from '../types/public_helpers_internal';
|
10
|
-
import { HookSubscriberInfo } from '../types';
|
11
|
-
import { IncomingSubscriptionEvent } from '../types/api_internal';
|
9
|
+
import { addContextMenuItems } from '../PublicHelpers.js';
|
10
|
+
import { SelectedMenuItemListenerData, MenuItemListHookData, MenuItemListHookAcceptData } from '../types/public_helpers_internal.js';
|
11
|
+
import { HookSubscriberInfo } from '../types/index.js';
|
12
|
+
import { IncomingSubscriptionEvent } from '../types/api_internal.js';
|
12
13
|
|
13
14
|
|
14
15
|
let server: ReturnType<typeof getMockServer>;
|
@@ -187,7 +188,7 @@ describe('public helpers', () => {
|
|
187
188
|
|
188
189
|
// Validate list items results
|
189
190
|
{
|
190
|
-
await waitForExpect(() => {
|
191
|
+
await waitForExpect.default(() => {
|
191
192
|
expect(hookResolveCallback).toHaveBeenCalledTimes(1);
|
192
193
|
});
|
193
194
|
|
@@ -197,7 +198,7 @@ describe('public helpers', () => {
|
|
197
198
|
}),
|
198
199
|
);
|
199
200
|
|
200
|
-
await waitForExpect(() => {
|
201
|
+
await waitForExpect.default(() => {
|
201
202
|
expect(onGetUrlsItem3Mock).toHaveBeenCalledTimes(1);
|
202
203
|
});
|
203
204
|
expect(onGetUrlsItem3Mock).toHaveBeenCalledWith(selectedMenuIds, null, PERMISSIONS, SUPPORTS);
|
@@ -225,7 +226,7 @@ describe('public helpers', () => {
|
|
225
226
|
|
226
227
|
// Validate select event results
|
227
228
|
{
|
228
|
-
await waitForExpect(() => {
|
229
|
+
await waitForExpect.default(() => {
|
229
230
|
expect(onClickItem1Mock).toHaveBeenCalledTimes(1);
|
230
231
|
});
|
231
232
|
expect(onClickItem1Mock).toHaveBeenCalledWith(selectedMenuIds, null, PERMISSIONS, SUPPORTS, FORM_VALUES);
|
package/src/types/index.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
export * from './api';
|
1
|
+
export * from './api.js';
|
2
2
|
|
3
|
-
export * from './logger';
|
4
|
-
export * from './requests';
|
5
|
-
export * from './subscriptions';
|
3
|
+
export * from './logger.js';
|
4
|
+
export * from './requests.js';
|
5
|
+
export * from './subscriptions.js';
|
6
6
|
|
7
|
-
export * from './socket';
|
8
|
-
export * from './options';
|
7
|
+
export * from './socket.js';
|
8
|
+
export * from './options.js';
|
9
9
|
|
10
|
-
export * from './public_helpers';
|
10
|
+
export * from './public_helpers.js';
|