@cruba/crubal 0.0.0-stage → 0.2.0

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 (99) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +97 -2
  3. package/dist/bin/crubal.d.ts +2 -0
  4. package/dist/bin/crubal.js +103 -0
  5. package/dist/bin/crubal.js.map +1 -0
  6. package/dist/src/access.d.ts +126 -0
  7. package/dist/src/access.js +517 -0
  8. package/dist/src/access.js.map +1 -0
  9. package/dist/src/arrival.d.ts +55 -0
  10. package/dist/src/arrival.js +124 -0
  11. package/dist/src/arrival.js.map +1 -0
  12. package/dist/src/browser.d.ts +10 -0
  13. package/dist/src/browser.js +13 -0
  14. package/dist/src/browser.js.map +1 -0
  15. package/dist/src/bundle.d.ts +66 -0
  16. package/dist/src/bundle.js +753 -0
  17. package/dist/src/bundle.js.map +1 -0
  18. package/dist/src/canonical.d.ts +6 -0
  19. package/dist/src/canonical.js +47 -0
  20. package/dist/src/canonical.js.map +1 -0
  21. package/dist/src/conditions.d.ts +28 -0
  22. package/dist/src/conditions.js +216 -0
  23. package/dist/src/conditions.js.map +1 -0
  24. package/dist/src/corpus.d.ts +8 -0
  25. package/dist/src/corpus.js +1207 -0
  26. package/dist/src/corpus.js.map +1 -0
  27. package/dist/src/defs.d.ts +151 -0
  28. package/dist/src/defs.js +611 -0
  29. package/dist/src/defs.js.map +1 -0
  30. package/dist/src/dictionary.d.ts +65 -0
  31. package/dist/src/dictionary.js +557 -0
  32. package/dist/src/dictionary.js.map +1 -0
  33. package/dist/src/exchange.d.ts +236 -0
  34. package/dist/src/exchange.js +1035 -0
  35. package/dist/src/exchange.js.map +1 -0
  36. package/dist/src/forms.d.ts +16 -0
  37. package/dist/src/forms.js +169 -0
  38. package/dist/src/forms.js.map +1 -0
  39. package/dist/src/index.d.ts +27 -0
  40. package/dist/src/index.js +29 -0
  41. package/dist/src/index.js.map +1 -0
  42. package/dist/src/lex.d.ts +21 -0
  43. package/dist/src/lex.js +142 -0
  44. package/dist/src/lex.js.map +1 -0
  45. package/dist/src/lifecycle.d.ts +84 -0
  46. package/dist/src/lifecycle.js +415 -0
  47. package/dist/src/lifecycle.js.map +1 -0
  48. package/dist/src/log.d.ts +78 -0
  49. package/dist/src/log.js +506 -0
  50. package/dist/src/log.js.map +1 -0
  51. package/dist/src/migrate.d.ts +111 -0
  52. package/dist/src/migrate.js +286 -0
  53. package/dist/src/migrate.js.map +1 -0
  54. package/dist/src/model.d.ts +68 -0
  55. package/dist/src/model.js +188 -0
  56. package/dist/src/model.js.map +1 -0
  57. package/dist/src/packages.d.ts +69 -0
  58. package/dist/src/packages.js +232 -0
  59. package/dist/src/packages.js.map +1 -0
  60. package/dist/src/print-text.d.ts +7 -0
  61. package/dist/src/print-text.js +216 -0
  62. package/dist/src/print-text.js.map +1 -0
  63. package/dist/src/publish.d.ts +27 -0
  64. package/dist/src/publish.js +275 -0
  65. package/dist/src/publish.js.map +1 -0
  66. package/dist/src/read-text.d.ts +10 -0
  67. package/dist/src/read-text.js +385 -0
  68. package/dist/src/read-text.js.map +1 -0
  69. package/dist/src/records.d.ts +31 -0
  70. package/dist/src/records.js +72 -0
  71. package/dist/src/records.js.map +1 -0
  72. package/dist/src/review.d.ts +22 -0
  73. package/dist/src/review.js +198 -0
  74. package/dist/src/review.js.map +1 -0
  75. package/dist/src/rules.d.ts +96 -0
  76. package/dist/src/rules.js +611 -0
  77. package/dist/src/rules.js.map +1 -0
  78. package/dist/src/schedule.d.ts +24 -0
  79. package/dist/src/schedule.js +126 -0
  80. package/dist/src/schedule.js.map +1 -0
  81. package/dist/src/std-packages.d.ts +9 -0
  82. package/dist/src/std-packages.js +268 -0
  83. package/dist/src/std-packages.js.map +1 -0
  84. package/dist/src/store.d.ts +164 -0
  85. package/dist/src/store.js +538 -0
  86. package/dist/src/store.js.map +1 -0
  87. package/dist/src/tree.d.ts +35 -0
  88. package/dist/src/tree.js +159 -0
  89. package/dist/src/tree.js.map +1 -0
  90. package/dist/src/units-table.d.ts +1 -0
  91. package/dist/src/units-table.js +200 -0
  92. package/dist/src/units-table.js.map +1 -0
  93. package/dist/src/units.d.ts +42 -0
  94. package/dist/src/units.js +98 -0
  95. package/dist/src/units.js.map +1 -0
  96. package/dist/src/views.d.ts +216 -0
  97. package/dist/src/views.js +761 -0
  98. package/dist/src/views.js.map +1 -0
  99. package/package.json +60 -4
@@ -0,0 +1,286 @@
1
+ // migrate.ts: migration recipes (spec chapter 10). A recipe names the version it leaves and the version it
2
+ // reaches, then steps grouped by facet, run in the order written. Restamping applies it to every record;
3
+ // steps that need a person send items to the review queue and hold the value. Nothing is dropped.
4
+ import { serialize } from "./canonical.js";
5
+ import { evaluate, parseCondition } from "./conditions.js";
6
+ import { checkScalar } from "./dictionary.js";
7
+ import { readUnder } from "./read-text.js";
8
+ import { splitTop } from "./lex.js";
9
+ import { CrubalError, readTree } from "./tree.js";
10
+ import { convert, unitOf } from "./units.js";
11
+ const unq = (s) => (s.trim().startsWith('"') ? JSON.parse(s.trim()) : s.trim());
12
+ function arrow(text, line) {
13
+ const at = text.lastIndexOf(" -> ");
14
+ if (at < 0) {
15
+ if (text.startsWith("-> "))
16
+ return ["", text.slice(3).trim()];
17
+ throw new CrubalError(`expected "from -> to": ${text}`, line);
18
+ }
19
+ return [text.slice(0, at).trim(), text.slice(at + 4).trim()];
20
+ }
21
+ /** Read `migration:` blocks. */
22
+ export function readRecipes(source) {
23
+ const out = [];
24
+ for (const node of readTree(source)) {
25
+ if (node.kind !== "pair" || node.key !== "migration")
26
+ continue;
27
+ const [from, to] = arrow(node.value, node.line);
28
+ const recipe = { from, to, steps: [], line: node.line };
29
+ for (const group of node.children) {
30
+ if (group.key !== "facet")
31
+ throw new CrubalError(`a recipe groups its steps under "facet: key"`, group.line);
32
+ const facet = group.value.trim();
33
+ const kids = group.children;
34
+ for (let i = 0; i < kids.length; i++) {
35
+ const s = kids[i];
36
+ const base = { facet, line: s.line, text: s.text };
37
+ if (s.kind === "line" && s.text === "recompute") {
38
+ recipe.steps.push({ verb: "recompute", ...base });
39
+ continue;
40
+ }
41
+ switch (s.key) {
42
+ case "rename": {
43
+ const [a, b] = arrow(s.value, s.line);
44
+ recipe.steps.push({ verb: "rename", from: unq(a), to: unq(b), ...base });
45
+ break;
46
+ }
47
+ case "merge": {
48
+ const [a, b] = arrow(s.value, s.line);
49
+ recipe.steps.push({ verb: "merge", from: splitTop(a, ",", s.line).map(unq), to: unq(b), ...base });
50
+ break;
51
+ }
52
+ case "convert": {
53
+ const [a, b] = arrow(s.value, s.line);
54
+ const next = kids[i + 1];
55
+ const rounding = next?.key === "rounding" ? next.value : "nearest";
56
+ if (next?.key === "rounding")
57
+ i++;
58
+ recipe.steps.push({ verb: "convert", from: a, to: b, rounding, ...base });
59
+ break;
60
+ }
61
+ case "precision":
62
+ case "retype": {
63
+ const [a, b] = arrow(s.value, s.line);
64
+ recipe.steps.push({ verb: s.key, from: a, to: b, ...base });
65
+ break;
66
+ }
67
+ case "split": {
68
+ const when = [];
69
+ let otherwise;
70
+ for (const b of s.children) {
71
+ if (b.key === "when") {
72
+ const [cond, to] = arrow(b.value, b.line);
73
+ when.push({ cond, to: unq(to) });
74
+ }
75
+ else if (b.key === "else")
76
+ otherwise = unq(b.value);
77
+ }
78
+ recipe.steps.push({ verb: "split", value: unq(s.value), when, ...(otherwise !== undefined ? { else: otherwise } : {}), ...base });
79
+ break;
80
+ }
81
+ case "move":
82
+ recipe.steps.push({ verb: "move", to: arrow(s.value, s.line)[1], ...base });
83
+ break;
84
+ case "review":
85
+ recipe.steps.push({ verb: "review", cond: s.value, ...base });
86
+ break;
87
+ case "fill": {
88
+ let level;
89
+ let when;
90
+ for (const b of s.children) {
91
+ if (b.key === "for")
92
+ level = b.value.trim().replace(/::$/, "");
93
+ else if (b.key === "when")
94
+ when = b.value.trim();
95
+ else
96
+ throw new CrubalError(`a fill takes "for:" and "when:" beneath it, not ${b.key}`, b.line);
97
+ }
98
+ recipe.steps.push({ verb: "fill", value: unq(s.value), ...(level ? { level } : {}), ...(when ? { when } : {}), ...base });
99
+ break;
100
+ }
101
+ default:
102
+ throw new CrubalError(`unknown recipe step: ${s.text}`, s.line);
103
+ }
104
+ }
105
+ }
106
+ out.push(recipe);
107
+ }
108
+ return out;
109
+ }
110
+ /** Publish checks (10.5) against the version the recipe reaches, given as `dict`. */
111
+ export function checkRecipe(r, dict) {
112
+ for (const s of r.steps) {
113
+ const f = dict.facets.get(s.facet);
114
+ const real = new Set((f?.values ?? []).map((v) => v.value));
115
+ const need = (v) => {
116
+ if (f?.type === "choice" && !real.has(v))
117
+ throw new CrubalError(`${v} is not a value of ${s.facet} in ${r.to}`, s.line);
118
+ };
119
+ if (s.verb === "rename" || s.verb === "merge")
120
+ need(s.to);
121
+ if (s.verb === "split") {
122
+ for (const b of s.when)
123
+ need(b.to);
124
+ if (s.else !== undefined)
125
+ need(s.else);
126
+ }
127
+ if (s.verb === "convert" && convert("1", s.from, s.to) === null)
128
+ throw new CrubalError(`can't convert ${s.from} to ${s.to}`, s.line);
129
+ if (s.verb === "fill") {
130
+ if (!f)
131
+ throw new CrubalError(`${s.facet} is not a facet of ${r.to}`, s.line);
132
+ const v = readUnder(f, s.value, dict, s.line);
133
+ if (v === undefined || checkScalar(f, v).outcome !== "absorbed")
134
+ throw new CrubalError(`${s.value} is not a value ${s.facet} takes`, s.line);
135
+ if (s.level && !dict.levels.has(s.level))
136
+ throw new CrubalError(`${s.level} is not a level of ${r.to}`, s.line);
137
+ if (s.when)
138
+ parseCondition(s.when, s.line);
139
+ }
140
+ }
141
+ }
142
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
143
+ function mapScalars(v, fn) {
144
+ if (Array.isArray(v))
145
+ return v.map((x) => mapScalars(x, fn));
146
+ if (isObj(v) && "$value" in v)
147
+ return { ...v, $value: fn(v.$value) };
148
+ return fn(v);
149
+ }
150
+ /** A value's text as the text form writes it, for a retype to re-read (10.3). */
151
+ function textOf(v) {
152
+ if (typeof v === "string")
153
+ return v;
154
+ if (typeof v === "number" || typeof v === "boolean")
155
+ return String(v);
156
+ if (isObj(v) && "$qty" in v)
157
+ return `${v.$qty}${v.unit}`;
158
+ if (isObj(v) && "$money" in v)
159
+ return `${v.$money}${v.currency}`;
160
+ if (isObj(v) && "$link" in v)
161
+ return `&${v.$link}`;
162
+ if (isObj(v) && "$value" in v)
163
+ return textOf(v.$value);
164
+ return JSON.stringify(v);
165
+ }
166
+ export function restamp(records, recipe, dict, stats) {
167
+ const review = [];
168
+ if (stats)
169
+ for (const s of recipe.steps)
170
+ stats.push({ step: s.text, facet: s.facet, verb: s.verb, changed: 0, review: 0 });
171
+ const out = records.map((rec) => {
172
+ const values = { ...rec.values };
173
+ // A moved value keeps its source under its new address (10.4): the record's own, else its default.
174
+ const sources = { ...(rec.sources ?? {}) };
175
+ recipe.steps.forEach((s, si) => {
176
+ const v = values[s.facet];
177
+ if (v === undefined && s.verb !== "review" && s.verb !== "fill")
178
+ return;
179
+ const before = serialize((values[s.facet] ?? null));
180
+ const reviewsBefore = review.length;
181
+ switch (s.verb) {
182
+ case "rename":
183
+ values[s.facet] = mapScalars(v, (x) => (x === s.from ? s.to : x));
184
+ break;
185
+ case "merge":
186
+ values[s.facet] = mapScalars(v, (x) => (typeof x === "string" && s.from.includes(x) ? s.to : x));
187
+ break;
188
+ case "convert":
189
+ values[s.facet] = mapScalars(v, (x) => {
190
+ if (!isObj(x) || !("$qty" in x))
191
+ return x;
192
+ const unit = unitOf(String(x.unit)) ?? String(x.unit);
193
+ if (unit !== s.from)
194
+ return x;
195
+ const places = dict.facets.get(s.facet)?.places ?? 0;
196
+ const exact = Number(convert(String(x.$qty), s.from, s.to, 12));
197
+ const scale = 10 ** places;
198
+ const round = s.rounding === "down" ? Math.floor : s.rounding === "up" ? Math.ceil : Math.round;
199
+ return { $qty: String(round(exact * scale) / scale), unit: s.to };
200
+ });
201
+ break;
202
+ case "precision": {
203
+ const len = s.to === "year" ? 4 : s.to === "month" ? 7 : 10;
204
+ values[s.facet] = mapScalars(v, (x) => (typeof x === "string" && x.length > len ? x.slice(0, len) : x));
205
+ break;
206
+ }
207
+ case "split":
208
+ values[s.facet] = mapScalars(v, (x) => {
209
+ if (x !== s.value)
210
+ return x;
211
+ for (const b of s.when)
212
+ if (evaluate(parseCondition(b.cond, s.line), values) === true)
213
+ return b.to;
214
+ if (s.else !== undefined)
215
+ return s.else;
216
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
217
+ return x;
218
+ });
219
+ break;
220
+ case "move":
221
+ if (!/^[A-Za-z_][\w:]*$/.test(s.to) || values[s.to] !== undefined) {
222
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
223
+ break;
224
+ }
225
+ values[s.to] = v;
226
+ delete values[s.facet];
227
+ {
228
+ const src = sources[s.facet] ?? sources["*"];
229
+ if (src)
230
+ sources[s.to] = src;
231
+ delete sources[s.facet];
232
+ }
233
+ break;
234
+ case "review":
235
+ if (evaluate(parseCondition(s.cond, s.line), values) === true)
236
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
237
+ break;
238
+ case "retype": {
239
+ // Each value is read again under the facet's new type (10.3): what fits lands, the rest goes to review.
240
+ const f = dict.facets.get(s.facet);
241
+ if (!f)
242
+ break;
243
+ const again = readUnder(f, textOf(v), dict);
244
+ const ok = again !== undefined && checkScalar(f, again).outcome === "absorbed";
245
+ if (ok)
246
+ values[s.facet] = again;
247
+ else
248
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
249
+ break;
250
+ }
251
+ case "recompute":
252
+ break; // the rules rebuild produced values
253
+ case "fill": {
254
+ // A backfill (10.3): a record lacking the key, at the level named, where the condition holds, gets the
255
+ // value read under the facet; a record that has one is left alone.
256
+ if (v !== undefined)
257
+ break;
258
+ if (s.level && rec.level !== s.level)
259
+ break;
260
+ if (s.when && evaluate(parseCondition(s.when, s.line), values) !== true)
261
+ break;
262
+ const f = dict.facets.get(s.facet);
263
+ const filled = f ? readUnder(f, s.value, dict) : undefined;
264
+ if (filled !== undefined)
265
+ values[s.facet] = filled;
266
+ break;
267
+ }
268
+ }
269
+ if (stats) {
270
+ const st = stats[si];
271
+ if (serialize((values[s.facet] ?? null)) !== before)
272
+ st.changed += 1;
273
+ st.review += review.length - reviewsBefore;
274
+ }
275
+ });
276
+ return { ...rec, values, ...(Object.keys(sources).length ? { sources } : {}) };
277
+ });
278
+ return { records: out, review };
279
+ }
280
+ /** What a restamp would do, without doing it (10.4): per step, how many values change and how many go to review. */
281
+ export function dryRun(records, recipe, dict) {
282
+ const stats = [];
283
+ const { review } = restamp(structuredClone(records), recipe, dict, stats);
284
+ return { steps: stats, records: records.length, review: review.length };
285
+ }
286
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { Dictionary } from "./defs.ts";
2
+ export type Json = string | number | boolean | Json[] | JsonObject;
3
+ export type JsonObject = {
4
+ [key: string]: Json;
5
+ };
6
+ export type Source = {
7
+ origin: string;
8
+ via: string;
9
+ owner?: string;
10
+ adopted?: boolean;
11
+ /** Taken under terms (7.8): when the value lapses, whether it may flow on, whether the presenter may withdraw it. */
12
+ until?: string;
13
+ reshare?: boolean;
14
+ revocable?: boolean;
15
+ };
16
+ /** A record's status (1.12): absent means active. */
17
+ export type Status = {
18
+ state: "active" | "archived";
19
+ reason?: string;
20
+ into?: string;
21
+ };
22
+ export type Record = {
23
+ id: string;
24
+ kind: string;
25
+ level: string;
26
+ /** Optional at every level (1.2): absent when the record stands alone. */
27
+ of?: string;
28
+ owner: string;
29
+ /** The record this one belongs to for access (14.2). */
30
+ within?: string;
31
+ status?: Status;
32
+ /** Per issuer of instructions, the last one applied (10.7). */
33
+ applied?: {
34
+ [issuer: string]: number;
35
+ };
36
+ wears?: string[];
37
+ created?: string;
38
+ updated?: string;
39
+ values: JsonObject;
40
+ parts?: Json[];
41
+ sources?: {
42
+ [address: string]: Source;
43
+ };
44
+ };
45
+ export type Wrapper = {
46
+ crubal: string;
47
+ package?: string;
48
+ prefixes?: {
49
+ [prefix: string]: string;
50
+ };
51
+ records: Record[];
52
+ };
53
+ /**
54
+ * Parse CRUBAL JSON text (chapter 3): RFC 8259, with a member named twice in one object refused. JSON.parse
55
+ * keeps the last of two equal names, so the text is scanned for them first; the scan follows strings and
56
+ * brackets only and leaves everything else to JSON.parse.
57
+ */
58
+ export declare function parseJson(text: string): Json;
59
+ /** Whether an address names a place in the record's values or parts (3.7). `*` is the record itself. */
60
+ export declare function addressNames(r: Record, address: string, dict?: Dictionary): boolean;
61
+ /** Refuse JSON the spec forbids: `null` anywhere (chapter 3), unknown record members (3.2). */
62
+ export declare function checkJson(doc: unknown, path?: string): void;
63
+ /**
64
+ * Check a wrapper read from JSON: no null, the members 3.2 lists, and every source address naming a place in
65
+ * the record (3.7). With the dictionary, a quoted list selector is matched by the item's text form; without
66
+ * it, by the item's core value.
67
+ */
68
+ export declare function checkWrapper(w: Wrapper, dict?: Dictionary): void;
@@ -0,0 +1,188 @@
1
+ // model.ts: the JSON form's shapes (spec chapter 3). The JSON is the model: readers produce it, printers
2
+ // consume it, and canonical.ts hashes it.
3
+ import { itemText } from "./print-text.js";
4
+ const RECORD_MEMBERS = new Set(["id", "kind", "level", "of", "owner", "within", "status", "applied", "wears", "created", "updated", "values", "parts", "sources", "alternatives", "suggestions", "held"]);
5
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
6
+ /**
7
+ * Parse CRUBAL JSON text (chapter 3): RFC 8259, with a member named twice in one object refused. JSON.parse
8
+ * keeps the last of two equal names, so the text is scanned for them first; the scan follows strings and
9
+ * brackets only and leaves everything else to JSON.parse.
10
+ */
11
+ export function parseJson(text) {
12
+ const stack = [];
13
+ let i = 0;
14
+ scan: while (i < text.length) {
15
+ const c = text[i];
16
+ if (c === '"') {
17
+ let j = i + 1;
18
+ while (j < text.length && text[j] !== '"')
19
+ j += text[j] === "\\" ? 2 : 1;
20
+ const raw = text.slice(i, j + 1);
21
+ i = j + 1;
22
+ const top = stack.at(-1);
23
+ if (top?.keys && top.expectKey) {
24
+ let key;
25
+ try {
26
+ key = JSON.parse(raw);
27
+ }
28
+ catch {
29
+ break scan; // malformed: JSON.parse below says where
30
+ }
31
+ if (top.keys.has(key))
32
+ throw new Error(`member ${key} twice in the object at $${stack.slice(0, -1).map((f) => f.at).join("")}: a document never names a member twice`);
33
+ top.keys.add(key);
34
+ top.expectKey = false;
35
+ top.at = `.${key}`;
36
+ }
37
+ continue;
38
+ }
39
+ if (c === "{")
40
+ stack.push({ keys: new Set(), expectKey: true, at: "" });
41
+ else if (c === "[")
42
+ stack.push({ keys: null, expectKey: false, at: "[0]" });
43
+ else if (c === "}" || c === "]")
44
+ stack.pop();
45
+ else if (c === ",") {
46
+ const top = stack.at(-1);
47
+ if (top?.keys)
48
+ top.expectKey = true;
49
+ else if (top)
50
+ top.at = `[${Number(top.at.slice(1, -1)) + 1}]`;
51
+ }
52
+ i++;
53
+ }
54
+ return JSON.parse(text);
55
+ }
56
+ /** An address's steps (1.10): `key` or `key[selector]`, `.`-separated outside brackets and quotes; undefined when malformed. */
57
+ function steps(address) {
58
+ const out = [];
59
+ let i = 0;
60
+ for (;;) {
61
+ let key = "";
62
+ while (i < address.length && address[i] !== "." && address[i] !== "[")
63
+ key += address[i++];
64
+ if (!key)
65
+ return undefined;
66
+ const step = { key };
67
+ if (address[i] === "[") {
68
+ i++;
69
+ if (address[i] === '"') {
70
+ let j = i + 1;
71
+ while (j < address.length && address[j] !== '"')
72
+ j += address[j] === "\\" ? 2 : 1;
73
+ if (j >= address.length)
74
+ return undefined;
75
+ try {
76
+ step.selector = JSON.parse(address.slice(i, j + 1));
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ step.quoted = true;
82
+ i = j + 1;
83
+ }
84
+ else {
85
+ const end = address.indexOf("]", i);
86
+ if (end <= i)
87
+ return undefined;
88
+ step.selector = address.slice(i, end);
89
+ i = end;
90
+ }
91
+ if (address[i] !== "]")
92
+ return undefined;
93
+ i++;
94
+ }
95
+ out.push(step);
96
+ if (i === address.length)
97
+ return out;
98
+ if (address[i] !== ".")
99
+ return undefined;
100
+ i++;
101
+ }
102
+ }
103
+ /** Whether an address names a place in the record's values or parts (3.7). `*` is the record itself. */
104
+ export function addressNames(r, address, dict) {
105
+ if (address === "*")
106
+ return true;
107
+ const st = steps(address);
108
+ if (!st?.length)
109
+ return false;
110
+ const [first, ...rest] = st;
111
+ if (first.key === "parts") {
112
+ if (first.selector === undefined || first.quoted)
113
+ return false;
114
+ const part = (r.parts ?? []).find((p) => isObj(p) && String(p.$row) === first.selector);
115
+ if (!isObj(part))
116
+ return false;
117
+ return rest.length ? walk(isObj(part.values) ? part.values : {}, rest, dict) : true;
118
+ }
119
+ return walk(r.values, st, dict);
120
+ }
121
+ function walk(values, st, dict) {
122
+ let cur = values;
123
+ for (const s of st) {
124
+ if (!isObj(cur))
125
+ return false;
126
+ let v = cur[s.key];
127
+ if (v === undefined)
128
+ return false;
129
+ if (s.selector !== undefined) {
130
+ if (!Array.isArray(v))
131
+ return false;
132
+ const sel = s.selector;
133
+ const facet = dict?.facets.get(s.key);
134
+ const hit = v.find((item) => {
135
+ // A plain list item by its text form (1.10); without the dictionary, by its core value.
136
+ if (s.quoted)
137
+ return facet ? itemText(facet, item) === sel : String(isObj(item) ? (item.$value ?? item.$qty ?? item.$money ?? item.$link ?? "") : item) === sel.replace(/ \[.*\]$/, "");
138
+ // A row by its key: written as `$row`, or derived from the identity child, which is a link (1.6).
139
+ return isObj(item) && (String(item.$row) === sel || Object.values(item).some((x) => isObj(x) && x.$link === sel));
140
+ });
141
+ if (hit === undefined)
142
+ return false;
143
+ v = hit;
144
+ }
145
+ cur = v;
146
+ }
147
+ return true;
148
+ }
149
+ /** Refuse JSON the spec forbids: `null` anywhere (chapter 3), unknown record members (3.2). */
150
+ export function checkJson(doc, path = "$") {
151
+ if (doc === null)
152
+ throw new Error(`null at ${path}: CRUBAL JSON never holds null`);
153
+ if (Array.isArray(doc)) {
154
+ doc.forEach((d, i) => checkJson(d, `${path}[${i}]`));
155
+ return;
156
+ }
157
+ if (typeof doc === "object") {
158
+ for (const [k, v] of Object.entries(doc))
159
+ checkJson(v, `${path}.${k}`);
160
+ }
161
+ }
162
+ /**
163
+ * Check a wrapper read from JSON: no null, the members 3.2 lists, and every source address naming a place in
164
+ * the record (3.7). With the dictionary, a quoted list selector is matched by the item's text form; without
165
+ * it, by the item's core value.
166
+ */
167
+ export function checkWrapper(w, dict) {
168
+ checkJson(w);
169
+ if (!/^\d+$/.test(String(w.crubal)) || Number(w.crubal) > 2)
170
+ throw new Error(`written in CRUBAL ${w.crubal}; this reader knows 2`);
171
+ if (!Array.isArray(w.records))
172
+ throw new Error("a wrapper needs records");
173
+ w.records.forEach((r, i) => {
174
+ for (const k of Object.keys(r)) {
175
+ if (!RECORD_MEMBERS.has(k))
176
+ throw new Error(`records[${i}] has an unknown member ${k}`);
177
+ }
178
+ for (const k of ["id", "kind", "level", "owner", "values"]) {
179
+ if (r[k] === undefined)
180
+ throw new Error(`records[${i}] needs ${k}`);
181
+ }
182
+ for (const address of Object.keys(r.sources ?? {})) {
183
+ if (!addressNames(r, address, dict))
184
+ throw new Error(`records[${i}].sources: ${address} names nothing in values or parts`);
185
+ }
186
+ });
187
+ }
188
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { type Dictionary } from "./defs.ts";
2
+ export type PackageInfo = {
3
+ name: string;
4
+ version: string;
5
+ owner: string;
6
+ line: number;
7
+ /** The language version it is written in (11.8), and the line that says so. */
8
+ crubal: number;
9
+ crubalLine: number;
10
+ extends: {
11
+ name: string;
12
+ version: string;
13
+ line: number;
14
+ }[];
15
+ prefixes: Map<string, {
16
+ target: string;
17
+ line: number;
18
+ }>;
19
+ trust: {
20
+ entry: string;
21
+ line: number;
22
+ }[];
23
+ dict: Dictionary;
24
+ contracts: string[];
25
+ /** The rest of the header (11.1), as written. */
26
+ header: {
27
+ [key: string]: string;
28
+ };
29
+ terms: {
30
+ [audience: string]: string;
31
+ };
32
+ /** The utilities the package declares (11.1, `utility:` blocks). */
33
+ utilities: Utility[];
34
+ };
35
+ /**
36
+ * A utility block (11.1): a named, versioned tool a platform mounts for the presets, relations or audiences
37
+ * it `serves`, the packages and utilities it `needs`, and the connections and settings a deployment must
38
+ * provide in `setup`. Read like any block; a reader that doesn't know it carries it unchanged (13.5).
39
+ */
40
+ export type Utility = {
41
+ name: string;
42
+ version: string;
43
+ label?: string;
44
+ describe?: string;
45
+ /** `curator(ship, returns)` → `{ as: "curator", items: ["ship", "returns"] }`; `controller` → no items. */
46
+ serves: {
47
+ as: string;
48
+ items?: string[];
49
+ line: number;
50
+ }[];
51
+ /** Package identities (`domain/name`, optionally ` /version`) and bare utility names. */
52
+ needs: {
53
+ name: string;
54
+ version?: string;
55
+ line: number;
56
+ }[];
57
+ setup: ({
58
+ connection: string;
59
+ line: number;
60
+ } | {
61
+ setting: string;
62
+ line: number;
63
+ })[];
64
+ line: number;
65
+ };
66
+ /** Split a file into its packages, keeping line numbers true. */
67
+ export declare function readPackages(source: string): PackageInfo[];
68
+ /** Check every package in a file (11.1, 11.3, 11.4). Throws the first problem. */
69
+ export declare function checkPackages(source: string): PackageInfo[];