@cbortech/cbor 0.27.0 → 0.27.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +100 -0
- package/README.md +103 -0
- package/dist/ast/CborAppSeqResult.d.ts +37 -4
- package/dist/ast/CborArray.d.ts +2 -2
- package/dist/ast/CborByteString.d.ts +2 -2
- package/dist/ast/CborEmbeddedCBOR.d.ts +1 -1
- package/dist/ast/CborFloat.d.ts +1 -1
- package/dist/ast/CborIndefiniteByteString.d.ts +1 -1
- package/dist/ast/CborIndefiniteTextString.d.ts +1 -1
- package/dist/ast/CborItem.d.ts +314 -9
- package/dist/ast/CborMap.d.ts +2 -2
- package/dist/ast/CborNint.d.ts +1 -1
- package/dist/ast/CborTag.d.ts +26 -4
- package/dist/ast/CborTextString.d.ts +2 -2
- package/dist/ast/CborUint.d.ts +1 -1
- package/dist/ast/CborUnresolvedAppExt.d.ts +9 -0
- package/dist/ast/index.cjs +1 -1
- package/dist/ast/index.js +2 -2
- package/dist/cbor/tagLabels.d.ts +26 -0
- package/dist/cddl/eRefScope.d.ts +241 -0
- package/dist/cddl/eref.d.ts +64 -0
- package/dist/cddl/implicitTags.d.ts +28 -0
- package/dist/cddl/index.cjs +2 -2
- package/dist/cddl/index.cjs.map +1 -1
- package/dist/cddl/index.d.ts +2 -0
- package/dist/cddl/index.js +26 -25
- package/dist/cddl/index.js.map +1 -1
- package/dist/cddl/validator.d.ts +98 -2
- package/dist/cdn/index.cjs +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/cdn/serialize-utils.d.ts +50 -15
- package/dist/extensions/cri.d.ts +2 -2
- package/dist/extensions/dt.d.ts +4 -4
- package/dist/extensions/eref.d.ts +135 -0
- package/dist/extensions/ip.d.ts +3 -3
- package/dist/extensions/types.d.ts +40 -1
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +190 -81
- package/dist/index.js.map +1 -1
- package/dist/js/fromJS.d.ts +23 -1
- package/dist/mapEntries-8zshEr-t.js +7085 -0
- package/dist/mapEntries-8zshEr-t.js.map +1 -0
- package/dist/mapEntries-DwHPAzCN.cjs +68 -0
- package/dist/mapEntries-DwHPAzCN.cjs.map +1 -0
- package/dist/schema-7r2xjpMK.js +345 -0
- package/dist/schema-7r2xjpMK.js.map +1 -0
- package/dist/schema-YiigSWjR.cjs +8 -0
- package/dist/schema-YiigSWjR.cjs.map +1 -0
- package/dist/{serialize-utils-BuIZPaUc.js → serialize-utils-BQtutOo6.js} +70 -52
- package/dist/serialize-utils-BQtutOo6.js.map +1 -0
- package/dist/{serialize-utils-CjTqQivB.cjs → serialize-utils-DQ8T3Mzw.cjs} +9 -9
- package/dist/serialize-utils-DQ8T3Mzw.cjs.map +1 -0
- package/dist/types.d.ts +426 -4
- package/dist/utils/hexfloat.d.ts +10 -2
- package/package.json +13 -14
- package/dist/mapEntries-C1f7G0AM.cjs +0 -13
- package/dist/mapEntries-C1f7G0AM.cjs.map +0 -1
- package/dist/mapEntries-CvLdiN0h.js +0 -3946
- package/dist/mapEntries-CvLdiN0h.js.map +0 -1
- package/dist/schema-CNfrVRYp.js +0 -1977
- package/dist/schema-CNfrVRYp.js.map +0 -1
- package/dist/schema-iXpYtKQl.cjs +0 -63
- package/dist/schema-iXpYtKQl.cjs.map +0 -1
- package/dist/serialize-utils-BuIZPaUc.js.map +0 -1
- package/dist/serialize-utils-CjTqQivB.cjs.map +0 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { D as e, Q as t, W as n, d as r, f as i, l as a, x as o } from "./mapEntries-8zshEr-t.js";
|
|
2
|
+
//#region src/cddl/writer.ts
|
|
3
|
+
var s = {
|
|
4
|
+
leading: [],
|
|
5
|
+
trailing: []
|
|
6
|
+
};
|
|
7
|
+
function c(e, t) {
|
|
8
|
+
let n = {
|
|
9
|
+
unit: t?.indent === void 0 ? null : typeof t.indent == "string" ? t.indent : " ".repeat(t.indent),
|
|
10
|
+
notes: null,
|
|
11
|
+
endNotes: null,
|
|
12
|
+
tail: []
|
|
13
|
+
};
|
|
14
|
+
if (t?.preserveComments && t.comments !== void 0 && t.comments.length > 0 && t.source !== void 0) {
|
|
15
|
+
let r = l(e, t.comments, t.source);
|
|
16
|
+
n.notes = r.notes, n.endNotes = r.endNotes, n.tail = r.tail;
|
|
17
|
+
}
|
|
18
|
+
let r = [], i = !1;
|
|
19
|
+
e.forEach((e, t) => {
|
|
20
|
+
let { text: a, multiline: o } = f(e, n);
|
|
21
|
+
t > 0 && n.unit !== null && (o || i) && r.push(""), r.push(a), i = o;
|
|
22
|
+
});
|
|
23
|
+
for (let e of n.tail) r.push(`;${e}`);
|
|
24
|
+
return r.length === 0 ? "" : r.join("\n") + "\n";
|
|
25
|
+
}
|
|
26
|
+
function l(e, t, n) {
|
|
27
|
+
let r = [0];
|
|
28
|
+
for (let e = 0; e < n.length; e++) n.charCodeAt(e) === 10 && r.push(e + 1);
|
|
29
|
+
let i = (e) => {
|
|
30
|
+
let t = 0, n = r.length - 1;
|
|
31
|
+
for (; t < n;) {
|
|
32
|
+
let i = t + n + 1 >> 1;
|
|
33
|
+
r[i] <= e ? t = i : n = i - 1;
|
|
34
|
+
}
|
|
35
|
+
return t + 1;
|
|
36
|
+
}, a = [], o = [], s = (e, t, n) => {
|
|
37
|
+
o.push({
|
|
38
|
+
group: e,
|
|
39
|
+
start: t,
|
|
40
|
+
end: n
|
|
41
|
+
});
|
|
42
|
+
for (let t of e.choices) t.forEach(c);
|
|
43
|
+
}, c = (e) => {
|
|
44
|
+
if (a.push({
|
|
45
|
+
node: e,
|
|
46
|
+
start: e.start,
|
|
47
|
+
end: e.end,
|
|
48
|
+
isRule: !1
|
|
49
|
+
}), e.kind === "entry-group") {
|
|
50
|
+
s(e.group, e.start, e.end);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
for (let t of e.value.alternatives) l(t);
|
|
54
|
+
}, l = (e) => {
|
|
55
|
+
u(e.target), e.controller && u(e.controller);
|
|
56
|
+
}, u = (e) => {
|
|
57
|
+
switch (e.kind) {
|
|
58
|
+
case "map":
|
|
59
|
+
case "array":
|
|
60
|
+
s(e.group, e.start, e.end);
|
|
61
|
+
return;
|
|
62
|
+
case "paren":
|
|
63
|
+
for (let t of e.type.alternatives) l(t);
|
|
64
|
+
return;
|
|
65
|
+
case "enum":
|
|
66
|
+
e.group.kind === "group" && s(e.group, e.start, e.end);
|
|
67
|
+
return;
|
|
68
|
+
case "tagged":
|
|
69
|
+
if (typeof e.tag == "object") for (let t of e.tag.alternatives) l(t);
|
|
70
|
+
for (let t of e.item.alternatives) l(t);
|
|
71
|
+
return;
|
|
72
|
+
default: return;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
for (let t of e) a.push({
|
|
76
|
+
node: t,
|
|
77
|
+
start: t.start,
|
|
78
|
+
end: t.end,
|
|
79
|
+
isRule: !0
|
|
80
|
+
}), c(t.body);
|
|
81
|
+
let d = [...a].sort((e, t) => e.end - t.end || Number(e.isRule) - Number(t.isRule)), f = [...a].sort((e, t) => e.start - t.start || Number(t.isRule) - Number(e.isRule)), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), h = [], g = (e) => {
|
|
82
|
+
let t = p.get(e);
|
|
83
|
+
return t || (t = {
|
|
84
|
+
leading: [],
|
|
85
|
+
trailing: []
|
|
86
|
+
}, p.set(e, t)), t;
|
|
87
|
+
};
|
|
88
|
+
for (let n of t) {
|
|
89
|
+
let t;
|
|
90
|
+
for (let e = d.length - 1; e >= 0; e--) {
|
|
91
|
+
let r = d[e];
|
|
92
|
+
if (!(r.end > n.start)) {
|
|
93
|
+
i(Math.max(r.start, r.end - 1)) === n.line && (t = r);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (t) {
|
|
98
|
+
g(t.node).trailing.push(n.text);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
let r;
|
|
102
|
+
for (let e of o) e.start <= n.start && n.end <= e.end && (!r || e.start >= r.start) && (r = e);
|
|
103
|
+
let a = e.find((e) => e.start <= n.start && n.end <= e.end), s = f.find((e) => e.start >= n.end), c = r !== void 0 && (s === void 0 || s.start > r.end), l = a !== void 0 && (s === void 0 || s.start > a.end);
|
|
104
|
+
if (s && !c && !l) g(s.node).leading.push(n.text);
|
|
105
|
+
else if (c) {
|
|
106
|
+
let e = m.get(r.group) ?? [];
|
|
107
|
+
e.push(n.text), m.set(r.group, e);
|
|
108
|
+
} else l ? g(a).trailing.push(n.text) : s ? g(s.node).leading.push(n.text) : h.push(n.text);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
notes: p,
|
|
112
|
+
endNotes: m,
|
|
113
|
+
tail: h
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
var u = (e, t) => e.notes?.get(t) ?? s, d = (e) => e.trailing.length === 0 ? "" : " " + e.trailing.map((e) => `;${e}`).join(" ");
|
|
117
|
+
function f(e, t) {
|
|
118
|
+
let n = u(t, e), r = u(t, e.body), i = e.generics ? `<${e.generics.join(", ")}>` : "", a = `${e.name}${i} ${e.assign}`, o = d({
|
|
119
|
+
leading: [],
|
|
120
|
+
trailing: [...r.trailing, ...n.trailing]
|
|
121
|
+
}), s, c = n.leading;
|
|
122
|
+
if (r.leading.length > 0 && t.unit !== null) {
|
|
123
|
+
let n = t.unit;
|
|
124
|
+
s = [
|
|
125
|
+
a,
|
|
126
|
+
...r.leading.map((e) => `${n};${e}`),
|
|
127
|
+
`${n}${p(e.body, t, 1)}${o}`
|
|
128
|
+
].join("\n");
|
|
129
|
+
} else r.leading.length > 0 && (c = [...c, ...r.leading]), s = `${a} ${p(e.body, t, 0)}${o}`;
|
|
130
|
+
let l = s.includes("\n");
|
|
131
|
+
return c.length === 0 ? {
|
|
132
|
+
text: s,
|
|
133
|
+
multiline: l
|
|
134
|
+
} : {
|
|
135
|
+
text: [...c.map((e) => `;${e}`), s].join("\n"),
|
|
136
|
+
multiline: l
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function p(e, t, n) {
|
|
140
|
+
let r = e.occur ? `${m(e.occur)} ` : "";
|
|
141
|
+
return e.kind === "entry-group" ? `${r}${g(e.group, t, n, "(", ")")}` : `${r}${e.memberKey ? `${h(e.memberKey, t, n)} ` : ""}${_(e.value, t, n)}`;
|
|
142
|
+
}
|
|
143
|
+
function m(e) {
|
|
144
|
+
return e.marker === "*" ? `${e.min ?? ""}*${e.max ?? ""}` : e.marker;
|
|
145
|
+
}
|
|
146
|
+
function h(e, t, n) {
|
|
147
|
+
switch (e.kind) {
|
|
148
|
+
case "bareword": return `${e.key}:`;
|
|
149
|
+
case "value": return `${e.key.raw}:`;
|
|
150
|
+
case "type1": return `${v(e.key, t, n)} ${e.cut ? "^ " : ""}=>`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function g(e, t, n, r, i) {
|
|
154
|
+
let a = e.choices.reduce((e, t) => e + t.length, 0), o = t.endNotes?.get(e) ?? [], s = o.length > 0 || t.notes !== null && e.choices.some((e) => e.some((e) => t.notes.has(e)));
|
|
155
|
+
if (!(t.unit !== null && (a > 1 || e.choices.length > 1 || s))) return `${r}${e.choices.map((e) => e.map((e) => p(e, t, n)).join(", ")).join(" // ") + (e.trailingComma ? "," : "")}${i}`;
|
|
156
|
+
let c = t.unit, l = c.repeat(n + 1), f = [r];
|
|
157
|
+
e.choices.forEach((r, i) => {
|
|
158
|
+
i > 0 && f.push(`${l}//`), r.forEach((a, o) => {
|
|
159
|
+
let s = u(t, a);
|
|
160
|
+
for (let e of s.leading) f.push(`${l};${e}`);
|
|
161
|
+
let c = i !== e.choices.length - 1 || o !== r.length - 1 || e.trailingComma ? "," : "";
|
|
162
|
+
f.push(`${l}${p(a, t, n + 1)}${c}${d(s)}`);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
for (let e of o) f.push(`${l};${e}`);
|
|
166
|
+
return f.push(`${c.repeat(n)}${i}`), f.join("\n");
|
|
167
|
+
}
|
|
168
|
+
function _(e, t, n) {
|
|
169
|
+
return e.alternatives.map((e) => v(e, t, n)).join(" / ");
|
|
170
|
+
}
|
|
171
|
+
function v(e, t, n) {
|
|
172
|
+
let r = b(e.target, t, n);
|
|
173
|
+
if (!e.op || !e.controller) return r;
|
|
174
|
+
let i = b(e.controller, t, n);
|
|
175
|
+
return e.op.kind === "range" ? `${r}${e.op.inclusive ? ".." : "..."}${i}` : `${r} .${e.op.name} ${i}`;
|
|
176
|
+
}
|
|
177
|
+
function y(e, t, n) {
|
|
178
|
+
let r = e.genericArgs ? `<${e.genericArgs.map((e) => v(e, t, n)).join(", ")}>` : "";
|
|
179
|
+
return `${e.name}${r}`;
|
|
180
|
+
}
|
|
181
|
+
function b(e, t, n) {
|
|
182
|
+
switch (e.kind) {
|
|
183
|
+
case "value": return e.raw;
|
|
184
|
+
case "ref": return y(e, t, n);
|
|
185
|
+
case "paren": return `(${_(e.type, t, n)})`;
|
|
186
|
+
case "map": return g(e.group, t, n, "{", "}");
|
|
187
|
+
case "array": return g(e.group, t, n, "[", "]");
|
|
188
|
+
case "unwrap": return `~${y(e.ref, t, n)}`;
|
|
189
|
+
case "enum": return e.group.kind === "ref" ? `&${y(e.group, t, n)}` : `&${g(e.group, t, n, "(", ")")}`;
|
|
190
|
+
case "tagged": return `${e.raw ?? (typeof e.tag == "object" ? `#6.<${_(e.tag, t, n)}>` : `#6${e.tag === void 0 ? "" : `.${e.tag}`}`)}(${_(e.item, t, n)})`;
|
|
191
|
+
case "major": return e.raw === void 0 ? typeof e.ai == "object" ? `#${e.major}.<${_(e.ai, t, n)}>` : `#${e.major}${e.ai === void 0 ? "" : `.${e.ai}`}` : e.raw;
|
|
192
|
+
case "any": return "#";
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/cddl/schema.ts
|
|
197
|
+
var x = class {
|
|
198
|
+
source;
|
|
199
|
+
comments;
|
|
200
|
+
ast;
|
|
201
|
+
rules;
|
|
202
|
+
root;
|
|
203
|
+
warnings;
|
|
204
|
+
constructor(e, t, n, r, i, a) {
|
|
205
|
+
this.source = e, this.comments = t, this.ast = n, this.rules = r, i && (this.root = i), a.length > 0 && (this.warnings = a);
|
|
206
|
+
}
|
|
207
|
+
format(e) {
|
|
208
|
+
return c(this.ast, {
|
|
209
|
+
...e,
|
|
210
|
+
source: this.source,
|
|
211
|
+
comments: this.comments
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
validate(t, r) {
|
|
215
|
+
let i = t instanceof n ? t : typeof t == "string" ? e(t) : o(t);
|
|
216
|
+
return a(this, i, r);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
function S(e, n) {
|
|
220
|
+
let { rules: a, comments: o } = i(e), s = [], c = r();
|
|
221
|
+
a.length === 0 && s.push({
|
|
222
|
+
code: "no-rules",
|
|
223
|
+
message: "a CDDL data model needs at least one rule to provide the root of the definition"
|
|
224
|
+
});
|
|
225
|
+
let l = /* @__PURE__ */ new Map();
|
|
226
|
+
for (let e of a) {
|
|
227
|
+
let t = l.get(e.name);
|
|
228
|
+
if (!t) {
|
|
229
|
+
l.set(e.name, [e]);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
e.assign === "=" && s.push({
|
|
233
|
+
code: "duplicate-rule",
|
|
234
|
+
message: `rule '${e.name}' is already defined; use /= or //= to extend it`,
|
|
235
|
+
start: e.start,
|
|
236
|
+
end: e.end
|
|
237
|
+
}), t.push(e);
|
|
238
|
+
}
|
|
239
|
+
let u = (e) => {
|
|
240
|
+
let t = l.get(e);
|
|
241
|
+
if (t) return t[0].generics?.length ?? 0;
|
|
242
|
+
let n = c.get(e);
|
|
243
|
+
if (n) return n.generics?.length ?? 0;
|
|
244
|
+
};
|
|
245
|
+
for (let e of a) {
|
|
246
|
+
let t = e.generics;
|
|
247
|
+
w(e.body, {
|
|
248
|
+
onRef(e) {
|
|
249
|
+
if (t?.includes(e.name) || e.name.startsWith("$")) return;
|
|
250
|
+
let n = u(e.name);
|
|
251
|
+
if (n === void 0) {
|
|
252
|
+
s.push({
|
|
253
|
+
code: "undefined-name",
|
|
254
|
+
message: `'${e.name}' is not defined (and is not a prelude name)`,
|
|
255
|
+
start: e.start,
|
|
256
|
+
end: e.end
|
|
257
|
+
});
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
let r = e.genericArgs?.length ?? 0;
|
|
261
|
+
n !== r && s.push({
|
|
262
|
+
code: "generic-arity",
|
|
263
|
+
message: `'${e.name}' takes ${n} generic argument${n === 1 ? "" : "s"} but is used with ${r}`,
|
|
264
|
+
start: e.start,
|
|
265
|
+
end: e.end
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
onMajor(e, t, n) {
|
|
269
|
+
e > 7 && s.push({
|
|
270
|
+
code: "invalid-major",
|
|
271
|
+
message: `#${e} is not a CBOR major type (0–7)`,
|
|
272
|
+
start: t,
|
|
273
|
+
end: n
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
let d = a[0];
|
|
279
|
+
if (d && !C(d.body) && s.push({
|
|
280
|
+
code: "invalid-root",
|
|
281
|
+
message: `the first rule '${d.name}' is the root of the data model and must define a type, not a group (RFC 8610 §2.2.4)`,
|
|
282
|
+
start: d.start,
|
|
283
|
+
end: d.end
|
|
284
|
+
}), (n?.strict ?? !0) && s.length > 0) throw new t(s);
|
|
285
|
+
return new x(e, o, a, l, d, s);
|
|
286
|
+
}
|
|
287
|
+
function C(e) {
|
|
288
|
+
if (e.kind === "entry") return !e.occur && !e.memberKey;
|
|
289
|
+
if (e.occur || e.group.trailingComma) return !1;
|
|
290
|
+
let { choices: t } = e.group;
|
|
291
|
+
return t.length === 1 && t[0].length === 1 && C(t[0][0]);
|
|
292
|
+
}
|
|
293
|
+
function w(e, t) {
|
|
294
|
+
if (e.kind === "entry-group") {
|
|
295
|
+
T(e.group, t);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
e.memberKey?.kind === "type1" && D(e.memberKey.key, t), E(e.value, t);
|
|
299
|
+
}
|
|
300
|
+
function T(e, t) {
|
|
301
|
+
for (let n of e.choices) for (let e of n) w(e, t);
|
|
302
|
+
}
|
|
303
|
+
function E(e, t) {
|
|
304
|
+
for (let n of e.alternatives) D(n, t);
|
|
305
|
+
}
|
|
306
|
+
function D(e, t) {
|
|
307
|
+
O(e.target, t), e.controller && O(e.controller, t);
|
|
308
|
+
}
|
|
309
|
+
function O(e, t) {
|
|
310
|
+
switch (e.kind) {
|
|
311
|
+
case "value":
|
|
312
|
+
case "any": return;
|
|
313
|
+
case "ref":
|
|
314
|
+
t.onRef(e);
|
|
315
|
+
for (let n of e.genericArgs ?? []) D(n, t);
|
|
316
|
+
return;
|
|
317
|
+
case "paren":
|
|
318
|
+
E(e.type, t);
|
|
319
|
+
return;
|
|
320
|
+
case "map":
|
|
321
|
+
case "array":
|
|
322
|
+
T(e.group, t);
|
|
323
|
+
return;
|
|
324
|
+
case "unwrap":
|
|
325
|
+
t.onRef(e.ref);
|
|
326
|
+
for (let n of e.ref.genericArgs ?? []) D(n, t);
|
|
327
|
+
return;
|
|
328
|
+
case "enum":
|
|
329
|
+
if (e.group.kind === "ref") {
|
|
330
|
+
t.onRef(e.group);
|
|
331
|
+
for (let n of e.group.genericArgs ?? []) D(n, t);
|
|
332
|
+
} else T(e.group, t);
|
|
333
|
+
return;
|
|
334
|
+
case "tagged":
|
|
335
|
+
typeof e.tag == "object" && E(e.tag, t), E(e.item, t);
|
|
336
|
+
return;
|
|
337
|
+
case "major":
|
|
338
|
+
t.onMajor(e.major, e.start, e.end), typeof e.ai == "object" && E(e.ai, t);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
//#endregion
|
|
343
|
+
export { S as n, x as t };
|
|
344
|
+
|
|
345
|
+
//# sourceMappingURL=schema-7r2xjpMK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-7r2xjpMK.js","names":[],"sources":["../src/cddl/writer.ts","../src/cddl/schema.ts"],"sourcesContent":["/**\n * CDDL formatter: serialize rule ASTs back to CDDL text.\n *\n * Two layouts:\n * - Compact (default): one rule per line with single-space separators.\n * - Pretty (`indent` set): groups with more than one entry (or group\n * choices) put each entry on its own indented line; multi-line rules are\n * separated by blank lines.\n *\n * Literal values are emitted verbatim from their source text (`raw`), so\n * number bases, string escapes, and byte-string qualifiers survive a round\n * trip. With `preserveComments`, `;` comments are re-attached by position\n * and none is dropped: rule leading/trailing, before a rule body (after\n * `=`), on group entries, before a group's closing delimiter, and — for\n * comments inside inline-only positions such as type choices — on the\n * enclosing rule's line end. The compact layout cannot hold an interior\n * line comment (`;` runs to the end of the line), so it hoists body\n * comments above the rule and keeps only rule-level placements.\n */\n\nimport type { CddlComment } from './tokenizer';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlMemberKey,\n CddlOccur,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\n\nexport interface CddlFormatOptions {\n /**\n * Pretty-print groups with one entry per line, indented by this many\n * spaces (or by the given string). Omit for compact single-line rules.\n */\n indent?: number | string;\n /**\n * Re-emit `;` comments. Rule-level comments are kept in both layouts;\n * comments attached to group entries require `indent` (the pretty\n * layout). Only effective when the formatter has the comment stream and\n * source text — i.e. when called through `CddlSchema.format()`.\n */\n preserveComments?: boolean;\n}\n\n/** @internal Extras supplied by CddlSchema.format(). */\nexport interface CddlFormatContext {\n source?: string;\n comments?: readonly CddlComment[];\n}\n\ninterface Notes {\n leading: string[];\n trailing: string[];\n}\n\ninterface Ctx {\n /** Indent unit; null = compact layout. */\n unit: string | null;\n notes: Map<object, Notes> | null;\n /** Comments emitted before a group's closing delimiter. */\n endNotes: Map<CddlGroup, string[]> | null;\n /** Comments after the last rule (emitted at the end). */\n tail: string[];\n}\n\nconst EMPTY_NOTES: Notes = { leading: [], trailing: [] };\n\n/** Format rules (in the given order) as CDDL text with a trailing newline. */\nexport function formatCddl(\n rules: readonly CddlRule[],\n options?: CddlFormatOptions & CddlFormatContext\n): string {\n const unit =\n options?.indent === undefined\n ? null\n : typeof options.indent === 'string'\n ? options.indent\n : ' '.repeat(options.indent);\n const ctx: Ctx = { unit, notes: null, endNotes: null, tail: [] };\n if (\n options?.preserveComments &&\n options.comments !== undefined &&\n options.comments.length > 0 &&\n options.source !== undefined\n ) {\n const built = buildNotes(rules, options.comments, options.source);\n ctx.notes = built.notes;\n ctx.endNotes = built.endNotes;\n ctx.tail = built.tail;\n }\n\n const parts: string[] = [];\n let prevMultiline = false;\n rules.forEach((rule, i) => {\n const { text, multiline } = formatRule(rule, ctx);\n // Blank line around rules with multi-line bodies in the pretty layout\n // (leading comments alone do not count).\n if (i > 0 && ctx.unit !== null && (multiline || prevMultiline))\n parts.push('');\n parts.push(text);\n prevMultiline = multiline;\n });\n for (const text of ctx.tail) parts.push(`;${text}`);\n if (parts.length === 0) return '';\n return parts.join('\\n') + '\\n';\n}\n\n// ─── Comment attachment ──────────────────────────────────────────────────────\n\ninterface Anchor {\n node: object;\n start: number;\n end: number;\n isRule: boolean;\n}\n\n/**\n * Associate each comment with the position it will be emitted at, so that\n * `preserveComments` never drops one:\n * - trailing on the rule/entry ending on the comment's line;\n * - else leading on the next rule/entry — but only when that target stays\n * inside every group/rule enclosing the comment;\n * - else, for a comment inside a group with nothing after it (including\n * empty groups), on the group's end position (before the closer);\n * - else, for a comment inside a rule's type expression (e.g. between type\n * choices, which format inline), trailing on the rule;\n * - comments after everything go to `tail`.\n */\nfunction buildNotes(\n rules: readonly CddlRule[],\n comments: readonly CddlComment[],\n source: string\n): {\n notes: Map<object, Notes>;\n endNotes: Map<CddlGroup, string[]>;\n tail: string[];\n} {\n // Line-start offsets for offset→line lookups (comments carry their line).\n const lineStarts = [0];\n for (let i = 0; i < source.length; i++)\n if (source.charCodeAt(i) === 0x0a) lineStarts.push(i + 1);\n const lineOf = (offset: number): number => {\n let lo = 0;\n let hi = lineStarts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (lineStarts[mid]! <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1; // 1-based, matching CddlComment.line\n };\n\n const anchors: Anchor[] = [];\n // Group containment uses the span of the *construct* holding the group\n // (including its delimiters) — an empty group's own span is zero-width.\n const groups: { group: CddlGroup; start: number; end: number }[] = [];\n const addGroup = (group: CddlGroup, start: number, end: number): void => {\n groups.push({ group, start, end });\n for (const choice of group.choices) choice.forEach(addEntry);\n };\n const addEntry = (entry: CddlGroupEntry): void => {\n anchors.push({\n node: entry,\n start: entry.start,\n end: entry.end,\n isRule: false,\n });\n if (entry.kind === 'entry-group') {\n addGroup(entry.group, entry.start, entry.end);\n return;\n }\n for (const t1 of entry.value.alternatives) addType1(t1);\n };\n const addType1 = (t1: CddlType1): void => {\n addType2(t1.target);\n if (t1.controller) addType2(t1.controller);\n };\n const addType2 = (t2: CddlType2): void => {\n switch (t2.kind) {\n case 'map':\n case 'array':\n addGroup(t2.group, t2.start, t2.end);\n return;\n case 'paren':\n for (const t1 of t2.type.alternatives) addType1(t1);\n return;\n case 'enum':\n if (t2.group.kind === 'group') addGroup(t2.group, t2.start, t2.end);\n return;\n case 'tagged':\n if (typeof t2.tag === 'object')\n for (const t1 of t2.tag.alternatives) addType1(t1);\n for (const t1 of t2.item.alternatives) addType1(t1);\n return;\n default:\n return;\n }\n };\n for (const rule of rules) {\n anchors.push({\n node: rule,\n start: rule.start,\n end: rule.end,\n isRule: true,\n });\n addEntry(rule.body);\n }\n\n // Trailing lookup: maximal end ≤ comment start; rules win end-ties so a\n // comment after `a = int` lands on the rule, not on its body entry.\n const byEnd = [...anchors].sort(\n (a, b) => a.end - b.end || Number(a.isRule) - Number(b.isRule)\n );\n // Leading lookup: minimal start ≥ comment end; rules win start-ties.\n const byStart = [...anchors].sort(\n (a, b) => a.start - b.start || Number(b.isRule) - Number(a.isRule)\n );\n\n const notes = new Map<object, Notes>();\n const endNotes = new Map<CddlGroup, string[]>();\n const tail: string[] = [];\n const notesFor = (node: object): Notes => {\n let n = notes.get(node);\n if (!n) {\n n = { leading: [], trailing: [] };\n notes.set(node, n);\n }\n return n;\n };\n\n for (const c of comments) {\n // Trailing: the anchor ending last at or before the comment, same line.\n let trailingTo: Anchor | undefined;\n for (let i = byEnd.length - 1; i >= 0; i--) {\n const a = byEnd[i]!;\n if (a.end > c.start) continue;\n if (lineOf(Math.max(a.start, a.end - 1)) === c.line) trailingTo = a;\n break;\n }\n if (trailingTo) {\n notesFor(trailingTo.node).trailing.push(c.text);\n continue;\n }\n\n // Innermost group / rule whose span encloses the comment.\n let containerGroup:\n { group: CddlGroup; start: number; end: number } | undefined;\n for (const g of groups)\n if (\n g.start <= c.start &&\n c.end <= g.end &&\n (!containerGroup || g.start >= containerGroup.start)\n )\n containerGroup = g;\n const containerRule = rules.find(\n (r) => r.start <= c.start && c.end <= r.end\n );\n\n // Leading on the next rule/entry — only when that target does not\n // escape an enclosing construct (which would move the comment outside).\n const leadingTo = byStart.find((a) => a.start >= c.end);\n const escapesGroup =\n containerGroup !== undefined &&\n (leadingTo === undefined || leadingTo.start > containerGroup.end);\n const escapesRule =\n containerRule !== undefined &&\n (leadingTo === undefined || leadingTo.start > containerRule.end);\n if (leadingTo && !escapesGroup && !escapesRule) {\n notesFor(leadingTo.node).leading.push(c.text);\n } else if (escapesGroup) {\n // Nothing follows inside the group (or it is empty): emit the\n // comment just before the group's closing delimiter.\n const list = endNotes.get(containerGroup!.group) ?? [];\n list.push(c.text);\n endNotes.set(containerGroup!.group, list);\n } else if (escapesRule) {\n // Inside the rule's type expression (choices format inline): keep it\n // on the rule line as a trailing comment.\n notesFor(containerRule!).trailing.push(c.text);\n } else if (leadingTo) {\n notesFor(leadingTo.node).leading.push(c.text);\n } else {\n tail.push(c.text);\n }\n }\n return { notes, endNotes, tail };\n}\n\n// ─── Emission ─────────────────────────────────────────────────────────────────\n\nconst notesOf = (ctx: Ctx, node: object): Notes =>\n ctx.notes?.get(node) ?? EMPTY_NOTES;\n\nconst trailingText = (notes: Notes): string =>\n notes.trailing.length === 0\n ? ''\n : ' ' + notes.trailing.map((t) => `;${t}`).join(' ');\n\nfunction formatRule(\n rule: CddlRule,\n ctx: Ctx\n): { text: string; multiline: boolean } {\n const notes = notesOf(ctx, rule);\n const bodyNotes = notesOf(ctx, rule.body);\n const generics = rule.generics ? `<${rule.generics.join(', ')}>` : '';\n const head = `${rule.name}${generics} ${rule.assign}`;\n const trailing = trailingText({\n leading: [],\n trailing: [...bodyNotes.trailing, ...notes.trailing],\n });\n\n let main: string;\n let leading = notes.leading;\n if (bodyNotes.leading.length > 0 && ctx.unit !== null) {\n // Comments between `=` and the body get their own indented lines:\n // a =\n // ; important\n // int\n const pad = ctx.unit;\n main = [\n head,\n ...bodyNotes.leading.map((t) => `${pad};${t}`),\n `${pad}${formatEntry(rule.body, ctx, 1)}${trailing}`,\n ].join('\\n');\n } else {\n // Compact layout cannot hold a mid-line comment: hoist body-leading\n // comments above the rule so they are never dropped.\n if (bodyNotes.leading.length > 0)\n leading = [...leading, ...bodyNotes.leading];\n main = `${head} ${formatEntry(rule.body, ctx, 0)}${trailing}`;\n }\n\n const multiline = main.includes('\\n');\n if (leading.length === 0) return { text: main, multiline };\n return {\n text: [...leading.map((t) => `;${t}`), main].join('\\n'),\n multiline,\n };\n}\n\nfunction formatEntry(entry: CddlGroupEntry, ctx: Ctx, depth: number): string {\n const occur = entry.occur ? `${formatOccur(entry.occur)} ` : '';\n if (entry.kind === 'entry-group')\n return `${occur}${formatGroupBody(entry.group, ctx, depth, '(', ')')}`;\n const key = entry.memberKey\n ? `${formatMemberKey(entry.memberKey, ctx, depth)} `\n : '';\n return `${occur}${key}${formatType(entry.value, ctx, depth)}`;\n}\n\nfunction formatOccur(occur: CddlOccur): string {\n if (occur.marker !== '*') return occur.marker;\n return `${occur.min ?? ''}*${occur.max ?? ''}`;\n}\n\nfunction formatMemberKey(key: CddlMemberKey, ctx: Ctx, depth: number): string {\n switch (key.kind) {\n case 'bareword':\n return `${key.key}:`;\n case 'value':\n return `${key.key.raw}:`;\n case 'type1':\n return `${formatType1(key.key, ctx, depth)} ${key.cut ? '^ ' : ''}=>`;\n }\n}\n\n/**\n * A group between `open`/`close` delimiters. In the pretty layout, groups\n * with more than one entry (or more than one choice) are laid out one entry\n * per line; group choices are separated by a `//` line.\n */\nfunction formatGroupBody(\n group: CddlGroup,\n ctx: Ctx,\n depth: number,\n open: string,\n close: string\n): string {\n const entryCount = group.choices.reduce((n, c) => n + c.length, 0);\n const endComments = ctx.endNotes?.get(group) ?? [];\n // Any comment inside the group forces the multi-line layout — an inline\n // group cannot hold a `;` comment (it runs to the end of the line).\n const hasNotes =\n endComments.length > 0 ||\n (ctx.notes !== null &&\n group.choices.some((c) => c.some((e) => ctx.notes!.has(e))));\n const multiline =\n ctx.unit !== null &&\n (entryCount > 1 || group.choices.length > 1 || hasNotes);\n\n if (!multiline) {\n const body =\n group.choices\n .map((entries) =>\n entries.map((e) => formatEntry(e, ctx, depth)).join(', ')\n )\n .join(' // ') + (group.trailingComma ? ',' : '');\n return `${open}${body}${close}`;\n }\n\n const unit = ctx.unit!;\n const pad = unit.repeat(depth + 1);\n const lines: string[] = [open];\n group.choices.forEach((entries, ci) => {\n if (ci > 0) lines.push(`${pad}//`);\n entries.forEach((entry, ei) => {\n const notes = notesOf(ctx, entry);\n for (const t of notes.leading) lines.push(`${pad};${t}`);\n const isLast =\n ci === group.choices.length - 1 && ei === entries.length - 1;\n const comma = !isLast || group.trailingComma ? ',' : '';\n lines.push(\n `${pad}${formatEntry(entry, ctx, depth + 1)}${comma}${trailingText(notes)}`\n );\n });\n });\n // Comments with nothing after them inside the group (including comments\n // in empty groups) sit just before the closing delimiter.\n for (const t of endComments) lines.push(`${pad};${t}`);\n lines.push(`${unit.repeat(depth)}${close}`);\n return lines.join('\\n');\n}\n\nfunction formatType(type: CddlType, ctx: Ctx, depth: number): string {\n return type.alternatives.map((t1) => formatType1(t1, ctx, depth)).join(' / ');\n}\n\nfunction formatType1(type1: CddlType1, ctx: Ctx, depth: number): string {\n const target = formatType2(type1.target, ctx, depth);\n if (!type1.op || !type1.controller) return target;\n const controller = formatType2(type1.controller, ctx, depth);\n if (type1.op.kind === 'range')\n return `${target}${type1.op.inclusive ? '..' : '...'}${controller}`;\n return `${target} .${type1.op.name} ${controller}`;\n}\n\nfunction formatRef(ref: CddlRef, ctx: Ctx, depth: number): string {\n const args = ref.genericArgs\n ? `<${ref.genericArgs.map((a) => formatType1(a, ctx, depth)).join(', ')}>`\n : '';\n return `${ref.name}${args}`;\n}\n\nfunction formatType2(type2: CddlType2, ctx: Ctx, depth: number): string {\n switch (type2.kind) {\n case 'value':\n return type2.raw;\n case 'ref':\n return formatRef(type2, ctx, depth);\n case 'paren':\n return `(${formatType(type2.type, ctx, depth)})`;\n case 'map':\n return formatGroupBody(type2.group, ctx, depth, '{', '}');\n case 'array':\n return formatGroupBody(type2.group, ctx, depth, '[', ']');\n case 'unwrap':\n return `~${formatRef(type2.ref, ctx, depth)}`;\n case 'enum':\n return type2.group.kind === 'ref'\n ? `&${formatRef(type2.group, ctx, depth)}`\n : `&${formatGroupBody(type2.group, ctx, depth, '(', ')')}`;\n case 'tagged': {\n const head =\n type2.raw ??\n (typeof type2.tag === 'object'\n ? `#6.<${formatType(type2.tag, ctx, depth)}>`\n : `#6${type2.tag === undefined ? '' : `.${type2.tag}`}`);\n return `${head}(${formatType(type2.item, ctx, depth)})`;\n }\n case 'major': {\n if (type2.raw !== undefined) return type2.raw;\n return typeof type2.ai === 'object'\n ? `#${type2.major}.<${formatType(type2.ai, ctx, depth)}>`\n : `#${type2.major}${type2.ai === undefined ? '' : `.${type2.ai}`}`;\n }\n case 'any':\n return '#';\n }\n}\n","/**\n * CDDL compilation: rule table construction and static checks.\n *\n * `compile()` parses CDDL text and performs the semantic checks that do not\n * require a data item: duplicate rule detection, name resolution against the\n * user rules and the standard prelude, and generic arity checks. Validation\n * of CBOR data against a schema is a later phase.\n */\n\nimport { parseCDDL } from './parser';\nimport { getPreludeRules } from './prelude';\nimport { formatCddl, type CddlFormatOptions } from './writer';\nimport type { CddlComment } from './tokenizer';\nimport { validateItem, type ValidateOptions } from './validator';\nimport { CborItem } from '../ast/CborItem';\nimport { decodeCBOR } from '../cbor/decoder';\nimport { parseCDN } from '../cdn/parser';\nimport {\n CddlSemanticError,\n type CddlWarning,\n type ValidationResult,\n} from './errors';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\n\nexport interface CompileOptions {\n /**\n * When true (the default), semantic problems (undefined names, duplicate\n * rules, generic arity mismatches) throw a {@link CddlSemanticError}.\n * When false, they are collected into {@link CddlSchema.warnings}.\n */\n strict?: boolean;\n}\n\n/**\n * A compiled CDDL data model.\n *\n * `rules` maps each rule name to its definitions in source order: the base\n * definition plus any `/=` / `//=` choice extensions. User rules shadow\n * prelude names; the prelude itself is available via `getPreludeRules()`.\n */\nexport class CddlSchema {\n /**\n * The CDDL source text this schema was compiled from. AST node offsets\n * (and validation errors' `schemaStart`/`schemaEnd`) index into it, so\n * tooling can render positions without carrying the text separately.\n */\n readonly source: string;\n /** `;` comments collected while parsing, in source order. */\n readonly comments: readonly CddlComment[];\n /** All rules in source order, as parsed (extensions unmerged). */\n readonly ast: readonly CddlRule[];\n /** Rule definitions by name (base definition first, then extensions). */\n readonly rules: ReadonlyMap<string, readonly CddlRule[]>;\n /**\n * The root of the data model: the first rule in the source (RFC 8610 §3.1).\n * Unset only for an empty model compiled with `strict: false`.\n */\n readonly root?: CddlRule;\n /** Semantic problems collected with `strict: false`; unset when clean. */\n readonly warnings?: CddlWarning[];\n\n /** @internal — use `CDDL.compile()`. */\n constructor(\n source: string,\n comments: readonly CddlComment[],\n ast: CddlRule[],\n rules: Map<string, CddlRule[]>,\n root: CddlRule | undefined,\n warnings: CddlWarning[]\n ) {\n this.source = source;\n this.comments = comments;\n this.ast = ast;\n this.rules = rules;\n if (root) this.root = root;\n if (warnings.length > 0) this.warnings = warnings;\n }\n\n /**\n * Serialize the data model back to CDDL text.\n *\n * Compact one-rule-per-line output by default; pass `indent` for a\n * pretty layout (one group entry per line) and `preserveComments` to\n * re-emit `;` comments.\n *\n * @example\n * CDDL.compile(text).format({ indent: 2, preserveComments: true });\n */\n format(options?: CddlFormatOptions): string {\n return formatCddl(this.ast, {\n ...options,\n source: this.source,\n comments: this.comments,\n });\n }\n\n /**\n * Validate a data item against this schema's root rule — the first rule\n * in source order (RFC 8610 §3.1). Pass `{ rule: 'otherName' }` to\n * validate against a different rule instead: any non-generic rule usable\n * as a type, defined in the schema or its prelude (e.g. `'uint'`).\n * Generic rules (`g<T> = ...`) and group-only rules are reported as\n * validation failures, as is an unknown name (see\n * {@link ValidateOptions.rule}).\n *\n * Accepts a CborItem, CBOR bytes (decoded with `decodeCBOR`), or CDN text\n * (parsed with `parseCDN`). Validation failures are reported in the\n * result, not thrown; decode/parse failures of the input throw as usual.\n *\n * @example\n * const schema = CDDL.compile('person = { name: tstr, ? age: uint }');\n * const result = schema.validate('{\"name\": \"kudo\", \"age\": 42}');\n * result.valid; // true\n *\n * @example\n * // Validate against a rule other than the root.\n * const schema = CDDL.compile(`\n * p1 = { name: tstr, ? addr: tstr }\n * p2 = { name: tstr, ? age: uint }\n * `);\n * schema.validate('{\"name\": \"kudo\", \"age\": 42}', { rule: 'p2' }).valid; // true\n */\n validate(\n input: CborItem | Uint8Array | string,\n options?: ValidateOptions\n ): ValidationResult {\n const item =\n input instanceof CborItem\n ? input\n : typeof input === 'string'\n ? parseCDN(input)\n : decodeCBOR(input);\n return validateItem(this, item, options);\n }\n}\n\n/**\n * Parse and compile CDDL text.\n *\n * Throws `CddlSyntaxError` on grammar errors. Semantic problems throw a\n * {@link CddlSemanticError} by default; pass `strict: false` to collect them\n * into `schema.warnings` instead.\n */\nexport function compile(text: string, options?: CompileOptions): CddlSchema {\n const { rules, comments } = parseCDDL(text);\n const warnings: CddlWarning[] = [];\n const prelude = getPreludeRules();\n\n if (rules.length === 0)\n warnings.push({\n code: 'no-rules',\n message:\n 'a CDDL data model needs at least one rule to provide the root of the definition',\n });\n\n // Rule table: base definition plus /= and //= extensions, in source order.\n const table = new Map<string, CddlRule[]>();\n for (const rule of rules) {\n const existing = table.get(rule.name);\n if (!existing) {\n table.set(rule.name, [rule]);\n continue;\n }\n if (rule.assign === '=')\n warnings.push({\n code: 'duplicate-rule',\n message: `rule '${rule.name}' is already defined; use /= or //= to extend it`,\n start: rule.start,\n end: rule.end,\n });\n existing.push(rule);\n }\n\n // Name resolution and generic arity, per rule (generic parameters are in\n // scope only within their own rule definition's body).\n const declaredArity = (name: string): number | undefined => {\n const defs = table.get(name);\n if (defs) return defs[0]!.generics?.length ?? 0;\n const preludeRule = prelude.get(name);\n if (preludeRule) return preludeRule.generics?.length ?? 0;\n return undefined;\n };\n\n for (const rule of rules) {\n const generics = rule.generics;\n walkEntry(rule.body, {\n onRef(ref: CddlRef): void {\n if (generics?.includes(ref.name)) return;\n // Type and group sockets ($name / $$name) may be referenced and\n // extended without ever being defined.\n if (ref.name.startsWith('$')) return;\n const arity = declaredArity(ref.name);\n if (arity === undefined) {\n warnings.push({\n code: 'undefined-name',\n message: `'${ref.name}' is not defined (and is not a prelude name)`,\n start: ref.start,\n end: ref.end,\n });\n return;\n }\n const given = ref.genericArgs?.length ?? 0;\n if (arity !== given)\n warnings.push({\n code: 'generic-arity',\n message: `'${ref.name}' takes ${arity} generic argument${arity === 1 ? '' : 's'} but is used with ${given}`,\n start: ref.start,\n end: ref.end,\n });\n },\n onMajor(major: number, start: number, end: number): void {\n if (major > 7)\n warnings.push({\n code: 'invalid-major',\n message: `#${major} is not a CBOR major type (0–7)`,\n start,\n end,\n });\n },\n });\n }\n\n // The first rule is the root of the data model, and \"there is no way to\n // use a group as a root -- it must be a type\" (RFC 8610 §2.2.4).\n const root = rules[0];\n if (root && !isTypeBody(root.body))\n warnings.push({\n code: 'invalid-root',\n message: `the first rule '${root.name}' is the root of the data model and must define a type, not a group (RFC 8610 §2.2.4)`,\n start: root.start,\n end: root.end,\n });\n\n if ((options?.strict ?? true) && warnings.length > 0)\n throw new CddlSemanticError(warnings);\n\n // An empty model has no root; `no-rules` was already reported above.\n return new CddlSchema(text, comments, rules, table, root, warnings);\n}\n\n/**\n * Whether a rule body is usable as a type: a plain entry (no occurrence, no\n * member key), or a parenthesized group that reduces to one such entry.\n * A trailing comma makes a parenthesized expression a group — `(int,)` is\n * never a parenthesized type.\n */\nfunction isTypeBody(entry: CddlGroupEntry): boolean {\n if (entry.kind === 'entry') return !entry.occur && !entry.memberKey;\n if (entry.occur || entry.group.trailingComma) return false;\n const { choices } = entry.group;\n return (\n choices.length === 1 &&\n choices[0]!.length === 1 &&\n isTypeBody(choices[0]![0]!)\n );\n}\n\n// ─── AST walk ─────────────────────────────────────────────────────────────────\n\ninterface WalkHooks {\n onRef(ref: CddlRef): void;\n onMajor(major: number, start: number, end: number): void;\n}\n\nfunction walkEntry(entry: CddlGroupEntry, hooks: WalkHooks): void {\n if (entry.kind === 'entry-group') {\n walkGroup(entry.group, hooks);\n return;\n }\n if (entry.memberKey?.kind === 'type1') walkType1(entry.memberKey.key, hooks);\n walkType(entry.value, hooks);\n}\n\nfunction walkGroup(group: CddlGroup, hooks: WalkHooks): void {\n for (const choice of group.choices)\n for (const entry of choice) walkEntry(entry, hooks);\n}\n\nfunction walkType(type: CddlType, hooks: WalkHooks): void {\n for (const alt of type.alternatives) walkType1(alt, hooks);\n}\n\nfunction walkType1(type1: CddlType1, hooks: WalkHooks): void {\n walkType2(type1.target, hooks);\n if (type1.controller) walkType2(type1.controller, hooks);\n}\n\nfunction walkType2(type2: CddlType2, hooks: WalkHooks): void {\n switch (type2.kind) {\n case 'value':\n case 'any':\n return;\n case 'ref':\n hooks.onRef(type2);\n for (const arg of type2.genericArgs ?? []) walkType1(arg, hooks);\n return;\n case 'paren':\n walkType(type2.type, hooks);\n return;\n case 'map':\n case 'array':\n walkGroup(type2.group, hooks);\n return;\n case 'unwrap':\n hooks.onRef(type2.ref);\n for (const arg of type2.ref.genericArgs ?? []) walkType1(arg, hooks);\n return;\n case 'enum':\n if (type2.group.kind === 'ref') {\n hooks.onRef(type2.group);\n for (const arg of type2.group.genericArgs ?? []) walkType1(arg, hooks);\n } else walkGroup(type2.group, hooks);\n return;\n case 'tagged':\n if (typeof type2.tag === 'object') walkType(type2.tag, hooks);\n walkType(type2.item, hooks);\n return;\n case 'major':\n hooks.onMajor(type2.major, type2.start, type2.end);\n if (typeof type2.ai === 'object') walkType(type2.ai, hooks);\n return;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const e=require("./mapEntries-DwHPAzCN.cjs");var t={leading:[],trailing:[]};function n(e,t){let n={unit:t?.indent===void 0?null:typeof t.indent==`string`?t.indent:` `.repeat(t.indent),notes:null,endNotes:null,tail:[]};if(t?.preserveComments&&t.comments!==void 0&&t.comments.length>0&&t.source!==void 0){let i=r(e,t.comments,t.source);n.notes=i.notes,n.endNotes=i.endNotes,n.tail=i.tail}let i=[],a=!1;e.forEach((e,t)=>{let{text:r,multiline:s}=o(e,n);t>0&&n.unit!==null&&(s||a)&&i.push(``),i.push(r),a=s});for(let e of n.tail)i.push(`;${e}`);return i.length===0?``:i.join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`}function r(e,t,n){let r=[0];for(let e=0;e<n.length;e++)n.charCodeAt(e)===10&&r.push(e+1);let i=e=>{let t=0,n=r.length-1;for(;t<n;){let i=t+n+1>>1;r[i]<=e?t=i:n=i-1}return t+1},a=[],o=[],s=(e,t,n)=>{o.push({group:e,start:t,end:n});for(let t of e.choices)t.forEach(c)},c=e=>{if(a.push({node:e,start:e.start,end:e.end,isRule:!1}),e.kind===`entry-group`){s(e.group,e.start,e.end);return}for(let t of e.value.alternatives)l(t)},l=e=>{u(e.target),e.controller&&u(e.controller)},u=e=>{switch(e.kind){case`map`:case`array`:s(e.group,e.start,e.end);return;case`paren`:for(let t of e.type.alternatives)l(t);return;case`enum`:e.group.kind===`group`&&s(e.group,e.start,e.end);return;case`tagged`:if(typeof e.tag==`object`)for(let t of e.tag.alternatives)l(t);for(let t of e.item.alternatives)l(t);return;default:return}};for(let t of e)a.push({node:t,start:t.start,end:t.end,isRule:!0}),c(t.body);let d=[...a].sort((e,t)=>e.end-t.end||Number(e.isRule)-Number(t.isRule)),f=[...a].sort((e,t)=>e.start-t.start||Number(t.isRule)-Number(e.isRule)),p=new Map,m=new Map,h=[],g=e=>{let t=p.get(e);return t||(t={leading:[],trailing:[]},p.set(e,t)),t};for(let n of t){let t;for(let e=d.length-1;e>=0;e--){let r=d[e];if(!(r.end>n.start)){i(Math.max(r.start,r.end-1))===n.line&&(t=r);break}}if(t){g(t.node).trailing.push(n.text);continue}let r;for(let e of o)e.start<=n.start&&n.end<=e.end&&(!r||e.start>=r.start)&&(r=e);let a=e.find(e=>e.start<=n.start&&n.end<=e.end),s=f.find(e=>e.start>=n.end),c=r!==void 0&&(s===void 0||s.start>r.end),l=a!==void 0&&(s===void 0||s.start>a.end);if(s&&!c&&!l)g(s.node).leading.push(n.text);else if(c){let e=m.get(r.group)??[];e.push(n.text),m.set(r.group,e)}else l?g(a).trailing.push(n.text):s?g(s.node).leading.push(n.text):h.push(n.text)}return{notes:p,endNotes:m,tail:h}}var i=(e,n)=>e.notes?.get(n)??t,a=e=>e.trailing.length===0?``:` `+e.trailing.map(e=>`;${e}`).join(` `);function o(e,t){let n=i(t,e),r=i(t,e.body),o=e.generics?`<${e.generics.join(`, `)}>`:``,c=`${e.name}${o} ${e.assign}`,l=a({leading:[],trailing:[...r.trailing,...n.trailing]}),u,d=n.leading;if(r.leading.length>0&&t.unit!==null){let n=t.unit;u=[c,...r.leading.map(e=>`${n};${e}`),`${n}${s(e.body,t,1)}${l}`].join(`
|
|
4
|
+
`)}else r.leading.length>0&&(d=[...d,...r.leading]),u=`${c} ${s(e.body,t,0)}${l}`;let f=u.includes(`
|
|
5
|
+
`);return d.length===0?{text:u,multiline:f}:{text:[...d.map(e=>`;${e}`),u].join(`
|
|
6
|
+
`),multiline:f}}function s(e,t,n){let r=e.occur?`${c(e.occur)} `:``;return e.kind===`entry-group`?`${r}${u(e.group,t,n,`(`,`)`)}`:`${r}${e.memberKey?`${l(e.memberKey,t,n)} `:``}${d(e.value,t,n)}`}function c(e){return e.marker===`*`?`${e.min??``}*${e.max??``}`:e.marker}function l(e,t,n){switch(e.kind){case`bareword`:return`${e.key}:`;case`value`:return`${e.key.raw}:`;case`type1`:return`${f(e.key,t,n)} ${e.cut?`^ `:``}=>`}}function u(e,t,n,r,o){let c=e.choices.reduce((e,t)=>e+t.length,0),l=t.endNotes?.get(e)??[],u=l.length>0||t.notes!==null&&e.choices.some(e=>e.some(e=>t.notes.has(e)));if(!(t.unit!==null&&(c>1||e.choices.length>1||u)))return`${r}${e.choices.map(e=>e.map(e=>s(e,t,n)).join(`, `)).join(` // `)+(e.trailingComma?`,`:``)}${o}`;let d=t.unit,f=d.repeat(n+1),p=[r];e.choices.forEach((r,o)=>{o>0&&p.push(`${f}//`),r.forEach((c,l)=>{let u=i(t,c);for(let e of u.leading)p.push(`${f};${e}`);let d=o!==e.choices.length-1||l!==r.length-1||e.trailingComma?`,`:``;p.push(`${f}${s(c,t,n+1)}${d}${a(u)}`)})});for(let e of l)p.push(`${f};${e}`);return p.push(`${d.repeat(n)}${o}`),p.join(`
|
|
7
|
+
`)}function d(e,t,n){return e.alternatives.map(e=>f(e,t,n)).join(` / `)}function f(e,t,n){let r=m(e.target,t,n);if(!e.op||!e.controller)return r;let i=m(e.controller,t,n);return e.op.kind===`range`?`${r}${e.op.inclusive?`..`:`...`}${i}`:`${r} .${e.op.name} ${i}`}function p(e,t,n){let r=e.genericArgs?`<${e.genericArgs.map(e=>f(e,t,n)).join(`, `)}>`:``;return`${e.name}${r}`}function m(e,t,n){switch(e.kind){case`value`:return e.raw;case`ref`:return p(e,t,n);case`paren`:return`(${d(e.type,t,n)})`;case`map`:return u(e.group,t,n,`{`,`}`);case`array`:return u(e.group,t,n,`[`,`]`);case`unwrap`:return`~${p(e.ref,t,n)}`;case`enum`:return e.group.kind===`ref`?`&${p(e.group,t,n)}`:`&${u(e.group,t,n,`(`,`)`)}`;case`tagged`:return`${e.raw??(typeof e.tag==`object`?`#6.<${d(e.tag,t,n)}>`:`#6${e.tag===void 0?``:`.${e.tag}`}`)}(${d(e.item,t,n)})`;case`major`:return e.raw===void 0?typeof e.ai==`object`?`#${e.major}.<${d(e.ai,t,n)}>`:`#${e.major}${e.ai===void 0?``:`.${e.ai}`}`:e.raw;case`any`:return`#`}}var h=class{source;comments;ast;rules;root;warnings;constructor(e,t,n,r,i,a){this.source=e,this.comments=t,this.ast=n,this.rules=r,i&&(this.root=i),a.length>0&&(this.warnings=a)}format(e){return n(this.ast,{...e,source:this.source,comments:this.comments})}validate(t,n){let r=t instanceof e.W?t:typeof t==`string`?e.D(t):e.x(t);return e.l(this,r,n)}};function g(t,n){let{rules:r,comments:i}=e.f(t),a=[],o=e.d();r.length===0&&a.push({code:`no-rules`,message:`a CDDL data model needs at least one rule to provide the root of the definition`});let s=new Map;for(let e of r){let t=s.get(e.name);if(!t){s.set(e.name,[e]);continue}e.assign===`=`&&a.push({code:`duplicate-rule`,message:`rule '${e.name}' is already defined; use /= or //= to extend it`,start:e.start,end:e.end}),t.push(e)}let c=e=>{let t=s.get(e);if(t)return t[0].generics?.length??0;let n=o.get(e);if(n)return n.generics?.length??0};for(let e of r){let t=e.generics;v(e.body,{onRef(e){if(t?.includes(e.name)||e.name.startsWith(`$`))return;let n=c(e.name);if(n===void 0){a.push({code:`undefined-name`,message:`'${e.name}' is not defined (and is not a prelude name)`,start:e.start,end:e.end});return}let r=e.genericArgs?.length??0;n!==r&&a.push({code:`generic-arity`,message:`'${e.name}' takes ${n} generic argument${n===1?``:`s`} but is used with ${r}`,start:e.start,end:e.end})},onMajor(e,t,n){e>7&&a.push({code:`invalid-major`,message:`#${e} is not a CBOR major type (0–7)`,start:t,end:n})}})}let l=r[0];if(l&&!_(l.body)&&a.push({code:`invalid-root`,message:`the first rule '${l.name}' is the root of the data model and must define a type, not a group (RFC 8610 §2.2.4)`,start:l.start,end:l.end}),(n?.strict??!0)&&a.length>0)throw new e.Q(a);return new h(t,i,r,s,l,a)}function _(e){if(e.kind===`entry`)return!e.occur&&!e.memberKey;if(e.occur||e.group.trailingComma)return!1;let{choices:t}=e.group;return t.length===1&&t[0].length===1&&_(t[0][0])}function v(e,t){if(e.kind===`entry-group`){y(e.group,t);return}e.memberKey?.kind===`type1`&&x(e.memberKey.key,t),b(e.value,t)}function y(e,t){for(let n of e.choices)for(let e of n)v(e,t)}function b(e,t){for(let n of e.alternatives)x(n,t)}function x(e,t){S(e.target,t),e.controller&&S(e.controller,t)}function S(e,t){switch(e.kind){case`value`:case`any`:return;case`ref`:t.onRef(e);for(let n of e.genericArgs??[])x(n,t);return;case`paren`:b(e.type,t);return;case`map`:case`array`:y(e.group,t);return;case`unwrap`:t.onRef(e.ref);for(let n of e.ref.genericArgs??[])x(n,t);return;case`enum`:if(e.group.kind===`ref`){t.onRef(e.group);for(let n of e.group.genericArgs??[])x(n,t)}else y(e.group,t);return;case`tagged`:typeof e.tag==`object`&&b(e.tag,t),b(e.item,t);return;case`major`:t.onMajor(e.major,e.start,e.end),typeof e.ai==`object`&&b(e.ai,t);return}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return h}});
|
|
8
|
+
//# sourceMappingURL=schema-YiigSWjR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-YiigSWjR.cjs","names":[],"sources":["../src/cddl/writer.ts","../src/cddl/schema.ts"],"sourcesContent":["/**\n * CDDL formatter: serialize rule ASTs back to CDDL text.\n *\n * Two layouts:\n * - Compact (default): one rule per line with single-space separators.\n * - Pretty (`indent` set): groups with more than one entry (or group\n * choices) put each entry on its own indented line; multi-line rules are\n * separated by blank lines.\n *\n * Literal values are emitted verbatim from their source text (`raw`), so\n * number bases, string escapes, and byte-string qualifiers survive a round\n * trip. With `preserveComments`, `;` comments are re-attached by position\n * and none is dropped: rule leading/trailing, before a rule body (after\n * `=`), on group entries, before a group's closing delimiter, and — for\n * comments inside inline-only positions such as type choices — on the\n * enclosing rule's line end. The compact layout cannot hold an interior\n * line comment (`;` runs to the end of the line), so it hoists body\n * comments above the rule and keeps only rule-level placements.\n */\n\nimport type { CddlComment } from './tokenizer';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlMemberKey,\n CddlOccur,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\n\nexport interface CddlFormatOptions {\n /**\n * Pretty-print groups with one entry per line, indented by this many\n * spaces (or by the given string). Omit for compact single-line rules.\n */\n indent?: number | string;\n /**\n * Re-emit `;` comments. Rule-level comments are kept in both layouts;\n * comments attached to group entries require `indent` (the pretty\n * layout). Only effective when the formatter has the comment stream and\n * source text — i.e. when called through `CddlSchema.format()`.\n */\n preserveComments?: boolean;\n}\n\n/** @internal Extras supplied by CddlSchema.format(). */\nexport interface CddlFormatContext {\n source?: string;\n comments?: readonly CddlComment[];\n}\n\ninterface Notes {\n leading: string[];\n trailing: string[];\n}\n\ninterface Ctx {\n /** Indent unit; null = compact layout. */\n unit: string | null;\n notes: Map<object, Notes> | null;\n /** Comments emitted before a group's closing delimiter. */\n endNotes: Map<CddlGroup, string[]> | null;\n /** Comments after the last rule (emitted at the end). */\n tail: string[];\n}\n\nconst EMPTY_NOTES: Notes = { leading: [], trailing: [] };\n\n/** Format rules (in the given order) as CDDL text with a trailing newline. */\nexport function formatCddl(\n rules: readonly CddlRule[],\n options?: CddlFormatOptions & CddlFormatContext\n): string {\n const unit =\n options?.indent === undefined\n ? null\n : typeof options.indent === 'string'\n ? options.indent\n : ' '.repeat(options.indent);\n const ctx: Ctx = { unit, notes: null, endNotes: null, tail: [] };\n if (\n options?.preserveComments &&\n options.comments !== undefined &&\n options.comments.length > 0 &&\n options.source !== undefined\n ) {\n const built = buildNotes(rules, options.comments, options.source);\n ctx.notes = built.notes;\n ctx.endNotes = built.endNotes;\n ctx.tail = built.tail;\n }\n\n const parts: string[] = [];\n let prevMultiline = false;\n rules.forEach((rule, i) => {\n const { text, multiline } = formatRule(rule, ctx);\n // Blank line around rules with multi-line bodies in the pretty layout\n // (leading comments alone do not count).\n if (i > 0 && ctx.unit !== null && (multiline || prevMultiline))\n parts.push('');\n parts.push(text);\n prevMultiline = multiline;\n });\n for (const text of ctx.tail) parts.push(`;${text}`);\n if (parts.length === 0) return '';\n return parts.join('\\n') + '\\n';\n}\n\n// ─── Comment attachment ──────────────────────────────────────────────────────\n\ninterface Anchor {\n node: object;\n start: number;\n end: number;\n isRule: boolean;\n}\n\n/**\n * Associate each comment with the position it will be emitted at, so that\n * `preserveComments` never drops one:\n * - trailing on the rule/entry ending on the comment's line;\n * - else leading on the next rule/entry — but only when that target stays\n * inside every group/rule enclosing the comment;\n * - else, for a comment inside a group with nothing after it (including\n * empty groups), on the group's end position (before the closer);\n * - else, for a comment inside a rule's type expression (e.g. between type\n * choices, which format inline), trailing on the rule;\n * - comments after everything go to `tail`.\n */\nfunction buildNotes(\n rules: readonly CddlRule[],\n comments: readonly CddlComment[],\n source: string\n): {\n notes: Map<object, Notes>;\n endNotes: Map<CddlGroup, string[]>;\n tail: string[];\n} {\n // Line-start offsets for offset→line lookups (comments carry their line).\n const lineStarts = [0];\n for (let i = 0; i < source.length; i++)\n if (source.charCodeAt(i) === 0x0a) lineStarts.push(i + 1);\n const lineOf = (offset: number): number => {\n let lo = 0;\n let hi = lineStarts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (lineStarts[mid]! <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1; // 1-based, matching CddlComment.line\n };\n\n const anchors: Anchor[] = [];\n // Group containment uses the span of the *construct* holding the group\n // (including its delimiters) — an empty group's own span is zero-width.\n const groups: { group: CddlGroup; start: number; end: number }[] = [];\n const addGroup = (group: CddlGroup, start: number, end: number): void => {\n groups.push({ group, start, end });\n for (const choice of group.choices) choice.forEach(addEntry);\n };\n const addEntry = (entry: CddlGroupEntry): void => {\n anchors.push({\n node: entry,\n start: entry.start,\n end: entry.end,\n isRule: false,\n });\n if (entry.kind === 'entry-group') {\n addGroup(entry.group, entry.start, entry.end);\n return;\n }\n for (const t1 of entry.value.alternatives) addType1(t1);\n };\n const addType1 = (t1: CddlType1): void => {\n addType2(t1.target);\n if (t1.controller) addType2(t1.controller);\n };\n const addType2 = (t2: CddlType2): void => {\n switch (t2.kind) {\n case 'map':\n case 'array':\n addGroup(t2.group, t2.start, t2.end);\n return;\n case 'paren':\n for (const t1 of t2.type.alternatives) addType1(t1);\n return;\n case 'enum':\n if (t2.group.kind === 'group') addGroup(t2.group, t2.start, t2.end);\n return;\n case 'tagged':\n if (typeof t2.tag === 'object')\n for (const t1 of t2.tag.alternatives) addType1(t1);\n for (const t1 of t2.item.alternatives) addType1(t1);\n return;\n default:\n return;\n }\n };\n for (const rule of rules) {\n anchors.push({\n node: rule,\n start: rule.start,\n end: rule.end,\n isRule: true,\n });\n addEntry(rule.body);\n }\n\n // Trailing lookup: maximal end ≤ comment start; rules win end-ties so a\n // comment after `a = int` lands on the rule, not on its body entry.\n const byEnd = [...anchors].sort(\n (a, b) => a.end - b.end || Number(a.isRule) - Number(b.isRule)\n );\n // Leading lookup: minimal start ≥ comment end; rules win start-ties.\n const byStart = [...anchors].sort(\n (a, b) => a.start - b.start || Number(b.isRule) - Number(a.isRule)\n );\n\n const notes = new Map<object, Notes>();\n const endNotes = new Map<CddlGroup, string[]>();\n const tail: string[] = [];\n const notesFor = (node: object): Notes => {\n let n = notes.get(node);\n if (!n) {\n n = { leading: [], trailing: [] };\n notes.set(node, n);\n }\n return n;\n };\n\n for (const c of comments) {\n // Trailing: the anchor ending last at or before the comment, same line.\n let trailingTo: Anchor | undefined;\n for (let i = byEnd.length - 1; i >= 0; i--) {\n const a = byEnd[i]!;\n if (a.end > c.start) continue;\n if (lineOf(Math.max(a.start, a.end - 1)) === c.line) trailingTo = a;\n break;\n }\n if (trailingTo) {\n notesFor(trailingTo.node).trailing.push(c.text);\n continue;\n }\n\n // Innermost group / rule whose span encloses the comment.\n let containerGroup:\n { group: CddlGroup; start: number; end: number } | undefined;\n for (const g of groups)\n if (\n g.start <= c.start &&\n c.end <= g.end &&\n (!containerGroup || g.start >= containerGroup.start)\n )\n containerGroup = g;\n const containerRule = rules.find(\n (r) => r.start <= c.start && c.end <= r.end\n );\n\n // Leading on the next rule/entry — only when that target does not\n // escape an enclosing construct (which would move the comment outside).\n const leadingTo = byStart.find((a) => a.start >= c.end);\n const escapesGroup =\n containerGroup !== undefined &&\n (leadingTo === undefined || leadingTo.start > containerGroup.end);\n const escapesRule =\n containerRule !== undefined &&\n (leadingTo === undefined || leadingTo.start > containerRule.end);\n if (leadingTo && !escapesGroup && !escapesRule) {\n notesFor(leadingTo.node).leading.push(c.text);\n } else if (escapesGroup) {\n // Nothing follows inside the group (or it is empty): emit the\n // comment just before the group's closing delimiter.\n const list = endNotes.get(containerGroup!.group) ?? [];\n list.push(c.text);\n endNotes.set(containerGroup!.group, list);\n } else if (escapesRule) {\n // Inside the rule's type expression (choices format inline): keep it\n // on the rule line as a trailing comment.\n notesFor(containerRule!).trailing.push(c.text);\n } else if (leadingTo) {\n notesFor(leadingTo.node).leading.push(c.text);\n } else {\n tail.push(c.text);\n }\n }\n return { notes, endNotes, tail };\n}\n\n// ─── Emission ─────────────────────────────────────────────────────────────────\n\nconst notesOf = (ctx: Ctx, node: object): Notes =>\n ctx.notes?.get(node) ?? EMPTY_NOTES;\n\nconst trailingText = (notes: Notes): string =>\n notes.trailing.length === 0\n ? ''\n : ' ' + notes.trailing.map((t) => `;${t}`).join(' ');\n\nfunction formatRule(\n rule: CddlRule,\n ctx: Ctx\n): { text: string; multiline: boolean } {\n const notes = notesOf(ctx, rule);\n const bodyNotes = notesOf(ctx, rule.body);\n const generics = rule.generics ? `<${rule.generics.join(', ')}>` : '';\n const head = `${rule.name}${generics} ${rule.assign}`;\n const trailing = trailingText({\n leading: [],\n trailing: [...bodyNotes.trailing, ...notes.trailing],\n });\n\n let main: string;\n let leading = notes.leading;\n if (bodyNotes.leading.length > 0 && ctx.unit !== null) {\n // Comments between `=` and the body get their own indented lines:\n // a =\n // ; important\n // int\n const pad = ctx.unit;\n main = [\n head,\n ...bodyNotes.leading.map((t) => `${pad};${t}`),\n `${pad}${formatEntry(rule.body, ctx, 1)}${trailing}`,\n ].join('\\n');\n } else {\n // Compact layout cannot hold a mid-line comment: hoist body-leading\n // comments above the rule so they are never dropped.\n if (bodyNotes.leading.length > 0)\n leading = [...leading, ...bodyNotes.leading];\n main = `${head} ${formatEntry(rule.body, ctx, 0)}${trailing}`;\n }\n\n const multiline = main.includes('\\n');\n if (leading.length === 0) return { text: main, multiline };\n return {\n text: [...leading.map((t) => `;${t}`), main].join('\\n'),\n multiline,\n };\n}\n\nfunction formatEntry(entry: CddlGroupEntry, ctx: Ctx, depth: number): string {\n const occur = entry.occur ? `${formatOccur(entry.occur)} ` : '';\n if (entry.kind === 'entry-group')\n return `${occur}${formatGroupBody(entry.group, ctx, depth, '(', ')')}`;\n const key = entry.memberKey\n ? `${formatMemberKey(entry.memberKey, ctx, depth)} `\n : '';\n return `${occur}${key}${formatType(entry.value, ctx, depth)}`;\n}\n\nfunction formatOccur(occur: CddlOccur): string {\n if (occur.marker !== '*') return occur.marker;\n return `${occur.min ?? ''}*${occur.max ?? ''}`;\n}\n\nfunction formatMemberKey(key: CddlMemberKey, ctx: Ctx, depth: number): string {\n switch (key.kind) {\n case 'bareword':\n return `${key.key}:`;\n case 'value':\n return `${key.key.raw}:`;\n case 'type1':\n return `${formatType1(key.key, ctx, depth)} ${key.cut ? '^ ' : ''}=>`;\n }\n}\n\n/**\n * A group between `open`/`close` delimiters. In the pretty layout, groups\n * with more than one entry (or more than one choice) are laid out one entry\n * per line; group choices are separated by a `//` line.\n */\nfunction formatGroupBody(\n group: CddlGroup,\n ctx: Ctx,\n depth: number,\n open: string,\n close: string\n): string {\n const entryCount = group.choices.reduce((n, c) => n + c.length, 0);\n const endComments = ctx.endNotes?.get(group) ?? [];\n // Any comment inside the group forces the multi-line layout — an inline\n // group cannot hold a `;` comment (it runs to the end of the line).\n const hasNotes =\n endComments.length > 0 ||\n (ctx.notes !== null &&\n group.choices.some((c) => c.some((e) => ctx.notes!.has(e))));\n const multiline =\n ctx.unit !== null &&\n (entryCount > 1 || group.choices.length > 1 || hasNotes);\n\n if (!multiline) {\n const body =\n group.choices\n .map((entries) =>\n entries.map((e) => formatEntry(e, ctx, depth)).join(', ')\n )\n .join(' // ') + (group.trailingComma ? ',' : '');\n return `${open}${body}${close}`;\n }\n\n const unit = ctx.unit!;\n const pad = unit.repeat(depth + 1);\n const lines: string[] = [open];\n group.choices.forEach((entries, ci) => {\n if (ci > 0) lines.push(`${pad}//`);\n entries.forEach((entry, ei) => {\n const notes = notesOf(ctx, entry);\n for (const t of notes.leading) lines.push(`${pad};${t}`);\n const isLast =\n ci === group.choices.length - 1 && ei === entries.length - 1;\n const comma = !isLast || group.trailingComma ? ',' : '';\n lines.push(\n `${pad}${formatEntry(entry, ctx, depth + 1)}${comma}${trailingText(notes)}`\n );\n });\n });\n // Comments with nothing after them inside the group (including comments\n // in empty groups) sit just before the closing delimiter.\n for (const t of endComments) lines.push(`${pad};${t}`);\n lines.push(`${unit.repeat(depth)}${close}`);\n return lines.join('\\n');\n}\n\nfunction formatType(type: CddlType, ctx: Ctx, depth: number): string {\n return type.alternatives.map((t1) => formatType1(t1, ctx, depth)).join(' / ');\n}\n\nfunction formatType1(type1: CddlType1, ctx: Ctx, depth: number): string {\n const target = formatType2(type1.target, ctx, depth);\n if (!type1.op || !type1.controller) return target;\n const controller = formatType2(type1.controller, ctx, depth);\n if (type1.op.kind === 'range')\n return `${target}${type1.op.inclusive ? '..' : '...'}${controller}`;\n return `${target} .${type1.op.name} ${controller}`;\n}\n\nfunction formatRef(ref: CddlRef, ctx: Ctx, depth: number): string {\n const args = ref.genericArgs\n ? `<${ref.genericArgs.map((a) => formatType1(a, ctx, depth)).join(', ')}>`\n : '';\n return `${ref.name}${args}`;\n}\n\nfunction formatType2(type2: CddlType2, ctx: Ctx, depth: number): string {\n switch (type2.kind) {\n case 'value':\n return type2.raw;\n case 'ref':\n return formatRef(type2, ctx, depth);\n case 'paren':\n return `(${formatType(type2.type, ctx, depth)})`;\n case 'map':\n return formatGroupBody(type2.group, ctx, depth, '{', '}');\n case 'array':\n return formatGroupBody(type2.group, ctx, depth, '[', ']');\n case 'unwrap':\n return `~${formatRef(type2.ref, ctx, depth)}`;\n case 'enum':\n return type2.group.kind === 'ref'\n ? `&${formatRef(type2.group, ctx, depth)}`\n : `&${formatGroupBody(type2.group, ctx, depth, '(', ')')}`;\n case 'tagged': {\n const head =\n type2.raw ??\n (typeof type2.tag === 'object'\n ? `#6.<${formatType(type2.tag, ctx, depth)}>`\n : `#6${type2.tag === undefined ? '' : `.${type2.tag}`}`);\n return `${head}(${formatType(type2.item, ctx, depth)})`;\n }\n case 'major': {\n if (type2.raw !== undefined) return type2.raw;\n return typeof type2.ai === 'object'\n ? `#${type2.major}.<${formatType(type2.ai, ctx, depth)}>`\n : `#${type2.major}${type2.ai === undefined ? '' : `.${type2.ai}`}`;\n }\n case 'any':\n return '#';\n }\n}\n","/**\n * CDDL compilation: rule table construction and static checks.\n *\n * `compile()` parses CDDL text and performs the semantic checks that do not\n * require a data item: duplicate rule detection, name resolution against the\n * user rules and the standard prelude, and generic arity checks. Validation\n * of CBOR data against a schema is a later phase.\n */\n\nimport { parseCDDL } from './parser';\nimport { getPreludeRules } from './prelude';\nimport { formatCddl, type CddlFormatOptions } from './writer';\nimport type { CddlComment } from './tokenizer';\nimport { validateItem, type ValidateOptions } from './validator';\nimport { CborItem } from '../ast/CborItem';\nimport { decodeCBOR } from '../cbor/decoder';\nimport { parseCDN } from '../cdn/parser';\nimport {\n CddlSemanticError,\n type CddlWarning,\n type ValidationResult,\n} from './errors';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\n\nexport interface CompileOptions {\n /**\n * When true (the default), semantic problems (undefined names, duplicate\n * rules, generic arity mismatches) throw a {@link CddlSemanticError}.\n * When false, they are collected into {@link CddlSchema.warnings}.\n */\n strict?: boolean;\n}\n\n/**\n * A compiled CDDL data model.\n *\n * `rules` maps each rule name to its definitions in source order: the base\n * definition plus any `/=` / `//=` choice extensions. User rules shadow\n * prelude names; the prelude itself is available via `getPreludeRules()`.\n */\nexport class CddlSchema {\n /**\n * The CDDL source text this schema was compiled from. AST node offsets\n * (and validation errors' `schemaStart`/`schemaEnd`) index into it, so\n * tooling can render positions without carrying the text separately.\n */\n readonly source: string;\n /** `;` comments collected while parsing, in source order. */\n readonly comments: readonly CddlComment[];\n /** All rules in source order, as parsed (extensions unmerged). */\n readonly ast: readonly CddlRule[];\n /** Rule definitions by name (base definition first, then extensions). */\n readonly rules: ReadonlyMap<string, readonly CddlRule[]>;\n /**\n * The root of the data model: the first rule in the source (RFC 8610 §3.1).\n * Unset only for an empty model compiled with `strict: false`.\n */\n readonly root?: CddlRule;\n /** Semantic problems collected with `strict: false`; unset when clean. */\n readonly warnings?: CddlWarning[];\n\n /** @internal — use `CDDL.compile()`. */\n constructor(\n source: string,\n comments: readonly CddlComment[],\n ast: CddlRule[],\n rules: Map<string, CddlRule[]>,\n root: CddlRule | undefined,\n warnings: CddlWarning[]\n ) {\n this.source = source;\n this.comments = comments;\n this.ast = ast;\n this.rules = rules;\n if (root) this.root = root;\n if (warnings.length > 0) this.warnings = warnings;\n }\n\n /**\n * Serialize the data model back to CDDL text.\n *\n * Compact one-rule-per-line output by default; pass `indent` for a\n * pretty layout (one group entry per line) and `preserveComments` to\n * re-emit `;` comments.\n *\n * @example\n * CDDL.compile(text).format({ indent: 2, preserveComments: true });\n */\n format(options?: CddlFormatOptions): string {\n return formatCddl(this.ast, {\n ...options,\n source: this.source,\n comments: this.comments,\n });\n }\n\n /**\n * Validate a data item against this schema's root rule — the first rule\n * in source order (RFC 8610 §3.1). Pass `{ rule: 'otherName' }` to\n * validate against a different rule instead: any non-generic rule usable\n * as a type, defined in the schema or its prelude (e.g. `'uint'`).\n * Generic rules (`g<T> = ...`) and group-only rules are reported as\n * validation failures, as is an unknown name (see\n * {@link ValidateOptions.rule}).\n *\n * Accepts a CborItem, CBOR bytes (decoded with `decodeCBOR`), or CDN text\n * (parsed with `parseCDN`). Validation failures are reported in the\n * result, not thrown; decode/parse failures of the input throw as usual.\n *\n * @example\n * const schema = CDDL.compile('person = { name: tstr, ? age: uint }');\n * const result = schema.validate('{\"name\": \"kudo\", \"age\": 42}');\n * result.valid; // true\n *\n * @example\n * // Validate against a rule other than the root.\n * const schema = CDDL.compile(`\n * p1 = { name: tstr, ? addr: tstr }\n * p2 = { name: tstr, ? age: uint }\n * `);\n * schema.validate('{\"name\": \"kudo\", \"age\": 42}', { rule: 'p2' }).valid; // true\n */\n validate(\n input: CborItem | Uint8Array | string,\n options?: ValidateOptions\n ): ValidationResult {\n const item =\n input instanceof CborItem\n ? input\n : typeof input === 'string'\n ? parseCDN(input)\n : decodeCBOR(input);\n return validateItem(this, item, options);\n }\n}\n\n/**\n * Parse and compile CDDL text.\n *\n * Throws `CddlSyntaxError` on grammar errors. Semantic problems throw a\n * {@link CddlSemanticError} by default; pass `strict: false` to collect them\n * into `schema.warnings` instead.\n */\nexport function compile(text: string, options?: CompileOptions): CddlSchema {\n const { rules, comments } = parseCDDL(text);\n const warnings: CddlWarning[] = [];\n const prelude = getPreludeRules();\n\n if (rules.length === 0)\n warnings.push({\n code: 'no-rules',\n message:\n 'a CDDL data model needs at least one rule to provide the root of the definition',\n });\n\n // Rule table: base definition plus /= and //= extensions, in source order.\n const table = new Map<string, CddlRule[]>();\n for (const rule of rules) {\n const existing = table.get(rule.name);\n if (!existing) {\n table.set(rule.name, [rule]);\n continue;\n }\n if (rule.assign === '=')\n warnings.push({\n code: 'duplicate-rule',\n message: `rule '${rule.name}' is already defined; use /= or //= to extend it`,\n start: rule.start,\n end: rule.end,\n });\n existing.push(rule);\n }\n\n // Name resolution and generic arity, per rule (generic parameters are in\n // scope only within their own rule definition's body).\n const declaredArity = (name: string): number | undefined => {\n const defs = table.get(name);\n if (defs) return defs[0]!.generics?.length ?? 0;\n const preludeRule = prelude.get(name);\n if (preludeRule) return preludeRule.generics?.length ?? 0;\n return undefined;\n };\n\n for (const rule of rules) {\n const generics = rule.generics;\n walkEntry(rule.body, {\n onRef(ref: CddlRef): void {\n if (generics?.includes(ref.name)) return;\n // Type and group sockets ($name / $$name) may be referenced and\n // extended without ever being defined.\n if (ref.name.startsWith('$')) return;\n const arity = declaredArity(ref.name);\n if (arity === undefined) {\n warnings.push({\n code: 'undefined-name',\n message: `'${ref.name}' is not defined (and is not a prelude name)`,\n start: ref.start,\n end: ref.end,\n });\n return;\n }\n const given = ref.genericArgs?.length ?? 0;\n if (arity !== given)\n warnings.push({\n code: 'generic-arity',\n message: `'${ref.name}' takes ${arity} generic argument${arity === 1 ? '' : 's'} but is used with ${given}`,\n start: ref.start,\n end: ref.end,\n });\n },\n onMajor(major: number, start: number, end: number): void {\n if (major > 7)\n warnings.push({\n code: 'invalid-major',\n message: `#${major} is not a CBOR major type (0–7)`,\n start,\n end,\n });\n },\n });\n }\n\n // The first rule is the root of the data model, and \"there is no way to\n // use a group as a root -- it must be a type\" (RFC 8610 §2.2.4).\n const root = rules[0];\n if (root && !isTypeBody(root.body))\n warnings.push({\n code: 'invalid-root',\n message: `the first rule '${root.name}' is the root of the data model and must define a type, not a group (RFC 8610 §2.2.4)`,\n start: root.start,\n end: root.end,\n });\n\n if ((options?.strict ?? true) && warnings.length > 0)\n throw new CddlSemanticError(warnings);\n\n // An empty model has no root; `no-rules` was already reported above.\n return new CddlSchema(text, comments, rules, table, root, warnings);\n}\n\n/**\n * Whether a rule body is usable as a type: a plain entry (no occurrence, no\n * member key), or a parenthesized group that reduces to one such entry.\n * A trailing comma makes a parenthesized expression a group — `(int,)` is\n * never a parenthesized type.\n */\nfunction isTypeBody(entry: CddlGroupEntry): boolean {\n if (entry.kind === 'entry') return !entry.occur && !entry.memberKey;\n if (entry.occur || entry.group.trailingComma) return false;\n const { choices } = entry.group;\n return (\n choices.length === 1 &&\n choices[0]!.length === 1 &&\n isTypeBody(choices[0]![0]!)\n );\n}\n\n// ─── AST walk ─────────────────────────────────────────────────────────────────\n\ninterface WalkHooks {\n onRef(ref: CddlRef): void;\n onMajor(major: number, start: number, end: number): void;\n}\n\nfunction walkEntry(entry: CddlGroupEntry, hooks: WalkHooks): void {\n if (entry.kind === 'entry-group') {\n walkGroup(entry.group, hooks);\n return;\n }\n if (entry.memberKey?.kind === 'type1') walkType1(entry.memberKey.key, hooks);\n walkType(entry.value, hooks);\n}\n\nfunction walkGroup(group: CddlGroup, hooks: WalkHooks): void {\n for (const choice of group.choices)\n for (const entry of choice) walkEntry(entry, hooks);\n}\n\nfunction walkType(type: CddlType, hooks: WalkHooks): void {\n for (const alt of type.alternatives) walkType1(alt, hooks);\n}\n\nfunction walkType1(type1: CddlType1, hooks: WalkHooks): void {\n walkType2(type1.target, hooks);\n if (type1.controller) walkType2(type1.controller, hooks);\n}\n\nfunction walkType2(type2: CddlType2, hooks: WalkHooks): void {\n switch (type2.kind) {\n case 'value':\n case 'any':\n return;\n case 'ref':\n hooks.onRef(type2);\n for (const arg of type2.genericArgs ?? []) walkType1(arg, hooks);\n return;\n case 'paren':\n walkType(type2.type, hooks);\n return;\n case 'map':\n case 'array':\n walkGroup(type2.group, hooks);\n return;\n case 'unwrap':\n hooks.onRef(type2.ref);\n for (const arg of type2.ref.genericArgs ?? []) walkType1(arg, hooks);\n return;\n case 'enum':\n if (type2.group.kind === 'ref') {\n hooks.onRef(type2.group);\n for (const arg of type2.group.genericArgs ?? []) walkType1(arg, hooks);\n } else walkGroup(type2.group, hooks);\n return;\n case 'tagged':\n if (typeof type2.tag === 'object') walkType(type2.tag, hooks);\n walkType(type2.item, hooks);\n return;\n case 'major':\n hooks.onMajor(type2.major, type2.start, type2.end);\n if (typeof type2.ai === 'object') walkType(type2.ai, hooks);\n return;\n }\n}\n"],"mappings":"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"}
|