@aventara/core 1.0.0-rc.1 → 1.0.0-rc.11
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 +1022 -16
- package/ERRORS.md +142 -0
- package/README.md +330 -16
- 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 +22 -0
- package/dist/adapters/adapter-identifier.d.ts +9 -0
- package/dist/adapters/adapter-identifier.js +6 -1
- package/dist/adapters/adapter-model.d.ts +9 -0
- package/dist/adapters/adapter-operation.d.ts +18 -3
- package/dist/adapters/adapter-resource.d.ts +5 -0
- package/dist/adapters/adapter.interface.d.ts +10 -0
- package/dist/avz/avz.d.ts +1 -1
- package/dist/avz/json-shape.registry.d.ts +2 -1
- 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 +6 -0
- package/dist/compiler/contract.compiler.js +281 -31
- package/dist/compiler/create-requirements.projector.js +1 -3
- package/dist/compiler/field-validator.compiler.js +1 -3
- 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/cache-stage.factory.d.ts +24 -0
- package/dist/config/cache-stage.factory.js +3 -0
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +73 -0
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config.resolver.d.ts +24 -0
- package/dist/config/config.resolver.js +66 -7
- package/dist/config/config.validator.js +283 -21
- package/dist/config/define-resource.d.ts +1 -5
- package/dist/config/entrypoint.normalizer.d.ts +3 -2
- package/dist/config/exact-framework-config.d.ts +73 -22
- package/dist/config/field-compute.resolver.d.ts +2 -0
- package/dist/config/field-compute.resolver.js +9 -3
- package/dist/config/framework-config.d.ts +53 -15
- package/dist/config/framework-resources-config.d.ts +25 -14
- package/dist/config/pipeline-config.d.ts +20 -4
- package/dist/config/pipeline-tree.resolver.d.ts +2 -2
- package/dist/config/pipeline-tree.resolver.js +2 -3
- package/dist/contracts/access-route.rules.d.ts +10 -0
- package/dist/contracts/access-route.rules.js +45 -0
- package/dist/contracts/canonical-json.writer.d.ts +7 -0
- package/dist/contracts/canonical-json.writer.js +55 -0
- package/dist/contracts/capability.d.ts +26 -1
- package/dist/contracts/capability.js +20 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +365 -89
- package/dist/contracts/client-contract-structure.validator.js +49 -2
- package/dist/contracts/contract-access.d.ts +29 -0
- package/dist/contracts/contract-access.js +1 -0
- package/dist/contracts/contract-canonicalizer.d.ts +9 -1
- package/dist/contracts/contract-canonicalizer.js +35 -4
- package/dist/contracts/contract-hash.d.ts +0 -1
- package/dist/contracts/contract-hash.js +1 -1
- package/dist/contracts/contract-limits.d.ts +6 -0
- package/dist/contracts/contract-limits.js +2 -0
- package/dist/contracts/contract.d.ts +42 -1
- package/dist/contracts/field.d.ts +58 -1
- package/dist/contracts/json-schema.projector.d.ts +11 -0
- package/dist/contracts/json-schema.projector.js +76 -0
- package/dist/contracts/scalar-value-type.d.ts +3 -1
- package/dist/framework/access-facade.d.ts +116 -0
- package/dist/framework/access-facade.js +118 -0
- package/dist/framework/contract-view.d.ts +120 -16
- package/dist/framework/framework-construction.error.d.ts +14 -4
- package/dist/framework/framework-construction.error.js +18 -2
- package/dist/framework/framework.d.ts +26 -5
- package/dist/framework/framework.factory.d.ts +1 -1
- package/dist/framework/framework.factory.js +145 -24
- package/dist/framework/operation-facade.d.ts +141 -13
- package/dist/framework/operation-facade.js +9 -1
- package/dist/framework/operation-set.runner.d.ts +47 -0
- package/dist/framework/operation-set.runner.js +168 -0
- package/dist/index.d.ts +19 -5
- package/dist/index.js +3 -0
- package/dist/internal.d.ts +9 -2
- package/dist/internal.js +8 -0
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +148 -60
- package/dist/operations/operation-call.d.ts +9 -5
- package/dist/operations/operation-result.d.ts +6 -4
- package/dist/operations/operation-validator-core.js +160 -39
- package/dist/operations/operation-validator.d.ts +1 -1
- package/dist/operations/structural-limits.walker.d.ts +1 -1
- package/dist/operations/structural-limits.walker.js +1 -3
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/write-scope.resolver.d.ts +4 -0
- 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 +295 -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 +407 -0
- package/dist/policy/policy-after-update.runtime.d.ts +79 -0
- package/dist/policy/policy-after-update.runtime.js +206 -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 +536 -0
- package/dist/policy/policy-read.runtime.d.ts +81 -0
- package/dist/policy/policy-read.runtime.js +501 -0
- package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
- package/dist/policy/policy-reference-write.runtime.js +336 -0
- package/dist/policy/policy-request.d.ts +72 -0
- package/dist/policy/policy-request.js +115 -0
- package/dist/policy/policy-session.d.ts +106 -0
- package/dist/policy/policy-session.js +293 -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 +530 -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 +63 -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 +75 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
- package/dist/prebuilt/prebuilt-inputs.fingerprint.js +227 -0
- package/dist/protocol/absent-route.responder.d.ts +49 -14
- package/dist/protocol/absent-route.responder.js +92 -15
- package/dist/protocol/contract-document.responder.d.ts +9 -1
- package/dist/protocol/contract-document.responder.js +3 -2
- package/dist/protocol/http-request.decoder.d.ts +52 -3
- package/dist/protocol/http-request.decoder.js +45 -6
- package/dist/protocol/http-request.reader.d.ts +10 -3
- package/dist/protocol/http-request.reader.js +12 -2
- package/dist/protocol/http-response.encoder.d.ts +12 -0
- package/dist/protocol/http-response.encoder.js +17 -3
- package/dist/protocol/operation-response.guard.js +1 -3
- package/dist/protocol/operation-set.decoder.d.ts +48 -0
- package/dist/protocol/operation-set.decoder.js +185 -0
- package/dist/protocol/operation-set.handler.d.ts +27 -0
- package/dist/protocol/operation-set.handler.js +179 -0
- package/dist/protocol/protocol-headers.d.ts +12 -3
- package/dist/protocol/protocol-headers.js +12 -5
- package/dist/protocol/protocol-surface.d.ts +16 -3
- package/dist/protocol/protocol-surface.js +41 -1
- package/dist/protocol/protocol.binder.d.ts +52 -1
- package/dist/protocol/protocol.binder.js +6 -1
- package/dist/protocol/protocol.handler.d.ts +45 -1
- package/dist/protocol/protocol.handler.js +164 -19
- package/dist/protocol/read-cache.responder.d.ts +26 -0
- package/dist/protocol/read-cache.responder.js +47 -0
- package/dist/protocol/read-query.codec.d.ts +34 -0
- package/dist/protocol/read-query.codec.js +125 -0
- package/dist/runtime/caller-data.copier.d.ts +18 -3
- package/dist/runtime/caller-data.copier.js +21 -8
- package/dist/runtime/caller-data.door.d.ts +13 -6
- package/dist/runtime/computed-read-runtime.d.ts +6 -1
- package/dist/runtime/computed-read-runtime.js +229 -48
- package/dist/runtime/computed-value.error.d.ts +3 -2
- package/dist/runtime/computed-value.error.js +3 -2
- package/dist/runtime/context-executor.runtime.d.ts +4 -3
- package/dist/runtime/context-executor.runtime.js +4 -2
- 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 +31 -5
- package/dist/runtime/create-requirement.js +130 -24
- package/dist/runtime/decimal.d.ts +14 -0
- package/dist/runtime/decimal.js +21 -0
- package/dist/runtime/diagnostics-reporter.d.ts +49 -9
- package/dist/runtime/diagnostics-reporter.js +16 -9
- package/dist/runtime/error-boundary.d.ts +9 -2
- package/dist/runtime/error-boundary.js +12 -0
- 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 +8 -0
- package/dist/runtime/field-check.evaluator.d.ts +0 -2
- package/dist/runtime/field-check.evaluator.js +1 -1
- package/dist/runtime/field-compute.d.ts +11 -10
- package/dist/runtime/field-stage.runtime.d.ts +3 -3
- package/dist/runtime/field-stage.runtime.js +9 -11
- package/dist/runtime/field-validator.runtime.d.ts +19 -1
- package/dist/runtime/field-validator.runtime.js +49 -9
- package/dist/runtime/framework-error.js +9 -0
- package/dist/runtime/framework-warning.emitter.d.ts +6 -0
- package/dist/runtime/framework-warning.emitter.js +8 -0
- package/dist/runtime/json-value.d.ts +10 -5
- package/dist/runtime/level-lifecycle.runtime.d.ts +4 -3
- package/dist/runtime/level-lifecycle.runtime.js +3 -5
- package/dist/runtime/mutation-planner.d.ts +1 -6
- package/dist/runtime/mutation-planner.js +4 -17
- package/dist/runtime/nested-write.walker.js +2 -1
- 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 +16 -9
- package/dist/runtime/operation-runtime.d.ts +35 -17
- package/dist/runtime/operation-runtime.js +220 -49
- package/dist/runtime/outcome-mapper.d.ts +2 -1
- package/dist/runtime/output-validator.d.ts +1 -1
- package/dist/runtime/output-validator.js +1 -3
- package/dist/runtime/owned-execution.registry.d.ts +34 -4
- package/dist/runtime/pipe-output.validator.d.ts +10 -0
- package/dist/runtime/pipe-output.validator.js +4 -2
- package/dist/runtime/pipeline.d.ts +52 -23
- package/dist/runtime/readonly-value.d.ts +20 -5
- package/dist/runtime/readonly-value.js +74 -26
- package/dist/runtime/record.guard.d.ts +14 -0
- package/dist/runtime/record.guard.js +10 -0
- package/dist/runtime/referential-action.d.ts +1 -1
- package/dist/runtime/request-envelope.validator.js +13 -10
- package/dist/runtime/scalar-runtime.d.ts +4 -21
- package/dist/runtime/scalar-runtime.js +91 -31
- package/dist/runtime/thenable.guard.d.ts +7 -0
- package/dist/runtime/thenable.guard.js +5 -0
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +129 -0
- package/dist/transactions/operation-arguments-encoder.js +9 -10
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +10 -2
- package/dist/transactions/sql-statement.validator.d.ts +2 -2
- package/dist/transactions/sql-statement.validator.js +40 -6
- package/dist/transactions/transaction-envelope.d.ts +5 -4
- package/dist/transactions/transaction-integrity-error.js +2 -0
- package/dist/transactions/transaction-plan-assembler.d.ts +12 -5
- package/dist/transactions/transaction-plan-assembler.js +49 -17
- package/dist/transactions/transaction-plan-validator.d.ts +23 -7
- package/dist/transactions/transaction-plan-validator.js +31 -7
- package/dist/transactions/transaction-reference-collector.js +8 -10
- package/dist/transactions/transaction-reference-resolver.d.ts +3 -2
- package/dist/transactions/transaction-reference-resolver.js +1 -3
- package/dist/transactions/transaction-reference-validator.d.ts +43 -3
- package/dist/transactions/transaction-reference-validator.js +83 -57
- package/dist/transactions/transaction-reference.d.ts +1 -1
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +8 -8
- package/dist/transactions/transaction-runtime.d.ts +5 -2
- package/dist/transactions/transaction-runtime.js +108 -27
- package/dist/transactions/transaction-settlement.runtime.d.ts +4 -3
- package/dist/transactions/transaction-slot-path-error.js +2 -0
- package/dist/transactions/transaction-stage.runtime.d.ts +5 -3
- package/dist/transactions/transaction-stage.runtime.js +8 -7
- package/package.json +6 -5
- package/src/runtime/field-check.evaluator.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { bindShapedField, jsonShapeOf } from "../avz/json-shape.registry.js";
|
|
2
|
-
import { PROJECTION_SCOPES, WRITE_SCOPES } from "../contracts/capability.js";
|
|
2
|
+
import { FILTER_MODES, PROJECTION_SCOPES, WRITE_SCOPES, } from "../contracts/capability.js";
|
|
3
3
|
import { validateClientContractStructure } from "../contracts/client-contract-structure.validator.js";
|
|
4
4
|
import { canonicalizeContract, canonicalizeContractMembers, canonicalizeJson, joinCanonicalContractMembers, recordCanonicalContractText, } from "../contracts/contract-canonicalizer.js";
|
|
5
5
|
import { hashCanonicalContractText, } from "../contracts/contract-hash.js";
|
|
@@ -7,8 +7,10 @@ import { DEFAULT_CONTRACT_LIMITS, } from "../contracts/contract-limits.js";
|
|
|
7
7
|
import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
|
|
8
8
|
import { advertisedDirectives, advertisedReducers, holdsInAnyScope, } from "../contracts/field.js";
|
|
9
9
|
import { isOperationVariantAvailable, } from "../contracts/resource-operations.js";
|
|
10
|
+
import { isRecord } from "../runtime/record.guard.js";
|
|
10
11
|
import { checkCreateRequirements, checkHiddenRequirements, projectCreateRequirements, } from "./create-requirements.projector.js";
|
|
11
12
|
import { applyValidators, bindFieldValidators, checkLayerValidators, compileValidatorTable, } from "./field-validator.compiler.js";
|
|
13
|
+
import { explainManagedRefusals, hideManagedElsewhere, managedElsewhereOf, managedWriteReason, markCoreResources, pruneManagedEnums, withholdManagedWrites, } from "./managed-elsewhere.projector.js";
|
|
12
14
|
const UNIQUE_VARIANTS = [
|
|
13
15
|
["find", "unique"],
|
|
14
16
|
["update", "unique"],
|
|
@@ -23,9 +25,6 @@ const COMPUTED_TRAITS = new Set([
|
|
|
23
25
|
function diagnostic(code, path, message) {
|
|
24
26
|
return { code, path, message };
|
|
25
27
|
}
|
|
26
|
-
function isRecord(value) {
|
|
27
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
28
|
-
}
|
|
29
28
|
function cloneValue(value) {
|
|
30
29
|
if (Array.isArray(value)) {
|
|
31
30
|
return value.map((entry) => cloneValue(entry));
|
|
@@ -41,6 +40,12 @@ function normalizeAdapterScalarCapabilities(capabilities) {
|
|
|
41
40
|
...(capabilities.filter !== undefined
|
|
42
41
|
? { filter: [...capabilities.filter] }
|
|
43
42
|
: {}),
|
|
43
|
+
...(capabilities.filterModes !== undefined
|
|
44
|
+
? { filterModes: [...capabilities.filterModes] }
|
|
45
|
+
: {}),
|
|
46
|
+
...(capabilities.pathFilterModes !== undefined
|
|
47
|
+
? { pathFilterModes: [...capabilities.pathFilterModes] }
|
|
48
|
+
: {}),
|
|
44
49
|
...(capabilities.order !== undefined ? { order: capabilities.order } : {}),
|
|
45
50
|
...(capabilities.orderNulls !== undefined
|
|
46
51
|
? { orderNulls: capabilities.orderNulls }
|
|
@@ -71,8 +76,65 @@ function cloneAdapterField(field) {
|
|
|
71
76
|
cardinality: field.cardinality,
|
|
72
77
|
nullable: field.nullable,
|
|
73
78
|
capabilities: cloneValue(field.capabilities),
|
|
79
|
+
...(typeof field.inverse === "string" ? { inverse: field.inverse } : {}),
|
|
80
|
+
...(Array.isArray(field.referenceFields) && field.referenceFields.length > 0
|
|
81
|
+
? { referenceFields: [...field.referenceFields] }
|
|
82
|
+
: {}),
|
|
83
|
+
...(Array.isArray(field.referenceFields) &&
|
|
84
|
+
Array.isArray(field.references) &&
|
|
85
|
+
field.references.length > 0 &&
|
|
86
|
+
field.references.length === field.referenceFields.length
|
|
87
|
+
? { references: [...field.references] }
|
|
88
|
+
: {}),
|
|
74
89
|
};
|
|
75
90
|
}
|
|
91
|
+
function pruneHiddenPairings(projection, references) {
|
|
92
|
+
const resources = projection.resources;
|
|
93
|
+
for (const [name, resource] of Object.entries(resources)) {
|
|
94
|
+
for (const field of Object.values(resource.fields)) {
|
|
95
|
+
if (field.kind !== "relation") {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(field.references) &&
|
|
99
|
+
(references === "none" ||
|
|
100
|
+
!wholePairing(resource.fields, Object.hasOwn(resources, String(field.target))
|
|
101
|
+
? resources[String(field.target)]?.fields
|
|
102
|
+
: undefined, field.referenceFields, field.references))) {
|
|
103
|
+
delete field.references;
|
|
104
|
+
}
|
|
105
|
+
if (Array.isArray(field.referenceFields)) {
|
|
106
|
+
const shown = field.referenceFields.filter((reference) => typeof reference === "string" &&
|
|
107
|
+
Object.hasOwn(resource.fields, reference) &&
|
|
108
|
+
resource.fields[reference]?.kind === "scalar");
|
|
109
|
+
if (shown.length > 0) {
|
|
110
|
+
field.referenceFields = shown;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
delete field.referenceFields;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (typeof field.inverse !== "string") {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const other = Object.hasOwn(resources, String(field.target))
|
|
120
|
+
? resources[String(field.target)]?.fields[field.inverse]
|
|
121
|
+
: undefined;
|
|
122
|
+
if (other?.kind !== "relation" || other.target !== name) {
|
|
123
|
+
delete field.inverse;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function wholePairing(fields, targetFields, referenceFields, references) {
|
|
129
|
+
const shownIn = (within, name) => typeof name === "string" &&
|
|
130
|
+
within !== undefined &&
|
|
131
|
+
Object.hasOwn(within, name) &&
|
|
132
|
+
within[name]?.kind === "scalar";
|
|
133
|
+
return (Array.isArray(referenceFields) &&
|
|
134
|
+
referenceFields.length === references.length &&
|
|
135
|
+
referenceFields.every((name) => shownIn(fields, name)) &&
|
|
136
|
+
references.every((name) => shownIn(targetFields, name)));
|
|
137
|
+
}
|
|
76
138
|
function cloneOperations(operations) {
|
|
77
139
|
return cloneValue(operations);
|
|
78
140
|
}
|
|
@@ -86,8 +148,40 @@ function cloneAdapterResource(resource) {
|
|
|
86
148
|
operations: cloneOperations(resource.operations),
|
|
87
149
|
};
|
|
88
150
|
}
|
|
151
|
+
function canonicalModes(modes) {
|
|
152
|
+
const stated = Array.isArray(modes) ? modes : [];
|
|
153
|
+
const known = FILTER_MODES.filter((mode) => mode === "default" || stated.includes(mode));
|
|
154
|
+
const unknown = stated.filter((mode) => !FILTER_MODES.includes(mode));
|
|
155
|
+
return [...known, ...unknown];
|
|
156
|
+
}
|
|
157
|
+
function qualifyFilterModes(projection) {
|
|
158
|
+
for (const resource of Object.values(projection.resources)) {
|
|
159
|
+
for (const field of Object.values(resource.fields)) {
|
|
160
|
+
if (field.kind !== "scalar") {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const capabilities = field.capabilities;
|
|
164
|
+
const filter = Array.isArray(capabilities.filter)
|
|
165
|
+
? capabilities.filter
|
|
166
|
+
: [];
|
|
167
|
+
if (!filter.includes("mode")) {
|
|
168
|
+
delete capabilities.filterModes;
|
|
169
|
+
delete capabilities.pathFilterModes;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const stated = capabilities.filterModes;
|
|
173
|
+
capabilities.filterModes = canonicalModes(stated);
|
|
174
|
+
if (filter.includes("path")) {
|
|
175
|
+
capabilities.pathFilterModes = canonicalModes(capabilities.pathFilterModes ?? stated);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
delete capabilities.pathFilterModes;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
89
183
|
function createBaseline(model) {
|
|
90
|
-
|
|
184
|
+
const baseline = {
|
|
91
185
|
scalars: Object.fromEntries(Object.entries(model.scalars).map(([key, value]) => [
|
|
92
186
|
key,
|
|
93
187
|
cloneValue(value),
|
|
@@ -106,6 +200,8 @@ function createBaseline(model) {
|
|
|
106
200
|
? {}
|
|
107
201
|
: { referenceWrites: model.referenceWrites }),
|
|
108
202
|
};
|
|
203
|
+
qualifyFilterModes(baseline);
|
|
204
|
+
return baseline;
|
|
109
205
|
}
|
|
110
206
|
function definitionPath(resource, field) {
|
|
111
207
|
return `root.resources.${resource}.fields.${field}.definition`;
|
|
@@ -285,7 +381,7 @@ function checkFieldCompute(model, resourceName, fieldName, field, compute, path,
|
|
|
285
381
|
}
|
|
286
382
|
}
|
|
287
383
|
}
|
|
288
|
-
function checkResourceTree(model, baseline, scope, tree, definitions, diagnostics) {
|
|
384
|
+
function checkResourceTree(model, baseline, scope, tree, definitions, managed, diagnostics) {
|
|
289
385
|
if (!isRecord(tree)) {
|
|
290
386
|
return;
|
|
291
387
|
}
|
|
@@ -296,12 +392,22 @@ function checkResourceTree(model, baseline, scope, tree, definitions, diagnostic
|
|
|
296
392
|
diagnostics.push(diagnostic("COMPILER_UNKNOWN_RESOURCE", resourcePath, `resource "${resourceName}" is not present in the canonical adapter model`));
|
|
297
393
|
continue;
|
|
298
394
|
}
|
|
395
|
+
if ((scope === "client" || scope === "agent") &&
|
|
396
|
+
managed.has(resourceName)) {
|
|
397
|
+
diagnostics.push(diagnostic("COMPILER_UNKNOWN_RESOURCE", resourcePath, `resource "${resourceName}" is managed elsewhere (resources.${resourceName}.managedElsewhere), so the ${scope} layer never has it: nothing configured for it here runs`));
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
299
400
|
if (!isRecord(entry)) {
|
|
300
401
|
continue;
|
|
301
402
|
}
|
|
302
403
|
if (isRecord(entry.operations)) {
|
|
303
404
|
for (const [family, level] of Object.entries(entry.operations)) {
|
|
304
405
|
const familyPath = `${resourcePath}.operations.${family}`;
|
|
406
|
+
const managedReason = managedWriteReason(managed, resourceName, family);
|
|
407
|
+
if (managedReason !== undefined) {
|
|
408
|
+
diagnostics.push(diagnostic("COMPILER_UNAVAILABLE_OPERATION", familyPath, managedReason));
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
305
411
|
const variants = resource.operations[family];
|
|
306
412
|
if (!isRecord(variants)) {
|
|
307
413
|
diagnostics.push(diagnostic("COMPILER_UNAVAILABLE_OPERATION", familyPath, `operation family "${family}" is not available for resource "${resourceName}"`));
|
|
@@ -330,7 +436,8 @@ function checkResourceTree(model, baseline, scope, tree, definitions, diagnostic
|
|
|
330
436
|
diagnostics.push(diagnostic("COMPILER_UNKNOWN_FIELD", `${resourcePath}.fields.${fieldName}`, `field "${fieldName}" is neither discovered by the adapter nor defined at the root`));
|
|
331
437
|
continue;
|
|
332
438
|
}
|
|
333
|
-
if (!isRecord(fieldEntry) ||
|
|
439
|
+
if (!isRecord(fieldEntry) ||
|
|
440
|
+
!isRecord(fieldEntry.pipelines)) {
|
|
334
441
|
continue;
|
|
335
442
|
}
|
|
336
443
|
const pipelinesPath = `${resourcePath}.fields.${fieldName}.pipelines`;
|
|
@@ -349,9 +456,14 @@ function checkReservedResourceNames(model, diagnostics) {
|
|
|
349
456
|
}
|
|
350
457
|
}
|
|
351
458
|
}
|
|
459
|
+
function isAdapterStated(axis) {
|
|
460
|
+
return axis?.kind === "limit" || axis?.kind === "adapterTokens";
|
|
461
|
+
}
|
|
352
462
|
const SCALAR_CAPABILITY_AXES = {
|
|
353
463
|
select: { kind: "flag" },
|
|
354
464
|
filter: { kind: "tokens" },
|
|
465
|
+
filterModes: { kind: "adapterTokens", values: FILTER_MODES },
|
|
466
|
+
pathFilterModes: { kind: "adapterTokens", values: FILTER_MODES },
|
|
355
467
|
order: { kind: "flag" },
|
|
356
468
|
orderNulls: { kind: "flag" },
|
|
357
469
|
create: { kind: "tokens" },
|
|
@@ -445,11 +557,11 @@ function fieldName(resource, field) {
|
|
|
445
557
|
}
|
|
446
558
|
function exemptableAxis(walk, universeField, capability, label, path) {
|
|
447
559
|
const axis = capabilityAxisFor(universeField.kind, capability);
|
|
448
|
-
if (axis === undefined || axis
|
|
560
|
+
if (axis === undefined || isAdapterStated(axis)) {
|
|
449
561
|
const names = Object.entries(universeField.kind === "scalar"
|
|
450
562
|
? SCALAR_CAPABILITY_AXES
|
|
451
563
|
: RELATION_CAPABILITY_AXES)
|
|
452
|
-
.filter(([, entry]) => entry
|
|
564
|
+
.filter(([, entry]) => !isAdapterStated(entry))
|
|
453
565
|
.map(([name]) => name);
|
|
454
566
|
unavailableCapability(path, `"${capability}" is not a capability a ${universeField.kind} field's exemption can name; it takes ${names.join(", ")}`, walk.diagnostics);
|
|
455
567
|
return undefined;
|
|
@@ -533,7 +645,7 @@ function exemptField(walk, universeField, parentField, entry, label, path) {
|
|
|
533
645
|
const result = walk.style === "omit" ? cloneValue(parentCapabilities) : {};
|
|
534
646
|
if (walk.style === "pick") {
|
|
535
647
|
for (const [key, value] of Object.entries(parentCapabilities)) {
|
|
536
|
-
if (capabilityAxisFor(universeField.kind, key)
|
|
648
|
+
if (isAdapterStated(capabilityAxisFor(universeField.kind, key))) {
|
|
537
649
|
result[key] = cloneValue(value);
|
|
538
650
|
}
|
|
539
651
|
}
|
|
@@ -552,7 +664,7 @@ function exemptField(walk, universeField, parentField, entry, label, path) {
|
|
|
552
664
|
return undefined;
|
|
553
665
|
}
|
|
554
666
|
if (walk.style === "pick" &&
|
|
555
|
-
!Object.keys(result).some((key) => capabilityAxisFor(universeField.kind, key)
|
|
667
|
+
!Object.keys(result).some((key) => !isAdapterStated(capabilityAxisFor(universeField.kind, key)))) {
|
|
556
668
|
return undefined;
|
|
557
669
|
}
|
|
558
670
|
return { ...cloneValue(parentField), capabilities: result };
|
|
@@ -651,7 +763,9 @@ function exemptOperations(walk, resourceName, universe, parent, entry, path) {
|
|
|
651
763
|
if (value === false || value === undefined) {
|
|
652
764
|
continue;
|
|
653
765
|
}
|
|
654
|
-
if (value !== true &&
|
|
766
|
+
if (value !== true &&
|
|
767
|
+
!Array.isArray(value) &&
|
|
768
|
+
!isRecord(value)) {
|
|
655
769
|
walk.diagnostics.push(diagnostic("COMPILER_UNAVAILABLE_OPERATION", familyPath, "an operation family takes true, false, a list of its variants or an object of them"));
|
|
656
770
|
continue;
|
|
657
771
|
}
|
|
@@ -698,7 +812,8 @@ function exemptResource(walk, resourceName, universe, parent, entry, path) {
|
|
|
698
812
|
}
|
|
699
813
|
function projectExposure(walk, universe, parent, exemptions) {
|
|
700
814
|
const path = `${walk.layer}.exemptions.resources`;
|
|
701
|
-
const entries = isRecord(exemptions) &&
|
|
815
|
+
const entries = isRecord(exemptions) &&
|
|
816
|
+
isRecord(exemptions.resources)
|
|
702
817
|
? exemptions.resources
|
|
703
818
|
: {};
|
|
704
819
|
const resources = {};
|
|
@@ -742,7 +857,8 @@ function projectExposure(walk, universe, parent, exemptions) {
|
|
|
742
857
|
}
|
|
743
858
|
function pruneEmptyOperationFamilies(operations) {
|
|
744
859
|
for (const [family, variants] of Object.entries(operations)) {
|
|
745
|
-
if (isRecord(variants) &&
|
|
860
|
+
if (isRecord(variants) &&
|
|
861
|
+
Object.keys(variants).length === 0) {
|
|
746
862
|
delete operations[family];
|
|
747
863
|
}
|
|
748
864
|
}
|
|
@@ -839,6 +955,11 @@ function representationFault(axis, value) {
|
|
|
839
955
|
return typeof value === "string" && axis.values.includes(value)
|
|
840
956
|
? undefined
|
|
841
957
|
: `one of ${axis.values.join(", ")} is expected`;
|
|
958
|
+
case "adapterTokens":
|
|
959
|
+
return isTokenList(value) &&
|
|
960
|
+
value.every((token) => axis.values.includes(token))
|
|
961
|
+
? undefined
|
|
962
|
+
: `a list of ${axis.values.join(", ")} is expected`;
|
|
842
963
|
case "flag":
|
|
843
964
|
return typeof value === "boolean" ? undefined : "a boolean is expected";
|
|
844
965
|
case "tokens":
|
|
@@ -912,35 +1033,71 @@ function exposureStyle(layer) {
|
|
|
912
1033
|
}
|
|
913
1034
|
function projectCore(model, config, diagnostics) {
|
|
914
1035
|
const scope = config.root;
|
|
1036
|
+
const managed = managedElsewhereOf(config.trees.root);
|
|
915
1037
|
const providerBaseline = createBaseline(model);
|
|
916
1038
|
const baseline = cloneValue(providerBaseline);
|
|
917
1039
|
baseline.limits = resolveLimits(scope);
|
|
918
1040
|
baseline.transactions = resolveTransactions(model, "root", scope, diagnostics);
|
|
919
|
-
checkResourceTree(model, baseline, "root", config.trees.root, config.definitions, diagnostics);
|
|
1041
|
+
checkResourceTree(model, baseline, "root", config.trees.root, config.definitions, managed, diagnostics);
|
|
920
1042
|
applyFieldDefinitions(model, baseline, config.definitions, diagnostics);
|
|
1043
|
+
const unwithheld = managed.size === 0 ? baseline : cloneValue(baseline);
|
|
1044
|
+
withholdManagedWrites(baseline, managed);
|
|
1045
|
+
markGovernedFields(baseline, config.policy?.governed);
|
|
921
1046
|
applyCompute(baseline, scope.compute);
|
|
922
1047
|
checkLayerValidators(baseline.resources, "root", config.trees.root, diagnostics);
|
|
923
1048
|
const validators = compileValidatorTable(baseline.resources, scope.pipelines);
|
|
924
1049
|
const projection = projectExposure({ layer: "root", style: exposureStyle(scope), diagnostics }, baseline, baseline, scope.exemptions);
|
|
1050
|
+
qualifyFilterModes(projection);
|
|
1051
|
+
pruneHiddenPairings(projection, "shown");
|
|
925
1052
|
projectCreateRequirements(model, projection.resources);
|
|
926
|
-
|
|
1053
|
+
const rootChecked = diagnostics.length;
|
|
1054
|
+
checkHiddenRequirements(model, "root", baseline.resources, unwithheld.resources, projection.resources, diagnostics);
|
|
1055
|
+
explainManagedRefusals(diagnostics, rootChecked, "root", baseline, managed);
|
|
927
1056
|
applyValidators(projection.resources, validators);
|
|
928
1057
|
validateProjection(projection, "root", diagnostics);
|
|
929
1058
|
return { baseline, projection, validators };
|
|
930
1059
|
}
|
|
1060
|
+
function markGovernedFields(baseline, governed) {
|
|
1061
|
+
if (governed === undefined) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
for (const [resourceName, names] of Object.entries(governed)) {
|
|
1065
|
+
const resource = Object.hasOwn(baseline.resources, resourceName)
|
|
1066
|
+
? baseline.resources[resourceName]
|
|
1067
|
+
: undefined;
|
|
1068
|
+
if (resource === undefined) {
|
|
1069
|
+
continue;
|
|
1070
|
+
}
|
|
1071
|
+
for (const name of names) {
|
|
1072
|
+
const field = Object.hasOwn(resource.fields, name)
|
|
1073
|
+
? resource.fields[name]
|
|
1074
|
+
: undefined;
|
|
1075
|
+
if (field !== undefined) {
|
|
1076
|
+
field.governed = true;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
931
1081
|
function projectDerivedScope(model, scopeName, core, parentView, config, diagnostics) {
|
|
932
1082
|
const scope = config[scopeName];
|
|
1083
|
+
const managed = managedElsewhereOf(config.trees.root);
|
|
933
1084
|
const baseline = cloneValue(core.baseline);
|
|
934
1085
|
baseline.limits = resolveLimits(scope);
|
|
935
1086
|
baseline.transactions = resolveTransactions(model, scopeName, scope, scopeName === "agent" &&
|
|
936
1087
|
scope.transactionsStyle === config[config.agent.parent].transactionsStyle
|
|
937
1088
|
? []
|
|
938
1089
|
: diagnostics);
|
|
939
|
-
checkResourceTree(model, baseline, scopeName, config.trees[scopeName], config.definitions, diagnostics);
|
|
1090
|
+
checkResourceTree(model, baseline, scopeName, config.trees[scopeName], config.definitions, managed, diagnostics);
|
|
940
1091
|
applyCompute(baseline, scope.compute);
|
|
941
1092
|
checkLayerValidators(baseline.resources, scopeName, config.trees[scopeName], diagnostics);
|
|
942
1093
|
const validators = compileValidatorTable(baseline.resources, scope.pipelines);
|
|
943
1094
|
const parent = cloneValue(parentView);
|
|
1095
|
+
const unhidden = (scopeName === "client" || scopeName === "agent") && managed.size > 0
|
|
1096
|
+
? cloneValue(parent)
|
|
1097
|
+
: parent;
|
|
1098
|
+
if (unhidden !== parent) {
|
|
1099
|
+
hideManagedElsewhere(parent, managed);
|
|
1100
|
+
}
|
|
944
1101
|
parent.limits = resolveLimits(scope);
|
|
945
1102
|
parent.transactions = baseline.transactions;
|
|
946
1103
|
applyCompute(parent, scope.compute);
|
|
@@ -950,8 +1107,15 @@ function projectDerivedScope(model, scopeName, core, parentView, config, diagnos
|
|
|
950
1107
|
diagnostics,
|
|
951
1108
|
...(scopeName === "agent" ? { parent: config.agent.parent } : {}),
|
|
952
1109
|
}, baseline, parent, scope.exemptions);
|
|
1110
|
+
qualifyFilterModes(projection);
|
|
1111
|
+
pruneHiddenPairings(projection, "none");
|
|
1112
|
+
if (unhidden !== parent) {
|
|
1113
|
+
pruneManagedEnums(projection, unhidden, managed);
|
|
1114
|
+
}
|
|
953
1115
|
projectCreateRequirements(model, projection.resources);
|
|
954
|
-
|
|
1116
|
+
const layerChecked = diagnostics.length;
|
|
1117
|
+
checkHiddenRequirements(model, scopeName, baseline.resources, unhidden.resources, projection.resources, diagnostics);
|
|
1118
|
+
explainManagedRefusals(diagnostics, layerChecked, scopeName, baseline, managed);
|
|
955
1119
|
applyValidators(projection.resources, validators);
|
|
956
1120
|
validateProjection(projection, scopeName, diagnostics);
|
|
957
1121
|
return { projection, validators };
|
|
@@ -984,12 +1148,16 @@ export async function compileContracts(model, config) {
|
|
|
984
1148
|
: agentParent === "application"
|
|
985
1149
|
? applicationProjection.projection
|
|
986
1150
|
: clientProjection.projection, compilerConfig, diagnostics);
|
|
1151
|
+
markCoreResources(coreCompilation.projection, model, managedElsewhereOf(compilerConfig.trees.root));
|
|
987
1152
|
if (diagnostics.length > 0) {
|
|
988
1153
|
return { ok: false, diagnostics };
|
|
989
1154
|
}
|
|
990
1155
|
const core = semanticObject(coreCompilation.projection);
|
|
991
1156
|
const application = semanticObject(applicationProjection.projection);
|
|
992
|
-
const
|
|
1157
|
+
const clientMarked = withReadCache(clientProjection.projection, compilerConfig.client.pipelines);
|
|
1158
|
+
const client = await identifiedContract(compilerConfig.access === undefined
|
|
1159
|
+
? clientMarked
|
|
1160
|
+
: { ...clientMarked, access: compilerConfig.access });
|
|
993
1161
|
const agent = await identifiedContract(agentProjection.projection);
|
|
994
1162
|
for (const [layer, contract] of [
|
|
995
1163
|
["client", client],
|
|
@@ -1007,18 +1175,100 @@ export async function compileContracts(model, config) {
|
|
|
1007
1175
|
};
|
|
1008
1176
|
}
|
|
1009
1177
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1178
|
+
const contracts = { core, application, client, agent };
|
|
1179
|
+
bindRuntimePieces(contracts, compilerConfig.definitions, {
|
|
1180
|
+
core: coreCompilation.validators,
|
|
1181
|
+
application: applicationProjection.validators,
|
|
1182
|
+
client: clientProjection.validators,
|
|
1183
|
+
agent: agentProjection.validators,
|
|
1184
|
+
});
|
|
1185
|
+
return { ok: true, contracts };
|
|
1186
|
+
}
|
|
1187
|
+
function lastCacheOf(levels) {
|
|
1188
|
+
for (let index = (levels?.length ?? 0) - 1; index >= 0; index -= 1) {
|
|
1189
|
+
const stage = levels?.[index]?.cache;
|
|
1190
|
+
if (stage !== undefined) {
|
|
1191
|
+
return { for: stage.for ?? "user", maxAge: stage.maxAge };
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
return undefined;
|
|
1195
|
+
}
|
|
1196
|
+
function withReadCache(projection, tree) {
|
|
1197
|
+
const layer = lastCacheOf(tree.layer);
|
|
1198
|
+
const resources = {};
|
|
1199
|
+
for (const [name, resource] of Object.entries(projection.resources)) {
|
|
1200
|
+
const pipelines = Object.hasOwn(tree.resources, name)
|
|
1201
|
+
? tree.resources[name]
|
|
1202
|
+
: undefined;
|
|
1203
|
+
const find = Object.hasOwn(pipelines?.families ?? {}, "find")
|
|
1204
|
+
? pipelines?.families.find
|
|
1205
|
+
: undefined;
|
|
1206
|
+
const fallback = lastCacheOf(find?.pipelines) ??
|
|
1207
|
+
lastCacheOf(pipelines?.pipelines) ??
|
|
1208
|
+
layer;
|
|
1209
|
+
const advertised = (resource.operations.find ?? {});
|
|
1210
|
+
const marks = {};
|
|
1211
|
+
for (const variant of Object.keys(advertised)) {
|
|
1212
|
+
if (!isOperationVariantAvailable(advertised[variant])) {
|
|
1213
|
+
continue;
|
|
1214
|
+
}
|
|
1215
|
+
const own = Object.hasOwn(find?.variants ?? {}, variant)
|
|
1216
|
+
? find?.variants[variant]?.pipelines
|
|
1217
|
+
: undefined;
|
|
1218
|
+
const mark = lastCacheOf(own) ?? fallback;
|
|
1219
|
+
if (mark !== undefined) {
|
|
1220
|
+
marks[variant] = mark;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
resources[name] =
|
|
1224
|
+
Object.keys(marks).length === 0
|
|
1225
|
+
? resource
|
|
1226
|
+
: { ...resource, cache: marks };
|
|
1227
|
+
}
|
|
1228
|
+
return { ...projection, resources };
|
|
1229
|
+
}
|
|
1230
|
+
function bindRuntimePieces(contracts, definitions, validators) {
|
|
1231
|
+
for (const origin of ["core", "application", "client", "agent"]) {
|
|
1232
|
+
bindShapedFields(contracts[origin], definitions);
|
|
1233
|
+
bindFieldValidators(contracts[origin], validators[origin]);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
export function bindPrebuiltContracts(model, config, contracts) {
|
|
1237
|
+
const compilerConfig = config;
|
|
1238
|
+
const fields = validatedFieldsView(model, compilerConfig.definitions);
|
|
1239
|
+
bindRuntimePieces(contracts, compilerConfig.definitions, {
|
|
1240
|
+
core: compileValidatorTable(fields, compilerConfig.root.pipelines),
|
|
1241
|
+
application: compileValidatorTable(fields, compilerConfig.application.pipelines),
|
|
1242
|
+
client: compileValidatorTable(fields, compilerConfig.client.pipelines),
|
|
1243
|
+
agent: compileValidatorTable(fields, compilerConfig.agent.pipelines),
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
function validatedFieldsView(model, definitions) {
|
|
1247
|
+
const resources = { ...model.resources };
|
|
1248
|
+
for (const [resourceName, resourceDefinitions] of Object.entries(definitions)) {
|
|
1249
|
+
const resource = Object.hasOwn(model.resources, resourceName)
|
|
1250
|
+
? model.resources[resourceName]
|
|
1251
|
+
: undefined;
|
|
1252
|
+
if (resource === undefined) {
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
let added;
|
|
1256
|
+
for (const [fieldName, definition] of Object.entries(resourceDefinitions)) {
|
|
1257
|
+
if (Object.hasOwn(resource.fields, fieldName)) {
|
|
1258
|
+
continue;
|
|
1259
|
+
}
|
|
1260
|
+
added ??= {};
|
|
1261
|
+
added[fieldName] = {
|
|
1262
|
+
kind: "scalar",
|
|
1263
|
+
type: definition.type,
|
|
1264
|
+
list: definition.list,
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
if (added !== undefined) {
|
|
1268
|
+
resources[resourceName] = { fields: { ...resource.fields, ...added } };
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return resources;
|
|
1022
1272
|
}
|
|
1023
1273
|
async function identifiedContract(projection) {
|
|
1024
1274
|
const members = canonicalizeContractMembers({
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { advertisedDirectives, advertisedDirectivesAt, } from "../contracts/field.js";
|
|
2
2
|
import { isOperationVariantAvailable, writeScopeOf, } from "../contracts/resource-operations.js";
|
|
3
|
-
|
|
4
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
-
}
|
|
3
|
+
import { isRecord } from "../runtime/record.guard.js";
|
|
6
4
|
function own(record, key) {
|
|
7
5
|
return Object.hasOwn(record, key) ? record[key] : undefined;
|
|
8
6
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { avzCheckOf, } from "../avz/avz-check.registry.js";
|
|
2
2
|
import { FIELD_CHECK_SUBJECTS, } from "../runtime/field-check.evaluator.js";
|
|
3
|
-
|
|
4
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
-
}
|
|
3
|
+
import { isRecord } from "../runtime/record.guard.js";
|
|
6
4
|
function own(record, key) {
|
|
7
5
|
return Object.hasOwn(record, key) ? record[key] : undefined;
|
|
8
6
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
2
|
+
import type { AvContractCompilerDiagnostic } from "./contract-compiler-diagnostic.js";
|
|
3
|
+
type ProjectedField = Record<string, unknown> & {
|
|
4
|
+
kind: "scalar" | "relation";
|
|
5
|
+
};
|
|
6
|
+
type ProjectedResource = {
|
|
7
|
+
fields: Record<string, ProjectedField>;
|
|
8
|
+
operations: Record<string, unknown>;
|
|
9
|
+
schema?: string;
|
|
10
|
+
managedElsewhere?: true;
|
|
11
|
+
};
|
|
12
|
+
type ProjectedContract = {
|
|
13
|
+
resources: Record<string, ProjectedResource>;
|
|
14
|
+
};
|
|
15
|
+
/** The Resources the root's `resources` tree marks `managedElsewhere: true`. */
|
|
16
|
+
export declare function managedElsewhereOf(rootTree: unknown): ReadonlySet<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Takes every write of a managed Resource away from `baseline`: its write
|
|
19
|
+
* families, its fields' `create`/`update`, and the directives of every relation
|
|
20
|
+
* into it that would write its rows.
|
|
21
|
+
*/
|
|
22
|
+
export declare function withholdManagedWrites(baseline: ProjectedContract, managed: ReadonlySet<string>): void;
|
|
23
|
+
/**
|
|
24
|
+
* Leaves every managed Resource out of `view`, with every relation into it: the
|
|
25
|
+
* client's and the agent's parent view.
|
|
26
|
+
*/
|
|
27
|
+
export declare function hideManagedElsewhere(view: ProjectedContract, managed: ReadonlySet<string>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Leaves out of `view` (a client's or the agent's projection) each enum the
|
|
30
|
+
* managed Resources' fields use in `unhidden` (the view before they were
|
|
31
|
+
* hidden) and no field of `view` uses.
|
|
32
|
+
*/
|
|
33
|
+
export declare function pruneManagedEnums(view: ProjectedContract & {
|
|
34
|
+
enums: Record<string, unknown>;
|
|
35
|
+
}, unhidden: ProjectedContract, managed: ReadonlySet<string>): void;
|
|
36
|
+
/**
|
|
37
|
+
* The Core Contract's Resource facts: the `schema` the adapter states, and
|
|
38
|
+
* `managedElsewhere: true` on each managed Resource.
|
|
39
|
+
*/
|
|
40
|
+
export declare function markCoreResources(projection: ProjectedContract, model: AvAdapterModel, managed: ReadonlySet<string>): void;
|
|
41
|
+
/**
|
|
42
|
+
* Why a write family of a managed Resource is unavailable, or `undefined` when
|
|
43
|
+
* the Resource is not managed or the family is not a write.
|
|
44
|
+
*/
|
|
45
|
+
export declare function managedWriteReason(managed: ReadonlySet<string>, resource: string, family: string): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Adds to each create-requirement refusal from `from` on whose relation points
|
|
48
|
+
* at a managed Resource why that relation cannot be written, and the reference
|
|
49
|
+
* fields that can: exposing the relation, the refusal's own advice, is not open.
|
|
50
|
+
*/
|
|
51
|
+
export declare function explainManagedRefusals(diagnostics: AvContractCompilerDiagnostic[], from: number, layer: string, universe: ProjectedContract, managed: ReadonlySet<string>): void;
|
|
52
|
+
export {};
|