@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
|
|
1
|
+
import { FILTER_MODES, PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
|
|
2
2
|
import { AVENTARA_PROTOCOL_VERSION } from "./contract-protocol.js";
|
|
3
3
|
import { LIFECYCLE_TRAITS } from "./lifecycle-trait.js";
|
|
4
4
|
import { REFERENCE_WRITE_LIMITS } from "./reference-write-limit.js";
|
|
@@ -10,13 +10,16 @@ function literal(values) {
|
|
|
10
10
|
return { is: "literal", values };
|
|
11
11
|
}
|
|
12
12
|
function list(item) {
|
|
13
|
-
return { is: "list", item,
|
|
13
|
+
return { is: "list", item, minimum: 0, unique: false };
|
|
14
14
|
}
|
|
15
15
|
function nonEmptyList(item) {
|
|
16
|
-
return { is: "list", item,
|
|
16
|
+
return { is: "list", item, minimum: 1, unique: false };
|
|
17
|
+
}
|
|
18
|
+
function pairOrMoreList(item) {
|
|
19
|
+
return { is: "list", item, minimum: 2, unique: false };
|
|
17
20
|
}
|
|
18
21
|
function uniqueList(item) {
|
|
19
|
-
return { is: "list", item,
|
|
22
|
+
return { is: "list", item, minimum: 0, unique: true };
|
|
20
23
|
}
|
|
21
24
|
function registry(entry) {
|
|
22
25
|
return { is: "registry", entry };
|
|
@@ -93,6 +96,127 @@ const RELATION_MUTATION = union(list(literal(RELATION_MUTATION_DIRECTIVES)), obj
|
|
|
93
96
|
directives: list(literal(RELATION_MUTATION_DIRECTIVES)),
|
|
94
97
|
scopes: WRITE_SCOPE_LIST,
|
|
95
98
|
}));
|
|
99
|
+
const NAMED_FORMATS = [
|
|
100
|
+
"lowercase",
|
|
101
|
+
"uppercase",
|
|
102
|
+
"email",
|
|
103
|
+
"url",
|
|
104
|
+
"emoji",
|
|
105
|
+
"uuid",
|
|
106
|
+
"guid",
|
|
107
|
+
"nanoid",
|
|
108
|
+
"cuid",
|
|
109
|
+
"cuid2",
|
|
110
|
+
"ulid",
|
|
111
|
+
"xid",
|
|
112
|
+
"ksuid",
|
|
113
|
+
"datetime",
|
|
114
|
+
"date",
|
|
115
|
+
"time",
|
|
116
|
+
"duration",
|
|
117
|
+
"ipv4",
|
|
118
|
+
"ipv6",
|
|
119
|
+
"cidrv4",
|
|
120
|
+
"cidrv6",
|
|
121
|
+
"base64",
|
|
122
|
+
"base64url",
|
|
123
|
+
"json_string",
|
|
124
|
+
"e164",
|
|
125
|
+
"credit_card",
|
|
126
|
+
"iban",
|
|
127
|
+
"jwt",
|
|
128
|
+
];
|
|
129
|
+
const STRING_FORMAT_CHECK = union(object({
|
|
130
|
+
check: literal(["string_format"]),
|
|
131
|
+
format: literal(["regex"]),
|
|
132
|
+
pattern: object({ source: STRING, flags: STRING }),
|
|
133
|
+
}), object({
|
|
134
|
+
check: literal(["string_format"]),
|
|
135
|
+
format: literal(["includes"]),
|
|
136
|
+
includes: STRING,
|
|
137
|
+
}), object({
|
|
138
|
+
check: literal(["string_format"]),
|
|
139
|
+
format: literal(["starts_with"]),
|
|
140
|
+
prefix: STRING,
|
|
141
|
+
}), object({
|
|
142
|
+
check: literal(["string_format"]),
|
|
143
|
+
format: literal(["ends_with"]),
|
|
144
|
+
suffix: STRING,
|
|
145
|
+
}), object({
|
|
146
|
+
check: literal(["string_format"]),
|
|
147
|
+
format: literal(NAMED_FORMATS),
|
|
148
|
+
}));
|
|
149
|
+
const STRING_LENGTH_CHECKS = {
|
|
150
|
+
max_length: object({ check: literal(["max_length"]), maximum: NUMBER }),
|
|
151
|
+
min_length: object({ check: literal(["min_length"]), minimum: NUMBER }),
|
|
152
|
+
length_equals: object({ check: literal(["length_equals"]), length: NUMBER }),
|
|
153
|
+
string_format: STRING_FORMAT_CHECK,
|
|
154
|
+
};
|
|
155
|
+
const FIELD_CHECK = {
|
|
156
|
+
is: "variants",
|
|
157
|
+
key: "check",
|
|
158
|
+
arms: {
|
|
159
|
+
less_than: object({
|
|
160
|
+
check: literal(["less_than"]),
|
|
161
|
+
value: union(NUMBER, STRING),
|
|
162
|
+
inclusive: BOOLEAN,
|
|
163
|
+
}),
|
|
164
|
+
greater_than: object({
|
|
165
|
+
check: literal(["greater_than"]),
|
|
166
|
+
value: union(NUMBER, STRING),
|
|
167
|
+
inclusive: BOOLEAN,
|
|
168
|
+
}),
|
|
169
|
+
multiple_of: object({
|
|
170
|
+
check: literal(["multiple_of"]),
|
|
171
|
+
value: union(NUMBER, STRING),
|
|
172
|
+
}),
|
|
173
|
+
max_length: object({ check: literal(["max_length"]), maximum: NUMBER }, { list: literal([true]) }),
|
|
174
|
+
min_length: object({ check: literal(["min_length"]), minimum: NUMBER }, { list: literal([true]) }),
|
|
175
|
+
length_equals: STRING_LENGTH_CHECKS.length_equals,
|
|
176
|
+
string_format: STRING_FORMAT_CHECK,
|
|
177
|
+
max_size: object({ check: literal(["max_size"]), maximum: NUMBER }),
|
|
178
|
+
min_size: object({ check: literal(["min_size"]), minimum: NUMBER }),
|
|
179
|
+
size_equals: object({ check: literal(["size_equals"]), size: NUMBER }),
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
const JSON_STRING_CHECK = {
|
|
183
|
+
is: "variants",
|
|
184
|
+
key: "check",
|
|
185
|
+
arms: STRING_LENGTH_CHECKS,
|
|
186
|
+
};
|
|
187
|
+
const JSON_NUMBER_CHECK = {
|
|
188
|
+
is: "variants",
|
|
189
|
+
key: "check",
|
|
190
|
+
arms: {
|
|
191
|
+
less_than: object({
|
|
192
|
+
check: literal(["less_than"]),
|
|
193
|
+
value: NUMBER,
|
|
194
|
+
inclusive: BOOLEAN,
|
|
195
|
+
}),
|
|
196
|
+
greater_than: object({
|
|
197
|
+
check: literal(["greater_than"]),
|
|
198
|
+
value: NUMBER,
|
|
199
|
+
inclusive: BOOLEAN,
|
|
200
|
+
}),
|
|
201
|
+
multiple_of: object({ check: literal(["multiple_of"]), value: NUMBER }),
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
const JSON_LIST_CHECK = {
|
|
205
|
+
is: "variants",
|
|
206
|
+
key: "check",
|
|
207
|
+
arms: {
|
|
208
|
+
max_length: object({
|
|
209
|
+
check: literal(["max_length"]),
|
|
210
|
+
maximum: NUMBER,
|
|
211
|
+
list: literal([true]),
|
|
212
|
+
}),
|
|
213
|
+
min_length: object({
|
|
214
|
+
check: literal(["min_length"]),
|
|
215
|
+
minimum: NUMBER,
|
|
216
|
+
list: literal([true]),
|
|
217
|
+
}),
|
|
218
|
+
},
|
|
219
|
+
};
|
|
96
220
|
const SCALAR_FIELD = object({
|
|
97
221
|
kind: literal(["scalar"]),
|
|
98
222
|
type: union(object({ scalar: STRING }), object({ enum: STRING })),
|
|
@@ -102,12 +226,18 @@ const SCALAR_FIELD = object({
|
|
|
102
226
|
capabilities: object({}, {
|
|
103
227
|
select: BOOLEAN,
|
|
104
228
|
filter: list(literal(SCALAR_FILTER_OPERATORS)),
|
|
229
|
+
filterModes: list(literal(FILTER_MODES)),
|
|
230
|
+
pathFilterModes: list(literal(FILTER_MODES)),
|
|
105
231
|
order: BOOLEAN,
|
|
106
232
|
orderNulls: BOOLEAN,
|
|
107
233
|
create: list(literal(SCALAR_MUTATION_DIRECTIVES)),
|
|
108
234
|
update: list(literal(SCALAR_MUTATION_DIRECTIVES)),
|
|
109
235
|
}),
|
|
110
|
-
}, {
|
|
236
|
+
}, {
|
|
237
|
+
format: STRING,
|
|
238
|
+
json: { is: "jsonSchema" },
|
|
239
|
+
validators: list(FIELD_CHECK),
|
|
240
|
+
});
|
|
111
241
|
const RELATION_FIELD = object({
|
|
112
242
|
kind: literal(["relation"]),
|
|
113
243
|
target: STRING,
|
|
@@ -127,7 +257,7 @@ const RELATION_FIELD = object({
|
|
|
127
257
|
update: RELATION_MUTATION,
|
|
128
258
|
nestedWriteFilter: literal(["scalar"]),
|
|
129
259
|
}),
|
|
130
|
-
});
|
|
260
|
+
}, { inverse: STRING, referenceFields: nonEmptyList(STRING) });
|
|
131
261
|
const OPERATION_AVAILABILITY = union(literal([true]), object({ projection: literal(PROJECTION_SCOPES) }, { write: literal(WRITE_SCOPES) }), object({ write: literal(WRITE_SCOPES) }, { projection: literal(PROJECTION_SCOPES) }));
|
|
132
262
|
const RESOURCE = object({
|
|
133
263
|
fields: registry({
|
|
@@ -162,6 +292,12 @@ const RESOURCE = object({
|
|
|
162
292
|
}),
|
|
163
293
|
upsert: object({}, { unique: OPERATION_AVAILABILITY }),
|
|
164
294
|
}),
|
|
295
|
+
}, {
|
|
296
|
+
createRequirements: object({}, {
|
|
297
|
+
required: nonEmptyList(STRING),
|
|
298
|
+
oneOf: nonEmptyList(pairOrMoreList(STRING)),
|
|
299
|
+
parentSupplies: registry(registry(nonEmptyList(STRING))),
|
|
300
|
+
}),
|
|
165
301
|
});
|
|
166
302
|
export const CLIENT_CONTRACT_STRUCTURE = object({
|
|
167
303
|
scalars: registry(object({ builtin: literal([true]) })),
|
|
@@ -173,6 +309,7 @@ export const CLIENT_CONTRACT_STRUCTURE = object({
|
|
|
173
309
|
maxListLimit: NUMBER,
|
|
174
310
|
maxTransactionOperations: NUMBER,
|
|
175
311
|
maxBooleanNodes: NUMBER,
|
|
312
|
+
maxJsonDepth: NUMBER,
|
|
176
313
|
}),
|
|
177
314
|
transactions: literal(TRANSACTION_CAPABILITIES),
|
|
178
315
|
protocol: object({
|
|
@@ -272,13 +409,20 @@ function jsonSchemaDefect(value, path, depth) {
|
|
|
272
409
|
switch (keys) {
|
|
273
410
|
case "type":
|
|
274
411
|
return literalDefect(JSON_SCHEMA_SCALAR_TYPES, schema.type, `${path}.type`, depth + 1);
|
|
412
|
+
case "checks,type":
|
|
413
|
+
return (literalDefect(["string", "number", "integer"], schema.type, `${path}.type`, depth + 1) ??
|
|
414
|
+
defectOf(list(schema.type === "string" ? JSON_STRING_CHECK : JSON_NUMBER_CHECK), schema.checks, `${path}.checks`, depth + 1));
|
|
415
|
+
case "checks,items,type":
|
|
416
|
+
return (literalDefect(["array"], schema.type, `${path}.type`, depth + 1) ??
|
|
417
|
+
child("items", schema.items) ??
|
|
418
|
+
defectOf(list(JSON_LIST_CHECK), schema.checks, `${path}.checks`, depth + 1));
|
|
275
419
|
case "const":
|
|
276
420
|
return Object.is(schema.const, null)
|
|
277
421
|
? undefined
|
|
278
422
|
: defectOf(JSON_PRIMITIVE, schema.const, `${path}.const`, depth + 1);
|
|
279
423
|
case "enum,type":
|
|
280
424
|
return (literalDefect(["string"], schema.type, `${path}.type`, depth + 1) ??
|
|
281
|
-
defectOf({ is: "list", item: STRING,
|
|
425
|
+
defectOf({ is: "list", item: STRING, minimum: 1, unique: true }, schema.enum, `${path}.enum`, depth + 1));
|
|
282
426
|
case "additionalProperties,properties,type":
|
|
283
427
|
case "additionalProperties,properties,required,type": {
|
|
284
428
|
const typeDefect = literalDefect(["object"], schema.type, `${path}.type`, depth + 1) ??
|
|
@@ -296,7 +440,7 @@ function jsonSchemaDefect(value, path, depth) {
|
|
|
296
440
|
}
|
|
297
441
|
if (!Object.hasOwn(schema, "required"))
|
|
298
442
|
return undefined;
|
|
299
|
-
const requiredDefect = defectOf({ is: "list", item: STRING,
|
|
443
|
+
const requiredDefect = defectOf({ is: "list", item: STRING, minimum: 0, unique: true }, schema.required, `${path}.required`, depth + 1);
|
|
300
444
|
if (requiredDefect !== undefined)
|
|
301
445
|
return requiredDefect;
|
|
302
446
|
const undeclared = schema.required.findIndex((name) => !Object.hasOwn(properties, name));
|
|
@@ -348,8 +492,10 @@ function listDefect(node, value, path, depth) {
|
|
|
348
492
|
if (kind !== undefined)
|
|
349
493
|
return kind;
|
|
350
494
|
const entries = value;
|
|
351
|
-
if (
|
|
352
|
-
return at(path, depth,
|
|
495
|
+
if (entries.length < node.minimum) {
|
|
496
|
+
return at(path, depth, entries.length === 0
|
|
497
|
+
? `is an empty JSON array, and needs at least ${node.minimum === 1 ? "one entry" : "two entries"}`
|
|
498
|
+
: "is a JSON array of one entry, and needs at least two");
|
|
353
499
|
}
|
|
354
500
|
const firstIndexOf = new Map();
|
|
355
501
|
for (let index = 0; index < entries.length; index += 1) {
|
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AvContract } from "./contract.js";
|
|
2
2
|
/**
|
|
3
3
|
* Thrown when a value cannot be written as canonical JSON (RFC 8785). It is a
|
|
4
4
|
* `TypeError`.
|
|
5
5
|
*/
|
|
6
|
-
export declare class
|
|
6
|
+
export declare class AvCanonicalJsonError extends TypeError {
|
|
7
7
|
}
|
|
8
8
|
/** Canonical JSON (RFC 8785) for a JSON-safe value. */
|
|
9
9
|
export declare function canonicalizeJson(value: unknown): string;
|
|
10
|
+
/**
|
|
11
|
+
* Canonical JSON (RFC 8785) for a value as JSON carries it: a key holding
|
|
12
|
+
* `undefined` is left out, and an array element holding it (or a hole) is
|
|
13
|
+
* `null`, as `JSON.stringify` writes them. Everything else as
|
|
14
|
+
* {@link canonicalizeJson}.
|
|
15
|
+
*/
|
|
16
|
+
export declare function canonicalizeWireJson(value: unknown): string;
|
|
17
|
+
/** One top-level member of a canonical Contract: its key and its value's canonical text. */
|
|
18
|
+
export type CanonicalContractMember = {
|
|
19
|
+
readonly key: string;
|
|
20
|
+
readonly text: string;
|
|
21
|
+
};
|
|
22
|
+
/** The Contract as canonical JSON (RFC 8785), one top-level member at a time, in order. */
|
|
23
|
+
export declare function canonicalizeContractMembers<C extends AvContract>(contract: C): readonly CanonicalContractMember[];
|
|
24
|
+
/** The canonical object text the members write: `{"key":text,…}`, in their order. */
|
|
25
|
+
export declare function joinCanonicalContractMembers(members: readonly CanonicalContractMember[]): string;
|
|
10
26
|
/** The Contract as canonical JSON (RFC 8785): the same bytes for the same Contract. */
|
|
11
|
-
export declare function canonicalizeContract<C extends
|
|
27
|
+
export declare function canonicalizeContract<C extends AvContract>(contract: C): string;
|
|
28
|
+
/** Records `text` as the canonical text `contract` was parsed from. */
|
|
29
|
+
export declare function recordCanonicalContractText(contract: AvContract, text: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* The Contract's canonical text: the text it was identified from, when the compiler
|
|
32
|
+
* recorded one, else written now. Both are the same bytes for the same Contract.
|
|
33
|
+
*/
|
|
34
|
+
export declare function canonicalContractTextOf<C extends AvContract>(contract: C): string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
|
|
1
|
+
import { FILTER_MODES, PROJECTION_SCOPES, WRITE_SCOPES } from "./capability.js";
|
|
2
2
|
import { LIFECYCLE_TRAITS } from "./lifecycle-trait.js";
|
|
3
3
|
import { projectionScopeOf, writeScopeOf } from "./resource-operations.js";
|
|
4
4
|
const PAGINATION_ORDER = ["limit", "offset", "cursor"];
|
|
5
5
|
const REDUCER_ORDER = ["$count"];
|
|
6
|
-
export class
|
|
6
|
+
export class AvCanonicalJsonError extends TypeError {
|
|
7
7
|
}
|
|
8
8
|
function compareCodeUnits(left, right) {
|
|
9
9
|
if (left === right) {
|
|
@@ -61,6 +61,12 @@ function normalizeCapabilities(capabilities) {
|
|
|
61
61
|
if (Array.isArray(filter)) {
|
|
62
62
|
normalized.filter = normalizeStringSet(filter);
|
|
63
63
|
}
|
|
64
|
+
for (const key of ["filterModes", "pathFilterModes"]) {
|
|
65
|
+
const modes = normalized[key];
|
|
66
|
+
if (Array.isArray(modes)) {
|
|
67
|
+
normalized[key] = normalizeStringSet(modes, FILTER_MODES);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
64
70
|
for (const key of ["create", "update"]) {
|
|
65
71
|
const value = normalized[key];
|
|
66
72
|
if (Array.isArray(value)) {
|
|
@@ -103,7 +109,7 @@ function normalizeJsonSchema(schema) {
|
|
|
103
109
|
normalizeJsonSchema(child),
|
|
104
110
|
]));
|
|
105
111
|
}
|
|
106
|
-
else if (key === "const" || key === "enum") {
|
|
112
|
+
else if (key === "const" || key === "enum" || key === "checks") {
|
|
107
113
|
normalized[key] = value;
|
|
108
114
|
}
|
|
109
115
|
else {
|
|
@@ -173,8 +179,46 @@ function normalizeResource(resource) {
|
|
|
173
179
|
fields,
|
|
174
180
|
identifiers,
|
|
175
181
|
operations: normalizeOperations(resource.operations),
|
|
182
|
+
...(resource.createRequirements === undefined
|
|
183
|
+
? {}
|
|
184
|
+
: {
|
|
185
|
+
createRequirements: normalizeCreateRequirements(resource.createRequirements),
|
|
186
|
+
}),
|
|
176
187
|
};
|
|
177
188
|
}
|
|
189
|
+
function isJsonObject(value) {
|
|
190
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
191
|
+
}
|
|
192
|
+
function normalizeCreateRequirements(requirements) {
|
|
193
|
+
if (!isJsonObject(requirements)) {
|
|
194
|
+
return requirements;
|
|
195
|
+
}
|
|
196
|
+
const normalized = { ...requirements };
|
|
197
|
+
if (Array.isArray(requirements.required)) {
|
|
198
|
+
normalized.required = normalizeStringSet(requirements.required);
|
|
199
|
+
}
|
|
200
|
+
if (Array.isArray(requirements.oneOf)) {
|
|
201
|
+
normalized.oneOf = requirements.oneOf
|
|
202
|
+
.map((group) => Array.isArray(group) && group.length > 0
|
|
203
|
+
? [group[0], ...normalizeStringSet(group.slice(1))]
|
|
204
|
+
: group)
|
|
205
|
+
.sort((left, right) => compareCodeUnits(canonicalizeJson(left), canonicalizeJson(right)));
|
|
206
|
+
}
|
|
207
|
+
if (isJsonObject(requirements.parentSupplies)) {
|
|
208
|
+
normalized.parentSupplies = Object.fromEntries(Object.entries(requirements.parentSupplies).map(([parent, byRelation]) => [
|
|
209
|
+
parent,
|
|
210
|
+
isJsonObject(byRelation)
|
|
211
|
+
? Object.fromEntries(Object.entries(byRelation).map(([relation, members]) => [
|
|
212
|
+
relation,
|
|
213
|
+
Array.isArray(members)
|
|
214
|
+
? normalizeStringSet(members)
|
|
215
|
+
: members,
|
|
216
|
+
]))
|
|
217
|
+
: byRelation,
|
|
218
|
+
]));
|
|
219
|
+
}
|
|
220
|
+
return normalized;
|
|
221
|
+
}
|
|
178
222
|
function normalizeContract(contract) {
|
|
179
223
|
const scalars = Object.fromEntries(Object.keys(contract.scalars)
|
|
180
224
|
.sort(compareCodeUnits)
|
|
@@ -201,17 +245,24 @@ function assertValidUnicode(value, path) {
|
|
|
201
245
|
if (code >= 0xd800 && code <= 0xdbff) {
|
|
202
246
|
const next = value.charCodeAt(index + 1);
|
|
203
247
|
if (!(next >= 0xdc00 && next <= 0xdfff)) {
|
|
204
|
-
throw new
|
|
248
|
+
throw new AvCanonicalJsonError(`invalid Unicode surrogate at ${path()}`);
|
|
205
249
|
}
|
|
206
250
|
index += 1;
|
|
207
251
|
continue;
|
|
208
252
|
}
|
|
209
253
|
if (code >= 0xdc00 && code <= 0xdfff) {
|
|
210
|
-
throw new
|
|
254
|
+
throw new AvCanonicalJsonError(`invalid Unicode surrogate at ${path()}`);
|
|
211
255
|
}
|
|
212
256
|
}
|
|
213
257
|
}
|
|
214
|
-
function
|
|
258
|
+
function pathOf(link) {
|
|
259
|
+
const segments = [];
|
|
260
|
+
for (let current = link; current !== undefined; current = current.parent) {
|
|
261
|
+
segments.push(current.segment);
|
|
262
|
+
}
|
|
263
|
+
return `$${segments.reverse().join("")}`;
|
|
264
|
+
}
|
|
265
|
+
function canonicalizePrimitive(value, link) {
|
|
215
266
|
if (value === null) {
|
|
216
267
|
return "null";
|
|
217
268
|
}
|
|
@@ -220,47 +271,123 @@ function canonicalizeValue(value, path) {
|
|
|
220
271
|
return value ? "true" : "false";
|
|
221
272
|
case "number": {
|
|
222
273
|
if (!Number.isFinite(value)) {
|
|
223
|
-
throw new
|
|
274
|
+
throw new AvCanonicalJsonError(`non-finite number at ${pathOf(link)}`);
|
|
224
275
|
}
|
|
225
276
|
const serialized = JSON.stringify(value);
|
|
226
277
|
if (serialized === undefined) {
|
|
227
|
-
throw new
|
|
278
|
+
throw new AvCanonicalJsonError(`number at ${pathOf(link)} is not JSON serializable`);
|
|
228
279
|
}
|
|
229
280
|
return serialized;
|
|
230
281
|
}
|
|
231
282
|
case "string":
|
|
232
|
-
assertValidUnicode(value,
|
|
283
|
+
assertValidUnicode(value, () => pathOf(link));
|
|
233
284
|
return JSON.stringify(value);
|
|
234
285
|
case "undefined":
|
|
235
|
-
throw new
|
|
286
|
+
throw new AvCanonicalJsonError(`undefined value at ${pathOf(link)}`);
|
|
236
287
|
case "bigint":
|
|
237
288
|
case "function":
|
|
238
289
|
case "symbol":
|
|
239
|
-
throw new
|
|
240
|
-
|
|
241
|
-
|
|
290
|
+
throw new AvCanonicalJsonError(`${typeof value} value at ${pathOf(link)} is not JSON serializable`);
|
|
291
|
+
default:
|
|
292
|
+
return undefined;
|
|
242
293
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
294
|
+
}
|
|
295
|
+
function canonicalizeValue(value, link = undefined, undefinedAsJson = false) {
|
|
296
|
+
const output = [];
|
|
297
|
+
const stack = [{ kind: "value", value, link }];
|
|
298
|
+
while (stack.length > 0) {
|
|
299
|
+
const task = stack.pop();
|
|
300
|
+
if (task.kind === "text") {
|
|
301
|
+
output.push(task.text);
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (task.kind === "key") {
|
|
305
|
+
assertValidUnicode(task.key, () => `${pathOf(task.link)} key`);
|
|
306
|
+
output.push(`${JSON.stringify(task.key)}:`);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const { value: current, link } = task;
|
|
310
|
+
const primitive = canonicalizePrimitive(current, link);
|
|
311
|
+
if (primitive !== undefined) {
|
|
312
|
+
output.push(primitive);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (Array.isArray(current)) {
|
|
316
|
+
output.push("[");
|
|
317
|
+
stack.push({ kind: "text", text: "]" });
|
|
318
|
+
for (let index = current.length - 1; index >= 0; index -= 1) {
|
|
319
|
+
if (undefinedAsJson && current[index] === undefined) {
|
|
320
|
+
stack.push({ kind: "text", text: "null" });
|
|
321
|
+
}
|
|
322
|
+
else if (index in current) {
|
|
323
|
+
stack.push({
|
|
324
|
+
kind: "value",
|
|
325
|
+
value: current[index],
|
|
326
|
+
link: { parent: link, segment: `[${index}]` },
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
if (index > 0) {
|
|
330
|
+
stack.push({ kind: "text", text: "," });
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const prototype = Object.getPrototypeOf(current);
|
|
336
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
337
|
+
throw new AvCanonicalJsonError(`non-plain object at ${pathOf(link)} is not canonical JSON`);
|
|
338
|
+
}
|
|
339
|
+
const record = current;
|
|
340
|
+
const keys = Object.keys(record)
|
|
341
|
+
.filter((key) => !undefinedAsJson || record[key] !== undefined)
|
|
342
|
+
.sort(compareCodeUnits);
|
|
343
|
+
output.push("{");
|
|
344
|
+
stack.push({ kind: "text", text: "}" });
|
|
345
|
+
for (let index = keys.length - 1; index >= 0; index -= 1) {
|
|
346
|
+
const key = keys[index];
|
|
347
|
+
stack.push({
|
|
348
|
+
kind: "value",
|
|
349
|
+
value: record[key],
|
|
350
|
+
link: { parent: link, segment: `.${key}` },
|
|
351
|
+
});
|
|
352
|
+
stack.push({ kind: "key", key, link });
|
|
353
|
+
if (index > 0) {
|
|
354
|
+
stack.push({ kind: "text", text: "," });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
251
357
|
}
|
|
252
|
-
|
|
253
|
-
|
|
358
|
+
return output.join("");
|
|
359
|
+
}
|
|
360
|
+
export function canonicalizeJson(value) {
|
|
361
|
+
return canonicalizeValue(value);
|
|
362
|
+
}
|
|
363
|
+
export function canonicalizeWireJson(value) {
|
|
364
|
+
return canonicalizeValue(value, undefined, true);
|
|
365
|
+
}
|
|
366
|
+
export function canonicalizeContractMembers(contract) {
|
|
367
|
+
const record = normalizeContract(contract);
|
|
368
|
+
return Object.keys(record)
|
|
254
369
|
.sort(compareCodeUnits)
|
|
255
370
|
.map((key) => {
|
|
256
|
-
assertValidUnicode(key,
|
|
257
|
-
return
|
|
371
|
+
assertValidUnicode(key, () => "$ key");
|
|
372
|
+
return {
|
|
373
|
+
key,
|
|
374
|
+
text: canonicalizeValue(record[key], {
|
|
375
|
+
parent: undefined,
|
|
376
|
+
segment: `.${key}`,
|
|
377
|
+
}),
|
|
378
|
+
};
|
|
258
379
|
});
|
|
259
|
-
return `{${entries.join(",")}}`;
|
|
260
380
|
}
|
|
261
|
-
export function
|
|
262
|
-
return
|
|
381
|
+
export function joinCanonicalContractMembers(members) {
|
|
382
|
+
return `{${members.map(({ key, text }) => `${JSON.stringify(key)}:${text}`).join(",")}}`;
|
|
263
383
|
}
|
|
264
384
|
export function canonicalizeContract(contract) {
|
|
265
|
-
return
|
|
385
|
+
return joinCanonicalContractMembers(canonicalizeContractMembers(contract));
|
|
386
|
+
}
|
|
387
|
+
const canonicalTexts = new WeakMap();
|
|
388
|
+
export function recordCanonicalContractText(contract, text) {
|
|
389
|
+
canonicalTexts.set(contract, text);
|
|
390
|
+
}
|
|
391
|
+
export function canonicalContractTextOf(contract) {
|
|
392
|
+
return canonicalTexts.get(contract) ?? canonicalizeContract(contract);
|
|
266
393
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { AvContractClient } from "./contract.js";
|
|
2
|
+
import type { AvContractHash, AvContractProtocol } from "./contract-protocol.js";
|
|
3
3
|
/** A ClientContract whose `protocol` does not carry the hash yet. */
|
|
4
|
-
export type
|
|
5
|
-
readonly protocol:
|
|
4
|
+
export type AvContractClientHashInput = Omit<AvContractClient, "protocol"> & {
|
|
5
|
+
readonly protocol: AvContractProtocol;
|
|
6
6
|
};
|
|
7
|
-
export declare function createClientContractHashInput(contract:
|
|
7
|
+
export declare function createClientContractHashInput(contract: AvContractClient | AvContractClientHashInput): AvContractClientHashInput;
|
|
8
8
|
/** Computes a ClientContract's `sha256:` hash, ignoring `protocol.hash` itself. */
|
|
9
|
-
export declare function computeClientContractHash(contract:
|
|
9
|
+
export declare function computeClientContractHash(contract: AvContractClient | AvContractClientHashInput): Promise<AvContractHash>;
|
|
10
|
+
/**
|
|
11
|
+
* The `sha256:` hash of a hash input's canonical text, already written: what
|
|
12
|
+
* {@link computeClientContractHash} answers for the input that text is of.
|
|
13
|
+
*/
|
|
14
|
+
export declare function hashCanonicalContractText(canonical: string): Promise<AvContractHash>;
|
|
10
15
|
/** Whether a ClientContract's `protocol.hash` matches its content. */
|
|
11
|
-
export declare function verifyClientContractHash(contract:
|
|
16
|
+
export declare function verifyClientContractHash(contract: AvContractClient): Promise<boolean>;
|
|
@@ -10,8 +10,9 @@ function digestHex(digest) {
|
|
|
10
10
|
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
11
11
|
}
|
|
12
12
|
export async function computeClientContractHash(contract) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
return hashCanonicalContractText(canonicalizeContract(createClientContractHashInput(contract)));
|
|
14
|
+
}
|
|
15
|
+
export async function hashCanonicalContractText(canonical) {
|
|
15
16
|
const bytes = new TextEncoder().encode(canonical);
|
|
16
17
|
const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
17
18
|
return `sha256:${digestHex(digest)}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The request limits a Contract enforces. */
|
|
2
|
-
export type
|
|
2
|
+
export type AvContractLimits = {
|
|
3
3
|
/** The largest request body accepted, in bytes. */
|
|
4
4
|
readonly maxRequestBytes: number;
|
|
5
5
|
/** How deeply arguments may nest. */
|
|
@@ -10,6 +10,8 @@ export type ContractLimits = {
|
|
|
10
10
|
readonly maxTransactionOperations: number;
|
|
11
11
|
/** The most boolean and filter nodes one request may hold. */
|
|
12
12
|
readonly maxBooleanNodes: number;
|
|
13
|
+
/** How deeply a `json` field's value may nest: its arrays and objects, counted from the value. */
|
|
14
|
+
readonly maxJsonDepth: number;
|
|
13
15
|
};
|
|
14
16
|
/** The limits in force when the configuration sets none. */
|
|
15
17
|
export declare const DEFAULT_CONTRACT_LIMITS: {
|
|
@@ -18,4 +20,5 @@ export declare const DEFAULT_CONTRACT_LIMITS: {
|
|
|
18
20
|
readonly maxListLimit: 250;
|
|
19
21
|
readonly maxTransactionOperations: 20;
|
|
20
22
|
readonly maxBooleanNodes: 50;
|
|
23
|
+
readonly maxJsonDepth: 64;
|
|
21
24
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type { AvContract } from "./contract.js";
|
|
2
|
+
import type { AvField } from "./field.js";
|
|
3
|
+
import type { AvResource } from "./resource.js";
|
|
4
4
|
/**
|
|
5
5
|
* Own-property lookups over Contract registries.
|
|
6
6
|
*
|
|
@@ -12,5 +12,5 @@ import type { Resource } from "./resource.js";
|
|
|
12
12
|
* must go through here so an unknown key is unknown, whatever its name.
|
|
13
13
|
*/
|
|
14
14
|
export declare function lookupOwn<T>(registry: Readonly<Record<string, T>> | undefined, key: string): T | undefined;
|
|
15
|
-
export declare function lookupResource<C extends
|
|
16
|
-
export declare function lookupField<C extends
|
|
15
|
+
export declare function lookupResource<C extends AvContract>(contract: C, resourceName: string): AvResource<C> | undefined;
|
|
16
|
+
export declare function lookupField<C extends AvContract>(resource: AvResource<C> | undefined, fieldName: string): AvField<C> | undefined;
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export declare const AVENTARA_PROTOCOL_VERSION: 1;
|
|
7
7
|
/** A Contract hash: `sha256:` followed by the hex digest. */
|
|
8
|
-
export type
|
|
8
|
+
export type AvContractHash = `sha256:${string}`;
|
|
9
9
|
/** The protocol a Contract is written for. */
|
|
10
|
-
export type
|
|
10
|
+
export type AvContractProtocol = {
|
|
11
11
|
/** The protocol version; see {@link AVENTARA_PROTOCOL_VERSION}. */
|
|
12
12
|
readonly version: typeof AVENTARA_PROTOCOL_VERSION;
|
|
13
13
|
};
|
|
14
14
|
/** A ClientContract's `protocol`: the protocol version and the Contract hash. */
|
|
15
|
-
export type
|
|
16
|
-
readonly hash:
|
|
15
|
+
export type AvContractClientProtocol = AvContractProtocol & {
|
|
16
|
+
readonly hash: AvContractHash;
|
|
17
17
|
};
|