@astrale-os/kernel-dsl 1.0.0-beta.2 → 1.0.0-beta.20
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/dist/v1/addressing/class-key.js +3 -3
- package/dist/v1/addressing/definition-ref.js +21 -37
- package/dist/v1/addressing/domain-dependency.d.ts +0 -6
- package/dist/v1/addressing/domain-dependency.js +1 -6
- package/dist/v1/addressing/key.d.ts +4 -1
- package/dist/v1/addressing/key.js +23 -3
- package/dist/v1/addressing/ordering.d.ts +2 -0
- package/dist/v1/addressing/ordering.js +4 -0
- package/dist/v1/addressing/patterns.d.ts +1 -1
- package/dist/v1/addressing/patterns.js +2 -6
- package/dist/v1/builder/callable/authoring.d.ts +11 -5
- package/dist/v1/builder/callable/authoring.js +2 -0
- package/dist/v1/builder/class/authoring.d.ts +94 -224
- package/dist/v1/builder/class/authoring.js +31 -33
- package/dist/v1/builder/class/handle.d.ts +27 -0
- package/dist/v1/builder/class/handle.js +1 -0
- package/dist/v1/builder/class/input.d.ts +159 -0
- package/dist/v1/builder/class/projection.d.ts +129 -0
- package/dist/v1/builder/class/projection.js +1 -0
- package/dist/v1/builder/class/property.d.ts +3 -9
- package/dist/v1/builder/class/property.js +1 -0
- package/dist/v1/builder/core/authoring.d.ts +1 -1
- package/dist/v1/builder/index.d.ts +5 -2
- package/dist/v1/builder/lowering/callable.js +1 -0
- package/dist/v1/builder/lowering/class.d.ts +9 -1
- package/dist/v1/builder/lowering/class.js +62 -17
- package/dist/v1/builder/lowering/policy.js +2 -0
- package/dist/v1/builder/lowering/property-keys.d.ts +27 -0
- package/dist/v1/builder/lowering/property-keys.js +108 -0
- package/dist/v1/builder/lowering/schema/compile.js +11 -6
- package/dist/v1/builder/lowering/schema/context.d.ts +9 -1
- package/dist/v1/builder/lowering/schema/context.js +36 -4
- package/dist/v1/builder/lowering/schema/lifetime.d.ts +11 -0
- package/dist/v1/builder/lowering/schema/lifetime.js +55 -0
- package/dist/v1/builder/lowering/value/path.d.ts +1 -1
- package/dist/v1/builder/lowering/value/path.js +2 -4
- package/dist/v1/builder/lowering/value/zod.js +1 -3
- package/dist/v1/builder/policy/authoring.d.ts +85 -5
- package/dist/v1/builder/policy/authoring.js +107 -68
- package/dist/v1/builder/schema/define.d.ts +0 -1
- package/dist/v1/builder/schema/diagnostic.d.ts +3 -2
- package/dist/v1/builder/schema/diagnostic.js +5 -10
- package/dist/v1/builder/schema/input.d.ts +1 -1
- package/dist/v1/builder/schema/projection/callable.d.ts +7 -5
- package/dist/v1/builder/schema/projection/class.d.ts +118 -15
- package/dist/v1/builder/schema/projection/core-input.d.ts +2 -1
- package/dist/v1/builder/schema/projection/identity.d.ts +2 -1
- package/dist/v1/builder/schema/projection/model.d.ts +4 -2
- package/dist/v1/builder/schema/projection/property.d.ts +1 -1
- package/dist/v1/builder/schema/projection/resolved-class.d.ts +2 -1
- package/dist/v1/builder/schema/projection.d.ts +1 -1
- package/dist/v1/builder/value/full-match.d.ts +0 -1
- package/dist/v1/builder/value/full-match.js +0 -1
- package/dist/v1/builder/value/path-metadata.d.ts +1 -1
- package/dist/v1/builder/value/path.d.ts +1 -1
- package/dist/v1/bundle/codec.js +11 -13
- package/dist/v1/bundle/diagnostic.d.ts +2 -0
- package/dist/v1/bundle/diagnostic.js +9 -7
- package/dist/v1/bundle/model.js +1 -1
- package/dist/v1/bundle/structure.js +4 -6
- package/dist/v1/compiled/admission/accept.js +4 -10
- package/dist/v1/compiled/admission/closure.js +2 -2
- package/dist/v1/compiled/admission/diagnostic.d.ts +1 -1
- package/dist/v1/compiled/admission/diagnostic.js +1 -3
- package/dist/v1/compiled/admission/revision.d.ts +9 -1
- package/dist/v1/compiled/admission/revision.js +6 -3
- package/dist/v1/compiled/admission/semantics/class.d.ts +4 -1
- package/dist/v1/compiled/admission/semantics/class.js +37 -12
- package/dist/v1/compiled/admission/semantics/core.d.ts +1 -24
- package/dist/v1/compiled/admission/semantics/core.js +56 -24
- package/dist/v1/compiled/admission/semantics/edge.d.ts +2 -4
- package/dist/v1/compiled/admission/semantics/edge.js +6 -65
- package/dist/v1/compiled/admission/semantics/policy/callable.js +0 -2
- package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +5 -20
- package/dist/v1/compiled/admission/semantics/policy/contracts.js +8 -21
- package/dist/v1/compiled/admission/semantics/policy/parity.js +40 -43
- package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +4 -1
- package/dist/v1/compiled/admission/semantics/policy/pattern.js +4 -16
- package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +2 -24
- package/dist/v1/compiled/admission/semantics/policy/typing.js +19 -201
- package/dist/v1/compiled/admission/wire/callable.js +11 -1
- package/dist/v1/compiled/admission/wire/class.js +73 -21
- package/dist/v1/compiled/admission/wire/policy.d.ts +4 -3
- package/dist/v1/compiled/admission/wire/policy.js +8 -7
- package/dist/v1/compiled/compiler/compile.js +8 -8
- package/dist/v1/compiled/diagnostic.js +2 -3
- package/dist/v1/compiled/loader/load.d.ts +3 -2
- package/dist/v1/compiled/loader/load.js +11 -45
- package/dist/v1/domain/create.js +5 -6
- package/dist/v1/domain/model/domain.d.ts +2 -7
- package/dist/v1/domain/model/input.d.ts +2 -1
- package/dist/v1/domain/namespace/member-collection.js +4 -6
- package/dist/v1/domain/projection/classes.js +4 -1
- package/dist/v1/domain/validation/create.d.ts +6 -3
- package/dist/v1/domain/validation/create.js +21 -69
- package/dist/v1/index.d.ts +2 -1
- package/dist/v1/language/.spec/schemas/draft-2020-12.schema.json +462 -0
- package/dist/v1/language/.spec/schemas/value-schema.schema.json +22 -0
- package/dist/v1/language/callable/admission.d.ts +15 -0
- package/dist/v1/language/callable/admission.js +43 -0
- package/dist/v1/language/callable/model/callable.d.ts +10 -0
- package/dist/v1/language/callable/resolved.d.ts +16 -3
- package/dist/v1/language/class/inheritance.d.ts +36 -5
- package/dist/v1/language/class/inheritance.js +87 -1
- package/dist/v1/language/class/lifetime.d.ts +50 -11
- package/dist/v1/language/class/lifetime.js +89 -20
- package/dist/v1/language/class/model/class.d.ts +45 -9
- package/dist/v1/language/class/model/edge.d.ts +31 -2
- package/dist/v1/language/class/model/property.d.ts +16 -7
- package/dist/v1/language/class/property-values.js +2 -4
- package/dist/v1/language/class/unique.d.ts +143 -0
- package/dist/v1/language/class/unique.js +264 -0
- package/dist/v1/language/core/facts.d.ts +85 -0
- package/dist/v1/language/core/facts.js +116 -0
- package/dist/v1/language/definition/metadata.d.ts +5 -0
- package/dist/v1/language/definition/metadata.js +7 -0
- package/dist/v1/language/freeze.d.ts +5 -0
- package/dist/v1/{schema/canonical → language}/freeze.js +4 -0
- package/dist/v1/language/index.d.ts +7 -2
- package/dist/v1/language/index.js +5 -1
- package/dist/v1/language/limits.d.ts +64 -0
- package/dist/v1/language/limits.js +60 -0
- package/dist/v1/language/policy/analysis/branches.d.ts +8 -0
- package/dist/v1/language/policy/analysis/branches.js +2 -1
- package/dist/v1/language/policy/analysis/budgets.d.ts +45 -12
- package/dist/v1/language/policy/analysis/budgets.js +133 -19
- package/dist/v1/language/policy/analysis/checks.js +3 -2
- package/dist/v1/language/policy/analysis/typing.d.ts +51 -0
- package/dist/v1/language/policy/analysis/typing.js +455 -0
- package/dist/v1/language/policy/model/policy.d.ts +49 -9
- package/dist/v1/language/policy/model/policy.js +14 -0
- package/dist/v1/language/policy/normalization/normalize.d.ts +6 -6
- package/dist/v1/language/policy/normalization/normalize.js +22 -21
- package/dist/v1/language/validation/diagnostic.d.ts +15 -1
- package/dist/v1/language/validation/diagnostic.js +21 -0
- package/dist/v1/language/validation/rule.d.ts +45 -0
- package/dist/v1/language/validation/rule.js +109 -0
- package/dist/v1/language/value/compile/fields.js +4 -8
- package/dist/v1/language/value/evaluate/program.d.ts +2 -1
- package/dist/v1/language/value/evaluate/program.js +2 -2
- package/dist/v1/language/value/evaluate/validate.d.ts +2 -2
- package/dist/v1/language/value/evaluate/validate.js +6 -2
- package/dist/v1/language/value/evaluate/validity.optimization.d.ts +14 -0
- package/dist/v1/language/value/evaluate/validity.optimization.js +342 -0
- package/dist/v1/language/value/inclusion/arrays.d.ts +3 -0
- package/dist/v1/language/value/inclusion/arrays.js +85 -0
- package/dist/v1/language/value/inclusion/assertions.d.ts +18 -0
- package/dist/v1/language/value/inclusion/assertions.js +29 -0
- package/dist/v1/language/value/inclusion/combinators.d.ts +3 -0
- package/dist/v1/language/value/inclusion/combinators.js +67 -0
- package/dist/v1/language/value/inclusion/equivalence.d.ts +4 -0
- package/dist/v1/language/value/inclusion/equivalence.js +74 -0
- package/dist/v1/language/value/inclusion/evidence.d.ts +34 -0
- package/dist/v1/language/value/inclusion/evidence.js +138 -0
- package/dist/v1/language/value/inclusion/includes.d.ts +17 -0
- package/dist/v1/language/value/inclusion/includes.js +25 -719
- package/dist/v1/language/value/inclusion/keywords.d.ts +5 -0
- package/dist/v1/language/value/inclusion/keywords.js +31 -0
- package/dist/v1/language/value/inclusion/kinds.d.ts +17 -0
- package/dist/v1/language/value/inclusion/kinds.js +57 -0
- package/dist/v1/language/value/inclusion/location.d.ts +24 -0
- package/dist/v1/language/value/inclusion/location.js +63 -0
- package/dist/v1/language/value/inclusion/numbers.d.ts +3 -0
- package/dist/v1/language/value/inclusion/numbers.js +41 -0
- package/dist/v1/language/value/inclusion/objects.d.ts +3 -0
- package/dist/v1/language/value/inclusion/objects.js +190 -0
- package/dist/v1/language/value/inclusion/strings.d.ts +3 -0
- package/dist/v1/language/value/inclusion/strings.js +29 -0
- package/dist/v1/language/value/inclusion/types.d.ts +3 -0
- package/dist/v1/language/value/inclusion/types.js +11 -0
- package/dist/v1/language/value/ordering.d.ts +14 -0
- package/dist/v1/language/value/ordering.js +86 -9
- package/dist/v1/language/value/profile/canonicalize.js +6 -5
- package/dist/v1/language/value/profile/json.validate.d.ts +3 -1
- package/dist/v1/language/value/profile/json.validate.js +3 -2
- package/dist/v1/language/value/profile/meta-schema.compiled.js +4 -1
- package/dist/v1/language/value/profile/rules.js +17 -43
- package/dist/v1/language/value/profile/validate.js +1 -10
- package/dist/v1/language/value/profile/vocabulary.d.ts +35 -2
- package/dist/v1/language/value/profile/vocabulary.js +52 -5
- package/dist/v1/language/value/reference/closure.js +3 -4
- package/dist/v1/language/value/reference/recursion.js +2 -22
- package/dist/v1/language/value/reference/registry.index.d.ts +2 -0
- package/dist/v1/language/value/reference/registry.index.js +33 -16
- package/dist/v1/language/value/regexp/ast.js +6 -7
- package/dist/v1/language/value/regexp/compile.d.ts +5 -11
- package/dist/v1/language/value/regexp/compile.js +14 -12
- package/dist/v1/language/value/regexp/syntax.js +3 -2
- package/dist/v1/language/value/syntax/keywords.d.ts +3 -3
- package/dist/v1/language/value/syntax/keywords.js +4 -20
- package/dist/v1/language/value/syntax/node-path/validate.js +2 -3
- package/dist/v1/language/value/syntax/pointer.d.ts +2 -0
- package/dist/v1/language/value/syntax/pointer.js +5 -2
- package/dist/v1/language/value/syntax/walk.d.ts +2 -0
- package/dist/v1/language/value/syntax/walk.js +19 -20
- package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +2519 -0
- package/dist/v1/schema/admission/accept.js +3 -14
- package/dist/v1/schema/admission/callable.d.ts +21 -0
- package/dist/v1/schema/admission/callable.js +96 -0
- package/dist/v1/schema/analysis/class.js +33 -15
- package/dist/v1/schema/canonical/revision.js +4 -4
- package/dist/v1/schema/compatibility/api.d.ts +2 -1
- package/dist/v1/schema/compatibility/api.js +1 -0
- package/dist/v1/schema/compatibility/comparators/callables.js +1 -1
- package/dist/v1/schema/compatibility/comparators/classes.d.ts +9 -4
- package/dist/v1/schema/compatibility/comparators/classes.js +29 -8
- package/dist/v1/schema/compatibility/comparators/index.d.ts +1 -1
- package/dist/v1/schema/compatibility/comparators/members.js +1 -1
- package/dist/v1/schema/compatibility/comparators/values.js +2 -2
- package/dist/v1/schema/compatibility/coordinate.js +3 -3
- package/dist/v1/schema/compatibility/diff.js +2 -4
- package/dist/v1/schema/compatibility/extension.d.ts +11 -0
- package/dist/v1/schema/compatibility/extension.js +22 -0
- package/dist/v1/schema/compatibility/fields.d.ts +20 -4
- package/dist/v1/schema/compatibility/fields.js +13 -3
- package/dist/v1/schema/compatibility/meaning/footprint.js +16 -50
- package/dist/v1/schema/compatibility/model.d.ts +17 -5
- package/dist/v1/schema/compatibility/report.js +1 -1
- package/dist/v1/schema/compatibility/scope.d.ts +2 -0
- package/dist/v1/schema/compatibility/scope.js +4 -1
- package/dist/v1/schema/compatibility/structure/index.js +6 -4
- package/dist/v1/schema/compatibility/structure/requirements.js +57 -58
- package/dist/v1/schema/compatibility/versioning/index.js +1 -1
- package/dist/v1/schema/compatibility/versioning/surface.d.ts +1 -1
- package/dist/v1/schema/compatibility/versioning/surface.js +30 -2
- package/dist/v1/schema/compatibility/walk.d.ts +17 -0
- package/dist/v1/schema/compatibility/walk.js +41 -0
- package/dist/v1/schema/diagnostic.d.ts +17 -3
- package/dist/v1/schema/diagnostic.js +14 -11
- package/dist/v1/schema/index.d.ts +10 -1
- package/dist/v1/schema/index.js +4 -0
- package/dist/v1/schema/model/schema.d.ts +20 -1
- package/dist/v1/schema/model/schema.js +1 -1
- package/dist/v1/schema/normalization/domain.d.ts +2 -0
- package/dist/v1/schema/normalization/domain.js +29 -9
- package/dist/v1/schema/resolution/closure.js +2 -1
- package/dist/v1/schema/resolution/context.js +13 -13
- package/dist/v1/schema/resolution/domain.d.ts +5 -0
- package/dist/v1/schema/resolution/domain.js +2 -2
- package/dist/v1/schema/resolution/origins.js +3 -2
- package/dist/v1/schema/rule.d.ts +26 -0
- package/dist/v1/schema/rule.js +440 -0
- package/dist/v1/schema/validation/callable.d.ts +35 -2
- package/dist/v1/schema/validation/callable.js +65 -9
- package/dist/v1/schema/validation/class.d.ts +6 -2
- package/dist/v1/schema/validation/class.js +127 -104
- package/dist/v1/schema/validation/core.js +90 -168
- package/dist/v1/schema/validation/domain.js +4 -13
- package/dist/v1/schema/validation/domain.json-schema.d.ts +15 -0
- package/dist/v1/schema/validation/domain.json-schema.js +197 -0
- package/dist/v1/schema/validation/domain.route.d.ts +6 -1
- package/dist/v1/schema/validation/domain.route.js +18 -0
- package/dist/v1/schema/validation/domain.structure.d.ts +7780 -0
- package/dist/v1/schema/validation/domain.structure.js +398 -147
- package/dist/v1/schema/validation/json.json-schema.d.ts +40 -0
- package/dist/v1/schema/validation/json.json-schema.js +46 -0
- package/dist/v1/schema/validation/policy/budgets.d.ts +33 -2
- package/dist/v1/schema/validation/policy/budgets.js +87 -121
- package/dist/v1/schema/validation/policy/context.d.ts +6 -5
- package/dist/v1/schema/validation/policy/context.js +7 -10
- package/dist/v1/schema/validation/policy/objects.d.ts +1 -1
- package/dist/v1/schema/validation/policy/objects.js +6 -14
- package/dist/v1/schema/validation/policy/references.js +11 -27
- package/dist/v1/schema/validation/policy/typing.d.ts +3 -18
- package/dist/v1/schema/validation/policy/typing.js +22 -356
- package/dist/v1/schema/validation/policy/uses.d.ts +40 -3
- package/dist/v1/schema/validation/policy/uses.js +66 -89
- package/dist/v1/schema/validation/policy/validate.js +5 -5
- package/dist/v1/schema/validation/value-api.d.ts +22 -0
- package/dist/v1/schema/validation/value-api.js +34 -1
- package/dist/v1/schema/validation/value.d.ts +3 -0
- package/dist/v1/schema/validation/value.js +9 -17
- package/dist/v1/schema/validation/value.json-schema.d.ts +49 -0
- package/dist/v1/schema/validation/value.json-schema.js +137 -0
- package/dist/v1/schema/validation/view.js +4 -8
- package/dist/value/canonical.d.ts +6 -0
- package/dist/value/canonical.js +36 -0
- package/dist/value/decode.d.ts +7 -0
- package/dist/value/decode.js +159 -9
- package/dist/value/index.d.ts +1 -1
- package/dist/value/json.d.ts +2 -2
- package/dist/value/json.js +2 -2
- package/dist/value/types.d.ts +6 -0
- package/dist/value/unicode.d.ts +2 -1
- package/dist/value/unicode.js +2 -0
- package/package.json +8 -1
- package/dist/v1/builder/lowering/core-properties.d.ts +0 -10
- package/dist/v1/builder/lowering/core-properties.js +0 -76
- package/dist/v1/compiled/admission/semantics/cardinality.d.ts +0 -5
- package/dist/v1/compiled/admission/semantics/cardinality.js +0 -113
- package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +0 -8
- package/dist/v1/compiled/admission/semantics/policy/equality.js +0 -27
- package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +0 -9
- package/dist/v1/compiled/admission/semantics/policy/measure.js +0 -81
- package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +0 -10
- package/dist/v1/compiled/admission/semantics/policy/variants.js +0 -65
- package/dist/v1/language/class/index.d.ts +0 -8
- package/dist/v1/language/class/index.js +0 -1
- package/dist/v1/language/core/index.d.ts +0 -2
- package/dist/v1/language/value/index.d.ts +0 -11
- package/dist/v1/language/value/index.js +0 -8
- package/dist/v1/schema/canonical/domain.d.ts +0 -3
- package/dist/v1/schema/canonical/domain.digest.d.ts +0 -3
- package/dist/v1/schema/canonical/domain.digest.js +0 -5
- package/dist/v1/schema/canonical/domain.js +0 -5
- package/dist/v1/schema/canonical/freeze.d.ts +0 -1
- /package/dist/v1/{language/core/index.js → builder/class/input.js} +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { PropertyKey as admitPropertyKey } from '../../addressing/index.js';
|
|
2
|
+
import { definitionRefIndex } from '../../addressing/ordering.js';
|
|
3
|
+
import { createPropertyValues } from '../../language/class/property-values.js';
|
|
4
|
+
import { analyzeDefinitions } from '../../schema/analysis/class.js';
|
|
5
|
+
import { buildDomainResolutionContext } from '../../schema/resolution/context.js';
|
|
6
|
+
import { escapeToken, fail } from '../schema/diagnostic.js';
|
|
7
|
+
/**
|
|
8
|
+
* Analyze the already-canonical Definition surface of `candidate` once, so Property shorthand
|
|
9
|
+
* resolves against each Class's own and inherited Properties. Core values and key tuples take no
|
|
10
|
+
* part in Class composition, so they are left out of the analysis.
|
|
11
|
+
*/
|
|
12
|
+
export function analyzePropertyOwners(candidate, lookup) {
|
|
13
|
+
const analysisCandidate = {
|
|
14
|
+
...candidate,
|
|
15
|
+
core: { nodes: {}, edges: [] },
|
|
16
|
+
};
|
|
17
|
+
return analyzeDefinitions(buildDomainResolutionContext(analysisCandidate, lookup)).definitions;
|
|
18
|
+
}
|
|
19
|
+
/** Lower rich builder shorthand to the canonical full-key Core representation. */
|
|
20
|
+
export function canonicalizeCorePropertyKeys(core, owners) {
|
|
21
|
+
const nodes = Object.fromEntries(Object.entries(core.nodes).map(([slug, node]) => {
|
|
22
|
+
const definition = owners.get(definitionRefIndex(node.class));
|
|
23
|
+
if (definition === undefined) {
|
|
24
|
+
fail('BUILDER_CORE_PROPERTY', `/core/nodes/${escapeToken(slug)}/class`, 'Core property shorthand requires a resolvable concrete Class.');
|
|
25
|
+
}
|
|
26
|
+
return [
|
|
27
|
+
slug,
|
|
28
|
+
{
|
|
29
|
+
...node,
|
|
30
|
+
properties: qualify(node.properties, definition, `/core/nodes/${escapeToken(slug)}/properties`),
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}));
|
|
34
|
+
const edges = core.edges.map((edge, index) => {
|
|
35
|
+
const definition = owners.get(definitionRefIndex(edge.class));
|
|
36
|
+
if (definition === undefined) {
|
|
37
|
+
fail('BUILDER_CORE_PROPERTY', `/core/edges/${index}/class`, 'Core property shorthand requires a resolvable concrete Class.');
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
...edge,
|
|
41
|
+
properties: qualify(edge.properties, definition, `/core/edges/${index}/properties`),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
return { nodes, edges };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Lower each Property a key tuple names by its name to its full key among the Class's own and
|
|
48
|
+
* inherited Properties; a full key stays as authored. Ambiguity and absence are refused here, so a
|
|
49
|
+
* tuple never names a Property the author did not mean. A Node tuple names Properties only; an Edge
|
|
50
|
+
* tuple names them as `{ property }` beside its structural fields.
|
|
51
|
+
*/
|
|
52
|
+
export function canonicalizeUniquePropertyKeys(classes, origin, owners) {
|
|
53
|
+
return Object.fromEntries(Object.entries(classes).map(([name, declaration]) => {
|
|
54
|
+
if (declaration.kind === 'edge' && declaration.orientation !== 'directed') {
|
|
55
|
+
return [name, declaration];
|
|
56
|
+
}
|
|
57
|
+
if (declaration.unique === undefined)
|
|
58
|
+
return [name, declaration];
|
|
59
|
+
const ref = { origin, kind: 'class', name };
|
|
60
|
+
const definition = owners.get(definitionRefIndex(ref));
|
|
61
|
+
const pointer = `/classes/${escapeToken(name)}/unique`;
|
|
62
|
+
const resolve = (input, at) => {
|
|
63
|
+
if (definition === undefined) {
|
|
64
|
+
fail('BUILDER_UNIQUE_PROPERTY', at, 'A key Property requires a resolvable Class.');
|
|
65
|
+
}
|
|
66
|
+
return resolveInputKey(input, definition, 'BUILDER_UNIQUE_PROPERTY', at);
|
|
67
|
+
};
|
|
68
|
+
if (declaration.kind === 'node') {
|
|
69
|
+
const unique = declaration.unique.map((tuple, t) => tuple.map((key, f) => resolve(key, `${pointer}/${t}/${f}`)));
|
|
70
|
+
return [name, { ...declaration, unique }];
|
|
71
|
+
}
|
|
72
|
+
const unique = declaration.unique.map((tuple, t) => tuple.map((field, f) => typeof field === 'string'
|
|
73
|
+
? field
|
|
74
|
+
: { property: resolve(field.property, `${pointer}/${t}/${f}/property`) }));
|
|
75
|
+
return [name, { ...declaration, unique }];
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
function qualify(input, definition, pointer) {
|
|
79
|
+
const result = {};
|
|
80
|
+
const sourceByKey = new Map();
|
|
81
|
+
for (const [inputKey, value] of Object.entries(input)) {
|
|
82
|
+
const key = resolveInputKey(inputKey, definition, 'BUILDER_CORE_PROPERTY', `${pointer}/${escapeToken(inputKey)}`);
|
|
83
|
+
const previous = sourceByKey.get(key);
|
|
84
|
+
if (previous !== undefined) {
|
|
85
|
+
fail('BUILDER_CORE_PROPERTY', `${pointer}/${escapeToken(inputKey)}`, `Property is supplied twice through ${JSON.stringify(previous)} and ${JSON.stringify(inputKey)}.`);
|
|
86
|
+
}
|
|
87
|
+
sourceByKey.set(key, inputKey);
|
|
88
|
+
result[key] = value;
|
|
89
|
+
}
|
|
90
|
+
return createPropertyValues(Object.entries(result).map(([key, value]) => [admitPropertyKey(key), value]));
|
|
91
|
+
}
|
|
92
|
+
/** The full key of the Property `input` names on `definition`: its full key, or its unique name. */
|
|
93
|
+
function resolveInputKey(input, definition, code, pointer) {
|
|
94
|
+
if (admitPropertyKey.is(input)) {
|
|
95
|
+
const key = admitPropertyKey(input);
|
|
96
|
+
if (!definition.properties.has(key)) {
|
|
97
|
+
fail(code, pointer, `Property ${input} is not present on the Class.`);
|
|
98
|
+
}
|
|
99
|
+
return key;
|
|
100
|
+
}
|
|
101
|
+
const candidates = [...definition.properties].flatMap(([key, field]) => field.name === input ? [key] : []);
|
|
102
|
+
if (candidates.length === 1)
|
|
103
|
+
return candidates[0];
|
|
104
|
+
if (candidates.length === 0) {
|
|
105
|
+
fail(code, pointer, `Property ${JSON.stringify(input)} does not exist.`);
|
|
106
|
+
}
|
|
107
|
+
fail(code, pointer, `Property ${JSON.stringify(input)} is ambiguous; use one of: ${candidates.join(', ')}.`);
|
|
108
|
+
}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
1
2
|
import { acceptDomainSchema } from '../../../schema/admission/accept.js';
|
|
2
|
-
import { canonicalizeDomainSchema } from '../../../schema/canonical/domain.js';
|
|
3
|
-
import { deepFreeze } from '../../../schema/canonical/freeze.js';
|
|
4
3
|
import { MemoryDomainSchemaLookup } from '../../../schema/dependency/lookup.js';
|
|
4
|
+
import { normalizeDomainSchema } from '../../../schema/normalization/domain.js';
|
|
5
5
|
import { lookupEntriesForDependencies } from '../../../schema/resolution/closure.js';
|
|
6
6
|
import { parseDomainSchemaStructure } from '../../../schema/validation/domain.structure.js';
|
|
7
7
|
import { assertKnownKeys, escapeToken } from '../../schema/diagnostic.js';
|
|
8
8
|
import { V1CallableCompiler } from '../callable.js';
|
|
9
9
|
import { V1DefinitionCompiler } from '../class.js';
|
|
10
|
-
import { canonicalizeCorePropertyKeys } from '../core-properties.js';
|
|
11
10
|
import { compileCore } from '../core.js';
|
|
12
11
|
import { assertPolicyCompositionAcyclic, V1PolicyCompiler } from '../policy.js';
|
|
12
|
+
import { analyzePropertyOwners, canonicalizeCorePropertyKeys, canonicalizeUniquePropertyKeys, } from '../property-keys.js';
|
|
13
13
|
import { BuilderValueSchemas } from '../value/compile.js';
|
|
14
14
|
import { V1ViewCompiler } from '../view.js';
|
|
15
15
|
import { captureSchema, commitSchemaOwnership } from './capture.js';
|
|
16
16
|
import { BuilderContext } from './context.js';
|
|
17
|
+
import { assertAuthoredLifetimes } from './lifetime.js';
|
|
17
18
|
/**
|
|
18
19
|
* Compile the V1 TypeScript builder graph through the same semantic acceptance
|
|
19
20
|
* path used for untrusted decoded schemas.
|
|
@@ -21,9 +22,11 @@ import { BuilderContext } from './context.js';
|
|
|
21
22
|
* This is the private implementation behind defineSchema.
|
|
22
23
|
*/
|
|
23
24
|
export function compileSchema(origin, input) {
|
|
24
|
-
const
|
|
25
|
+
const dependencies = lookupEntriesForDependencies(input.dependencies ?? {});
|
|
26
|
+
const lookup = new MemoryDomainSchemaLookup(dependencies);
|
|
25
27
|
const candidate = assembleDomainSchema(origin, input, lookup);
|
|
26
28
|
const accepted = acceptDomainSchema(candidate, lookup);
|
|
29
|
+
assertAuthoredLifetimes(accepted, dependencies);
|
|
27
30
|
commitSchemaOwnership(input, origin);
|
|
28
31
|
return accepted;
|
|
29
32
|
}
|
|
@@ -75,9 +78,11 @@ function assembleDomainSchema(origin, input, lookup) {
|
|
|
75
78
|
views,
|
|
76
79
|
core,
|
|
77
80
|
};
|
|
81
|
+
const owners = analyzePropertyOwners(semanticContent, lookup);
|
|
78
82
|
const qualifiedContent = {
|
|
79
83
|
...semanticContent,
|
|
80
|
-
|
|
84
|
+
classes: canonicalizeUniquePropertyKeys(classes, origin, owners),
|
|
85
|
+
core: canonicalizeCorePropertyKeys(core, owners),
|
|
81
86
|
};
|
|
82
87
|
context.noteDomainEndpointReferences(qualifiedContent);
|
|
83
88
|
const candidate = {
|
|
@@ -85,7 +90,7 @@ function assembleDomainSchema(origin, input, lookup) {
|
|
|
85
90
|
dependencies: context.dependencies(),
|
|
86
91
|
};
|
|
87
92
|
const structured = parseDomainSchemaStructure(candidate);
|
|
88
|
-
const canonical = parseDomainSchemaStructure(
|
|
93
|
+
const canonical = parseDomainSchemaStructure(normalizeDomainSchema(structured));
|
|
89
94
|
return deepFreeze(canonical);
|
|
90
95
|
}
|
|
91
96
|
function mapRecord(record, map) {
|
|
@@ -6,7 +6,8 @@ import type { PolicyObjectRef } from '../../../language/index.js';
|
|
|
6
6
|
import type { ValueSchemaRegistry } from '../../../language/value/reference/registry.js';
|
|
7
7
|
import type { DomainSchema, DomainSchemaIR } from '../../../schema/model/schema.js';
|
|
8
8
|
import type { Function, PolicyObjectInput } from '../../callable/authoring.js';
|
|
9
|
-
import type { Class
|
|
9
|
+
import type { Class } from '../../class/handle.js';
|
|
10
|
+
import type { ClassReferenceInput } from '../../class/input.js';
|
|
10
11
|
import type { CoreEndpoint, CoreNode } from '../../core/authoring.js';
|
|
11
12
|
import type { Policy } from '../../policy/authoring.js';
|
|
12
13
|
import type { View } from '../../view/authoring.js';
|
|
@@ -29,8 +30,15 @@ export declare class BuilderContext {
|
|
|
29
30
|
captureFunction(value: Function, ref: FunctionRef, pointer: string): void;
|
|
30
31
|
captureView(value: View, ref: ViewRef, pointer: string): void;
|
|
31
32
|
resolveClass(input: ClassReferenceInput, kind: ClassKind, pointer: string): ClassRef;
|
|
33
|
+
/** A parent of another Domain must be open to it in the dependency revision authored against. */
|
|
34
|
+
resolveParent(input: ClassReferenceInput, kind: ClassKind, pointer: string): ClassRef;
|
|
32
35
|
resolveNodeClass(input: ClassReferenceInput, pointer: string): ClassRef;
|
|
33
36
|
resolveEdgeClass(input: ClassReferenceInput, pointer: string): ClassRef;
|
|
37
|
+
/**
|
|
38
|
+
* The roles of a resolved Edge Class's source and target, or of an undirected Class's two
|
|
39
|
+
* endpoints in their stored order, which is the authored one.
|
|
40
|
+
*/
|
|
41
|
+
edgeRoles(ref: ClassRef): readonly [source: string, target: string];
|
|
34
42
|
resolvePolicy(input: Lazy<unknown>, pointer: string): PolicyRef;
|
|
35
43
|
resolvePolicyObject(input: PolicyObjectInput | PolicyObjectRef, pointer: string): PolicyObjectRef;
|
|
36
44
|
/** A Core fact belongs to the Domain that declares it, so a dependency endpoint never resolves. */
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { compareDefinitionRefs, compareUnicode, definitionRefIndex, } from '../../../addressing/ordering.js';
|
|
2
2
|
import { DEPENDENCY_ALIAS_PATTERN } from '../../../addressing/patterns.js';
|
|
3
3
|
import { isMethodExecutable } from '../../../language/callable/executable.js';
|
|
4
|
+
import { admitsForeignSubclass, inheritanceOf } from '../../../language/class/inheritance.js';
|
|
4
5
|
import { policyObjectKey, policyObjectOrigin } from '../../../language/index.js';
|
|
5
6
|
import { graphNodePathSchema } from '../../../language/value/syntax/node-path/schema.js';
|
|
7
|
+
import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
|
|
6
8
|
import { revisionOfDomainSchema } from '../../../schema/canonical/revision.js';
|
|
7
9
|
import { requireDomainClosure } from '../../../schema/resolution/closure.js';
|
|
8
10
|
import { collectUsedForeignOrigins } from '../../../schema/resolution/origins.js';
|
|
11
|
+
import { classConfiguration } from '../../class/authoring.js';
|
|
9
12
|
import { fail } from '../../schema/diagnostic.js';
|
|
10
13
|
import { resolveLazy } from '../../schema/lazy.js';
|
|
11
14
|
import { OwnershipCapture } from './ownership.js';
|
|
@@ -14,6 +17,7 @@ export class BuilderContext {
|
|
|
14
17
|
ownership = new OwnershipCapture();
|
|
15
18
|
localDefinitions = new Map();
|
|
16
19
|
localClassKinds = new Map();
|
|
20
|
+
#localClasses = new Map();
|
|
17
21
|
policies = new Map();
|
|
18
22
|
policyObjects = new Map();
|
|
19
23
|
policyObjectRefs = new Set();
|
|
@@ -22,7 +26,7 @@ export class BuilderContext {
|
|
|
22
26
|
constructor(origin, dependencies) {
|
|
23
27
|
this.origin = origin;
|
|
24
28
|
for (const [alias, schema] of Object.entries(dependencies)) {
|
|
25
|
-
const pointer = `/dependencies/${
|
|
29
|
+
const pointer = `/dependencies/${escapePointerToken(alias)}`;
|
|
26
30
|
if (!DEPENDENCY_ALIAS_PATTERN.test(alias)) {
|
|
27
31
|
fail('BUILDER_DEPENDENCY_ALIAS', pointer, `Dependency alias ${JSON.stringify(alias)} must be an ASCII lower-camel identifier.`);
|
|
28
32
|
}
|
|
@@ -47,6 +51,7 @@ export class BuilderContext {
|
|
|
47
51
|
}
|
|
48
52
|
this.localDefinitions.set(key, ref);
|
|
49
53
|
this.localClassKinds.set(key, value.kind);
|
|
54
|
+
this.#localClasses.set(key, value);
|
|
50
55
|
this.ownership.captureDefinition(value, ref, pointer);
|
|
51
56
|
this.capturePolicyObject(value, ref);
|
|
52
57
|
}
|
|
@@ -90,12 +95,42 @@ export class BuilderContext {
|
|
|
90
95
|
}
|
|
91
96
|
return { ...ref };
|
|
92
97
|
}
|
|
98
|
+
/** A parent of another Domain must be open to it in the dependency revision authored against. */
|
|
99
|
+
resolveParent(input, kind, pointer) {
|
|
100
|
+
const ref = this.resolveClass(input, kind, pointer);
|
|
101
|
+
if (ref.origin === this.origin)
|
|
102
|
+
return ref;
|
|
103
|
+
const parent = this.#dependencies.get(ref.origin).schema.classes[ref.name];
|
|
104
|
+
if (!admitsForeignSubclass(parent)) {
|
|
105
|
+
fail('BUILDER_CLASS_INHERITANCE', pointer, `Class ${ref.origin}:class.${ref.name} is ${inheritanceOf(parent)}: only an open Class admits a subclass of another Domain.`);
|
|
106
|
+
}
|
|
107
|
+
return ref;
|
|
108
|
+
}
|
|
93
109
|
resolveNodeClass(input, pointer) {
|
|
94
110
|
return this.resolveClass(input, 'node', pointer);
|
|
95
111
|
}
|
|
96
112
|
resolveEdgeClass(input, pointer) {
|
|
97
113
|
return this.resolveClass(input, 'edge', pointer);
|
|
98
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The roles of a resolved Edge Class's source and target, or of an undirected Class's two
|
|
117
|
+
* endpoints in their stored order, which is the authored one.
|
|
118
|
+
*/
|
|
119
|
+
edgeRoles(ref) {
|
|
120
|
+
if (ref.origin === this.origin) {
|
|
121
|
+
const value = this.#localClasses.get(definitionRefIndex(ref));
|
|
122
|
+
if (value.orientation === 'directed') {
|
|
123
|
+
const input = classConfiguration(value);
|
|
124
|
+
return [input.source.as, input.target.as];
|
|
125
|
+
}
|
|
126
|
+
const input = classConfiguration(value);
|
|
127
|
+
return [input.endpoints[0].as, input.endpoints[1].as];
|
|
128
|
+
}
|
|
129
|
+
const definition = this.#dependencies.get(ref.origin).schema.classes[ref.name];
|
|
130
|
+
return definition.orientation === 'directed'
|
|
131
|
+
? [definition.endpoints.source.role, definition.endpoints.target.role]
|
|
132
|
+
: [definition.endpoints[0].role, definition.endpoints[1].role];
|
|
133
|
+
}
|
|
99
134
|
resolvePolicy(input, pointer) {
|
|
100
135
|
const value = resolveLazy(input, pointer);
|
|
101
136
|
if (typeof value !== 'object' || value === null) {
|
|
@@ -211,9 +246,6 @@ export class BuilderContext {
|
|
|
211
246
|
this.policyObjectRefs.add(policyObjectKey(ref));
|
|
212
247
|
}
|
|
213
248
|
}
|
|
214
|
-
function escapePointer(value) {
|
|
215
|
-
return value.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
216
|
-
}
|
|
217
249
|
function isResolvedClass(value) {
|
|
218
250
|
if (typeof value !== 'object' || value === null)
|
|
219
251
|
return false;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DomainSchemaEntry } from '../../../schema/dependency/lookup.js';
|
|
2
|
+
import type { DomainSchema } from '../../../schema/model/schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Authoring refuses two Edge Classes that acceptance keeps, because a stored Schema must decode
|
|
5
|
+
* again with the lifetimes it derives (BUILDER-EDGE-LIFETIMES):
|
|
6
|
+
* - one with an endpoint that can hold a Node of another Domain while an endpoint requires an Edge.
|
|
7
|
+
* It can neither restrict that Domain's deletions nor detach below the required count, so the
|
|
8
|
+
* required endpoint must become optional;
|
|
9
|
+
* - one whose lifetimes differ from those of an Edge Class it extends, the root Edge aside.
|
|
10
|
+
*/
|
|
11
|
+
export declare function assertAuthoredLifetimes(schema: DomainSchema, dependencies: readonly DomainSchemaEntry[]): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Key } from '../../../addressing/key.js';
|
|
2
|
+
import { definitionRefIndex } from '../../../addressing/ordering.js';
|
|
3
|
+
import { isGraphRoot } from '../../../language/class/inheritance.js';
|
|
4
|
+
import { contractEndpoints, edgeLifetimes, lifetimeScope, reachesAnotherDomain, requiredEndpoint, } from '../../../language/class/lifetime.js';
|
|
5
|
+
import { BuilderError, diagnostic, escapeToken } from '../../schema/diagnostic.js';
|
|
6
|
+
/**
|
|
7
|
+
* Authoring refuses two Edge Classes that acceptance keeps, because a stored Schema must decode
|
|
8
|
+
* again with the lifetimes it derives (BUILDER-EDGE-LIFETIMES):
|
|
9
|
+
* - one with an endpoint that can hold a Node of another Domain while an endpoint requires an Edge.
|
|
10
|
+
* It can neither restrict that Domain's deletions nor detach below the required count, so the
|
|
11
|
+
* required endpoint must become optional;
|
|
12
|
+
* - one whose lifetimes differ from those of an Edge Class it extends, the root Edge aside.
|
|
13
|
+
*/
|
|
14
|
+
export function assertAuthoredLifetimes(schema, dependencies) {
|
|
15
|
+
const classes = [
|
|
16
|
+
...Object.values(schema.classes),
|
|
17
|
+
...dependencies.flatMap((entry) => Object.values(entry.schema.classes)),
|
|
18
|
+
];
|
|
19
|
+
const scope = lifetimeScope(classes);
|
|
20
|
+
const declarations = new Map(classes.map((declaration) => [definitionRefIndex(declaration.ref), declaration]));
|
|
21
|
+
const diagnostics = Object.entries(schema.classes).flatMap(([name, declaration]) => {
|
|
22
|
+
if (declaration.kind !== 'edge')
|
|
23
|
+
return [];
|
|
24
|
+
const pointer = `/classes/${escapeToken(name)}`;
|
|
25
|
+
const endpoints = contractEndpoints(declaration);
|
|
26
|
+
const keys = declaration.orientation === 'directed' ? ['source', 'target'] : ['0', '1'];
|
|
27
|
+
const counts = declaration.orientation === 'directed' ? ['outgoing', 'incoming'] : ['incident', 'incident'];
|
|
28
|
+
const found = [];
|
|
29
|
+
const required = requiredEndpoint(declaration);
|
|
30
|
+
const reaching = endpoints.find(({ endpoint }) => reachesAnotherDomain(schema.origin, endpoint, scope));
|
|
31
|
+
if (required !== undefined && reaching !== undefined)
|
|
32
|
+
found.push(diagnostic('BUILDER_EDGE_LIFETIME', `${pointer}/endpoints/${keys[required.index]}/${counts[required.index]}`, `${Key.of(declaration.ref)} endpoint ${reaching.endpoint.role} can hold Nodes of another ` +
|
|
33
|
+
`Domain, so it cannot restrict their deletion, and endpoint ${required.endpoint.role} ` +
|
|
34
|
+
`requires ${required.count} Edges, so it cannot detach: make ${required.endpoint.role} optional.`));
|
|
35
|
+
const lifetimes = edgeLifetimes(declaration, scope);
|
|
36
|
+
declaration.extends.forEach((ref, index) => {
|
|
37
|
+
const parent = declarations.get(definitionRefIndex(ref));
|
|
38
|
+
if (parent?.kind !== 'edge' || isGraphRoot(parent))
|
|
39
|
+
return;
|
|
40
|
+
const inherited = edgeLifetimes(parent, scope);
|
|
41
|
+
const same = (order) => order.every((at, position) => lifetimes[position] === inherited[at]);
|
|
42
|
+
if (same([0, 1]) || (declaration.orientation === 'undirected' && same([1, 0])))
|
|
43
|
+
return;
|
|
44
|
+
found.push(diagnostic('BUILDER_EDGE_LIFETIME', `${pointer}/extends/${index}`, `${Key.of(declaration.ref)} has lifetimes ${spell(endpoints, lifetimes)}, and ` +
|
|
45
|
+
`${Key.of(parent.ref)} it extends has ${spell(contractEndpoints(parent), inherited)}: ` +
|
|
46
|
+
`an Edge Class keeps the lifetimes of the Classes it extends.`));
|
|
47
|
+
});
|
|
48
|
+
return found;
|
|
49
|
+
});
|
|
50
|
+
if (diagnostics.length > 0)
|
|
51
|
+
throw new BuilderError(diagnostics);
|
|
52
|
+
}
|
|
53
|
+
function spell(endpoints, lifetimes) {
|
|
54
|
+
return `${endpoints[0].endpoint.role} ${lifetimes[0]} and ${endpoints[1].endpoint.role} ${lifetimes[1]}`;
|
|
55
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { NodeClassReferenceInput } from '../../class/
|
|
1
|
+
import type { NodeClassReferenceInput } from '../../class/input.js';
|
|
2
2
|
import type { ZodValueSchemaOverrideContext } from './zod.js';
|
|
3
3
|
export declare function lowerPathSchema(context: ZodValueSchemaOverrideContext, resolveAccepts: (inputs: readonly NodeClassReferenceInput[], pointer: string) => readonly unknown[], pointer: string): void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
|
|
1
2
|
import { pathAccepts } from '../../value/path-metadata.js';
|
|
2
3
|
export function lowerPathSchema(context, resolveAccepts, pointer) {
|
|
3
4
|
const inputs = pathAccepts(context.zodSchema);
|
|
4
5
|
if (inputs === undefined)
|
|
5
6
|
return;
|
|
6
|
-
const location = context.path.reduce((current, segment) => `${current}/${
|
|
7
|
+
const location = context.path.reduce((current, segment) => `${current}/${escapePointerToken(String(segment))}`, pointer);
|
|
7
8
|
for (const key of Object.keys(context.jsonSchema))
|
|
8
9
|
delete context.jsonSchema[key];
|
|
9
10
|
Object.assign(context.jsonSchema, {
|
|
@@ -15,6 +16,3 @@ export function lowerPathSchema(context, resolveAccepts, pointer) {
|
|
|
15
16
|
},
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
|
-
function escapeToken(value) {
|
|
19
|
-
return value.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
20
|
-
}
|
|
@@ -4,6 +4,7 @@ import { canonicalizeValueSchema } from '../../../language/value/profile/canonic
|
|
|
4
4
|
import { validateValueSchema } from '../../../language/value/profile/validate.js';
|
|
5
5
|
import { isIRegexp } from '../../../language/value/regexp/syntax.js';
|
|
6
6
|
import { fullMatchSource } from '../../../language/value/syntax/full-match.js';
|
|
7
|
+
import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
|
|
7
8
|
import { diagnostic } from '../../schema/diagnostic.js';
|
|
8
9
|
/**
|
|
9
10
|
* Converts only Zod contracts whose JSON-value acceptance is represented
|
|
@@ -289,9 +290,6 @@ function getCheckDefinition(value) {
|
|
|
289
290
|
function isZodType(value) {
|
|
290
291
|
return value instanceof ZodType;
|
|
291
292
|
}
|
|
292
|
-
function escapePointerToken(value) {
|
|
293
|
-
return value.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
294
|
-
}
|
|
295
293
|
function isPlainRecord(value) {
|
|
296
294
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
297
295
|
}
|
|
@@ -1,18 +1,79 @@
|
|
|
1
1
|
import type { ClassRef } from '../../addressing/index.js';
|
|
2
|
+
import type { ResolvedClass } from '../../language/class/resolved.js';
|
|
2
3
|
import type { PolicyCheckExpression, PolicyPatternExpression, PolicyPatternTerm as CanonicalPolicyPatternTerm, PolicyObjectRef } from '../../language/policy/model/policy.js';
|
|
3
4
|
import type { PolicyObjectInput } from '../callable/authoring.js';
|
|
4
|
-
import type {
|
|
5
|
+
import type { DirectedEdgeClass, EdgeClass, UndirectedEdgeClass } from '../class/handle.js';
|
|
6
|
+
import type { EdgeClassReferenceInput, NodeClassReferenceInput } from '../class/input.js';
|
|
5
7
|
import type { AuthoringValue } from '../schema/handle.js';
|
|
6
8
|
import type { Lazy } from '../schema/lazy.js';
|
|
9
|
+
import type { ResolveLazy } from '../schema/projection/identity.js';
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Name the ends by their roles: `edge(classValue, { [role]: term }, { repeat })`
|
|
12
|
+
* lowers to this same pattern.
|
|
13
|
+
*/
|
|
7
14
|
export interface PolicyEdgeInput {
|
|
8
15
|
readonly source: CanonicalPolicyPatternTerm;
|
|
9
16
|
readonly class: EdgeClassReferenceInput;
|
|
10
17
|
readonly target: CanonicalPolicyPatternTerm;
|
|
11
|
-
readonly repeat?:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
readonly repeat?: PolicyEdgeRepeat;
|
|
19
|
+
}
|
|
20
|
+
/** How many Edges of the Class a path between the two terms crosses, both bounds included. */
|
|
21
|
+
export interface PolicyEdgeRepeat {
|
|
22
|
+
readonly min: number;
|
|
23
|
+
readonly max: number;
|
|
24
|
+
}
|
|
25
|
+
export interface PolicyEdgeOptions {
|
|
26
|
+
readonly repeat?: PolicyEdgeRepeat;
|
|
15
27
|
}
|
|
28
|
+
/** An Edge Class whose ends a Policy names by role: authored, resolved, or either lazily. */
|
|
29
|
+
export type PolicyEdgeClassInput = Lazy<EdgeClass | ResolvedClass<'edge'>>;
|
|
30
|
+
/**
|
|
31
|
+
* The roles of an Edge Class's two ends, as literal types: the `as` of an authored Class's ends,
|
|
32
|
+
* the `role` of a resolved Class's, read through a lazy reference.
|
|
33
|
+
*/
|
|
34
|
+
export type EdgeRolesOf<Value> = ResolveLazy<Value> extends infer Resolved ? Resolved extends DirectedEdgeClass<infer Config> ? Config extends {
|
|
35
|
+
readonly source: {
|
|
36
|
+
readonly as: infer Source;
|
|
37
|
+
};
|
|
38
|
+
readonly target: {
|
|
39
|
+
readonly as: infer Target;
|
|
40
|
+
};
|
|
41
|
+
} ? Source | Target : never : Resolved extends UndirectedEdgeClass<infer Config> ? Config extends {
|
|
42
|
+
readonly endpoints: readonly [
|
|
43
|
+
{
|
|
44
|
+
readonly as: infer First;
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
readonly as: infer Second;
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
} ? First | Second : never : Resolved extends {
|
|
51
|
+
readonly kind: 'edge';
|
|
52
|
+
readonly definition: {
|
|
53
|
+
readonly endpoints: infer Endpoints;
|
|
54
|
+
};
|
|
55
|
+
} ? Endpoints extends {
|
|
56
|
+
readonly source: {
|
|
57
|
+
readonly role: infer Source;
|
|
58
|
+
};
|
|
59
|
+
readonly target: {
|
|
60
|
+
readonly role: infer Target;
|
|
61
|
+
};
|
|
62
|
+
} ? Source | Target : Endpoints extends readonly [
|
|
63
|
+
{
|
|
64
|
+
readonly role: infer First;
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
readonly role: infer Second;
|
|
68
|
+
}
|
|
69
|
+
] ? First | Second : never : never : never;
|
|
70
|
+
/**
|
|
71
|
+
* The two ends of an Edge, keyed by exactly the Class's two roles, both required. A Class whose
|
|
72
|
+
* roles the types do not know names no ends.
|
|
73
|
+
*/
|
|
74
|
+
export type PolicyEdgeEnds<Value> = [EdgeRolesOf<Value>] extends [never] ? never : string extends EdgeRolesOf<Value> ? never : {
|
|
75
|
+
readonly [Role in EdgeRolesOf<Value> & string]: CanonicalPolicyPatternTerm;
|
|
76
|
+
};
|
|
16
77
|
export interface PolicyNodeBinder {
|
|
17
78
|
(): CanonicalPolicyPatternTerm;
|
|
18
79
|
(definition: NodeClassReferenceInput): CanonicalPolicyPatternTerm;
|
|
@@ -36,6 +97,23 @@ export interface PolicyPatternContext {
|
|
|
36
97
|
readonly object: CanonicalPolicyPatternTerm;
|
|
37
98
|
readonly source: CanonicalPolicyPatternTerm;
|
|
38
99
|
readonly target: CanonicalPolicyPatternTerm;
|
|
100
|
+
/**
|
|
101
|
+
* An Edge of `classValue` between two terms, each keyed by the role of its end: `{ [role]: term }`,
|
|
102
|
+
* the source's role written first by convention. It lowers to the pattern whose source is the
|
|
103
|
+
* term of the source's role and whose target is the term of the target's role. For an undirected
|
|
104
|
+
* Class, the first endpoint's role lowers to the source, and the roles only order the two terms:
|
|
105
|
+
* the pattern still matches an Edge between the two Nodes whichever end each Node holds.
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* edge(project_owned_by, { owner: subject, project })
|
|
109
|
+
* edge(() => subtask_of, { child: a, parent: b }, { repeat: { min: 1, max: 3 } })
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
edge<ClassValue extends PolicyEdgeClassInput>(classValue: ClassValue, ends: PolicyEdgeEnds<ClassValue>, options?: PolicyEdgeOptions): PolicyPatternExpression;
|
|
113
|
+
/**
|
|
114
|
+
* @deprecated Name the ends by their roles: `edge(classValue, { [role]: term }, { repeat })`
|
|
115
|
+
* lowers to this same pattern.
|
|
116
|
+
*/
|
|
39
117
|
edge(input: PolicyEdgeInput): PolicyPatternExpression;
|
|
40
118
|
exists(build: (context: PolicyExistsContext) => PolicyPatternExpression): PolicyPatternExpression;
|
|
41
119
|
allOf(first: PolicyPatternExpression, ...rest: readonly PolicyPatternExpression[]): PolicyPatternExpression;
|
|
@@ -63,6 +141,8 @@ export declare const policy: PolicyBuilder;
|
|
|
63
141
|
export declare function createPatternContext(options: {
|
|
64
142
|
readonly resolveObject: (value: PolicyObjectInput, pointer: string) => PolicyObjectRef;
|
|
65
143
|
readonly resolveEdgeClass: (value: EdgeClassReferenceInput, pointer: string) => ClassRef;
|
|
144
|
+
/** The roles of an Edge Class's source and target, or of an undirected Class's two endpoints. */
|
|
145
|
+
readonly edgeRoles: (ref: ClassRef) => readonly [source: string, target: string];
|
|
66
146
|
readonly resolveNodeClass: (value: NodeClassReferenceInput, pointer: string) => ClassRef;
|
|
67
147
|
readonly pointer: string;
|
|
68
148
|
}): PolicyPatternContext;
|