@aventara/core 1.0.0-rc.0 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1434 -0
- package/ERRORS.md +142 -0
- package/README.md +247 -57
- package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
- package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
- package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
- package/dist/adapters/adapter-field.d.ts +25 -11
- package/dist/adapters/adapter-identifier.d.ts +6 -6
- package/dist/adapters/adapter-model.d.ts +18 -9
- package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
- package/dist/adapters/adapter-operation.d.ts +3 -3
- package/dist/adapters/adapter-resource.d.ts +18 -9
- package/dist/adapters/adapter-sql-statement.d.ts +19 -0
- package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
- package/dist/adapters/adapter.interface.d.ts +59 -29
- package/dist/avz/avz-check.factory.d.ts +83 -0
- package/dist/avz/avz-check.factory.js +116 -0
- package/dist/avz/avz-check.registry.d.ts +35 -0
- package/dist/avz/avz-check.registry.js +9 -0
- package/dist/avz/avz.d.ts +203 -0
- package/dist/{json → avz}/avz.js +150 -8
- package/dist/{json → avz}/index.d.ts +2 -1
- package/dist/{json → avz}/json-shape.registry.d.ts +7 -7
- package/dist/{json → avz}/zod-issue.translator.d.ts +8 -2
- package/dist/{json → avz}/zod-issue.translator.js +7 -0
- package/dist/compiler/contract-compiler-diagnostic.d.ts +31 -5
- package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
- package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
- package/dist/compiler/contract.compiler.d.ts +18 -18
- package/dist/compiler/contract.compiler.js +637 -442
- package/dist/compiler/create-requirements.projector.d.ts +49 -0
- package/dist/compiler/create-requirements.projector.js +423 -0
- package/dist/compiler/field-validator.compiler.d.ts +47 -0
- package/dist/compiler/field-validator.compiler.js +238 -0
- package/dist/config/any-framework-config.d.ts +19 -12
- package/dist/config/computed-fields.d.ts +62 -0
- package/dist/config/computed-fields.js +80 -0
- package/dist/config/config-diagnostic.d.ts +11 -4
- package/dist/config/config-diagnostic.guidance.d.ts +6 -0
- package/dist/config/config-diagnostic.guidance.js +32 -0
- package/dist/config/config-layer.d.ts +15 -6
- package/dist/config/config.resolver.d.ts +74 -31
- package/dist/config/config.resolver.js +108 -44
- package/dist/config/config.validator.d.ts +7 -7
- package/dist/config/config.validator.js +581 -72
- package/dist/config/define-resource.d.ts +57 -0
- package/dist/config/define-resource.js +14 -0
- package/dist/config/effective-fields.d.ts +19 -23
- package/dist/config/entrypoint.normalizer.d.ts +1 -1
- package/dist/config/exact-framework-config.d.ts +308 -0
- package/dist/config/field-compute.resolver.d.ts +21 -0
- package/dist/config/field-compute.resolver.js +123 -0
- package/dist/config/field-pipeline-config.d.ts +47 -0
- package/dist/config/forced-operation.validator.d.ts +10 -0
- package/dist/config/forced-operation.validator.js +66 -0
- package/dist/config/framework-config.d.ts +111 -39
- package/dist/config/framework-exemptions-config.d.ts +91 -0
- package/dist/config/framework-exemptions-config.js +1 -0
- package/dist/config/framework-field-definition.d.ts +78 -0
- package/dist/config/framework-field-definition.js +28 -0
- package/dist/config/framework-resources-config.d.ts +122 -0
- package/dist/config/framework-resources-config.js +1 -0
- package/dist/config/pipeline-config.d.ts +56 -20
- package/dist/config/pipeline-tree.resolver.d.ts +79 -0
- package/dist/config/pipeline-tree.resolver.js +220 -0
- package/dist/config/stage-type.eraser.d.ts +65 -0
- package/dist/config/stage-type.eraser.js +1 -0
- package/dist/contracts/capability.d.ts +21 -12
- package/dist/contracts/capability.js +2 -0
- package/dist/contracts/client-contract-structure.validator.d.ts +388 -63
- package/dist/contracts/client-contract-structure.validator.js +156 -10
- package/dist/contracts/contract-canonicalizer.d.ts +26 -3
- package/dist/contracts/contract-canonicalizer.js +156 -29
- package/dist/contracts/contract-hash.d.ts +12 -7
- package/dist/contracts/contract-hash.js +3 -2
- package/dist/contracts/contract-limits.d.ts +4 -1
- package/dist/contracts/contract-limits.js +1 -0
- package/dist/contracts/contract-lookup.d.ts +5 -5
- package/dist/contracts/contract-protocol.d.ts +4 -4
- package/dist/contracts/contract.d.ts +24 -16
- package/dist/contracts/create-requirements.d.ts +35 -0
- package/dist/contracts/create-requirements.js +1 -0
- package/dist/contracts/enum-definition.d.ts +1 -1
- package/dist/contracts/field-check.d.ts +101 -0
- package/dist/contracts/field-check.js +1 -0
- package/dist/contracts/field.d.ts +81 -42
- package/dist/contracts/identifier.d.ts +4 -4
- package/dist/contracts/json-shape.d.ts +12 -1
- package/dist/contracts/lifecycle-trait.d.ts +2 -2
- package/dist/contracts/resource-operations.d.ts +28 -28
- package/dist/contracts/resource.d.ts +15 -9
- package/dist/contracts/scalar-value-type.d.ts +15 -15
- package/dist/contracts/scalar.d.ts +3 -3
- package/dist/contracts/transaction-capability.d.ts +1 -1
- package/dist/contracts/wire-scalar-format.d.ts +4 -4
- package/dist/framework/contract-view.d.ts +213 -147
- package/dist/framework/framework-construction.error.d.ts +19 -10
- package/dist/framework/framework-construction.error.js +7 -3
- package/dist/framework/framework.d.ts +47 -23
- package/dist/framework/framework.factory.d.ts +8 -6
- package/dist/framework/framework.factory.js +49 -22
- package/dist/framework/operation-facade.d.ts +123 -52
- package/dist/framework/operation-facade.js +9 -1
- package/dist/index.d.ts +57 -50
- package/dist/index.js +7 -6
- package/dist/internal.d.ts +17 -10
- package/dist/internal.js +4 -1
- package/dist/operations/database-refusal.d.ts +51 -0
- package/dist/operations/database-refusal.js +45 -0
- package/dist/operations/operation-arguments.d.ts +343 -207
- package/dist/operations/operation-call.d.ts +27 -28
- package/dist/operations/operation-identity.d.ts +10 -10
- package/dist/operations/operation-result.d.ts +21 -21
- package/dist/operations/operation-validator-core.d.ts +6 -6
- package/dist/operations/operation-validator-core.js +99 -6
- package/dist/operations/operation-validator.d.ts +9 -9
- package/dist/operations/projection-scope.resolver.d.ts +6 -6
- package/dist/operations/structural-limits.walker.d.ts +6 -6
- package/dist/operations/structural-limits.walker.js +145 -0
- package/dist/operations/validation-code.d.ts +11 -6
- package/dist/operations/validation-code.guidance.d.ts +6 -0
- package/dist/operations/validation-code.guidance.js +90 -0
- package/dist/operations/validation-code.js +4 -0
- package/dist/operations/write-scope.resolver.d.ts +10 -6
- package/dist/operations/write-scope.resolver.js +2 -0
- package/dist/protocol/absent-route.responder.d.ts +13 -12
- package/dist/protocol/absent-route.responder.js +19 -19
- package/dist/protocol/contract-document.responder.d.ts +3 -3
- package/dist/protocol/contract-document.responder.js +2 -2
- package/dist/protocol/http-request.decoder.d.ts +17 -13
- package/dist/protocol/http-request.decoder.js +10 -10
- package/dist/protocol/http-request.reader.d.ts +3 -3
- package/dist/protocol/http-response.encoder.d.ts +4 -4
- package/dist/protocol/http-response.encoder.js +94 -55
- package/dist/protocol/http-status.table.d.ts +2 -2
- package/dist/protocol/operation-response.guard.d.ts +2 -2
- package/dist/protocol/protocol-surface.d.ts +4 -4
- package/dist/protocol/protocol.binder.d.ts +50 -27
- package/dist/protocol/protocol.binder.js +12 -9
- package/dist/protocol/protocol.handler.d.ts +22 -13
- package/dist/protocol/protocol.handler.js +91 -17
- package/dist/protocol/unmounted-route.error.d.ts +4 -4
- package/dist/protocol/unmounted-route.error.js +2 -2
- package/dist/runtime/caller-data.copier.d.ts +22 -5
- package/dist/runtime/caller-data.copier.js +31 -14
- package/dist/runtime/caller-data.door.d.ts +17 -11
- package/dist/runtime/caller-data.door.js +6 -4
- package/dist/runtime/computed-read-runtime.d.ts +7 -6
- package/dist/runtime/computed-read-runtime.js +76 -50
- package/dist/runtime/computed-value.error.d.ts +7 -6
- package/dist/runtime/computed-value.error.js +5 -4
- package/dist/runtime/context-executor.runtime.d.ts +59 -0
- package/dist/runtime/context-executor.runtime.js +275 -0
- package/dist/runtime/create-requirement.d.ts +44 -79
- package/dist/runtime/create-requirement.js +213 -73
- package/dist/runtime/decimal.d.ts +2 -2
- package/dist/runtime/decimal.js +1 -1
- package/dist/runtime/diagnostics-reporter.d.ts +54 -27
- package/dist/runtime/diagnostics-reporter.js +24 -0
- package/dist/runtime/error-boundary.d.ts +65 -8
- package/dist/runtime/error-boundary.js +49 -19
- package/dist/runtime/error-guidance.d.ts +12 -0
- package/dist/runtime/error-guidance.js +1 -0
- package/dist/runtime/error.catalog.d.ts +49 -0
- package/dist/runtime/error.catalog.js +49 -0
- package/dist/runtime/execution-options.d.ts +10 -2
- package/dist/runtime/field-check.evaluator.d.ts +29 -0
- package/dist/runtime/field-check.evaluator.js +521 -0
- package/dist/runtime/field-compute.d.ts +64 -0
- package/dist/runtime/field-compute.js +1 -0
- package/dist/runtime/field-stage.plan.d.ts +15 -0
- package/dist/runtime/field-stage.plan.js +27 -0
- package/dist/runtime/field-stage.runtime.d.ts +37 -0
- package/dist/runtime/field-stage.runtime.js +147 -0
- package/dist/runtime/field-validator.runtime.d.ts +19 -0
- package/dist/runtime/field-validator.runtime.js +92 -0
- package/dist/runtime/framework-error-class.table.d.ts +33 -0
- package/dist/runtime/framework-error-class.table.js +25 -0
- package/dist/runtime/framework-error.d.ts +68 -8
- package/dist/runtime/framework-error.factory.d.ts +4 -0
- package/dist/runtime/framework-error.factory.js +15 -0
- package/dist/runtime/framework-error.js +23 -2
- package/dist/runtime/interceptor-next.error.d.ts +5 -0
- package/dist/runtime/interceptor-next.error.js +6 -0
- package/dist/runtime/json-value.d.ts +11 -6
- package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
- package/dist/runtime/level-lifecycle.runtime.js +39 -0
- package/dist/runtime/misuse-reporter.d.ts +12 -12
- package/dist/runtime/mutation-planner.d.ts +19 -10
- package/dist/runtime/mutation-planner.js +48 -35
- package/dist/runtime/nested-write.walker.d.ts +32 -0
- package/dist/runtime/nested-write.walker.js +73 -0
- package/dist/runtime/operation-code.guidance.d.ts +6 -0
- package/dist/runtime/operation-code.guidance.js +167 -0
- package/dist/runtime/operation-request.d.ts +33 -6
- package/dist/runtime/operation-response.d.ts +17 -17
- package/dist/runtime/operation-runtime.d.ts +127 -25
- package/dist/runtime/operation-runtime.js +441 -78
- package/dist/runtime/outcome-mapper.d.ts +16 -5
- package/dist/runtime/outcome-mapper.js +23 -6
- package/dist/runtime/output-validator.d.ts +10 -10
- package/dist/runtime/output-validator.js +3 -3
- package/dist/runtime/owned-execution.registry.d.ts +16 -6
- package/dist/runtime/pipe-output.validator.d.ts +43 -18
- package/dist/runtime/pipe-output.validator.js +15 -13
- package/dist/runtime/pipeline.d.ts +223 -34
- package/dist/runtime/readonly-value.d.ts +43 -0
- package/dist/runtime/readonly-value.js +150 -0
- package/dist/runtime/request-envelope.validator.d.ts +3 -3
- package/dist/runtime/request-envelope.validator.js +12 -7
- package/dist/runtime/request-id.d.ts +1 -1
- package/dist/runtime/request-state.d.ts +14 -0
- package/dist/runtime/request-state.js +1 -0
- package/dist/runtime/request-state.resolver.d.ts +12 -0
- package/dist/runtime/request-state.resolver.js +20 -0
- package/dist/runtime/scalar-runtime.d.ts +35 -16
- package/dist/runtime/scalar-runtime.js +102 -34
- package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
- package/dist/runtime/unsent-value.normalizer.js +128 -0
- package/dist/transactions/deferred-operation.d.ts +35 -20
- package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
- package/dist/transactions/operation-arguments-encoder.js +2 -2
- package/dist/transactions/operation-fingerprint.js +2 -2
- package/dist/transactions/sql-statement.d.ts +85 -0
- package/dist/transactions/sql-statement.js +47 -0
- package/dist/transactions/sql-statement.validator.d.ts +44 -0
- package/dist/transactions/sql-statement.validator.js +167 -0
- package/dist/transactions/transaction-envelope.d.ts +4 -4
- package/dist/transactions/transaction-integrity-error.d.ts +6 -6
- package/dist/transactions/transaction-integrity-error.js +5 -2
- package/dist/transactions/transaction-plan-assembler.d.ts +21 -11
- package/dist/transactions/transaction-plan-assembler.js +169 -32
- package/dist/transactions/transaction-plan-validator.d.ts +45 -20
- package/dist/transactions/transaction-plan-validator.js +96 -38
- package/dist/transactions/transaction-reference-collector.d.ts +5 -5
- package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
- package/dist/transactions/transaction-reference-resolver.js +26 -14
- package/dist/transactions/transaction-reference-validator.d.ts +76 -4
- package/dist/transactions/transaction-reference-validator.js +129 -71
- package/dist/transactions/transaction-reference.d.ts +13 -13
- package/dist/transactions/transaction-reference.js +5 -0
- package/dist/transactions/transaction-request.d.ts +18 -5
- package/dist/transactions/transaction-response.d.ts +6 -6
- package/dist/transactions/transaction-runtime.d.ts +8 -7
- package/dist/transactions/transaction-runtime.js +191 -50
- package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
- package/dist/transactions/transaction-settlement.runtime.js +120 -0
- package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
- package/dist/transactions/transaction-slot-path-error.js +2 -2
- package/dist/transactions/transaction-slot-writer.js +2 -2
- package/dist/transactions/transaction-stage.runtime.d.ts +82 -0
- package/dist/transactions/transaction-stage.runtime.js +126 -0
- package/package.json +9 -7
- package/src/runtime/field-check.evaluator.ts +720 -0
- package/dist/config/define-fields.d.ts +0 -42
- package/dist/config/define-fields.js +0 -3
- package/dist/config/framework-behaviors-config.d.ts +0 -30
- package/dist/config/framework-fields-config.d.ts +0 -42
- package/dist/config/framework-restrictions-config.d.ts +0 -142
- package/dist/json/avz.d.ts +0 -96
- package/dist/runtime/field-behavior.d.ts +0 -48
- /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
- /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
- /package/dist/{json → avz}/index.js +0 -0
- /package/dist/{json → avz}/json-shape.registry.js +0 -0
- /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
- /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { avzCheckOf, } from "../avz/avz-check.registry.js";
|
|
2
|
+
import { FIELD_CHECK_SUBJECTS, } from "../runtime/field-check.evaluator.js";
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function own(record, key) {
|
|
7
|
+
return Object.hasOwn(record, key) ? record[key] : undefined;
|
|
8
|
+
}
|
|
9
|
+
function scalarOf(field) {
|
|
10
|
+
const type = field.type;
|
|
11
|
+
return typeof type?.scalar === "string" ? type.scalar : undefined;
|
|
12
|
+
}
|
|
13
|
+
function subjectOf(field) {
|
|
14
|
+
const scalar = scalarOf(field);
|
|
15
|
+
return scalar === undefined ? undefined : own(FIELD_CHECK_SUBJECTS, scalar);
|
|
16
|
+
}
|
|
17
|
+
function describeField(field) {
|
|
18
|
+
const scalar = scalarOf(field) ?? "enum";
|
|
19
|
+
const noun = `${scalar}${field.list === true ? " list" : ""} field`;
|
|
20
|
+
return `${/^[aeiou]/.test(scalar) ? "an" : "a"} ${noun}`;
|
|
21
|
+
}
|
|
22
|
+
function describeCheck(check) {
|
|
23
|
+
switch (check.check) {
|
|
24
|
+
case "less_than":
|
|
25
|
+
return check.inclusive ? "AvZ.lte" : "AvZ.lt";
|
|
26
|
+
case "greater_than":
|
|
27
|
+
return check.inclusive ? "AvZ.gte" : "AvZ.gt";
|
|
28
|
+
case "multiple_of":
|
|
29
|
+
return "AvZ.multipleOf";
|
|
30
|
+
case "max_length":
|
|
31
|
+
return check.list === true ? "AvZ.maxItems" : "AvZ.maxLength";
|
|
32
|
+
case "min_length":
|
|
33
|
+
return check.list === true ? "AvZ.minItems" : "AvZ.minLength";
|
|
34
|
+
case "length_equals":
|
|
35
|
+
return "AvZ.length";
|
|
36
|
+
case "string_format":
|
|
37
|
+
return `a string format check (${check.format})`;
|
|
38
|
+
case "max_size":
|
|
39
|
+
return "AvZ.maxSize";
|
|
40
|
+
case "min_size":
|
|
41
|
+
return "AvZ.minSize";
|
|
42
|
+
case "size_equals":
|
|
43
|
+
return "AvZ.size";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function boundFor(value, subject, multiple) {
|
|
47
|
+
switch (subject) {
|
|
48
|
+
case "number":
|
|
49
|
+
return typeof value === "number"
|
|
50
|
+
? { value }
|
|
51
|
+
: { fault: "an int or float field's bound is a number" };
|
|
52
|
+
case "decimal":
|
|
53
|
+
return value instanceof Date
|
|
54
|
+
? { fault: "a decimal field's bound is a number or a bigint" }
|
|
55
|
+
: { value: String(value) };
|
|
56
|
+
case "bigint":
|
|
57
|
+
return typeof value === "bigint" ||
|
|
58
|
+
(typeof value === "number" && Number.isSafeInteger(value))
|
|
59
|
+
? { value: String(value) }
|
|
60
|
+
: { fault: "a bigint field's bound is a bigint" };
|
|
61
|
+
case "datetime":
|
|
62
|
+
return multiple
|
|
63
|
+
? { fault: "a datetime takes bounds, not multiples" }
|
|
64
|
+
: value instanceof Date
|
|
65
|
+
? { value: value.toISOString() }
|
|
66
|
+
: { fault: "a datetime field's bound is a Date" };
|
|
67
|
+
default:
|
|
68
|
+
return {
|
|
69
|
+
fault: "bounds apply to number, bigint, decimal and datetime fields",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function compileCheck(check, field) {
|
|
74
|
+
const subject = subjectOf(field);
|
|
75
|
+
switch (check.check) {
|
|
76
|
+
case "less_than":
|
|
77
|
+
case "greater_than":
|
|
78
|
+
case "multiple_of": {
|
|
79
|
+
const written = boundFor(check.value, subject, check.check === "multiple_of");
|
|
80
|
+
if ("fault" in written) {
|
|
81
|
+
return written;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
check: check.check === "multiple_of"
|
|
85
|
+
? { check: "multiple_of", value: written.value }
|
|
86
|
+
: {
|
|
87
|
+
check: check.check,
|
|
88
|
+
value: written.value,
|
|
89
|
+
inclusive: check.inclusive,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
case "max_length":
|
|
94
|
+
case "min_length":
|
|
95
|
+
if (check.list === true) {
|
|
96
|
+
return field.list === true
|
|
97
|
+
? { check }
|
|
98
|
+
: {
|
|
99
|
+
fault: "AvZ.minItems and AvZ.maxItems check a list's length; the field is not a list",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return subject === "string"
|
|
103
|
+
? { check }
|
|
104
|
+
: { fault: "length checks apply to string fields" };
|
|
105
|
+
case "length_equals":
|
|
106
|
+
case "string_format":
|
|
107
|
+
return subject === "string"
|
|
108
|
+
? { check }
|
|
109
|
+
: { fault: "string checks apply to string fields" };
|
|
110
|
+
case "max_size":
|
|
111
|
+
case "min_size":
|
|
112
|
+
case "size_equals":
|
|
113
|
+
return subject === "bytes"
|
|
114
|
+
? { check }
|
|
115
|
+
: { fault: "size checks apply to bytes fields" };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function label(resource, field) {
|
|
119
|
+
return `${resource}.${field}`;
|
|
120
|
+
}
|
|
121
|
+
export function checkLayerValidators(resources, layer, tree, diagnostics) {
|
|
122
|
+
if (!isRecord(tree)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const [resourceName, entry] of Object.entries(tree)) {
|
|
126
|
+
const resource = own(resources, resourceName);
|
|
127
|
+
if (resource === undefined || !isRecord(entry) || !isRecord(entry.fields)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
for (const [fieldName, fieldEntry] of Object.entries(entry.fields)) {
|
|
131
|
+
const field = own(resource.fields, fieldName);
|
|
132
|
+
if (field === undefined ||
|
|
133
|
+
!isRecord(fieldEntry) ||
|
|
134
|
+
!isRecord(fieldEntry.pipelines) ||
|
|
135
|
+
!Object.hasOwn(fieldEntry.pipelines, "validators")) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const path = `${layer}.resources.${resourceName}.fields.${fieldName}.pipelines.validators`;
|
|
139
|
+
const refuse = (at, message) => diagnostics.push({
|
|
140
|
+
code: "COMPILER_INVALID_VALIDATOR",
|
|
141
|
+
path: at,
|
|
142
|
+
message,
|
|
143
|
+
});
|
|
144
|
+
if (field.kind === "relation") {
|
|
145
|
+
refuse(path, `relation field "${label(resourceName, fieldName)}" takes write guards only; validators check a scalar field's value`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (scalarOf(field) === "json") {
|
|
149
|
+
refuse(path, `field "${label(resourceName, fieldName)}" is a Json field: Json fields carry their checks in definition.json (AvZ.string().check(AvZ.maxLength(80)), …)`);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const validators = fieldEntry.pipelines.validators;
|
|
153
|
+
if (!Array.isArray(validators)) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
for (const [index, value] of validators.entries()) {
|
|
157
|
+
const at = `${path}[${index}]`;
|
|
158
|
+
const check = avzCheckOf(value);
|
|
159
|
+
if (check === undefined) {
|
|
160
|
+
refuse(at, `field "${label(resourceName, fieldName)}": a validator must be a check built with AvZ from "@aventara/core/avz" (AvZ.maxLength(80), AvZ.email(), …); a Zod check or any other value is not accepted`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const compiled = compileCheck(check, field);
|
|
164
|
+
if ("fault" in compiled) {
|
|
165
|
+
refuse(at, `${describeCheck(check)} does not fit field "${label(resourceName, fieldName)}", ${describeField(field)}: ${compiled.fault}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export function compileValidatorTable(resources, tree) {
|
|
172
|
+
const table = {};
|
|
173
|
+
for (const [resourceName, pipelines] of Object.entries(tree.resources)) {
|
|
174
|
+
const resource = own(resources, resourceName);
|
|
175
|
+
if (resource === undefined) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
for (const [fieldName, field] of Object.entries(resource.fields)) {
|
|
179
|
+
const stages = own(pipelines.fields, fieldName);
|
|
180
|
+
if (stages === undefined ||
|
|
181
|
+
field.kind !== "scalar" ||
|
|
182
|
+
scalarOf(field) === "json" ||
|
|
183
|
+
stages.validators.length === 0) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const checks = stages.validators.flatMap((value) => {
|
|
187
|
+
const check = avzCheckOf(value);
|
|
188
|
+
const compiled = check === undefined ? undefined : compileCheck(check, field);
|
|
189
|
+
return compiled !== undefined && "check" in compiled
|
|
190
|
+
? [compiled.check]
|
|
191
|
+
: [];
|
|
192
|
+
});
|
|
193
|
+
if (checks.length > 0) {
|
|
194
|
+
table[resourceName] ??= {};
|
|
195
|
+
table[resourceName][fieldName] = {
|
|
196
|
+
checks,
|
|
197
|
+
subject: subjectOf(field),
|
|
198
|
+
list: field.list === true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return table;
|
|
204
|
+
}
|
|
205
|
+
export function applyValidators(resources, table) {
|
|
206
|
+
for (const [resourceName, fields] of Object.entries(table)) {
|
|
207
|
+
const resource = own(resources, resourceName);
|
|
208
|
+
for (const [fieldName, compiled] of Object.entries(fields)) {
|
|
209
|
+
const field = resource === undefined ? undefined : own(resource.fields, fieldName);
|
|
210
|
+
if (field !== undefined && field.kind === "scalar") {
|
|
211
|
+
field.validators = compiled.checks.map((check) => ({ ...check }));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const tables = new WeakMap();
|
|
217
|
+
export function bindFieldValidators(contract, table) {
|
|
218
|
+
tables.set(contract, table);
|
|
219
|
+
}
|
|
220
|
+
const shaped = new WeakMap();
|
|
221
|
+
function hasShapedField(contract) {
|
|
222
|
+
let found = shaped.get(contract);
|
|
223
|
+
if (found === undefined) {
|
|
224
|
+
found = Object.values(contract.resources).some((resource) => Object.values(resource.fields).some((field) => field.kind === "scalar" && field.json !== undefined));
|
|
225
|
+
shaped.set(contract, found);
|
|
226
|
+
}
|
|
227
|
+
return found;
|
|
228
|
+
}
|
|
229
|
+
export function hasFieldValidators(contract) {
|
|
230
|
+
const table = tables.get(contract);
|
|
231
|
+
return ((table !== undefined && Object.keys(table).length > 0) ||
|
|
232
|
+
hasShapedField(contract));
|
|
233
|
+
}
|
|
234
|
+
const NO_FIELDS = Object.freeze({});
|
|
235
|
+
export function validatedFieldsOf(contract, resource) {
|
|
236
|
+
const table = tables.get(contract);
|
|
237
|
+
return (table === undefined ? undefined : own(table, resource)) ?? NO_FIELDS;
|
|
238
|
+
}
|
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* A `resources` block whose Resource and field names are both unconstrained:
|
|
3
|
+
* each Resource entry may carry a `fields` record of any names.
|
|
4
|
+
*/
|
|
5
|
+
export type AvConfigResourcesAny = Readonly<Record<string, {
|
|
5
6
|
readonly [key: string]: unknown;
|
|
6
|
-
readonly fields?:
|
|
7
|
+
readonly fields?: Readonly<Record<string, unknown>> | undefined;
|
|
8
|
+
} | undefined>>;
|
|
9
|
+
/** The widest layer overlay: a `resources` block, and anything else. */
|
|
10
|
+
export type AvConfigLayerAny = {
|
|
11
|
+
readonly [key: string | symbol]: unknown;
|
|
12
|
+
readonly resources?: AvConfigResourcesAny;
|
|
7
13
|
};
|
|
8
14
|
/**
|
|
9
|
-
* The widest configuration type: every
|
|
10
|
-
* is the default `Cfg` of `
|
|
15
|
+
* The widest configuration type: every Resource admits every field name. It
|
|
16
|
+
* is the default `Cfg` of `AvConfig`, `AvFramework` and
|
|
11
17
|
* `createFramework`; pass your own configuration's type instead to get field
|
|
12
18
|
* names checked.
|
|
13
19
|
*/
|
|
14
|
-
export type
|
|
15
|
-
readonly [key: string]: unknown;
|
|
16
|
-
readonly
|
|
17
|
-
readonly application?:
|
|
18
|
-
readonly client?:
|
|
20
|
+
export type AvConfigAny = {
|
|
21
|
+
readonly [key: string | symbol]: unknown;
|
|
22
|
+
readonly resources?: AvConfigResourcesAny;
|
|
23
|
+
readonly application?: AvConfigLayerAny;
|
|
24
|
+
readonly client?: AvConfigLayerAny;
|
|
25
|
+
readonly agent?: AvConfigLayerAny;
|
|
19
26
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { AvConfigAgentParent, AvConfigLayerName } from "./config-layer.js";
|
|
2
|
+
/** The fields one layer's write compute fills, per Resource and phase. */
|
|
3
|
+
type LayerComputedFields = Readonly<Record<string, {
|
|
4
|
+
/** Fields with a `compute.create` stage, sorted. */
|
|
5
|
+
readonly create?: readonly string[];
|
|
6
|
+
/** Fields with a `compute.update` stage, sorted. */
|
|
7
|
+
readonly update?: readonly string[];
|
|
8
|
+
}>>;
|
|
9
|
+
/**
|
|
10
|
+
* Which fields a configuration's write compute fills: per layer, the
|
|
11
|
+
* Resources, and per Resource the fields with a `compute.create` and a
|
|
12
|
+
* `compute.update` stage, each list sorted; and the layer the agent layer
|
|
13
|
+
* extends. Written by an adapter's generate step from the configuration's type,
|
|
14
|
+
* and compared with the configuration at startup.
|
|
15
|
+
*/
|
|
16
|
+
export type AvConfigComputedFields = {
|
|
17
|
+
readonly agent: LayerComputedFields;
|
|
18
|
+
/** The agent layer's `extends`: `"client"` when the configuration leaves it out. */
|
|
19
|
+
readonly agentExtends: AvConfigAgentParent;
|
|
20
|
+
readonly application: LayerComputedFields;
|
|
21
|
+
readonly client: LayerComputedFields;
|
|
22
|
+
readonly root: LayerComputedFields;
|
|
23
|
+
};
|
|
24
|
+
/** The layers whose compute may have filled a field when a stage of layer `L` runs. */
|
|
25
|
+
type ComputingLayers<Facts extends AvConfigComputedFields, L extends AvConfigLayerName> = L extends "root" ? AvConfigLayerName : L extends "agent" ? "root" | "agent" | Exclude<Facts["agentExtends"], "root"> : "root" | L | (Facts["agentExtends"] extends L ? "agent" : never);
|
|
26
|
+
/** `"<Resource>.<field>"` for every field a layer's `compute.create` fills. */
|
|
27
|
+
type CreateComputedOf<Layer> = Layer extends object ? {
|
|
28
|
+
[R in keyof Layer]: Layer[R] extends {
|
|
29
|
+
readonly create?: readonly (infer Field extends string)[];
|
|
30
|
+
} ? `${R & string}.${Field}` : never;
|
|
31
|
+
}[keyof Layer] : never;
|
|
32
|
+
/**
|
|
33
|
+
* The create fields a variant's guards, pipes and filters of layer `L` may be
|
|
34
|
+
* told without, as `"<Resource>.<field>"`: those a layer whose compute runs for
|
|
35
|
+
* the stage's origins fills on create. `string` (every field) when the model's
|
|
36
|
+
* type carries no statement of them.
|
|
37
|
+
*/
|
|
38
|
+
export type AvPreComputeLift<M, L extends AvConfigLayerName> = M extends {
|
|
39
|
+
readonly "~computedFields"?: infer Facts;
|
|
40
|
+
} ? Exclude<Facts, undefined> extends infer Stated extends AvConfigComputedFields ? string extends keyof Stated["root"] ? string : CreateComputedOf<Stated[ComputingLayers<Stated, L>]> : string : string;
|
|
41
|
+
/** The configuration's layers' `resources` trees and the agent's parent. */
|
|
42
|
+
export type ComputedFieldsSource = {
|
|
43
|
+
readonly trees: Readonly<Record<AvConfigLayerName, unknown>>;
|
|
44
|
+
readonly agentExtends: AvConfigAgentParent;
|
|
45
|
+
};
|
|
46
|
+
/** The computed fields of a configuration, in the form a generate step writes them. */
|
|
47
|
+
export declare function computedFieldsOf(source: ComputedFieldsSource): AvConfigComputedFields;
|
|
48
|
+
/**
|
|
49
|
+
* How the configuration's computed fields differ from the ones the generated
|
|
50
|
+
* types were written with, one sentence per difference; empty when they agree.
|
|
51
|
+
*/
|
|
52
|
+
export declare function computedFieldsDrift(generated: AvConfigComputedFields, configured: AvConfigComputedFields): string[];
|
|
53
|
+
/** The warning's code, as `process.emitWarning` reports it. */
|
|
54
|
+
export declare const STALE_GENERATED_TYPES_WARNING = "AVENTARA_STALE_GENERATED_TYPES";
|
|
55
|
+
/**
|
|
56
|
+
* Warns, through `process.emitWarning` (code
|
|
57
|
+
* {@link STALE_GENERATED_TYPES_WARNING}), when the generated types' computed
|
|
58
|
+
* fields differ from the configuration's. Nothing to compare (an Adapter that
|
|
59
|
+
* carries none) warns nothing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function warnOnStaleComputedFields(generated: AvConfigComputedFields | undefined, configured: AvConfigComputedFields): void;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { computeOfLayer } from "./field-compute.resolver.js";
|
|
2
|
+
function layerComputedFields(resources) {
|
|
3
|
+
const result = {};
|
|
4
|
+
const compute = computeOfLayer(resources);
|
|
5
|
+
for (const resource of Object.keys(compute).sort()) {
|
|
6
|
+
const fields = compute[resource] ?? {};
|
|
7
|
+
const create = Object.keys(fields)
|
|
8
|
+
.filter((field) => fields[field]?.create !== undefined)
|
|
9
|
+
.sort();
|
|
10
|
+
const update = Object.keys(fields)
|
|
11
|
+
.filter((field) => fields[field]?.update !== undefined)
|
|
12
|
+
.sort();
|
|
13
|
+
if (create.length === 0 && update.length === 0) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
result[resource] = {
|
|
17
|
+
...(create.length === 0 ? {} : { create }),
|
|
18
|
+
...(update.length === 0 ? {} : { update }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
export function computedFieldsOf(source) {
|
|
24
|
+
return {
|
|
25
|
+
agent: layerComputedFields(source.trees.agent),
|
|
26
|
+
agentExtends: source.agentExtends,
|
|
27
|
+
application: layerComputedFields(source.trees.application),
|
|
28
|
+
client: layerComputedFields(source.trees.client),
|
|
29
|
+
root: layerComputedFields(source.trees.root),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const LAYERS = ["root", "application", "client", "agent"];
|
|
33
|
+
const PHASES = ["create", "update"];
|
|
34
|
+
function missingFrom(left, right) {
|
|
35
|
+
const missing = [];
|
|
36
|
+
for (const layer of LAYERS) {
|
|
37
|
+
for (const [resource, phases] of Object.entries(left[layer])) {
|
|
38
|
+
for (const phase of PHASES) {
|
|
39
|
+
for (const field of phases[phase] ?? []) {
|
|
40
|
+
if (!right[layer][resource]?.[phase]?.includes(field)) {
|
|
41
|
+
missing.push(`${layer} ${resource}.${field} (${phase})`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return missing;
|
|
48
|
+
}
|
|
49
|
+
export function computedFieldsDrift(generated, configured) {
|
|
50
|
+
const drift = [
|
|
51
|
+
...missingFrom(configured, generated).map((entry) => `computed in the configuration, not in the types: ${entry}`),
|
|
52
|
+
...missingFrom(generated, configured).map((entry) => `computed in the types, not in the configuration: ${entry}`),
|
|
53
|
+
];
|
|
54
|
+
if (generated.agentExtends !== configured.agentExtends) {
|
|
55
|
+
drift.push(`the agent layer extends "${configured.agentExtends}", the types say "${generated.agentExtends}"`);
|
|
56
|
+
}
|
|
57
|
+
return drift;
|
|
58
|
+
}
|
|
59
|
+
export const STALE_GENERATED_TYPES_WARNING = "AVENTARA_STALE_GENERATED_TYPES";
|
|
60
|
+
export function warnOnStaleComputedFields(generated, configured) {
|
|
61
|
+
if (generated === undefined) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const drift = computedFieldsDrift(generated, configured);
|
|
65
|
+
if (drift.length === 0) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const message = `generated types are stale: run aventara:prepare. The computed fields the pre-compute stages are typed with differ from the configuration's:\n${drift
|
|
69
|
+
.map((line) => ` - ${line}`)
|
|
70
|
+
.join("\n")}`;
|
|
71
|
+
const emitWarning = globalThis.process?.emitWarning;
|
|
72
|
+
if (typeof emitWarning === "function") {
|
|
73
|
+
emitWarning(message, {
|
|
74
|
+
type: "AventaraWarning",
|
|
75
|
+
code: STALE_GENERATED_TYPES_WARNING,
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
globalThis.console?.warn(`AventaraWarning: ${message}`);
|
|
80
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
/** Codes of {@link
|
|
2
|
-
export type
|
|
1
|
+
/** Codes of {@link AvConfigDiagnostic}. */
|
|
2
|
+
export type AvConfigDiagnosticCode = "CONFIG_REQUIRED" | "CONFIG_UNKNOWN_PROPERTY" | "CONFIG_INVALID_TYPE" | "CONFIG_INVALID_VALUE"
|
|
3
|
+
/** An rc.0 key that moved in rc.1; the message names where it lives now. */
|
|
4
|
+
| "CONFIG_MOVED_PROPERTY"
|
|
5
|
+
/**
|
|
6
|
+
* A key only the root may hold, written in `application`, `client` or `agent`: a field's
|
|
7
|
+
* `definition` is the root's, and an overlay only chooses its visibility.
|
|
8
|
+
*/
|
|
9
|
+
| "CONFIG_FORBIDDEN_IN_OVERLAY";
|
|
3
10
|
/** One problem found in a configuration, at its path. */
|
|
4
|
-
export type
|
|
5
|
-
readonly code:
|
|
11
|
+
export type AvConfigDiagnostic = {
|
|
12
|
+
readonly code: AvConfigDiagnosticCode;
|
|
6
13
|
readonly path: string;
|
|
7
14
|
readonly message: string;
|
|
8
15
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ErrorCodeDescription } from "../runtime/error-guidance.js";
|
|
2
|
+
import type { AvConfigDiagnosticCode } from "./config-diagnostic.js";
|
|
3
|
+
/** Meaning, cause and fix of every configuration diagnostic code. */
|
|
4
|
+
export declare const CONFIG_DIAGNOSTIC_GUIDANCE: {
|
|
5
|
+
readonly [C in AvConfigDiagnosticCode]: ErrorCodeDescription;
|
|
6
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const CONFIG_DIAGNOSTIC_GUIDANCE = {
|
|
2
|
+
CONFIG_REQUIRED: {
|
|
3
|
+
message: "A required configuration key is missing.",
|
|
4
|
+
cause: "A key that must be present is absent: api, adapter, or an overlay's exposed when the overlay sets exemptions.",
|
|
5
|
+
fix: "Add the key at the diagnostic's path.",
|
|
6
|
+
},
|
|
7
|
+
CONFIG_UNKNOWN_PROPERTY: {
|
|
8
|
+
message: "Unknown configuration key.",
|
|
9
|
+
cause: "A key the configuration does not define at that place: a typo, or a key written at the wrong level of the tree.",
|
|
10
|
+
fix: 'Remove it, or move it where it belongs (the configuration reference\'s "Where a key can go").',
|
|
11
|
+
},
|
|
12
|
+
CONFIG_INVALID_TYPE: {
|
|
13
|
+
message: "A configuration key has the wrong type.",
|
|
14
|
+
cause: "A value of the wrong type, or a key set to an explicit undefined.",
|
|
15
|
+
fix: "Give the value the type the reference states; leave a key out rather than setting it to undefined.",
|
|
16
|
+
},
|
|
17
|
+
CONFIG_INVALID_VALUE: {
|
|
18
|
+
message: "A configuration value is not allowed.",
|
|
19
|
+
cause: 'A malformed api or mcp path, a negative limit, an unknown transactionsStyle, a format that is not a named zod format, or forceTransaction under an effective transactionsStyle "none".',
|
|
20
|
+
fix: "Use a value the message allows.",
|
|
21
|
+
},
|
|
22
|
+
CONFIG_MOVED_PROPERTY: {
|
|
23
|
+
message: "A configuration key moved in rc.1.",
|
|
24
|
+
cause: "Configuration written for 1.0.0-rc.0: restrictions, entrypoint, fields, behaviors, transactions or pipelines.before/after.",
|
|
25
|
+
fix: "Move it where the message says: restrictions to exposed + exemptions, entrypoint to api, fields to `resources.<R>.fields.<f>.definition`, transactions to transactionsStyle, before/after to pipelines.hooks.",
|
|
26
|
+
},
|
|
27
|
+
CONFIG_FORBIDDEN_IN_OVERLAY: {
|
|
28
|
+
message: "A root-only key is written in an overlay.",
|
|
29
|
+
cause: "A field definition in application, client or agent.",
|
|
30
|
+
fix: "Define the field once at the root (`resources.<R>.fields.<f>.definition`); an overlay only chooses its visibility.",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One layer of the configuration: `root` is the configuration's own top level
|
|
3
3
|
* and compiles to the Core Contract; `application` and `client` are overlays
|
|
4
|
-
* on top of it and compile to the Application and Client Contracts
|
|
4
|
+
* on top of it and compile to the Application and Client Contracts; `agent`
|
|
5
|
+
* narrows the layer it extends and compiles to the Agent Contract.
|
|
5
6
|
*/
|
|
6
|
-
export type
|
|
7
|
+
export type AvConfigLayerName = "root" | "application" | "client" | "agent";
|
|
7
8
|
/**
|
|
8
|
-
* The layers a request can come from: `application` (in-process calls)
|
|
9
|
-
* `client` (remote calls)
|
|
10
|
-
*
|
|
9
|
+
* The layers a request can come from: `application` (in-process calls),
|
|
10
|
+
* `client` (remote calls) or `agent` (calls an AI agent makes over MCP). Each
|
|
11
|
+
* sees the root configuration plus its own layer, and `agent` the layer it
|
|
12
|
+
* extends between the two.
|
|
11
13
|
*/
|
|
12
|
-
export type
|
|
14
|
+
export type AvRequestOrigin = Exclude<AvConfigLayerName, "root">;
|
|
15
|
+
/**
|
|
16
|
+
* The layer the `agent` layer starts from (its `extends`): its final view is
|
|
17
|
+
* the agent's parent, and its pipelines run before the agent's.
|
|
18
|
+
*/
|
|
19
|
+
export type AvConfigAgentParent = Exclude<AvConfigLayerName, "agent">;
|
|
20
|
+
/** The origins whose requests carry a protocol identity: remote callers. */
|
|
21
|
+
export type RemoteRequestOrigin = Exclude<AvRequestOrigin, "application">;
|
|
@@ -1,38 +1,81 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
-
import
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
10
|
-
import type
|
|
11
|
-
/**
|
|
12
|
-
export type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
readonly
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import type { AvAdapter } from "../adapters/adapter.interface.js";
|
|
2
|
+
import type { AvAdapterModel } from "../adapters/adapter-model.js";
|
|
3
|
+
import type { AvTransactionCapability } from "../contracts/transaction-capability.js";
|
|
4
|
+
import type { AvDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
|
|
5
|
+
import type { AvMisuseSink } from "../runtime/misuse-reporter.js";
|
|
6
|
+
import type { AvConfigAgentParent } from "./config-layer.js";
|
|
7
|
+
import { type ResolvedComputeConfig } from "./field-compute.resolver.js";
|
|
8
|
+
import type { AvConfig, AvConfigLimits } from "./framework-config.js";
|
|
9
|
+
import type { AvConfigFieldDefinition } from "./framework-field-definition.js";
|
|
10
|
+
import { type ResolvedPipelineTree } from "./pipeline-tree.resolver.js";
|
|
11
|
+
/** The root's field definitions, by Resource and field name. */
|
|
12
|
+
export type ResolvedFieldDefinitions = Readonly<Record<string, Readonly<Record<string, AvConfigFieldDefinition>>>>;
|
|
13
|
+
/** One resolved layer of the configuration: root, application, client or agent. */
|
|
14
|
+
export type ResolvedFrameworkLayerConfig = {
|
|
15
|
+
/** The compute stages that run for this layer's operations, chained root first. */
|
|
16
|
+
readonly compute: ResolvedComputeConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Whether this layer's exemptions hide (`true`, the root's default) or grant
|
|
19
|
+
* (`false`); `undefined` for an overlay that states none, which keeps the
|
|
20
|
+
* root's view.
|
|
21
|
+
*/
|
|
22
|
+
readonly exposed: boolean | undefined;
|
|
23
|
+
/** This layer's own `exemptions`, as authored; the compiler checks every name. */
|
|
24
|
+
readonly exemptions: unknown;
|
|
25
|
+
readonly limits: AvConfigLimits | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Every stage that runs for this layer's operations, level by level: the root's
|
|
28
|
+
* registrations, then the overlay's, at each level.
|
|
29
|
+
*/
|
|
30
|
+
readonly pipelines: ResolvedPipelineTree;
|
|
31
|
+
readonly transactionsStyle: AvTransactionCapability | undefined;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The MCP endpoint a Framework serves (`mcp` resolved): its mount path in
|
|
35
|
+
* canonical form, and the authorization its callers present, when it has one.
|
|
36
|
+
*/
|
|
37
|
+
export type AvMcpEndpoint = {
|
|
38
|
+
/** The mount path in its canonical form, as `framework.api` is. */
|
|
39
|
+
readonly path: string;
|
|
40
|
+
readonly authorization?: {
|
|
41
|
+
readonly servers: readonly string[];
|
|
42
|
+
readonly verify: (token: string) => unknown | null | Promise<unknown | null>;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/** The agent layer resolved: a layer, and the layer it extends. */
|
|
46
|
+
export type ResolvedAgentLayerConfig = ResolvedFrameworkLayerConfig & {
|
|
47
|
+
/** The layer whose final view the agent narrows (`extends`; `"client"` when left out). */
|
|
48
|
+
readonly parent: AvConfigAgentParent;
|
|
49
|
+
/** Whether the configuration states `agent` or `mcp`. */
|
|
50
|
+
readonly stated: boolean;
|
|
20
51
|
};
|
|
21
52
|
/** A configuration after defaults and overlays are resolved, before compilation. */
|
|
22
|
-
export type ResolvedFrameworkConfig<M extends
|
|
53
|
+
export type ResolvedFrameworkConfig<M extends AvAdapterModel = AvAdapterModel> = {
|
|
23
54
|
/**
|
|
24
|
-
* The mount path in its canonical form: `""` at the
|
|
25
|
-
* `/seg(/seg)*`.
|
|
55
|
+
* The protocol's mount path (`api`) in its canonical form: `""` at the
|
|
56
|
+
* root, otherwise `/seg(/seg)*`.
|
|
26
57
|
*/
|
|
27
|
-
readonly
|
|
28
|
-
|
|
58
|
+
readonly api: string;
|
|
59
|
+
/** The MCP endpoint, when `mcp` turns it on. */
|
|
60
|
+
readonly mcp: AvMcpEndpoint | undefined;
|
|
61
|
+
readonly adapter: AvAdapter<M>;
|
|
29
62
|
/** The diagnostics sink, from the root configuration only. */
|
|
30
|
-
readonly diagnostics:
|
|
63
|
+
readonly diagnostics: AvDiagnosticsSink | undefined;
|
|
31
64
|
/** The misuse sink, from the root configuration only. */
|
|
32
|
-
readonly misuse:
|
|
33
|
-
|
|
34
|
-
readonly
|
|
35
|
-
|
|
65
|
+
readonly misuse: AvMisuseSink | undefined;
|
|
66
|
+
/** Every field definition, from the root only; the same for all three layers. */
|
|
67
|
+
readonly definitions: ResolvedFieldDefinitions;
|
|
68
|
+
/** Each layer's `resources` tree as authored: the compiler checks its names. */
|
|
69
|
+
readonly trees: {
|
|
70
|
+
readonly root: unknown;
|
|
71
|
+
readonly application: unknown;
|
|
72
|
+
readonly client: unknown;
|
|
73
|
+
readonly agent: unknown;
|
|
74
|
+
};
|
|
75
|
+
readonly root: ResolvedFrameworkLayerConfig;
|
|
76
|
+
readonly application: ResolvedFrameworkLayerConfig;
|
|
77
|
+
readonly client: ResolvedFrameworkLayerConfig;
|
|
78
|
+
readonly agent: ResolvedAgentLayerConfig;
|
|
36
79
|
};
|
|
37
|
-
/** Resolve
|
|
38
|
-
export declare function resolveFrameworkConfig<M extends
|
|
80
|
+
/** Resolve every layer of the configuration without compiling Contracts. */
|
|
81
|
+
export declare function resolveFrameworkConfig<M extends AvAdapterModel>(config: AvConfig<M>): ResolvedFrameworkConfig<M>;
|