@awarevue/agent-sdk 1.0.30 → 1.0.31
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.d.ts +1 -0
- package/dist/agent-app.js +36 -2
- package/dist/agent.d.ts +4 -1
- package/dist/default-validator.d.ts +10 -0
- package/dist/default-validator.js +128 -0
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/agent-app.d.ts
CHANGED
package/dist/agent-app.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentApp = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
|
+
const default_validator_1 = require("./default-validator");
|
|
5
6
|
class AgentApp {
|
|
6
7
|
constructor(agent, options) {
|
|
7
8
|
this.agent = agent;
|
|
@@ -31,7 +32,32 @@ class AgentApp {
|
|
|
31
32
|
version: this.options.version,
|
|
32
33
|
on: Date.now(),
|
|
33
34
|
});
|
|
35
|
+
this.createAccessChangeContext = (context, refMap, objectCache) => {
|
|
36
|
+
return {
|
|
37
|
+
...context,
|
|
38
|
+
objectsById: (objectKind, objectId) => {
|
|
39
|
+
const objectKindRefs = refMap[objectKind] || {};
|
|
40
|
+
const refs = objectKindRefs[objectId] || [];
|
|
41
|
+
return refs.flatMap((foreignRef) => {
|
|
42
|
+
const value = objectCache[objectKind][foreignRef];
|
|
43
|
+
return value ? [value] : [];
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
objectByForeignRef: (objectKind, foreignRef) => {
|
|
47
|
+
return objectCache[objectKind][foreignRef] || null;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
};
|
|
34
51
|
this.runProvider$ = (context) => {
|
|
52
|
+
const changeValidator$ = (0, default_validator_1.createValidator)(this.agent);
|
|
53
|
+
// we assume that there will be only one validate-apply cycle per agent at the same time
|
|
54
|
+
let objectCache = {
|
|
55
|
+
person: {},
|
|
56
|
+
accessRule: {},
|
|
57
|
+
schedule: {},
|
|
58
|
+
device: {},
|
|
59
|
+
zone: {},
|
|
60
|
+
};
|
|
35
61
|
return (0, rxjs_1.merge)(
|
|
36
62
|
// run the agent monitor
|
|
37
63
|
this.agent
|
|
@@ -81,7 +107,14 @@ class AgentApp {
|
|
|
81
107
|
// validate access change
|
|
82
108
|
const validateOb$ = !this.agent.validateAccessChange$
|
|
83
109
|
? (0, rxjs_1.throwError)(() => new Error(`Agent ${context.provider} does not support access change validation`))
|
|
84
|
-
:
|
|
110
|
+
: changeValidator$(context, message).pipe((0, rxjs_1.mergeMap)(([issues, cache]) => {
|
|
111
|
+
objectCache = cache;
|
|
112
|
+
const validationContext = this.createAccessChangeContext(context, message.refMap, objectCache);
|
|
113
|
+
return issues.length > 0
|
|
114
|
+
? (0, rxjs_1.of)(issues)
|
|
115
|
+
: this.agent.validateAccessChange$(validationContext, message);
|
|
116
|
+
return (0, rxjs_1.of)(issues);
|
|
117
|
+
}));
|
|
85
118
|
return validateOb$.pipe((0, rxjs_1.map)((issues) => ({
|
|
86
119
|
kind: 'validate-change-rs',
|
|
87
120
|
requestId: message.id,
|
|
@@ -96,9 +129,10 @@ class AgentApp {
|
|
|
96
129
|
}), (0, rxjs_1.tap)((rs) => this.options.transport.send(this.addEnvelope(rs))));
|
|
97
130
|
case 'apply-change':
|
|
98
131
|
// apply access change
|
|
132
|
+
const applyContext = this.createAccessChangeContext(context, message.refMap, objectCache);
|
|
99
133
|
const applyOb$ = !this.agent.applyAccessChange$
|
|
100
134
|
? (0, rxjs_1.throwError)(() => new Error(`Agent ${context.provider} does not support access change application`))
|
|
101
|
-
: this.agent.applyAccessChange$(
|
|
135
|
+
: this.agent.applyAccessChange$(applyContext, message);
|
|
102
136
|
return applyOb$.pipe((0, rxjs_1.map)((result) => ({
|
|
103
137
|
kind: 'apply-change-rs',
|
|
104
138
|
requestId: message.id,
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ValidateProviderConfigRs, DeviceDiscoveryDto, RunCommandRq, AccessValidateChangeRq, AccessChangeIssue, AccessApplyChange, AccessRefMap } from '@awarevue/api-types';
|
|
1
|
+
import { ValidateProviderConfigRs, DeviceDiscoveryDto, RunCommandRq, AccessValidateChangeRq, AccessChangeIssue, AccessApplyChange, AccessRefMap, AccessObjectKind } from '@awarevue/api-types';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { DeviceActivity } from './agent-app';
|
|
4
4
|
export type Context = {
|
|
@@ -15,6 +15,8 @@ export type RunCommandContext = Context & {
|
|
|
15
15
|
};
|
|
16
16
|
export type AccessChangeContext = Context & {
|
|
17
17
|
deviceCatalog: DeviceDiscoveryDto;
|
|
18
|
+
objectsById: <T extends Record<string, unknown>>(objectKind: AccessObjectKind, objectId: string) => T[];
|
|
19
|
+
objectByForeignRef: <T extends Record<string, unknown>>(objectKind: AccessObjectKind, foreignRef: string) => T | null;
|
|
18
20
|
};
|
|
19
21
|
export interface Agent {
|
|
20
22
|
getConfigIssues$: (context: Context) => Observable<ValidateProviderConfigRs['issues']>;
|
|
@@ -23,4 +25,5 @@ export interface Agent {
|
|
|
23
25
|
runCommand$: (context: RunCommandContext, command: RunCommandRq) => Observable<unknown>;
|
|
24
26
|
validateAccessChange$?: (context: AccessChangeContext, change: AccessValidateChangeRq) => Observable<AccessChangeIssue[]>;
|
|
25
27
|
applyAccessChange$?: (context: AccessChangeContext, change: AccessApplyChange) => Observable<AccessRefMap>;
|
|
28
|
+
find$?: (context: Context, objectKind: AccessObjectKind, objectIds: string[]) => Observable<Record<string, Record<string, unknown>[]>>;
|
|
26
29
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AccessValidateChangeRq } from '@awarevue/api-types';
|
|
2
|
+
import { Agent, Context } from './agent';
|
|
3
|
+
export declare const createValidator: <T extends Agent>(agent: T) => (context: Context, change: AccessValidateChangeRq) => import("rxjs").Observable<readonly [{
|
|
4
|
+
index?: number | undefined;
|
|
5
|
+
code?: "BAD_REFERENCE" | "NOT_FOUND" | "NOT_UNIQUE" | "INVALID" | "NOT_SUPPORTED" | undefined;
|
|
6
|
+
message?: string | undefined;
|
|
7
|
+
path?: string | undefined;
|
|
8
|
+
objectKind?: "person" | "zone" | "device" | "schedule" | "accessRule" | undefined;
|
|
9
|
+
objectId?: string | undefined;
|
|
10
|
+
}[], Record<"accessRule" | "schedule" | "person" | "device" | "zone", Record<string, Record<string, unknown>>>]>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createValidator = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const emptyMap = {};
|
|
6
|
+
const createValidator = (agent) => {
|
|
7
|
+
const getNotFoundIssues = (req) => {
|
|
8
|
+
// check object ref contains all related objects
|
|
9
|
+
const personIds = [
|
|
10
|
+
...new Set(req.mutations.flatMap((m) => {
|
|
11
|
+
var _a;
|
|
12
|
+
return m.kind === 'merge' && m.objectKind === 'accessRule'
|
|
13
|
+
? ((_a = m.props.appliedTo) !== null && _a !== void 0 ? _a : [])
|
|
14
|
+
: [];
|
|
15
|
+
})),
|
|
16
|
+
];
|
|
17
|
+
const scheduleIds = [
|
|
18
|
+
...new Set(req.mutations.flatMap((m) => m.kind === 'merge' && m.objectKind === 'accessRule'
|
|
19
|
+
? [
|
|
20
|
+
...(m.props.permissions || []).map((p) => p.scheduleId),
|
|
21
|
+
...(m.props.groupPermissions || []).map((p) => p.scheduleId),
|
|
22
|
+
]
|
|
23
|
+
: [])),
|
|
24
|
+
];
|
|
25
|
+
const notFoundPersonIds = personIds.filter((p) => !req.refMap['person'][p]);
|
|
26
|
+
const notFoundScheduleIds = scheduleIds.filter((s) => !req.refMap['schedule'][s]);
|
|
27
|
+
return [
|
|
28
|
+
...notFoundPersonIds.map((id) => ({
|
|
29
|
+
code: 'NOT_FOUND',
|
|
30
|
+
objectId: id,
|
|
31
|
+
objectKind: 'person',
|
|
32
|
+
})),
|
|
33
|
+
...notFoundScheduleIds.map((id) => ({
|
|
34
|
+
code: 'NOT_FOUND',
|
|
35
|
+
objectId: id,
|
|
36
|
+
objectKind: 'schedule',
|
|
37
|
+
})),
|
|
38
|
+
];
|
|
39
|
+
};
|
|
40
|
+
const getBadReferenceIssues$ = (context, req) => {
|
|
41
|
+
if (!agent.find$)
|
|
42
|
+
return [];
|
|
43
|
+
const personIds = Object.entries(req.refMap['person'] || {}).flatMap(([objectId, refs]) => refs.map((ref) => ({ objectId, ref })));
|
|
44
|
+
const scheduleIds = Object.entries(req.refMap['schedule'] || {}).flatMap(([objectId, refs]) => refs.map((ref) => ({ objectId, ref })));
|
|
45
|
+
const ruleIds = Object.entries(req.refMap['accessRule'] || {}).flatMap(([objectId, refs]) => refs.map((ref) => ({ objectId, ref })));
|
|
46
|
+
const zoneIds = Object.entries(req.refMap['zone'] || {}).flatMap(([objectId, refs]) => refs.map((ref) => ({ objectId, ref })));
|
|
47
|
+
return (0, rxjs_1.forkJoin)([
|
|
48
|
+
// load persons
|
|
49
|
+
personIds.length < 1
|
|
50
|
+
? (0, rxjs_1.of)(emptyMap)
|
|
51
|
+
: agent.find$(context, 'person', personIds.map((p) => p.ref)),
|
|
52
|
+
// load schedules
|
|
53
|
+
scheduleIds.length < 1
|
|
54
|
+
? (0, rxjs_1.of)(emptyMap)
|
|
55
|
+
: agent.find$(context, 'schedule', scheduleIds.map((p) => p.ref)),
|
|
56
|
+
// load rules
|
|
57
|
+
ruleIds.length < 1
|
|
58
|
+
? (0, rxjs_1.of)(emptyMap)
|
|
59
|
+
: agent.find$(context, 'accessRule', ruleIds.map((p) => p.ref)),
|
|
60
|
+
// load zones
|
|
61
|
+
zoneIds.length < 1
|
|
62
|
+
? (0, rxjs_1.of)(emptyMap)
|
|
63
|
+
: agent.find$(context, 'zone', zoneIds.map((p) => p.ref)),
|
|
64
|
+
]).pipe((0, rxjs_1.mergeMap)(([persons, schedules, rules, zones]) => {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
const issues = [];
|
|
67
|
+
// check persons
|
|
68
|
+
for (const personId of personIds) {
|
|
69
|
+
if (!persons[personId.ref]) {
|
|
70
|
+
issues.push({
|
|
71
|
+
code: 'BAD_REFERENCE',
|
|
72
|
+
objectId: personId.objectId,
|
|
73
|
+
objectKind: 'person',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// check schedules
|
|
78
|
+
for (const scheduleId of scheduleIds) {
|
|
79
|
+
if (!schedules[scheduleId.ref]) {
|
|
80
|
+
issues.push({
|
|
81
|
+
code: 'BAD_REFERENCE',
|
|
82
|
+
objectId: scheduleId.objectId,
|
|
83
|
+
objectKind: 'schedule',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// check rules
|
|
88
|
+
for (const ruleId of ruleIds) {
|
|
89
|
+
if (!((_a = rules['accessRule']) === null || _a === void 0 ? void 0 : _a[ruleId.ref])) {
|
|
90
|
+
issues.push({
|
|
91
|
+
code: 'BAD_REFERENCE',
|
|
92
|
+
objectId: ruleId.ref,
|
|
93
|
+
objectKind: 'accessRule',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// check zones
|
|
98
|
+
for (const zoneId of zoneIds) {
|
|
99
|
+
if (!((_b = zones['zone']) === null || _b === void 0 ? void 0 : _b[zoneId.ref])) {
|
|
100
|
+
issues.push({
|
|
101
|
+
code: 'BAD_REFERENCE',
|
|
102
|
+
objectId: zoneId.objectId,
|
|
103
|
+
objectKind: 'zone',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return (0, rxjs_1.of)([
|
|
108
|
+
issues,
|
|
109
|
+
{
|
|
110
|
+
person: persons,
|
|
111
|
+
schedule: schedules,
|
|
112
|
+
accessRule: rules,
|
|
113
|
+
zone: zones,
|
|
114
|
+
},
|
|
115
|
+
]);
|
|
116
|
+
}));
|
|
117
|
+
};
|
|
118
|
+
return (context, change) => {
|
|
119
|
+
return (0, rxjs_1.forkJoin)([
|
|
120
|
+
(0, rxjs_1.of)(getNotFoundIssues(change)),
|
|
121
|
+
getBadReferenceIssues$(context, change),
|
|
122
|
+
]).pipe((0, rxjs_1.mergeMap)(([notFoundIssues, [badReferenceIssues, cache]]) => (0, rxjs_1.of)([
|
|
123
|
+
[...notFoundIssues, ...badReferenceIssues],
|
|
124
|
+
cache,
|
|
125
|
+
])));
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
exports.createValidator = createValidator;
|
package/dist/package.json
CHANGED