@agentshouse/mdmodel 0.1.0-cc9fa0498a7f7 → 0.1.0-cd90851746292

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/API.md +231 -225
  2. package/README.md +16 -19
  3. package/dist/blocks.d.ts.map +1 -1
  4. package/dist/blocks.js +35 -20
  5. package/dist/condition.d.ts +41 -11
  6. package/dist/condition.d.ts.map +1 -1
  7. package/dist/condition.js +223 -87
  8. package/dist/definition.d.ts +17 -1
  9. package/dist/definition.d.ts.map +1 -1
  10. package/dist/definition.js +319 -43
  11. package/dist/divide.d.ts.map +1 -1
  12. package/dist/divide.js +27 -17
  13. package/dist/document.d.ts +6 -3
  14. package/dist/document.d.ts.map +1 -1
  15. package/dist/document.js +326 -176
  16. package/dist/index.d.ts +13 -9
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +7 -6
  19. package/dist/links.d.ts +3 -0
  20. package/dist/links.d.ts.map +1 -1
  21. package/dist/links.js +108 -51
  22. package/dist/paths.d.ts +10 -1
  23. package/dist/paths.d.ts.map +1 -1
  24. package/dist/paths.js +118 -12
  25. package/dist/pattern.d.ts +10 -0
  26. package/dist/pattern.d.ts.map +1 -0
  27. package/dist/pattern.js +355 -0
  28. package/dist/project.d.ts +1 -0
  29. package/dist/project.d.ts.map +1 -1
  30. package/dist/project.js +38 -15
  31. package/dist/references.d.ts +2 -2
  32. package/dist/references.d.ts.map +1 -1
  33. package/dist/references.js +6 -1
  34. package/dist/schema.d.ts +1 -0
  35. package/dist/schema.d.ts.map +1 -1
  36. package/dist/schema.js +55 -4
  37. package/dist/types.d.ts +50 -2
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/validate.d.ts +30 -2
  40. package/dist/validate.d.ts.map +1 -1
  41. package/dist/validate.js +317 -114
  42. package/dist/yaml.d.ts.map +1 -1
  43. package/dist/yaml.js +66 -21
  44. package/fixtures/README.md +10 -5
  45. package/fixtures/cases/conditional-section/context.json +1 -0
  46. package/fixtures/cases/conditional-section/expected.json +6 -0
  47. package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
  48. package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
  49. package/fixtures/cases/conditional-section/schema.yaml +14 -0
  50. package/fixtures/cases/cross-room-link/context.json +1 -0
  51. package/fixtures/cases/cross-room-link/expected.json +1 -0
  52. package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
  53. package/fixtures/cases/cross-room-link/schema.yaml +3 -0
  54. package/fixtures/cases/cross-room-reference/context.json +1 -0
  55. package/fixtures/cases/cross-room-reference/expected.json +1 -0
  56. package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
  57. package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
  58. package/fixtures/division.json +26 -26
  59. package/package.json +10 -3
package/dist/condition.js CHANGED
@@ -1,13 +1,26 @@
1
- import { ARRAY_INDEX, escapePointer, fieldFacts, itemFacts, memberFacts, pointerSegments, } from './definition.js';
2
- import { target } from './paths.js';
3
- import { isRecord, plain } from './yaml.js';
4
- export const WRITE_DOORS = ['browser', 'agent', 'client'];
1
+ import { ARRAY_INDEX, escapePointer, fieldFacts, itemFacts, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
2
+ import { roomPath, target } from './paths.js';
3
+ import { plain } from './yaml.js';
4
+ export const CONDITION_OPERATORS = [
5
+ 'eq',
6
+ 'in',
7
+ 'exists',
8
+ 'contains',
9
+ 'gt',
10
+ 'gte',
11
+ 'lt',
12
+ 'lte',
13
+ 'prefix',
14
+ ];
15
+ export const TEXT_FIELD = '/text';
16
+ export const WRITE_DOORS = ['browser', 'agent', 'client', 'function'];
5
17
  const PROSE = { kind: 'prose' };
6
18
  const NULL = { kind: 'null' };
7
19
  const UNREADABLE = { kind: 'unreadable' };
8
20
  const UNREAD = { present: undefined, values: [undefined], items: [undefined] };
9
21
  const NO_ITEM = { present: false, values: [], items: [] };
10
22
  const DATE = /^\d{4}-\d{2}-\d{2}$/u;
23
+ const HEADER = /^\/headers\/[!#$%&'*+.^_`|~0-9a-z-]+$/u;
11
24
  const DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:[Zz]|([+-])(\d{2}):(\d{2}))$/u;
12
25
  export function factKind(facts) {
13
26
  if (facts.reference !== undefined)
@@ -71,7 +84,7 @@ function factOf(value, declared, place) {
71
84
  return UNREADABLE;
72
85
  if (kind !== 'reference')
73
86
  return { kind, value };
74
- const reached = target(place.path, value);
87
+ const reached = target(place.path, value) ?? roomPath(value);
75
88
  const resolved = reached === null ? undefined : place.resolve(reached);
76
89
  if (resolved === undefined)
77
90
  return UNREADABLE;
@@ -181,10 +194,9 @@ function documentRead({ reached, several, missing }, held) {
181
194
  };
182
195
  }
183
196
  function readDocument(facts, path) {
184
- if (path === '/path')
185
- return single({ kind: 'path', value: facts.path });
186
- if (path === '/type')
187
- return facts.type === null ? undefined : single({ kind: 'string', value: facts.type });
197
+ const own = tested(DOCUMENT_TESTS, path);
198
+ if (own !== undefined)
199
+ return own.read(facts, path);
188
200
  if (path.startsWith('/sections/'))
189
201
  return facts.sections.includes(path.slice('/sections/'.length))
190
202
  ? single({ kind: 'prose' })
@@ -195,22 +207,156 @@ function readDocument(facts, path) {
195
207
  return documentRead(walked(rootOf(facts, '/members'), path.slice('/members'.length)), memberHeld);
196
208
  return undefined;
197
209
  }
198
- function readActor(actor, path) {
199
- const value = path === '/user'
200
- ? actor.user
201
- : path === '/site'
202
- ? actor.site
203
- : path === '/door'
204
- ? actor.door
205
- : undefined;
206
- return value === undefined ? undefined : single({ kind: 'actor', value });
207
- }
208
210
  export function datePointers(fields) {
209
211
  return Object.entries(fields)
210
212
  .filter(([, facts]) => facts.type === 'string' && facts.format === 'date')
211
- .map(([name]) => `/fields/${name}`)
213
+ .map(([name]) => `/fields/${escapePointer(name)}`)
212
214
  .sort();
213
215
  }
216
+ export function valuedChange(definition, field) {
217
+ if (!field.startsWith('/fields/'))
218
+ return false;
219
+ const reached = pointerFacts(definition, field.slice('/fields'.length));
220
+ return (reached !== undefined &&
221
+ !reached.through &&
222
+ reached.facts.type !== 'array' &&
223
+ !reached.facts.prose &&
224
+ factKind(reached.facts) !== null);
225
+ }
226
+ export function changeFields(definition) {
227
+ return [
228
+ ...Object.keys(definition.fields).map((name) => `/fields/${escapePointer(name)}`),
229
+ ...Object.keys(definition.sections).map((heading) => `/sections/${heading}`),
230
+ ];
231
+ }
232
+ export function memberPointers(definition, memberType) {
233
+ return Object.entries(definition.fields)
234
+ .filter(([, facts]) => (facts.type === 'array' ? facts.items : facts)?.reference?.includes(memberType) === true)
235
+ .map(([name]) => `/members/${escapePointer(name)}`);
236
+ }
237
+ function kindOperators(kind) {
238
+ switch (kind) {
239
+ case 'string':
240
+ return ['eq', 'in', 'prefix', 'exists'];
241
+ case 'boolean':
242
+ return ['eq', 'exists'];
243
+ case 'number':
244
+ case 'date':
245
+ case 'time':
246
+ return ['eq', 'in', 'gt', 'gte', 'lt', 'lte', 'exists'];
247
+ default:
248
+ return ['eq', 'in', 'exists'];
249
+ }
250
+ }
251
+ function pointerOperators({ facts, through }) {
252
+ const scalar = facts.type === 'array' ? facts.items : facts;
253
+ const kind = scalar === undefined || scalar.prose ? null : factKind(scalar);
254
+ if (kind === null)
255
+ return ['exists'];
256
+ if (facts.type === 'array')
257
+ return ['contains', 'exists'];
258
+ const own = kindOperators(kind);
259
+ return through ? [...own.filter((operator) => operator !== 'exists'), 'contains', 'exists'] : own;
260
+ }
261
+ function typeOperators(definition, path, memberType) {
262
+ if (path.startsWith('/sections/'))
263
+ return Object.hasOwn(definition.sections, path.slice('/sections/'.length)) ? ['exists'] : [];
264
+ const pointer = path.startsWith('/fields/')
265
+ ? path.slice('/fields'.length)
266
+ : memberType !== null && memberPointers(definition, memberType).includes(path)
267
+ ? path.slice('/members'.length)
268
+ : undefined;
269
+ const reached = pointer === undefined ? undefined : pointerFacts(definition, pointer);
270
+ return reached === undefined ? [] : pointerOperators(reached);
271
+ }
272
+ function envelope(path, kind, value) {
273
+ return {
274
+ path,
275
+ names: (named) => named === path,
276
+ kind,
277
+ operators: kindOperators(kind),
278
+ read: (facts) => {
279
+ const held = value(facts);
280
+ return held === null || held === undefined ? undefined : single({ kind, value: held });
281
+ },
282
+ };
283
+ }
284
+ function tested(tests, path) {
285
+ return tests.find(({ names }) => names(path));
286
+ }
287
+ function reader(tests, facts) {
288
+ return (path) => tested(tests, path)?.read(facts, path);
289
+ }
290
+ const DOCUMENT_TESTS = [
291
+ {
292
+ path: '/path',
293
+ names: (named) => named === '/path',
294
+ kind: 'string',
295
+ operators: ['eq', 'in', 'prefix'],
296
+ read: (facts) => single({ kind: 'string', value: facts.path }),
297
+ },
298
+ envelope('/type', 'enum', (facts) => facts.type),
299
+ ];
300
+ const ACTOR_TESTS = [
301
+ envelope('/user', 'enum', (actor) => actor.user),
302
+ envelope('/site', 'enum', (actor) => actor.site),
303
+ envelope('/app', 'enum', (actor) => actor.app),
304
+ envelope('/door', 'enum', (actor) => actor.door),
305
+ ];
306
+ const ITEM_TESTS = [
307
+ envelope('/delivery', 'enum', (item) => item.delivery),
308
+ envelope('/source', 'enum', (item) => item.source),
309
+ envelope('/container', 'string', (item) => item.container),
310
+ envelope('/author', 'string', (item) => item.author),
311
+ {
312
+ path: '/headers/<lowercase name>',
313
+ names: (named) => HEADER.test(named),
314
+ kind: 'string',
315
+ operators: kindOperators('string'),
316
+ read: (item, path) => {
317
+ const name = path.slice('/headers/'.length);
318
+ return Object.hasOwn(item.headers, name)
319
+ ? single({ kind: 'string', value: item.headers[name] })
320
+ : undefined;
321
+ },
322
+ },
323
+ {
324
+ path: '/json/<JSON Pointer>',
325
+ names: (named) => named.startsWith('/json/'),
326
+ kind: null,
327
+ operators: CONDITION_OPERATORS,
328
+ read: (item, path) => item.json === null ? UNREAD : jsonRead(pointed(item.json.value, path.slice('/json'.length))),
329
+ },
330
+ ];
331
+ const MESSAGE_TESTS = [
332
+ envelope('/sender', 'enum', (message) => message.sender),
333
+ envelope('/routine', 'string', (message) => message.routine),
334
+ envelope('/path', 'string', (message) => message.path),
335
+ ];
336
+ export const DOCUMENT_PATHS = DOCUMENT_TESTS.map(({ path }) => path);
337
+ export const ACTOR_PATHS = ACTOR_TESTS.map(({ path }) => path);
338
+ export const ITEM_PATHS = ITEM_TESTS.map(({ path }) => path);
339
+ export const MESSAGE_PATHS = MESSAGE_TESTS.map(({ path }) => path);
340
+ export function testOperators(definitions, path, memberType) {
341
+ const own = tested(DOCUMENT_TESTS, path);
342
+ if (own !== undefined)
343
+ return own.operators;
344
+ return [
345
+ ...new Set(definitions.flatMap((definition) => typeOperators(definition, path, memberType))),
346
+ ];
347
+ }
348
+ export function actorOperators(path) {
349
+ return tested(ACTOR_TESTS, path)?.operators ?? [];
350
+ }
351
+ export function itemOperators(path) {
352
+ return tested(ITEM_TESTS, path)?.operators ?? [];
353
+ }
354
+ export function messageOperators(path) {
355
+ return tested(MESSAGE_TESTS, path)?.operators ?? [];
356
+ }
357
+ export function itemKind(path) {
358
+ return tested(ITEM_TESTS, path)?.kind ?? null;
359
+ }
214
360
  export function dated(value) {
215
361
  return (typeof value === 'string' && DATE.test(value) && instant(`${value}T00:00:00Z`) !== undefined);
216
362
  }
@@ -239,11 +385,8 @@ export function instant(value) {
239
385
  return (BigInt(at.getTime()) - BigInt(offset) * 60000n) * 1000000n + BigInt(fraction);
240
386
  }
241
387
  export function pointed(value, pointer) {
242
- if (pointer === '')
243
- return value;
244
388
  let reached = value;
245
- for (const part of pointer.slice(1).split('/')) {
246
- const token = part.replaceAll('~1', '/').replaceAll('~0', '~');
389
+ for (const token of pointerSegments(pointer)) {
247
390
  if (Array.isArray(reached)) {
248
391
  if (!ARRAY_INDEX.test(token))
249
392
  return undefined;
@@ -282,46 +425,15 @@ function jsonRead(value) {
282
425
  return single({ kind: 'prose' });
283
426
  return { present: true, values: [], items: value.filter(scalar).map(jsonHeld), loose: true };
284
427
  }
285
- function readItem(item, path) {
286
- if (path.startsWith('/json/')) {
287
- if (item.json === null)
288
- return UNREAD;
289
- return jsonRead(pointed(item.json.value, path.slice('/json'.length)));
290
- }
291
- if (path.startsWith('/headers/')) {
292
- const name = path.slice('/headers/'.length);
293
- return Object.hasOwn(item.headers, name)
294
- ? single({ kind: 'string', value: item.headers[name] })
295
- : undefined;
296
- }
297
- if (path === '/has_attachment')
298
- return single({ kind: 'boolean', value: item.has_attachment });
299
- const value = path === '/delivery'
300
- ? item.delivery
301
- : path === '/source'
302
- ? item.source
303
- : path === '/provider'
304
- ? item.provider
305
- : path === '/container'
306
- ? item.container
307
- : path === '/author'
308
- ? item.author
309
- : null;
310
- return value === null ? undefined : single({ kind: 'string', value });
311
- }
312
- function wanted(value, owner) {
313
- return isRecord(value) && value.owner === true ? owner : value;
314
- }
315
- function equal(held, value, owner) {
428
+ function equal(held, value) {
316
429
  if (!('value' in held))
317
430
  return undefined;
318
- const expected = wanted(value, owner);
319
- if (typeof expected !== typeof held.value)
431
+ if (typeof value !== typeof held.value)
320
432
  return undefined;
321
433
  if (held.kind !== 'time')
322
- return expected === held.value;
434
+ return value === held.value;
323
435
  const left = instant(held.value);
324
- const right = instant(expected);
436
+ const right = instant(value);
325
437
  return left === undefined || right === undefined ? undefined : left === right;
326
438
  }
327
439
  function sign(left, right) {
@@ -358,11 +470,11 @@ function allOf(truths) {
358
470
  return false;
359
471
  return truths.some((truth) => truth === undefined) ? undefined : true;
360
472
  }
361
- function compared(test, held, owner) {
473
+ function compared(test, held) {
362
474
  if ('eq' in test)
363
- return equal(held, test.eq, owner);
475
+ return equal(held, test.eq);
364
476
  if ('in' in test)
365
- return anyOf(test.in.map((value) => equal(held, value, owner)));
477
+ return anyOf(test.in.map((value) => equal(held, value)));
366
478
  if ('prefix' in test) {
367
479
  if (!('value' in held) || typeof held.value !== 'string')
368
480
  return undefined;
@@ -378,7 +490,7 @@ function compared(test, held, owner) {
378
490
  return ordered(held, test.lt, (sign) => sign < 0);
379
491
  return ordered(held, test.lte, (sign) => sign <= 0);
380
492
  }
381
- function leaf(test, read, owner) {
493
+ function leaf(test, read) {
382
494
  if ('exists' in test) {
383
495
  const present = read === undefined ? false : read.present;
384
496
  return present === undefined ? undefined : present === test.exists;
@@ -388,26 +500,37 @@ function leaf(test, read, owner) {
388
500
  if ('contains' in test) {
389
501
  if (read.items === null)
390
502
  return undefined;
391
- const truths = read.items.map((item) => item === undefined ? undefined : equal(item, test.contains, owner));
503
+ const truths = read.items.map((item) => item === undefined ? undefined : equal(item, test.contains));
392
504
  return read.loose === true && !truths.includes(true) ? false : anyOf(truths);
393
505
  }
394
506
  if (read.values.length === 0)
395
507
  return read === NO_ITEM ? false : undefined;
396
- return anyOf(read.values.map((value) => (value === undefined ? undefined : compared(test, value, owner))));
508
+ return anyOf(read.values.map((value) => (value === undefined ? undefined : compared(test, value))));
397
509
  }
398
- function evaluated(test, read, owner) {
510
+ function evaluated(test, read) {
399
511
  if ('all' in test)
400
- return allOf(test.all.map((part) => evaluated(part, read, owner)));
512
+ return allOf(test.all.map((part) => evaluated(part, read)));
401
513
  if ('any' in test)
402
- return anyOf(test.any.map((part) => evaluated(part, read, owner)));
514
+ return anyOf(test.any.map((part) => evaluated(part, read)));
403
515
  if ('not' in test) {
404
- const truth = evaluated(test.not, read, owner);
516
+ const truth = evaluated(test.not, read);
405
517
  return truth === undefined ? undefined : !truth;
406
518
  }
407
- return leaf(test, read(test.path), owner);
519
+ return leaf(test, read(test.path));
408
520
  }
409
- export function holds(test, document, owner) {
410
- return evaluated(test, (path) => readDocument(document, path), owner);
521
+ export function members(document, path) {
522
+ if (!path.startsWith('/members/'))
523
+ return [];
524
+ const read = readDocument(document, path);
525
+ const values = read === undefined ? [] : [...read.values, ...(read.items ?? [])];
526
+ return [
527
+ ...new Set(values.flatMap((value) => value !== undefined && value.kind === 'member' && 'value' in value
528
+ ? [String(value.value)]
529
+ : [])),
530
+ ].sort();
531
+ }
532
+ export function holds(test, document) {
533
+ return evaluated(test, (path) => readDocument(document, path));
411
534
  }
412
535
  function inScope(scope, document) {
413
536
  if (document === null)
@@ -418,10 +541,10 @@ function inScope(scope, document) {
418
541
  return document.id === scope.document;
419
542
  return scope.folder === '/' || document.path.startsWith(`${scope.folder}/`);
420
543
  }
421
- function matched(condition, test, document, owner) {
544
+ function matched(condition, test, document) {
422
545
  if (!inScope(condition.scope, document))
423
546
  return false;
424
- return test === undefined || holds(test, document, owner) === true;
547
+ return test === undefined || holds(test, document) === true;
425
548
  }
426
549
  function reachedAt(document, field) {
427
550
  if (document === null)
@@ -444,15 +567,20 @@ function valueOf(fact) {
444
567
  .sort()
445
568
  .map((key) => [key, valueOf(fact.fields[key])]),
446
569
  };
570
+ if (fact.kind === 'time') {
571
+ const at = instant(fact.value);
572
+ if (at !== undefined)
573
+ return { kind: fact.kind, at: String(at) };
574
+ }
447
575
  return 'value' in fact ? { kind: fact.kind, value: fact.value } : fact;
448
576
  }
449
577
  function signature(reached) {
450
578
  return JSON.stringify(reached.map(({ fact }) => valueOf(fact)));
451
579
  }
452
- function among(values, document, field, owner) {
453
- return holds({ path: field, in: values }, document, owner) === true;
580
+ function among(values, document, field) {
581
+ return holds({ path: field, in: values }, document) === true;
454
582
  }
455
- function fieldChanged(condition, event, owner) {
583
+ function fieldChanged(condition, event) {
456
584
  const { field, from, to } = condition;
457
585
  const before = reachedAt(event.before, field);
458
586
  const after = reachedAt(event.after, field);
@@ -466,32 +594,40 @@ function fieldChanged(condition, event, owner) {
466
594
  return false;
467
595
  if (from === 'new'
468
596
  ? event.before !== null
469
- : from !== undefined && (event.before === null || !among(from, event.before, field, owner)))
597
+ : from !== undefined && (event.before === null || !among(from, event.before, field)))
470
598
  return false;
471
599
  if (to === 'deleted'
472
600
  ? event.after !== null
473
- : to !== undefined && (event.after === null || !among(to, event.after, field, owner)))
601
+ : to !== undefined && (event.after === null || !among(to, event.after, field)))
474
602
  return false;
475
603
  return true;
476
604
  }
477
- export function fires(condition, event, owner) {
478
- if (condition.by !== undefined &&
479
- evaluated(condition.by, (path) => readActor(event.by, path), owner) !== true)
605
+ export function fires(condition, event) {
606
+ if (condition.moved_between_rooms !== undefined &&
607
+ condition.moved_between_rooms !== event.moved_between_rooms)
608
+ return false;
609
+ if (condition.by !== undefined && evaluated(condition.by, reader(ACTOR_TESTS, event.by)) !== true)
480
610
  return false;
481
611
  if (condition.mode === 'starts_matching') {
482
612
  if (event.before === null && !condition.new_documents)
483
613
  return false;
484
- return (matched(condition, condition.match, event.after, owner) &&
485
- !matched(condition, condition.match, event.before, owner));
614
+ return (matched(condition, condition.match, event.after) &&
615
+ !matched(condition, condition.match, event.before));
486
616
  }
487
617
  const side = event.after ?? event.before;
488
- return matched(condition, condition.match, side, owner) && fieldChanged(condition, event, owner);
618
+ return matched(condition, condition.match, side) && fieldChanged(condition, event);
489
619
  }
490
- export function itemFires(condition, item, owner) {
620
+ export function itemFires(condition, item) {
491
621
  if (condition.source !== undefined && item.source !== condition.source)
492
622
  return false;
493
623
  if (condition.address !== undefined && item.address !== condition.address)
494
624
  return false;
625
+ return (condition.match === undefined || evaluated(condition.match, reader(ITEM_TESTS, item)) === true);
626
+ }
627
+ export function notificationFires(condition, notification) {
628
+ return condition.match === undefined || holds(condition.match, notification) === true;
629
+ }
630
+ export function messageFires(condition, message) {
495
631
  return (condition.match === undefined ||
496
- evaluated(condition.match, (path) => readItem(item, path), owner) === true);
632
+ evaluated(condition.match, reader(MESSAGE_TESTS, message)) === true);
497
633
  }
@@ -5,6 +5,7 @@ export type ValueFacts = {
5
5
  readonly format?: string;
6
6
  readonly values?: readonly unknown[];
7
7
  readonly reference?: readonly string[];
8
+ readonly crossRoom?: true;
8
9
  readonly prose: boolean;
9
10
  readonly conditional?: true;
10
11
  readonly prefix?: readonly ValueFacts[];
@@ -29,12 +30,26 @@ export type Shape = {
29
30
  readonly schema: Readonly<Record<string, unknown>>;
30
31
  readonly defs: Readonly<Record<string, unknown>>;
31
32
  };
33
+ export type RuleValue = string | number | boolean | null;
34
+ export type Transition = {
35
+ readonly from: RuleValue;
36
+ readonly to: RuleValue;
37
+ readonly roles?: readonly string[];
38
+ };
39
+ export type FieldRules = {
40
+ readonly changeRoles?: readonly string[];
41
+ readonly initialRoles?: readonly string[];
42
+ readonly transitions?: readonly Transition[];
43
+ };
32
44
  export type Definition = {
33
45
  readonly name: string;
34
46
  readonly memberDocument: boolean;
35
47
  readonly frontmatter: ValueFacts;
36
48
  readonly fields: Readonly<Record<string, ValueFacts>>;
37
49
  readonly sections: Readonly<Record<string, SectionSpec>>;
50
+ readonly rules: Readonly<Record<string, FieldRules>>;
51
+ readonly createRoles?: readonly string[];
52
+ readonly deleteRoles?: readonly string[];
38
53
  readonly shape: Shape;
39
54
  };
40
55
  export type Failure = {
@@ -45,6 +60,7 @@ export declare const JSON_TYPES: readonly JsonType[];
45
60
  export declare const BUILT_IN_TYPE = "any";
46
61
  export declare const ATTACHMENT = "attachment";
47
62
  export declare const ARRAY_INDEX: RegExp;
63
+ export declare const JSON_POINTER: RegExp;
48
64
  export declare function escapePointer(key: string): string;
49
65
  export declare function pointerSegments(pointer: string): string[];
50
66
  export declare function refTarget(reference: string, defs: Readonly<Record<string, unknown>>): {
@@ -62,5 +78,5 @@ export type PointerFacts = {
62
78
  export declare function crossedFacts(facts: ValueFacts): ValueFacts[];
63
79
  export declare function fieldFacts(definition: Definition, key: string): ValueFacts | undefined;
64
80
  export declare function pointerFacts(definition: Definition, pointer: string): PointerFacts | undefined;
65
- export declare function readSchema(text: string): VerifiedModel | Failure;
81
+ export declare function readSchema(text: string, provided?: VerifiedModel): VerifiedModel | Failure;
66
82
  //# sourceMappingURL=definition.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}