@agentshouse/mdmodel 0.1.0-c4fe1bc82bc55 → 0.1.0-c520180b7a33f
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/API.md +264 -250
- package/README.md +21 -22
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +35 -20
- package/dist/definition.d.ts +17 -1
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +321 -45
- package/dist/divide.d.ts.map +1 -1
- package/dist/divide.js +27 -17
- package/dist/document.d.ts +6 -3
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +326 -171
- package/dist/event.d.ts +78 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +230 -0
- package/dist/fields.d.ts +2 -0
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +7 -0
- package/dist/index.d.ts +24 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -7
- package/dist/kinds.d.ts +19 -0
- package/dist/kinds.d.ts.map +1 -0
- package/dist/kinds.js +161 -0
- package/dist/links.d.ts +3 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +108 -51
- package/dist/paths.d.ts +10 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +118 -12
- package/dist/pattern.d.ts +10 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +355 -0
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +38 -15
- package/dist/query/language.d.ts +223 -0
- package/dist/query/language.d.ts.map +1 -0
- package/dist/query/language.js +565 -0
- package/dist/query/match.d.ts +14 -0
- package/dist/query/match.d.ts.map +1 -0
- package/dist/query/match.js +121 -0
- package/dist/query/rows.d.ts +32 -0
- package/dist/query/rows.d.ts.map +1 -0
- package/dist/query/rows.js +161 -0
- package/dist/query/sql.d.ts +39 -0
- package/dist/query/sql.d.ts.map +1 -0
- package/dist/query/sql.js +279 -0
- package/dist/references.d.ts +2 -2
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +6 -1
- package/dist/reserved.d.ts +5 -0
- package/dist/reserved.d.ts.map +1 -0
- package/dist/reserved.js +20 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +57 -6
- package/dist/types.d.ts +57 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +31 -2
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +400 -115
- package/dist/yaml.d.ts +1 -2
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +75 -32
- package/fixtures/README.md +27 -7
- package/fixtures/cases/conditional-section/context.json +1 -0
- package/fixtures/cases/conditional-section/expected.json +6 -0
- package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
- package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
- package/fixtures/cases/conditional-section/schema.yaml +14 -0
- package/fixtures/cases/cross-room-link/context.json +1 -0
- package/fixtures/cases/cross-room-link/expected.json +1 -0
- package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
- package/fixtures/cases/cross-room-link/schema.yaml +3 -0
- package/fixtures/cases/cross-room-reference/context.json +1 -0
- package/fixtures/cases/cross-room-reference/expected.json +1 -0
- package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
- package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
- package/fixtures/cases/link-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name/library/notes/a.md +6 -0
- package/fixtures/cases/link-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/library/notes/b.md +5 -0
- package/fixtures/cases/member-on-an-untyped-document/context.json +1 -0
- package/fixtures/cases/member-on-an-untyped-document/expected.json +6 -0
- package/fixtures/cases/member-on-an-untyped-document/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/context.json +1 -0
- package/fixtures/cases/member-on-another-type/expected.json +6 -0
- package/fixtures/cases/member-on-another-type/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/schema.yaml +7 -0
- package/fixtures/cases/reference-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/expected.json +6 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/notes/a.md +4 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/settings/brief.md +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/room-md-declares-a-type/context.json +1 -0
- package/fixtures/cases/room-md-declares-a-type/expected.json +6 -0
- package/fixtures/cases/room-md-declares-a-type/library/ROOM.md +5 -0
- package/fixtures/cases/typed-path-names-another-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-another-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-another-type/library/settings/prefs/one.md +3 -0
- package/fixtures/cases/typed-path-names-another-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-its-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-its-type/expected.json +3 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/deeper/two.md +1 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/one.md +4 -0
- package/fixtures/cases/typed-path-names-its-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-no-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-no-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-no-type/library/settings/prefs/one.md +1 -0
- package/fixtures/cases/typed-path-names-no-type/schema.yaml +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/library/rooms/team/tasks/plan.md +4 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/library/rooms/team/tasks/plan.md +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/expected.json +3 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/plan.md +1 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/expected.json +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/schema.yaml +5 -0
- package/fixtures/division.json +26 -26
- package/fixtures/queries.json +913 -0
- package/package.json +10 -3
- package/dist/condition.d.ts +0 -149
- package/dist/condition.d.ts.map +0 -1
- package/dist/condition.js +0 -491
package/dist/yaml.js
CHANGED
|
@@ -6,6 +6,18 @@ export class YamlError extends Error {
|
|
|
6
6
|
this.name = 'YamlError';
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
const YAML_DEPTH_MAX = 64;
|
|
10
|
+
function nested(c, parse) {
|
|
11
|
+
if (c.depth >= YAML_DEPTH_MAX)
|
|
12
|
+
throw new YamlError(c.i);
|
|
13
|
+
c.depth += 1;
|
|
14
|
+
try {
|
|
15
|
+
return parse();
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
c.depth -= 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
9
21
|
function peek(c) {
|
|
10
22
|
return c.i < c.end ? c.text[c.i] : '';
|
|
11
23
|
}
|
|
@@ -70,7 +82,10 @@ function indentAt(c) {
|
|
|
70
82
|
}
|
|
71
83
|
return n;
|
|
72
84
|
}
|
|
85
|
+
const UNHELD_TEXT = /[\0\ud800-\udfff]/u;
|
|
73
86
|
function scalar(value, start, end) {
|
|
87
|
+
if (typeof value === 'string' && UNHELD_TEXT.test(value))
|
|
88
|
+
throw new YamlError(start);
|
|
74
89
|
return { kind: 'scalar', value, start, end };
|
|
75
90
|
}
|
|
76
91
|
export function interpretPlain(text) {
|
|
@@ -84,6 +99,30 @@ export function interpretPlain(text) {
|
|
|
84
99
|
return Number(text);
|
|
85
100
|
return text;
|
|
86
101
|
}
|
|
102
|
+
const ESCAPES = {
|
|
103
|
+
b: '\b',
|
|
104
|
+
f: '\f',
|
|
105
|
+
n: '\n',
|
|
106
|
+
r: '\r',
|
|
107
|
+
t: '\t',
|
|
108
|
+
'"': '"',
|
|
109
|
+
'/': '/',
|
|
110
|
+
'\\': '\\',
|
|
111
|
+
};
|
|
112
|
+
function parseEscape(c) {
|
|
113
|
+
c.i += 1;
|
|
114
|
+
const escaped = peek(c);
|
|
115
|
+
const held = ESCAPES[escaped];
|
|
116
|
+
if (held !== undefined) {
|
|
117
|
+
c.i += 1;
|
|
118
|
+
return held;
|
|
119
|
+
}
|
|
120
|
+
const hex = c.text.slice(c.i + 1, c.i + 5);
|
|
121
|
+
if (escaped !== 'u' || c.i + 5 > c.end || !/^[0-9A-Fa-f]{4}$/.test(hex))
|
|
122
|
+
throw new YamlError(c.i);
|
|
123
|
+
c.i += 5;
|
|
124
|
+
return String.fromCharCode(Number.parseInt(hex, 16));
|
|
125
|
+
}
|
|
87
126
|
function parseQuoted(c) {
|
|
88
127
|
const quote = peek(c);
|
|
89
128
|
const start = c.i;
|
|
@@ -91,31 +130,19 @@ function parseQuoted(c) {
|
|
|
91
130
|
let out = '';
|
|
92
131
|
while (c.i < c.end) {
|
|
93
132
|
const ch = peek(c);
|
|
133
|
+
if (quote === "'" && ch === "'" && c.i + 1 < c.end && c.text[c.i + 1] === "'") {
|
|
134
|
+
out += "'";
|
|
135
|
+
c.i += 2;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
94
138
|
if (ch === quote) {
|
|
95
139
|
c.i += 1;
|
|
96
140
|
return scalar(out, start, c.i);
|
|
97
141
|
}
|
|
98
142
|
if (ch === '\n' || ch === '\r')
|
|
99
143
|
throw new YamlError(c.i);
|
|
100
|
-
if (quote === "'" && ch === "'" && c.text[c.i + 1] === "'") {
|
|
101
|
-
out += "'";
|
|
102
|
-
c.i += 2;
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
144
|
if (quote === '"' && ch === '\\') {
|
|
106
|
-
|
|
107
|
-
const escaped = peek(c);
|
|
108
|
-
if (escaped === 'n')
|
|
109
|
-
out += '\n';
|
|
110
|
-
else if (escaped === 't')
|
|
111
|
-
out += '\t';
|
|
112
|
-
else if (escaped === '"')
|
|
113
|
-
out += '"';
|
|
114
|
-
else if (escaped === '\\')
|
|
115
|
-
out += '\\';
|
|
116
|
-
else
|
|
117
|
-
throw new YamlError(c.i);
|
|
118
|
-
c.i += 1;
|
|
145
|
+
out += parseEscape(c);
|
|
119
146
|
continue;
|
|
120
147
|
}
|
|
121
148
|
out += ch;
|
|
@@ -190,6 +217,9 @@ function parseFlowValue(c) {
|
|
|
190
217
|
return parseScalar(c, true);
|
|
191
218
|
}
|
|
192
219
|
function parseFlowMap(c) {
|
|
220
|
+
return nested(c, () => flowMap(c));
|
|
221
|
+
}
|
|
222
|
+
function flowMap(c) {
|
|
193
223
|
const start = c.i;
|
|
194
224
|
if (peek(c) !== '{')
|
|
195
225
|
throw new YamlError(c.i);
|
|
@@ -208,11 +238,12 @@ function parseFlowMap(c) {
|
|
|
208
238
|
if (peek(c) !== ':')
|
|
209
239
|
throw new YamlError(c.i);
|
|
210
240
|
c.i += 1;
|
|
241
|
+
const after = c.i;
|
|
211
242
|
const value = parseFlowValue(c);
|
|
212
243
|
if (seen.has(key.name))
|
|
213
244
|
throw new YamlError(key.start);
|
|
214
245
|
seen.add(key.name);
|
|
215
|
-
entries.push({ key: key.name,
|
|
246
|
+
entries.push({ key: key.name, after, value });
|
|
216
247
|
skipFlowSpace(c);
|
|
217
248
|
if (peek(c) === ',') {
|
|
218
249
|
c.i += 1;
|
|
@@ -227,6 +258,9 @@ function parseFlowMap(c) {
|
|
|
227
258
|
throw new YamlError(c.i);
|
|
228
259
|
}
|
|
229
260
|
function parseFlowSeq(c) {
|
|
261
|
+
return nested(c, () => flowSeq(c));
|
|
262
|
+
}
|
|
263
|
+
function flowSeq(c) {
|
|
230
264
|
const start = c.i;
|
|
231
265
|
if (peek(c) !== '[')
|
|
232
266
|
throw new YamlError(c.i);
|
|
@@ -254,6 +288,7 @@ function parseFlowSeq(c) {
|
|
|
254
288
|
throw new YamlError(c.i);
|
|
255
289
|
}
|
|
256
290
|
function parseValue(c, parentKeyIndent) {
|
|
291
|
+
const at = c.i;
|
|
257
292
|
skipSpaces(c);
|
|
258
293
|
if (peek(c) === '#')
|
|
259
294
|
skipToEol(c);
|
|
@@ -262,12 +297,12 @@ function parseValue(c, parentKeyIndent) {
|
|
|
262
297
|
skipEol(c);
|
|
263
298
|
skipBlankAndComments(c);
|
|
264
299
|
if (c.i >= c.end)
|
|
265
|
-
return scalar(null,
|
|
300
|
+
return scalar(null, at, at);
|
|
266
301
|
const nextIndent = indentAt(c);
|
|
267
302
|
if (nextIndent === parentKeyIndent && seqAhead(c))
|
|
268
303
|
return parseBlockSeq(c, nextIndent);
|
|
269
304
|
if (nextIndent <= parentKeyIndent)
|
|
270
|
-
return scalar(null,
|
|
305
|
+
return scalar(null, at, at);
|
|
271
306
|
if (peek(c) === '-')
|
|
272
307
|
return parseBlockSeq(c, nextIndent);
|
|
273
308
|
if (peek(c) === '[')
|
|
@@ -315,9 +350,6 @@ function lineStartOf(c) {
|
|
|
315
350
|
j -= 1;
|
|
316
351
|
return j;
|
|
317
352
|
}
|
|
318
|
-
function valueEnd(value, marked) {
|
|
319
|
-
return value.kind === 'scalar' && value.start === value.end ? marked : value.end;
|
|
320
|
-
}
|
|
321
353
|
function parseSeqItem(c, indent) {
|
|
322
354
|
skipSpaces(c);
|
|
323
355
|
if (peek(c) !== '#' && peek(c) !== '\n' && peek(c) !== '\r' && c.i < c.end && mappingAhead(c))
|
|
@@ -325,6 +357,9 @@ function parseSeqItem(c, indent) {
|
|
|
325
357
|
return parseValue(c, indent);
|
|
326
358
|
}
|
|
327
359
|
function parseBlockSeq(c, indent) {
|
|
360
|
+
return nested(c, () => blockSeq(c, indent));
|
|
361
|
+
}
|
|
362
|
+
function blockSeq(c, indent) {
|
|
328
363
|
const start = c.i;
|
|
329
364
|
const items = [];
|
|
330
365
|
let end = start;
|
|
@@ -337,14 +372,16 @@ function parseBlockSeq(c, indent) {
|
|
|
337
372
|
if (peek(c) !== '-')
|
|
338
373
|
break;
|
|
339
374
|
c.i += 1;
|
|
340
|
-
const marked = c.i;
|
|
341
375
|
const item = parseSeqItem(c, indent);
|
|
342
376
|
items.push(item);
|
|
343
|
-
end =
|
|
377
|
+
end = item.end;
|
|
344
378
|
}
|
|
345
379
|
return { kind: 'seq', items, start, end };
|
|
346
380
|
}
|
|
347
381
|
function parseBlockMap(c, indent, inline = false) {
|
|
382
|
+
return nested(c, () => blockMap(c, indent, inline));
|
|
383
|
+
}
|
|
384
|
+
function blockMap(c, indent, inline) {
|
|
348
385
|
const start = c.i;
|
|
349
386
|
const entries = [];
|
|
350
387
|
const seen = new Set();
|
|
@@ -366,18 +403,18 @@ function parseBlockMap(c, indent, inline = false) {
|
|
|
366
403
|
if (peek(c) !== ':')
|
|
367
404
|
throw new YamlError(c.i);
|
|
368
405
|
c.i += 1;
|
|
369
|
-
const
|
|
406
|
+
const after = c.i;
|
|
370
407
|
const value = parseValue(c, indent);
|
|
371
408
|
if (seen.has(key.name))
|
|
372
409
|
throw new YamlError(key.start);
|
|
373
410
|
seen.add(key.name);
|
|
374
|
-
entries.push({ key: key.name,
|
|
375
|
-
end =
|
|
411
|
+
entries.push({ key: key.name, after, value });
|
|
412
|
+
end = value.end;
|
|
376
413
|
}
|
|
377
414
|
return { kind: 'map', entries, start, end };
|
|
378
415
|
}
|
|
379
416
|
export function parseYamlMapping(text, start, end) {
|
|
380
|
-
const c = { text, i: start, end };
|
|
417
|
+
const c = { text, i: start, end, depth: 0 };
|
|
381
418
|
skipBlankAndComments(c);
|
|
382
419
|
if (c.i >= end)
|
|
383
420
|
return { kind: 'map', entries: [], start, end };
|
|
@@ -429,17 +466,23 @@ function listed(value) {
|
|
|
429
466
|
return keys.length === value.length && keys.every((key, index) => key === String(index));
|
|
430
467
|
}
|
|
431
468
|
function heldWithin(value, within) {
|
|
432
|
-
if (
|
|
469
|
+
if (typeof value === 'string')
|
|
470
|
+
return !UNHELD_TEXT.test(value);
|
|
471
|
+
if (value === null || typeof value === 'boolean')
|
|
433
472
|
return true;
|
|
434
473
|
if (typeof value === 'number')
|
|
435
474
|
return Number.isFinite(value);
|
|
436
475
|
if (typeof value !== 'object' || within.includes(value))
|
|
437
476
|
return false;
|
|
477
|
+
if (within.length + 1 >= YAML_DEPTH_MAX)
|
|
478
|
+
return false;
|
|
438
479
|
const path = [...within, value];
|
|
439
480
|
const held = (item) => heldWithin(item, path);
|
|
440
481
|
if (Array.isArray(value))
|
|
441
482
|
return listed(value) && value.every(held);
|
|
442
|
-
return plain(value) &&
|
|
483
|
+
return (plain(value) &&
|
|
484
|
+
Object.keys(value).every((key) => !UNHELD_TEXT.test(key)) &&
|
|
485
|
+
Object.values(value).every(held));
|
|
443
486
|
}
|
|
444
487
|
export function frontmatterValue(value) {
|
|
445
488
|
return heldWithin(value, []);
|
package/fixtures/README.md
CHANGED
|
@@ -51,8 +51,8 @@ change to a value that is not prose leaves the projection alone.
|
|
|
51
51
|
|
|
52
52
|
`division.json` exercises the public `divide` seam separately from the
|
|
53
53
|
validation Libraries. It carries `schema` and `cases` like `projection.json`,
|
|
54
|
-
and each case adds the `
|
|
55
|
-
`divide(document, file, context)` with `{ documentTargets, definition,
|
|
54
|
+
and each case adds the `bound` the division runs under. Parse the source, call
|
|
55
|
+
`divide(document, file, context)` with `{ documentTargets, definition, bound }`,
|
|
56
56
|
and compare against `expected`: either `{ "ok": true, "spans": [...] }`, where
|
|
57
57
|
each span carries the exact `text` to embed and the exact `source` the returned
|
|
58
58
|
`start` and `end` address in that case's source, or `{ "ok": false, "refusal": ... }`. Then
|
|
@@ -65,6 +65,19 @@ value one span carries part of. `start` and `end` are UTF-8 byte offsets into th
|
|
|
65
65
|
source; every source in this corpus is ASCII, so a consumer compares the
|
|
66
66
|
addressed `source` with an ordinary string slice.
|
|
67
67
|
|
|
68
|
+
## Queries
|
|
69
|
+
|
|
70
|
+
`queries.json` is the one table of cases both query evaluators answer. It carries `schema`,
|
|
71
|
+
one schema text; `documents`, each named and carrying its `path`, the `type` a collection
|
|
72
|
+
stores for it (`any` for an untyped Markdown Document, `null` for one that is not Markdown),
|
|
73
|
+
its `fileId`, the `text` the device holds or `null`, and its `fields`; and `cases`, each with a
|
|
74
|
+
`name`, a `query` of filter parts, the `document` it names and whether it `matches`. Verify
|
|
75
|
+
the schema and plan `{ ...query, select: {} }` with `planOf` against its types. Then
|
|
76
|
+
`matches(plan, candidate)` over the named Document, given its type's definition, and the
|
|
77
|
+
condition `sql.tests` writes over a collection holding every Document of the table with the
|
|
78
|
+
values `indexed` derives from it must both answer `matches`. A new operator adds its cases
|
|
79
|
+
here first.
|
|
80
|
+
|
|
68
81
|
## Verdict format
|
|
69
82
|
|
|
70
83
|
Acceptance:
|
|
@@ -107,6 +120,7 @@ schema text. The model's own rules:
|
|
|
107
120
|
| `frontmatter-fence` | A present frontmatter fence does not parse as the accepted YAML subset |
|
|
108
121
|
| `schema-yaml` | A schema text is not a mapping in the accepted YAML subset |
|
|
109
122
|
| `schema-type-name` | A type name is empty, starts with `$`, or is `any` or `attachment` |
|
|
123
|
+
| `provided-type` | A schema names a type its caller provides with a key but its two role keywords |
|
|
110
124
|
| `schema` | A type or subschema is neither a mapping nor a boolean |
|
|
111
125
|
| `schema-keyword` | A schema carries a key that is no JSON Schema 2020-12 keyword the model admits |
|
|
112
126
|
| `$defs` | `$defs` is not a mapping |
|
|
@@ -114,17 +128,23 @@ schema text. The model's own rules:
|
|
|
114
128
|
| `reference` | `reference` is not on a string or names something but a type, `any`, `attachment` |
|
|
115
129
|
| `sections` | A section is not `{ kind: text }` or `{ kind: list, items }` over one scalar |
|
|
116
130
|
| `member_document` | The mark is not a boolean, or a second type carries it |
|
|
117
|
-
| `unknown-type` | A file declares a type absent from the governing schema
|
|
131
|
+
| `unknown-type` | A file declares a type absent from the governing schema, or other than its typed path requires it to name |
|
|
118
132
|
| `undeclared-field` | A closed object carries a key it does not declare |
|
|
119
133
|
| `required-section` | A required section heading is missing |
|
|
134
|
+
| `conditional-section` | A section its type's `if` branch requires is absent or holds no text |
|
|
120
135
|
| `unresolved-reference` | A reference at any depth or a section item reaches no member it admits |
|
|
121
|
-
| `unresolved-link` | A body link is an absolute path
|
|
136
|
+
| `unresolved-link` | A body link is an absolute path, leaves the collection or, from a typed Document at a document path, reaches a reserved name |
|
|
137
|
+
| `room-md-type` | `ROOM.md` declares a type |
|
|
138
|
+
| `required-body` | A file at a typed path that requires a body has a body holding no text |
|
|
122
139
|
| `structured-section` | A declared list section is not a list of values of its item schema |
|
|
123
140
|
| `referenced-missing-file` | Remaining files still reference an absent path |
|
|
124
141
|
| `unwritable-link` | No Markdown destination form can carry a new link destination |
|
|
125
|
-
| `division-
|
|
142
|
+
| `division-bound` | A division bound is not a whole number of at least 2 |
|
|
143
|
+
|
|
144
|
+
A `then` or `else` of an `if` on a type, in its `allOf` or in such a branch may hold
|
|
145
|
+
`sections`, naming sections the type declares as the type declares them, else `sections`.
|
|
126
146
|
|
|
127
|
-
`unwritable-link` is refused by `apply` and `division-
|
|
147
|
+
`unwritable-link` is refused by `apply` and `division-bound` by `divide`, not
|
|
128
148
|
by `validate`, so no case under `cases/` carries either.
|
|
129
149
|
|
|
130
150
|
A reference that admits `attachment` reaches any path in the same Library, so
|
|
@@ -136,6 +156,6 @@ Library is accepted too, so `unresolved-link` never names it and
|
|
|
136
156
|
## YAML subset
|
|
137
157
|
|
|
138
158
|
Frontmatter and a schema text are each a mapping in a closed YAML subset: block and flow mappings,
|
|
139
|
-
block and flow sequences, a block sequence item that opens a mapping, plain and quoted scalars, `true`, `false`, `null`,
|
|
159
|
+
block and flow sequences, a block sequence item that opens a mapping, plain and quoted scalars (a single-quoted scalar doubles its apostrophe, a double-quoted one takes JSON's escapes), `true`, `false`, `null`,
|
|
140
160
|
and decimal numbers. It does not take YAML 1.1 boolean or timestamp aliases,
|
|
141
161
|
octal numbers, anchors, tags, or block scalars. A mapping carries each key once.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
question:
|
|
2
|
+
properties:
|
|
3
|
+
title: { type: string }
|
|
4
|
+
status: { enum: [open, answered, withdrawn] }
|
|
5
|
+
required: [title, status]
|
|
6
|
+
sections:
|
|
7
|
+
Question: { kind: text, required: true }
|
|
8
|
+
Answer: { kind: text }
|
|
9
|
+
if:
|
|
10
|
+
properties:
|
|
11
|
+
status: { enum: [answered, withdrawn] }
|
|
12
|
+
then:
|
|
13
|
+
sections:
|
|
14
|
+
Answer: { kind: text, required: true }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "verdict": "accept" }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "verdict": "accept" }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
client:
|
|
2
|
+
properties:
|
|
3
|
+
name: { type: string }
|
|
4
|
+
finance: { type: string, reference: invoice, cross_room: true }
|
|
5
|
+
sections:
|
|
6
|
+
Invoices: { kind: list, items: { type: string, reference: invoice, cross_room: true } }
|
|
7
|
+
invoice:
|
|
8
|
+
properties:
|
|
9
|
+
name: { type: string }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The brief.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "binaryTargets": [] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Dark.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Dark.
|