@astrale-os/kernel-dsl 1.0.0-beta.12 → 1.0.0-beta.14

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.
Files changed (152) hide show
  1. package/dist/v1/addressing/definition-ref.js +21 -37
  2. package/dist/v1/addressing/key.js +2 -1
  3. package/dist/v1/addressing/ordering.d.ts +2 -0
  4. package/dist/v1/addressing/ordering.js +4 -0
  5. package/dist/v1/addressing/patterns.d.ts +1 -1
  6. package/dist/v1/addressing/patterns.js +2 -6
  7. package/dist/v1/builder/class/authoring.js +5 -28
  8. package/dist/v1/builder/class/property.d.ts +3 -9
  9. package/dist/v1/builder/class/property.js +1 -0
  10. package/dist/v1/builder/lowering/class.js +5 -1
  11. package/dist/v1/builder/lowering/policy.js +1 -0
  12. package/dist/v1/builder/lowering/schema/context.js +2 -4
  13. package/dist/v1/builder/lowering/value/path.js +2 -4
  14. package/dist/v1/builder/lowering/value/zod.js +1 -3
  15. package/dist/v1/builder/policy/authoring.js +3 -2
  16. package/dist/v1/builder/schema/define.d.ts +0 -1
  17. package/dist/v1/builder/schema/diagnostic.d.ts +2 -1
  18. package/dist/v1/builder/schema/diagnostic.js +5 -10
  19. package/dist/v1/builder/schema/projection.d.ts +1 -1
  20. package/dist/v1/builder/value/full-match.d.ts +0 -1
  21. package/dist/v1/builder/value/full-match.js +0 -1
  22. package/dist/v1/bundle/codec.js +4 -6
  23. package/dist/v1/bundle/diagnostic.d.ts +2 -0
  24. package/dist/v1/bundle/diagnostic.js +9 -7
  25. package/dist/v1/bundle/structure.js +4 -6
  26. package/dist/v1/compiled/admission/diagnostic.d.ts +1 -1
  27. package/dist/v1/compiled/admission/diagnostic.js +1 -3
  28. package/dist/v1/compiled/admission/revision.d.ts +9 -1
  29. package/dist/v1/compiled/admission/revision.js +6 -3
  30. package/dist/v1/compiled/admission/semantics/class.d.ts +4 -1
  31. package/dist/v1/compiled/admission/semantics/class.js +4 -8
  32. package/dist/v1/compiled/admission/semantics/core.d.ts +1 -24
  33. package/dist/v1/compiled/admission/semantics/core.js +54 -34
  34. package/dist/v1/compiled/admission/semantics/edge.d.ts +2 -4
  35. package/dist/v1/compiled/admission/semantics/edge.js +6 -65
  36. package/dist/v1/compiled/admission/semantics/policy/callable.js +0 -2
  37. package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +5 -20
  38. package/dist/v1/compiled/admission/semantics/policy/contracts.js +8 -21
  39. package/dist/v1/compiled/admission/semantics/policy/parity.js +13 -22
  40. package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +4 -1
  41. package/dist/v1/compiled/admission/semantics/policy/pattern.js +4 -16
  42. package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +2 -24
  43. package/dist/v1/compiled/admission/semantics/policy/typing.js +19 -201
  44. package/dist/v1/compiled/compiler/compile.js +6 -8
  45. package/dist/v1/compiled/diagnostic.js +2 -3
  46. package/dist/v1/compiled/loader/load.d.ts +3 -2
  47. package/dist/v1/compiled/loader/load.js +10 -44
  48. package/dist/v1/domain/create.js +3 -5
  49. package/dist/v1/domain/namespace/member-collection.js +4 -6
  50. package/dist/v1/domain/validation/create.d.ts +4 -2
  51. package/dist/v1/domain/validation/create.js +21 -69
  52. package/dist/v1/language/.spec/schemas/value-schema.schema.json +22 -0
  53. package/dist/v1/language/class/inheritance.d.ts +18 -0
  54. package/dist/v1/language/class/inheritance.js +73 -0
  55. package/dist/v1/language/class/model/class.d.ts +4 -4
  56. package/dist/v1/language/class/model/edge.d.ts +2 -2
  57. package/dist/v1/language/class/model/property.d.ts +16 -7
  58. package/dist/v1/language/class/property-values.js +2 -4
  59. package/dist/v1/language/core/facts.d.ts +72 -0
  60. package/dist/v1/language/core/facts.js +95 -0
  61. package/dist/v1/language/definition/metadata.d.ts +5 -0
  62. package/dist/v1/language/definition/metadata.js +7 -0
  63. package/dist/v1/language/policy/analysis/branches.d.ts +8 -0
  64. package/dist/v1/language/policy/analysis/branches.js +2 -1
  65. package/dist/v1/language/policy/analysis/budgets.d.ts +13 -1
  66. package/dist/v1/language/policy/analysis/budgets.js +104 -0
  67. package/dist/v1/language/policy/analysis/typing.d.ts +48 -0
  68. package/dist/v1/language/policy/analysis/typing.js +338 -0
  69. package/dist/v1/language/policy/model/policy.d.ts +5 -5
  70. package/dist/v1/language/policy/normalization/normalize.js +17 -16
  71. package/dist/v1/language/validation/diagnostic.d.ts +15 -1
  72. package/dist/v1/language/validation/diagnostic.js +21 -0
  73. package/dist/v1/language/validation/rule.d.ts +26 -0
  74. package/dist/v1/language/validation/rule.js +116 -0
  75. package/dist/v1/language/value/compile/fields.js +4 -8
  76. package/dist/v1/language/value/profile/meta-schema.compiled.js +4 -1
  77. package/dist/v1/language/value/profile/rules.js +17 -43
  78. package/dist/v1/language/value/profile/validate.js +1 -10
  79. package/dist/v1/language/value/profile/vocabulary.d.ts +35 -2
  80. package/dist/v1/language/value/profile/vocabulary.js +52 -5
  81. package/dist/v1/language/value/reference/recursion.js +2 -22
  82. package/dist/v1/language/value/reference/registry.index.js +2 -1
  83. package/dist/v1/language/value/syntax/keywords.d.ts +3 -3
  84. package/dist/v1/language/value/syntax/keywords.js +4 -20
  85. package/dist/v1/language/value/syntax/node-path/validate.js +2 -3
  86. package/dist/v1/language/value/syntax/pointer.d.ts +2 -0
  87. package/dist/v1/language/value/syntax/pointer.js +5 -2
  88. package/dist/v1/language/value/syntax/walk.d.ts +2 -0
  89. package/dist/v1/language/value/syntax/walk.js +19 -20
  90. package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +2336 -0
  91. package/dist/v1/schema/analysis/class.js +33 -15
  92. package/dist/v1/schema/compatibility/api.d.ts +1 -1
  93. package/dist/v1/schema/compatibility/coordinate.js +3 -3
  94. package/dist/v1/schema/compatibility/diff.js +2 -4
  95. package/dist/v1/schema/compatibility/meaning/footprint.js +16 -50
  96. package/dist/v1/schema/compatibility/model.d.ts +5 -0
  97. package/dist/v1/schema/compatibility/structure/requirements.js +26 -58
  98. package/dist/v1/schema/compatibility/walk.d.ts +17 -0
  99. package/dist/v1/schema/compatibility/walk.js +41 -0
  100. package/dist/v1/schema/diagnostic.d.ts +17 -3
  101. package/dist/v1/schema/diagnostic.js +14 -11
  102. package/dist/v1/schema/index.d.ts +3 -1
  103. package/dist/v1/schema/index.js +1 -0
  104. package/dist/v1/schema/model/schema.d.ts +19 -1
  105. package/dist/v1/schema/normalization/domain.js +1 -0
  106. package/dist/v1/schema/resolution/closure.js +2 -1
  107. package/dist/v1/schema/resolution/context.js +6 -6
  108. package/dist/v1/schema/rule.d.ts +29 -0
  109. package/dist/v1/schema/rule.js +415 -0
  110. package/dist/v1/schema/validation/callable.d.ts +4 -1
  111. package/dist/v1/schema/validation/callable.js +13 -6
  112. package/dist/v1/schema/validation/class.js +46 -96
  113. package/dist/v1/schema/validation/core.js +68 -202
  114. package/dist/v1/schema/validation/domain.js +1 -10
  115. package/dist/v1/schema/validation/domain.json-schema.d.ts +15 -0
  116. package/dist/v1/schema/validation/domain.json-schema.js +183 -0
  117. package/dist/v1/schema/validation/domain.structure.d.ts +4018 -0
  118. package/dist/v1/schema/validation/domain.structure.js +343 -155
  119. package/dist/v1/schema/validation/json.json-schema.d.ts +24 -0
  120. package/dist/v1/schema/validation/json.json-schema.js +36 -0
  121. package/dist/v1/schema/validation/policy/budgets.js +5 -112
  122. package/dist/v1/schema/validation/policy/context.d.ts +5 -3
  123. package/dist/v1/schema/validation/policy/context.js +5 -3
  124. package/dist/v1/schema/validation/policy/objects.d.ts +1 -1
  125. package/dist/v1/schema/validation/policy/objects.js +6 -14
  126. package/dist/v1/schema/validation/policy/references.js +10 -27
  127. package/dist/v1/schema/validation/policy/typing.d.ts +3 -18
  128. package/dist/v1/schema/validation/policy/typing.js +22 -356
  129. package/dist/v1/schema/validation/policy/uses.d.ts +1 -1
  130. package/dist/v1/schema/validation/policy/uses.js +9 -25
  131. package/dist/v1/schema/validation/policy/validate.js +3 -2
  132. package/dist/v1/schema/validation/value-api.d.ts +12 -1
  133. package/dist/v1/schema/validation/value-api.js +12 -3
  134. package/dist/v1/schema/validation/value.js +8 -10
  135. package/dist/v1/schema/validation/value.json-schema.d.ts +51 -0
  136. package/dist/v1/schema/validation/value.json-schema.js +126 -0
  137. package/dist/v1/schema/validation/view.js +4 -8
  138. package/package.json +3 -1
  139. package/dist/v1/compiled/admission/semantics/cardinality.d.ts +0 -5
  140. package/dist/v1/compiled/admission/semantics/cardinality.js +0 -128
  141. package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +0 -8
  142. package/dist/v1/compiled/admission/semantics/policy/equality.js +0 -27
  143. package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +0 -9
  144. package/dist/v1/compiled/admission/semantics/policy/measure.js +0 -81
  145. package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +0 -10
  146. package/dist/v1/compiled/admission/semantics/policy/variants.js +0 -65
  147. package/dist/v1/language/class/index.d.ts +0 -8
  148. package/dist/v1/language/class/index.js +0 -1
  149. package/dist/v1/language/core/index.d.ts +0 -2
  150. package/dist/v1/language/core/index.js +0 -1
  151. package/dist/v1/language/value/index.d.ts +0 -11
  152. package/dist/v1/language/value/index.js +0 -8
@@ -8,55 +8,39 @@ const DEFINITION_KINDS = new Set([
8
8
  ]);
9
9
  /** Admit and detach one canonical DefinitionRef from an untrusted value. */
10
10
  export function acceptDefinitionRef(input) {
11
- if (input === null || typeof input !== 'object' || Array.isArray(input)) {
12
- invalid(input);
13
- }
11
+ return readDefinitionRef(input) ?? invalid(input);
12
+ }
13
+ /** Identify a canonical DefinitionRef-shaped value without retaining caller state. */
14
+ export function isDefinitionRef(input) {
15
+ return readDefinitionRef(input) !== undefined;
16
+ }
17
+ /** Compare exact Definition coordinates, independent of object identity. */
18
+ export function equalDefinitionRefs(left, right) {
19
+ return left.origin === right.origin && left.kind === right.kind && left.name === right.name;
20
+ }
21
+ function invalid(input) {
22
+ throw new TypeError(`Invalid DefinitionRef: ${JSON.stringify(input)}.`);
23
+ }
24
+ /** A detached copy of the canonical DefinitionRef `input` holds, reading each field once. */
25
+ function readDefinitionRef(input) {
26
+ if (input === null || typeof input !== 'object' || Array.isArray(input))
27
+ return undefined;
14
28
  const value = input;
15
29
  const keys = Reflect.ownKeys(value);
16
30
  if (keys.length !== 3 ||
17
31
  !keys.every((key) => key === 'origin' || key === 'kind' || key === 'name')) {
18
- invalid(input);
32
+ return undefined;
19
33
  }
20
- const origin = value.origin;
21
- const kind = value.kind;
22
- const name = value.name;
34
+ const { origin, kind, name } = value;
23
35
  if (typeof origin !== 'string' ||
24
36
  !DOMAIN_ORIGIN_PATTERN.test(origin) ||
25
37
  typeof kind !== 'string' ||
26
38
  !DEFINITION_KINDS.has(kind) ||
27
39
  typeof name !== 'string' ||
28
40
  !definitionNameMatches(kind, name)) {
29
- invalid(input);
41
+ return undefined;
30
42
  }
31
- return Object.freeze({
32
- origin,
33
- kind: kind,
34
- name,
35
- });
36
- }
37
- /** Identify a canonical DefinitionRef-shaped value without retaining caller state. */
38
- export function isDefinitionRef(input) {
39
- if (input === null || typeof input !== 'object' || Array.isArray(input))
40
- return false;
41
- const value = input;
42
- const keys = Reflect.ownKeys(value);
43
- if (keys.length !== 3 ||
44
- !keys.every((key) => key === 'origin' || key === 'kind' || key === 'name')) {
45
- return false;
46
- }
47
- return (typeof value.origin === 'string' &&
48
- DOMAIN_ORIGIN_PATTERN.test(value.origin) &&
49
- typeof value.kind === 'string' &&
50
- DEFINITION_KINDS.has(value.kind) &&
51
- typeof value.name === 'string' &&
52
- definitionNameMatches(value.kind, value.name));
53
- }
54
- /** Compare exact Definition coordinates, independent of object identity. */
55
- export function equalDefinitionRefs(left, right) {
56
- return left.origin === right.origin && left.kind === right.kind && left.name === right.name;
57
- }
58
- function invalid(input) {
59
- throw new TypeError(`Invalid DefinitionRef: ${JSON.stringify(input)}.`);
43
+ return Object.freeze({ origin, kind: kind, name });
60
44
  }
61
45
  function definitionNameMatches(kind, name) {
62
46
  return kind === 'core' ? CORE_SLUG_PATTERN.test(name) : MEMBER_NAME_PATTERN.test(name);
@@ -1,7 +1,8 @@
1
1
  import { acceptDefinitionRef, } from './definition-ref.js';
2
2
  import { DOMAIN_ORIGIN_PATTERN } from './patterns.js';
3
3
  const DEFINITION_KEY = /^(?:class|function|policy|view)\.([A-Za-z][A-Za-z0-9_]*)$/u;
4
- const CORE_KEY = /^core\.([a-z][a-z0-9-]{0,99})$/u;
4
+ // The slug is the whole rest of the coordinate, its own `.` included: no member follows a Core key.
5
+ const CORE_KEY = /^core\.((?=.{1,100}$)[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*)$/u;
5
6
  const MEMBER_KEY = /^class\.([A-Za-z][A-Za-z0-9_]*)\.(property|method)\.([A-Za-z][A-Za-z0-9_]*)$/u;
6
7
  /** The keys of frozen Definition coordinates, derived once each. */
7
8
  const derived = new WeakMap();
@@ -4,3 +4,5 @@ export declare function definitionRefIndex(ref: DefinitionRef): string;
4
4
  export declare function compareDefinitionRefs(left: DefinitionRef, right: DefinitionRef): number;
5
5
  /** Locale-independent Unicode code-point ordering for canonical DSL values. */
6
6
  export declare function compareUnicode(left: string, right: string): number;
7
+ /** Order strings by UTF-16 code unit, the order `<` gives strings. */
8
+ export declare function compareCodeUnits(left: string, right: string): number;
@@ -18,3 +18,7 @@ export function compareUnicode(left, right) {
18
18
  }
19
19
  return a.length - b.length;
20
20
  }
21
+ /** Order strings by UTF-16 code unit, the order `<` gives strings. */
22
+ export function compareCodeUnits(left, right) {
23
+ return left < right ? -1 : left > right ? 1 : 0;
24
+ }
@@ -3,6 +3,7 @@ export type DomainOrigin = string;
3
3
  export declare const DOMAIN_ORIGIN_PATTERN: RegExp;
4
4
  export declare const MEMBER_NAME_PATTERN: RegExp;
5
5
  export declare const DEPENDENCY_ALIAS_PATTERN: RegExp;
6
+ /** Labels of `[a-z][a-z0-9-]*` joined by `.`, 100 code points at most: `graph.reader`. */
6
7
  export declare const CORE_SLUG_PATTERN: RegExp;
7
8
  export declare const DOMAIN_REVISION_PATTERN: RegExp;
8
9
  export declare const PROPERTY_KEY_PATTERN: RegExp;
@@ -19,4 +20,3 @@ export declare const patterns: Readonly<{
19
20
  revision: RegExp;
20
21
  revisionFullMatch: "sha256:[0-9a-f]{64}";
21
22
  }>;
22
- export declare function assertMemberName(name: string): void;
@@ -1,7 +1,8 @@
1
1
  export const DOMAIN_ORIGIN_PATTERN = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u;
2
2
  export const MEMBER_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*$/u;
3
3
  export const DEPENDENCY_ALIAS_PATTERN = /^[a-z][A-Za-z0-9]*$/u;
4
- export const CORE_SLUG_PATTERN = /^[a-z][a-z0-9-]{0,99}$/u;
4
+ /** Labels of `[a-z][a-z0-9-]*` joined by `.`, 100 code points at most: `graph.reader`. */
5
+ export const CORE_SLUG_PATTERN = /^(?=.{1,100}$)[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*$/u;
5
6
  export const DOMAIN_REVISION_PATTERN = /^sha256:[0-9a-f]{64}$/u;
6
7
  const DOMAIN_REVISION_FULL_MATCH = 'sha256:[0-9a-f]{64}';
7
8
  const DOMAIN_ORIGIN_FULL_MATCH = '([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?';
@@ -22,8 +23,3 @@ export const patterns = Object.freeze({
22
23
  revision: DOMAIN_REVISION_PATTERN,
23
24
  revisionFullMatch: DOMAIN_REVISION_FULL_MATCH,
24
25
  });
25
- export function assertMemberName(name) {
26
- if (!MEMBER_NAME_PATTERN.test(name)) {
27
- throw new TypeError(`Invalid member name: ${JSON.stringify(name)}.`);
28
- }
29
- }
@@ -59,7 +59,7 @@ export const edgeClass = Object.freeze({
59
59
  validateDirectedSourceInput(input.source);
60
60
  validateDirectedTargetInput(input.target);
61
61
  const { source, target, unique, ...options } = input;
62
- validateEdgeClassOptions(options);
62
+ validateEdgeClassOptions(options, ['noSelf', 'acyclic']);
63
63
  const value = authoringValue('definition', {
64
64
  kind: 'edge',
65
65
  orientation: 'directed',
@@ -94,7 +94,7 @@ export const edgeClass = Object.freeze({
94
94
  validateIncidentEndpointInput(input.endpoints[0]);
95
95
  validateIncidentEndpointInput(input.endpoints[1]);
96
96
  const { endpoints, ...options } = input;
97
- validateUndirectedEdgeClassOptions(options);
97
+ validateEdgeClassOptions(options, ['noSelf']);
98
98
  const value = authoringValue('definition', {
99
99
  kind: 'edge',
100
100
  orientation: 'undirected',
@@ -122,33 +122,10 @@ function validateDirectedTargetInput(value) {
122
122
  function validateIncidentEndpointInput(value) {
123
123
  assertKnownKeys(value, ['as', 'accepts', 'incident', 'onDelete']);
124
124
  }
125
- function validateEdgeClassOptions(value) {
126
- assertKnownKeys(value, [
127
- 'abstract',
128
- 'inheritance',
129
- 'description',
130
- 'extends',
131
- 'properties',
132
- 'policies',
133
- 'constraints',
134
- ]);
135
- if (value.policies !== undefined)
136
- assertKnownKeys(value.policies, ['read', 'traverse']);
137
- if (value.constraints !== undefined)
138
- assertKnownKeys(value.constraints, ['noSelf', 'acyclic']);
139
- }
140
- function validateUndirectedEdgeClassOptions(value) {
141
- assertKnownKeys(value, [
142
- 'abstract',
143
- 'inheritance',
144
- 'description',
145
- 'extends',
146
- 'properties',
147
- 'policies',
148
- 'constraints',
149
- ]);
125
+ /** Check the nested Edge Class options; the caller has checked the option keys themselves. */
126
+ function validateEdgeClassOptions(value, constraints) {
150
127
  if (value.policies !== undefined)
151
128
  assertKnownKeys(value.policies, ['read', 'traverse']);
152
129
  if (value.constraints !== undefined)
153
- assertKnownKeys(value.constraints, ['noSelf']);
130
+ assertKnownKeys(value.constraints, constraints);
154
131
  }
@@ -1,5 +1,5 @@
1
1
  import type { z } from 'zod';
2
- import type { AutoEvent, AutoSet, PropertyImmutability } from '../../language/class/model/property.js';
2
+ import type { AutoEvent, AutoSet, PropertyAuto, PropertyImmutability } from '../../language/class/model/property.js';
3
3
  import type { StateMachine } from '../../language/state/index.js';
4
4
  import type { JsonSchema } from '../../language/value/model/schema.js';
5
5
  import type { AUTHORING } from '../schema/handle.js';
@@ -31,10 +31,7 @@ export interface AutoProperty<out PropertyValue extends Property = Property> {
31
31
  readonly [AUTHORING]: 'auto';
32
32
  readonly [AUTO_INPUT]: {
33
33
  readonly property: PropertyValue;
34
- readonly options: {
35
- readonly on: readonly AutoEvent[];
36
- readonly set: AutoSet;
37
- };
34
+ readonly options: PropertyAuto;
38
35
  };
39
36
  }
40
37
  type PropertyAuthoringInput<Value extends Property> = Value extends Property<infer Schema, infer Options, infer Machine> ? {
@@ -45,10 +42,7 @@ type PropertyAuthoringInput<Value extends Property> = Value extends Property<inf
45
42
  export declare function propertyAuthoringInput<const Value extends Property>(value: Value): PropertyAuthoringInput<Value>;
46
43
  export declare function autoPropertyAuthoringInput<const Value extends AutoProperty>(value: Value): Value extends AutoProperty<infer Property> ? {
47
44
  readonly property: Property;
48
- readonly options: {
49
- readonly on: readonly AutoEvent[];
50
- readonly set: AutoSet;
51
- };
45
+ readonly options: PropertyAuto;
52
46
  } : never;
53
47
  export type PropertyFieldInput = ValueSchemaInput | Property | AutoProperty;
54
48
  export type PropertyRecordInput = Readonly<Record<string, PropertyFieldInput>>;
@@ -59,6 +59,7 @@ export function auto(property, options) {
59
59
  return authoringValue('auto', {
60
60
  [AUTO_INPUT]: {
61
61
  property,
62
+ // `events` holds at least the one authored event.
62
63
  options: { on: Object.freeze(events), set: options.set },
63
64
  },
64
65
  });
@@ -48,6 +48,7 @@ export class V1DefinitionCompiler {
48
48
  }
49
49
  edgeClass(value, name, pointer) {
50
50
  const input = classConfiguration(value);
51
+ // The authoring types give an Edge no State Property; the structure refuses an erased one.
51
52
  const facet = this.values.properties(input.properties, `${pointer}/properties`);
52
53
  const contract = (() => {
53
54
  if (value.orientation === 'directed') {
@@ -63,7 +64,9 @@ export class V1DefinitionCompiler {
63
64
  // against the Class's effective Properties, once every Class is lowered.
64
65
  ...(directed.unique === undefined
65
66
  ? {}
66
- : { unique: directed.unique }),
67
+ : {
68
+ unique: directed.unique,
69
+ }),
67
70
  };
68
71
  }
69
72
  const undirected = classConfiguration(value);
@@ -135,6 +138,7 @@ export class V1DefinitionCompiler {
135
138
  endpointBase(value, pointer) {
136
139
  return {
137
140
  role: value.as,
141
+ // An empty list stays as authored: the structure refuses it when it judges the candidate.
138
142
  accepts: value.accepts
139
143
  .map((entry, index) => this.context.resolveNodeClass(entry, `${pointer}/accepts/${index}`))
140
144
  .sort(compareDefinitionRefs),
@@ -14,6 +14,7 @@ export class V1PolicyCompiler {
14
14
  const input = policyDeclaration(value);
15
15
  const ref = { origin: this.context.origin, kind: 'policy', name };
16
16
  if ('operator' in input) {
17
+ // One ref for each Policy of a non-empty composition.
17
18
  const refs = input.policies.map((policy, index) => this.context.resolvePolicy(policy, `${pointer}/${input.operator}/${index}`));
18
19
  return {
19
20
  ref,
@@ -4,6 +4,7 @@ import { isMethodExecutable } from '../../../language/callable/executable.js';
4
4
  import { admitsForeignSubclass, inheritanceOf } from '../../../language/class/inheritance.js';
5
5
  import { policyObjectKey, policyObjectOrigin } from '../../../language/index.js';
6
6
  import { graphNodePathSchema } from '../../../language/value/syntax/node-path/schema.js';
7
+ import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
7
8
  import { revisionOfDomainSchema } from '../../../schema/canonical/revision.js';
8
9
  import { requireDomainClosure } from '../../../schema/resolution/closure.js';
9
10
  import { collectUsedForeignOrigins } from '../../../schema/resolution/origins.js';
@@ -23,7 +24,7 @@ export class BuilderContext {
23
24
  constructor(origin, dependencies) {
24
25
  this.origin = origin;
25
26
  for (const [alias, schema] of Object.entries(dependencies)) {
26
- const pointer = `/dependencies/${escapePointer(alias)}`;
27
+ const pointer = `/dependencies/${escapePointerToken(alias)}`;
27
28
  if (!DEPENDENCY_ALIAS_PATTERN.test(alias)) {
28
29
  fail('BUILDER_DEPENDENCY_ALIAS', pointer, `Dependency alias ${JSON.stringify(alias)} must be an ASCII lower-camel identifier.`);
29
30
  }
@@ -223,9 +224,6 @@ export class BuilderContext {
223
224
  this.policyObjectRefs.add(policyObjectKey(ref));
224
225
  }
225
226
  }
226
- function escapePointer(value) {
227
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
228
- }
229
227
  function isResolvedClass(value) {
230
228
  if (typeof value !== 'object' || value === null)
231
229
  return false;
@@ -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}/${escapeToken(String(segment))}`, pointer);
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
  }
@@ -86,10 +86,11 @@ export function createPatternContext(options) {
86
86
  });
87
87
  Object.freeze(node);
88
88
  const where = build({ node });
89
- if (nodes.length === 0) {
89
+ const [first, ...rest] = nodes;
90
+ if (first === undefined) {
90
91
  fail('BUILDER_POLICY_EMPTY_EXISTS', `${options.pointer}/match/exists/nodes`, 'exists(...) must declare at least one variable Node.');
91
92
  }
92
- return { exists: { nodes, where } };
93
+ return { exists: { nodes: [first, ...rest], where } };
93
94
  },
94
95
  allOf(...expressions) {
95
96
  nonEmpty(expressions, `${options.pointer}/match/allOf`);
@@ -2,7 +2,6 @@ import type { Domain } from '../../domain/model/domain.js';
2
2
  import type { DomainSchema } from '../../schema/model/schema.js';
3
3
  import type { DomainSchemaInput, EntrypointOf } from './input.js';
4
4
  import type { ResolvedDomainOfInput } from './projection.js';
5
- export type { DomainSchemaInput } from './input.js';
6
5
  /** Exact named Schema produced from one authored input. */
7
6
  export interface DefinedSchema<Origin extends string, Resolved extends Domain> extends DomainSchema<Origin, Resolved> {
8
7
  }
@@ -1,4 +1,6 @@
1
1
  import type { DiagnosticCode as LanguageDiagnosticCode } from '../../language/validation/diagnostic.js';
2
+ import { escapePointerToken as escapeToken } from '../../language/value/syntax/pointer.js';
3
+ export { escapeToken };
2
4
  export type BuilderDiagnosticCode = LanguageDiagnosticCode | 'BUILDER_ABSTRACT_POLICY' | 'BUILDER_AMBIGUOUS_OWNERSHIP' | 'BUILDER_AUTO_EVENT_INVALID' | 'BUILDER_AUTO_IMMUTABLE' | 'BUILDER_AUTO_NESTED' | 'BUILDER_AUTO_SET_INVALID' | 'BUILDER_CALLABLE_AUTH' | 'BUILDER_CALLABLE_PLACEMENT' | 'BUILDER_CALLABLE_POLICY_AUTH' | 'BUILDER_CLASS_INHERITANCE' | 'BUILDER_CORE_CLASS' | 'BUILDER_CORE_EDGE' | 'BUILDER_CORE_NODE' | 'BUILDER_CORE_PROPERTY' | 'BUILDER_CORE_REF' | 'BUILDER_DEFINITION' | 'BUILDER_DEPENDENCY_CONFLICT' | 'BUILDER_DEPENDENCY_ALIAS' | 'BUILDER_DEPENDENCY_DIRECT' | 'BUILDER_DUPLICATE_MEMBER' | 'BUILDER_EDGE_LIFETIME' | 'BUILDER_FOREIGN_POLICY' | 'BUILDER_FULL_MATCH_INVALID' | 'BUILDER_FUNCTION' | 'BUILDER_METHOD' | 'BUILDER_PATH_DUPLICATE' | 'BUILDER_PATH_EMPTY' | 'BUILDER_POLICY' | 'BUILDER_POLICY_COMPOSITION' | 'BUILDER_POLICY_CYCLE' | 'BUILDER_POLICY_EMPTY_COMPOSITION' | 'BUILDER_POLICY_EMPTY_EXISTS' | 'BUILDER_POLICY_INPUT' | 'BUILDER_POLICY_REF' | 'BUILDER_POLICY_SELF' | 'BUILDER_PROPERTY_IMMUTABLE_INVALID' | 'BUILDER_REFERENCE_CYCLE' | 'BUILDER_REFERENCE_KIND' | 'BUILDER_REFERENCE_MISSING' | 'BUILDER_UNIQUE_PROPERTY' | 'BUILDER_UNKNOWN_FIELD' | 'BUILDER_UNOWNED_REFERENCE' | 'BUILDER_VIEW' | 'ZOD_SCHEMA_NOT_LOSSLESS';
3
5
  export interface BuilderDiagnostic<out Code extends BuilderDiagnosticCode = BuilderDiagnosticCode> {
4
6
  readonly code: Code;
@@ -13,4 +15,3 @@ export declare class BuilderError extends Error {
13
15
  }
14
16
  export declare function assertKnownKeys(value: object, allowed: readonly string[], pointer?: string): void;
15
17
  export declare function fail(code: BuilderDiagnosticCode, pointer: string, message: string): never;
16
- export declare function escapeToken(value: string): string;
@@ -1,16 +1,14 @@
1
- import { compareUnicode } from '../../addressing/ordering.js';
1
+ import { formatDiagnostics, orderDiagnostics } from '../../language/validation/diagnostic.js';
2
+ import { escapePointerToken as escapeToken } from '../../language/value/syntax/pointer.js';
3
+ export { escapeToken };
2
4
  export function diagnostic(code, pointer, message, ref) {
3
5
  return Object.freeze({ code, pointer, message, ...(ref === undefined ? {} : { ref }) });
4
6
  }
5
7
  export class BuilderError extends Error {
6
8
  diagnostics;
7
9
  constructor(diagnostics) {
8
- const ordered = [...diagnostics].sort((left, right) => compareUnicode(left.pointer, right.pointer) ||
9
- compareUnicode(left.code, right.code) ||
10
- compareUnicode(left.message, right.message));
11
- super(ordered
12
- .map(({ code, pointer, message }) => `${pointer || '/'} [${code}] ${message}`)
13
- .join('\n'));
10
+ const ordered = orderDiagnostics(diagnostics);
11
+ super(formatDiagnostics(ordered));
14
12
  this.name = 'BuilderError';
15
13
  this.diagnostics = Object.freeze(ordered);
16
14
  }
@@ -26,6 +24,3 @@ export function assertKnownKeys(value, allowed, pointer = '') {
26
24
  export function fail(code, pointer, message) {
27
25
  throw new BuilderError([diagnostic(code, pointer, message)]);
28
26
  }
29
- export function escapeToken(value) {
30
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
31
- }
@@ -1,4 +1,4 @@
1
- export type { PropertyProjection, MethodProjection, FunctionProjection, ClassProjection, DomainProjection, } from './projection/model.js';
1
+ export type { PropertyProjection, MethodProjection, FunctionProjection, ClassProjection, } from './projection/model.js';
2
2
  export type { ResolvedDomainOfInput } from './projection/domain.js';
3
3
  export type { CoreNamedPropertyInput, CorePropertyInput } from './projection/core-input.js';
4
4
  export type { ClassProjectionOfResolved } from './projection/resolved-class.js';
@@ -1,4 +1,3 @@
1
1
  import { type FullMatch } from '../../language/value/syntax/full-match.js';
2
- export { fullMatchSource, type FullMatch } from '../../language/value/syntax/full-match.js';
3
2
  /** Authoring facade preserving the Builder-owned diagnostic for invalid source syntax. */
4
3
  export declare function fullMatch(source: string): FullMatch;
@@ -1,7 +1,6 @@
1
1
  import { refuseIRegexp, stateBudgetMessage } from '../../language/value/regexp/syntax.js';
2
2
  import { fullMatch as languageFullMatch, } from '../../language/value/syntax/full-match.js';
3
3
  import { fail } from '../schema/diagnostic.js';
4
- export { fullMatchSource } from '../../language/value/syntax/full-match.js';
5
4
  /** Authoring facade preserving the Builder-owned diagnostic for invalid source syntax. */
6
5
  export function fullMatch(source) {
7
6
  const refusal = refuseIRegexp(source);
@@ -1,17 +1,15 @@
1
1
  import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, json, } from '@astrale-os/kernel-dsl/value';
2
2
  import { dependencyLimits } from '../addressing/domain-dependency.js';
3
3
  import { compareUnicode } from '../addressing/ordering.js';
4
+ import { escapePointerToken } from '../language/value/syntax/pointer.js';
4
5
  import { acceptDomainSchema } from '../schema/admission/accept.js';
5
6
  import { canonicalDomainSchemaAfterValidation } from '../schema/canonical/revision.js';
6
7
  import { revisionOfDomainSchema } from '../schema/canonical/revision.js';
7
8
  import { MemoryDomainSchemaLookup } from '../schema/dependency/lookup.js';
8
9
  import { SchemaError } from '../schema/diagnostic.js';
9
- import { BundleError, diagnostic } from './diagnostic.js';
10
+ import { BundleError, diagnostic, schemaDiagnosticAt } from './diagnostic.js';
10
11
  import { asDomainSchemaBundle, } from './model.js';
11
12
  import { parseDomainSchemaBundleStructure } from './structure.js';
12
- function escapeToken(value) {
13
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
14
- }
15
13
  export function acceptDomainSchemaBundle(input) {
16
14
  let admitted;
17
15
  try {
@@ -101,7 +99,7 @@ function acceptBundleValue(input) {
101
99
  catch (error) {
102
100
  if (!(error instanceof SchemaError))
103
101
  throw error;
104
- throw new BundleError(error.diagnostics.map((item) => diagnostic(item.code, `${entry.pointer}${item.pointer}`, item.message, item.ref)));
102
+ throw new BundleError(error.diagnostics.map((item) => schemaDiagnosticAt(entry.pointer, item)));
105
103
  }
106
104
  };
107
105
  for (const entry of candidates.values()) {
@@ -136,7 +134,7 @@ function collectReachable(current, root, candidates, reachable, active, revision
136
134
  return;
137
135
  }
138
136
  for (const [alias, dependency] of Object.entries(current.schema.dependencies)) {
139
- const pointer = `${current.pointer}/dependencies/${escapeToken(alias)}`;
137
+ const pointer = `${current.pointer}/dependencies/${escapePointerToken(alias)}`;
140
138
  const dependencyKey = keyOf(dependency.origin, dependency.revision);
141
139
  if (dependencyKey === root.key) {
142
140
  diagnostics.push(diagnostic('BUNDLE_CLOSURE_CYCLE', pointer, 'Bundle dependency closure returns to its root.'));
@@ -4,6 +4,8 @@ export type BundleDiagnostic<Code extends BundleDiagnosticCode = BundleDiagnosti
4
4
  readonly code: Code;
5
5
  };
6
6
  export declare function diagnostic<const Code extends BundleDiagnosticCode>(code: Code, pointer: string, message: string, ref?: string): BundleDiagnostic<Code>;
7
+ /** A refusal of one bundled schema, its pointer rebased under the schema's place in the bundle. */
8
+ export declare function schemaDiagnosticAt(pointer: string, refusal: SchemaDiagnostic): BundleDiagnostic;
7
9
  export declare class BundleError extends Error {
8
10
  readonly diagnostics: readonly BundleDiagnostic[];
9
11
  constructor(diagnostics: readonly BundleDiagnostic[]);
@@ -1,16 +1,18 @@
1
- import { compareUnicode } from '../addressing/ordering.js';
1
+ import { formatDiagnostics, orderDiagnostics } from '../language/validation/diagnostic.js';
2
2
  export function diagnostic(code, pointer, message, ref) {
3
3
  return Object.freeze({ code, pointer, message, ...(ref === undefined ? {} : { ref }) });
4
4
  }
5
+ /** A refusal of one bundled schema, its pointer rebased under the schema's place in the bundle. */
6
+ export function schemaDiagnosticAt(pointer, refusal) {
7
+ // Acceptance refuses a document with Schema codes only, never with comparison request codes.
8
+ const code = refusal.code;
9
+ return Object.freeze({ ...refusal, code, pointer: `${pointer}${refusal.pointer}` });
10
+ }
5
11
  export class BundleError extends Error {
6
12
  diagnostics;
7
13
  constructor(diagnostics) {
8
- const ordered = [...diagnostics].sort((left, right) => compareUnicode(left.pointer, right.pointer) ||
9
- compareUnicode(left.code, right.code) ||
10
- compareUnicode(left.message, right.message));
11
- super(ordered
12
- .map(({ code, pointer, message }) => `${pointer || '/'} [${code}] ${message}`)
13
- .join('\n'));
14
+ const ordered = orderDiagnostics(diagnostics);
15
+ super(formatDiagnostics(ordered));
14
16
  this.name = 'BundleError';
15
17
  this.diagnostics = Object.freeze(ordered);
16
18
  }
@@ -1,6 +1,7 @@
1
+ import { escapePointerToken } from '../language/value/syntax/pointer.js';
1
2
  import { SchemaError } from '../schema/diagnostic.js';
2
3
  import { routeDomainSchema } from '../schema/validation/domain.route.js';
3
- import { BundleError, diagnostic } from './diagnostic.js';
4
+ import { BundleError, diagnostic, schemaDiagnosticAt } from './diagnostic.js';
4
5
  import { DOMAIN_BUNDLE_FORMAT, DOMAIN_BUNDLE_VERSION } from './model.js';
5
6
  export function parseDomainSchemaBundleStructure(input) {
6
7
  if (!isObject(input)) {
@@ -12,7 +13,7 @@ export function parseDomainSchemaBundleStructure(input) {
12
13
  const expected = new Set(['format', 'version', 'root', 'closure']);
13
14
  for (const key of Object.keys(input)) {
14
15
  if (!expected.has(key)) {
15
- diagnostics.push(diagnostic('BUNDLE_STRUCTURE', `/${escapeToken(key)}`, `Unknown bundle field ${key}.`));
16
+ diagnostics.push(diagnostic('BUNDLE_STRUCTURE', `/${escapePointerToken(key)}`, `Unknown bundle field ${key}.`));
16
17
  }
17
18
  }
18
19
  for (const key of expected) {
@@ -56,7 +57,7 @@ function routeAt(value, pointer, diagnostics) {
56
57
  catch (error) {
57
58
  if (!(error instanceof SchemaError))
58
59
  throw error;
59
- diagnostics.push(...error.diagnostics.map((entry) => diagnostic(entry.code, `${pointer}${entry.pointer}`, entry.message, entry.ref)));
60
+ diagnostics.push(...error.diagnostics.map((entry) => schemaDiagnosticAt(pointer, entry)));
60
61
  return undefined;
61
62
  }
62
63
  }
@@ -66,6 +67,3 @@ function isObject(value) {
66
67
  function describe(value) {
67
68
  return value === undefined ? '(missing)' : JSON.stringify(value);
68
69
  }
69
- function escapeToken(value) {
70
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
71
- }
@@ -1,6 +1,6 @@
1
1
  import { type CompiledDiagnosticCode } from '../diagnostic.js';
2
2
  /** Append one escaped JSON Pointer segment. */
3
- export declare function pointer(parent: string, member: string | number): string;
3
+ export { appendPointer as pointer } from '../../language/value/syntax/pointer.js';
4
4
  /** Report a structural compiled-input violation with its stable diagnostic code. */
5
5
  export declare function invalid(label: string, code?: CompiledDiagnosticCode, path?: string): never;
6
6
  /** Report a contextual compiled-language violation at its original source pointer. */
@@ -1,8 +1,6 @@
1
1
  import { invalidCompiled } from '../diagnostic.js';
2
2
  /** Append one escaped JSON Pointer segment. */
3
- export function pointer(parent, member) {
4
- return `${parent}/${String(member).replaceAll('~', '~0').replaceAll('/', '~1')}`;
5
- }
3
+ export { appendPointer as pointer } from '../../language/value/syntax/pointer.js';
6
4
  /** Report a structural compiled-input violation with its stable diagnostic code. */
7
5
  export function invalid(label, code = 'COMPILED_STRUCTURE_INVALID', path = '') {
8
6
  return invalidCompiled(code, `Invalid compiled Schema ${label}.`, path);
@@ -1,4 +1,12 @@
1
1
  import type { Revision } from '../../addressing/index.js';
2
- import type { CompiledSchemaEntry } from '../model/schema.js';
2
+ import type { FunctionDefinition, MethodDefinition } from '../../language/callable/model/callable.js';
3
+ import type { JsonSchema } from '../../language/value/model/schema.js';
4
+ import type { CompiledFunction, CompiledMethod, CompiledSchemaEntry } from '../model/schema.js';
3
5
  /** Derive the exact canonical source-revision preimage without constructing an authored Schema. */
4
6
  export declare function revisionOfCompiledEntry(entry: CompiledSchemaEntry): Revision;
7
+ /** The source definition of a compiled Method: its value programs back to their schemas. */
8
+ export declare function sourceMethod(entry: CompiledSchemaEntry, method: CompiledMethod): MethodDefinition;
9
+ /** The source definition of a compiled Function: its value programs back to their schemas. */
10
+ export declare function sourceFunction(entry: CompiledSchemaEntry, definition: CompiledFunction): FunctionDefinition;
11
+ /** The schema of the root node of the entry's value program `index`. */
12
+ export declare function schemaOf(entry: CompiledSchemaEntry, index: number): JsonSchema;
@@ -44,7 +44,8 @@ function sourceClass(entry, definition) {
44
44
  methods: Object.fromEntries(methods.map((method) => [method.name, sourceMethod(entry, method)])),
45
45
  };
46
46
  }
47
- function sourceMethod(entry, method) {
47
+ /** The source definition of a compiled Method: its value programs back to their schemas. */
48
+ export function sourceMethod(entry, method) {
48
49
  const { name: _, input, fields: __, output, ...rest } = method;
49
50
  return {
50
51
  ...rest,
@@ -52,7 +53,8 @@ function sourceMethod(entry, method) {
52
53
  output: sourceOutput(entry, output),
53
54
  };
54
55
  }
55
- function sourceFunction(entry, definition) {
56
+ /** The source definition of a compiled Function: its value programs back to their schemas. */
57
+ export function sourceFunction(entry, definition) {
56
58
  const { input, fields: _, output, ...rest } = definition;
57
59
  return {
58
60
  ...rest,
@@ -72,7 +74,8 @@ function sourceOutput(entry, output) {
72
74
  const schema = schemaOf(entry, output.value);
73
75
  return output.mode === 'value' ? { mode: 'value', schema } : { mode: 'stream', item: schema };
74
76
  }
75
- function schemaOf(entry, index) {
77
+ /** The schema of the root node of the entry's value program `index`. */
78
+ export function schemaOf(entry, index) {
76
79
  const program = entry.values[index];
77
80
  const root = program?.nodes[program.root];
78
81
  if (root === undefined)
@@ -1,5 +1,8 @@
1
1
  import { type Located, type CompiledClass, type ClassAnalysis, type SemanticIndex } from './context.js';
2
- /** Compose inherited Properties, Methods and Data ownership once per Class. */
2
+ /**
3
+ * Compose inherited Properties, Methods and Data ownership once per Class. The closure check has
4
+ * already proved every parent present and the inheritance graph acyclic.
5
+ */
3
6
  export declare function analyzeClasses(classes: ReadonlyMap<string, Located<CompiledClass>>): ReadonlyMap<string, ClassAnalysis>;
4
7
  /** Check automatic Properties, immutability and abstract Class obligations. */
5
8
  export declare function validateClassFacets(context: SemanticIndex): void;