@aventara/core 0.1.0-pilot.4 → 1.0.0-rc.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 +1478 -0
- package/README.md +275 -11
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-field.d.ts +11 -11
- package/dist/adapters/adapter-identifier.d.ts +6 -6
- package/dist/adapters/adapter-model.d.ts +17 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +3 -3
- package/dist/adapters/adapter-resource.d.ts +18 -9
- package/dist/adapters/adapter-sql-statement.d.ts +19 -0
- package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
- package/dist/adapters/adapter.interface.d.ts +49 -25
- package/dist/avz/avz-check.factory.d.ts +83 -0
- package/dist/avz/avz-check.factory.js +116 -0
- package/dist/avz/avz-check.registry.d.ts +35 -0
- package/dist/avz/avz-check.registry.js +9 -0
- package/dist/avz/avz.d.ts +203 -0
- package/dist/avz/avz.js +354 -0
- package/dist/avz/index.d.ts +7 -0
- package/dist/avz/index.js +1 -0
- package/dist/avz/json-shape.registry.d.ts +22 -0
- package/dist/avz/json-shape.registry.js +16 -0
- package/dist/avz/zod-issue.translator.d.ts +57 -0
- package/dist/avz/zod-issue.translator.js +149 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +37 -5
- package/dist/compiler/contract.compiler.d.ts +18 -18
- package/dist/compiler/contract.compiler.js +595 -421
- package/dist/compiler/create-requirements.projector.d.ts +49 -0
- package/dist/compiler/create-requirements.projector.js +423 -0
- package/dist/compiler/field-validator.compiler.d.ts +47 -0
- package/dist/compiler/field-validator.compiler.js +238 -0
- package/dist/config/any-framework-config.d.ts +19 -12
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +75 -29
- package/dist/config/config.resolver.js +109 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +586 -71
- package/dist/config/define-resource.d.ts +57 -0
- package/dist/config/define-resource.js +14 -0
- package/dist/config/effective-fields.d.ts +19 -23
- package/dist/config/entrypoint.normalizer.d.ts +1 -1
- package/dist/config/exact-framework-config.d.ts +280 -0
- package/dist/config/field-compute.resolver.d.ts +19 -0
- package/dist/config/field-compute.resolver.js +115 -0
- package/dist/config/field-pipeline-config.d.ts +47 -0
- package/dist/config/forced-operation.validator.d.ts +10 -0
- package/dist/config/forced-operation.validator.js +66 -0
- package/dist/config/framework-config.d.ts +111 -37
- package/dist/config/framework-exemptions-config.d.ts +91 -0
- package/dist/config/framework-exemptions-config.js +1 -0
- package/dist/config/framework-field-definition.d.ts +78 -0
- package/dist/config/framework-field-definition.js +28 -0
- package/dist/config/framework-resources-config.d.ts +116 -0
- package/dist/config/framework-resources-config.js +1 -0
- package/dist/config/pipeline-config.d.ts +56 -20
- package/dist/config/pipeline-tree.resolver.d.ts +79 -0
- package/dist/config/pipeline-tree.resolver.js +220 -0
- package/dist/config/stage-type.eraser.d.ts +65 -0
- package/dist/config/stage-type.eraser.js +1 -0
- package/dist/contracts/capability.d.ts +11 -11
- package/dist/contracts/client-contract-structure.validator.d.ts +344 -29
- package/dist/contracts/client-contract-structure.validator.js +248 -7
- package/dist/contracts/contract-canonicalizer.d.ts +19 -3
- package/dist/contracts/contract-canonicalizer.js +172 -27
- package/dist/contracts/contract-hash.d.ts +12 -7
- package/dist/contracts/contract-hash.js +3 -2
- package/dist/contracts/contract-limits.d.ts +4 -1
- package/dist/contracts/contract-limits.js +1 -0
- package/dist/contracts/contract-lookup.d.ts +5 -5
- package/dist/contracts/contract-protocol.d.ts +4 -4
- package/dist/contracts/contract.d.ts +31 -16
- package/dist/contracts/create-requirements.d.ts +35 -0
- package/dist/contracts/create-requirements.js +1 -0
- package/dist/contracts/enum-definition.d.ts +1 -1
- package/dist/contracts/field-check.d.ts +101 -0
- package/dist/contracts/field-check.js +1 -0
- package/dist/contracts/field.d.ts +61 -41
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-shape.d.ts +76 -0
- package/dist/contracts/json-shape.js +1 -0
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- package/dist/contracts/reference-write-limit.d.ts +7 -0
- package/dist/contracts/reference-write-limit.js +1 -0
- package/dist/contracts/resource-operations.d.ts +28 -28
- package/dist/contracts/resource.d.ts +15 -9
- package/dist/contracts/scalar-value-type.d.ts +25 -14
- package/dist/contracts/scalar.d.ts +3 -3
- package/dist/contracts/transaction-capability.d.ts +1 -1
- package/dist/contracts/wire-scalar-format.d.ts +4 -4
- package/dist/framework/contract-view.d.ts +234 -63
- package/dist/framework/framework-construction.error.d.ts +10 -10
- package/dist/framework/framework-construction.error.js +2 -2
- package/dist/framework/framework.d.ts +50 -24
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +95 -32
- package/dist/framework/operation-facade.d.ts +123 -52
- package/dist/framework/operation-facade.js +9 -1
- package/dist/index.d.ts +55 -82
- package/dist/index.js +6 -26
- package/dist/internal.d.ts +40 -0
- package/dist/internal.js +18 -0
- package/dist/operations/operation-arguments.d.ts +316 -201
- package/dist/operations/operation-call.d.ts +27 -28
- package/dist/operations/operation-identity.d.ts +12 -10
- package/dist/operations/operation-identity.js +3 -0
- package/dist/operations/operation-result.d.ts +21 -21
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +41 -12
- package/dist/operations/operation-validator.d.ts +24 -9
- package/dist/operations/operation-validator.js +26 -10
- package/dist/operations/projection-scope.resolver.d.ts +7 -7
- package/dist/operations/structural-limits.walker.d.ts +19 -0
- package/dist/operations/structural-limits.walker.js +489 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +6 -6
- package/dist/protocol/absent-route.responder.d.ts +13 -11
- package/dist/protocol/absent-route.responder.js +42 -16
- package/dist/protocol/contract-document.responder.d.ts +3 -3
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +23 -13
- package/dist/protocol/http-request.decoder.js +19 -11
- package/dist/protocol/http-request.reader.d.ts +3 -3
- package/dist/protocol/http-response.encoder.d.ts +4 -4
- package/dist/protocol/http-response.encoder.js +94 -55
- package/dist/protocol/http-status.table.d.ts +2 -2
- package/dist/protocol/operation-response.guard.d.ts +2 -2
- package/dist/protocol/protocol-surface.d.ts +4 -4
- package/dist/protocol/protocol.binder.d.ts +52 -27
- package/dist/protocol/protocol.binder.js +14 -9
- package/dist/protocol/protocol.handler.d.ts +28 -15
- package/dist/protocol/protocol.handler.js +55 -10
- package/dist/protocol/unmounted-route.error.d.ts +19 -0
- package/dist/protocol/unmounted-route.error.js +10 -0
- package/dist/runtime/caller-data.copier.d.ts +59 -0
- package/dist/runtime/caller-data.copier.js +470 -0
- package/dist/runtime/caller-data.door.d.ts +56 -0
- package/dist/runtime/caller-data.door.js +67 -0
- package/dist/runtime/computed-read-runtime.d.ts +7 -6
- package/dist/runtime/computed-read-runtime.js +61 -55
- package/dist/runtime/computed-value.error.d.ts +13 -0
- package/dist/runtime/computed-value.error.js +9 -0
- package/dist/runtime/context-executor.runtime.d.ts +59 -0
- package/dist/runtime/context-executor.runtime.js +275 -0
- package/dist/runtime/create-requirement.d.ts +22 -57
- package/dist/runtime/create-requirement.js +140 -37
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +1 -1
- package/dist/runtime/diagnostics-reporter.d.ts +64 -22
- package/dist/runtime/diagnostics-reporter.js +35 -4
- package/dist/runtime/error-boundary.d.ts +73 -8
- package/dist/runtime/error-boundary.js +104 -48
- package/dist/runtime/execution-options.d.ts +10 -2
- package/dist/runtime/field-check.evaluator.d.ts +29 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +64 -0
- package/dist/runtime/field-compute.js +1 -0
- package/dist/runtime/field-stage.plan.d.ts +15 -0
- package/dist/runtime/field-stage.plan.js +27 -0
- package/dist/runtime/field-stage.runtime.d.ts +35 -0
- package/dist/runtime/field-stage.runtime.js +143 -0
- package/dist/runtime/field-validator.runtime.d.ts +11 -0
- package/dist/runtime/field-validator.runtime.js +87 -0
- package/dist/runtime/framework-error-class.table.d.ts +33 -0
- package/dist/runtime/framework-error-class.table.js +25 -0
- package/dist/runtime/framework-error.d.ts +79 -7
- package/dist/runtime/framework-error.factory.d.ts +4 -0
- package/dist/runtime/framework-error.factory.js +15 -0
- package/dist/runtime/framework-error.js +23 -2
- package/dist/runtime/interceptor-next.error.d.ts +5 -0
- package/dist/runtime/interceptor-next.error.js +6 -0
- package/dist/runtime/json-value.d.ts +3 -3
- package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
- package/dist/runtime/level-lifecycle.runtime.js +42 -0
- package/dist/runtime/misuse-reporter.d.ts +32 -0
- package/dist/runtime/misuse-reporter.js +19 -0
- package/dist/runtime/mutation-planner.d.ts +19 -10
- package/dist/runtime/mutation-planner.js +62 -36
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-request.d.ts +35 -15
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +125 -30
- package/dist/runtime/operation-runtime.js +423 -83
- package/dist/runtime/outcome-mapper.d.ts +16 -5
- package/dist/runtime/outcome-mapper.js +35 -8
- package/dist/runtime/output-validator.d.ts +16 -6
- package/dist/runtime/output-validator.js +12 -1
- package/dist/runtime/owned-execution.registry.d.ts +13 -0
- package/dist/runtime/owned-execution.registry.js +7 -0
- package/dist/runtime/pipe-output.validator.d.ts +33 -18
- package/dist/runtime/pipe-output.validator.js +12 -12
- package/dist/runtime/pipeline.d.ts +202 -28
- package/dist/runtime/readonly-value.d.ts +32 -0
- package/dist/runtime/readonly-value.js +141 -0
- package/dist/runtime/referential-action.d.ts +7 -0
- package/dist/runtime/request-envelope.validator.d.ts +5 -0
- package/dist/runtime/request-envelope.validator.js +123 -0
- package/dist/runtime/request-id.d.ts +1 -1
- package/dist/runtime/request-state.d.ts +14 -0
- package/dist/runtime/request-state.js +1 -0
- package/dist/runtime/request-state.resolver.d.ts +12 -0
- package/dist/runtime/request-state.resolver.js +20 -0
- package/dist/runtime/scalar-runtime.d.ts +56 -13
- package/dist/runtime/scalar-runtime.js +167 -86
- package/dist/transactions/deferred-operation.d.ts +35 -20
- package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
- package/dist/transactions/operation-arguments-encoder.js +2 -2
- package/dist/transactions/sql-statement.d.ts +77 -0
- package/dist/transactions/sql-statement.js +47 -0
- package/dist/transactions/sql-statement.validator.d.ts +44 -0
- package/dist/transactions/sql-statement.validator.js +134 -0
- package/dist/transactions/transaction-envelope.d.ts +4 -4
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +5 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +23 -9
- package/dist/transactions/transaction-plan-assembler.js +195 -82
- package/dist/transactions/transaction-plan-validator.d.ts +53 -21
- package/dist/transactions/transaction-plan-validator.js +246 -163
- package/dist/transactions/transaction-reference-collector.d.ts +30 -0
- package/dist/transactions/transaction-reference-collector.js +204 -0
- package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
- package/dist/transactions/transaction-reference-resolver.js +27 -10
- package/dist/transactions/transaction-reference-validator.d.ts +34 -4
- package/dist/transactions/transaction-reference-validator.js +82 -43
- package/dist/transactions/transaction-reference.d.ts +30 -58
- package/dist/transactions/transaction-request.d.ts +20 -7
- package/dist/transactions/transaction-response.d.ts +12 -7
- package/dist/transactions/transaction-response.js +24 -1
- package/dist/transactions/transaction-runtime.d.ts +11 -8
- package/dist/transactions/transaction-runtime.js +167 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
- package/dist/transactions/transaction-settlement.runtime.js +120 -0
- package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
- package/dist/transactions/transaction-slot-path-error.js +2 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
- package/dist/transactions/transaction-stage.runtime.js +123 -0
- package/package.json +18 -3
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -35
- package/dist/config/define-fields.js +0 -3
- package/dist/config/framework-behaviors-config.d.ts +0 -30
- package/dist/config/framework-fields-config.d.ts +0 -36
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/operations/operation-boolean-nodes.d.ts +0 -11
- package/dist/operations/operation-boolean-nodes.js +0 -283
- package/dist/operations/operation-nesting.d.ts +0 -8
- package/dist/operations/operation-nesting.js +0 -307
- package/dist/runtime/field-behavior.d.ts +0 -48
- /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
- /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
- /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
- /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { AvDecimal } from "./decimal.js";
|
|
2
|
+
const FAILURE_MESSAGES = {
|
|
3
|
+
"unreadable-value": "Value could not be read.",
|
|
4
|
+
"non-plain-value": "Value must be plain data.",
|
|
5
|
+
};
|
|
6
|
+
export class AvCallerDataError extends Error {
|
|
7
|
+
kind;
|
|
8
|
+
path;
|
|
9
|
+
within;
|
|
10
|
+
name = "AvCallerDataError";
|
|
11
|
+
constructor(kind, path, within) {
|
|
12
|
+
super(FAILURE_MESSAGES[kind]);
|
|
13
|
+
this.kind = kind;
|
|
14
|
+
this.path = path;
|
|
15
|
+
this.within = within;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const NO_POLICY = {};
|
|
19
|
+
const OBJECT_PROTOTYPE = Object.prototype;
|
|
20
|
+
const DATE_PROTOTYPE = Date.prototype;
|
|
21
|
+
const dateValueOf = Date.prototype.getTime;
|
|
22
|
+
const decimalValueOf = AvDecimal.prototype.toString;
|
|
23
|
+
const FAST_WALK_DEPTH = 256;
|
|
24
|
+
const SLOW_WALK = Symbol("slow walk");
|
|
25
|
+
class FastWalkFailure {
|
|
26
|
+
at;
|
|
27
|
+
constructor(at) {
|
|
28
|
+
this.at = at;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const HOLE = Symbol("hole");
|
|
32
|
+
function copyValueType(value, prototype) {
|
|
33
|
+
if (prototype === DATE_PROTOTYPE || value instanceof Date) {
|
|
34
|
+
return new Date(dateValueOf.call(value));
|
|
35
|
+
}
|
|
36
|
+
if (value instanceof AvDecimal) {
|
|
37
|
+
return new AvDecimal(decimalValueOf.call(value));
|
|
38
|
+
}
|
|
39
|
+
if (value instanceof Uint8Array) {
|
|
40
|
+
return new Uint8Array(value);
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
function isPlainPrototype(prototype) {
|
|
45
|
+
return prototype === OBJECT_PROTOTYPE || prototype === null;
|
|
46
|
+
}
|
|
47
|
+
function copyRecordShallow(value, prototype) {
|
|
48
|
+
const copy = prototype === null
|
|
49
|
+
? Object.assign(Object.create(null), value)
|
|
50
|
+
: { ...value };
|
|
51
|
+
const symbols = Object.getOwnPropertySymbols(copy);
|
|
52
|
+
for (let index = 0; index < symbols.length; index += 1) {
|
|
53
|
+
delete copy[symbols[index]];
|
|
54
|
+
}
|
|
55
|
+
return copy;
|
|
56
|
+
}
|
|
57
|
+
function defineKey(record, key, value) {
|
|
58
|
+
if (key === "__proto__") {
|
|
59
|
+
Object.defineProperty(record, key, {
|
|
60
|
+
value,
|
|
61
|
+
writable: true,
|
|
62
|
+
enumerable: true,
|
|
63
|
+
configurable: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
record[key] = value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function copyFast(value, depth, policy) {
|
|
71
|
+
try {
|
|
72
|
+
return copyFastNode(value, depth, policy);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (error === SLOW_WALK || error instanceof FastWalkFailure) {
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
throw new FastWalkFailure(value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function copyFastNode(value, depth, policy) {
|
|
82
|
+
if (depth > FAST_WALK_DEPTH) {
|
|
83
|
+
throw SLOW_WALK;
|
|
84
|
+
}
|
|
85
|
+
if (policy.keep?.(value) === true) {
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
if (policy.mirror?.(value) === true) {
|
|
89
|
+
return mirrorControlData(value);
|
|
90
|
+
}
|
|
91
|
+
if (Array.isArray(value)) {
|
|
92
|
+
const length = value.length;
|
|
93
|
+
const copy = [];
|
|
94
|
+
for (let index = 0; index < length; index += 1) {
|
|
95
|
+
const entry = value[index];
|
|
96
|
+
if (entry === undefined && !(index in value)) {
|
|
97
|
+
throw SLOW_WALK;
|
|
98
|
+
}
|
|
99
|
+
copy.push(typeof entry === "object" && entry !== null
|
|
100
|
+
? copyFast(entry, depth + 1, policy)
|
|
101
|
+
: entry);
|
|
102
|
+
}
|
|
103
|
+
return copy;
|
|
104
|
+
}
|
|
105
|
+
const prototype = Object.getPrototypeOf(value);
|
|
106
|
+
if (isPlainPrototype(prototype)) {
|
|
107
|
+
const copy = copyRecordShallow(value, prototype);
|
|
108
|
+
for (const key in copy) {
|
|
109
|
+
const entry = copy[key];
|
|
110
|
+
if (typeof entry === "object" && entry !== null) {
|
|
111
|
+
copy[key] = copyFast(entry, depth + 1, policy);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return copy;
|
|
115
|
+
}
|
|
116
|
+
const copied = copyValueType(value, prototype);
|
|
117
|
+
if (copied === undefined) {
|
|
118
|
+
throw SLOW_WALK;
|
|
119
|
+
}
|
|
120
|
+
return copied;
|
|
121
|
+
}
|
|
122
|
+
function pathOf(link) {
|
|
123
|
+
const segments = [];
|
|
124
|
+
for (let current = link; current !== undefined; current = current.parent) {
|
|
125
|
+
segments.push(current.segment);
|
|
126
|
+
}
|
|
127
|
+
return segments.reverse();
|
|
128
|
+
}
|
|
129
|
+
function childLink(parent, segment) {
|
|
130
|
+
return { parent, segment };
|
|
131
|
+
}
|
|
132
|
+
function readAt(link, read) {
|
|
133
|
+
try {
|
|
134
|
+
return read();
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
throw new AvCallerDataError("unreadable-value", pathOf(link));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function copySlow(value, policy, failedAt) {
|
|
141
|
+
let root;
|
|
142
|
+
const ancestors = new Map();
|
|
143
|
+
const stack = [
|
|
144
|
+
{
|
|
145
|
+
kind: "visit",
|
|
146
|
+
read: () => value,
|
|
147
|
+
link: undefined,
|
|
148
|
+
assign: (copy) => {
|
|
149
|
+
root = copy;
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
while (stack.length > 0) {
|
|
154
|
+
const task = stack.pop();
|
|
155
|
+
if (task.kind === "leave") {
|
|
156
|
+
if (task.refuse !== false) {
|
|
157
|
+
throw new AvCallerDataError("unreadable-value", pathOf(task.refuse));
|
|
158
|
+
}
|
|
159
|
+
ancestors.delete(task.container);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const { link } = task;
|
|
163
|
+
const current = readAt(link, task.read);
|
|
164
|
+
if (typeof current !== "object" || current === null) {
|
|
165
|
+
task.assign(current);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (ancestors.has(current)) {
|
|
169
|
+
task.assign(ancestors.get(current));
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const refuse = current === failedAt ? link : false;
|
|
173
|
+
const settle = (copy) => {
|
|
174
|
+
if (refuse !== false) {
|
|
175
|
+
throw new AvCallerDataError("unreadable-value", pathOf(refuse));
|
|
176
|
+
}
|
|
177
|
+
task.assign(copy);
|
|
178
|
+
};
|
|
179
|
+
if (readAt(link, () => policy.keep?.(current)) === true) {
|
|
180
|
+
settle(current);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (readAt(link, () => policy.mirror?.(current)) === true) {
|
|
184
|
+
settle(readAt(link, () => mirrorControlData(current)));
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (readAt(link, () => Array.isArray(current))) {
|
|
188
|
+
const source = current;
|
|
189
|
+
const length = readAt(link, () => source.length);
|
|
190
|
+
const copy = new Array(length);
|
|
191
|
+
task.assign(copy);
|
|
192
|
+
ancestors.set(current, copy);
|
|
193
|
+
stack.push({ kind: "leave", container: current, refuse });
|
|
194
|
+
for (let index = length - 1; index >= 0; index -= 1) {
|
|
195
|
+
stack.push({
|
|
196
|
+
kind: "visit",
|
|
197
|
+
read: () => (index in source ? source[index] : HOLE),
|
|
198
|
+
link: childLink(link, index),
|
|
199
|
+
assign: (entry) => {
|
|
200
|
+
if (entry !== HOLE) {
|
|
201
|
+
copy[index] = entry;
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const prototype = readAt(link, () => Object.getPrototypeOf(current));
|
|
209
|
+
if (!isPlainPrototype(prototype)) {
|
|
210
|
+
const copied = readAt(link, () => copyValueType(current, prototype));
|
|
211
|
+
if (copied === undefined) {
|
|
212
|
+
throw new AvCallerDataError("non-plain-value", pathOf(link));
|
|
213
|
+
}
|
|
214
|
+
settle(copied);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const source = current;
|
|
218
|
+
const copy = prototype === null ? Object.create(null) : {};
|
|
219
|
+
task.assign(copy);
|
|
220
|
+
ancestors.set(current, copy);
|
|
221
|
+
stack.push({ kind: "leave", container: current, refuse });
|
|
222
|
+
const keys = readAt(link, () => Object.keys(source));
|
|
223
|
+
for (const key of keys) {
|
|
224
|
+
defineKey(copy, key, undefined);
|
|
225
|
+
}
|
|
226
|
+
for (let index = keys.length - 1; index >= 0; index -= 1) {
|
|
227
|
+
const key = keys[index];
|
|
228
|
+
stack.push({
|
|
229
|
+
kind: "visit",
|
|
230
|
+
read: () => source[key],
|
|
231
|
+
link: childLink(link, key),
|
|
232
|
+
assign: (entry) => {
|
|
233
|
+
defineKey(copy, key, entry);
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return root;
|
|
239
|
+
}
|
|
240
|
+
const UNREADABLE = (() => {
|
|
241
|
+
const { proxy, revoke } = Proxy.revocable({}, {});
|
|
242
|
+
revoke();
|
|
243
|
+
return proxy;
|
|
244
|
+
})();
|
|
245
|
+
const NON_PLAIN_PROTOTYPE = Object.freeze(Object.create(null));
|
|
246
|
+
function reflectNode(source) {
|
|
247
|
+
try {
|
|
248
|
+
const array = Array.isArray(source);
|
|
249
|
+
const prototype = Object.getPrototypeOf(source);
|
|
250
|
+
const keys = Reflect.ownKeys(source);
|
|
251
|
+
const descriptors = [];
|
|
252
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
253
|
+
descriptors.push(Object.getOwnPropertyDescriptor(source, keys[index]) ??
|
|
254
|
+
{});
|
|
255
|
+
}
|
|
256
|
+
return { array, prototype, keys, descriptors };
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function pathSegment(array, key) {
|
|
263
|
+
if (array) {
|
|
264
|
+
const index = Number(key);
|
|
265
|
+
if (Number.isInteger(index) && index >= 0 && String(index) === key) {
|
|
266
|
+
return index;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return key;
|
|
270
|
+
}
|
|
271
|
+
function mirrorControlData(value) {
|
|
272
|
+
const shape = reflectNode(value);
|
|
273
|
+
if (shape === undefined) {
|
|
274
|
+
throw new AvCallerDataError("unreadable-value", []);
|
|
275
|
+
}
|
|
276
|
+
let root;
|
|
277
|
+
const refuse = (kind, path) => {
|
|
278
|
+
throw new AvCallerDataError(kind, path, root);
|
|
279
|
+
};
|
|
280
|
+
const mirrors = new Map();
|
|
281
|
+
const stack = [
|
|
282
|
+
{
|
|
283
|
+
source: value,
|
|
284
|
+
shape,
|
|
285
|
+
link: undefined,
|
|
286
|
+
assign: (mirror) => {
|
|
287
|
+
root = mirror;
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
while (stack.length > 0) {
|
|
292
|
+
const { source, shape, link, assign } = stack.pop();
|
|
293
|
+
const known = mirrors.get(source);
|
|
294
|
+
if (known !== undefined) {
|
|
295
|
+
assign(known);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (!shape.array && !isPlainPrototype(shape.prototype)) {
|
|
299
|
+
let copied;
|
|
300
|
+
try {
|
|
301
|
+
copied = copyValueType(source, shape.prototype);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
copied = undefined;
|
|
305
|
+
}
|
|
306
|
+
if (copied !== undefined) {
|
|
307
|
+
mirrors.set(source, copied);
|
|
308
|
+
assign(copied);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const plain = shape.array
|
|
313
|
+
? shape.prototype === Array.prototype || shape.prototype === null
|
|
314
|
+
: isPlainPrototype(shape.prototype);
|
|
315
|
+
const target = shape.array
|
|
316
|
+
? []
|
|
317
|
+
: shape.prototype === null
|
|
318
|
+
? Object.create(null)
|
|
319
|
+
: {};
|
|
320
|
+
if (!plain) {
|
|
321
|
+
Object.setPrototypeOf(target, NON_PLAIN_PROTOTYPE);
|
|
322
|
+
}
|
|
323
|
+
else if (shape.array && shape.prototype === null) {
|
|
324
|
+
Object.setPrototypeOf(target, null);
|
|
325
|
+
}
|
|
326
|
+
let unreadable;
|
|
327
|
+
for (let index = 0; index < shape.keys.length; index += 1) {
|
|
328
|
+
const key = shape.keys[index];
|
|
329
|
+
const descriptor = shape.descriptors[index];
|
|
330
|
+
const enumerable = descriptor.enumerable === true;
|
|
331
|
+
if (shape.array && key === "length") {
|
|
332
|
+
if (typeof descriptor.value === "number") {
|
|
333
|
+
target.length = descriptor.value;
|
|
334
|
+
}
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (typeof key === "symbol") {
|
|
338
|
+
Object.defineProperty(target, key, {
|
|
339
|
+
value: undefined,
|
|
340
|
+
enumerable,
|
|
341
|
+
configurable: true,
|
|
342
|
+
});
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (!("value" in descriptor)) {
|
|
346
|
+
const at = childLink(link, pathSegment(shape.array, key));
|
|
347
|
+
Object.defineProperty(target, key, {
|
|
348
|
+
get: () => refuse("unreadable-value", pathOf(at)),
|
|
349
|
+
enumerable,
|
|
350
|
+
configurable: true,
|
|
351
|
+
});
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
const store = enumerable &&
|
|
355
|
+
descriptor.writable === true &&
|
|
356
|
+
descriptor.configurable === true
|
|
357
|
+
? (member) => {
|
|
358
|
+
defineKey(target, key, member);
|
|
359
|
+
}
|
|
360
|
+
: (member) => {
|
|
361
|
+
Object.defineProperty(target, key, {
|
|
362
|
+
value: member,
|
|
363
|
+
writable: descriptor.writable === true,
|
|
364
|
+
enumerable,
|
|
365
|
+
configurable: true,
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
const member = descriptor.value;
|
|
369
|
+
if (typeof member !== "object" || member === null) {
|
|
370
|
+
store(member);
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (mirrors.has(member)) {
|
|
374
|
+
store(mirrors.get(member));
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const memberLink = childLink(link, pathSegment(shape.array, key));
|
|
378
|
+
const memberShape = reflectNode(member);
|
|
379
|
+
if (memberShape === undefined) {
|
|
380
|
+
store(UNREADABLE);
|
|
381
|
+
unreadable ??= new Map();
|
|
382
|
+
unreadable.set(key, memberLink);
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
store(undefined);
|
|
386
|
+
stack.push({
|
|
387
|
+
source: member,
|
|
388
|
+
shape: memberShape,
|
|
389
|
+
link: memberLink,
|
|
390
|
+
assign: store,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
const node = plain && unreadable === undefined
|
|
394
|
+
? target
|
|
395
|
+
: new Proxy(target, {
|
|
396
|
+
get: (into, key, receiver) => {
|
|
397
|
+
if (!plain) {
|
|
398
|
+
return refuse("non-plain-value", pathOf(link));
|
|
399
|
+
}
|
|
400
|
+
const at = typeof key === "string" ? unreadable?.get(key) : undefined;
|
|
401
|
+
return at === undefined
|
|
402
|
+
? Reflect.get(into, key, receiver)
|
|
403
|
+
: refuse("unreadable-value", pathOf(at));
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
mirrors.set(source, node);
|
|
407
|
+
assign(node);
|
|
408
|
+
}
|
|
409
|
+
return root;
|
|
410
|
+
}
|
|
411
|
+
export function locateCallerDataError(error, copy) {
|
|
412
|
+
const within = error.within;
|
|
413
|
+
if (within === undefined) {
|
|
414
|
+
return error;
|
|
415
|
+
}
|
|
416
|
+
const at = pathTo(copy, within);
|
|
417
|
+
return at === undefined
|
|
418
|
+
? error
|
|
419
|
+
: new AvCallerDataError(error.kind, [...at, ...error.path]);
|
|
420
|
+
}
|
|
421
|
+
function pathTo(copy, target) {
|
|
422
|
+
const seen = new Set();
|
|
423
|
+
const stack = [
|
|
424
|
+
{ value: copy, path: [] },
|
|
425
|
+
];
|
|
426
|
+
while (stack.length > 0) {
|
|
427
|
+
const { value, path } = stack.pop();
|
|
428
|
+
if (value === target) {
|
|
429
|
+
return path;
|
|
430
|
+
}
|
|
431
|
+
if (typeof value !== "object" ||
|
|
432
|
+
value === null ||
|
|
433
|
+
value === UNREADABLE ||
|
|
434
|
+
seen.has(value)) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
seen.add(value);
|
|
438
|
+
const array = Array.isArray(value);
|
|
439
|
+
for (const key of Object.getOwnPropertyNames(value)) {
|
|
440
|
+
if (array && key === "length") {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
444
|
+
if (descriptor !== undefined && "value" in descriptor) {
|
|
445
|
+
stack.push({
|
|
446
|
+
value: descriptor.value,
|
|
447
|
+
path: [...path, pathSegment(array, key)],
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
function guardNative(operation, onFailure) {
|
|
455
|
+
try {
|
|
456
|
+
return operation();
|
|
457
|
+
}
|
|
458
|
+
catch (failure) {
|
|
459
|
+
return onFailure(failure);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
export function copyCallerData(value, policy = NO_POLICY) {
|
|
463
|
+
if (typeof value !== "object" || value === null) {
|
|
464
|
+
return value;
|
|
465
|
+
}
|
|
466
|
+
return guardNative(() => copyFast(value, 0, policy), (failure) => copySlow(value, policy, failure instanceof FastWalkFailure ? failure.at : undefined));
|
|
467
|
+
}
|
|
468
|
+
export function callerDataFailureMessage(kind) {
|
|
469
|
+
return FAILURE_MESSAGES[kind];
|
|
470
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
2
|
+
import { AvCallerDataError, type CallerDataPath, type CallerDataPolicy } from "./caller-data.copier.js";
|
|
3
|
+
import type { AvMisuseEvent, MisuseReporter } from "./misuse-reporter.js";
|
|
4
|
+
/**
|
|
5
|
+
* Where the arguments an execution entry receives came from.
|
|
6
|
+
*
|
|
7
|
+
* - `"caller"`: a server-side caller's own objects — copied at the door.
|
|
8
|
+
* - `"owned"`: data no caller holds a reference to — a body the protocol decoder
|
|
9
|
+
* parsed with `JSON.parse` for this request alone, or a plan the typed runner
|
|
10
|
+
* assembled from copies its builders took. It is never copied again.
|
|
11
|
+
*
|
|
12
|
+
* Only core's own modules choose `"owned"`: the public `framework.execute` and
|
|
13
|
+
* `executeTransaction` always pass `"caller"`.
|
|
14
|
+
*/
|
|
15
|
+
export type ArgumentsSource = "caller" | "owned";
|
|
16
|
+
/** The operation identity a misuse event may name, as far as it could be read. */
|
|
17
|
+
export type MisuseIdentity = Omit<AvMisuseEvent, "kind" | "path">;
|
|
18
|
+
/**
|
|
19
|
+
* The identity of a request the framework holds a copy of, keeping only what is
|
|
20
|
+
* identity: an origin, a Resource name and a standard operation, each present only
|
|
21
|
+
* when it is one. Nothing the caller wrote anywhere else is carried.
|
|
22
|
+
*/
|
|
23
|
+
export declare function misuseIdentityOf(request: {
|
|
24
|
+
readonly origin?: unknown;
|
|
25
|
+
readonly resource?: unknown;
|
|
26
|
+
readonly family?: unknown;
|
|
27
|
+
readonly variant?: unknown;
|
|
28
|
+
}): MisuseIdentity;
|
|
29
|
+
/**
|
|
30
|
+
* The caller's `V1001` for a refused value at `address` (the door's own spelling of
|
|
31
|
+
* where the copied value stands), reported once to the misuse hook.
|
|
32
|
+
*/
|
|
33
|
+
export declare function refuseCallerData(error: AvCallerDataError, address: CallerDataPath, identity: MisuseIdentity, misuse: MisuseReporter): AvValidationIssue;
|
|
34
|
+
/**
|
|
35
|
+
* A door's copy of one caller value, or the failure it met. The door holds it until
|
|
36
|
+
* its answer is due — a plan answers its steps in order — so the failure is a value
|
|
37
|
+
* here, not yet a response.
|
|
38
|
+
*/
|
|
39
|
+
export type CallerDataCopy = {
|
|
40
|
+
readonly ok: true;
|
|
41
|
+
readonly value: unknown;
|
|
42
|
+
} | {
|
|
43
|
+
readonly ok: false;
|
|
44
|
+
readonly error: AvCallerDataError;
|
|
45
|
+
};
|
|
46
|
+
/** Copies `value` at a door, keeping {@link copyCallerData}'s refusal as a value. */
|
|
47
|
+
export declare function copyAtDoor(value: unknown, policy?: CallerDataPolicy): CallerDataCopy;
|
|
48
|
+
/**
|
|
49
|
+
* A request envelope handed to `framework.execute` or `executeTransaction`, copied at
|
|
50
|
+
* the door: its own members read once (a revoked envelope or a throwing member getter
|
|
51
|
+
* is refused at `[]` or `[member]`), the `members` named here — the protocol identity,
|
|
52
|
+
* the transport context — copied whole, and every other member kept as it is for its
|
|
53
|
+
* own door: the arguments, copied after the availability check, and a plan, which the
|
|
54
|
+
* plan validator inspects and copies step by step.
|
|
55
|
+
*/
|
|
56
|
+
export declare function copyEnvelopeAtDoor(request: unknown, members: readonly string[]): CallerDataCopy;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { parseOperationIdentity } from "../operations/operation-identity.js";
|
|
2
|
+
import { validationIssue } from "../operations/validation-code.js";
|
|
3
|
+
import { AvCallerDataError, copyCallerData, } from "./caller-data.copier.js";
|
|
4
|
+
export function misuseIdentityOf(request) {
|
|
5
|
+
const origin = request.origin === "application" ||
|
|
6
|
+
request.origin === "client" ||
|
|
7
|
+
request.origin === "agent"
|
|
8
|
+
? request.origin
|
|
9
|
+
: undefined;
|
|
10
|
+
const identity = typeof request.family === "string" && typeof request.variant === "string"
|
|
11
|
+
? parseOperationIdentity(request.family, request.variant)
|
|
12
|
+
: undefined;
|
|
13
|
+
return {
|
|
14
|
+
...(origin === undefined ? {} : { origin }),
|
|
15
|
+
...(typeof request.resource === "string"
|
|
16
|
+
? { resource: request.resource }
|
|
17
|
+
: {}),
|
|
18
|
+
...(identity === undefined
|
|
19
|
+
? {}
|
|
20
|
+
: { family: identity.family, variant: identity.variant }),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function refuseCallerData(error, address, identity, misuse) {
|
|
24
|
+
const path = [...address, ...error.path];
|
|
25
|
+
misuse({ kind: error.kind, path, ...identity });
|
|
26
|
+
return validationIssue("V1001", path, error.message);
|
|
27
|
+
}
|
|
28
|
+
export function copyAtDoor(value, policy) {
|
|
29
|
+
try {
|
|
30
|
+
return { ok: true, value: copyCallerData(value, policy) };
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error instanceof AvCallerDataError) {
|
|
34
|
+
return { ok: false, error };
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function copyEnvelopeAtDoor(request, members) {
|
|
40
|
+
const shallow = copyAtDoor(request, {
|
|
41
|
+
keep: (value) => value !== request,
|
|
42
|
+
});
|
|
43
|
+
if (!shallow.ok ||
|
|
44
|
+
typeof shallow.value !== "object" ||
|
|
45
|
+
shallow.value === null ||
|
|
46
|
+
Array.isArray(shallow.value)) {
|
|
47
|
+
return shallow;
|
|
48
|
+
}
|
|
49
|
+
const envelope = shallow.value;
|
|
50
|
+
for (const member of members) {
|
|
51
|
+
if (!Object.hasOwn(envelope, member)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const copy = copyAtDoor(envelope[member]);
|
|
55
|
+
if (!copy.ok) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
error: new AvCallerDataError(copy.error.kind, [
|
|
59
|
+
member,
|
|
60
|
+
...copy.error.path,
|
|
61
|
+
]),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
envelope[member] = copy.value;
|
|
65
|
+
}
|
|
66
|
+
return { ok: true, value: envelope };
|
|
67
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
2
|
+
import type { ResolvedComputeConfig } from "../config/field-compute.resolver.js";
|
|
3
|
+
import type { AvContract, AvContractCore } from "../contracts/contract.js";
|
|
4
|
+
import type { AvComputeContext } from "./field-compute.js";
|
|
3
5
|
import type { OperationExecutionRequest } from "./operation-request.js";
|
|
4
|
-
|
|
5
|
-
type ContextFactory = () => PipelineContext;
|
|
6
|
+
type ContextFactory = () => AvComputeContext;
|
|
6
7
|
export type RelationReadPlan = {
|
|
7
8
|
readonly field: string;
|
|
8
9
|
readonly cardinality: "one" | "many";
|
|
@@ -27,10 +28,10 @@ export type PlannedReadOperation = {
|
|
|
27
28
|
* are never mutated and hidden dependencies are resolved through the Core
|
|
28
29
|
* Contract.
|
|
29
30
|
*/
|
|
30
|
-
export declare function planReadOperation(core:
|
|
31
|
+
export declare function planReadOperation(core: AvContractCore, model: AvAdapterModel, active: AvContract, compute: ResolvedComputeConfig | undefined, request: OperationExecutionRequest, args: unknown): PlannedReadOperation;
|
|
31
32
|
/**
|
|
32
33
|
* Materialize computed scalar reads and remove internal dependency fields,
|
|
33
34
|
* against `active` — the Contract `planReadOperation` was given as `active`.
|
|
34
35
|
*/
|
|
35
|
-
export declare function materializeReadOperation(active:
|
|
36
|
+
export declare function materializeReadOperation(active: AvContract, compute: ResolvedComputeConfig | undefined, request: OperationExecutionRequest, plan: PlannedReadOperation, value: unknown, contextFactory: ContextFactory): Promise<unknown>;
|
|
36
37
|
export {};
|