@astrale-os/kernel-dsl 1.0.0-beta.15 → 1.0.0-beta.17
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/builder/class/authoring.js +3 -2
- package/dist/v1/builder/class/input.d.ts +45 -14
- package/dist/v1/builder/index.d.ts +2 -1
- package/dist/v1/builder/lowering/class.d.ts +8 -0
- package/dist/v1/builder/lowering/class.js +40 -16
- package/dist/v1/builder/lowering/schema/compile.js +3 -3
- package/dist/v1/builder/policy/authoring.js +97 -88
- package/dist/v1/bundle/model.js +1 -1
- package/dist/v1/compiled/admission/accept.js +1 -7
- package/dist/v1/compiled/admission/semantics/class.js +2 -3
- package/dist/v1/compiled/admission/semantics/policy/parity.js +25 -13
- package/dist/v1/compiled/admission/semantics/policy/typing.js +2 -2
- package/dist/v1/compiled/admission/wire/class.js +23 -18
- 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/loader/load.js +1 -1
- package/dist/v1/domain/create.js +1 -1
- package/dist/v1/domain/model/input.d.ts +2 -1
- package/dist/v1/domain/projection/classes.js +1 -1
- package/dist/v1/domain/validation/create.d.ts +2 -1
- package/dist/v1/domain/validation/create.js +1 -1
- package/dist/v1/index.d.ts +1 -1
- package/dist/v1/language/.spec/schemas/draft-2020-12.schema.json +462 -0
- package/dist/v1/language/callable/resolved.d.ts +11 -2
- package/dist/v1/language/class/model/class.d.ts +17 -5
- package/dist/v1/language/freeze.d.ts +5 -0
- package/dist/v1/{schema/canonical → language}/freeze.js +4 -0
- package/dist/v1/language/policy/analysis/typing.d.ts +5 -2
- package/dist/v1/language/policy/analysis/typing.js +158 -42
- package/dist/v1/language/policy/model/policy.d.ts +44 -4
- 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 +5 -5
- package/dist/v1/language/validation/rule.d.ts +22 -6
- package/dist/v1/language/validation/rule.js +4 -15
- 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 +2 -2
- package/dist/v1/language/value/ordering.d.ts +5 -0
- package/dist/v1/language/value/ordering.js +14 -0
- 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/reference/closure.js +3 -4
- package/dist/v1/language/value/reference/registry.index.d.ts +2 -0
- package/dist/v1/language/value/reference/registry.index.js +31 -15
- package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +210 -27
- package/dist/v1/schema/admission/callable.js +1 -1
- package/dist/v1/schema/canonical/revision.js +4 -4
- package/dist/v1/schema/compatibility/comparators/callables.js +1 -1
- package/dist/v1/schema/compatibility/comparators/classes.js +4 -4
- 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/report.js +1 -1
- package/dist/v1/schema/compatibility/versioning/index.js +1 -1
- package/dist/v1/schema/model/schema.js +1 -1
- package/dist/v1/schema/normalization/domain.js +9 -8
- package/dist/v1/schema/resolution/domain.js +1 -1
- package/dist/v1/schema/resolution/origins.js +3 -2
- package/dist/v1/schema/rule.d.ts +8 -14
- package/dist/v1/schema/rule.js +14 -2
- package/dist/v1/schema/validation/class.d.ts +6 -2
- package/dist/v1/schema/validation/class.js +20 -25
- package/dist/v1/schema/validation/domain.js +1 -1
- package/dist/v1/schema/validation/domain.json-schema.d.ts +2 -2
- package/dist/v1/schema/validation/domain.json-schema.js +20 -6
- package/dist/v1/schema/validation/domain.structure.d.ts +4765 -1005
- package/dist/v1/schema/validation/domain.structure.js +21 -9
- package/dist/v1/schema/validation/json.json-schema.d.ts +18 -2
- package/dist/v1/schema/validation/json.json-schema.js +14 -4
- package/dist/v1/schema/validation/policy/budgets.d.ts +1 -1
- package/dist/v1/schema/validation/policy/budgets.js +4 -4
- package/dist/v1/schema/validation/policy/context.d.ts +1 -2
- package/dist/v1/schema/validation/policy/context.js +2 -7
- package/dist/v1/schema/validation/policy/uses.d.ts +10 -2
- package/dist/v1/schema/validation/policy/uses.js +26 -13
- package/dist/v1/schema/validation/policy/validate.js +2 -3
- package/dist/v1/schema/validation/value-api.d.ts +2 -0
- package/dist/v1/schema/validation/value-api.js +2 -0
- package/dist/v1/schema/validation/value.json-schema.d.ts +7 -9
- package/dist/v1/schema/validation/value.json-schema.js +38 -27
- package/package.json +2 -1
- 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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Value as JsonValue } from '@astrale-os/kernel-dsl/value';
|
|
1
|
+
import type { Value as JsonValue, Options } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import type { Diagnostic } from '../../validation/diagnostic.js';
|
|
3
3
|
import type { JsonSchema } from '../model/schema.js';
|
|
4
4
|
import type { ValueSchemaRegistry } from '../reference/registry.js';
|
|
@@ -13,4 +13,4 @@ import { type PatternPool } from './preparation.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function validateJsonInstance(schema: JsonSchema, value: JsonValue, registry: ValueSchemaRegistry, pointer?: string, patterns?: PatternPool): Diagnostic[];
|
|
15
15
|
/** Validate with the exact preparation already retained by a source-resolved Property or Callable. */
|
|
16
|
-
export declare function validatePreparedInstance(compiled: CompiledInstanceSchema, value: unknown): Diagnostic[];
|
|
16
|
+
export declare function validatePreparedInstance(compiled: CompiledInstanceSchema, value: unknown, options?: Options): Diagnostic[];
|
|
@@ -24,8 +24,8 @@ export function validateJsonInstance(schema, value, registry, pointer = '', patt
|
|
|
24
24
|
return instanceDiagnostics(prepared.value, value, pointer);
|
|
25
25
|
}
|
|
26
26
|
/** Validate with the exact preparation already retained by a source-resolved Property or Callable. */
|
|
27
|
-
export function validatePreparedInstance(compiled, value) {
|
|
28
|
-
const diagnostics = [...validateCanonicalJsonDomain(value, '')];
|
|
27
|
+
export function validatePreparedInstance(compiled, value, options) {
|
|
28
|
+
const diagnostics = [...validateCanonicalJsonDomain(value, '', options)];
|
|
29
29
|
return diagnostics.length > 0
|
|
30
30
|
? diagnostics
|
|
31
31
|
: instanceDiagnostics(compiled, value, '');
|
|
@@ -14,6 +14,11 @@ export declare function classifyOrdering(contract: JsonSchema, registry: ValueSc
|
|
|
14
14
|
/** Recompute the scalar ordering classification from one admitted portable value program. */
|
|
15
15
|
export declare function classifyValueProgramOrdering(program: ValueProgram): OrderingKind | undefined;
|
|
16
16
|
export declare function classifyPreparedOrdering(compiled: CompiledInstanceSchema): OrderingKind | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Every value kind `classifyValueKind` returns, frozen, in the order `ValueKind` names them. A kind
|
|
19
|
+
* added to `ValueKind` does not compile until it is listed here.
|
|
20
|
+
*/
|
|
21
|
+
export declare const VALUE_KINDS: readonly ValueKind[];
|
|
17
22
|
/**
|
|
18
23
|
* The value kind of a property schema (page "Fondations Query v7", § Atoms et value kinds, Y4):
|
|
19
24
|
* the one kind its non-null values admit, `null` being a point of every kind. An annotated
|
|
@@ -34,6 +34,20 @@ export function classifyPreparedOrdering(compiled) {
|
|
|
34
34
|
? kind
|
|
35
35
|
: undefined;
|
|
36
36
|
}
|
|
37
|
+
const valueKinds = {
|
|
38
|
+
text: true,
|
|
39
|
+
number: true,
|
|
40
|
+
instant: true,
|
|
41
|
+
enum: true,
|
|
42
|
+
boolean: true,
|
|
43
|
+
set: true,
|
|
44
|
+
json: true,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Every value kind `classifyValueKind` returns, frozen, in the order `ValueKind` names them. A kind
|
|
48
|
+
* added to `ValueKind` does not compile until it is listed here.
|
|
49
|
+
*/
|
|
50
|
+
export const VALUE_KINDS = Object.freeze(Object.keys(valueKinds));
|
|
37
51
|
/**
|
|
38
52
|
* The value kind of a property schema (page "Fondations Query v7", § Atoms et value kinds, Y4):
|
|
39
53
|
* the one kind its non-null values admit, `null` being a point of every kind. An annotated
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
import { type Options } from '@astrale-os/kernel-dsl/value';
|
|
1
2
|
import type { Diagnostic } from '../../validation/diagnostic.js';
|
|
2
|
-
|
|
3
|
+
/** Whether `value` is a portable JSON Value, within the portable limits `options` overrides. */
|
|
4
|
+
export declare function validateCanonicalJsonDomain(value: unknown, pointer: string, options?: Options): readonly Diagnostic[];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { acceptForRead as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { diagnostic } from '../../validation/diagnostic.js';
|
|
3
|
-
|
|
3
|
+
/** Whether `value` is a portable JSON Value, within the portable limits `options` overrides. */
|
|
4
|
+
export function validateCanonicalJsonDomain(value, pointer, options) {
|
|
4
5
|
try {
|
|
5
|
-
acceptJsonValue(value);
|
|
6
|
+
acceptJsonValue(value, options);
|
|
6
7
|
return [];
|
|
7
8
|
}
|
|
8
9
|
catch (error) {
|
|
@@ -36,10 +36,9 @@ export function collectResourceClosure(schema, context, index, pointer) {
|
|
|
36
36
|
const target = result.resolved.resource;
|
|
37
37
|
if (resources.has(target.key))
|
|
38
38
|
return;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
39
|
+
// The graph NodePath resource is no part of the schema: what it holds is reported at the
|
|
40
|
+
// $ref that names it.
|
|
41
|
+
const registered = { ...target, diagnosticPointer: refPointer };
|
|
43
42
|
resources.set(target.key, registered);
|
|
44
43
|
queue.push(registered);
|
|
45
44
|
});
|
|
@@ -5,6 +5,8 @@ export interface RegistryIndex {
|
|
|
5
5
|
readonly registry: ValueSchemaRegistry;
|
|
6
6
|
readonly domains: ReadonlyMap<string, ValueSchemaDomainRegistry>;
|
|
7
7
|
readonly dependenciesByOwner: ReadonlyMap<string, ReadonlyMap<string, string>>;
|
|
8
|
+
/** The `definitionRefIndex` of each Node Definition its own Domain lists. */
|
|
9
|
+
readonly nodeDefinitions: ReadonlySet<string>;
|
|
8
10
|
}
|
|
9
11
|
export declare function indexRegistry(registry: ValueSchemaRegistry, pointer: string): {
|
|
10
12
|
readonly index: RegistryIndex;
|
|
@@ -4,11 +4,21 @@ import { diagnostic } from '../../validation/diagnostic.js';
|
|
|
4
4
|
import { isValueObject as isJsonObject } from '../model/object.js';
|
|
5
5
|
import { JSON_SCHEMA_DIALECT } from '../model/schema.js';
|
|
6
6
|
import { GRAPH_NODE_PATH_SCHEMA_ID } from '../syntax/node-path/schema.js';
|
|
7
|
+
// A registry is an immutable value, and every value schema of a Domain is validated against the
|
|
8
|
+
// same one: an index that admitted it without a diagnostic is reused, so the closure is indexed
|
|
9
|
+
// once per registry rather than once per value schema.
|
|
10
|
+
const admittedIndexes = new WeakMap();
|
|
7
11
|
export function indexRegistry(registry, pointer) {
|
|
12
|
+
const admitted = admittedIndexes.get(registry);
|
|
13
|
+
if (admitted !== undefined)
|
|
14
|
+
return { index: admitted, diagnostics: [] };
|
|
8
15
|
const diagnostics = [];
|
|
9
16
|
const domains = new Map();
|
|
10
17
|
domains.set(registry.current.origin, registry.current);
|
|
11
|
-
|
|
18
|
+
// The registry is the closure the Kernel builds for the schema at `pointer`, not a document: a
|
|
19
|
+
// fault of one of its entries is a fault of the closure that schema is checked with, reported
|
|
20
|
+
// there, the entry named in the message.
|
|
21
|
+
validateDomainRegistry(registry.current, 'current', false, pointer, diagnostics);
|
|
12
22
|
const dependencies = [
|
|
13
23
|
...registry.directDependencies.map((domain) => ({ domain, lane: 'directDependencies' })),
|
|
14
24
|
...registry.transitiveDependencies.map((domain) => ({
|
|
@@ -17,10 +27,9 @@ export function indexRegistry(registry, pointer) {
|
|
|
17
27
|
})),
|
|
18
28
|
];
|
|
19
29
|
dependencies.forEach(({ domain, lane }, index) => {
|
|
20
|
-
|
|
21
|
-
validateDomainRegistry(domain, domainPointer, true, diagnostics);
|
|
30
|
+
validateDomainRegistry(domain, `${lane}/${index}`, true, pointer, diagnostics);
|
|
22
31
|
if (domain.origin === registry.current.origin || domains.has(domain.origin)) {
|
|
23
|
-
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION',
|
|
32
|
+
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION', pointer, `Registry origin ${domain.origin} is duplicated in the exact closure, at ${lane}/${index}.`));
|
|
24
33
|
return;
|
|
25
34
|
}
|
|
26
35
|
domains.set(domain.origin, domain);
|
|
@@ -37,31 +46,38 @@ export function indexRegistry(registry, pointer) {
|
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
48
|
}
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
const nodeDefinitions = new Set();
|
|
50
|
+
for (const domain of domains.values()) {
|
|
51
|
+
for (const ref of domain.nodeDefinitions) {
|
|
52
|
+
if (ref.origin === domain.origin)
|
|
53
|
+
nodeDefinitions.add(definitionRefIndex(ref));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
validateGraphNodePathResource(registry.graphNodePath, pointer, diagnostics);
|
|
57
|
+
const index = { registry, domains, dependenciesByOwner, nodeDefinitions };
|
|
58
|
+
if (diagnostics.length === 0)
|
|
59
|
+
admittedIndexes.set(registry, index);
|
|
60
|
+
return { index, diagnostics };
|
|
42
61
|
}
|
|
43
62
|
export function isOriginVisibleFrom(index, ownerOrigin, targetOrigin) {
|
|
44
63
|
return (ownerOrigin === targetOrigin ||
|
|
45
64
|
index.dependenciesByOwner.get(ownerOrigin)?.has(targetOrigin) === true);
|
|
46
65
|
}
|
|
47
66
|
export function hasNodeDefinition(index, ref, ownerOrigin) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return (index.domains
|
|
51
|
-
.get(ref.origin)
|
|
52
|
-
?.nodeDefinitions.some((candidate) => definitionRefIndex(candidate) === definitionRefIndex(ref)) === true);
|
|
67
|
+
return (isOriginVisibleFrom(index, ownerOrigin, ref.origin) &&
|
|
68
|
+
index.nodeDefinitions.has(definitionRefIndex(ref)));
|
|
53
69
|
}
|
|
54
|
-
function validateDomainRegistry(domain,
|
|
70
|
+
function validateDomainRegistry(domain, entry, revisionRequired, pointer, diagnostics) {
|
|
55
71
|
if (!DOMAIN_ORIGIN_PATTERN.test(domain.origin)) {
|
|
56
|
-
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION',
|
|
72
|
+
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION', pointer, `Registry origin is invalid, at ${entry}.`));
|
|
57
73
|
}
|
|
58
74
|
if ((revisionRequired && domain.revision === undefined) ||
|
|
59
75
|
(domain.revision !== undefined && !DOMAIN_REVISION_PATTERN.test(domain.revision))) {
|
|
60
|
-
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION',
|
|
76
|
+
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION', pointer, `A dependency-closure registry entry requires its exact sha256 revision, at ${entry}.`));
|
|
61
77
|
}
|
|
62
78
|
for (const ref of domain.nodeDefinitions) {
|
|
63
79
|
if (ref.origin !== domain.origin) {
|
|
64
|
-
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION',
|
|
80
|
+
diagnostics.push(diagnostic('VS_REFERENCE_RESOLUTION', pointer, `A registry domain can list only its own Node Definitions, at ${entry}.`));
|
|
65
81
|
}
|
|
66
82
|
}
|
|
67
83
|
}
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"code": "DV_VALUE_SCHEMA",
|
|
47
47
|
"valueCode": "VS_PATH_EXTENSION",
|
|
48
48
|
"stage": "rule",
|
|
49
|
-
"statement": "x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema
|
|
49
|
+
"statement": "x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema.",
|
|
50
50
|
"positions": [
|
|
51
51
|
"#/$defs/value-location/anyOf/1/properties/x-astrale-path"
|
|
52
52
|
]
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"stage": "context",
|
|
76
76
|
"statement": "A $ref resolves to a location of its own value schema, and x-astrale-path accepts Node Classes of the Domain or of a direct dependency.",
|
|
77
77
|
"positions": [
|
|
78
|
+
"#/$defs/path-annotation/properties/accepts/items",
|
|
78
79
|
"#/$defs/value-location/anyOf/1/properties/$ref"
|
|
79
80
|
]
|
|
80
81
|
},
|
|
@@ -322,17 +323,6 @@
|
|
|
322
323
|
}
|
|
323
324
|
]
|
|
324
325
|
},
|
|
325
|
-
"class-policy": {
|
|
326
|
-
"anyOf": [
|
|
327
|
-
{
|
|
328
|
-
"type": "boolean",
|
|
329
|
-
"const": false
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
"$ref": "#/$defs/policy-ref"
|
|
333
|
-
}
|
|
334
|
-
]
|
|
335
|
-
},
|
|
336
326
|
"class-ref": {
|
|
337
327
|
"type": "object",
|
|
338
328
|
"properties": {
|
|
@@ -586,6 +576,136 @@
|
|
|
586
576
|
"maxLength": 100,
|
|
587
577
|
"pattern": "^(?=.{1,100}$)[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)*$"
|
|
588
578
|
},
|
|
579
|
+
"create-policy": {
|
|
580
|
+
"anyOf": [
|
|
581
|
+
{
|
|
582
|
+
"type": "boolean",
|
|
583
|
+
"const": true
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
587
|
+
}
|
|
588
|
+
]
|
|
589
|
+
},
|
|
590
|
+
"create-rule-check-expr": {
|
|
591
|
+
"anyOf": [
|
|
592
|
+
{
|
|
593
|
+
"type": "object",
|
|
594
|
+
"properties": {
|
|
595
|
+
"sameNode": {
|
|
596
|
+
"type": "object",
|
|
597
|
+
"properties": {
|
|
598
|
+
"left": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": {
|
|
601
|
+
"kind": {
|
|
602
|
+
"type": "string",
|
|
603
|
+
"const": "ref"
|
|
604
|
+
},
|
|
605
|
+
"ref": {
|
|
606
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
"required": [
|
|
610
|
+
"kind",
|
|
611
|
+
"ref"
|
|
612
|
+
],
|
|
613
|
+
"additionalProperties": false
|
|
614
|
+
},
|
|
615
|
+
"right": {
|
|
616
|
+
"type": "object",
|
|
617
|
+
"properties": {
|
|
618
|
+
"kind": {
|
|
619
|
+
"type": "string",
|
|
620
|
+
"const": "ref"
|
|
621
|
+
},
|
|
622
|
+
"ref": {
|
|
623
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
"required": [
|
|
627
|
+
"kind",
|
|
628
|
+
"ref"
|
|
629
|
+
],
|
|
630
|
+
"additionalProperties": false
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
"required": [
|
|
634
|
+
"left",
|
|
635
|
+
"right"
|
|
636
|
+
],
|
|
637
|
+
"additionalProperties": false
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
"required": [
|
|
641
|
+
"sameNode"
|
|
642
|
+
],
|
|
643
|
+
"additionalProperties": false
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"type": "object",
|
|
647
|
+
"properties": {
|
|
648
|
+
"check": {
|
|
649
|
+
"$ref": "#/$defs/policy-ref"
|
|
650
|
+
},
|
|
651
|
+
"object": {
|
|
652
|
+
"type": "object",
|
|
653
|
+
"properties": {
|
|
654
|
+
"kind": {
|
|
655
|
+
"type": "string",
|
|
656
|
+
"const": "ref"
|
|
657
|
+
},
|
|
658
|
+
"ref": {
|
|
659
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"required": [
|
|
663
|
+
"kind",
|
|
664
|
+
"ref"
|
|
665
|
+
],
|
|
666
|
+
"additionalProperties": false
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
"required": [
|
|
670
|
+
"check",
|
|
671
|
+
"object"
|
|
672
|
+
],
|
|
673
|
+
"additionalProperties": false
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"type": "object",
|
|
677
|
+
"properties": {
|
|
678
|
+
"allOf": {
|
|
679
|
+
"minItems": 1,
|
|
680
|
+
"type": "array",
|
|
681
|
+
"items": {
|
|
682
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
"required": [
|
|
687
|
+
"allOf"
|
|
688
|
+
],
|
|
689
|
+
"additionalProperties": false
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
"type": "object",
|
|
693
|
+
"properties": {
|
|
694
|
+
"anyOf": {
|
|
695
|
+
"minItems": 1,
|
|
696
|
+
"type": "array",
|
|
697
|
+
"items": {
|
|
698
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
"required": [
|
|
703
|
+
"anyOf"
|
|
704
|
+
],
|
|
705
|
+
"additionalProperties": false
|
|
706
|
+
}
|
|
707
|
+
]
|
|
708
|
+
},
|
|
589
709
|
"dependency": {
|
|
590
710
|
"type": "object",
|
|
591
711
|
"properties": {
|
|
@@ -779,10 +899,19 @@
|
|
|
779
899
|
"type": "object",
|
|
780
900
|
"properties": {
|
|
781
901
|
"read": {
|
|
782
|
-
"$ref": "#/$defs/
|
|
902
|
+
"$ref": "#/$defs/observation-policy"
|
|
783
903
|
},
|
|
784
904
|
"traverse": {
|
|
785
|
-
"$ref": "#/$defs/
|
|
905
|
+
"$ref": "#/$defs/observation-policy"
|
|
906
|
+
},
|
|
907
|
+
"create": {
|
|
908
|
+
"$ref": "#/$defs/write-policy"
|
|
909
|
+
},
|
|
910
|
+
"update": {
|
|
911
|
+
"$ref": "#/$defs/write-policy"
|
|
912
|
+
},
|
|
913
|
+
"delete": {
|
|
914
|
+
"$ref": "#/$defs/write-policy"
|
|
786
915
|
}
|
|
787
916
|
},
|
|
788
917
|
"additionalProperties": false
|
|
@@ -1259,10 +1388,19 @@
|
|
|
1259
1388
|
"type": "object",
|
|
1260
1389
|
"properties": {
|
|
1261
1390
|
"read": {
|
|
1262
|
-
"$ref": "#/$defs/
|
|
1391
|
+
"$ref": "#/$defs/observation-policy"
|
|
1263
1392
|
},
|
|
1264
1393
|
"traverse": {
|
|
1265
|
-
"$ref": "#/$defs/
|
|
1394
|
+
"$ref": "#/$defs/observation-policy"
|
|
1395
|
+
},
|
|
1396
|
+
"create": {
|
|
1397
|
+
"$ref": "#/$defs/create-policy"
|
|
1398
|
+
},
|
|
1399
|
+
"update": {
|
|
1400
|
+
"$ref": "#/$defs/write-policy"
|
|
1401
|
+
},
|
|
1402
|
+
"delete": {
|
|
1403
|
+
"$ref": "#/$defs/write-policy"
|
|
1266
1404
|
}
|
|
1267
1405
|
},
|
|
1268
1406
|
"additionalProperties": false
|
|
@@ -1292,16 +1430,6 @@
|
|
|
1292
1430
|
],
|
|
1293
1431
|
"additionalProperties": false
|
|
1294
1432
|
},
|
|
1295
|
-
"node-class-policy": {
|
|
1296
|
-
"anyOf": [
|
|
1297
|
-
{
|
|
1298
|
-
"$ref": "#/$defs/class-policy"
|
|
1299
|
-
},
|
|
1300
|
-
{
|
|
1301
|
-
"$ref": "#/$defs/class-rule-check-expr"
|
|
1302
|
-
}
|
|
1303
|
-
]
|
|
1304
|
-
},
|
|
1305
1433
|
"node-property-definition": {
|
|
1306
1434
|
"type": "object",
|
|
1307
1435
|
"properties": {
|
|
@@ -1378,12 +1506,53 @@
|
|
|
1378
1506
|
"$ref": "#/$defs/node-property-definition"
|
|
1379
1507
|
}
|
|
1380
1508
|
},
|
|
1509
|
+
"observation-policy": {
|
|
1510
|
+
"anyOf": [
|
|
1511
|
+
{
|
|
1512
|
+
"type": "boolean",
|
|
1513
|
+
"const": false
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
"$ref": "#/$defs/policy-ref"
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
"$ref": "#/$defs/class-rule-check-expr"
|
|
1520
|
+
}
|
|
1521
|
+
]
|
|
1522
|
+
},
|
|
1381
1523
|
"origin": {
|
|
1382
1524
|
"type": "string",
|
|
1383
1525
|
"minLength": 3,
|
|
1384
1526
|
"maxLength": 253,
|
|
1385
1527
|
"pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"
|
|
1386
1528
|
},
|
|
1529
|
+
"path-annotation": {
|
|
1530
|
+
"type": "object",
|
|
1531
|
+
"properties": {
|
|
1532
|
+
"target": {
|
|
1533
|
+
"type": "string",
|
|
1534
|
+
"const": "node"
|
|
1535
|
+
},
|
|
1536
|
+
"cardinality": {
|
|
1537
|
+
"type": "string",
|
|
1538
|
+
"const": "one"
|
|
1539
|
+
},
|
|
1540
|
+
"accepts": {
|
|
1541
|
+
"type": "array",
|
|
1542
|
+
"minItems": 1,
|
|
1543
|
+
"uniqueItems": true,
|
|
1544
|
+
"items": {
|
|
1545
|
+
"$ref": "#/$defs/class-ref"
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
},
|
|
1549
|
+
"required": [
|
|
1550
|
+
"target",
|
|
1551
|
+
"cardinality",
|
|
1552
|
+
"accepts"
|
|
1553
|
+
],
|
|
1554
|
+
"additionalProperties": false
|
|
1555
|
+
},
|
|
1387
1556
|
"policy-check-expr": {
|
|
1388
1557
|
"anyOf": [
|
|
1389
1558
|
{
|
|
@@ -2100,7 +2269,7 @@
|
|
|
2100
2269
|
"type": "string"
|
|
2101
2270
|
},
|
|
2102
2271
|
"x-astrale-path": {
|
|
2103
|
-
"
|
|
2272
|
+
"$ref": "#/$defs/path-annotation"
|
|
2104
2273
|
},
|
|
2105
2274
|
"additionalProperties": {
|
|
2106
2275
|
"$ref": "#/$defs/value-subschema"
|
|
@@ -2331,6 +2500,20 @@
|
|
|
2331
2500
|
],
|
|
2332
2501
|
"additionalProperties": false,
|
|
2333
2502
|
"description": "Every View targets its owning Domain."
|
|
2503
|
+
},
|
|
2504
|
+
"write-policy": {
|
|
2505
|
+
"anyOf": [
|
|
2506
|
+
{
|
|
2507
|
+
"type": "boolean",
|
|
2508
|
+
"const": true
|
|
2509
|
+
},
|
|
2510
|
+
{
|
|
2511
|
+
"$ref": "#/$defs/policy-ref"
|
|
2512
|
+
},
|
|
2513
|
+
{
|
|
2514
|
+
"$ref": "#/$defs/class-rule-check-expr"
|
|
2515
|
+
}
|
|
2516
|
+
]
|
|
2334
2517
|
}
|
|
2335
2518
|
}
|
|
2336
2519
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { definitionRefIndex } from '../../addressing/ordering.js';
|
|
3
3
|
import { isBinaryInput } from '../../language/callable/model/callable.js';
|
|
4
|
+
import { deepFreeze } from '../../language/freeze.js';
|
|
4
5
|
import { measureChecks } from '../../language/policy/analysis/budgets.js';
|
|
5
6
|
import { PolicyTyping } from '../../language/policy/analysis/typing.js';
|
|
6
7
|
import { normalizePolicyChecks } from '../../language/policy/normalization/normalize.js';
|
|
7
8
|
import {} from '../../language/value/evaluate/preparation.js';
|
|
8
9
|
import { analyzeDefinitions } from '../analysis/class.js';
|
|
9
|
-
import { deepFreeze } from '../canonical/freeze.js';
|
|
10
10
|
import { SchemaError, diagnostic } from '../diagnostic.js';
|
|
11
11
|
import { canonicalizeCallable } from '../normalization/domain.js';
|
|
12
12
|
import { lookupForDomainClosure } from '../resolution/closure.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { digestRevisionBytes } from '../../addressing/revision.js';
|
|
2
3
|
import { asDomainSchema } from '../model/schema.js';
|
|
3
|
-
import {
|
|
4
|
-
import { canonicalizeDomainSchema } from './domain.js';
|
|
4
|
+
import { normalizeDomainSchema } from '../normalization/domain.js';
|
|
5
5
|
// Only canonical schemas created here own a retained revision, never caller-owned input.
|
|
6
6
|
const revisions = new WeakMap();
|
|
7
7
|
export function canonicalDomainSchema(value) {
|
|
@@ -9,9 +9,9 @@ export function canonicalDomainSchema(value) {
|
|
|
9
9
|
}
|
|
10
10
|
/** Internal acceptance seam. The caller must establish whole-Domain validity first. */
|
|
11
11
|
export function canonicalDomainSchemaAfterValidation(value) {
|
|
12
|
-
const schema = asDomainSchema(
|
|
12
|
+
const schema = asDomainSchema(normalizeDomainSchema(value));
|
|
13
13
|
const bytes = json.encode(schema);
|
|
14
|
-
const revision =
|
|
14
|
+
const revision = digestRevisionBytes(bytes);
|
|
15
15
|
revisions.set(schema, revision);
|
|
16
16
|
return Object.freeze({ schema, bytes, revision });
|
|
17
17
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isMethodExecutable } from '../../../language/callable/executable.js';
|
|
2
2
|
import { isBinaryInput } from '../../../language/callable/model/callable.js';
|
|
3
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
3
4
|
import { methodSignature as inheritedSignature } from '../../analysis/class.js';
|
|
4
|
-
import { deepFreeze } from '../../canonical/freeze.js';
|
|
5
5
|
import { keyForDefinitionRef } from '../coordinate.js';
|
|
6
6
|
import { CALLABLE_FIELDS, fieldsOf } from '../fields.js';
|
|
7
7
|
import { fingerprintMeaning, semanticValueSchema } from './values.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { compareUnicode } from '../../../addressing/ordering.js';
|
|
2
2
|
import { compareEdgeUniqueTuples, coveringEdgeUniqueTuples, } from '../../../language/class/unique.js';
|
|
3
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
3
4
|
import { isClassRuleChecks } from '../../../language/policy/model/policy.js';
|
|
4
|
-
import { deepFreeze } from '../../canonical/freeze.js';
|
|
5
5
|
import { effectiveDefinition } from '../context.js';
|
|
6
6
|
import { propertyCoordinate } from '../coordinate.js';
|
|
7
7
|
import { keyForDefinitionRef } from '../coordinate.js';
|
|
@@ -56,12 +56,12 @@ export function classMeaning(context, coordinate, level, onto) {
|
|
|
56
56
|
return { meaning: deepFreeze(meaning), requirement };
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* A named Policy compares by its key;
|
|
59
|
+
* A named Policy compares by its key; a constant or Policy checks by their value, as a callable's
|
|
60
60
|
* Policy does.
|
|
61
61
|
*/
|
|
62
62
|
function classPolicyMeaning(policy) {
|
|
63
|
-
if (policy ===
|
|
64
|
-
return
|
|
63
|
+
if (typeof policy === 'boolean')
|
|
64
|
+
return policy;
|
|
65
65
|
return isClassRuleChecks(policy) ? policy : keyForDefinitionRef(policy);
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepFreeze } from '
|
|
1
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
2
2
|
import { CORE_FIELDS, POLICY_FIELDS, VIEW_FIELDS, fieldsOf } from '../fields.js';
|
|
3
3
|
import { functionSignature } from './callables.js';
|
|
4
4
|
export function memberMeaning(owner, ref) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { digestRevisionBytes } from '../../../addressing/revision.js';
|
|
2
3
|
import { isValueObject as isJsonObject } from '../../../language/value/model/object.js';
|
|
3
4
|
import { SCHEMA_ARRAY_KEYWORDS, SCHEMA_MAP_KEYWORDS, SCHEMA_SINGLE_KEYWORDS, } from '../../../language/value/syntax/keywords.js';
|
|
4
|
-
import { digestDomainSchemaBytes } from '../../canonical/domain.digest.js';
|
|
5
5
|
import { ANNOTATION_KEYWORDS } from '../fields.js';
|
|
6
6
|
/** Drop annotation keywords wherever a schema keyword nests a schema; never inside data. */
|
|
7
7
|
export function semanticValueSchema(value) {
|
|
@@ -30,7 +30,7 @@ export function semanticValueSchema(value) {
|
|
|
30
30
|
return semantic;
|
|
31
31
|
}
|
|
32
32
|
export function fingerprintMeaning(value) {
|
|
33
|
-
return
|
|
33
|
+
return digestRevisionBytes(json.encode(value));
|
|
34
34
|
}
|
|
35
35
|
function isJsonSchema(value) {
|
|
36
36
|
return typeof value === 'boolean' || isJsonObject(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { compareUnicode } from '../../addressing/ordering.js';
|
|
3
|
-
import { deepFreeze } from '
|
|
3
|
+
import { deepFreeze } from '../../language/freeze.js';
|
|
4
4
|
import { fingerprintMeaning } from './comparators/values.js';
|
|
5
5
|
import { differences } from './diff.js';
|
|
6
6
|
import { schemaIdentity } from './references.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepFreeze } from '
|
|
1
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
2
2
|
import { SchemaError, diagnostic } from '../../diagnostic.js';
|
|
3
3
|
import { compareFootprint } from '../meaning/footprint.js';
|
|
4
4
|
import { schemaIdentity } from '../references.js';
|