@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,16 +1,16 @@
|
|
|
1
|
+
import { adapterPrimaryIdentifier } from "../adapters/adapter-identifier.js";
|
|
1
2
|
import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
2
|
-
import {
|
|
3
|
+
import { AvComputedValueError } from "./computed-value.error.js";
|
|
4
|
+
import { frozenCopy } from "./readonly-value.js";
|
|
3
5
|
import { normalizeScalarFieldValue } from "./scalar-runtime.js";
|
|
4
6
|
function isRecord(value) {
|
|
5
7
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
8
|
}
|
|
7
|
-
function
|
|
9
|
+
function readCompute(value) {
|
|
8
10
|
if (typeof value === "function") {
|
|
9
11
|
return { compute: value, dependsOn: [] };
|
|
10
12
|
}
|
|
11
|
-
if (value === undefined ||
|
|
12
|
-
value === false ||
|
|
13
|
-
typeof value.compute !== "function") {
|
|
13
|
+
if (value === undefined || typeof value.compute !== "function") {
|
|
14
14
|
return undefined;
|
|
15
15
|
}
|
|
16
16
|
return {
|
|
@@ -18,6 +18,16 @@ function readBehavior(value) {
|
|
|
18
18
|
dependsOn: value.dependsOn ?? [],
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
function storedScalar(model, resource, field) {
|
|
22
|
+
const resources = model.resources;
|
|
23
|
+
const fields = Object.hasOwn(resources, resource)
|
|
24
|
+
? resources[resource]?.fields
|
|
25
|
+
: undefined;
|
|
26
|
+
const entry = fields !== undefined && Object.hasOwn(fields, field)
|
|
27
|
+
? fields[field]
|
|
28
|
+
: undefined;
|
|
29
|
+
return isRecord(entry) && entry.kind === "scalar";
|
|
30
|
+
}
|
|
21
31
|
function appendUnique(values, value) {
|
|
22
32
|
if (!values.includes(value)) {
|
|
23
33
|
values.push(value);
|
|
@@ -34,18 +44,22 @@ function supportsProjection(request) {
|
|
|
34
44
|
}
|
|
35
45
|
return request.variant !== "count";
|
|
36
46
|
}
|
|
37
|
-
function addScalarProjection(core, active,
|
|
47
|
+
function addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed) {
|
|
38
48
|
const activeField = lookupField(lookupResource(active, resourceName), fieldName);
|
|
39
49
|
if (activeField?.kind !== "scalar") {
|
|
40
50
|
return;
|
|
41
51
|
}
|
|
42
52
|
appendUnique(requested, fieldName);
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
53
|
+
const stage = readCompute(compute?.[resourceName]?.[fieldName]?.read);
|
|
54
|
+
if (stage !== undefined) {
|
|
45
55
|
appendUnique(computed, fieldName);
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
56
|
+
if (stage.dependsOn.length === 0) {
|
|
57
|
+
for (const member of adapterPrimaryIdentifier(model, resourceName)) {
|
|
58
|
+
appendUniqueProjection(adapterSelect, member);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const dependency of stage.dependsOn) {
|
|
62
|
+
if (storedScalar(model, resourceName, dependency)) {
|
|
49
63
|
appendUniqueProjection(adapterSelect, dependency);
|
|
50
64
|
}
|
|
51
65
|
}
|
|
@@ -70,18 +84,27 @@ function projectionEntry(entry) {
|
|
|
70
84
|
function withoutProjectionChoice(value) {
|
|
71
85
|
return Object.fromEntries(Object.entries(value).filter(([key]) => key !== "select" && key !== "include"));
|
|
72
86
|
}
|
|
73
|
-
function
|
|
87
|
+
export function defaultProjectionFields(active, resourceName) {
|
|
74
88
|
const activeResource = lookupResource(active, resourceName);
|
|
89
|
+
if (activeResource === undefined) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
const fields = [];
|
|
93
|
+
for (const [fieldName, field] of Object.entries(activeResource.fields)) {
|
|
94
|
+
if (field.kind === "scalar" &&
|
|
95
|
+
field.capabilities.select === true &&
|
|
96
|
+
field.governed !== true) {
|
|
97
|
+
fields.push(fieldName);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return fields;
|
|
101
|
+
}
|
|
102
|
+
function defaultProjectionLevel(core, model, active, compute, resourceName) {
|
|
75
103
|
const adapterSelect = [];
|
|
76
104
|
const requested = [];
|
|
77
105
|
const computed = [];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (field.kind !== "scalar" || field.capabilities.select !== true) {
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
addScalarProjection(core, active, behaviors, resourceName, fieldName, adapterSelect, requested, computed);
|
|
84
|
-
}
|
|
106
|
+
for (const fieldName of defaultProjectionFields(active, resourceName)) {
|
|
107
|
+
addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed);
|
|
85
108
|
}
|
|
86
109
|
return {
|
|
87
110
|
select: adapterSelect,
|
|
@@ -94,25 +117,25 @@ function defaultProjectionLevel(core, active, behaviors, resourceName) {
|
|
|
94
117
|
},
|
|
95
118
|
};
|
|
96
119
|
}
|
|
97
|
-
function planRelationProjection(core, active,
|
|
120
|
+
function planRelationProjection(core, model, active, compute, field, value) {
|
|
98
121
|
if (!isRecord(value)) {
|
|
99
|
-
return defaultProjectionLevel(core, active,
|
|
122
|
+
return defaultProjectionLevel(core, model, active, compute, field.target);
|
|
100
123
|
}
|
|
101
124
|
if (Array.isArray(value.select)) {
|
|
102
|
-
return planSelectLevel(core, active,
|
|
125
|
+
return planSelectLevel(core, model, active, compute, field.target, value.select, true);
|
|
103
126
|
}
|
|
104
127
|
if (Array.isArray(value.include)) {
|
|
105
|
-
return planIncludeLevel(core, active,
|
|
128
|
+
return planIncludeLevel(core, model, active, compute, field.target, value.include);
|
|
106
129
|
}
|
|
107
|
-
return defaultProjectionLevel(core, active,
|
|
130
|
+
return defaultProjectionLevel(core, model, active, compute, field.target);
|
|
108
131
|
}
|
|
109
|
-
function planRelationEntry(core, active,
|
|
132
|
+
function planRelationEntry(core, model, active, compute, resourceName, fieldName, value) {
|
|
110
133
|
const activeField = lookupField(lookupResource(active, resourceName), fieldName);
|
|
111
134
|
const coreField = lookupField(lookupResource(core, resourceName), fieldName);
|
|
112
135
|
if (activeField?.kind !== "relation" || coreField?.kind !== "relation") {
|
|
113
136
|
return undefined;
|
|
114
137
|
}
|
|
115
|
-
const nested = planRelationProjection(core, active,
|
|
138
|
+
const nested = planRelationProjection(core, model, active, compute, coreField, value);
|
|
116
139
|
return {
|
|
117
140
|
adapterEntry: {
|
|
118
141
|
[fieldName]: {
|
|
@@ -127,7 +150,7 @@ function planRelationEntry(core, active, behaviors, resourceName, fieldName, val
|
|
|
127
150
|
},
|
|
128
151
|
};
|
|
129
152
|
}
|
|
130
|
-
function planSelectLevel(core, active,
|
|
153
|
+
function planSelectLevel(core, model, active, compute, resourceName, select, collectReducers = false) {
|
|
131
154
|
const activeResource = lookupResource(active, resourceName);
|
|
132
155
|
const coreResource = lookupResource(core, resourceName);
|
|
133
156
|
const adapterSelect = [];
|
|
@@ -149,6 +172,12 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
149
172
|
}
|
|
150
173
|
for (const entry of select) {
|
|
151
174
|
if (typeof entry === "string") {
|
|
175
|
+
if (entry === "$defaults") {
|
|
176
|
+
for (const fieldName of defaultProjectionFields(active, resourceName)) {
|
|
177
|
+
addScalarProjection(core, model, active, compute, resourceName, fieldName, adapterSelect, requested, computed);
|
|
178
|
+
}
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
152
181
|
if (entry === "$count") {
|
|
153
182
|
adapterSelect.push(entry);
|
|
154
183
|
if (collectReducers) {
|
|
@@ -159,11 +188,11 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
159
188
|
const activeField = lookupField(activeResource, entry);
|
|
160
189
|
const coreField = lookupField(coreResource, entry);
|
|
161
190
|
if (activeField?.kind === "scalar") {
|
|
162
|
-
addScalarProjection(core, active,
|
|
191
|
+
addScalarProjection(core, model, active, compute, resourceName, entry, adapterSelect, requested, computed);
|
|
163
192
|
continue;
|
|
164
193
|
}
|
|
165
194
|
if (activeField?.kind === "relation" && coreField?.kind === "relation") {
|
|
166
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
195
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
|
|
167
196
|
if (plannedRelation !== undefined) {
|
|
168
197
|
appendUnique(requested, entry);
|
|
169
198
|
adapterSelect.push(plannedRelation.adapterEntry);
|
|
@@ -180,7 +209,7 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
180
209
|
continue;
|
|
181
210
|
}
|
|
182
211
|
const [fieldName, nestedValue] = relationEntry;
|
|
183
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
212
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
|
|
184
213
|
if (plannedRelation === undefined) {
|
|
185
214
|
adapterSelect.push(entry);
|
|
186
215
|
continue;
|
|
@@ -194,15 +223,15 @@ function planSelectLevel(core, active, behaviors, resourceName, select, collectR
|
|
|
194
223
|
plan: { resource: resourceName, requested, computed, relations, reducers },
|
|
195
224
|
};
|
|
196
225
|
}
|
|
197
|
-
function planIncludeLevel(core, active,
|
|
198
|
-
const defaults = defaultProjectionLevel(core, active,
|
|
226
|
+
function planIncludeLevel(core, model, active, compute, resourceName, include) {
|
|
227
|
+
const defaults = defaultProjectionLevel(core, model, active, compute, resourceName);
|
|
199
228
|
const adapterSelect = [...defaults.select];
|
|
200
229
|
const requested = [...defaults.plan.requested];
|
|
201
230
|
const computed = [...defaults.plan.computed];
|
|
202
231
|
const relations = [];
|
|
203
232
|
for (const entry of include) {
|
|
204
233
|
if (typeof entry === "string") {
|
|
205
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
234
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, entry, undefined);
|
|
206
235
|
if (plannedRelation === undefined) {
|
|
207
236
|
continue;
|
|
208
237
|
}
|
|
@@ -216,7 +245,7 @@ function planIncludeLevel(core, active, behaviors, resourceName, include) {
|
|
|
216
245
|
continue;
|
|
217
246
|
}
|
|
218
247
|
const [fieldName, nestedValue] = relationEntry;
|
|
219
|
-
const plannedRelation = planRelationEntry(core, active,
|
|
248
|
+
const plannedRelation = planRelationEntry(core, model, active, compute, resourceName, fieldName, nestedValue);
|
|
220
249
|
if (plannedRelation === undefined) {
|
|
221
250
|
continue;
|
|
222
251
|
}
|
|
@@ -241,7 +270,7 @@ function replaceWithInternalSelect(args, select) {
|
|
|
241
270
|
internal.select = select;
|
|
242
271
|
return internal;
|
|
243
272
|
}
|
|
244
|
-
export function planReadOperation(core, active,
|
|
273
|
+
export function planReadOperation(core, model, active, compute, request, args) {
|
|
245
274
|
if (!isRecord(args) || !supportsProjection(request)) {
|
|
246
275
|
return { arguments: args, projection: undefined, materialize: false };
|
|
247
276
|
}
|
|
@@ -251,7 +280,7 @@ export function planReadOperation(core, active, behaviors, request, args) {
|
|
|
251
280
|
return { arguments: args, projection: undefined, materialize: false };
|
|
252
281
|
}
|
|
253
282
|
if (Array.isArray(args.select)) {
|
|
254
|
-
const planned = planSelectLevel(core, active,
|
|
283
|
+
const planned = planSelectLevel(core, model, active, compute, request.resource, args.select);
|
|
255
284
|
return {
|
|
256
285
|
arguments: replaceWithInternalSelect(args, planned.select),
|
|
257
286
|
projection: planned.plan,
|
|
@@ -259,21 +288,189 @@ export function planReadOperation(core, active, behaviors, request, args) {
|
|
|
259
288
|
};
|
|
260
289
|
}
|
|
261
290
|
if (Array.isArray(args.include)) {
|
|
262
|
-
const planned = planIncludeLevel(core, active,
|
|
291
|
+
const planned = planIncludeLevel(core, model, active, compute, request.resource, args.include);
|
|
263
292
|
return {
|
|
264
293
|
arguments: replaceWithInternalSelect(args, planned.select),
|
|
265
294
|
projection: planned.plan,
|
|
266
295
|
materialize: true,
|
|
267
296
|
};
|
|
268
297
|
}
|
|
269
|
-
const defaults = defaultProjectionLevel(core, active,
|
|
298
|
+
const defaults = defaultProjectionLevel(core, model, active, compute, request.resource);
|
|
270
299
|
return {
|
|
271
300
|
arguments: { ...args, select: defaults.select },
|
|
272
301
|
projection: defaults.plan,
|
|
273
302
|
materialize: defaults.plan.computed.length > 0,
|
|
274
303
|
};
|
|
275
304
|
}
|
|
276
|
-
|
|
305
|
+
function resolveReadLevel(active, compute, plan, tail) {
|
|
306
|
+
const resource = lookupResource(active, plan.resource);
|
|
307
|
+
if (resource === undefined) {
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
const stages = [];
|
|
311
|
+
for (const fieldName of plan.computed) {
|
|
312
|
+
const field = lookupField(resource, fieldName);
|
|
313
|
+
const stage = readCompute(compute?.[plan.resource]?.[fieldName]?.read);
|
|
314
|
+
if (field?.kind !== "scalar" || stage === undefined) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
stages.push({
|
|
318
|
+
field: fieldName,
|
|
319
|
+
definition: field,
|
|
320
|
+
compute: stage.compute,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
const relations = [];
|
|
324
|
+
let restFree = true;
|
|
325
|
+
for (const relation of [...plan.relations].reverse()) {
|
|
326
|
+
const level = resolveReadLevel(active, compute, relation.projection, tail && restFree);
|
|
327
|
+
relations.unshift({ relation, level });
|
|
328
|
+
restFree &&= level?.computeFree ?? true;
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
plan,
|
|
332
|
+
stages,
|
|
333
|
+
relations,
|
|
334
|
+
computeFree: stages.length === 0 && restFree,
|
|
335
|
+
atOnce: tail && stages.length <= 1 && restFree,
|
|
336
|
+
plainKeys: plan.requested.every((field) => !(field in Object.prototype)),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function isNestedContainer(value) {
|
|
340
|
+
return (value !== null &&
|
|
341
|
+
typeof value === "object" &&
|
|
342
|
+
!(value instanceof Date) &&
|
|
343
|
+
!(value instanceof Uint8Array));
|
|
344
|
+
}
|
|
345
|
+
function isThenable(value) {
|
|
346
|
+
return (value !== null &&
|
|
347
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
348
|
+
typeof value.then === "function");
|
|
349
|
+
}
|
|
350
|
+
function setOwn(target, key, value) {
|
|
351
|
+
if (key in target) {
|
|
352
|
+
Object.defineProperty(target, key, {
|
|
353
|
+
value,
|
|
354
|
+
writable: true,
|
|
355
|
+
enumerable: true,
|
|
356
|
+
configurable: true,
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
target[key] = value;
|
|
361
|
+
}
|
|
362
|
+
function answerOf(level, record) {
|
|
363
|
+
const answer = {};
|
|
364
|
+
for (const fieldName of level.plan.requested) {
|
|
365
|
+
if (!Object.hasOwn(record, fieldName)) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (level.plainKeys) {
|
|
369
|
+
answer[fieldName] = record[fieldName];
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
setOwn(answer, fieldName, record[fieldName]);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return answer;
|
|
376
|
+
}
|
|
377
|
+
function heldReadValue(active, level, stage, value) {
|
|
378
|
+
const validation = normalizeScalarFieldValue(active, stage.definition, value, "runtime", [
|
|
379
|
+
"resources",
|
|
380
|
+
level.plan.resource,
|
|
381
|
+
"fields",
|
|
382
|
+
stage.field,
|
|
383
|
+
"pipelines",
|
|
384
|
+
"compute",
|
|
385
|
+
"read",
|
|
386
|
+
]);
|
|
387
|
+
if (!validation.ok) {
|
|
388
|
+
throw new AvComputedValueError(level.plan.resource, stage.field, "read", validation.issues);
|
|
389
|
+
}
|
|
390
|
+
return validation.value;
|
|
391
|
+
}
|
|
392
|
+
function projectedAtOnce(level, value) {
|
|
393
|
+
if (!isRecord(value) || level === undefined) {
|
|
394
|
+
return value;
|
|
395
|
+
}
|
|
396
|
+
const record = { ...value };
|
|
397
|
+
relationsAtOnce(level, record);
|
|
398
|
+
return answerOf(level, record);
|
|
399
|
+
}
|
|
400
|
+
function relationsAtOnce(level, record) {
|
|
401
|
+
for (const { relation, level: nested } of level.relations) {
|
|
402
|
+
if (!Object.hasOwn(record, relation.field)) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const value = record[relation.field];
|
|
406
|
+
if (value === null || value === undefined) {
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
if (relation.cardinality === "many") {
|
|
410
|
+
if (Array.isArray(value)) {
|
|
411
|
+
record[relation.field] = Array.from(value, (entry) => projectedAtOnce(nested, entry));
|
|
412
|
+
}
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
record[relation.field] = projectedAtOnce(nested, value);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function computedAtOnce(active, level, stage, value, contextFactory) {
|
|
419
|
+
const record = { ...value };
|
|
420
|
+
const view = frozenCopy(record);
|
|
421
|
+
let computedValue;
|
|
422
|
+
try {
|
|
423
|
+
computedValue = stage.compute({
|
|
424
|
+
field: stage.field,
|
|
425
|
+
value: view[stage.field],
|
|
426
|
+
record: view,
|
|
427
|
+
ctx: contextFactory(),
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
catch (error) {
|
|
431
|
+
return Promise.reject(error);
|
|
432
|
+
}
|
|
433
|
+
const finish = (returned) => {
|
|
434
|
+
if (returned !== undefined) {
|
|
435
|
+
record[stage.field] = heldReadValue(active, level, stage, returned);
|
|
436
|
+
}
|
|
437
|
+
relationsAtOnce(level, record);
|
|
438
|
+
return answerOf(level, record);
|
|
439
|
+
};
|
|
440
|
+
const later = (error) => Promise.resolve().then(() => {
|
|
441
|
+
throw error;
|
|
442
|
+
});
|
|
443
|
+
let waits;
|
|
444
|
+
try {
|
|
445
|
+
waits = isThenable(computedValue);
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
return later(error);
|
|
449
|
+
}
|
|
450
|
+
if (waits) {
|
|
451
|
+
const pending = computedValue;
|
|
452
|
+
return (async () => finish(await pending))();
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
return finish(computedValue);
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
return later(error);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function materializeRecord(active, level, value, contextFactory) {
|
|
462
|
+
if (level?.atOnce !== true) {
|
|
463
|
+
return materializeInTurn(active, level, value, contextFactory);
|
|
464
|
+
}
|
|
465
|
+
if (!isRecord(value)) {
|
|
466
|
+
return value;
|
|
467
|
+
}
|
|
468
|
+
const [stage] = level.stages;
|
|
469
|
+
return stage === undefined
|
|
470
|
+
? projectedAtOnce(level, value)
|
|
471
|
+
: computedAtOnce(active, level, stage, value, contextFactory);
|
|
472
|
+
}
|
|
473
|
+
async function materializeRelation(active, level, relation, value, contextFactory) {
|
|
277
474
|
if (value === null || value === undefined) {
|
|
278
475
|
return value;
|
|
279
476
|
}
|
|
@@ -281,59 +478,62 @@ async function materializeRelation(active, behaviors, request, relation, value,
|
|
|
281
478
|
if (!Array.isArray(value)) {
|
|
282
479
|
return value;
|
|
283
480
|
}
|
|
284
|
-
return Promise.all(value.map((entry) => materializeRecord(active,
|
|
481
|
+
return Promise.all(value.map((entry) => materializeRecord(active, level, entry, contextFactory)));
|
|
285
482
|
}
|
|
286
|
-
return materializeRecord(active,
|
|
483
|
+
return materializeRecord(active, level, value, contextFactory);
|
|
287
484
|
}
|
|
288
|
-
async function
|
|
289
|
-
if (!isRecord(value)) {
|
|
290
|
-
return value;
|
|
291
|
-
}
|
|
292
|
-
const resource = lookupResource(active, plan.resource);
|
|
293
|
-
if (resource === undefined) {
|
|
485
|
+
async function materializeInTurn(active, level, value, contextFactory) {
|
|
486
|
+
if (!isRecord(value) || level === undefined) {
|
|
294
487
|
return value;
|
|
295
488
|
}
|
|
489
|
+
const { stages } = level;
|
|
296
490
|
const record = { ...value };
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
491
|
+
let told;
|
|
492
|
+
if (stages.length > 1) {
|
|
493
|
+
told = { ...record };
|
|
494
|
+
for (const key of Object.keys(told)) {
|
|
495
|
+
const nested = told[key];
|
|
496
|
+
if (isNestedContainer(nested)) {
|
|
497
|
+
told[key] = frozenCopy(nested, true);
|
|
498
|
+
}
|
|
302
499
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
500
|
+
}
|
|
501
|
+
for (const stage of stages) {
|
|
502
|
+
const view = frozenCopy(told ?? record);
|
|
503
|
+
const computedValue = await stage.compute({
|
|
504
|
+
field: stage.field,
|
|
505
|
+
value: view[stage.field],
|
|
506
|
+
record: view,
|
|
507
|
+
ctx: contextFactory(),
|
|
310
508
|
});
|
|
311
509
|
if (computedValue === undefined) {
|
|
312
510
|
continue;
|
|
313
511
|
}
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
512
|
+
const held = heldReadValue(active, level, stage, computedValue);
|
|
513
|
+
record[stage.field] = held;
|
|
514
|
+
if (told !== undefined) {
|
|
515
|
+
told[stage.field] = held;
|
|
317
516
|
}
|
|
318
|
-
record[fieldName] = validation.value;
|
|
319
517
|
}
|
|
320
|
-
for (const relation of
|
|
518
|
+
for (const { relation, level: nested } of level.relations) {
|
|
321
519
|
if (!Object.hasOwn(record, relation.field)) {
|
|
322
520
|
continue;
|
|
323
521
|
}
|
|
324
|
-
record[relation.field] = await materializeRelation(active,
|
|
522
|
+
record[relation.field] = await materializeRelation(active, nested, relation, record[relation.field], contextFactory);
|
|
325
523
|
}
|
|
326
|
-
return
|
|
327
|
-
.filter((fieldName) => Object.hasOwn(record, fieldName))
|
|
328
|
-
.map((fieldName) => [fieldName, record[fieldName]]));
|
|
524
|
+
return answerOf(level, record);
|
|
329
525
|
}
|
|
330
|
-
export async function materializeReadOperation(active,
|
|
526
|
+
export async function materializeReadOperation(active, compute, _request, plan, value, contextFactory) {
|
|
331
527
|
const projection = plan.projection;
|
|
332
528
|
if (!plan.materialize || projection === undefined) {
|
|
333
529
|
return value;
|
|
334
530
|
}
|
|
531
|
+
const level = resolveReadLevel(active, compute, projection, true);
|
|
335
532
|
if (Array.isArray(value)) {
|
|
336
|
-
|
|
533
|
+
const rows = value.map((entry) => materializeRecord(active, level, entry, contextFactory));
|
|
534
|
+
return rows.some((row) => row instanceof Promise)
|
|
535
|
+
? Promise.all(rows)
|
|
536
|
+
: Array.from(rows);
|
|
337
537
|
}
|
|
338
|
-
return materializeRecord(active,
|
|
538
|
+
return materializeRecord(active, level, value, contextFactory);
|
|
339
539
|
}
|
|
@@ -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,60 @@
|
|
|
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 { AvApplicationOperationRequest } 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
|
+
type RawOperationRunner<M extends AvAdapterModel> = (request: AvApplicationOperationRequest, transaction: AvAdapterTransactionExecutor<M> | undefined) => Promise<AvOperationResponse>;
|
|
39
|
+
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>;
|
|
60
|
+
export {};
|