@agentshouse/mdmodel 0.1.0-ccf1367190878 → 0.1.0-cdbd463e01dc2

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 (135) hide show
  1. package/API.md +197 -178
  2. package/README.md +21 -22
  3. package/dist/blocks.d.ts.map +1 -1
  4. package/dist/blocks.js +35 -20
  5. package/dist/definition.d.ts +3 -1
  6. package/dist/definition.d.ts.map +1 -1
  7. package/dist/definition.js +112 -24
  8. package/dist/divide.d.ts.map +1 -1
  9. package/dist/divide.js +27 -17
  10. package/dist/document.d.ts +5 -5
  11. package/dist/document.d.ts.map +1 -1
  12. package/dist/document.js +304 -187
  13. package/dist/event.d.ts +78 -0
  14. package/dist/event.d.ts.map +1 -0
  15. package/dist/event.js +230 -0
  16. package/dist/facts.d.ts +15 -0
  17. package/dist/facts.d.ts.map +1 -0
  18. package/dist/facts.js +39 -0
  19. package/dist/index.d.ts +22 -8
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +13 -6
  22. package/dist/kinds.d.ts +19 -0
  23. package/dist/kinds.d.ts.map +1 -0
  24. package/dist/kinds.js +161 -0
  25. package/dist/links.d.ts +2 -0
  26. package/dist/links.d.ts.map +1 -1
  27. package/dist/links.js +107 -50
  28. package/dist/paths.d.ts +9 -1
  29. package/dist/paths.d.ts.map +1 -1
  30. package/dist/paths.js +28 -2
  31. package/dist/pattern.d.ts +10 -0
  32. package/dist/pattern.d.ts.map +1 -0
  33. package/dist/pattern.js +355 -0
  34. package/dist/project.d.ts +1 -0
  35. package/dist/project.d.ts.map +1 -1
  36. package/dist/project.js +38 -15
  37. package/dist/query/language.d.ts +223 -0
  38. package/dist/query/language.d.ts.map +1 -0
  39. package/dist/query/language.js +565 -0
  40. package/dist/query/match.d.ts +14 -0
  41. package/dist/query/match.d.ts.map +1 -0
  42. package/dist/query/match.js +121 -0
  43. package/dist/query/rows.d.ts +32 -0
  44. package/dist/query/rows.d.ts.map +1 -0
  45. package/dist/query/rows.js +161 -0
  46. package/dist/query/sql.d.ts +39 -0
  47. package/dist/query/sql.d.ts.map +1 -0
  48. package/dist/query/sql.js +279 -0
  49. package/dist/references.d.ts.map +1 -1
  50. package/dist/references.js +6 -1
  51. package/dist/reserved.d.ts +5 -0
  52. package/dist/reserved.d.ts.map +1 -0
  53. package/dist/reserved.js +20 -0
  54. package/dist/schema.d.ts +1 -0
  55. package/dist/schema.d.ts.map +1 -1
  56. package/dist/schema.js +55 -4
  57. package/dist/types.d.ts +35 -4
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/validate.d.ts +29 -4
  60. package/dist/validate.d.ts.map +1 -1
  61. package/dist/validate.js +301 -85
  62. package/dist/yaml.d.ts.map +1 -1
  63. package/dist/yaml.js +36 -3
  64. package/fixtures/README.md +26 -6
  65. package/fixtures/cases/conditional-section/context.json +1 -0
  66. package/fixtures/cases/conditional-section/expected.json +6 -0
  67. package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
  68. package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
  69. package/fixtures/cases/conditional-section/schema.yaml +14 -0
  70. package/fixtures/cases/cross-room-link/context.json +1 -0
  71. package/fixtures/cases/cross-room-link/expected.json +1 -0
  72. package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
  73. package/fixtures/cases/cross-room-link/schema.yaml +3 -0
  74. package/fixtures/cases/cross-room-reference/context.json +1 -0
  75. package/fixtures/cases/cross-room-reference/expected.json +1 -0
  76. package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
  77. package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
  78. package/fixtures/cases/link-into-a-reserved-name/context.json +1 -0
  79. package/fixtures/cases/link-into-a-reserved-name/expected.json +5 -0
  80. package/fixtures/cases/link-into-a-reserved-name/library/notes/a.md +6 -0
  81. package/fixtures/cases/link-into-a-reserved-name/schema.yaml +3 -0
  82. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/context.json +1 -0
  83. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/expected.json +5 -0
  84. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/library/notes/b.md +5 -0
  85. package/fixtures/cases/member-on-an-untyped-document/context.json +1 -0
  86. package/fixtures/cases/member-on-an-untyped-document/expected.json +6 -0
  87. package/fixtures/cases/member-on-an-untyped-document/library/note.md +4 -0
  88. package/fixtures/cases/member-on-another-type/context.json +1 -0
  89. package/fixtures/cases/member-on-another-type/expected.json +6 -0
  90. package/fixtures/cases/member-on-another-type/library/note.md +4 -0
  91. package/fixtures/cases/member-on-another-type/schema.yaml +7 -0
  92. package/fixtures/cases/reference-into-a-reserved-name/context.json +1 -0
  93. package/fixtures/cases/reference-into-a-reserved-name/expected.json +6 -0
  94. package/fixtures/cases/reference-into-a-reserved-name/library/notes/a.md +4 -0
  95. package/fixtures/cases/reference-into-a-reserved-name/library/settings/brief.md +1 -0
  96. package/fixtures/cases/reference-into-a-reserved-name/schema.yaml +3 -0
  97. package/fixtures/cases/room-md-declares-a-type/context.json +1 -0
  98. package/fixtures/cases/room-md-declares-a-type/expected.json +6 -0
  99. package/fixtures/cases/room-md-declares-a-type/library/ROOM.md +5 -0
  100. package/fixtures/cases/typed-path-names-another-type/context.json +11 -0
  101. package/fixtures/cases/typed-path-names-another-type/expected.json +6 -0
  102. package/fixtures/cases/typed-path-names-another-type/library/settings/prefs/one.md +3 -0
  103. package/fixtures/cases/typed-path-names-another-type/schema.yaml +6 -0
  104. package/fixtures/cases/typed-path-names-its-type/context.json +11 -0
  105. package/fixtures/cases/typed-path-names-its-type/expected.json +3 -0
  106. package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/deeper/two.md +1 -0
  107. package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/one.md +4 -0
  108. package/fixtures/cases/typed-path-names-its-type/schema.yaml +6 -0
  109. package/fixtures/cases/typed-path-names-no-type/context.json +11 -0
  110. package/fixtures/cases/typed-path-names-no-type/expected.json +6 -0
  111. package/fixtures/cases/typed-path-names-no-type/library/settings/prefs/one.md +1 -0
  112. package/fixtures/cases/typed-path-names-no-type/schema.yaml +6 -0
  113. package/fixtures/cases/unnamed-typed-path-checks-its-fields/context.json +11 -0
  114. package/fixtures/cases/unnamed-typed-path-checks-its-fields/expected.json +6 -0
  115. package/fixtures/cases/unnamed-typed-path-checks-its-fields/library/rooms/team/tasks/plan.md +4 -0
  116. package/fixtures/cases/unnamed-typed-path-checks-its-fields/schema.yaml +5 -0
  117. package/fixtures/cases/unnamed-typed-path-names-a-type/context.json +11 -0
  118. package/fixtures/cases/unnamed-typed-path-names-a-type/expected.json +6 -0
  119. package/fixtures/cases/unnamed-typed-path-names-a-type/library/rooms/team/tasks/plan.md +6 -0
  120. package/fixtures/cases/unnamed-typed-path-names-a-type/schema.yaml +5 -0
  121. package/fixtures/cases/unnamed-typed-path-reads-its-type/context.json +11 -0
  122. package/fixtures/cases/unnamed-typed-path-reads-its-type/expected.json +3 -0
  123. package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/plan.md +1 -0
  124. package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/tasks/plan.md +5 -0
  125. package/fixtures/cases/unnamed-typed-path-reads-its-type/schema.yaml +5 -0
  126. package/fixtures/cases/unnamed-typed-path-without-a-body/context.json +11 -0
  127. package/fixtures/cases/unnamed-typed-path-without-a-body/expected.json +5 -0
  128. package/fixtures/cases/unnamed-typed-path-without-a-body/library/rooms/team/tasks/plan.md +5 -0
  129. package/fixtures/cases/unnamed-typed-path-without-a-body/schema.yaml +5 -0
  130. package/fixtures/division.json +26 -26
  131. package/fixtures/queries.json +913 -0
  132. package/package.json +7 -2
  133. package/dist/condition.d.ts +0 -149
  134. package/dist/condition.d.ts.map +0 -1
  135. package/dist/condition.js +0 -500
package/dist/links.js CHANGED
@@ -17,17 +17,28 @@ const HTML_TAG_LINE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\v\f]+[A-Za-z_:][A-Za-z0
17
17
  const ORDERED = /^(\d{1,9})[.)]/;
18
18
  const LABEL_LENGTH = 999;
19
19
  const PUNCTUATION = /^[!-/:-@[-`{-~]$/;
20
- const INLINE_RAW = new RegExp([
20
+ const INLINE_TAG = new RegExp([
21
21
  '<[A-Za-z][A-Za-z0-9-]*(?:[ \\t\\n\\v\\f\\r]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \\t\\n\\v\\f\\r]*=[ \\t\\n\\v\\f\\r]*(?:[^ \\t\\n\\v\\f\\r"\'=<>`]+|\'[^\']*\'|"[^"]*"))?)*[ \\t\\n\\v\\f\\r]*\\/?>',
22
22
  '<\\/[A-Za-z][A-Za-z0-9-]*[ \\t\\n\\v\\f\\r]*>',
23
23
  '<!--(?!-?>)(?:-?[^-])*-->',
24
- '<\\?[\\s\\S]*?\\?>',
25
- '<![A-Z]+[ \\t\\n\\v\\f\\r]+[^>]*>',
26
- '<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
24
+ ].join('|'), 'y');
25
+ const AUTOLINK = new RegExp([
27
26
  '<[A-Za-z][A-Za-z0-9+.-]{1,31}:[^\\x00-\\x20<>]*>',
28
27
  "<[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*>",
29
28
  ].join('|'), 'y');
30
- const DELIMITER_ROW = /^\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
29
+ const DECLARATION = /<![A-Z]+[ \t\n\v\f\r]/y;
30
+ const INSTRUCTION = '<?';
31
+ const CDATA = '<![CDATA[';
32
+ const BACKSLASH = 0x5c;
33
+ const BACKTICK = 0x60;
34
+ const LINE_FEED = 0x0a;
35
+ const CARRIAGE_RETURN = 0x0d;
36
+ const LESS_THAN = 0x3c;
37
+ const OPEN_BRACKET = 0x5b;
38
+ const CLOSE_BRACKET = 0x5d;
39
+ const EXCLAMATION = 0x21;
40
+ const OPEN_PAREN = 0x28;
41
+ const DELIMITER_ROW = /^\|?[ \t]*:?-+:?(?:[ \t]*\|[ \t]*:?-+:?)*(?:[ \t]*\|)?[ \t]*$/;
31
42
  const GAP = /^[ \t\v\f]+/;
32
43
  function endOfLine(text, from) {
33
44
  const nl = text.indexOf('\n', from);
@@ -155,28 +166,34 @@ function fenceSpan(text, line, open) {
155
166
  }
156
167
  return text.length;
157
168
  }
158
- function skipInlineCode(text, index, joins) {
169
+ function skipInlineCode(text, index, joins, unclosed) {
159
170
  let ticks = 0;
160
171
  while (text[index + ticks] === '`')
161
172
  ticks += 1;
173
+ if (index < unclosed.stop && (unclosed.runs.get(ticks) ?? -1) <= index)
174
+ return index + ticks;
175
+ const runs = new Map();
162
176
  let i = index + ticks;
163
177
  while (i < text.length) {
164
- const ch = text[i];
165
- if (ch === '`') {
178
+ const code = text.charCodeAt(i);
179
+ if (code === BACKTICK) {
166
180
  let run = 0;
167
- while (text[i + run] === '`')
181
+ while (text.charCodeAt(i + run) === BACKTICK)
168
182
  run += 1;
169
183
  if (run === ticks)
170
184
  return i + run;
185
+ runs.set(run, i);
171
186
  i += run;
172
187
  continue;
173
188
  }
174
- if (ch === '\r' && text[i + 1] !== '\n')
189
+ if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
175
190
  break;
176
- if (ch === '\n' && !joins.has(i))
191
+ if (code === LINE_FEED && !joins.has(i))
177
192
  break;
178
193
  i += 1;
179
194
  }
195
+ unclosed.stop = i;
196
+ unclosed.runs = runs;
180
197
  return index + ticks;
181
198
  }
182
199
  function skipLinkSpace(text, start) {
@@ -194,21 +211,21 @@ function skipInlineSpace(text, start, joins) {
194
211
  return afterIndent(text, readLine(text, i + 1, endOfLine(text, i + 1)));
195
212
  }
196
213
  function closeEnd(text, start, open, joins) {
197
- const close = open === '(' ? ')' : open;
214
+ const close = (open === '(' ? ')' : open).charCodeAt(0);
198
215
  let i = start;
199
216
  while (i < text.length) {
200
- const ch = text[i];
217
+ const code = text.charCodeAt(i);
201
218
  if (escapes(text, i)) {
202
219
  i += 2;
203
220
  continue;
204
221
  }
205
- if (ch === close)
222
+ if (code === close)
206
223
  return i + 1;
207
- if (open === '(' && ch === '(')
224
+ if (open === '(' && code === OPEN_PAREN)
208
225
  return null;
209
- if (ch === '\r' && text[i + 1] !== '\n')
226
+ if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
210
227
  return null;
211
- if (ch === '\n' && !joins.has(i))
228
+ if (code === LINE_FEED && !joins.has(i))
212
229
  return null;
213
230
  i += 1;
214
231
  }
@@ -505,23 +522,23 @@ function structure(text) {
505
522
  return { joins, raw };
506
523
  }
507
524
  export function escapes(text, index) {
508
- return text[index] === '\\' && PUNCTUATION.test(text[index + 1] ?? '');
525
+ return text.charCodeAt(index) === BACKSLASH && PUNCTUATION.test(text[index + 1] ?? '');
509
526
  }
510
527
  function referenceEnd(text, start, joins) {
511
528
  let i = start;
512
529
  while (i < text.length) {
513
- const ch = text[i];
530
+ const code = text.charCodeAt(i);
514
531
  if (escapes(text, i)) {
515
532
  i += 2;
516
533
  continue;
517
534
  }
518
- if (ch === ']')
535
+ if (code === CLOSE_BRACKET)
519
536
  return i + 1;
520
- if (ch === '[')
537
+ if (code === OPEN_BRACKET)
521
538
  return -1;
522
- if (ch === '\r' && text[i + 1] !== '\n')
539
+ if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
523
540
  return -1;
524
- if (ch === '\n' && !joins.has(i))
541
+ if (code === LINE_FEED && !joins.has(i))
525
542
  return -1;
526
543
  i += 1;
527
544
  }
@@ -641,12 +658,13 @@ function endsBlock(content) {
641
658
  }
642
659
  function scanBlocks(text) {
643
660
  const { joins, raw } = structure(text);
661
+ const rawEnd = spanCursor(raw);
644
662
  const definitions = new Map();
645
663
  const blocks = [];
646
664
  let fresh = 0;
647
665
  let i = 0;
648
666
  while (i < text.length) {
649
- const skip = spanEndAt(raw, i);
667
+ const skip = rawEnd(i);
650
668
  if (skip !== undefined) {
651
669
  i = skip;
652
670
  continue;
@@ -667,12 +685,14 @@ function scanBlocks(text) {
667
685
  }
668
686
  return { raw, definitions, blocks, joins };
669
687
  }
670
- function spanEndAt(spans, index) {
671
- for (const [start, end] of spans) {
672
- if (index >= start && index < end)
673
- return end;
674
- }
675
- return undefined;
688
+ export function spanCursor(spans) {
689
+ let next = 0;
690
+ return (index) => {
691
+ while (next < spans.length && spans[next][1] <= index)
692
+ next += 1;
693
+ const span = spans[next];
694
+ return span !== undefined && span[0] <= index ? span[1] : undefined;
695
+ };
676
696
  }
677
697
  export function fenceSpans(text) {
678
698
  const fences = [];
@@ -693,61 +713,95 @@ export function fenceSpans(text) {
693
713
  function paragraphEnd(text, from, joins) {
694
714
  let i = from;
695
715
  while (i < text.length) {
696
- if (text[i] === '\n' && !joins.has(i))
716
+ const code = text.charCodeAt(i);
717
+ if (code === LINE_FEED && !joins.has(i))
697
718
  return i;
698
- if (text[i] === '\r' && text[i + 1] !== '\n')
719
+ if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
699
720
  return i;
700
721
  i += 1;
701
722
  }
702
723
  return i;
703
724
  }
725
+ function closerAt(text, closer, from, closers) {
726
+ const held = closers.get(closer);
727
+ if (held !== undefined && from >= held[0] && (held[1] === -1 || from <= held[1]))
728
+ return held[1];
729
+ const at = text.indexOf(closer, from);
730
+ closers.set(closer, [from, at]);
731
+ return at;
732
+ }
733
+ function closedAfter(text, closer, from, closers) {
734
+ const at = closerAt(text, closer, from, closers);
735
+ return at === -1 ? -1 : at + closer.length;
736
+ }
737
+ function stuck(pattern, text, at) {
738
+ pattern.lastIndex = at;
739
+ return pattern.test(text) ? pattern.lastIndex : -1;
740
+ }
741
+ function markupEnd(text, at, closers) {
742
+ if (text.startsWith(INSTRUCTION, at))
743
+ return closedAfter(text, '?>', at + INSTRUCTION.length, closers);
744
+ if (text.startsWith(CDATA, at))
745
+ return closedAfter(text, ']]>', at + CDATA.length, closers);
746
+ const declared = stuck(DECLARATION, text, at);
747
+ if (declared !== -1)
748
+ return closedAfter(text, '>', declared, closers);
749
+ return stuck(INLINE_TAG, text, at);
750
+ }
751
+ function inlineRawEnd(text, at, closers) {
752
+ const end = markupEnd(text, at, closers);
753
+ return end === -1 ? stuck(AUTOLINK, text, at) : end;
754
+ }
704
755
  export function linkInventory(body) {
705
756
  const { raw, definitions, blocks, joins } = scanBlocks(body);
706
- const skipped = [...raw, ...blocks.map((block) => [block.start, block.end])];
757
+ const rawEnd = spanCursor(raw);
758
+ const blockEnd = spanCursor(blocks.map((block) => [block.start, block.end]));
707
759
  const uses = [];
708
760
  const openers = [];
709
- let paragraph = { start: 0, end: -1, text: '' };
761
+ const unclosed = { stop: 0, runs: new Map() };
762
+ let paragraph = { start: 0, end: -1, text: '', closers: new Map() };
710
763
  let i = 0;
711
764
  while (i < body.length) {
712
- const skipEnd = spanEndAt(skipped, i);
765
+ const skipEnd = rawEnd(i) ?? blockEnd(i);
713
766
  if (skipEnd !== undefined) {
714
767
  openers.length = 0;
715
768
  i = skipEnd;
716
769
  continue;
717
770
  }
718
- const ch = body[i];
771
+ const code = body.charCodeAt(i);
719
772
  if (escapes(body, i)) {
720
773
  i += 2;
721
774
  continue;
722
775
  }
723
- if (ch === '`') {
724
- i = skipInlineCode(body, i, joins);
776
+ if (code === BACKTICK) {
777
+ i = skipInlineCode(body, i, joins, unclosed);
725
778
  continue;
726
779
  }
727
- if (ch === '<') {
780
+ if (code === LESS_THAN) {
728
781
  if (i >= paragraph.end) {
729
782
  const end = paragraphEnd(body, i, joins);
730
- paragraph = { start: i, end, text: body.slice(i, end) };
783
+ paragraph = { start: i, end, text: body.slice(i, end), closers: new Map() };
731
784
  }
732
- INLINE_RAW.lastIndex = i - paragraph.start;
733
- const raw = INLINE_RAW.exec(paragraph.text);
734
- if (raw !== null) {
735
- i += raw[0].length;
785
+ const raw = inlineRawEnd(paragraph.text, i - paragraph.start, paragraph.closers);
786
+ if (raw !== -1) {
787
+ i = paragraph.start + raw;
736
788
  continue;
737
789
  }
738
790
  }
739
- if ((ch === '\n' && !joins.has(i)) || (ch === '\r' && body[i + 1] !== '\n'))
791
+ if ((code === LINE_FEED && !joins.has(i)) ||
792
+ (code === CARRIAGE_RETURN && body.charCodeAt(i + 1) !== LINE_FEED))
740
793
  openers.length = 0;
741
- if (ch === '[' || (ch === '!' && body[i + 1] === '[')) {
794
+ if (code === OPEN_BRACKET ||
795
+ (code === EXCLAMATION && body.charCodeAt(i + 1) === OPEN_BRACKET)) {
742
796
  const previous = openers.at(-1);
743
797
  if (previous !== undefined)
744
798
  previous.bracketAfter = true;
745
- const image = ch === '!';
799
+ const image = code === EXCLAMATION;
746
800
  openers.push({ at: image ? i + 1 : i, start: i, image, active: true, bracketAfter: false });
747
801
  i += image ? 2 : 1;
748
802
  continue;
749
803
  }
750
- if (ch === ']') {
804
+ if (code === CLOSE_BRACKET) {
751
805
  const opener = openers.pop();
752
806
  const use = opener?.active ? closeLink(body, opener, i, definitions, joins) : null;
753
807
  if (opener === undefined || use === null) {
@@ -766,9 +820,12 @@ export function linkInventory(body) {
766
820
  }
767
821
  return { uses, blocks };
768
822
  }
769
- export function hrefOccurrences(body) {
823
+ export function destinations(inventory) {
770
824
  const byStart = new Map();
771
- for (const use of linkInventory(body).uses)
825
+ for (const use of inventory.uses)
772
826
  byStart.set(use.destination.start, use.destination);
773
827
  return [...byStart.values()].sort((left, right) => left.start - right.start);
774
828
  }
829
+ export function hrefOccurrences(body) {
830
+ return destinations(linkInventory(body));
831
+ }
package/dist/paths.d.ts CHANGED
@@ -2,14 +2,22 @@ export declare function dirname(path: string): string;
2
2
  export declare function join(base: string, relative: string): string;
3
3
  export declare function normalize(path: string): string | null;
4
4
  export declare function destinationPath(href: string): string | null;
5
+ export type RoomTarget = {
6
+ readonly handle: string;
7
+ readonly path: string;
8
+ };
5
9
  export declare function classifyHref(from: string, href: string): {
6
10
  kind: 'skip';
7
11
  } | {
8
12
  kind: 'path';
9
13
  path: string;
10
- } | {
14
+ } | ({
15
+ kind: 'room';
16
+ } & RoomTarget) | {
11
17
  kind: 'invalid';
12
18
  };
19
+ export declare function roomTarget(href: string): RoomTarget | null;
20
+ export declare function roomPath(href: string): string | null;
13
21
  export declare function target(from: string, href: string): string | null;
14
22
  export declare function retarget(href: string, to: string): string;
15
23
  export declare function relative(from: string, target: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAoDD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAgBD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CASzE;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAwDD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAgBD,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAEV;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAatB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAG1D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvE"}
package/dist/paths.js CHANGED
@@ -61,7 +61,10 @@ function located(href) {
61
61
  const written = href.trim();
62
62
  const { base, suffix } = unescaped(written);
63
63
  const url = base.replace(/[\t\n\r]/g, '').replace(/^[\u0000-\u0020]+/, '');
64
- return { base: suffix === written.length ? url.replace(/[\u0000-\u0020]+$/, '') : url, suffix };
64
+ return {
65
+ base: suffix === written.length ? url.replace(/(?<![\u0000-\u0020])[\u0000-\u0020]+$/, '') : url,
66
+ suffix,
67
+ };
65
68
  }
66
69
  const ENCODED = /(?:%[0-9a-fA-F]{2})+/g;
67
70
  function decodedRun(run) {
@@ -104,6 +107,17 @@ function written(path) {
104
107
  }
105
108
  return text;
106
109
  }
110
+ function roomTargetOf(path) {
111
+ if (!path.startsWith(SHELL_ROOMS))
112
+ return null;
113
+ const rest = path.slice(SHELL_ROOMS.length);
114
+ const slash = rest.indexOf('/');
115
+ const handle = rest.slice(0, slash);
116
+ if (slash <= 0 || handle === '.' || handle === '..')
117
+ return null;
118
+ const within = normalize(rest.slice(slash + 1));
119
+ return within === null || within === '' ? null : { handle, path: within };
120
+ }
107
121
  export function classifyHref(from, href) {
108
122
  const base = located(href).base;
109
123
  if (base === '')
@@ -111,13 +125,25 @@ export function classifyHref(from, href) {
111
125
  if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(base))
112
126
  return { kind: 'skip' };
113
127
  const path = destinationPath(href);
114
- if (path === null || path.startsWith('/'))
128
+ if (path === null)
115
129
  return { kind: 'invalid' };
130
+ if (path.startsWith('/')) {
131
+ const room = roomTargetOf(path);
132
+ return room === null ? { kind: 'invalid' } : { kind: 'room', ...room };
133
+ }
116
134
  const resolved = normalize(join(dirname(from), path));
117
135
  if (resolved === null || resolved === '')
118
136
  return { kind: 'invalid' };
119
137
  return { kind: 'path', path: resolved };
120
138
  }
139
+ export function roomTarget(href) {
140
+ const path = destinationPath(href);
141
+ return path === null ? null : roomTargetOf(path);
142
+ }
143
+ export function roomPath(href) {
144
+ const room = roomTarget(href);
145
+ return room === null ? null : `${SHELL_ROOMS}${room.handle}/${room.path}`;
146
+ }
121
147
  export function target(from, href) {
122
148
  const resolved = classifyHref(from, href);
123
149
  return resolved.kind === 'path' ? resolved.path : null;
@@ -0,0 +1,10 @@
1
+ export declare const PATTERN_STATES = 1000;
2
+ export declare class PatternTooCostly extends Error {
3
+ }
4
+ export type Pattern = {
5
+ readonly test: (text: string) => boolean;
6
+ };
7
+ export declare function linearPattern(source: string): Pattern | null;
8
+ export declare function withLinearRegExp<T>(run: () => T): T;
9
+ export declare function openPatternBudget(): () => void;
10
+ //# sourceMappingURL=pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../src/pattern.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,OAAQ,CAAC;AAMpC,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AAQ9C,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,CAAC;AAiUnE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAM5D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAkBnD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CAM9C"}