@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
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AvPolicyWhere } from "./policy-engine.js";
|
|
2
|
+
/** A row condition: every row, no row, or a `where` fragment. */
|
|
3
|
+
export type PolicyCondition = boolean | AvPolicyWhere;
|
|
4
|
+
/** Both conditions: a constant folds, two fragments become one `AND`. */
|
|
5
|
+
export declare function allOf(left: PolicyCondition, right: PolicyCondition): PolicyCondition;
|
|
6
|
+
/** Either condition: a constant folds, two fragments become one `OR`. */
|
|
7
|
+
export declare function anyOf(left: PolicyCondition, right: PolicyCondition): PolicyCondition;
|
|
8
|
+
/** Every condition of `conditions`; `true` when there is none. */
|
|
9
|
+
export declare function everyOf(conditions: readonly PolicyCondition[]): PolicyCondition;
|
|
10
|
+
/** Any condition of `conditions`; `false` when there is none. */
|
|
11
|
+
export declare function someOf(conditions: readonly PolicyCondition[]): PolicyCondition;
|
|
12
|
+
/** The negation: a constant flips, a fragment is wrapped in `NOT`. */
|
|
13
|
+
export declare function noneOf(condition: PolicyCondition): PolicyCondition;
|
|
14
|
+
/** A condition as a `where` an `exists` or a read can run: `{}` for every row. */
|
|
15
|
+
export declare function whereOf(condition: Exclude<PolicyCondition, false>): AvPolicyWhere;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function allOf(left, right) {
|
|
2
|
+
if (left === false || right === false) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (left === true) {
|
|
6
|
+
return right;
|
|
7
|
+
}
|
|
8
|
+
if (right === true) {
|
|
9
|
+
return left;
|
|
10
|
+
}
|
|
11
|
+
return { AND: [left, right] };
|
|
12
|
+
}
|
|
13
|
+
export function anyOf(left, right) {
|
|
14
|
+
if (left === true || right === true) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (left === false) {
|
|
18
|
+
return right;
|
|
19
|
+
}
|
|
20
|
+
if (right === false) {
|
|
21
|
+
return left;
|
|
22
|
+
}
|
|
23
|
+
return { OR: [left, right] };
|
|
24
|
+
}
|
|
25
|
+
export function everyOf(conditions) {
|
|
26
|
+
return conditions.reduce(allOf, true);
|
|
27
|
+
}
|
|
28
|
+
export function someOf(conditions) {
|
|
29
|
+
return conditions.reduce(anyOf, false);
|
|
30
|
+
}
|
|
31
|
+
export function noneOf(condition) {
|
|
32
|
+
return typeof condition === "boolean" ? !condition : { NOT: condition };
|
|
33
|
+
}
|
|
34
|
+
export function whereOf(condition) {
|
|
35
|
+
return condition === true ? {} : condition;
|
|
36
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { AvRequestOrigin } from "../config/config-layer.js";
|
|
2
|
+
/** An answer now or later: every question may be answered asynchronously. */
|
|
3
|
+
type PolicyAnswer<T> = T | Promise<T>;
|
|
4
|
+
/**
|
|
5
|
+
* A fragment of Aventara's own `where` grammar, as a policy states a row
|
|
6
|
+
* condition: a scope, a field's per-row grant, or the question an engine's rule
|
|
7
|
+
* asks through `exists`. It is validated against the Core Contract when it is
|
|
8
|
+
* used, never the caller's, so it may name a field the caller cannot see
|
|
9
|
+
* (`ownerId`). A typed literal may be stated in its application form (`Date`,
|
|
10
|
+
* `AvDecimal`, `bigint`, `Uint8Array`) or in its wire form (an ISO-8601 UTC
|
|
11
|
+
* string, a decimal string, a base-10 digit string, base64), as a policy read
|
|
12
|
+
* from JSON states it; either reaches the adapter as the runtime value. One
|
|
13
|
+
* that does not validate is the server's defect: the request answers `A3000`.
|
|
14
|
+
*/
|
|
15
|
+
export type AvPolicyWhere = {
|
|
16
|
+
readonly [key: string]: unknown;
|
|
17
|
+
};
|
|
18
|
+
/** What every question to the engine states. */
|
|
19
|
+
type PolicyQuestion = {
|
|
20
|
+
/** What the configuration's `policy.principal` derived for the request, or the `as` of an application call. */
|
|
21
|
+
readonly principal: unknown;
|
|
22
|
+
/** Which layer the request runs under. */
|
|
23
|
+
readonly origin: AvRequestOrigin;
|
|
24
|
+
/** The Resource the question is about. */
|
|
25
|
+
readonly resource: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* The policy engine a Framework consults (root configuration `policy.engine`).
|
|
29
|
+
* Core asks it three questions per request and Resource, and enforces the
|
|
30
|
+
* answers: the operation (`can`), the rows (`scopeOf`) and the fields
|
|
31
|
+
* (`fieldsOf`). Every method may answer with a promise.
|
|
32
|
+
*
|
|
33
|
+
* `Governed` is the engine's `governed` set, stated by its type so the
|
|
34
|
+
* application's types leave those fields out of every default projection, as
|
|
35
|
+
* the Contracts do.
|
|
36
|
+
*/
|
|
37
|
+
export interface AvPolicyEngine<Governed extends {
|
|
38
|
+
readonly [resource: string]: readonly string[];
|
|
39
|
+
} = {
|
|
40
|
+
readonly [resource: string]: readonly string[];
|
|
41
|
+
}> {
|
|
42
|
+
/**
|
|
43
|
+
* The fields and relations the policy governs, by Resource. Each is left out
|
|
44
|
+
* of every default projection, for every caller, and is the only trace the
|
|
45
|
+
* policy leaves in a Contract (a `governed: true` mark). A caller that wants
|
|
46
|
+
* one names it, and is refused (`A4002`) unless it may read it on every row
|
|
47
|
+
* it uses it on. Checked against the Core Contract at startup.
|
|
48
|
+
*/
|
|
49
|
+
readonly governed?: Governed;
|
|
50
|
+
/**
|
|
51
|
+
* The relation paths and filter operators the engine's rules filter on, by
|
|
52
|
+
* the rule's name, each path a list of segments:
|
|
53
|
+
* `["Note", "campaign", "memberships", "some", "userId", "equals"]`, a
|
|
54
|
+
* Resource, then its fields and relations (a to-many relation followed by
|
|
55
|
+
* `some`, `every` or `none`), then the scalar field, then optionally the
|
|
56
|
+
* filter operator. Checked against the Core Contract at startup: a path it
|
|
57
|
+
* cannot filter fails construction, naming the rule.
|
|
58
|
+
*/
|
|
59
|
+
readonly paths?: {
|
|
60
|
+
readonly [rule: string]: readonly (readonly string[])[];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The writes whose grants carry an `after` condition, by Resource: a row
|
|
64
|
+
* they change must still meet it once changed (`{ Note: ["update"] }`).
|
|
65
|
+
* Inside a transaction core asks `can` about each row every checked update
|
|
66
|
+
* changed, listed or not, and rolls the write back (`A4002`) when one fails.
|
|
67
|
+
* This list decides where the operation has no interactive transaction:
|
|
68
|
+
* these updates are refused there (`A4002`), and every other one runs
|
|
69
|
+
* without the after check. It also decides which after checks carry
|
|
70
|
+
* `before`, the row as it was before the update (see `can`), and which rows
|
|
71
|
+
* `grantsOf` is asked about: only these.
|
|
72
|
+
* Checked against the Core Contract at startup.
|
|
73
|
+
*/
|
|
74
|
+
readonly afterChecks?: {
|
|
75
|
+
readonly [resource: string]: readonly "update"[];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The Resources the engine's rules read in conditions and decide no read of. A
|
|
79
|
+
* written reference to a row of one is not held to the caller's read scope, nor is
|
|
80
|
+
* a relation directive that links one where the writing row holds the reference
|
|
81
|
+
* and names the row by the reference's own values (one that names it by another
|
|
82
|
+
* unique key still is, or the link would tell the caller its identifier): the
|
|
83
|
+
* write's own grant decides which row may be linked (its `can`, and the after
|
|
84
|
+
* check `afterChecks` lists). Every read of them is still decided by `scopeOf`,
|
|
85
|
+
* and a link that changes a row of one is still held to its update scope. Read
|
|
86
|
+
* once, when the Framework is built: a name the data source's model does not have
|
|
87
|
+
* fails construction. An engine that does decide reads of a Resource it lists lets
|
|
88
|
+
* a write link a row of it the caller cannot read.
|
|
89
|
+
*/
|
|
90
|
+
readonly unheld?: readonly string[];
|
|
91
|
+
/**
|
|
92
|
+
* Whether the principal may run `action` on `resource`. Asked once per
|
|
93
|
+
* request before any developer stage, without a row: `false` refuses the
|
|
94
|
+
* request (`A4002`). Asked again with the row a write leaves: each row a
|
|
95
|
+
* create inserts (before the insert), and each row an update changed (after
|
|
96
|
+
* the write, inside its transaction; see `afterChecks`), one `afterChecks`
|
|
97
|
+
* lists with `before`, the same row as it was before the update; `false`
|
|
98
|
+
* refuses the write. An engine that requires one grant to cover a row both
|
|
99
|
+
* before and after its update lists the update and reads both, so no update
|
|
100
|
+
* moves a row from the rows one grant reaches to another's; one whose
|
|
101
|
+
* grants read relations through `exists` also answers {@link grantsOf}, so
|
|
102
|
+
* `before` is decided before the write. Rules that need a fact the row does not
|
|
103
|
+
* carry ask it through `exists`, which core runs through the adapter,
|
|
104
|
+
* unscoped, inside the write's transaction when it has one, and answers
|
|
105
|
+
* with a boolean only.
|
|
106
|
+
*/
|
|
107
|
+
can(question: PolicyQuestion & {
|
|
108
|
+
readonly action: "read" | "create" | "update" | "delete";
|
|
109
|
+
readonly row?: Readonly<Record<string, unknown>>;
|
|
110
|
+
/**
|
|
111
|
+
* On the after check of an update `afterChecks` lists only: the
|
|
112
|
+
* changed row as it was before the update, read by core inside the
|
|
113
|
+
* update's transaction, with the fields `row` carries (its identifier
|
|
114
|
+
* and every scalar field). A root update and a to-many nested `$update`
|
|
115
|
+
* are held to that row as read (its values of the fields offering
|
|
116
|
+
* `equals` ANDed into the write's selector), so a concurrent change
|
|
117
|
+
* makes the write miss instead of passing a check on a stale `before`;
|
|
118
|
+
* an upsert's update branch, a to-one nested `$update` and a linked
|
|
119
|
+
* row's update have no selector to hold, and a field the adapter
|
|
120
|
+
* offers no `equals` for is not compared. An update of several rows that cannot pair a changed
|
|
121
|
+
* row with its `before` is refused. Absent on every other question, an
|
|
122
|
+
* unlisted update's after check included.
|
|
123
|
+
*/
|
|
124
|
+
readonly before?: Readonly<Record<string, unknown>>;
|
|
125
|
+
/**
|
|
126
|
+
* With `before`, when the engine answers {@link grantsOf}: its answer
|
|
127
|
+
* about `before`, asked before the write and handed back unchanged, so
|
|
128
|
+
* an engine can require the grant that covers `row` to be one of these
|
|
129
|
+
* rather than decide `before`'s relation conditions after the write.
|
|
130
|
+
* Absent wherever `before` is absent, and when the engine has no `grantsOf`.
|
|
131
|
+
* An engine that answers `grantsOf` and finds `before` here without
|
|
132
|
+
* `beforeGrants` must refuse (`false`), never fall back to deciding
|
|
133
|
+
* `before` after the write: core states it on every such question, so
|
|
134
|
+
* its absence is a path core did not ask on, and the fallback is the
|
|
135
|
+
* gap `grantsOf` closes.
|
|
136
|
+
*/
|
|
137
|
+
readonly beforeGrants?: readonly string[];
|
|
138
|
+
readonly exists: (resource: string, where: AvPolicyWhere) => Promise<boolean>;
|
|
139
|
+
}): PolicyAnswer<boolean>;
|
|
140
|
+
/**
|
|
141
|
+
* The grants that cover `row`, the row an update `afterChecks` lists will change,
|
|
142
|
+
* as it is before the write: asked once per such row, inside the update's
|
|
143
|
+
* transaction, after core read the row and before any interceptor, hook or the
|
|
144
|
+
* write itself runs, so `exists` sees no row the request writes. It takes no lock:
|
|
145
|
+
* a related row another transaction changes between `exists` and the write is not
|
|
146
|
+
* held. Each entry is the engine's own key for a grant; core never reads them, and
|
|
147
|
+
* hands the list back as `beforeGrants` on the after check of the same row. Never
|
|
148
|
+
* asked about an update `afterChecks` does not list, so an engine whose
|
|
149
|
+
* `afterChecks` lists none is never asked it, and that is no startup error: an
|
|
150
|
+
* engine may carry it whatever its rules list. An answer that is not a list of
|
|
151
|
+
* strings is the server's defect (`A3000`).
|
|
152
|
+
*/
|
|
153
|
+
grantsOf?(question: PolicyQuestion & {
|
|
154
|
+
readonly action: "update";
|
|
155
|
+
readonly row: Readonly<Record<string, unknown>>;
|
|
156
|
+
readonly exists: (resource: string, where: AvPolicyWhere) => Promise<boolean>;
|
|
157
|
+
}): PolicyAnswer<readonly string[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Told once, when a Framework is built on this engine and its startup
|
|
160
|
+
* checks have passed: `held` lists the Resources a written reference is held
|
|
161
|
+
* to the read scope of, every Resource the Core Contract shows but those
|
|
162
|
+
* {@link unheld} lists. A write that
|
|
163
|
+
* sends a reference to a row of one of them is refused (`A4002`) unless the
|
|
164
|
+
* caller may read that row; a reference to any other Resource is not asked
|
|
165
|
+
* about. An engine may check its rules against it here, as a warning; what
|
|
166
|
+
* it answers is unchanged. The list is frozen. It may answer with a
|
|
167
|
+
* promise, which construction awaits; a throw or a rejection fails the
|
|
168
|
+
* Framework's construction.
|
|
169
|
+
*/
|
|
170
|
+
hosted?(host: {
|
|
171
|
+
readonly held: readonly string[];
|
|
172
|
+
}): PolicyAnswer<void>;
|
|
173
|
+
/**
|
|
174
|
+
* The rows the principal may `action`: `true` every row, `false` none, or a
|
|
175
|
+
* condition core ANDs into the request at every level that reads the
|
|
176
|
+
* Resource (its `where`, an included relation's, a relation filter, a
|
|
177
|
+
* relation count).
|
|
178
|
+
*/
|
|
179
|
+
scopeOf(question: PolicyQuestion & {
|
|
180
|
+
readonly action: "read" | "update" | "delete";
|
|
181
|
+
}): PolicyAnswer<boolean | AvPolicyWhere>;
|
|
182
|
+
/**
|
|
183
|
+
* The fields the principal may read or write. `always` lists the fields it
|
|
184
|
+
* may use on every row it can reach (`"all"`: every field that is not
|
|
185
|
+
* governed); `perRow` maps a field it may use only on some rows to the
|
|
186
|
+
* condition those rows meet. A field in neither is refused (`A4002`)
|
|
187
|
+
* wherever the request names it. A write question names the `action` the
|
|
188
|
+
* fields are written by, `"create"` or `"update"` (an upsert's branches
|
|
189
|
+
* each by their own), so a field may be locked on update and still written
|
|
190
|
+
* at create.
|
|
191
|
+
*/
|
|
192
|
+
fieldsOf(question: PolicyQuestion & ({
|
|
193
|
+
readonly access: "read";
|
|
194
|
+
readonly action?: undefined;
|
|
195
|
+
} | {
|
|
196
|
+
readonly access: "write";
|
|
197
|
+
readonly action: "create" | "update";
|
|
198
|
+
})): PolicyAnswer<{
|
|
199
|
+
readonly always: "all" | readonly string[];
|
|
200
|
+
readonly perRow: {
|
|
201
|
+
readonly [field: string]: AvPolicyWhere | undefined;
|
|
202
|
+
};
|
|
203
|
+
}>;
|
|
204
|
+
}
|
|
205
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PolicyCondition } from "./policy-condition.js";
|
|
2
|
+
import type { AvPolicyWhere } from "./policy-engine.js";
|
|
3
|
+
import type { PolicySession } from "./policy-session.js";
|
|
4
|
+
/** The rows a write names, each with the scopes it must be within. */
|
|
5
|
+
export declare class NamedRows {
|
|
6
|
+
private readonly named;
|
|
7
|
+
/** Selectors with no stable key: asked the old way, outside any scope. */
|
|
8
|
+
private readonly unkeyed;
|
|
9
|
+
get size(): number;
|
|
10
|
+
/** Notes `selector` (one row by an identifier) held to `scope`; `true` holds nothing. */
|
|
11
|
+
add(selector: AvPolicyWhere, scope: PolicyCondition): void;
|
|
12
|
+
/**
|
|
13
|
+
* Whether every named row of `resource` is there and within its scopes: one
|
|
14
|
+
* count (an `exists` instead where the Resource offers neither a count nor a
|
|
15
|
+
* list, and one more for a selector with no stable key).
|
|
16
|
+
*/
|
|
17
|
+
within(session: PolicySession, resource: string): Promise<boolean>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { allOf, everyOf, noneOf, someOf, whereOf, } from "./policy-condition.js";
|
|
2
|
+
function selectorKey(selector) {
|
|
3
|
+
try {
|
|
4
|
+
return JSON.stringify(Object.entries(selector).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0), (_key, value) => typeof value === "bigint" ? `#bigint(${value})` : value);
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class NamedRows {
|
|
11
|
+
named = new Map();
|
|
12
|
+
unkeyed = [];
|
|
13
|
+
get size() {
|
|
14
|
+
return this.named.size + this.unkeyed.length;
|
|
15
|
+
}
|
|
16
|
+
add(selector, scope) {
|
|
17
|
+
if (scope === true) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const key = selectorKey(selector);
|
|
21
|
+
if (key === undefined) {
|
|
22
|
+
this.unkeyed.push(allOf(selector, noneOf(scope)));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const entry = this.named.get(key);
|
|
26
|
+
if (entry === undefined) {
|
|
27
|
+
this.named.set(key, { selector, scopes: [scope] });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
entry.scopes.push(scope);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async within(session, resource) {
|
|
34
|
+
const entries = [...this.named.values()];
|
|
35
|
+
const inside = someOf(entries.map(({ selector, scopes }) => allOf(selector, everyOf(scopes))));
|
|
36
|
+
let outside = someOf(this.unkeyed);
|
|
37
|
+
if (entries.length > 0) {
|
|
38
|
+
const counted = inside === false ? 0 : await session.count(resource, whereOf(inside));
|
|
39
|
+
if (counted === undefined) {
|
|
40
|
+
outside = someOf([
|
|
41
|
+
outside,
|
|
42
|
+
...entries.map(({ selector, scopes }) => allOf(selector, noneOf(everyOf(scopes)))),
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
else if (counted < entries.length) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return (outside === false || !(await session.exists(resource, whereOf(outside))));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
2
|
+
import type { AvContractCore } from "../contracts/contract.js";
|
|
3
|
+
import type { AvOperationFailureResponse } from "../runtime/operation-response.js";
|
|
4
|
+
import { type PolicyCondition } from "./policy-condition.js";
|
|
5
|
+
import { type PolicySession } from "./policy-session.js";
|
|
6
|
+
type Row = Readonly<Record<string, unknown>>;
|
|
7
|
+
/** The rows a level's records write: new rows, or rows a condition reaches before the write. */
|
|
8
|
+
export type NestedParent = {
|
|
9
|
+
readonly kind: "new";
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: "existing";
|
|
12
|
+
readonly reach: PolicyCondition;
|
|
13
|
+
};
|
|
14
|
+
/** The checks after the write: told the root rows it wrote, the refusal or `undefined`. */
|
|
15
|
+
export type NestedWriteCheck = (rows: readonly Row[]) => Promise<AvOperationFailureResponse | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* What a nested write needs: a refusal before it runs, or the root record the
|
|
18
|
+
* adapter runs (its to-many `$update` and `$delete` narrowed to the rows within
|
|
19
|
+
* their scopes) and the check after it.
|
|
20
|
+
*/
|
|
21
|
+
export type NestedWritePlan = {
|
|
22
|
+
readonly kind: "refused";
|
|
23
|
+
readonly response: AvOperationFailureResponse;
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: "planned";
|
|
26
|
+
readonly record: Row;
|
|
27
|
+
readonly after: NestedWriteCheck;
|
|
28
|
+
/**
|
|
29
|
+
* Asked when the adapter call failed: the refusal when a row a to-one `$update`
|
|
30
|
+
* was held to no longer holds the values it was read with, otherwise `undefined`
|
|
31
|
+
* and the failure stands.
|
|
32
|
+
*/
|
|
33
|
+
readonly failed: () => Promise<AvOperationFailureResponse | undefined>;
|
|
34
|
+
};
|
|
35
|
+
/** Whether `record` of `resource` writes a relation through a directive. */
|
|
36
|
+
export declare function writesNested(core: AvContractCore, resource: string, record: unknown): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The policy of the nested writes in one root record (see the module comment):
|
|
39
|
+
* the refusal before the call, or the checks after it. `created` says the root
|
|
40
|
+
* rows are created by this write, so they too are read as stored and asked
|
|
41
|
+
* `can({ action: "create", row })` after the call.
|
|
42
|
+
*/
|
|
43
|
+
export declare function planNestedWrites(session: PolicySession, core: AvContractCore, model: AvAdapterModel, resource: string, record: Row, parent: NestedParent): Promise<NestedWritePlan>;
|
|
44
|
+
export {};
|