@aventara/core 1.0.0-rc.0 → 1.0.0-rc.10
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 +2068 -1
- package/ERRORS.md +142 -0
- package/README.md +485 -60
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
- package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
- package/dist/adapters/adapter-field.d.ts +33 -11
- package/dist/adapters/adapter-identifier.d.ts +15 -6
- package/dist/adapters/adapter-identifier.js +6 -1
- package/dist/adapters/adapter-model.d.ts +18 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +21 -6
- package/dist/adapters/adapter-resource.d.ts +23 -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 +59 -29
- 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/{json → avz}/avz.js +150 -8
- package/dist/{json → avz}/index.d.ts +2 -1
- package/dist/{json → avz}/json-shape.registry.d.ts +9 -8
- package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
- package/dist/{json → avz}/zod-issue.translator.js +7 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
- package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
- package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
- package/dist/compiler/contract.compiler.d.ts +23 -17
- package/dist/compiler/contract.compiler.js +753 -443
- 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/compiler/managed-elsewhere.projector.d.ts +52 -0
- package/dist/compiler/managed-elsewhere.projector.js +179 -0
- package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
- package/dist/compiler/managed-elsewhere.validator.js +74 -0
- package/dist/config/any-framework-config.d.ts +19 -12
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +73 -0
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +98 -31
- package/dist/config/config.resolver.js +173 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +792 -69
- package/dist/config/define-resource.d.ts +53 -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 +4 -3
- package/dist/config/exact-framework-config.d.ts +325 -0
- package/dist/config/field-compute.resolver.d.ts +21 -0
- package/dist/config/field-compute.resolver.js +123 -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 +148 -39
- 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 +127 -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/access-route.rules.d.ts +10 -0
- package/dist/contracts/access-route.rules.js +45 -0
- package/dist/contracts/capability.d.ts +37 -12
- package/dist/contracts/capability.js +20 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +621 -114
- package/dist/contracts/client-contract-structure.validator.js +189 -10
- package/dist/contracts/contract-access.d.ts +29 -0
- package/dist/contracts/contract-access.js +1 -0
- package/dist/contracts/contract-canonicalizer.d.ts +27 -3
- package/dist/contracts/contract-canonicalizer.js +168 -29
- package/dist/contracts/contract-hash.d.ts +11 -7
- package/dist/contracts/contract-hash.js +4 -3
- 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 +51 -17
- 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 +109 -42
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-schema.projector.d.ts +11 -0
- package/dist/contracts/json-schema.projector.js +78 -0
- package/dist/contracts/json-shape.d.ts +12 -1
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- 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 +17 -15
- 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/access-facade.d.ts +116 -0
- package/dist/framework/access-facade.js +120 -0
- package/dist/framework/contract-view.d.ts +315 -145
- package/dist/framework/framework-construction.error.d.ts +21 -11
- package/dist/framework/framework-construction.error.js +20 -4
- package/dist/framework/framework.d.ts +71 -26
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +150 -38
- package/dist/framework/operation-facade.d.ts +192 -54
- package/dist/framework/operation-facade.js +10 -1
- package/dist/index.d.ts +67 -50
- package/dist/index.js +7 -6
- package/dist/internal.d.ts +20 -10
- package/dist/internal.js +9 -1
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +381 -228
- package/dist/operations/operation-call.d.ts +31 -28
- package/dist/operations/operation-identity.d.ts +10 -10
- package/dist/operations/operation-result.d.ts +25 -23
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +172 -38
- package/dist/operations/operation-validator.d.ts +10 -10
- package/dist/operations/projection-scope.resolver.d.ts +6 -6
- package/dist/operations/structural-limits.walker.d.ts +7 -7
- package/dist/operations/structural-limits.walker.js +145 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +10 -6
- package/dist/operations/write-scope.resolver.js +2 -0
- package/dist/policy/access-provider.interface.d.ts +91 -0
- package/dist/policy/access-provider.interface.js +1 -0
- package/dist/policy/access-provider.registry.d.ts +17 -0
- package/dist/policy/access-provider.registry.js +15 -0
- package/dist/policy/access-question.d.ts +20 -0
- package/dist/policy/access-question.js +1 -0
- package/dist/policy/access-question.registry.d.ts +5 -0
- package/dist/policy/access-question.registry.js +19 -0
- package/dist/policy/access-question.runtime.d.ts +36 -0
- package/dist/policy/access-question.runtime.js +297 -0
- package/dist/policy/access-verb.table.d.ts +56 -0
- package/dist/policy/access-verb.table.js +21 -0
- package/dist/policy/access-verbs.d.ts +46 -0
- package/dist/policy/access-verbs.js +1 -0
- package/dist/policy/policy-admission.d.ts +20 -0
- package/dist/policy/policy-admission.js +409 -0
- package/dist/policy/policy-after-update.runtime.d.ts +79 -0
- package/dist/policy/policy-after-update.runtime.js +208 -0
- package/dist/policy/policy-condition.d.ts +15 -0
- package/dist/policy/policy-condition.js +36 -0
- package/dist/policy/policy-engine.d.ts +205 -0
- package/dist/policy/policy-engine.js +1 -0
- package/dist/policy/policy-named-rows.d.ts +18 -0
- package/dist/policy/policy-named-rows.js +51 -0
- package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
- package/dist/policy/policy-nested-write.runtime.js +545 -0
- package/dist/policy/policy-read.runtime.d.ts +81 -0
- package/dist/policy/policy-read.runtime.js +503 -0
- package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
- package/dist/policy/policy-reference-write.runtime.js +345 -0
- package/dist/policy/policy-request.d.ts +41 -0
- package/dist/policy/policy-request.js +63 -0
- package/dist/policy/policy-session.d.ts +106 -0
- package/dist/policy/policy-session.js +295 -0
- package/dist/policy/policy-startup.validator.d.ts +10 -0
- package/dist/policy/policy-startup.validator.js +112 -0
- package/dist/policy/policy-write.runtime.d.ts +39 -0
- package/dist/policy/policy-write.runtime.js +532 -0
- package/dist/prebuilt/core-version.generated.d.ts +2 -0
- package/dist/prebuilt/core-version.generated.js +1 -0
- package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
- package/dist/prebuilt/prebuilt-changes.js +65 -0
- package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
- package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
- package/dist/prebuilt/prebuilt-contracts.js +1 -0
- package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
- package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.js +229 -0
- package/dist/protocol/absent-route.responder.d.ts +17 -34
- package/dist/protocol/absent-route.responder.js +53 -20
- package/dist/protocol/contract-document.responder.d.ts +5 -4
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +33 -13
- package/dist/protocol/http-request.decoder.js +34 -11
- package/dist/protocol/http-request.reader.d.ts +9 -6
- package/dist/protocol/http-request.reader.js +1 -0
- 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-headers.d.ts +3 -3
- package/dist/protocol/protocol-surface.d.ts +10 -5
- package/dist/protocol/protocol-surface.js +7 -0
- package/dist/protocol/protocol.binder.d.ts +66 -28
- package/dist/protocol/protocol.binder.js +16 -10
- package/dist/protocol/protocol.handler.d.ts +34 -14
- package/dist/protocol/protocol.handler.js +122 -18
- package/dist/protocol/unmounted-route.error.d.ts +4 -4
- package/dist/protocol/unmounted-route.error.js +2 -2
- package/dist/runtime/caller-data.copier.d.ts +22 -7
- package/dist/runtime/caller-data.copier.js +30 -17
- package/dist/runtime/caller-data.door.d.ts +18 -11
- package/dist/runtime/caller-data.door.js +6 -4
- package/dist/runtime/computed-read-runtime.d.ts +12 -6
- package/dist/runtime/computed-read-runtime.js +271 -71
- package/dist/runtime/computed-value.error.d.ts +7 -6
- package/dist/runtime/computed-value.error.js +5 -4
- package/dist/runtime/context-executor.runtime.d.ts +60 -0
- package/dist/runtime/context-executor.runtime.js +277 -0
- package/dist/runtime/core-class.brand.d.ts +10 -0
- package/dist/runtime/core-class.brand.js +21 -0
- package/dist/runtime/create-requirement.d.ts +34 -79
- package/dist/runtime/create-requirement.js +205 -74
- package/dist/runtime/decimal.d.ts +16 -2
- package/dist/runtime/decimal.js +22 -1
- package/dist/runtime/diagnostics-reporter.d.ts +91 -30
- package/dist/runtime/diagnostics-reporter.js +37 -1
- package/dist/runtime/error-boundary.d.ts +73 -9
- package/dist/runtime/error-boundary.js +57 -19
- package/dist/runtime/error-guidance.d.ts +12 -0
- package/dist/runtime/error-guidance.js +1 -0
- package/dist/runtime/error.catalog.d.ts +49 -0
- package/dist/runtime/error.catalog.js +49 -0
- package/dist/runtime/execution-options.d.ts +18 -2
- package/dist/runtime/field-check.evaluator.d.ts +27 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +65 -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 +37 -0
- package/dist/runtime/field-stage.runtime.js +147 -0
- package/dist/runtime/field-validator.runtime.d.ts +29 -0
- package/dist/runtime/field-validator.runtime.js +126 -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 +68 -8
- 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 +32 -2
- package/dist/runtime/framework-warning.emitter.d.ts +6 -0
- package/dist/runtime/framework-warning.emitter.js +8 -0
- 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 +11 -6
- package/dist/runtime/level-lifecycle.runtime.d.ts +26 -0
- package/dist/runtime/level-lifecycle.runtime.js +40 -0
- package/dist/runtime/misuse-reporter.d.ts +12 -12
- package/dist/runtime/mutation-planner.d.ts +20 -16
- package/dist/runtime/mutation-planner.js +48 -35
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-code.guidance.d.ts +6 -0
- package/dist/runtime/operation-code.guidance.js +167 -0
- package/dist/runtime/operation-request.d.ts +45 -11
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +133 -27
- package/dist/runtime/operation-runtime.js +576 -84
- package/dist/runtime/outcome-mapper.d.ts +17 -5
- package/dist/runtime/outcome-mapper.js +23 -6
- package/dist/runtime/output-validator.d.ts +11 -11
- package/dist/runtime/output-validator.js +3 -3
- package/dist/runtime/owned-execution.registry.d.ts +16 -6
- package/dist/runtime/pipe-output.validator.d.ts +43 -18
- package/dist/runtime/pipe-output.validator.js +15 -13
- package/dist/runtime/pipeline.d.ts +221 -34
- package/dist/runtime/readonly-value.d.ts +47 -0
- package/dist/runtime/readonly-value.js +189 -0
- package/dist/runtime/referential-action.d.ts +1 -1
- package/dist/runtime/request-envelope.validator.d.ts +3 -3
- package/dist/runtime/request-envelope.validator.js +12 -7
- 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 +33 -25
- package/dist/runtime/scalar-runtime.js +105 -38
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +128 -0
- 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 +8 -3
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +85 -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 +167 -0
- package/dist/transactions/transaction-envelope.d.ts +9 -8
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +7 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +30 -13
- package/dist/transactions/transaction-plan-assembler.js +184 -32
- package/dist/transactions/transaction-plan-validator.d.ts +50 -25
- package/dist/transactions/transaction-plan-validator.js +96 -38
- package/dist/transactions/transaction-reference-collector.d.ts +5 -5
- package/dist/transactions/transaction-reference-resolver.d.ts +21 -3
- package/dist/transactions/transaction-reference-resolver.js +26 -14
- package/dist/transactions/transaction-reference-validator.d.ts +74 -4
- package/dist/transactions/transaction-reference-validator.js +129 -71
- package/dist/transactions/transaction-reference.d.ts +14 -14
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +22 -9
- package/dist/transactions/transaction-response.d.ts +6 -6
- package/dist/transactions/transaction-runtime.d.ts +12 -8
- package/dist/transactions/transaction-runtime.js +218 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +52 -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 +4 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +83 -0
- package/dist/transactions/transaction-stage.runtime.js +126 -0
- package/package.json +11 -9
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -42
- 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 -42
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/json/avz.d.ts +0 -96
- 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/{json → avz}/index.js +0 -0
- /package/dist/{json → avz}/json-shape.registry.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
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { validationIssue } from "../operations/validation-code.js";
|
|
1
|
+
import { VALIDATION_CODE_MESSAGES, validationIssue, } from "../operations/validation-code.js";
|
|
2
|
+
import { AvCallerDataError, } from "../runtime/caller-data.copier.js";
|
|
2
3
|
import { copyAtDoor, refuseCallerData } from "../runtime/caller-data.door.js";
|
|
3
4
|
import { operationFailure } from "../runtime/operation-response.js";
|
|
4
5
|
import { mapValidationOutcome } from "../runtime/outcome-mapper.js";
|
|
6
|
+
import { withoutUnsentWriteValues } from "../runtime/unsent-value.normalizer.js";
|
|
5
7
|
import { encodeOperationArgumentsForWire } from "./operation-arguments-encoder.js";
|
|
6
8
|
import { computeOperationFingerprint } from "./operation-fingerprint.js";
|
|
9
|
+
import { readSqlTemplate } from "./sql-statement.js";
|
|
10
|
+
import { routeTransactionReferenceCandidate } from "./transaction-reference.js";
|
|
7
11
|
import { transactionOperationFailure } from "./transaction-response.js";
|
|
12
|
+
const SQL_STEP_NODE = Object.freeze({ fingerprint: null });
|
|
8
13
|
function isPlainRecord(value) {
|
|
9
14
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
10
15
|
return false;
|
|
@@ -13,26 +18,76 @@ function isPlainRecord(value) {
|
|
|
13
18
|
return prototype === Object.prototype || prototype === null;
|
|
14
19
|
}
|
|
15
20
|
const KEEP = Symbol("keep");
|
|
16
|
-
function rebuildArguments(
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function rebuildArguments(root, leaf) {
|
|
22
|
+
const pathOf = (parent, key) => () => {
|
|
23
|
+
const segments = [];
|
|
24
|
+
if (key !== undefined) {
|
|
25
|
+
segments.push(key);
|
|
26
|
+
}
|
|
27
|
+
for (let frame = parent; frame?.key !== undefined; frame = frame.parent) {
|
|
28
|
+
segments.push(frame.key);
|
|
29
|
+
}
|
|
30
|
+
return segments.reverse();
|
|
31
|
+
};
|
|
32
|
+
const ancestors = new Set();
|
|
33
|
+
const finish = (frame) => {
|
|
34
|
+
ancestors.delete(frame.source);
|
|
35
|
+
if (!Array.isArray(frame.source)) {
|
|
36
|
+
return Object.fromEntries(frame.built);
|
|
37
|
+
}
|
|
38
|
+
const rebuilt = new Array(frame.source.length);
|
|
39
|
+
for (const [index, value] of frame.built) {
|
|
40
|
+
rebuilt[index] = value;
|
|
41
|
+
}
|
|
42
|
+
return rebuilt;
|
|
43
|
+
};
|
|
44
|
+
const enter = (value, parent, key) => {
|
|
45
|
+
const replaced = leaf(value, pathOf(parent, key));
|
|
46
|
+
if (replaced !== KEEP) {
|
|
47
|
+
return { value: replaced };
|
|
48
|
+
}
|
|
49
|
+
if (!Array.isArray(value) && !isPlainRecord(value)) {
|
|
50
|
+
return { value };
|
|
51
|
+
}
|
|
52
|
+
if (Object.hasOwn(value, "$ref")) {
|
|
53
|
+
return { value };
|
|
54
|
+
}
|
|
55
|
+
if (ancestors.has(value)) {
|
|
56
|
+
return { value };
|
|
57
|
+
}
|
|
58
|
+
ancestors.add(value);
|
|
59
|
+
const keys = Array.isArray(value)
|
|
60
|
+
? Object.keys(value).map(Number)
|
|
61
|
+
: Object.keys(value);
|
|
62
|
+
return { source: value, keys, built: [], parent, key, next: 0 };
|
|
63
|
+
};
|
|
64
|
+
const first = enter(root, undefined, undefined);
|
|
65
|
+
if (!("source" in first)) {
|
|
66
|
+
return first.value;
|
|
23
67
|
}
|
|
24
|
-
|
|
25
|
-
|
|
68
|
+
let frame = first;
|
|
69
|
+
for (;;) {
|
|
70
|
+
if (frame.next < frame.keys.length) {
|
|
71
|
+
const key = frame.keys[frame.next];
|
|
72
|
+
frame.next += 1;
|
|
73
|
+
const entry = frame.source[key];
|
|
74
|
+
const child = enter(entry, frame, key);
|
|
75
|
+
if ("source" in child) {
|
|
76
|
+
frame = child;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
frame.built.push([key, child.value]);
|
|
80
|
+
}
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const rebuilt = finish(frame);
|
|
84
|
+
const parent = frame.parent;
|
|
85
|
+
if (parent === undefined) {
|
|
86
|
+
return rebuilt;
|
|
87
|
+
}
|
|
88
|
+
parent.built.push([frame.key, rebuilt]);
|
|
89
|
+
frame = parent;
|
|
26
90
|
}
|
|
27
|
-
ancestors.add(value);
|
|
28
|
-
const rebuilt = Array.isArray(value)
|
|
29
|
-
? value.map((entry, index) => rebuildArguments(entry, [...path, index], leaf, ancestors))
|
|
30
|
-
: Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
31
|
-
key,
|
|
32
|
-
rebuildArguments(entry, [...path, key], leaf, ancestors),
|
|
33
|
-
]));
|
|
34
|
-
ancestors.delete(value);
|
|
35
|
-
return rebuilt;
|
|
36
91
|
}
|
|
37
92
|
function operationEntryFailure(operation, message) {
|
|
38
93
|
return transactionOperationFailure(operationFailure("A2004", {
|
|
@@ -43,33 +98,35 @@ function operationEntryFailure(operation, message) {
|
|
|
43
98
|
function referenceFailure(issue, operation) {
|
|
44
99
|
return transactionOperationFailure(mapValidationOutcome([issue]), operation);
|
|
45
100
|
}
|
|
101
|
+
const STEP_REFERENCE_MIRROR = (value) => Object.hasOwn(value, "$ref");
|
|
46
102
|
export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
47
103
|
const handles = new WeakMap();
|
|
48
104
|
const placeholders = new WeakMap();
|
|
49
105
|
const originOf = (origin) => origin === "application"
|
|
50
106
|
? { origin: "application" }
|
|
51
107
|
: { origin: "client", protocol };
|
|
52
|
-
const snapshot = (args) => {
|
|
108
|
+
const snapshot = (args, mirror) => {
|
|
53
109
|
const copy = copyAtDoor(args, {
|
|
54
110
|
keep: (value) => placeholders.has(value),
|
|
111
|
+
...(mirror === undefined ? {} : { mirror }),
|
|
55
112
|
});
|
|
56
113
|
return copy.ok ? { args: copy.value } : { args: {}, refused: copy.error };
|
|
57
114
|
};
|
|
58
115
|
const placeholderSites = (args) => {
|
|
59
116
|
const sites = [];
|
|
60
|
-
rebuildArguments(args,
|
|
117
|
+
rebuildArguments(args, (value, pathOf) => {
|
|
61
118
|
const placeholder = typeof value === "object" && value !== null
|
|
62
119
|
? placeholders.get(value)
|
|
63
120
|
: undefined;
|
|
64
121
|
if (placeholder === undefined) {
|
|
65
122
|
return KEEP;
|
|
66
123
|
}
|
|
67
|
-
sites.push({ path, object: value, placeholder });
|
|
124
|
+
sites.push({ path: pathOf(), object: value, placeholder });
|
|
68
125
|
return value;
|
|
69
126
|
});
|
|
70
127
|
return sites;
|
|
71
128
|
};
|
|
72
|
-
const
|
|
129
|
+
const createHandle = (record) => {
|
|
73
130
|
const handle = Object.freeze({
|
|
74
131
|
$ref: (field) => {
|
|
75
132
|
const placeholder = Object.freeze({
|
|
@@ -79,13 +136,77 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
|
79
136
|
return placeholder;
|
|
80
137
|
},
|
|
81
138
|
});
|
|
82
|
-
handles.set(handle,
|
|
139
|
+
handles.set(handle, record);
|
|
140
|
+
return handle;
|
|
141
|
+
};
|
|
142
|
+
const defer = (origin, resource, identity, args, forms = "wire") => {
|
|
143
|
+
const snapped = snapshot(args, STEP_REFERENCE_MIRROR);
|
|
144
|
+
let copy = snapped;
|
|
145
|
+
if (origin === "client" &&
|
|
146
|
+
forms === "application" &&
|
|
147
|
+
snapped.refused === undefined) {
|
|
148
|
+
try {
|
|
149
|
+
copy = {
|
|
150
|
+
args: encodeOperationArgumentsForWire(contracts.client, { resource, ...identity }, snapped.args),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
if (!(error instanceof AvCallerDataError)) {
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let sent = copy.args;
|
|
160
|
+
try {
|
|
161
|
+
sent = withoutUnsentWriteValues(origin === "application" ? contracts.application : contracts.client, { resource, family: identity.family }, copy.args);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (!(error instanceof AvCallerDataError)) {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return createHandle({
|
|
169
|
+
kind: "operation",
|
|
83
170
|
origin,
|
|
84
171
|
resource,
|
|
85
172
|
identity,
|
|
86
|
-
...
|
|
173
|
+
...copy,
|
|
174
|
+
args: sent,
|
|
87
175
|
});
|
|
88
|
-
|
|
176
|
+
};
|
|
177
|
+
const deferSql = (strings, values) => {
|
|
178
|
+
const copy = snapshot(values, STEP_REFERENCE_MIRROR);
|
|
179
|
+
return createHandle({
|
|
180
|
+
kind: "sql",
|
|
181
|
+
strings: readSqlTemplate(strings, values.length),
|
|
182
|
+
values: Array.isArray(copy.args) ? copy.args : [],
|
|
183
|
+
...(copy.refused === undefined ? {} : { refused: copy.refused }),
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
const recordPlaceholderSites = (record) => placeholderSites(record.kind === "sql" ? record.values : record.args);
|
|
187
|
+
const planSqlStatement = (record, positions) => {
|
|
188
|
+
const values = record.values.map((value) => {
|
|
189
|
+
const sites = placeholderSites(value);
|
|
190
|
+
const [site] = sites;
|
|
191
|
+
if (site === undefined) {
|
|
192
|
+
return routeTransactionReferenceCandidate(value).kind === "ordinary"
|
|
193
|
+
? { kind: "value", value }
|
|
194
|
+
: { kind: "candidate", candidate: value };
|
|
195
|
+
}
|
|
196
|
+
if (site.path.length > 0) {
|
|
197
|
+
return { kind: "misplaced-reference", path: site.path };
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
kind: "reference",
|
|
201
|
+
operation: positions.get(site.placeholder.source),
|
|
202
|
+
field: site.placeholder.field,
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
return {
|
|
206
|
+
strings: record.strings,
|
|
207
|
+
values,
|
|
208
|
+
...(record.refused === undefined ? {} : { refused: record.refused }),
|
|
209
|
+
};
|
|
89
210
|
};
|
|
90
211
|
const assemble = async (input) => {
|
|
91
212
|
const list = copyAtDoor(input, { keep: (value) => value !== input });
|
|
@@ -131,12 +252,35 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
|
131
252
|
positions.set(entry, index);
|
|
132
253
|
records.push(record);
|
|
133
254
|
}
|
|
255
|
+
const originOfRecord = (record) => record.kind === "sql" ? "application" : record.origin;
|
|
256
|
+
const [first] = records;
|
|
257
|
+
if (first !== undefined) {
|
|
258
|
+
const planOrigin = originOfRecord(first);
|
|
259
|
+
const other = records.findIndex((record) => originOfRecord(record) !== planOrigin);
|
|
260
|
+
if (other !== -1) {
|
|
261
|
+
return {
|
|
262
|
+
ok: false,
|
|
263
|
+
response: transactionOperationFailure(operationFailure("A2004", {
|
|
264
|
+
message: "Transaction plan failed framework validation.",
|
|
265
|
+
issues: [
|
|
266
|
+
validationIssue("V1020", [], VALIDATION_CODE_MESSAGES.V1020),
|
|
267
|
+
],
|
|
268
|
+
}), other),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
134
272
|
for (const [index, record] of records.entries()) {
|
|
135
|
-
for (const { path, placeholder } of
|
|
273
|
+
for (const { path, placeholder } of recordPlaceholderSites(record)) {
|
|
136
274
|
if (!positions.has(placeholder.source)) {
|
|
137
275
|
return {
|
|
138
276
|
ok: false,
|
|
139
|
-
response: referenceFailure(validationIssue("V1010", [
|
|
277
|
+
response: referenceFailure(validationIssue("V1010", [
|
|
278
|
+
"operations",
|
|
279
|
+
index,
|
|
280
|
+
record.kind === "sql" ? "values" : "args",
|
|
281
|
+
...path,
|
|
282
|
+
"$ref",
|
|
283
|
+
], "Transaction reference names an operation that is not in this transaction."), index),
|
|
140
284
|
};
|
|
141
285
|
}
|
|
142
286
|
}
|
|
@@ -152,6 +296,9 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
|
152
296
|
};
|
|
153
297
|
const materialize = async (index) => {
|
|
154
298
|
const record = records[index];
|
|
299
|
+
if (record.kind === "sql") {
|
|
300
|
+
return SQL_STEP_NODE;
|
|
301
|
+
}
|
|
155
302
|
const bound = new Map();
|
|
156
303
|
await Promise.all(placeholderSites(record.args).map(async ({ object, placeholder }) => {
|
|
157
304
|
const operation = positions.get(placeholder.source);
|
|
@@ -160,7 +307,7 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
|
160
307
|
$ref: { operation, fingerprint, path: [placeholder.field] },
|
|
161
308
|
});
|
|
162
309
|
}));
|
|
163
|
-
const args = rebuildArguments(record.args,
|
|
310
|
+
const args = rebuildArguments(record.args, (value) => typeof value === "object" && value !== null && bound.has(value)
|
|
164
311
|
? bound.get(value)
|
|
165
312
|
: KEEP);
|
|
166
313
|
return {
|
|
@@ -192,9 +339,14 @@ export function createTransactionPlanAssembler(contracts, protocol, misuse) {
|
|
|
192
339
|
plan: {
|
|
193
340
|
operations: await Promise.all(records.map((_, index) => nodeAt(index))),
|
|
194
341
|
},
|
|
195
|
-
origins: records.map((record) => originOf(record.origin)),
|
|
196
|
-
refused: new Map(records.flatMap((record, index) => record.
|
|
342
|
+
origins: records.map((record) => originOf(record.kind === "sql" ? "application" : record.origin)),
|
|
343
|
+
refused: new Map(records.flatMap((record, index) => record.kind === "sql" || record.refused === undefined
|
|
344
|
+
? []
|
|
345
|
+
: [[index, record.refused]])),
|
|
346
|
+
statements: new Map(records.flatMap((record, index) => record.kind === "sql"
|
|
347
|
+
? [[index, planSqlStatement(record, positions)]]
|
|
348
|
+
: [])),
|
|
197
349
|
};
|
|
198
350
|
};
|
|
199
|
-
return { defer, assemble };
|
|
351
|
+
return { defer, deferSql, assemble };
|
|
200
352
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
2
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
3
|
+
import type { AvScalarField } from "../contracts/field.js";
|
|
4
4
|
import type { SemanticOperationArguments } from "../operations/operation-validator.js";
|
|
5
|
-
import {
|
|
5
|
+
import { AvCallerDataError } from "../runtime/caller-data.copier.js";
|
|
6
6
|
import { type ReadProjectionPlan } from "../runtime/computed-read-runtime.js";
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
7
|
+
import type { AvOperationRequest } from "../runtime/operation-request.js";
|
|
8
|
+
import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
|
|
9
9
|
import type { OperationPipelineDependencies } from "../runtime/operation-runtime.js";
|
|
10
10
|
import type { CascadeClosure } from "../runtime/referential-action.js";
|
|
11
11
|
import type { OperationFingerprint } from "./deferred-operation.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type { PlannedSqlStatement, ValidatedSqlStatement } from "./sql-statement.js";
|
|
13
|
+
import type { AvTransactionReference } from "./transaction-reference.js";
|
|
13
14
|
import { type TransactionSlotShape } from "./transaction-reference.js";
|
|
14
15
|
import { type TransactionReferenceCandidateSlot } from "./transaction-reference-collector.js";
|
|
15
|
-
import type {
|
|
16
|
+
import type { AvTransactionRequest, TransactionOperationOrigin } from "./transaction-request.js";
|
|
16
17
|
/**
|
|
17
18
|
* Where a plan's step arguments came from, so the validator knows whether to copy
|
|
18
19
|
* them at the door (see `ArgumentsSource`):
|
|
@@ -22,51 +23,73 @@ import type { FrameworkTransactionRequest, TransactionOperationOrigin } from "./
|
|
|
22
23
|
* await, so a step revoked or changed after the call is never read again;
|
|
23
24
|
* - `"owned"` — a plan the protocol decoder parsed, or the typed runner assembled
|
|
24
25
|
* from its builders' copies; `refused` names the steps whose arguments a builder
|
|
25
|
-
* could not copy, answered at their turn
|
|
26
|
+
* could not copy, answered at their turn, and `statements` the steps that are
|
|
27
|
+
* `appTx.$sql` statements, which only the typed runner builds: they have no wire
|
|
28
|
+
* form, so no plan a caller or a remote client hands in can hold one.
|
|
26
29
|
*/
|
|
27
30
|
export type PlanArguments = {
|
|
28
31
|
readonly source: "caller";
|
|
29
32
|
} | {
|
|
30
33
|
readonly source: "owned";
|
|
31
|
-
readonly refused?: ReadonlyMap<number,
|
|
34
|
+
readonly refused?: ReadonlyMap<number, AvCallerDataError>;
|
|
35
|
+
readonly statements?: ReadonlyMap<number, PlannedSqlStatement>;
|
|
32
36
|
};
|
|
37
|
+
/** A plan taken at a call, and the steps whose arguments could not be copied. */
|
|
38
|
+
type CapturedPlan = {
|
|
39
|
+
readonly plan: unknown;
|
|
40
|
+
readonly refused: ReadonlyMap<number, AvCallerDataError>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A host's parsed plan taken at `protocol.handleTransaction`'s call, before its first
|
|
44
|
+
* await (rc.2, e2e batch 2): its structure mirrored by descriptors, which is how this
|
|
45
|
+
* validator inspects it — so no getter it refuses runs, and every accessor stays one
|
|
46
|
+
* for it to refuse — and each step's `args` copied as {@link captureSteps} copies a
|
|
47
|
+
* caller's, its `$ref` control objects mirrored. Run as an `"owned"` plan with
|
|
48
|
+
* `refused`, it is answered exactly as the plan the host held at the call. A plan
|
|
49
|
+
* that is no object, or cannot be reflected, is returned as it is: nothing in it can
|
|
50
|
+
* change.
|
|
51
|
+
*/
|
|
52
|
+
export declare function capturePlanAtCall(plan: unknown): CapturedPlan;
|
|
33
53
|
export type { TransactionReferenceCandidateSlot } from "./transaction-reference-collector.js";
|
|
34
54
|
/** One validated Transaction Slot: where it is, what it holds, and its reference. */
|
|
35
55
|
export type TransactionReferenceSlot = {
|
|
36
56
|
readonly path: readonly (string | number)[];
|
|
37
57
|
/** The destination field. */
|
|
38
|
-
readonly field:
|
|
58
|
+
readonly field: AvScalarField<AvContract>;
|
|
39
59
|
readonly shape: TransactionSlotShape;
|
|
40
60
|
/** The slot is a scalar value of mutation data: what it resolves to is written. */
|
|
41
61
|
readonly written: boolean;
|
|
42
62
|
/** The source field, under its own step's Contract: what the slot receives. */
|
|
43
|
-
readonly source:
|
|
44
|
-
readonly reference:
|
|
63
|
+
readonly source: AvScalarField<AvContract>;
|
|
64
|
+
readonly reference: AvTransactionReference;
|
|
45
65
|
};
|
|
46
66
|
export type CandidateTransactionOperation = {
|
|
47
67
|
readonly index: number;
|
|
48
|
-
readonly request:
|
|
68
|
+
readonly request: AvOperationRequest;
|
|
49
69
|
readonly arguments: SemanticOperationArguments;
|
|
50
70
|
readonly projection: ReadProjectionPlan | undefined;
|
|
51
71
|
readonly declaredFingerprint: unknown;
|
|
52
72
|
readonly candidates: readonly TransactionReferenceCandidateSlot[];
|
|
53
73
|
};
|
|
54
74
|
export type ValidatedTransactionOperation = {
|
|
75
|
+
readonly kind: "operation";
|
|
55
76
|
readonly index: number;
|
|
56
|
-
readonly request:
|
|
77
|
+
readonly request: AvOperationRequest;
|
|
57
78
|
/**
|
|
58
|
-
* The Contract of this operation's
|
|
59
|
-
* against, the one it runs under, and the one a later `$ref` reads its
|
|
60
|
-
* field from.
|
|
79
|
+
* The Contract of this operation's origin, which is the plan's: the one it was
|
|
80
|
+
* validated against, the one it runs under, and the one a later `$ref` reads its
|
|
81
|
+
* source field from.
|
|
61
82
|
*/
|
|
62
|
-
readonly contract:
|
|
83
|
+
readonly contract: AvContract;
|
|
63
84
|
readonly arguments: SemanticOperationArguments;
|
|
64
85
|
readonly projection: ReadProjectionPlan | undefined;
|
|
65
86
|
readonly fingerprint: OperationFingerprint;
|
|
66
87
|
readonly references: readonly TransactionReferenceSlot[];
|
|
67
88
|
};
|
|
89
|
+
/** One validated plan step: a standard operation, or an `appTx.$sql` statement. */
|
|
90
|
+
export type ValidatedTransactionStep = ValidatedTransactionOperation | ValidatedSqlStatement;
|
|
68
91
|
export type ValidatedTransactionPlan = {
|
|
69
|
-
readonly operations: readonly
|
|
92
|
+
readonly operations: readonly ValidatedTransactionStep[];
|
|
70
93
|
};
|
|
71
94
|
/**
|
|
72
95
|
* What validating a plan needs beyond one operation's pipeline: the cascade
|
|
@@ -74,23 +97,25 @@ export type ValidatedTransactionPlan = {
|
|
|
74
97
|
* Framework is constructed. The record-write facts are not among them: they
|
|
75
98
|
* are checked when each operation runs, after its pipes.
|
|
76
99
|
*/
|
|
77
|
-
|
|
100
|
+
type TransactionPlanDependencies<M extends AvAdapterModel> = Omit<OperationPipelineDependencies<M>, "recordWrites" | "contexts" | "fieldStages"> & {
|
|
78
101
|
readonly cascades: CascadeClosure;
|
|
102
|
+
/** Whether the Adapter declares `sqlStatements`: read once, at construction. */
|
|
103
|
+
readonly sqlStatements: boolean;
|
|
79
104
|
};
|
|
80
|
-
|
|
105
|
+
type TransactionPlanValidationResult = {
|
|
81
106
|
readonly ok: true;
|
|
82
107
|
readonly plan: ValidatedTransactionPlan;
|
|
83
108
|
} | {
|
|
84
109
|
readonly ok: false;
|
|
85
|
-
readonly response:
|
|
110
|
+
readonly response: AvOperationFailureResponse;
|
|
86
111
|
};
|
|
87
112
|
/**
|
|
88
113
|
* The refusal of a plan on a Contract without transaction plans (`A2002`, one `V1006`
|
|
89
114
|
* at `["operations"]`). The one spelling — the protocol's absence answer for
|
|
90
115
|
* `/_transactions` is this envelope too.
|
|
91
116
|
*/
|
|
92
|
-
export declare function transactionsUnavailableFailure():
|
|
117
|
+
export declare function transactionsUnavailableFailure(): AvOperationFailureResponse;
|
|
93
118
|
/**
|
|
94
119
|
* Whole-plan Framework Validation Layer for transaction structure and identity.
|
|
95
120
|
*/
|
|
96
|
-
export declare function validateTransactionPlan<M extends
|
|
121
|
+
export declare function validateTransactionPlan<M extends AvAdapterModel>(dependencies: TransactionPlanDependencies<M>, request: AvTransactionRequest, origins?: readonly TransactionOperationOrigin[], planArguments?: PlanArguments): Promise<TransactionPlanValidationResult>;
|