@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,11 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
2
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
3
|
+
import type { AvOperationFailureResponse, AvOperationResponse } from "./operation-response.js";
|
|
4
|
+
/**
|
|
5
|
+
* The failure a strict unique operation's miss raises inside the pipeline, or
|
|
6
|
+
* `undefined` when `data` is a row, or the variant answers a miss with `null`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function uniqueMissFailure(operation: AvOperationIdentity, data: unknown): AvOperationFailureResponse | undefined;
|
|
4
9
|
/**
|
|
5
10
|
* Maps one validated operation result to its stable outcome envelope. The
|
|
6
11
|
* result must already have passed output validation, so `null` can only
|
|
7
12
|
* reach a variant whose cardinality admits it.
|
|
8
13
|
*/
|
|
9
|
-
export declare function mapOperationOutcome(operation:
|
|
14
|
+
export declare function mapOperationOutcome(operation: AvOperationIdentity, data: unknown): AvOperationResponse;
|
|
15
|
+
/** The A-codes a set of Framework Validation Layer issues can roll up to. */
|
|
16
|
+
type ValidationOutcomeCode = "A2001" | "A2002" | "A2004" | "A2007" | "A2009";
|
|
17
|
+
/** The framework's top-level `cause.message` for each validation outcome code. */
|
|
18
|
+
export declare const VALIDATION_OUTCOME_MESSAGES: {
|
|
19
|
+
readonly [K in ValidationOutcomeCode]: string;
|
|
20
|
+
};
|
|
10
21
|
/** Maps framework validation issues to their stable failure envelope. */
|
|
11
|
-
export declare function mapValidationOutcome(issues: readonly
|
|
22
|
+
export declare function mapValidationOutcome(issues: readonly AvValidationIssue[]): AvOperationFailureResponse;
|
|
23
|
+
export {};
|
|
@@ -21,18 +21,26 @@ function outcomeRule(operation) {
|
|
|
21
21
|
const table = OUTCOME_TABLE;
|
|
22
22
|
return table[`${operation.family}.${operation.variant}`];
|
|
23
23
|
}
|
|
24
|
+
function notFound() {
|
|
25
|
+
return operationFailure("A2003", {
|
|
26
|
+
message: "No record matched the unique selector.",
|
|
27
|
+
});
|
|
28
|
+
}
|
|
24
29
|
function absenceOutcome(absence) {
|
|
25
30
|
switch (absence) {
|
|
26
31
|
case "no-match":
|
|
27
32
|
return operationNoMatch();
|
|
28
33
|
case "not-found":
|
|
29
|
-
return
|
|
30
|
-
message: "No record matched the unique selector.",
|
|
31
|
-
});
|
|
34
|
+
return notFound();
|
|
32
35
|
case undefined:
|
|
33
36
|
return internalFailure();
|
|
34
37
|
}
|
|
35
38
|
}
|
|
39
|
+
export function uniqueMissFailure(operation, data) {
|
|
40
|
+
return data === null && outcomeRule(operation)?.absence === "not-found"
|
|
41
|
+
? notFound()
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
36
44
|
export function mapOperationOutcome(operation, data) {
|
|
37
45
|
const rule = outcomeRule(operation);
|
|
38
46
|
if (rule === undefined) {
|
|
@@ -52,6 +60,13 @@ function namesUnavailableOperation(issue) {
|
|
|
52
60
|
const head = stepRelativeHead(issue);
|
|
53
61
|
return issue.code === "V1006" && (head === "family" || head === "variant");
|
|
54
62
|
}
|
|
63
|
+
export const VALIDATION_OUTCOME_MESSAGES = {
|
|
64
|
+
A2001: "The requested Resource is not available.",
|
|
65
|
+
A2002: "The requested operation is not available on this Resource.",
|
|
66
|
+
A2004: "Operation arguments failed framework validation.",
|
|
67
|
+
A2007: "Operation arguments failed framework validation.",
|
|
68
|
+
A2009: "Operation arguments failed framework validation.",
|
|
69
|
+
};
|
|
55
70
|
function validationCode(issues) {
|
|
56
71
|
if (issues.some((issue) => issue.code !== "V1019" && stepRelativeHead(issue) === "resource")) {
|
|
57
72
|
return "A2001";
|
|
@@ -68,14 +83,16 @@ function validationCode(issues) {
|
|
|
68
83
|
}
|
|
69
84
|
if (issues.some((issue) => issue.code === "V1013" ||
|
|
70
85
|
issue.code === "V1014" ||
|
|
71
|
-
issue.code === "V1015"
|
|
86
|
+
issue.code === "V1015" ||
|
|
87
|
+
issue.code === "V1021")) {
|
|
72
88
|
return "A2009";
|
|
73
89
|
}
|
|
74
90
|
return "A2004";
|
|
75
91
|
}
|
|
76
92
|
export function mapValidationOutcome(issues) {
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
const code = validationCode(issues);
|
|
94
|
+
return operationFailure(code, {
|
|
95
|
+
message: VALIDATION_OUTCOME_MESSAGES[code],
|
|
79
96
|
issues,
|
|
80
97
|
});
|
|
81
98
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
2
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
3
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
4
4
|
import type { ReadProjectionPlan } from "./computed-read-runtime.js";
|
|
5
|
-
|
|
5
|
+
type OutputValidationResult = {
|
|
6
6
|
readonly ok: true;
|
|
7
7
|
} | {
|
|
8
8
|
readonly ok: false;
|
|
9
|
-
readonly issues: readonly
|
|
9
|
+
readonly issues: readonly AvValidationIssue[];
|
|
10
10
|
};
|
|
11
|
-
type OutputOperation =
|
|
11
|
+
type OutputOperation = AvOperationIdentity & {
|
|
12
12
|
readonly resource: string;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
@@ -16,11 +16,11 @@ type OutputOperation = OperationIdentity & {
|
|
|
16
16
|
* validation: whose result it was and what the validator found. The caller
|
|
17
17
|
* receives the generic `A3000` and never this.
|
|
18
18
|
*/
|
|
19
|
-
export declare class
|
|
20
|
-
readonly issues: readonly
|
|
21
|
-
readonly name = "
|
|
22
|
-
constructor(operation: OutputOperation, issues: readonly
|
|
19
|
+
export declare class AvOutputValidationError extends Error {
|
|
20
|
+
readonly issues: readonly AvValidationIssue[];
|
|
21
|
+
readonly name = "AvOutputValidationError";
|
|
22
|
+
constructor(operation: OutputOperation, issues: readonly AvValidationIssue[]);
|
|
23
23
|
}
|
|
24
24
|
/** Validate final operation output against fixed cardinality and executed projection. */
|
|
25
|
-
export declare function validateOperationOutput(contract:
|
|
25
|
+
export declare function validateOperationOutput(contract: AvContract, operation: OutputOperation, projection: ReadProjectionPlan | undefined, value: unknown): OutputValidationResult;
|
|
26
26
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { lookupField, lookupResource } from "../contracts/contract-lookup.js";
|
|
2
|
-
import { advertisedReducers } from "../contracts/field.js";
|
|
2
|
+
import { advertisedReducers, } from "../contracts/field.js";
|
|
3
3
|
import { normalizeScalarFieldValue } from "./scalar-runtime.js";
|
|
4
4
|
function issue(message, path = ["data"]) {
|
|
5
5
|
return { ok: false, issues: [{ path, code: "V1001", message }] };
|
|
@@ -168,9 +168,9 @@ function validateProjection(contract, operation, projection, value) {
|
|
|
168
168
|
? validateExactRecord(contract, value, projection, ["data"])
|
|
169
169
|
: { ok: true };
|
|
170
170
|
}
|
|
171
|
-
export class
|
|
171
|
+
export class AvOutputValidationError extends Error {
|
|
172
172
|
issues;
|
|
173
|
-
name = "
|
|
173
|
+
name = "AvOutputValidationError";
|
|
174
174
|
constructor(operation, issues) {
|
|
175
175
|
const [first] = issues;
|
|
176
176
|
super(`The result of ${operation.resource}.${operation.family}.${operation.variant} does not satisfy its Contract${first === undefined
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
1
|
+
import type { AvAgentTransactionRequest, AvClientTransactionRequest } from "../transactions/transaction-request.js";
|
|
2
|
+
import type { AvTransactionResponse } from "../transactions/transaction-response.js";
|
|
3
|
+
import type { AvCallerDataError } from "./caller-data.copier.js";
|
|
4
|
+
import type { RemoteOperationRequest } from "./operation-request.js";
|
|
5
|
+
import type { AvOperationResponse } from "./operation-response.js";
|
|
5
6
|
/** The two entries that run a request the protocol decoded itself, uncopied. */
|
|
6
7
|
export type OwnedExecution = {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Runs `request` uncopied; with `refused`, its arguments are a host's parsed body
|
|
10
|
+
* whose copy at the call failed, answered as the door answers that failure.
|
|
11
|
+
*/
|
|
12
|
+
readonly execute: (request: RemoteOperationRequest, refused?: AvCallerDataError) => Promise<AvOperationResponse>;
|
|
13
|
+
/**
|
|
14
|
+
* Runs `request` uncopied; with `refused`, its plan is a host's parsed plan taken
|
|
15
|
+
* at the call, and these steps' arguments could not be copied there: each is
|
|
16
|
+
* answered at its turn as the door answers that failure.
|
|
17
|
+
*/
|
|
18
|
+
readonly executeTransaction: (request: AvClientTransactionRequest | AvAgentTransactionRequest, refused?: ReadonlyMap<number, AvCallerDataError>) => Promise<AvTransactionResponse>;
|
|
9
19
|
};
|
|
10
20
|
/** Records `framework`'s owned entries; called once, at construction. */
|
|
11
21
|
export declare function recordOwnedExecution(framework: object, execution: OwnedExecution): void;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
1
|
+
import type { AvContract, AvContractCore } from "../contracts/contract.js";
|
|
2
|
+
import type { AvOperationIdentity } from "../operations/operation-identity.js";
|
|
3
|
+
import type { OperationValidationOptions } from "../operations/operation-validator.js";
|
|
4
|
+
import type { AvValidationIssue } from "../operations/validation-code.js";
|
|
5
|
+
import type { AvOperationFailureResponse } from "./operation-response.js";
|
|
5
6
|
/**
|
|
6
7
|
* The check a pipe's output passes before it can reach the Adapter.
|
|
7
8
|
*
|
|
@@ -12,37 +13,61 @@ import type { OperationFailureResponse } from "./operation-response.js";
|
|
|
12
13
|
* are held to the **server's** rules — the Core Contract, plus the fields the
|
|
13
14
|
* active scope itself adds (they are virtual: computed, then stripped before
|
|
14
15
|
* the Adapter call) — in the values' runtime forms (`bigint`, `Date`,
|
|
15
|
-
* `
|
|
16
|
+
* `AvDecimal`, `Uint8Array`), which is what every pipe receives.
|
|
16
17
|
*
|
|
17
18
|
* A refusal is the server's defect, not the caller's: `A3004
|
|
18
19
|
* PIPE_OUTPUT_INVALID`, a 500 that tells the caller no more than any internal
|
|
19
20
|
* failure does — {@link PIPE_OUTPUT_FAILURE_MESSAGE}, and the step in a plan.
|
|
20
21
|
* The pipe, the operation, the first offending field and its V-code go to the
|
|
21
|
-
* diagnostics channel only, as a {@link
|
|
22
|
+
* diagnostics channel only, as a {@link AvPipeOutputError}: they name server
|
|
22
23
|
* internals — a pipe's function name, a field the caller's Contract hides.
|
|
23
24
|
*/
|
|
24
25
|
/** The one text every `A3004` carries on the wire. */
|
|
25
26
|
export declare const PIPE_OUTPUT_FAILURE_MESSAGE = "A server pipeline produced invalid arguments.";
|
|
27
|
+
/** The Contract a stage's output is held to: Core's Resources plus what `active` adds. */
|
|
28
|
+
export declare function serverContractFor(core: AvContractCore, active: AvContract): AvContract;
|
|
26
29
|
/** The error the diagnostics channel receives for a refused pipe output. */
|
|
27
|
-
export declare class
|
|
28
|
-
readonly issues: readonly
|
|
29
|
-
readonly name = "
|
|
30
|
-
constructor(message: string, issues: readonly
|
|
30
|
+
export declare class AvPipeOutputError extends Error {
|
|
31
|
+
readonly issues: readonly AvValidationIssue[];
|
|
32
|
+
readonly name = "AvPipeOutputError";
|
|
33
|
+
constructor(message: string, issues: readonly AvValidationIssue[]);
|
|
31
34
|
}
|
|
35
|
+
/** A refused stage output: the `A3004` answer and what diagnostics are told. */
|
|
36
|
+
export type RefusedStageOutput = {
|
|
37
|
+
readonly response: AvOperationFailureResponse;
|
|
38
|
+
readonly error: AvPipeOutputError;
|
|
39
|
+
};
|
|
32
40
|
/**
|
|
33
41
|
* `undefined` when the pipe's output passes the server's rules; otherwise the
|
|
34
42
|
* `A3004` failure, and the error the diagnostics channel is told.
|
|
35
43
|
*/
|
|
36
44
|
export declare function refusePipeOutput(contracts: {
|
|
37
|
-
readonly core:
|
|
38
|
-
readonly active:
|
|
39
|
-
}, request:
|
|
45
|
+
readonly core: AvContractCore;
|
|
46
|
+
readonly active: AvContract;
|
|
47
|
+
}, request: AvOperationIdentity & {
|
|
40
48
|
readonly resource: string;
|
|
41
49
|
}, args: unknown,
|
|
42
50
|
/** The pipe that produced `args`, named in the message by its function name. */
|
|
43
51
|
pipe: unknown,
|
|
44
|
-
/** Its position in the effective pipe list (
|
|
45
|
-
index: number
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
/** Its position in the effective pipe list (outer levels first). */
|
|
53
|
+
index: number,
|
|
54
|
+
/** A plan step's pipes run before BEGIN, its `$ref` slots unresolved: these admit them. */
|
|
55
|
+
options?: OperationValidationOptions): RefusedStageOutput | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* {@link refusePipeOutput} for any stage that changed the arguments; `subject`
|
|
58
|
+
* names it in the diagnostic (`Field pipes`, `Transaction pipes`).
|
|
59
|
+
*/
|
|
60
|
+
export declare function refuseStageOutput(contracts: {
|
|
61
|
+
readonly core: AvContractCore;
|
|
62
|
+
readonly active: AvContract;
|
|
63
|
+
}, request: AvOperationIdentity & {
|
|
64
|
+
readonly resource: string;
|
|
65
|
+
}, args: unknown, subject: string, options?: OperationValidationOptions): RefusedStageOutput | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* The `A3004` for a stage output the server's rules raised `issues` against
|
|
68
|
+
* (paths under `["arguments", …]`), the first named in the diagnostic;
|
|
69
|
+
* `undefined` when there are none.
|
|
70
|
+
*/
|
|
71
|
+
export declare function refusedStageOutput(request: AvOperationIdentity & {
|
|
72
|
+
readonly resource: string;
|
|
73
|
+
}, issues: readonly AvValidationIssue[], subject: string): RefusedStageOutput | undefined;
|
|
@@ -19,7 +19,7 @@ function serverContract(core, active) {
|
|
|
19
19
|
return { ...core, resources };
|
|
20
20
|
}
|
|
21
21
|
const SERVER_VIEWS = new WeakMap();
|
|
22
|
-
function serverContractFor(core, active) {
|
|
22
|
+
export function serverContractFor(core, active) {
|
|
23
23
|
let view = SERVER_VIEWS.get(active);
|
|
24
24
|
if (view === undefined) {
|
|
25
25
|
view = serverContract(core, active);
|
|
@@ -27,15 +27,12 @@ function serverContractFor(core, active) {
|
|
|
27
27
|
}
|
|
28
28
|
return view;
|
|
29
29
|
}
|
|
30
|
-
function serverIssues(contract, request, args) {
|
|
31
|
-
const validation = validateOperationArguments(contract, {
|
|
32
|
-
...request,
|
|
33
|
-
arguments: args,
|
|
34
|
-
});
|
|
30
|
+
function serverIssues(contract, request, args, options) {
|
|
31
|
+
const validation = validateOperationArguments(contract, { ...request, arguments: args }, options);
|
|
35
32
|
if (!validation.ok) {
|
|
36
33
|
return validation.issues;
|
|
37
34
|
}
|
|
38
|
-
const normalization = normalizeOperationScalarValues(contract, { ...request, arguments: validation.arguments }, "application");
|
|
35
|
+
const normalization = normalizeOperationScalarValues(contract, { ...request, arguments: validation.arguments }, "application", options);
|
|
39
36
|
return normalization.ok ? [] : normalization.issues;
|
|
40
37
|
}
|
|
41
38
|
function pipeLabel(pipe, index) {
|
|
@@ -55,25 +52,30 @@ function fieldOf(issue) {
|
|
|
55
52
|
const relative = path[0] === "arguments" ? path.slice(1) : path;
|
|
56
53
|
return relative.length === 0 ? "(arguments)" : relative.join(".");
|
|
57
54
|
}
|
|
58
|
-
export class
|
|
55
|
+
export class AvPipeOutputError extends Error {
|
|
59
56
|
issues;
|
|
60
|
-
name = "
|
|
57
|
+
name = "AvPipeOutputError";
|
|
61
58
|
constructor(message, issues) {
|
|
62
59
|
super(message);
|
|
63
60
|
this.issues = issues;
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
|
-
export function refusePipeOutput(contracts, request, args, pipe, index) {
|
|
67
|
-
|
|
63
|
+
export function refusePipeOutput(contracts, request, args, pipe, index, options) {
|
|
64
|
+
return refuseStageOutput(contracts, request, args, `Pipe ${pipeLabel(pipe, index)}`, options);
|
|
65
|
+
}
|
|
66
|
+
export function refuseStageOutput(contracts, request, args, subject, options) {
|
|
67
|
+
return refusedStageOutput(request, serverIssues(serverContractFor(contracts.core, contracts.active), request, args, options), subject);
|
|
68
|
+
}
|
|
69
|
+
export function refusedStageOutput(request, issues, subject) {
|
|
68
70
|
const [first] = issues;
|
|
69
71
|
if (first === undefined) {
|
|
70
72
|
return undefined;
|
|
71
73
|
}
|
|
72
|
-
const message =
|
|
74
|
+
const message = `${subject} returned arguments for ${request.resource}.${request.family}.${request.variant} that the server contract refuses at "${fieldOf(first)}" (${first.code}: ${first.message})`;
|
|
73
75
|
return {
|
|
74
76
|
response: operationFailure("A3004", {
|
|
75
77
|
message: PIPE_OUTPUT_FAILURE_MESSAGE,
|
|
76
78
|
}),
|
|
77
|
-
error: new
|
|
79
|
+
error: new AvPipeOutputError(message, issues),
|
|
78
80
|
};
|
|
79
81
|
}
|
|
@@ -1,54 +1,241 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
1
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
2
|
+
import type { AvAdapterSqlValue } from "../adapters/adapter-sql-statement.js";
|
|
3
|
+
import type { AvPreComputeLift } from "../config/computed-fields.js";
|
|
4
|
+
import type { AvRequestOrigin } from "../config/config-layer.js";
|
|
5
|
+
import type { AvConfigResourceKey } from "../config/framework-field-definition.js";
|
|
6
|
+
import type { AvContract } from "../contracts/contract.js";
|
|
7
|
+
import type { AvApplicationScalarForms } from "../contracts/scalar-value-type.js";
|
|
8
|
+
import type { AvContractApplicationView, RequirementsLessComputed } from "../framework/contract-view.js";
|
|
9
|
+
import type { AvContextOperations } from "../framework/operation-facade.js";
|
|
10
|
+
import type { AvOperationArgumentsFor, AvResourceKey } from "../operations/operation-arguments.js";
|
|
11
|
+
import type { AvOperationFamily, AvOperationIdentity } from "../operations/operation-identity.js";
|
|
12
|
+
import type { AvTransactionReference } from "../transactions/transaction-reference.js";
|
|
13
|
+
import type { AvError } from "./framework-error.js";
|
|
14
|
+
import type { ArrayForm, AvDeepReadonly, AvDeepReadonlyLeaf } from "./readonly-value.js";
|
|
15
|
+
import type { AvState } from "./request-state.js";
|
|
7
16
|
/**
|
|
8
17
|
* What a pipeline is told about the HTTP request a client-origin operation arrived on.
|
|
9
18
|
*/
|
|
10
|
-
export type
|
|
19
|
+
export type AvTransportContext = {
|
|
11
20
|
readonly method: "POST";
|
|
12
21
|
readonly headers: Readonly<Record<string, string>>;
|
|
13
22
|
};
|
|
14
|
-
/** What a pipeline
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
readonly origin:
|
|
18
|
-
readonly
|
|
19
|
-
|
|
20
|
-
readonly
|
|
21
|
-
|
|
22
|
-
readonly
|
|
23
|
-
|
|
23
|
+
/** What a pipeline ctx states about the request, whatever the stage. */
|
|
24
|
+
type AvContextFacts = {
|
|
25
|
+
/** `"application"` for server code and ctx calls, `"client"` for a remote caller. */
|
|
26
|
+
readonly $origin: AvRequestOrigin;
|
|
27
|
+
readonly $requestId: string;
|
|
28
|
+
/** The HTTP request a client-origin operation arrived on, when it did. */
|
|
29
|
+
readonly $transport?: AvTransportContext;
|
|
30
|
+
/** The active Contract: the Application or the Client Contract. */
|
|
31
|
+
readonly $contract: AvContract;
|
|
32
|
+
/**
|
|
33
|
+
* The request's state: the one writable per-request space. Every stage of the
|
|
34
|
+
* request, a transaction's steps and transaction stages, and the ctx calls they
|
|
35
|
+
* make share this object. Seeded by the caller or the host; `{}` otherwise. Its
|
|
36
|
+
* members are the application's, declared by augmenting {@link AvState}.
|
|
37
|
+
*/
|
|
38
|
+
readonly $state: AvState;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The arguments a variant-level stage is told: the operation's arguments under
|
|
42
|
+
* the model's Application Contract view, in the application forms, a reference
|
|
43
|
+
* position admitting an unresolved `$ref`. `unknown` for a model whose Resource
|
|
44
|
+
* names are not literal.
|
|
45
|
+
*/
|
|
46
|
+
export type AvStageArguments<M extends AvAdapterModel, R extends string, F extends AvOperationFamily, V extends string> = StageArgumentsOf<AvContractApplicationView<M>, R, F, V>;
|
|
47
|
+
/** The arguments of operation `F`.`V` on `R` under the Contract view `C`. */
|
|
48
|
+
type StageArgumentsOf<C extends AvContract, R extends string, F extends AvOperationFamily, V extends string> = string extends R ? unknown : R extends AvResourceKey<C> ? AvOperationArgumentsFor<C, R, Extract<AvOperationIdentity, {
|
|
49
|
+
readonly family: F;
|
|
50
|
+
readonly variant: V;
|
|
51
|
+
}>, AvApplicationScalarForms, AvApplicationScalarForms> : unknown;
|
|
52
|
+
/**
|
|
53
|
+
* The arguments a variant's guards, pipes and filters are told: the operation's
|
|
54
|
+
* arguments before write compute has run, so a create need not hold a field
|
|
55
|
+
* `compute.create` fills (`Lift`, as `"<Resource>.<field>"`; `string`: any).
|
|
56
|
+
*/
|
|
57
|
+
export type AvPreComputeStageArguments<M extends AvAdapterModel, R extends string, F extends AvOperationFamily, V extends string, Lift extends string = AvPreComputeLift<M, "root">> = F extends "find" | "delete" ? AvStageArguments<M, R, F, V> : [Lift] extends [never] ? AvStageArguments<M, R, F, V> : StageArgumentsOf<PreComputeView<AvContractApplicationView<M>, Lift>, R, F, V>;
|
|
58
|
+
/** A Contract view with the create requirements `Lift` names lifted. */
|
|
59
|
+
type PreComputeView<C, Lift extends string> = Extract<{
|
|
60
|
+
readonly [P in keyof C]: P extends "resources" ? string extends Lift ? {
|
|
61
|
+
readonly [R in keyof C[P]]: Omit<C[P][R], "createRequirements">;
|
|
62
|
+
} : {
|
|
63
|
+
readonly [R in keyof C[P]]: LiftedResource<C[P][R], LiftedFieldOf<Lift, R>>;
|
|
64
|
+
} : C[P];
|
|
65
|
+
}, AvContract>;
|
|
66
|
+
/** The fields of Resource `R` that `Lift` names. */
|
|
67
|
+
type LiftedFieldOf<Lift extends string, R> = Lift extends `${R & string}.${infer Field}` ? Field : never;
|
|
68
|
+
/** One Resource with the create requirements on `Fields` lifted; itself when none. */
|
|
69
|
+
type LiftedResource<Resource, Fields> = [Fields] extends [never] ? Resource : {
|
|
70
|
+
readonly [P in keyof Resource]: P extends "createRequirements" ? RequirementsLessComputed<Exclude<Resource[P], undefined>, Fields> : Resource[P];
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* What a pipeline callback is told about the operation it is wrapping, and the
|
|
74
|
+
* framework's executor: `ctx.<Resource>.<family>.<variant>(args)`, `ctx.$sql` and
|
|
75
|
+
* `ctx.$transaction`. Every framework member is `$`-prefixed.
|
|
76
|
+
*
|
|
77
|
+
* A ctx call is raw and application-origin: it runs the Framework Validation
|
|
78
|
+
* Layer, field pipes, field validators and compute, and no developer stage
|
|
79
|
+
* (guards, pipes, hooks, interceptors, filters, field write guards, transaction
|
|
80
|
+
* stages), so a hook's call never re-enters the hook. It joins the current
|
|
81
|
+
* transaction when there is one, and resolves the operation's data or throws an
|
|
82
|
+
* `AvError`.
|
|
83
|
+
*/
|
|
84
|
+
export type AvContext<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = AvContextOperations<M> & AvContextFacts & {
|
|
85
|
+
/**
|
|
86
|
+
* The operation the stage wraps. For a nested write's target `resource` is the
|
|
87
|
+
* target, `family` the family its directive maps to, `variant` is `"one"` and
|
|
88
|
+
* `nested` is `true`.
|
|
89
|
+
*/
|
|
90
|
+
readonly $operation: {
|
|
91
|
+
readonly resource: R;
|
|
92
|
+
readonly family: F;
|
|
93
|
+
readonly variant: V;
|
|
94
|
+
readonly nested?: true;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The arguments, deep-frozen: as the caller sent them in a guard, as the pipes
|
|
98
|
+
* returned them in a pipe, and the validated arguments the operation executes in
|
|
99
|
+
* an interceptor, a hook or a filter. Only a pipe changes them, by returning new
|
|
100
|
+
* ones; writing to them throws a `TypeError`. At a variant, typed as that
|
|
101
|
+
* operation's arguments ({@link AvStageArguments}), deep read-only; in a guard or
|
|
102
|
+
* a filter a create may lack the fields `compute.create` fills ({@link
|
|
103
|
+
* AvPreComputeStageArguments}: write compute has not run); above it, `unknown`.
|
|
104
|
+
*/
|
|
105
|
+
readonly $args: AvDeepReadonly<A>;
|
|
106
|
+
/**
|
|
107
|
+
* A developer SQL statement, written only as a tagged template —
|
|
108
|
+
* ``await ctx.$sql<Row>`insert into audit (actor) values (${actorId})` ``
|
|
109
|
+
* — run at once. Every interpolated value is bound as a parameter, never
|
|
110
|
+
* spliced into the text. It runs in the current transaction; outside one,
|
|
111
|
+
* as a plain statement, with no transaction opened around it. Resolves
|
|
112
|
+
* the rows the statement returned.
|
|
113
|
+
*/
|
|
114
|
+
readonly $sql: <Row = unknown>(strings: TemplateStringsArray, ...values: readonly AvAdapterSqlValue[]) => Promise<Row[]>;
|
|
115
|
+
/**
|
|
116
|
+
* Runs `work` in a transaction, `tx` being this ctx bound to it, and resolves
|
|
117
|
+
* what `work` resolved; a throw rolls it back. Inside an open transaction it
|
|
118
|
+
* opens nothing and joins it.
|
|
119
|
+
*/
|
|
120
|
+
$transaction<T>(work: (tx: AvContext<M, R, F, V, A>) => Promise<T>): Promise<T>;
|
|
24
121
|
};
|
|
25
122
|
/** Allows or denies an operation; returning `false` answers `A4001`. */
|
|
26
|
-
export type
|
|
27
|
-
guard(context:
|
|
123
|
+
export type AvGuard<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
124
|
+
guard(context: AvContext<M, R, F, V, A>): boolean | undefined | Promise<boolean | undefined>;
|
|
28
125
|
}["guard"];
|
|
29
126
|
/**
|
|
30
|
-
* Transforms the arguments before the
|
|
31
|
-
*
|
|
127
|
+
* Transforms the arguments before the validators judge them: the only stage
|
|
128
|
+
* that changes them. `args` is deep-frozen, so a pipe returns new arguments;
|
|
129
|
+
* returning `undefined` keeps them as they are. At a variant, `args` and the
|
|
130
|
+
* return are typed as that operation's arguments before write compute runs
|
|
131
|
+
* ({@link AvPreComputeStageArguments}: a create may lack the fields
|
|
132
|
+
* `compute.create` fills), `args` deep read-only.
|
|
32
133
|
*/
|
|
33
|
-
export type
|
|
34
|
-
pipe(args:
|
|
134
|
+
export type AvPipe<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
135
|
+
pipe(args: PipeArguments<A>, context: AvContext<M, R, F, V, A>): unknown extends PipeArguments<A> ? any : PipeArguments<A> | undefined | void | Promise<PipeArguments<A> | undefined | void>;
|
|
35
136
|
}["pipe"];
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
137
|
+
/**
|
|
138
|
+
* A variant pipe's arguments and return: the operation's arguments, deep
|
|
139
|
+
* read-only, each member closed to inference.
|
|
140
|
+
*/
|
|
141
|
+
type PipeArguments<T> = T extends AvDeepReadonlyLeaf | AvTransactionReference ? T : T extends readonly unknown[] ? ArrayForm<T> extends "array" ? readonly NoInfer<PipeArguments<Exclude<T[number], undefined>>>[] : {
|
|
142
|
+
readonly [K in keyof T]: NoInfer<PipeArguments<Exclude<T[K], undefined>>>;
|
|
143
|
+
} : T extends object ? {
|
|
144
|
+
readonly [K in keyof T]: NoInfer<PipeArguments<Exclude<T[K], undefined>>>;
|
|
145
|
+
} : T;
|
|
146
|
+
/** Runs just before the operation executes, inside every interceptor; `ctx.$args` is deep-frozen. */
|
|
147
|
+
export type AvBeforeHook<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
148
|
+
before(context: AvContext<M, R, F, V, A>): void | Promise<void>;
|
|
39
149
|
}["before"];
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Runs after the operation succeeds, with its result, deep-frozen; an
|
|
152
|
+
* interceptor may still answer a different one.
|
|
153
|
+
*/
|
|
154
|
+
export type AvAfterHook<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
155
|
+
after(result: unknown, context: AvContext<M, R, F, V, A>): void | Promise<void>;
|
|
43
156
|
}["after"];
|
|
44
157
|
/** Wraps the operation's execution; call `next()` to run it and get its result. */
|
|
45
|
-
export type
|
|
46
|
-
intercept(context:
|
|
158
|
+
export type AvInterceptor<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
159
|
+
intercept(context: AvContext<M, R, F, V, A>, next: () => Promise<unknown>): Promise<unknown>;
|
|
47
160
|
}["intercept"];
|
|
48
161
|
/**
|
|
49
|
-
* Turns a thrown error into a {@link
|
|
162
|
+
* Turns a thrown error into a {@link AvError} to answer with; returning
|
|
50
163
|
* `undefined` passes the error on.
|
|
51
164
|
*/
|
|
52
|
-
export type
|
|
53
|
-
filter(error: unknown, context:
|
|
165
|
+
export type AvFilter<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>, F extends AvOperationFamily = AvOperationFamily, V extends string = string, A = unknown> = {
|
|
166
|
+
filter(error: unknown, context: AvContext<M, R, F, V, A>): AvError | undefined | Promise<AvError | undefined>;
|
|
167
|
+
}["filter"];
|
|
168
|
+
/**
|
|
169
|
+
* A pure transform of the value the caller sent for one scalar field: value in,
|
|
170
|
+
* value out, no context. Returning `undefined` keeps the value.
|
|
171
|
+
*/
|
|
172
|
+
export type AvFieldPipe = (value: unknown) => unknown | Promise<unknown>;
|
|
173
|
+
/**
|
|
174
|
+
* Write-only admission for one field: refuses the operation when the caller sends
|
|
175
|
+
* the field. Returning `false` answers `A4001`.
|
|
176
|
+
*/
|
|
177
|
+
export type AvFieldGuard<M extends AvAdapterModel = AvAdapterModel, R extends string = AvConfigResourceKey<M>> = {
|
|
178
|
+
guard(value: unknown, context: AvContext<M, R, "create" | "update" | "upsert">): boolean | undefined | Promise<boolean | undefined>;
|
|
179
|
+
}["guard"];
|
|
180
|
+
/**
|
|
181
|
+
* One plan step as a transaction stage reads it: an operation step with its
|
|
182
|
+
* `$ref`s unresolved, or a SQL step, which names no Resource.
|
|
183
|
+
*/
|
|
184
|
+
export type AvTransactionStep<M extends AvAdapterModel = AvAdapterModel> = {
|
|
185
|
+
readonly resource: AvConfigResourceKey<M>;
|
|
186
|
+
readonly family: AvOperationFamily;
|
|
187
|
+
readonly variant: string;
|
|
188
|
+
readonly args: unknown;
|
|
189
|
+
readonly sql?: never;
|
|
190
|
+
} | {
|
|
191
|
+
readonly sql: {
|
|
192
|
+
readonly strings: readonly string[] | undefined;
|
|
193
|
+
readonly values: readonly unknown[];
|
|
194
|
+
};
|
|
195
|
+
readonly resource?: never;
|
|
196
|
+
readonly family?: never;
|
|
197
|
+
readonly variant?: never;
|
|
198
|
+
readonly args?: never;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* What a Resource's transaction stage is told: the plan, not one operation
|
|
202
|
+
* (`$operation` is absent), and the executor, bound to the transaction.
|
|
203
|
+
*/
|
|
204
|
+
export type AvTransactionContext<M extends AvAdapterModel = AvAdapterModel> = AvContextOperations<M> & AvContextFacts & {
|
|
205
|
+
/** The plan, in step order, `$ref`s unresolved, deep-frozen. */
|
|
206
|
+
readonly $args: readonly AvTransactionStep<M>[];
|
|
207
|
+
/** As a stage's `ctx.$sql`: a developer SQL statement, run in this transaction. */
|
|
208
|
+
readonly $sql: <Row = unknown>(strings: TemplateStringsArray, ...values: readonly AvAdapterSqlValue[]) => Promise<Row[]>;
|
|
209
|
+
/** Runs `work` inside this transaction (it opens nothing): `tx` is this ctx. */
|
|
210
|
+
$transaction<T>(work: (tx: AvTransactionContext<M>) => Promise<T>): Promise<T>;
|
|
211
|
+
};
|
|
212
|
+
/** Allows or denies a whole transaction; returning `false` answers `A4001`. */
|
|
213
|
+
export type AvTransactionGuard<M extends AvAdapterModel = AvAdapterModel> = {
|
|
214
|
+
guard(context: AvTransactionContext<M>): boolean | undefined | Promise<boolean | undefined>;
|
|
215
|
+
}["guard"];
|
|
216
|
+
/**
|
|
217
|
+
* Transforms the plan before any step runs; returning `undefined` keeps it. The
|
|
218
|
+
* plan it is given is deep-frozen, so it returns a new one. A
|
|
219
|
+
* returned plan keeps its steps (the same number, each on the same operation,
|
|
220
|
+
* each SQL step as it was); only an operation step's `args` may change.
|
|
221
|
+
*/
|
|
222
|
+
export type AvTransactionPipe<M extends AvAdapterModel = AvAdapterModel> = {
|
|
223
|
+
pipe(plan: readonly AvTransactionStep<M>[], context: AvTransactionContext<M>): readonly AvTransactionStep[] | undefined | Promise<readonly AvTransactionStep[] | undefined>;
|
|
224
|
+
}["pipe"];
|
|
225
|
+
/** Runs inside the transaction before its steps. */
|
|
226
|
+
export type AvTransactionBeforeHook<M extends AvAdapterModel = AvAdapterModel> = {
|
|
227
|
+
before(context: AvTransactionContext<M>): void | Promise<void>;
|
|
228
|
+
}["before"];
|
|
229
|
+
/** Runs inside the transaction after its steps, with every step's result, deep-frozen. */
|
|
230
|
+
export type AvTransactionAfterHook<M extends AvAdapterModel = AvAdapterModel> = {
|
|
231
|
+
after(results: unknown, context: AvTransactionContext<M>): void | Promise<void>;
|
|
232
|
+
}["after"];
|
|
233
|
+
/** Wraps the transaction's steps; call `next()` to run them. */
|
|
234
|
+
export type AvTransactionInterceptor<M extends AvAdapterModel = AvAdapterModel> = {
|
|
235
|
+
intercept(context: AvTransactionContext<M>, next: () => Promise<unknown>): Promise<unknown>;
|
|
236
|
+
}["intercept"];
|
|
237
|
+
/** Turns an error thrown inside the transaction into a {@link AvError}. */
|
|
238
|
+
export type AvTransactionFilter<M extends AvAdapterModel = AvAdapterModel> = {
|
|
239
|
+
filter(error: unknown, context: AvTransactionContext<M>): AvError | undefined | Promise<AvError | undefined>;
|
|
54
240
|
}["filter"];
|
|
241
|
+
export {};
|