@awarevue/agent-sdk 2.0.73 → 2.0.75
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/agent-app-with-defaults.d.ts +16 -0
- package/dist/agent-app-with-defaults.js +22 -0
- package/dist/agent-app.js +30 -23
- package/dist/agent-error.d.ts +4 -0
- package/dist/agent-error.js +7 -1
- package/dist/agent-protocol.d.ts +1 -1
- package/dist/agent-protocol.js +13 -6
- package/dist/default-validator.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/package.json +3 -3
- package/dist/transports/logging.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FromAgent, FromServer, Message } from '@awarevue/api-types';
|
|
2
|
+
import { Agent } from './agent';
|
|
3
|
+
import { AgentApp, AgentOptions } from './agent-app';
|
|
4
|
+
import { DuplexTransport } from './transport_types';
|
|
5
|
+
export type AgentAppWithDefaultsOptions = Omit<AgentOptions, 'transport'> & {
|
|
6
|
+
url: string;
|
|
7
|
+
apiKey: string;
|
|
8
|
+
transport?: DuplexTransport<Message<FromServer>, Message<FromAgent>>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Creates an AgentApp instance with default transport settings (WS transport wrapped in a logging decorator) if no custom transport is provided.
|
|
12
|
+
* @param agent The agent instance to use.
|
|
13
|
+
* @param options Configuration options for the AgentApp.
|
|
14
|
+
* @returns A configured AgentApp instance.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createAgentApp(agent: Agent, options: AgentAppWithDefaultsOptions): AgentApp;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAgentApp = createAgentApp;
|
|
4
|
+
const agent_app_1 = require("./agent-app");
|
|
5
|
+
const logging_1 = require("./transports/logging");
|
|
6
|
+
const ws_1 = require("./transports/ws");
|
|
7
|
+
/**
|
|
8
|
+
* Creates an AgentApp instance with default transport settings (WS transport wrapped in a logging decorator) if no custom transport is provided.
|
|
9
|
+
* @param agent The agent instance to use.
|
|
10
|
+
* @param options Configuration options for the AgentApp.
|
|
11
|
+
* @returns A configured AgentApp instance.
|
|
12
|
+
*/
|
|
13
|
+
function createAgentApp(agent, options) {
|
|
14
|
+
const { url, apiKey, transport, ...rest } = options;
|
|
15
|
+
const finalTransport = transport !== null && transport !== void 0 ? transport : new logging_1.LoggingDuplexTransport(new ws_1.WsDuplexTransport({
|
|
16
|
+
url,
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `APIKey ${apiKey}`,
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
21
|
+
return new agent_app_1.AgentApp(agent, { ...rest, transport: finalTransport });
|
|
22
|
+
}
|
package/dist/agent-app.js
CHANGED
|
@@ -11,7 +11,15 @@ class AgentApp {
|
|
|
11
11
|
this.agent = agent;
|
|
12
12
|
this.options = options;
|
|
13
13
|
this.sub = null;
|
|
14
|
-
this.handleResponse$ = (requestId) => (obs) => obs.pipe((0, rxjs_1.
|
|
14
|
+
this.handleResponse$ = (requestId, responseBuilder) => (obs) => obs.pipe((0, rxjs_1.mergeMap)((result) => result instanceof agent_error_1.AgentProgressMessage
|
|
15
|
+
? (0, rxjs_1.of)({
|
|
16
|
+
kind: 'progress',
|
|
17
|
+
requestId,
|
|
18
|
+
message: result.message,
|
|
19
|
+
})
|
|
20
|
+
: responseBuilder
|
|
21
|
+
? (0, rxjs_1.of)(responseBuilder(result))
|
|
22
|
+
: rxjs_1.EMPTY), (0, rxjs_1.tap)({
|
|
15
23
|
error: (error) => console.error('Error processing request', requestId, (0, utils_1.stringifyError)(error)),
|
|
16
24
|
}), (0, rxjs_1.catchError)((error) => (0, rxjs_1.of)({
|
|
17
25
|
kind: 'error-rs',
|
|
@@ -63,25 +71,28 @@ class AgentApp {
|
|
|
63
71
|
case 'command':
|
|
64
72
|
return this.agent.runCommand$(context, message).pipe(
|
|
65
73
|
// if command observable completes without emitting, throw not supported error
|
|
66
|
-
(0, rxjs_1.throwIfEmpty)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support command ${message.command}`, 'NOT_SUPPORTED')),
|
|
67
|
-
// success
|
|
68
|
-
(0, rxjs_1.map)(() => ({
|
|
74
|
+
(0, rxjs_1.throwIfEmpty)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support command ${message.command}`, 'NOT_SUPPORTED')), this.handleResponse$(message.id, (result) => ({
|
|
69
75
|
kind: 'command-rs',
|
|
70
76
|
requestId: message.id,
|
|
71
|
-
|
|
77
|
+
result,
|
|
78
|
+
})));
|
|
72
79
|
case 'query':
|
|
73
80
|
if (!this.agent.getResult$) {
|
|
74
|
-
return (0, rxjs_1.throwError)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support queries`, 'NOT_SUPPORTED')).pipe(this.handleResponse$(message.id)
|
|
81
|
+
return (0, rxjs_1.throwError)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support queries`, 'NOT_SUPPORTED')).pipe(this.handleResponse$(message.id, (result) => ({
|
|
82
|
+
kind: 'query-rs',
|
|
83
|
+
requestId: message.id,
|
|
84
|
+
result,
|
|
85
|
+
})));
|
|
75
86
|
}
|
|
76
87
|
return this.agent.getResult$(context, message).pipe(
|
|
77
88
|
// if query observable completes without emitting, throw not supported error
|
|
78
89
|
(0, rxjs_1.throwIfEmpty)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support query ${message.query}`, 'NOT_SUPPORTED')),
|
|
79
90
|
// success
|
|
80
|
-
(
|
|
91
|
+
this.handleResponse$(message.id, (result) => ({
|
|
81
92
|
kind: 'query-rs',
|
|
82
93
|
requestId: message.id,
|
|
83
94
|
result,
|
|
84
|
-
}))
|
|
95
|
+
})));
|
|
85
96
|
case 'push-file':
|
|
86
97
|
if (!this.agent.pushFile) {
|
|
87
98
|
return (0, rxjs_1.throwError)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support file pushing`, 'NOT_SUPPORTED'));
|
|
@@ -91,13 +102,11 @@ class AgentApp {
|
|
|
91
102
|
(0, rxjs_1.mergeMap)(() => rxjs_1.EMPTY), this.handleResponse$(message.id));
|
|
92
103
|
case 'get-available-devices':
|
|
93
104
|
// get available devices
|
|
94
|
-
return this.agent.getDevicesAndRelations$(context).pipe(
|
|
95
|
-
|
|
96
|
-
(0, rxjs_1.map)((rs) => ({
|
|
105
|
+
return this.agent.getDevicesAndRelations$(context).pipe(this.handleResponse$(message.id, (result) => ({
|
|
106
|
+
...result,
|
|
97
107
|
kind: 'get-available-devices-rs',
|
|
98
|
-
...rs,
|
|
99
108
|
requestId: message.id,
|
|
100
|
-
}))
|
|
109
|
+
})));
|
|
101
110
|
case 'validate-change':
|
|
102
111
|
let validateOb$ = (0, rxjs_1.throwError)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support access change validation`, 'NOT_SUPPORTED'));
|
|
103
112
|
if (this.agent.validateAccessChange$) {
|
|
@@ -111,22 +120,22 @@ class AgentApp {
|
|
|
111
120
|
: v$(validationContext, message);
|
|
112
121
|
}));
|
|
113
122
|
}
|
|
114
|
-
return validateOb$.pipe((
|
|
123
|
+
return validateOb$.pipe(this.handleResponse$(message.id, (result) => ({
|
|
115
124
|
kind: 'validate-change-rs',
|
|
116
125
|
requestId: message.id,
|
|
117
|
-
issues,
|
|
118
|
-
}))
|
|
126
|
+
issues: result,
|
|
127
|
+
})));
|
|
119
128
|
case 'apply-change':
|
|
120
129
|
// apply access change
|
|
121
130
|
const applyContext = this.createAccessChangeContext(context, message.refMap, objectCache);
|
|
122
131
|
const applyOb$ = !this.agent.applyAccessChange$
|
|
123
132
|
? (0, rxjs_1.throwError)(() => new agent_error_1.AgentError(`Agent ${context.provider} does not support access change apply`, 'NOT_SUPPORTED'))
|
|
124
133
|
: this.agent.applyAccessChange$(applyContext, message);
|
|
125
|
-
return applyOb$.pipe((
|
|
134
|
+
return applyOb$.pipe(this.handleResponse$(message.id, (result) => ({
|
|
126
135
|
kind: 'apply-change-rs',
|
|
127
136
|
requestId: message.id,
|
|
128
137
|
refs: result,
|
|
129
|
-
}))
|
|
138
|
+
})));
|
|
130
139
|
default:
|
|
131
140
|
return rxjs_1.EMPTY;
|
|
132
141
|
}
|
|
@@ -170,13 +179,11 @@ class AgentApp {
|
|
|
170
179
|
provider,
|
|
171
180
|
config,
|
|
172
181
|
})
|
|
173
|
-
.pipe(
|
|
174
|
-
// success
|
|
175
|
-
(0, rxjs_1.map)((issues) => ({
|
|
182
|
+
.pipe(this.handleResponse$(message.id, (result) => ({
|
|
176
183
|
kind: 'validate-config-rs',
|
|
177
184
|
requestId: message.id,
|
|
178
|
-
issues,
|
|
179
|
-
}))
|
|
185
|
+
issues: result,
|
|
186
|
+
})));
|
|
180
187
|
}));
|
|
181
188
|
return (0, rxjs_1.merge)(registration$, startStop$, validateConfig$);
|
|
182
189
|
};
|
package/dist/agent-error.d.ts
CHANGED
package/dist/agent-error.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AgentError = void 0;
|
|
3
|
+
exports.AgentProgressMessage = exports.AgentError = void 0;
|
|
4
4
|
class AgentError extends Error {
|
|
5
5
|
constructor(message, code) {
|
|
6
6
|
super(message);
|
|
@@ -9,3 +9,9 @@ class AgentError extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
exports.AgentError = AgentError;
|
|
12
|
+
class AgentProgressMessage {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
this.message = message;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.AgentProgressMessage = AgentProgressMessage;
|
package/dist/agent-protocol.d.ts
CHANGED
|
@@ -27,6 +27,6 @@ export declare class AgentProtocol<D extends Direction> {
|
|
|
27
27
|
constructor(transport: DuplexTransport<Message<Inbound<D>>, Message<Outbound<D>>>, options: AgentProtocolOptions);
|
|
28
28
|
getReply$: <K extends RequestKind>(payload: Extract<Outbound<D>, {
|
|
29
29
|
kind: K;
|
|
30
|
-
}
|
|
30
|
+
}>, timeoutMs?: number) => Observable<Message<PayloadByKind[ResponseKind<K>]>>;
|
|
31
31
|
send: (payload: Outbound<D>) => void;
|
|
32
32
|
}
|
package/dist/agent-protocol.js
CHANGED
|
@@ -15,17 +15,24 @@ class AgentProtocol {
|
|
|
15
15
|
version: constants_1.AGENT_PROTOCOL_VERSION,
|
|
16
16
|
on: Date.now(),
|
|
17
17
|
});
|
|
18
|
-
this.getReply$ = (payload) => {
|
|
18
|
+
this.getReply$ = (payload, timeoutMs) => {
|
|
19
19
|
const responseKind = api_types_1.ReplyKindByRequestKind[payload.kind];
|
|
20
|
-
const reply$ = (id) => this.transport.messages$.pipe(
|
|
21
|
-
|
|
20
|
+
const reply$ = (id) => this.transport.messages$.pipe(
|
|
21
|
+
// pass through only messages with matching requestId (it could be response, error or progress update)
|
|
22
|
+
(0, rxjs_1.filter)((message) => 'requestId' in message && message.requestId === id), (0, rxjs_1.mergeMap)((message) => {
|
|
23
|
+
// if the agent responded with an error message related to our request, throw an error to fail the stream
|
|
24
|
+
if (message.kind === 'error-rs') {
|
|
22
25
|
const error = message.error;
|
|
23
26
|
return (0, rxjs_1.throwError)(() => new Error(`Server failed to process message ${payload.kind}: ${error}`));
|
|
24
27
|
}
|
|
25
28
|
return (0, rxjs_1.of)(message);
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
}),
|
|
30
|
+
// enforce timeout (progress updates will reset the timer, but if no messages arrive for `timeoutMs` duration, the request is considered failed)
|
|
31
|
+
(0, rxjs_1.timeout)(timeoutMs || this.options.replyTimeout || 10000),
|
|
32
|
+
// pass through only the final response message (filter out progress updates)
|
|
33
|
+
(0, rxjs_1.filter)((message) => message.kind === responseKind),
|
|
34
|
+
// we only expect one response message, so complete the stream after the response arrives
|
|
35
|
+
(0, rxjs_1.take)(1));
|
|
29
36
|
return (0, rxjs_1.of)(this.addEnvelope({ ...payload, id: AgentProtocol.nextId() })).pipe(
|
|
30
37
|
// send the message to the agent
|
|
31
38
|
(0, rxjs_1.tap)((p) => this.transport.send(p)),
|
|
@@ -7,4 +7,4 @@ export declare const createValidator: <T extends Agent>(agent: T) => (context: C
|
|
|
7
7
|
objectKind?: "person" | "zone" | "schedule" | "device" | "accessRule" | undefined;
|
|
8
8
|
objectId?: string | undefined;
|
|
9
9
|
index?: number | undefined;
|
|
10
|
-
}[], Record<"accessRule" | "schedule" | "person" | "
|
|
10
|
+
}[], Record<"accessRule" | "schedule" | "person" | "zone" | "device", Record<string, Record<string, unknown>>>]>;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./agent-app"), exports);
|
|
18
|
+
__exportStar(require("./agent-app-with-defaults"), exports);
|
|
18
19
|
__exportStar(require("./agent"), exports);
|
|
19
20
|
__exportStar(require("./constants"), exports);
|
|
20
21
|
__exportStar(require("./agent-protocol"), exports);
|
package/dist/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "git+https://github.com/Linc-Security-Systems/aware-essentials.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "2.0.
|
|
7
|
+
"version": "2.0.75",
|
|
8
8
|
"description": "SDK for building Agent implementations that speak the agent protocol.",
|
|
9
9
|
"author": "Yaser Awajan",
|
|
10
10
|
"license": "MIT",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"lint:fix": "yarn lint --fix"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@awarevue/api-types": "2.0.
|
|
34
|
+
"@awarevue/api-types": "2.0.75",
|
|
35
35
|
"rxjs": "^7.8.2",
|
|
36
36
|
"ws": "^8"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@awarevue/api-types": "2.0.
|
|
39
|
+
"@awarevue/api-types": "2.0.75",
|
|
40
40
|
"@types/node": "^20.12.7",
|
|
41
41
|
"@types/ws": "^8.18.1",
|
|
42
42
|
"@typescript-eslint/eslint-plugin": "^8.31.1",
|
|
@@ -16,7 +16,7 @@ class LoggingDuplexTransport {
|
|
|
16
16
|
this.inner = inner;
|
|
17
17
|
this.label = (_a = opts.label) !== null && _a !== void 0 ? _a : 'transport';
|
|
18
18
|
this.sink =
|
|
19
|
-
(_b = opts.logger) !== null && _b !== void 0 ? _b : ((direction, label, msg) => console.log(`[${label}] ${direction}`, JSON.stringify(msg
|
|
19
|
+
(_b = opts.logger) !== null && _b !== void 0 ? _b : ((direction, label, msg) => console.log(`[${label}] ${direction}`, JSON.stringify(msg)));
|
|
20
20
|
this.connected$ = inner.connected$;
|
|
21
21
|
// Tap into the incoming stream before exposing it to consumers.
|
|
22
22
|
this.messages$ = inner.messages$.pipe((0, operators_1.tap)((msg) => this.sink('IN', this.label, msg)));
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "git+https://github.com/Linc-Security-Systems/aware-essentials.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "2.0.
|
|
7
|
+
"version": "2.0.75",
|
|
8
8
|
"description": "SDK for building Agent implementations that speak the agent protocol.",
|
|
9
9
|
"author": "Yaser Awajan",
|
|
10
10
|
"license": "MIT",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"lint:fix": "yarn lint --fix"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@awarevue/api-types": "2.0.
|
|
34
|
+
"@awarevue/api-types": "2.0.75",
|
|
35
35
|
"rxjs": "^7.8.2",
|
|
36
36
|
"ws": "^8"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@awarevue/api-types": "2.0.
|
|
39
|
+
"@awarevue/api-types": "2.0.75",
|
|
40
40
|
"@types/node": "^20.12.7",
|
|
41
41
|
"@types/ws": "^8.18.1",
|
|
42
42
|
"@typescript-eslint/eslint-plugin": "^8.31.1",
|