@aventara/core 1.0.0-rc.0 → 1.0.0-rc.2
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 +1434 -0
- package/ERRORS.md +142 -0
- package/README.md +247 -57
- 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 +25 -11
- package/dist/adapters/adapter-identifier.d.ts +6 -6
- 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 +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 +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 +7 -7
- 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 +18 -18
- package/dist/compiler/contract.compiler.js +637 -442
- 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/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +80 -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 +74 -31
- package/dist/config/config.resolver.js +108 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +581 -72
- 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 +308 -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 +111 -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 +122 -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 +21 -12
- package/dist/contracts/capability.js +2 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +388 -63
- package/dist/contracts/client-contract-structure.validator.js +156 -10
- package/dist/contracts/contract-canonicalizer.d.ts +26 -3
- package/dist/contracts/contract-canonicalizer.js +156 -29
- 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 +24 -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 +81 -42
- package/dist/contracts/identifier.d.ts +4 -4
- 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 +15 -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/contract-view.d.ts +213 -147
- package/dist/framework/framework-construction.error.d.ts +19 -10
- package/dist/framework/framework-construction.error.js +7 -3
- package/dist/framework/framework.d.ts +47 -23
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +49 -22
- package/dist/framework/operation-facade.d.ts +123 -52
- package/dist/framework/operation-facade.js +9 -1
- package/dist/index.d.ts +57 -50
- package/dist/index.js +7 -6
- package/dist/internal.d.ts +17 -10
- package/dist/internal.js +4 -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 +343 -207
- package/dist/operations/operation-call.d.ts +27 -28
- package/dist/operations/operation-identity.d.ts +10 -10
- 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 +99 -6
- package/dist/operations/operation-validator.d.ts +9 -9
- package/dist/operations/projection-scope.resolver.d.ts +6 -6
- package/dist/operations/structural-limits.walker.d.ts +6 -6
- 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/protocol/absent-route.responder.d.ts +13 -12
- package/dist/protocol/absent-route.responder.js +19 -19
- 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 +17 -13
- package/dist/protocol/http-request.decoder.js +10 -10
- 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 +50 -27
- package/dist/protocol/protocol.binder.js +12 -9
- package/dist/protocol/protocol.handler.d.ts +22 -13
- package/dist/protocol/protocol.handler.js +91 -17
- 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 -5
- package/dist/runtime/caller-data.copier.js +31 -14
- package/dist/runtime/caller-data.door.d.ts +17 -11
- package/dist/runtime/caller-data.door.js +6 -4
- package/dist/runtime/computed-read-runtime.d.ts +7 -6
- package/dist/runtime/computed-read-runtime.js +76 -50
- 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 +59 -0
- package/dist/runtime/context-executor.runtime.js +275 -0
- package/dist/runtime/create-requirement.d.ts +44 -79
- package/dist/runtime/create-requirement.js +213 -73
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +1 -1
- package/dist/runtime/diagnostics-reporter.d.ts +54 -27
- package/dist/runtime/diagnostics-reporter.js +24 -0
- package/dist/runtime/error-boundary.d.ts +65 -8
- package/dist/runtime/error-boundary.js +49 -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 +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 +37 -0
- package/dist/runtime/field-stage.runtime.js +147 -0
- package/dist/runtime/field-validator.runtime.d.ts +19 -0
- package/dist/runtime/field-validator.runtime.js +92 -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 +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 +11 -6
- package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
- package/dist/runtime/level-lifecycle.runtime.js +39 -0
- package/dist/runtime/misuse-reporter.d.ts +12 -12
- package/dist/runtime/mutation-planner.d.ts +19 -10
- 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 +33 -6
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +127 -25
- package/dist/runtime/operation-runtime.js +441 -78
- package/dist/runtime/outcome-mapper.d.ts +16 -5
- package/dist/runtime/outcome-mapper.js +23 -6
- package/dist/runtime/output-validator.d.ts +10 -10
- 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 +223 -34
- package/dist/runtime/readonly-value.d.ts +43 -0
- package/dist/runtime/readonly-value.js +150 -0
- 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 +35 -16
- package/dist/runtime/scalar-runtime.js +102 -34
- 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 +2 -2
- 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 +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 +21 -11
- package/dist/transactions/transaction-plan-assembler.js +169 -32
- package/dist/transactions/transaction-plan-validator.d.ts +45 -20
- 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 +19 -2
- package/dist/transactions/transaction-reference-resolver.js +26 -14
- package/dist/transactions/transaction-reference-validator.d.ts +76 -4
- package/dist/transactions/transaction-reference-validator.js +129 -71
- package/dist/transactions/transaction-reference.d.ts +13 -13
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +18 -5
- package/dist/transactions/transaction-response.d.ts +6 -6
- package/dist/transactions/transaction-runtime.d.ts +8 -7
- package/dist/transactions/transaction-runtime.js +191 -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 +82 -0
- package/dist/transactions/transaction-stage.runtime.js +126 -0
- package/package.json +9 -7
- 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,16 +1,15 @@
|
|
|
1
1
|
import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
2
|
-
import {
|
|
2
|
+
import { AvComputedValueError } from "./computed-value.error.js";
|
|
3
|
+
import { frozenCopy } from "./readonly-value.js";
|
|
3
4
|
import { normalizeScalarFieldValue } from "./scalar-runtime.js";
|
|
4
5
|
function isRecord(value) {
|
|
5
6
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
7
|
}
|
|
7
|
-
function
|
|
8
|
+
function readCompute(value) {
|
|
8
9
|
if (typeof value === "function") {
|
|
9
10
|
return { compute: value, dependsOn: [] };
|
|
10
11
|
}
|
|
11
|
-
if (value === undefined ||
|
|
12
|
-
value === false ||
|
|
13
|
-
typeof value.compute !== "function") {
|
|
12
|
+
if (value === undefined || typeof value.compute !== "function") {
|
|
14
13
|
return undefined;
|
|
15
14
|
}
|
|
16
15
|
return {
|
|
@@ -18,6 +17,16 @@ function readBehavior(value) {
|
|
|
18
17
|
dependsOn: value.dependsOn ?? [],
|
|
19
18
|
};
|
|
20
19
|
}
|
|
20
|
+
function storedScalar(model, resource, field) {
|
|
21
|
+
const resources = model.resources;
|
|
22
|
+
const fields = Object.hasOwn(resources, resource)
|
|
23
|
+
? resources[resource]?.fields
|
|
24
|
+
: undefined;
|
|
25
|
+
const entry = fields !== undefined && Object.hasOwn(fields, field)
|
|
26
|
+
? fields[field]
|
|
27
|
+
: undefined;
|
|
28
|
+
return isRecord(entry) && entry.kind === "scalar";
|
|
29
|
+
}
|
|
21
30
|
function appendUnique(values, value) {
|
|
22
31
|
if (!values.includes(value)) {
|
|
23
32
|
values.push(value);
|
|
@@ -28,24 +37,34 @@ function appendUniqueProjection(values, value) {
|
|
|
28
37
|
values.push(value);
|
|
29
38
|
}
|
|
30
39
|
}
|
|
40
|
+
function adapterIdentifier(model, resource) {
|
|
41
|
+
const resources = model.resources;
|
|
42
|
+
return ((Object.hasOwn(resources, resource)
|
|
43
|
+
? resources[resource]?.identifiers?.[0]
|
|
44
|
+
: undefined) ?? []);
|
|
45
|
+
}
|
|
31
46
|
function supportsProjection(request) {
|
|
32
47
|
if (request.family === "upsert") {
|
|
33
48
|
return true;
|
|
34
49
|
}
|
|
35
50
|
return request.variant !== "count";
|
|
36
51
|
}
|
|
37
|
-
function addScalarProjection(core, active,
|
|
52
|
+
function addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed) {
|
|
38
53
|
const activeField = lookupField(lookupResource(active, resourceName), fieldName);
|
|
39
54
|
if (activeField?.kind !== "scalar") {
|
|
40
55
|
return;
|
|
41
56
|
}
|
|
42
57
|
appendUnique(requested, fieldName);
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
58
|
+
const stage = readCompute(compute?.[resourceName]?.[fieldName]?.read);
|
|
59
|
+
if (stage !== undefined) {
|
|
45
60
|
appendUnique(computed, fieldName);
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
61
|
+
if (stage.dependsOn.length === 0) {
|
|
62
|
+
for (const member of adapterIdentifier(model, resourceName)) {
|
|
63
|
+
appendUniqueProjection(adapterSelect, member);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (const dependency of stage.dependsOn) {
|
|
67
|
+
if (storedScalar(model, resourceName, dependency)) {
|
|
49
68
|
appendUniqueProjection(adapterSelect, dependency);
|
|
50
69
|
}
|
|
51
70
|
}
|
|
@@ -70,7 +89,7 @@ function projectionEntry(entry) {
|
|
|
70
89
|
function withoutProjectionChoice(value) {
|
|
71
90
|
return Object.fromEntries(Object.entries(value).filter(([key]) => key !== "select" && key !== "include"));
|
|
72
91
|
}
|
|
73
|
-
function defaultProjectionLevel(core, active,
|
|
92
|
+
function defaultProjectionLevel(core, model, active, compute, resourceName) {
|
|
74
93
|
const activeResource = lookupResource(active, resourceName);
|
|
75
94
|
const adapterSelect = [];
|
|
76
95
|
const requested = [];
|
|
@@ -80,7 +99,7 @@ function defaultProjectionLevel(core, active, behaviors, resourceName) {
|
|
|
80
99
|
if (field.kind !== "scalar" || field.capabilities.select !== true) {
|
|
81
100
|
continue;
|
|
82
101
|
}
|
|
83
|
-
addScalarProjection(core, active,
|
|
102
|
+
addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed);
|
|
84
103
|
}
|
|
85
104
|
}
|
|
86
105
|
return {
|
|
@@ -94,25 +113,25 @@ function defaultProjectionLevel(core, active, behaviors, resourceName) {
|
|
|
94
113
|
},
|
|
95
114
|
};
|
|
96
115
|
}
|
|
97
|
-
function planRelationProjection(core, active,
|
|
116
|
+
function planRelationProjection(core, model, active, compute, field, value) {
|
|
98
117
|
if (!isRecord(value)) {
|
|
99
|
-
return defaultProjectionLevel(core, active,
|
|
118
|
+
return defaultProjectionLevel(core, model, active, compute, field.target);
|
|
100
119
|
}
|
|
101
120
|
if (Array.isArray(value.select)) {
|
|
102
|
-
return planSelectLevel(core, active,
|
|
121
|
+
return planSelectLevel(core, model, active, compute, field.target, value.select, true);
|
|
103
122
|
}
|
|
104
123
|
if (Array.isArray(value.include)) {
|
|
105
|
-
return planIncludeLevel(core, active,
|
|
124
|
+
return planIncludeLevel(core, model, active, compute, field.target, value.include);
|
|
106
125
|
}
|
|
107
|
-
return defaultProjectionLevel(core, active,
|
|
126
|
+
return defaultProjectionLevel(core, model, active, compute, field.target);
|
|
108
127
|
}
|
|
109
|
-
function planRelationEntry(core, active,
|
|
128
|
+
function planRelationEntry(core, model, active, compute, resourceName, fieldName, value) {
|
|
110
129
|
const activeField = lookupField(lookupResource(active, resourceName), fieldName);
|
|
111
130
|
const coreField = lookupField(lookupResource(core, resourceName), fieldName);
|
|
112
131
|
if (activeField?.kind !== "relation" || coreField?.kind !== "relation") {
|
|
113
132
|
return undefined;
|
|
114
133
|
}
|
|
115
|
-
const nested = planRelationProjection(core, active,
|
|
134
|
+
const nested = planRelationProjection(core, model, active, compute, coreField, value);
|
|
116
135
|
return {
|
|
117
136
|
adapterEntry: {
|
|
118
137
|
[fieldName]: {
|
|
@@ -127,7 +146,7 @@ function planRelationEntry(core, active, behaviors, resourceName, fieldName, val
|
|
|
127
146
|
},
|
|
128
147
|
};
|
|
129
148
|
}
|
|
130
|
-
function planSelectLevel(core, active,
|
|
149
|
+
function planSelectLevel(core, model, active, compute, resourceName, select, collectReducers = false) {
|
|
131
150
|
const activeResource = lookupResource(active, resourceName);
|
|
132
151
|
const coreResource = lookupResource(core, resourceName);
|
|
133
152
|
const adapterSelect = [];
|
|
@@ -159,11 +178,11 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
159
178
|
const activeField = lookupField(activeResource, entry);
|
|
160
179
|
const coreField = lookupField(coreResource, entry);
|
|
161
180
|
if (activeField?.kind === "scalar") {
|
|
162
|
-
addScalarProjection(core, active,
|
|
181
|
+
addScalarProjection(core, model, active, compute, resourceName, entry, adapterSelect, requested, computed);
|
|
163
182
|
continue;
|
|
164
183
|
}
|
|
165
184
|
if (activeField?.kind === "relation" && coreField?.kind === "relation") {
|
|
166
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
185
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
|
|
167
186
|
if (plannedRelation !== undefined) {
|
|
168
187
|
appendUnique(requested, entry);
|
|
169
188
|
adapterSelect.push(plannedRelation.adapterEntry);
|
|
@@ -180,7 +199,7 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
180
199
|
continue;
|
|
181
200
|
}
|
|
182
201
|
const [fieldName, nestedValue] = relationEntry;
|
|
183
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
202
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
|
|
184
203
|
if (plannedRelation === undefined) {
|
|
185
204
|
adapterSelect.push(entry);
|
|
186
205
|
continue;
|
|
@@ -194,15 +213,15 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
194
213
|
plan: { resource: resourceName, requested, computed, relations, reducers },
|
|
195
214
|
};
|
|
196
215
|
}
|
|
197
|
-
function planIncludeLevel(core, active,
|
|
198
|
-
const defaults = defaultProjectionLevel(core, active,
|
|
216
|
+
function planIncludeLevel(core, model, active, compute, resourceName, include) {
|
|
217
|
+
const defaults = defaultProjectionLevel(core, model, active, compute, resourceName);
|
|
199
218
|
const adapterSelect = [...defaults.select];
|
|
200
219
|
const requested = [...defaults.plan.requested];
|
|
201
220
|
const computed = [...defaults.plan.computed];
|
|
202
221
|
const relations = [];
|
|
203
222
|
for (const entry of include) {
|
|
204
223
|
if (typeof entry === "string") {
|
|
205
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
224
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
|
|
206
225
|
if (plannedRelation === undefined) {
|
|
207
226
|
continue;
|
|
208
227
|
}
|
|
@@ -216,7 +235,7 @@ function planIncludeLevel(core, active, behaviors, resourceName, include) {
|
|
|
216
235
|
continue;
|
|
217
236
|
}
|
|
218
237
|
const [fieldName, nestedValue] = relationEntry;
|
|
219
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
238
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
|
|
220
239
|
if (plannedRelation === undefined) {
|
|
221
240
|
continue;
|
|
222
241
|
}
|
|
@@ -241,7 +260,7 @@ function replaceWithInternalSelect(args, select) {
|
|
|
241
260
|
internal.select = select;
|
|
242
261
|
return internal;
|
|
243
262
|
}
|
|
244
|
-
export function planReadOperation(core, active,
|
|
263
|
+
export function planReadOperation(core, model, active, compute, request, args) {
|
|
245
264
|
if (!isRecord(args) || !supportsProjection(request)) {
|
|
246
265
|
return { arguments: args, projection: undefined, materialize: false };
|
|
247
266
|
}
|
|
@@ -251,7 +270,7 @@ export function planReadOperation(core, active, behaviors, request, args) {
|
|
|
251
270
|
return { arguments: args, projection: undefined, materialize: false };
|
|
252
271
|
}
|
|
253
272
|
if (Array.isArray(args.select)) {
|
|
254
|
-
const planned = planSelectLevel(core, active,
|
|
273
|
+
const planned = planSelectLevel(core, model, active, compute, request.resource, args.select);
|
|
255
274
|
return {
|
|
256
275
|
arguments: replaceWithInternalSelect(args, planned.select),
|
|
257
276
|
projection: planned.plan,
|
|
@@ -259,21 +278,21 @@ export function planReadOperation(core, active, behaviors, request, args) {
|
|
|
259
278
|
};
|
|
260
279
|
}
|
|
261
280
|
if (Array.isArray(args.include)) {
|
|
262
|
-
const planned = planIncludeLevel(core, active,
|
|
281
|
+
const planned = planIncludeLevel(core, model, active, compute, request.resource, args.include);
|
|
263
282
|
return {
|
|
264
283
|
arguments: replaceWithInternalSelect(args, planned.select),
|
|
265
284
|
projection: planned.plan,
|
|
266
285
|
materialize: true,
|
|
267
286
|
};
|
|
268
287
|
}
|
|
269
|
-
const defaults = defaultProjectionLevel(core, active,
|
|
288
|
+
const defaults = defaultProjectionLevel(core, model, active, compute, request.resource);
|
|
270
289
|
return {
|
|
271
290
|
arguments: { ...args, select: defaults.select },
|
|
272
291
|
projection: defaults.plan,
|
|
273
292
|
materialize: defaults.plan.computed.length > 0,
|
|
274
293
|
};
|
|
275
294
|
}
|
|
276
|
-
async function materializeRelation(active,
|
|
295
|
+
async function materializeRelation(active, compute, request, relation, value, contextFactory) {
|
|
277
296
|
if (value === null || value === undefined) {
|
|
278
297
|
return value;
|
|
279
298
|
}
|
|
@@ -281,11 +300,11 @@ async function materializeRelation(active, behaviors, request, relation, value,
|
|
|
281
300
|
if (!Array.isArray(value)) {
|
|
282
301
|
return value;
|
|
283
302
|
}
|
|
284
|
-
return Promise.all(value.map((entry) => materializeRecord(active,
|
|
303
|
+
return Promise.all(value.map((entry) => materializeRecord(active, compute, request, relation.projection, entry, contextFactory)));
|
|
285
304
|
}
|
|
286
|
-
return materializeRecord(active,
|
|
305
|
+
return materializeRecord(active, compute, request, relation.projection, value, contextFactory);
|
|
287
306
|
}
|
|
288
|
-
async function materializeRecord(active,
|
|
307
|
+
async function materializeRecord(active, compute, request, plan, value, contextFactory) {
|
|
289
308
|
if (!isRecord(value)) {
|
|
290
309
|
return value;
|
|
291
310
|
}
|
|
@@ -296,24 +315,31 @@ async function materializeRecord(active, behaviors, request, plan, value, contex
|
|
|
296
315
|
const record = { ...value };
|
|
297
316
|
for (const fieldName of plan.computed) {
|
|
298
317
|
const field = lookupField(resource, fieldName);
|
|
299
|
-
const
|
|
300
|
-
if (field?.kind !== "scalar" ||
|
|
318
|
+
const stage = readCompute(compute?.[plan.resource]?.[fieldName]?.read);
|
|
319
|
+
if (field?.kind !== "scalar" || stage === undefined) {
|
|
301
320
|
continue;
|
|
302
321
|
}
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
resource: plan.resource,
|
|
322
|
+
const view = frozenCopy(record);
|
|
323
|
+
const computedValue = await stage.compute({
|
|
306
324
|
field: fieldName,
|
|
307
|
-
value:
|
|
308
|
-
record,
|
|
309
|
-
|
|
325
|
+
value: view[fieldName],
|
|
326
|
+
record: view,
|
|
327
|
+
ctx: contextFactory(),
|
|
310
328
|
});
|
|
311
329
|
if (computedValue === undefined) {
|
|
312
330
|
continue;
|
|
313
331
|
}
|
|
314
|
-
const validation = normalizeScalarFieldValue(active, field, computedValue, "runtime", [
|
|
332
|
+
const validation = normalizeScalarFieldValue(active, field, computedValue, "runtime", [
|
|
333
|
+
"resources",
|
|
334
|
+
plan.resource,
|
|
335
|
+
"fields",
|
|
336
|
+
fieldName,
|
|
337
|
+
"pipelines",
|
|
338
|
+
"compute",
|
|
339
|
+
"read",
|
|
340
|
+
]);
|
|
315
341
|
if (!validation.ok) {
|
|
316
|
-
throw new
|
|
342
|
+
throw new AvComputedValueError(plan.resource, fieldName, "read", validation.issues);
|
|
317
343
|
}
|
|
318
344
|
record[fieldName] = validation.value;
|
|
319
345
|
}
|
|
@@ -321,19 +347,19 @@ async function materializeRecord(active, behaviors, request, plan, value, contex
|
|
|
321
347
|
if (!Object.hasOwn(record, relation.field)) {
|
|
322
348
|
continue;
|
|
323
349
|
}
|
|
324
|
-
record[relation.field] = await materializeRelation(active,
|
|
350
|
+
record[relation.field] = await materializeRelation(active, compute, request, relation, record[relation.field], contextFactory);
|
|
325
351
|
}
|
|
326
352
|
return Object.fromEntries(plan.requested
|
|
327
353
|
.filter((fieldName) => Object.hasOwn(record, fieldName))
|
|
328
354
|
.map((fieldName) => [fieldName, record[fieldName]]));
|
|
329
355
|
}
|
|
330
|
-
export async function materializeReadOperation(active,
|
|
356
|
+
export async function materializeReadOperation(active, compute, request, plan, value, contextFactory) {
|
|
331
357
|
const projection = plan.projection;
|
|
332
358
|
if (!plan.materialize || projection === undefined) {
|
|
333
359
|
return value;
|
|
334
360
|
}
|
|
335
361
|
if (Array.isArray(value)) {
|
|
336
|
-
return Promise.all(value.map((entry) => materializeRecord(active,
|
|
362
|
+
return Promise.all(value.map((entry) => materializeRecord(active, compute, request, projection, entry, contextFactory)));
|
|
337
363
|
}
|
|
338
|
-
return materializeRecord(active,
|
|
364
|
+
return materializeRecord(active, compute, request, projection, value, contextFactory);
|
|
339
365
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
2
2
|
/**
|
|
3
3
|
* What the diagnostics channel receives when a computed value — a read or write
|
|
4
|
-
*
|
|
4
|
+
* compute stage's return — is one its Contract refuses, or a `compute.create`
|
|
5
|
+
* stage returned `undefined` for a field a create cannot do without (rc.2): the developer's broken code,
|
|
5
6
|
* never the caller's. It is thrown, not a deliberate outcome, so the framework's
|
|
6
7
|
* boundary answers the caller the generic `A3000` and reports this error, with the
|
|
7
8
|
* issues, exactly once.
|
|
8
9
|
*/
|
|
9
|
-
export declare class
|
|
10
|
-
readonly issues: readonly
|
|
11
|
-
readonly name = "
|
|
12
|
-
constructor(resource: string, field: string, stage: "read" | "create" | "update", issues: readonly
|
|
10
|
+
export declare class AvComputedValueError extends Error {
|
|
11
|
+
readonly issues: readonly AvValidationIssue[];
|
|
12
|
+
readonly name = "AvComputedValueError";
|
|
13
|
+
constructor(resource: string, field: string, stage: "read" | "create" | "update", issues: readonly AvValidationIssue[], message?: string);
|
|
13
14
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export class
|
|
1
|
+
export class AvComputedValueError extends Error {
|
|
2
2
|
issues;
|
|
3
|
-
name = "
|
|
4
|
-
constructor(resource, field, stage, issues) {
|
|
3
|
+
name = "AvComputedValueError";
|
|
4
|
+
constructor(resource, field, stage, issues, message) {
|
|
5
5
|
const [first] = issues;
|
|
6
|
-
super(
|
|
6
|
+
super(message ??
|
|
7
|
+
`The compute.${stage} stage of ${resource}.${field} returned a value its Contract refuses${first === undefined ? "." : ` (${first.code}: ${first.message})`}`);
|
|
7
8
|
this.issues = issues;
|
|
8
9
|
}
|
|
9
10
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { AvAdapter } from "../adapters/adapter.interface.js";
|
|
2
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
3
|
+
import type { AvAdapterTransactionExecutor } from "../adapters/adapter-transaction-executor.interface.js";
|
|
4
|
+
import type { AvRequestOrigin } from "../config/config-layer.js";
|
|
5
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
6
|
+
import type { AvOperationFamily } from "../operations/operation-identity.js";
|
|
7
|
+
import { type AvDiagnosticsSink } from "./diagnostics-reporter.js";
|
|
8
|
+
import type { AvComputeContext } from "./field-compute.js";
|
|
9
|
+
import type { MisuseReporter } from "./misuse-reporter.js";
|
|
10
|
+
import type { ApplicationOperationRequest } from "./operation-request.js";
|
|
11
|
+
import type { AvOperationResponse } from "./operation-response.js";
|
|
12
|
+
import type { AvContext, AvTransactionContext, AvTransportContext } from "./pipeline.js";
|
|
13
|
+
import type { AvState } from "./request-state.js";
|
|
14
|
+
/** Where a ctx's calls run: inside the open transaction, or standalone. */
|
|
15
|
+
export type ExecutorScope<M extends AvAdapterModel = AvAdapterModel> = {
|
|
16
|
+
/** The request id every call of this ctx carries: its stage's request's. */
|
|
17
|
+
readonly requestId: string;
|
|
18
|
+
/** The open transaction's executor; `undefined` outside any transaction. */
|
|
19
|
+
readonly transaction: AvAdapterTransactionExecutor<M> | undefined;
|
|
20
|
+
/** The request's state, which every call of this ctx inherits. */
|
|
21
|
+
readonly state: AvState;
|
|
22
|
+
};
|
|
23
|
+
/** The `$` facts a ctx states, as own data properties. */
|
|
24
|
+
export type ContextFacts = {
|
|
25
|
+
readonly $origin: AvRequestOrigin;
|
|
26
|
+
readonly $requestId: string;
|
|
27
|
+
readonly $transport?: AvTransportContext;
|
|
28
|
+
readonly $contract: AvContract;
|
|
29
|
+
readonly $operation?: {
|
|
30
|
+
readonly resource: string;
|
|
31
|
+
readonly family: AvOperationFamily;
|
|
32
|
+
readonly variant: string;
|
|
33
|
+
readonly nested?: true;
|
|
34
|
+
};
|
|
35
|
+
readonly $args: unknown;
|
|
36
|
+
};
|
|
37
|
+
/** Runs one raw application-origin call in `transaction`, or standalone. Total. */
|
|
38
|
+
export type RawOperationRunner<M extends AvAdapterModel> = (request: ApplicationOperationRequest, transaction: AvAdapterTransactionExecutor<M> | undefined) => Promise<AvOperationResponse>;
|
|
39
|
+
export type ContextExecutorDependencies<M extends AvAdapterModel> = {
|
|
40
|
+
/** The model, as construction read it once: the ctx's Resources. */
|
|
41
|
+
readonly model: M;
|
|
42
|
+
readonly adapter: AvAdapter<M>;
|
|
43
|
+
/** The Application Contract: a `ctx.$transaction` needs its transactions. */
|
|
44
|
+
readonly application: AvContract;
|
|
45
|
+
readonly diagnostics: AvDiagnosticsSink | undefined;
|
|
46
|
+
readonly misuse: MisuseReporter;
|
|
47
|
+
readonly run: RawOperationRunner<M>;
|
|
48
|
+
};
|
|
49
|
+
/** Builds the ctx every stage is told. */
|
|
50
|
+
export type ContextExecutor<M extends AvAdapterModel = AvAdapterModel> = {
|
|
51
|
+
/** An operation stage's ctx: its facts and the full executor. */
|
|
52
|
+
readonly operation: (scope: ExecutorScope<M>, facts: ContextFacts) => AvContext;
|
|
53
|
+
/** A Resource transaction stage's ctx: the plan as `$args`, the full executor. */
|
|
54
|
+
readonly transaction: (scope: ExecutorScope<M>, facts: ContextFacts) => AvTransactionContext;
|
|
55
|
+
/** Compute's read-only ctx: the facts, and `find.*` reads only. */
|
|
56
|
+
readonly compute: (scope: ExecutorScope<M>, facts: ContextFacts) => AvComputeContext;
|
|
57
|
+
};
|
|
58
|
+
/** Builds the ctx factory of one Framework over its model. */
|
|
59
|
+
export declare function createContextExecutor<M extends AvAdapterModel>(dependencies: ContextExecutorDependencies<M>): ContextExecutor<M>;
|