@cruba/crubal 0.0.0-stage → 0.1.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 (63) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +69 -2
  3. package/dist/bin/crubal.d.ts +2 -0
  4. package/dist/bin/crubal.js +37 -0
  5. package/dist/bin/crubal.js.map +1 -0
  6. package/dist/src/browser.d.ts +10 -0
  7. package/dist/src/browser.js +13 -0
  8. package/dist/src/browser.js.map +1 -0
  9. package/dist/src/canonical.d.ts +6 -0
  10. package/dist/src/canonical.js +47 -0
  11. package/dist/src/canonical.js.map +1 -0
  12. package/dist/src/conditions.d.ts +22 -0
  13. package/dist/src/conditions.js +175 -0
  14. package/dist/src/conditions.js.map +1 -0
  15. package/dist/src/corpus.d.ts +8 -0
  16. package/dist/src/corpus.js +673 -0
  17. package/dist/src/corpus.js.map +1 -0
  18. package/dist/src/defs.d.ts +116 -0
  19. package/dist/src/defs.js +530 -0
  20. package/dist/src/defs.js.map +1 -0
  21. package/dist/src/dictionary.d.ts +50 -0
  22. package/dist/src/dictionary.js +498 -0
  23. package/dist/src/dictionary.js.map +1 -0
  24. package/dist/src/exchange.d.ts +45 -0
  25. package/dist/src/exchange.js +321 -0
  26. package/dist/src/exchange.js.map +1 -0
  27. package/dist/src/index.d.ts +15 -0
  28. package/dist/src/index.js +17 -0
  29. package/dist/src/index.js.map +1 -0
  30. package/dist/src/lex.d.ts +21 -0
  31. package/dist/src/lex.js +142 -0
  32. package/dist/src/lex.js.map +1 -0
  33. package/dist/src/migrate.d.ts +88 -0
  34. package/dist/src/migrate.js +191 -0
  35. package/dist/src/migrate.js.map +1 -0
  36. package/dist/src/model.d.ts +36 -0
  37. package/dist/src/model.js +32 -0
  38. package/dist/src/model.js.map +1 -0
  39. package/dist/src/packages.d.ts +25 -0
  40. package/dist/src/packages.js +98 -0
  41. package/dist/src/packages.js.map +1 -0
  42. package/dist/src/print-text.d.ts +7 -0
  43. package/dist/src/print-text.js +194 -0
  44. package/dist/src/print-text.js.map +1 -0
  45. package/dist/src/read-text.d.ts +8 -0
  46. package/dist/src/read-text.js +317 -0
  47. package/dist/src/read-text.js.map +1 -0
  48. package/dist/src/rules.d.ts +64 -0
  49. package/dist/src/rules.js +486 -0
  50. package/dist/src/rules.js.map +1 -0
  51. package/dist/src/store.d.ts +133 -0
  52. package/dist/src/store.js +396 -0
  53. package/dist/src/store.js.map +1 -0
  54. package/dist/src/tree.d.ts +32 -0
  55. package/dist/src/tree.js +123 -0
  56. package/dist/src/tree.js.map +1 -0
  57. package/dist/src/units.d.ts +4 -0
  58. package/dist/src/units.js +37 -0
  59. package/dist/src/units.js.map +1 -0
  60. package/dist/src/views.d.ts +114 -0
  61. package/dist/src/views.js +436 -0
  62. package/dist/src/views.js.map +1 -0
  63. package/package.json +58 -4
@@ -0,0 +1,88 @@
1
+ import type { Dictionary } from "./defs.ts";
2
+ import type { Record } from "./model.ts";
3
+ export type Step = {
4
+ verb: "rename";
5
+ facet: string;
6
+ from: string;
7
+ to: string;
8
+ line: number;
9
+ text: string;
10
+ } | {
11
+ verb: "merge";
12
+ facet: string;
13
+ from: string[];
14
+ to: string;
15
+ line: number;
16
+ text: string;
17
+ } | {
18
+ verb: "convert";
19
+ facet: string;
20
+ from: string;
21
+ to: string;
22
+ rounding: string;
23
+ line: number;
24
+ text: string;
25
+ } | {
26
+ verb: "precision";
27
+ facet: string;
28
+ from: string;
29
+ to: string;
30
+ line: number;
31
+ text: string;
32
+ } | {
33
+ verb: "split";
34
+ facet: string;
35
+ value: string;
36
+ when: {
37
+ cond: string;
38
+ to: string;
39
+ }[];
40
+ else?: string;
41
+ line: number;
42
+ text: string;
43
+ } | {
44
+ verb: "move";
45
+ facet: string;
46
+ to: string;
47
+ line: number;
48
+ text: string;
49
+ } | {
50
+ verb: "review";
51
+ facet: string;
52
+ cond: string;
53
+ line: number;
54
+ text: string;
55
+ } | {
56
+ verb: "recompute";
57
+ facet: string;
58
+ line: number;
59
+ text: string;
60
+ } | {
61
+ verb: "retype";
62
+ facet: string;
63
+ from: string;
64
+ to: string;
65
+ line: number;
66
+ text: string;
67
+ };
68
+ export type Recipe = {
69
+ from: string;
70
+ to: string;
71
+ steps: Step[];
72
+ line: number;
73
+ };
74
+ /** Read `migration:` blocks. */
75
+ export declare function readRecipes(source: string): Recipe[];
76
+ /** Publish checks (10.5) against the version the recipe reaches, given as `dict`. */
77
+ export declare function checkRecipe(r: Recipe, dict: Dictionary): void;
78
+ export type ReviewItem = {
79
+ record: string;
80
+ address: string;
81
+ step: string;
82
+ held: true;
83
+ };
84
+ /** Restamp records with a recipe. Returns the restamped records and the review queue. */
85
+ export declare function restamp(records: Record[], recipe: Recipe, dict: Dictionary): {
86
+ records: Record[];
87
+ review: ReviewItem[];
88
+ };
@@ -0,0 +1,191 @@
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 { evaluate, parseCondition } from "./conditions.js";
5
+ import { splitTop } from "./lex.js";
6
+ import { CrubalError, readTree } from "./tree.js";
7
+ import { convert, unitOf } from "./units.js";
8
+ const unq = (s) => (s.trim().startsWith('"') ? JSON.parse(s.trim()) : s.trim());
9
+ function arrow(text, line) {
10
+ const at = text.lastIndexOf(" -> ");
11
+ if (at < 0) {
12
+ if (text.startsWith("-> "))
13
+ return ["", text.slice(3).trim()];
14
+ throw new CrubalError(`expected "from -> to": ${text}`, line);
15
+ }
16
+ return [text.slice(0, at).trim(), text.slice(at + 4).trim()];
17
+ }
18
+ /** Read `migration:` blocks. */
19
+ export function readRecipes(source) {
20
+ const out = [];
21
+ for (const node of readTree(source)) {
22
+ if (node.kind !== "pair" || node.key !== "migration")
23
+ continue;
24
+ const [from, to] = arrow(node.value, node.line);
25
+ const recipe = { from, to, steps: [], line: node.line };
26
+ for (const group of node.children) {
27
+ if (group.key !== "facet")
28
+ throw new CrubalError(`a recipe groups its steps under "facet: key"`, group.line);
29
+ const facet = group.value.trim();
30
+ const kids = group.children;
31
+ for (let i = 0; i < kids.length; i++) {
32
+ const s = kids[i];
33
+ const base = { facet, line: s.line, text: s.text };
34
+ if (s.kind === "line" && s.text === "recompute") {
35
+ recipe.steps.push({ verb: "recompute", ...base });
36
+ continue;
37
+ }
38
+ switch (s.key) {
39
+ case "rename": {
40
+ const [a, b] = arrow(s.value, s.line);
41
+ recipe.steps.push({ verb: "rename", from: unq(a), to: unq(b), ...base });
42
+ break;
43
+ }
44
+ case "merge": {
45
+ const [a, b] = arrow(s.value, s.line);
46
+ recipe.steps.push({ verb: "merge", from: splitTop(a, ",", s.line).map(unq), to: unq(b), ...base });
47
+ break;
48
+ }
49
+ case "convert": {
50
+ const [a, b] = arrow(s.value, s.line);
51
+ const next = kids[i + 1];
52
+ const rounding = next?.key === "rounding" ? next.value : "nearest";
53
+ if (next?.key === "rounding")
54
+ i++;
55
+ recipe.steps.push({ verb: "convert", from: a, to: b, rounding, ...base });
56
+ break;
57
+ }
58
+ case "precision":
59
+ case "retype": {
60
+ const [a, b] = arrow(s.value, s.line);
61
+ recipe.steps.push({ verb: s.key, from: a, to: b, ...base });
62
+ break;
63
+ }
64
+ case "split": {
65
+ const when = [];
66
+ let otherwise;
67
+ for (const b of s.children) {
68
+ if (b.key === "when") {
69
+ const [cond, to] = arrow(b.value, b.line);
70
+ when.push({ cond, to: unq(to) });
71
+ }
72
+ else if (b.key === "else")
73
+ otherwise = unq(b.value);
74
+ }
75
+ recipe.steps.push({ verb: "split", value: unq(s.value), when, ...(otherwise !== undefined ? { else: otherwise } : {}), ...base });
76
+ break;
77
+ }
78
+ case "move":
79
+ recipe.steps.push({ verb: "move", to: arrow(s.value, s.line)[1], ...base });
80
+ break;
81
+ case "review":
82
+ recipe.steps.push({ verb: "review", cond: s.value, ...base });
83
+ break;
84
+ default:
85
+ throw new CrubalError(`unknown recipe step: ${s.text}`, s.line);
86
+ }
87
+ }
88
+ }
89
+ out.push(recipe);
90
+ }
91
+ return out;
92
+ }
93
+ /** Publish checks (10.5) against the version the recipe reaches, given as `dict`. */
94
+ export function checkRecipe(r, dict) {
95
+ for (const s of r.steps) {
96
+ const f = dict.facets.get(s.facet);
97
+ const real = new Set((f?.values ?? []).map((v) => v.value));
98
+ const need = (v) => {
99
+ if (f?.type === "choice" && !real.has(v))
100
+ throw new CrubalError(`${v} is not a value of ${s.facet} in ${r.to}`, s.line);
101
+ };
102
+ if (s.verb === "rename" || s.verb === "merge")
103
+ need(s.to);
104
+ if (s.verb === "split") {
105
+ for (const b of s.when)
106
+ need(b.to);
107
+ if (s.else !== undefined)
108
+ need(s.else);
109
+ }
110
+ if (s.verb === "convert" && convert("1", s.from, s.to) === null)
111
+ throw new CrubalError(`can't convert ${s.from} to ${s.to}`, s.line);
112
+ }
113
+ }
114
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
115
+ function mapScalars(v, fn) {
116
+ if (Array.isArray(v))
117
+ return v.map((x) => mapScalars(x, fn));
118
+ if (isObj(v) && "$value" in v)
119
+ return { ...v, $value: fn(v.$value) };
120
+ return fn(v);
121
+ }
122
+ /** Restamp records with a recipe. Returns the restamped records and the review queue. */
123
+ export function restamp(records, recipe, dict) {
124
+ const review = [];
125
+ const out = records.map((rec) => {
126
+ const values = { ...rec.values };
127
+ for (const s of recipe.steps) {
128
+ const v = values[s.facet];
129
+ if (v === undefined && s.verb !== "review")
130
+ continue;
131
+ switch (s.verb) {
132
+ case "rename":
133
+ values[s.facet] = mapScalars(v, (x) => (x === s.from ? s.to : x));
134
+ break;
135
+ case "merge":
136
+ values[s.facet] = mapScalars(v, (x) => (typeof x === "string" && s.from.includes(x) ? s.to : x));
137
+ break;
138
+ case "convert":
139
+ values[s.facet] = mapScalars(v, (x) => {
140
+ if (!isObj(x) || !("$qty" in x))
141
+ return x;
142
+ const unit = unitOf(String(x.unit)) ?? String(x.unit);
143
+ if (unit !== s.from)
144
+ return x;
145
+ const places = dict.facets.get(s.facet)?.places ?? 0;
146
+ const exact = Number(convert(String(x.$qty), s.from, s.to, 12));
147
+ const scale = 10 ** places;
148
+ const round = s.rounding === "down" ? Math.floor : s.rounding === "up" ? Math.ceil : Math.round;
149
+ return { $qty: String(round(exact * scale) / scale), unit: s.to };
150
+ });
151
+ break;
152
+ case "precision": {
153
+ const len = s.to === "year" ? 4 : s.to === "month" ? 7 : 10;
154
+ values[s.facet] = mapScalars(v, (x) => (typeof x === "string" && x.length > len ? x.slice(0, len) : x));
155
+ break;
156
+ }
157
+ case "split":
158
+ values[s.facet] = mapScalars(v, (x) => {
159
+ if (x !== s.value)
160
+ return x;
161
+ for (const b of s.when)
162
+ if (evaluate(parseCondition(b.cond, s.line), values) === true)
163
+ return b.to;
164
+ if (s.else !== undefined)
165
+ return s.else;
166
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
167
+ return x;
168
+ });
169
+ break;
170
+ case "move":
171
+ if (!/^[A-Za-z_][\w:]*$/.test(s.to) || values[s.to] !== undefined) {
172
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
173
+ break;
174
+ }
175
+ values[s.to] = v;
176
+ delete values[s.facet];
177
+ break;
178
+ case "review":
179
+ if (evaluate(parseCondition(s.cond, s.line), values) === true)
180
+ review.push({ record: rec.id, address: s.facet, step: s.text, held: true });
181
+ break;
182
+ case "recompute":
183
+ case "retype":
184
+ break; // the rules rebuild produced values; the new type reads the value on the next check
185
+ }
186
+ }
187
+ return { ...rec, values };
188
+ });
189
+ return { records: out, review };
190
+ }
191
+ //# 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,36 @@
1
+ export type Json = string | number | boolean | Json[] | JsonObject;
2
+ export type JsonObject = {
3
+ [key: string]: Json;
4
+ };
5
+ export type Source = {
6
+ origin: string;
7
+ via: string;
8
+ owner?: string;
9
+ adopted?: boolean;
10
+ };
11
+ export type Record = {
12
+ id: string;
13
+ kind: string;
14
+ level: string;
15
+ of?: string;
16
+ owner: string;
17
+ wears?: string[];
18
+ created?: string;
19
+ updated?: string;
20
+ values: JsonObject;
21
+ parts?: Json[];
22
+ sources?: {
23
+ [address: string]: Source;
24
+ };
25
+ };
26
+ export type Wrapper = {
27
+ crubal: string;
28
+ package?: string;
29
+ prefixes?: {
30
+ [prefix: string]: string;
31
+ };
32
+ records: Record[];
33
+ };
34
+ /** Refuse JSON the spec forbids: `null` anywhere (chapter 3), unknown record members (3.2). */
35
+ export declare function checkJson(doc: unknown, path?: string): void;
36
+ export declare function checkWrapper(w: Wrapper): void;
@@ -0,0 +1,32 @@
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
+ const RECORD_MEMBERS = new Set(["id", "kind", "level", "of", "owner", "wears", "created", "updated", "values", "parts", "sources", "alternatives", "suggestions"]);
4
+ /** Refuse JSON the spec forbids: `null` anywhere (chapter 3), unknown record members (3.2). */
5
+ export function checkJson(doc, path = "$") {
6
+ if (doc === null)
7
+ throw new Error(`null at ${path}: CRUBAL JSON never holds null`);
8
+ if (Array.isArray(doc)) {
9
+ doc.forEach((d, i) => checkJson(d, `${path}[${i}]`));
10
+ return;
11
+ }
12
+ if (typeof doc === "object") {
13
+ for (const [k, v] of Object.entries(doc))
14
+ checkJson(v, `${path}.${k}`);
15
+ }
16
+ }
17
+ export function checkWrapper(w) {
18
+ checkJson(w);
19
+ if (!Array.isArray(w.records))
20
+ throw new Error("a wrapper needs records");
21
+ w.records.forEach((r, i) => {
22
+ for (const k of Object.keys(r)) {
23
+ if (!RECORD_MEMBERS.has(k))
24
+ throw new Error(`records[${i}] has an unknown member ${k}`);
25
+ }
26
+ for (const k of ["id", "kind", "level", "owner", "values"]) {
27
+ if (r[k] === undefined)
28
+ throw new Error(`records[${i}] needs ${k}`);
29
+ }
30
+ });
31
+ }
32
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,0CAA0C;AA4B1C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;AAEnK,+FAA+F;AAC/F,MAAM,UAAU,SAAS,CAAC,GAAY,EAAE,IAAI,GAAG,GAAG;IAChD,IAAI,GAAG,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,gCAAgC,CAAC,CAAC;IACnF,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAa,CAAC;YAAE,SAAS,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,SAAS,CAAC,CAAC,CAAC,CAAC;IACb,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC1E,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAU,EAAE,CAAC;YACpE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type Dictionary } from "./defs.ts";
2
+ export type PackageInfo = {
3
+ name: string;
4
+ version: string;
5
+ owner: string;
6
+ line: number;
7
+ extends: {
8
+ name: string;
9
+ version: string;
10
+ }[];
11
+ prefixes: Map<string, {
12
+ target: string;
13
+ line: number;
14
+ }>;
15
+ trust: {
16
+ entry: string;
17
+ line: number;
18
+ }[];
19
+ dict: Dictionary;
20
+ contracts: string[];
21
+ };
22
+ /** Split a file into its packages, keeping line numbers true. */
23
+ export declare function readPackages(source: string): PackageInfo[];
24
+ /** Check every package in a file (11.1, 11.3, 11.4). Throws the first problem. */
25
+ export declare function checkPackages(source: string): PackageInfo[];
@@ -0,0 +1,98 @@
1
+ // packages.ts: package files (spec chapter 11). A file may hold several packages, each starting at a
2
+ // `package:` line. The checks here are 11.1's prefixes, 11.3's trust entries and 11.4's rule that an
3
+ // extending package may add to what it extends but never change it.
4
+ import { emptyDictionary, readDefinitions } from "./defs.js";
5
+ import { readContracts } from "./store.js";
6
+ import { CrubalError, readTree } from "./tree.js";
7
+ const ORIGINS = new Set(["observed", "declared", "derived", "reported"]);
8
+ /** Split a file into its packages, keeping line numbers true. */
9
+ export function readPackages(source) {
10
+ const lines = source.split(/\r?\n/);
11
+ const starts = lines.flatMap((l, i) => (/^package: /.test(l) ? [i] : []));
12
+ return starts.map((start, n) => {
13
+ const end = starts[n + 1] ?? lines.length;
14
+ const text = lines.map((l, i) => (i >= start && i < end ? l : "")).join("\n");
15
+ const [head, ...rest] = readTree(text);
16
+ if (!head)
17
+ throw new CrubalError("an empty package", start + 1);
18
+ const [name = "", version = ""] = head.value.split(/\s+\//).map((s) => s.trim());
19
+ const info = { name, version, owner: "", line: head.line, extends: [], prefixes: new Map(), trust: [], dict: emptyDictionary(), contracts: [] };
20
+ for (const c of head.children) {
21
+ if (c.key === "owner")
22
+ info.owner = c.value;
23
+ if (c.key === "extends") {
24
+ for (const e of c.value.split(",")) {
25
+ const [en = "", ev = ""] = e.trim().split(/\s+\//);
26
+ info.extends.push({ name: en.trim(), version: ev.trim() });
27
+ }
28
+ }
29
+ if (c.key === "prefixes")
30
+ for (const p of c.children)
31
+ if (p.key)
32
+ info.prefixes.set(p.key, { target: p.value, line: p.line });
33
+ }
34
+ for (const node of rest) {
35
+ if (node.key === "trust")
36
+ for (const t of node.children)
37
+ info.trust.push({ entry: t.text.trim(), line: t.line });
38
+ }
39
+ // Definitions are everything after the header block.
40
+ const headerEnd = Math.max(start, ...head.children.flatMap(function deep(c) { return [c.line - 1, ...c.children.flatMap(deep)]; }));
41
+ const defs = text.split("\n").map((l, i) => (i > headerEnd ? l : "")).join("\n");
42
+ readDefinitions(defs, info.dict);
43
+ info.contracts = readContracts(defs).map((c) => c.name);
44
+ return info;
45
+ });
46
+ }
47
+ function sameDefinition(base, mine) {
48
+ if (base.type !== mine.type)
49
+ return "type";
50
+ if (base.pick !== mine.pick)
51
+ return "pick";
52
+ if ((base.unit ?? "") !== (mine.unit ?? ""))
53
+ return "unit";
54
+ const baseValues = (base.values ?? []).map((v) => v.value);
55
+ const mineValues = (mine.values ?? []).map((v) => v.value);
56
+ if (mine.values && baseValues.some((v) => !mineValues.includes(v)))
57
+ return "values";
58
+ return null;
59
+ }
60
+ /** Check every package in a file (11.1, 11.3, 11.4). Throws the first problem. */
61
+ export function checkPackages(source) {
62
+ const pkgs = readPackages(source);
63
+ const byName = new Map(pkgs.map((p) => [p.name, p]));
64
+ for (const p of pkgs) {
65
+ for (const [prefix, { target, line }] of p.prefixes) {
66
+ if (prefix === "crubal")
67
+ throw new CrubalError("the prefix crubal is reserved for the core", line);
68
+ if (prefix === p.name && target !== `${p.owner}/${p.name}`)
69
+ throw new CrubalError(`${p.name} can't map its own name to something else`, line);
70
+ }
71
+ for (const { entry, line } of p.trust) {
72
+ if (entry === "person" || ORIGINS.has(entry))
73
+ continue;
74
+ const bare = entry.startsWith(`${p.name}:`) ? entry.slice(p.name.length + 1) : entry;
75
+ if (p.contracts.includes(bare))
76
+ continue;
77
+ if (!entry.includes(":") && entry.includes("."))
78
+ continue; // a party's domain
79
+ throw new CrubalError(`${entry} is not a contract of this package`, line);
80
+ }
81
+ for (const f of p.dict.facets.values()) {
82
+ const m = f.key.match(/^([a-z][a-z0-9-]*):(.+)$/);
83
+ if (!m || m[1] === "crubal")
84
+ continue;
85
+ const base = byName.get(m[1]);
86
+ if (!base || !p.extends.some((e) => e.name === base.name))
87
+ continue;
88
+ const original = base.dict.facets.get(m[2]);
89
+ if (!original)
90
+ continue;
91
+ const changed = sameDefinition(original, f);
92
+ if (changed)
93
+ throw new CrubalError(`${p.name} changes ${f.key}'s ${changed}; an extending package may only add to it`, f.line);
94
+ }
95
+ }
96
+ return pkgs;
97
+ }
98
+ //# sourceMappingURL=packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packages.js","sourceRoot":"","sources":["../../src/packages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type Dictionary, type Facet } from "./defs.ts";
2
+ import type { Json, Wrapper } from "./model.ts";
3
+ export type PrintMode = "full" | "plain";
4
+ /** A list item's text form with its qualifiers and without its sources: the selector in an address. */
5
+ export declare function itemText(f: Facet, v: Json): string;
6
+ /** Print a wrapper as text. */
7
+ export declare function printText(w: Wrapper, dict: Dictionary, mode?: PrintMode): string;