apcore-js 0.18.0 → 0.20.0
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/README.md +112 -9
- package/dist/acl-handlers.d.ts +14 -0
- package/dist/acl-handlers.d.ts.map +1 -1
- package/dist/acl-handlers.js +37 -4
- package/dist/acl-handlers.js.map +1 -1
- package/dist/acl.d.ts +22 -1
- package/dist/acl.d.ts.map +1 -1
- package/dist/acl.js +90 -34
- package/dist/acl.js.map +1 -1
- package/dist/async-task.d.ts +70 -16
- package/dist/async-task.d.ts.map +1 -1
- package/dist/async-task.js +212 -72
- package/dist/async-task.js.map +1 -1
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +113 -11
- package/dist/bindings.js.map +1 -1
- package/dist/builtin-steps.d.ts +33 -8
- package/dist/builtin-steps.d.ts.map +1 -1
- package/dist/builtin-steps.js +119 -47
- package/dist/builtin-steps.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +163 -33
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +34 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +108 -40
- package/dist/context.js.map +1 -1
- package/dist/decorator.d.ts +3 -0
- package/dist/decorator.d.ts.map +1 -1
- package/dist/decorator.js +3 -0
- package/dist/decorator.js.map +1 -1
- package/dist/errors.d.ts +88 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +231 -56
- package/dist/errors.js.map +1 -1
- package/dist/events/circuit-breaker.d.ts +45 -0
- package/dist/events/circuit-breaker.d.ts.map +1 -0
- package/dist/events/circuit-breaker.js +115 -0
- package/dist/events/circuit-breaker.js.map +1 -0
- package/dist/events/emitter.d.ts +24 -1
- package/dist/events/emitter.d.ts.map +1 -1
- package/dist/events/emitter.js +86 -12
- package/dist/events/emitter.js.map +1 -1
- package/dist/events/index.d.ts +4 -2
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +3 -2
- package/dist/events/index.js.map +1 -1
- package/dist/events/subscribers.d.ts +33 -1
- package/dist/events/subscribers.d.ts.map +1 -1
- package/dist/events/subscribers.js +124 -1
- package/dist/events/subscribers.js.map +1 -1
- package/dist/executor.d.ts +14 -3
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +155 -48
- package/dist/executor.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/index.d.ts +47 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -18
- package/dist/index.js.map +1 -1
- package/dist/middleware/base.d.ts +25 -3
- package/dist/middleware/base.d.ts.map +1 -1
- package/dist/middleware/base.js +24 -0
- package/dist/middleware/base.js.map +1 -1
- package/dist/middleware/circuit-breaker.d.ts +54 -0
- package/dist/middleware/circuit-breaker.d.ts.map +1 -0
- package/dist/middleware/circuit-breaker.js +168 -0
- package/dist/middleware/circuit-breaker.js.map +1 -0
- package/dist/middleware/context-namespace.d.ts +30 -0
- package/dist/middleware/context-namespace.d.ts.map +1 -0
- package/dist/middleware/context-namespace.js +38 -0
- package/dist/middleware/context-namespace.js.map +1 -0
- package/dist/middleware/index.d.ts +8 -2
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +5 -2
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/logging.d.ts +6 -0
- package/dist/middleware/logging.d.ts.map +1 -1
- package/dist/middleware/logging.js +13 -3
- package/dist/middleware/logging.js.map +1 -1
- package/dist/middleware/manager.d.ts +11 -4
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +26 -9
- package/dist/middleware/manager.js.map +1 -1
- package/dist/middleware/platform-notify.d.ts +8 -4
- package/dist/middleware/platform-notify.d.ts.map +1 -1
- package/dist/middleware/platform-notify.js +15 -7
- package/dist/middleware/platform-notify.js.map +1 -1
- package/dist/middleware/retry.d.ts +16 -7
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +21 -15
- package/dist/middleware/retry.js.map +1 -1
- package/dist/middleware/tracing.d.ts +50 -0
- package/dist/middleware/tracing.d.ts.map +1 -0
- package/dist/middleware/tracing.js +89 -0
- package/dist/middleware/tracing.js.map +1 -0
- package/dist/observability/batch-span-processor.d.ts +48 -0
- package/dist/observability/batch-span-processor.d.ts.map +1 -0
- package/dist/observability/batch-span-processor.js +89 -0
- package/dist/observability/batch-span-processor.js.map +1 -0
- package/dist/observability/context-logger.d.ts +54 -1
- package/dist/observability/context-logger.d.ts.map +1 -1
- package/dist/observability/context-logger.js +287 -10
- package/dist/observability/context-logger.js.map +1 -1
- package/dist/observability/error-history.d.ts +36 -7
- package/dist/observability/error-history.d.ts.map +1 -1
- package/dist/observability/error-history.js +169 -50
- package/dist/observability/error-history.js.map +1 -1
- package/dist/observability/index.d.ts +16 -5
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +8 -3
- package/dist/observability/index.js.map +1 -1
- package/dist/observability/metrics-utils.d.ts.map +1 -1
- package/dist/observability/metrics-utils.js +3 -5
- package/dist/observability/metrics-utils.js.map +1 -1
- package/dist/observability/metrics.d.ts +15 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/metrics.js +37 -3
- package/dist/observability/metrics.js.map +1 -1
- package/dist/observability/prometheus-exporter.d.ts +37 -0
- package/dist/observability/prometheus-exporter.d.ts.map +1 -0
- package/dist/observability/prometheus-exporter.js +135 -0
- package/dist/observability/prometheus-exporter.js.map +1 -0
- package/dist/observability/storage.d.ts +43 -0
- package/dist/observability/storage.d.ts.map +1 -0
- package/dist/observability/storage.js +58 -0
- package/dist/observability/storage.js.map +1 -0
- package/dist/observability/store.d.ts +29 -0
- package/dist/observability/store.d.ts.map +1 -0
- package/dist/observability/store.js +36 -0
- package/dist/observability/store.js.map +1 -0
- package/dist/observability/tracing.d.ts +2 -0
- package/dist/observability/tracing.d.ts.map +1 -1
- package/dist/observability/tracing.js +12 -2
- package/dist/observability/tracing.js.map +1 -1
- package/dist/observability/usage-exporter.d.ts +58 -0
- package/dist/observability/usage-exporter.d.ts.map +1 -0
- package/dist/observability/usage-exporter.js +86 -0
- package/dist/observability/usage-exporter.js.map +1 -0
- package/dist/observability/usage.d.ts +18 -1
- package/dist/observability/usage.d.ts.map +1 -1
- package/dist/observability/usage.js +35 -4
- package/dist/observability/usage.js.map +1 -1
- package/dist/pipeline-config.d.ts +24 -7
- package/dist/pipeline-config.d.ts.map +1 -1
- package/dist/pipeline-config.js +113 -19
- package/dist/pipeline-config.js.map +1 -1
- package/dist/pipeline.d.ts +123 -2
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +249 -50
- package/dist/pipeline.js.map +1 -1
- package/dist/registry/conflicts.d.ts +2 -2
- package/dist/registry/conflicts.d.ts.map +1 -1
- package/dist/registry/conflicts.js +10 -11
- package/dist/registry/conflicts.js.map +1 -1
- package/dist/registry/dependencies.d.ts +1 -1
- package/dist/registry/dependencies.d.ts.map +1 -1
- package/dist/registry/dependencies.js +69 -20
- package/dist/registry/dependencies.js.map +1 -1
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +1 -0
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/multi-class.d.ts +57 -0
- package/dist/registry/multi-class.d.ts.map +1 -0
- package/dist/registry/multi-class.js +120 -0
- package/dist/registry/multi-class.js.map +1 -0
- package/dist/registry/registry.d.ts +99 -4
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +291 -33
- package/dist/registry/registry.js.map +1 -1
- package/dist/registry/scanner.d.ts.map +1 -1
- package/dist/registry/scanner.js +6 -0
- package/dist/registry/scanner.js.map +1 -1
- package/dist/registry/version.d.ts +1 -0
- package/dist/registry/version.d.ts.map +1 -1
- package/dist/registry/version.js +33 -4
- package/dist/registry/version.js.map +1 -1
- package/dist/schema/constants.d.ts +9 -0
- package/dist/schema/constants.d.ts.map +1 -0
- package/dist/schema/constants.js +9 -0
- package/dist/schema/constants.js.map +1 -0
- package/dist/schema/extractor.d.ts +69 -0
- package/dist/schema/extractor.d.ts.map +1 -0
- package/dist/schema/extractor.js +142 -0
- package/dist/schema/extractor.js.map +1 -0
- package/dist/schema/index.d.ts +3 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/loader.d.ts +27 -3
- package/dist/schema/loader.d.ts.map +1 -1
- package/dist/schema/loader.js +137 -32
- package/dist/schema/loader.js.map +1 -1
- package/dist/schema/ref-resolver.d.ts.map +1 -1
- package/dist/schema/ref-resolver.js +10 -1
- package/dist/schema/ref-resolver.js.map +1 -1
- package/dist/schema/types.d.ts +4 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js.map +1 -1
- package/dist/schema/validator.d.ts +9 -0
- package/dist/schema/validator.d.ts.map +1 -1
- package/dist/schema/validator.js +153 -4
- package/dist/schema/validator.js.map +1 -1
- package/dist/sys-modules/audit.d.ts +50 -0
- package/dist/sys-modules/audit.d.ts.map +1 -0
- package/dist/sys-modules/audit.js +89 -0
- package/dist/sys-modules/audit.js.map +1 -0
- package/dist/sys-modules/control.d.ts +32 -4
- package/dist/sys-modules/control.d.ts.map +1 -1
- package/dist/sys-modules/control.js +197 -23
- package/dist/sys-modules/control.js.map +1 -1
- package/dist/sys-modules/index.d.ts +7 -2
- package/dist/sys-modules/index.d.ts.map +1 -1
- package/dist/sys-modules/index.js +3 -1
- package/dist/sys-modules/index.js.map +1 -1
- package/dist/sys-modules/overrides.d.ts +58 -0
- package/dist/sys-modules/overrides.d.ts.map +1 -0
- package/dist/sys-modules/overrides.js +106 -0
- package/dist/sys-modules/overrides.js.map +1 -0
- package/dist/sys-modules/registration.d.ts +18 -1
- package/dist/sys-modules/registration.d.ts.map +1 -1
- package/dist/sys-modules/registration.js +115 -11
- package/dist/sys-modules/registration.js.map +1 -1
- package/dist/sys-modules/toggle.d.ts +7 -2
- package/dist/sys-modules/toggle.d.ts.map +1 -1
- package/dist/sys-modules/toggle.js +61 -5
- package/dist/sys-modules/toggle.js.map +1 -1
- package/dist/trace-context.d.ts +47 -9
- package/dist/trace-context.d.ts.map +1 -1
- package/dist/trace-context.js +139 -16
- package/dist/trace-context.js.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/schema/validator.js
CHANGED
|
@@ -1,27 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SchemaValidator — validates runtime data against TypeBox schemas.
|
|
3
3
|
*/
|
|
4
|
+
import { FormatRegistry, TypeGuard } from '@sinclair/typebox';
|
|
4
5
|
import { Value } from '@sinclair/typebox/value';
|
|
5
6
|
import { validationResultToError } from './types.js';
|
|
7
|
+
import { ONEOF_MARKER } from './constants.js';
|
|
8
|
+
// SHOULD-level format validators (Issue #44 §4).
|
|
9
|
+
// These check semantic correctness; failures emit warnings but do not reject.
|
|
10
|
+
const FORMAT_VALIDATORS = {
|
|
11
|
+
'date-time': (v) => !isNaN(new Date(v).getTime()),
|
|
12
|
+
'date': (v) => /^\d{4}-\d{2}-\d{2}$/.test(v),
|
|
13
|
+
'time': (v) => /^\d{2}:\d{2}:\d{2}/.test(v),
|
|
14
|
+
'email': (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
|
|
15
|
+
'uri': (v) => { try {
|
|
16
|
+
new URL(v);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
} },
|
|
22
|
+
'uuid': (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v),
|
|
23
|
+
'ipv4': (v) => /^(\d{1,3}\.){3}\d{1,3}$/.test(v) && v.split('.').every((n) => parseInt(n, 10) <= 255),
|
|
24
|
+
'ipv6': (v) => /^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i.test(v),
|
|
25
|
+
};
|
|
6
26
|
export class SchemaValidator {
|
|
7
27
|
_coerceTypes;
|
|
8
28
|
constructor(coerceTypes = true) {
|
|
9
29
|
this._coerceTypes = coerceTypes;
|
|
30
|
+
// Register known formats with TypeBox so Value.Check accepts them structurally.
|
|
31
|
+
// TypeBox 0.34+ rejects strings with unregistered formats; we override to always
|
|
32
|
+
// pass the structural check and handle enforcement ourselves via SHOULD-level warnings.
|
|
33
|
+
// Guarded by Has() so pre-existing registrations from the host process are not clobbered.
|
|
34
|
+
for (const fmt of Object.keys(FORMAT_VALIDATORS)) {
|
|
35
|
+
if (!FormatRegistry.Has(fmt)) {
|
|
36
|
+
FormatRegistry.Set(fmt, () => true);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
10
39
|
}
|
|
11
40
|
validate(data, schema) {
|
|
41
|
+
const s = schema;
|
|
42
|
+
// oneOf: exhaustive counting — exactly one branch must match
|
|
43
|
+
if (s[ONEOF_MARKER] === 'oneOf') {
|
|
44
|
+
return this._validateOneOf(data, schema);
|
|
45
|
+
}
|
|
46
|
+
// anyOf: at least one branch must match; use Value.Check per branch for SCHEMA_UNION_NO_MATCH
|
|
47
|
+
if ('anyOf' in s && !(ONEOF_MARKER in s)) {
|
|
48
|
+
return this._validateAnyOf(data, schema);
|
|
49
|
+
}
|
|
12
50
|
if (this._coerceTypes) {
|
|
13
51
|
try {
|
|
14
52
|
Value.Decode(schema, data);
|
|
15
|
-
|
|
53
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
54
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
16
55
|
}
|
|
17
56
|
catch {
|
|
18
|
-
return {
|
|
57
|
+
return {
|
|
58
|
+
valid: false,
|
|
59
|
+
errors: this._collectErrors(schema, data),
|
|
60
|
+
errorCode: 'SCHEMA_VALIDATION_FAILED',
|
|
61
|
+
};
|
|
19
62
|
}
|
|
20
63
|
}
|
|
21
64
|
if (Value.Check(schema, data)) {
|
|
22
|
-
|
|
65
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
66
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
23
67
|
}
|
|
24
|
-
return {
|
|
68
|
+
return {
|
|
69
|
+
valid: false,
|
|
70
|
+
errors: this._collectErrors(schema, data),
|
|
71
|
+
errorCode: 'SCHEMA_VALIDATION_FAILED',
|
|
72
|
+
};
|
|
25
73
|
}
|
|
26
74
|
validateInput(data, schema) {
|
|
27
75
|
return this._validateAndReturn(data, schema);
|
|
@@ -29,6 +77,64 @@ export class SchemaValidator {
|
|
|
29
77
|
validateOutput(data, schema) {
|
|
30
78
|
return this._validateAndReturn(data, schema);
|
|
31
79
|
}
|
|
80
|
+
_validateOneOf(data, schema) {
|
|
81
|
+
if (!TypeGuard.IsUnion(schema)) {
|
|
82
|
+
// TypeBox 0.34 unwraps single-element unions to the branch type itself.
|
|
83
|
+
// A single-branch oneOf always matches exactly one branch if the data is valid.
|
|
84
|
+
if (!Value.Check(schema, data)) {
|
|
85
|
+
return {
|
|
86
|
+
valid: false,
|
|
87
|
+
errors: this._collectErrors(schema, data),
|
|
88
|
+
errorCode: 'SCHEMA_UNION_NO_MATCH',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
92
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
93
|
+
}
|
|
94
|
+
const branches = schema.anyOf;
|
|
95
|
+
const matchCount = branches.filter((b) => Value.Check(b, data)).length;
|
|
96
|
+
if (matchCount === 0) {
|
|
97
|
+
return {
|
|
98
|
+
valid: false,
|
|
99
|
+
errors: [{ path: '/', message: 'oneOf: no branches matched', constraint: 'oneOf' }],
|
|
100
|
+
errorCode: 'SCHEMA_UNION_NO_MATCH',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (matchCount > 1) {
|
|
104
|
+
return {
|
|
105
|
+
valid: false,
|
|
106
|
+
errors: [{ path: '/', message: `oneOf: expected exactly 1 match, got ${matchCount}`, constraint: 'oneOf' }],
|
|
107
|
+
errorCode: 'SCHEMA_UNION_AMBIGUOUS',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
111
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
112
|
+
}
|
|
113
|
+
_validateAnyOf(data, schema) {
|
|
114
|
+
if (!TypeGuard.IsUnion(schema)) {
|
|
115
|
+
// TypeBox 0.34 unwraps single-element unions; treat the unwrapped schema as a single branch.
|
|
116
|
+
if (!Value.Check(schema, data)) {
|
|
117
|
+
return {
|
|
118
|
+
valid: false,
|
|
119
|
+
errors: this._collectErrors(schema, data),
|
|
120
|
+
errorCode: 'SCHEMA_UNION_NO_MATCH',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
124
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
125
|
+
}
|
|
126
|
+
const branches = schema.anyOf;
|
|
127
|
+
const hasMatch = branches.some((b) => Value.Check(b, data));
|
|
128
|
+
if (!hasMatch) {
|
|
129
|
+
return {
|
|
130
|
+
valid: false,
|
|
131
|
+
errors: [{ path: '/', message: 'anyOf: no branches matched', constraint: 'anyOf' }],
|
|
132
|
+
errorCode: 'SCHEMA_UNION_NO_MATCH',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const warnLogged = this._checkFormats(data, schema);
|
|
136
|
+
return { valid: true, errors: [], ...(warnLogged && { warnLogged: true }) };
|
|
137
|
+
}
|
|
32
138
|
_validateAndReturn(data, schema) {
|
|
33
139
|
if (this._coerceTypes) {
|
|
34
140
|
try {
|
|
@@ -51,6 +157,49 @@ export class SchemaValidator {
|
|
|
51
157
|
};
|
|
52
158
|
throw validationResultToError(result);
|
|
53
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Walk the schema and data together to find format-annotated string fields.
|
|
162
|
+
* Emits console.warn for each format violation (SHOULD-level enforcement).
|
|
163
|
+
* Returns true if any warnings were emitted.
|
|
164
|
+
*/
|
|
165
|
+
_checkFormats(data, schema) {
|
|
166
|
+
const warnings = [];
|
|
167
|
+
this._walkFormats(data, schema, '/', warnings);
|
|
168
|
+
for (const w of warnings) {
|
|
169
|
+
console.warn(`[apcore:schema] ${w}`);
|
|
170
|
+
}
|
|
171
|
+
return warnings.length > 0;
|
|
172
|
+
}
|
|
173
|
+
_walkFormats(data, schema, path, warnings) {
|
|
174
|
+
if (typeof schema !== 'object' || schema === null)
|
|
175
|
+
return;
|
|
176
|
+
// String with format annotation
|
|
177
|
+
if (schema['type'] === 'string' && typeof schema['format'] === 'string' && typeof data === 'string') {
|
|
178
|
+
const format = schema['format'];
|
|
179
|
+
const validator = FORMAT_VALIDATORS[format];
|
|
180
|
+
if (validator && !validator(data)) {
|
|
181
|
+
warnings.push(`Format '${format}' validation failed at ${path}: "${data}"`);
|
|
182
|
+
}
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Object: recurse into properties
|
|
186
|
+
if (schema['type'] === 'object' && schema['properties'] && typeof data === 'object' && data !== null && !Array.isArray(data)) {
|
|
187
|
+
const props = schema['properties'];
|
|
188
|
+
const dataObj = data;
|
|
189
|
+
for (const [key, propSchema] of Object.entries(props)) {
|
|
190
|
+
if (key in dataObj) {
|
|
191
|
+
this._walkFormats(dataObj[key], propSchema, `${path}${path === '/' ? '' : '/'}${key}`, warnings);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Array: recurse into each element using the items schema
|
|
196
|
+
if (schema['type'] === 'array' && schema['items'] && Array.isArray(data)) {
|
|
197
|
+
const itemSchema = schema['items'];
|
|
198
|
+
data.forEach((item, i) => {
|
|
199
|
+
this._walkFormats(item, itemSchema, `${path === '/' ? '' : path}/${i}`, warnings);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
54
203
|
_collectErrors(schema, data) {
|
|
55
204
|
const errors = [];
|
|
56
205
|
for (const error of Value.Errors(schema, data)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Context } from '../context.js';
|
|
2
|
+
export type AuditAction = 'update_config' | 'reload_module' | 'toggle_feature';
|
|
3
|
+
export interface AuditEntry {
|
|
4
|
+
timestamp: string;
|
|
5
|
+
action: AuditAction;
|
|
6
|
+
targetModuleId: string;
|
|
7
|
+
actorId: string;
|
|
8
|
+
actorType: string;
|
|
9
|
+
traceId: string;
|
|
10
|
+
change: {
|
|
11
|
+
before: unknown;
|
|
12
|
+
after: unknown;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface AuditFilter {
|
|
16
|
+
moduleId?: string;
|
|
17
|
+
actorId?: string;
|
|
18
|
+
since?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AuditStore {
|
|
21
|
+
append(entry: AuditEntry): void;
|
|
22
|
+
query(filter?: AuditFilter): AuditEntry[];
|
|
23
|
+
}
|
|
24
|
+
export declare class InMemoryAuditStore implements AuditStore {
|
|
25
|
+
private readonly _entries;
|
|
26
|
+
append(entry: AuditEntry): void;
|
|
27
|
+
query(filter?: AuditFilter): AuditEntry[];
|
|
28
|
+
}
|
|
29
|
+
export declare function buildAuditEntry(action: AuditAction, targetModuleId: string, context: Context | null, change: {
|
|
30
|
+
before: unknown;
|
|
31
|
+
after: unknown;
|
|
32
|
+
}): AuditEntry;
|
|
33
|
+
/**
|
|
34
|
+
* Issue #45.2: Extract requester identity fields for audit event payloads.
|
|
35
|
+
*
|
|
36
|
+
* Returns `caller_id` (defaulting to `"@external"` when absent so that audit
|
|
37
|
+
* events always carry a non-null requester marker) and a redacted-safe
|
|
38
|
+
* `identity` snapshot (or `null` when the context has no identity).
|
|
39
|
+
*
|
|
40
|
+
* Per docs/features/system-modules.md §"Contextual auditing", the snapshot
|
|
41
|
+
* MUST contain `id`, `type`, and (optionally) `display_name`; any attribute
|
|
42
|
+
* whose key looks x-sensitive (bearer_token, api_key, etc.) is replaced with
|
|
43
|
+
* the literal string `"<redacted>"` rather than dropped, so subscribers can
|
|
44
|
+
* see that a sensitive credential was involved without leaking its value.
|
|
45
|
+
*/
|
|
46
|
+
export declare function extractAuditIdentity(context: Context | null): {
|
|
47
|
+
caller_id: string;
|
|
48
|
+
identity: Record<string, unknown> | null;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/sys-modules/audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAE/E,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,EAAE,CAAC;CAC3C;AAED,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAE7C,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAI/B,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,EAAE;CAc1C;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,MAAM,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC1C,UAAU,CAUZ;AAkBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,GAAG,IAAI,GACtB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CA2BjE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export class InMemoryAuditStore {
|
|
2
|
+
_entries = [];
|
|
3
|
+
append(entry) {
|
|
4
|
+
this._entries.push(entry);
|
|
5
|
+
}
|
|
6
|
+
query(filter) {
|
|
7
|
+
let results = [...this._entries];
|
|
8
|
+
if (filter?.moduleId !== undefined) {
|
|
9
|
+
results = results.filter((e) => e.targetModuleId === filter.moduleId);
|
|
10
|
+
}
|
|
11
|
+
if (filter?.actorId !== undefined) {
|
|
12
|
+
results = results.filter((e) => e.actorId === filter.actorId);
|
|
13
|
+
}
|
|
14
|
+
if (filter?.since !== undefined) {
|
|
15
|
+
const since = new Date(filter.since);
|
|
16
|
+
results = results.filter((e) => new Date(e.timestamp) >= since);
|
|
17
|
+
}
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function buildAuditEntry(action, targetModuleId, context, change) {
|
|
22
|
+
return {
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
action,
|
|
25
|
+
targetModuleId,
|
|
26
|
+
actorId: context?.identity?.id ?? 'unknown',
|
|
27
|
+
actorType: context?.identity?.type ?? 'unknown',
|
|
28
|
+
traceId: context?.traceId ?? 'unknown',
|
|
29
|
+
change,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Identity attribute substrings treated as x-sensitive in audit payloads. */
|
|
33
|
+
const SENSITIVE_IDENTITY_ATTR_SUBSTRINGS = [
|
|
34
|
+
'token',
|
|
35
|
+
'secret',
|
|
36
|
+
'password',
|
|
37
|
+
'passwd',
|
|
38
|
+
'credential',
|
|
39
|
+
'api_key',
|
|
40
|
+
'apikey',
|
|
41
|
+
'access_key',
|
|
42
|
+
'private_key',
|
|
43
|
+
'authorization',
|
|
44
|
+
'cookie',
|
|
45
|
+
'bearer',
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Issue #45.2: Extract requester identity fields for audit event payloads.
|
|
49
|
+
*
|
|
50
|
+
* Returns `caller_id` (defaulting to `"@external"` when absent so that audit
|
|
51
|
+
* events always carry a non-null requester marker) and a redacted-safe
|
|
52
|
+
* `identity` snapshot (or `null` when the context has no identity).
|
|
53
|
+
*
|
|
54
|
+
* Per docs/features/system-modules.md §"Contextual auditing", the snapshot
|
|
55
|
+
* MUST contain `id`, `type`, and (optionally) `display_name`; any attribute
|
|
56
|
+
* whose key looks x-sensitive (bearer_token, api_key, etc.) is replaced with
|
|
57
|
+
* the literal string `"<redacted>"` rather than dropped, so subscribers can
|
|
58
|
+
* see that a sensitive credential was involved without leaking its value.
|
|
59
|
+
*/
|
|
60
|
+
export function extractAuditIdentity(context) {
|
|
61
|
+
const callerIdRaw = context?.callerId;
|
|
62
|
+
const callerId = callerIdRaw == null || callerIdRaw === '' ? '@external' : callerIdRaw;
|
|
63
|
+
const ident = context?.identity ?? null;
|
|
64
|
+
if (!ident) {
|
|
65
|
+
return { caller_id: callerId, identity: null };
|
|
66
|
+
}
|
|
67
|
+
const snapshot = {
|
|
68
|
+
id: ident.id,
|
|
69
|
+
type: ident.type,
|
|
70
|
+
roles: [...ident.roles],
|
|
71
|
+
};
|
|
72
|
+
// Surface display_name from attrs if present (spec #45.2 calls it out as
|
|
73
|
+
// an optional first-class field on the audit identity snapshot).
|
|
74
|
+
const displayName = ident.attrs['display_name'];
|
|
75
|
+
if (typeof displayName === 'string' && displayName.length > 0) {
|
|
76
|
+
snapshot['display_name'] = displayName;
|
|
77
|
+
}
|
|
78
|
+
// Pass through any other attrs, redacting those whose key matches a
|
|
79
|
+
// sensitive substring (case-insensitive).
|
|
80
|
+
for (const [k, v] of Object.entries(ident.attrs)) {
|
|
81
|
+
if (k === 'display_name')
|
|
82
|
+
continue;
|
|
83
|
+
const lk = k.toLowerCase();
|
|
84
|
+
const sensitive = SENSITIVE_IDENTITY_ATTR_SUBSTRINGS.some((s) => lk.includes(s));
|
|
85
|
+
snapshot[k] = sensitive ? '<redacted>' : v;
|
|
86
|
+
}
|
|
87
|
+
return { caller_id: callerId, identity: snapshot };
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/sys-modules/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
import type { Registry } from '../registry/registry.js';
|
|
5
5
|
import type { EventEmitter } from '../events/emitter.js';
|
|
6
6
|
import type { Config } from '../config.js';
|
|
7
|
+
import type { AuditStore } from './audit.js';
|
|
8
|
+
import type { OverridesStore } from './overrides.js';
|
|
9
|
+
export interface UpdateConfigOptions {
|
|
10
|
+
auditStore?: AuditStore;
|
|
11
|
+
overridesPath?: string;
|
|
12
|
+
/** Pluggable persistent override store (Issue #45.1). */
|
|
13
|
+
overridesStore?: OverridesStore;
|
|
14
|
+
}
|
|
7
15
|
export declare class UpdateConfigModule {
|
|
8
16
|
readonly description = "Update a runtime configuration value by dot-path key";
|
|
9
17
|
readonly annotations: {
|
|
@@ -58,8 +66,13 @@ export declare class UpdateConfigModule {
|
|
|
58
66
|
};
|
|
59
67
|
private readonly _config;
|
|
60
68
|
private readonly _emitter;
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
private readonly _auditStore;
|
|
70
|
+
private readonly _overridesPath;
|
|
71
|
+
private readonly _overridesStore;
|
|
72
|
+
constructor(config: Config, eventEmitter: EventEmitter, options?: UpdateConfigOptions);
|
|
73
|
+
execute(inputs: Record<string, unknown>, context: unknown): Record<string, unknown>;
|
|
74
|
+
private _persistOverrideToStore;
|
|
75
|
+
private _persistOverride;
|
|
63
76
|
private _validateInputs;
|
|
64
77
|
}
|
|
65
78
|
/** @internal */
|
|
@@ -85,6 +98,14 @@ export declare class ReloadModule {
|
|
|
85
98
|
type: "string";
|
|
86
99
|
description: string;
|
|
87
100
|
};
|
|
101
|
+
path_filter: {
|
|
102
|
+
type: "string";
|
|
103
|
+
description: string;
|
|
104
|
+
};
|
|
105
|
+
reload_dependents: {
|
|
106
|
+
type: "boolean";
|
|
107
|
+
description: string;
|
|
108
|
+
};
|
|
88
109
|
reason: {
|
|
89
110
|
type: "string";
|
|
90
111
|
description: string;
|
|
@@ -103,6 +124,10 @@ export declare class ReloadModule {
|
|
|
103
124
|
type: "string";
|
|
104
125
|
description: string;
|
|
105
126
|
};
|
|
127
|
+
reloaded_modules: {
|
|
128
|
+
type: "array";
|
|
129
|
+
description: string;
|
|
130
|
+
};
|
|
106
131
|
previous_version: {
|
|
107
132
|
type: "string";
|
|
108
133
|
description: string;
|
|
@@ -120,8 +145,11 @@ export declare class ReloadModule {
|
|
|
120
145
|
};
|
|
121
146
|
private readonly _registry;
|
|
122
147
|
private readonly _emitter;
|
|
123
|
-
|
|
124
|
-
|
|
148
|
+
private readonly _auditStore;
|
|
149
|
+
constructor(registry: Registry, eventEmitter: EventEmitter, auditStore?: AuditStore);
|
|
150
|
+
execute(inputs: Record<string, unknown>, context: unknown): Promise<Record<string, unknown>>;
|
|
151
|
+
private _reloadSingleModule;
|
|
152
|
+
private _reloadWithPathFilter;
|
|
125
153
|
private _validateInputs;
|
|
126
154
|
}
|
|
127
155
|
//# sourceMappingURL=control.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../src/sys-modules/control.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../src/sys-modules/control.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,WAAW,0DAA0D;IAC9E,QAAQ,CAAC,WAAW;;;;;;;;;;;;MAAoO;IACxP,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;MAQlB;IACF,QAAQ,CAAC,YAAY;;;;;;;;;;;;;;;;;;;MASnB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwB;gBAE5C,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,mBAAmB;IAQrF,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA8CnF,OAAO,CAAC,uBAAuB;IA6B/B,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,eAAe;CAYxB;AAED,gBAAgB;AAChB,qBAAa,YAAY;IACvB,QAAQ,CAAC,WAAW,4DAA4D;IAChF,QAAQ,CAAC,WAAW;;;;;;;;;;;;MAAoO;IACxP,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;MASlB;IACF,QAAQ,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAWnB;IAEF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,UAAU;IAM7E,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAWpF,mBAAmB;YA4EnB,qBAAqB;IAwDnC,OAAO,CAAC,eAAe;CAiCxB"}
|