@agentshouse/mdmodel 0.1.0-c64dbada0730d → 0.1.0-c679f403bf3fb
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 +230 -216
- package/README.md +15 -18
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +7 -14
- package/dist/condition.d.ts +21 -8
- package/dist/condition.d.ts.map +1 -1
- package/dist/condition.js +208 -89
- package/dist/definition.d.ts +16 -1
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +255 -29
- 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 +315 -167
- 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 +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/links.d.ts +3 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +66 -40
- package/dist/paths.d.ts +10 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +115 -12
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +38 -15
- package/dist/references.d.ts +2 -2
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +6 -1
- package/dist/schema.js +2 -2
- package/dist/types.d.ts +49 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +30 -2
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +290 -115
- package/dist/yaml.d.ts +7 -3
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +72 -43
- package/fixtures/README.md +6 -5
- 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/division.json +26 -26
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
export { dated, factKind, facts, fires, holds, instant, itemFires, pointed, prosePaths, WRITE_DOORS, } from './condition.js';
|
|
1
|
+
export { ACTOR_PATHS, actorOperators, changeFields, CONDITION_OPERATORS, dated, datePointers, DOCUMENT_PATHS, factKind, facts, fires, holds, instant, ITEM_PATHS, itemFires, itemKind, itemOperators, memberPointers, members, pointed, prosePaths, testOperators, valuedChange, WRITE_DOORS, } from './condition.js';
|
|
2
|
+
export { headingLines } from './blocks.js';
|
|
2
3
|
export { divide } from './divide.js';
|
|
3
|
-
export { apply, bodyLinks, links, parse, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
4
|
-
export { MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD } from './fields.js';
|
|
5
|
-
export { relative, retarget, target } from './paths.js';
|
|
4
|
+
export { apply, bodyLinks, links, parse, parseFrontmatter, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
5
|
+
export { HOUSE_FIELDS, MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD, TYPE_FIELD } from './fields.js';
|
|
6
|
+
export { relative, retarget, roomPath, roomTarget, target } from './paths.js';
|
|
6
7
|
export { MARKDOWN_SYNTAX_PROFILE } from './profile.js';
|
|
7
8
|
export { project } from './project.js';
|
|
8
9
|
export { references } from './references.js';
|
|
9
10
|
export { ARRAY_INDEX, ATTACHMENT, crossedFacts, escapePointer, itemFacts, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
10
|
-
export { validate, verify } from './validate.js';
|
|
11
|
+
export { assess, bodyRoomLinks, checkDocument, resolves, roomReferences, sectionReferences, validate, validating, verdicts, verify, } from './validate.js';
|
|
11
12
|
export { VERSION } from './version.js';
|
|
13
|
+
export { bodyAfterFrontmatter, equalValue, frontmatterValue } from './yaml.js';
|
package/dist/links.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare function escapes(text: string, index: number): boolean;
|
|
2
|
+
export declare function spanCursor(spans: readonly (readonly [number, number])[]): (index: number) => number | undefined;
|
|
1
3
|
export type HrefOccurrence = {
|
|
2
4
|
readonly href: string;
|
|
3
5
|
readonly start: number;
|
|
@@ -22,5 +24,6 @@ export type LinkInventory = {
|
|
|
22
24
|
};
|
|
23
25
|
export declare function fenceSpans(text: string): readonly (readonly [number, number])[];
|
|
24
26
|
export declare function linkInventory(body: string): LinkInventory;
|
|
27
|
+
export declare function destinations(inventory: LinkInventory): readonly HrefOccurrence[];
|
|
25
28
|
export declare function hrefOccurrences(body: string): readonly HrefOccurrence[];
|
|
26
29
|
//# sourceMappingURL=links.d.ts.map
|
package/dist/links.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AA2hBA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAyLD,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAC5C,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAOvC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAe/E;AAaD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAoEzD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,aAAa,GAAG,SAAS,cAAc,EAAE,CAIhF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAEvE"}
|
package/dist/links.js
CHANGED
|
@@ -27,6 +27,15 @@ const INLINE_RAW = new RegExp([
|
|
|
27
27
|
'<[A-Za-z][A-Za-z0-9+.-]{1,31}:[^\\x00-\\x20<>]*>',
|
|
28
28
|
"<[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
29
|
].join('|'), 'y');
|
|
30
|
+
const BACKSLASH = 0x5c;
|
|
31
|
+
const BACKTICK = 0x60;
|
|
32
|
+
const LINE_FEED = 0x0a;
|
|
33
|
+
const CARRIAGE_RETURN = 0x0d;
|
|
34
|
+
const LESS_THAN = 0x3c;
|
|
35
|
+
const OPEN_BRACKET = 0x5b;
|
|
36
|
+
const CLOSE_BRACKET = 0x5d;
|
|
37
|
+
const EXCLAMATION = 0x21;
|
|
38
|
+
const OPEN_PAREN = 0x28;
|
|
30
39
|
const DELIMITER_ROW = /^\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
|
|
31
40
|
const GAP = /^[ \t\v\f]+/;
|
|
32
41
|
function endOfLine(text, from) {
|
|
@@ -155,28 +164,34 @@ function fenceSpan(text, line, open) {
|
|
|
155
164
|
}
|
|
156
165
|
return text.length;
|
|
157
166
|
}
|
|
158
|
-
function skipInlineCode(text, index, joins) {
|
|
167
|
+
function skipInlineCode(text, index, joins, unclosed) {
|
|
159
168
|
let ticks = 0;
|
|
160
169
|
while (text[index + ticks] === '`')
|
|
161
170
|
ticks += 1;
|
|
171
|
+
if (index < unclosed.stop && (unclosed.runs.get(ticks) ?? -1) <= index)
|
|
172
|
+
return index + ticks;
|
|
173
|
+
const runs = new Map();
|
|
162
174
|
let i = index + ticks;
|
|
163
175
|
while (i < text.length) {
|
|
164
|
-
const
|
|
165
|
-
if (
|
|
176
|
+
const code = text.charCodeAt(i);
|
|
177
|
+
if (code === BACKTICK) {
|
|
166
178
|
let run = 0;
|
|
167
|
-
while (text
|
|
179
|
+
while (text.charCodeAt(i + run) === BACKTICK)
|
|
168
180
|
run += 1;
|
|
169
181
|
if (run === ticks)
|
|
170
182
|
return i + run;
|
|
183
|
+
runs.set(run, i);
|
|
171
184
|
i += run;
|
|
172
185
|
continue;
|
|
173
186
|
}
|
|
174
|
-
if (
|
|
187
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
175
188
|
break;
|
|
176
|
-
if (
|
|
189
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
177
190
|
break;
|
|
178
191
|
i += 1;
|
|
179
192
|
}
|
|
193
|
+
unclosed.stop = i;
|
|
194
|
+
unclosed.runs = runs;
|
|
180
195
|
return index + ticks;
|
|
181
196
|
}
|
|
182
197
|
function skipLinkSpace(text, start) {
|
|
@@ -194,21 +209,21 @@ function skipInlineSpace(text, start, joins) {
|
|
|
194
209
|
return afterIndent(text, readLine(text, i + 1, endOfLine(text, i + 1)));
|
|
195
210
|
}
|
|
196
211
|
function closeEnd(text, start, open, joins) {
|
|
197
|
-
const close = open === '(' ? ')' : open;
|
|
212
|
+
const close = (open === '(' ? ')' : open).charCodeAt(0);
|
|
198
213
|
let i = start;
|
|
199
214
|
while (i < text.length) {
|
|
200
|
-
const
|
|
215
|
+
const code = text.charCodeAt(i);
|
|
201
216
|
if (escapes(text, i)) {
|
|
202
217
|
i += 2;
|
|
203
218
|
continue;
|
|
204
219
|
}
|
|
205
|
-
if (
|
|
220
|
+
if (code === close)
|
|
206
221
|
return i + 1;
|
|
207
|
-
if (open === '(' &&
|
|
222
|
+
if (open === '(' && code === OPEN_PAREN)
|
|
208
223
|
return null;
|
|
209
|
-
if (
|
|
224
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
210
225
|
return null;
|
|
211
|
-
if (
|
|
226
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
212
227
|
return null;
|
|
213
228
|
i += 1;
|
|
214
229
|
}
|
|
@@ -504,24 +519,24 @@ function structure(text) {
|
|
|
504
519
|
}
|
|
505
520
|
return { joins, raw };
|
|
506
521
|
}
|
|
507
|
-
function escapes(text, index) {
|
|
508
|
-
return text
|
|
522
|
+
export function escapes(text, index) {
|
|
523
|
+
return text.charCodeAt(index) === BACKSLASH && PUNCTUATION.test(text[index + 1] ?? '');
|
|
509
524
|
}
|
|
510
525
|
function referenceEnd(text, start, joins) {
|
|
511
526
|
let i = start;
|
|
512
527
|
while (i < text.length) {
|
|
513
|
-
const
|
|
528
|
+
const code = text.charCodeAt(i);
|
|
514
529
|
if (escapes(text, i)) {
|
|
515
530
|
i += 2;
|
|
516
531
|
continue;
|
|
517
532
|
}
|
|
518
|
-
if (
|
|
533
|
+
if (code === CLOSE_BRACKET)
|
|
519
534
|
return i + 1;
|
|
520
|
-
if (
|
|
535
|
+
if (code === OPEN_BRACKET)
|
|
521
536
|
return -1;
|
|
522
|
-
if (
|
|
537
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
523
538
|
return -1;
|
|
524
|
-
if (
|
|
539
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
525
540
|
return -1;
|
|
526
541
|
i += 1;
|
|
527
542
|
}
|
|
@@ -641,12 +656,13 @@ function endsBlock(content) {
|
|
|
641
656
|
}
|
|
642
657
|
function scanBlocks(text) {
|
|
643
658
|
const { joins, raw } = structure(text);
|
|
659
|
+
const rawEnd = spanCursor(raw);
|
|
644
660
|
const definitions = new Map();
|
|
645
661
|
const blocks = [];
|
|
646
662
|
let fresh = 0;
|
|
647
663
|
let i = 0;
|
|
648
664
|
while (i < text.length) {
|
|
649
|
-
const skip =
|
|
665
|
+
const skip = rawEnd(i);
|
|
650
666
|
if (skip !== undefined) {
|
|
651
667
|
i = skip;
|
|
652
668
|
continue;
|
|
@@ -667,12 +683,14 @@ function scanBlocks(text) {
|
|
|
667
683
|
}
|
|
668
684
|
return { raw, definitions, blocks, joins };
|
|
669
685
|
}
|
|
670
|
-
function
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
686
|
+
export function spanCursor(spans) {
|
|
687
|
+
let next = 0;
|
|
688
|
+
return (index) => {
|
|
689
|
+
while (next < spans.length && spans[next][1] <= index)
|
|
690
|
+
next += 1;
|
|
691
|
+
const span = spans[next];
|
|
692
|
+
return span !== undefined && span[0] <= index ? span[1] : undefined;
|
|
693
|
+
};
|
|
676
694
|
}
|
|
677
695
|
export function fenceSpans(text) {
|
|
678
696
|
const fences = [];
|
|
@@ -693,9 +711,10 @@ export function fenceSpans(text) {
|
|
|
693
711
|
function paragraphEnd(text, from, joins) {
|
|
694
712
|
let i = from;
|
|
695
713
|
while (i < text.length) {
|
|
696
|
-
|
|
714
|
+
const code = text.charCodeAt(i);
|
|
715
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
697
716
|
return i;
|
|
698
|
-
if (
|
|
717
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
699
718
|
return i;
|
|
700
719
|
i += 1;
|
|
701
720
|
}
|
|
@@ -703,28 +722,30 @@ function paragraphEnd(text, from, joins) {
|
|
|
703
722
|
}
|
|
704
723
|
export function linkInventory(body) {
|
|
705
724
|
const { raw, definitions, blocks, joins } = scanBlocks(body);
|
|
706
|
-
const
|
|
725
|
+
const rawEnd = spanCursor(raw);
|
|
726
|
+
const blockEnd = spanCursor(blocks.map((block) => [block.start, block.end]));
|
|
707
727
|
const uses = [];
|
|
708
728
|
const openers = [];
|
|
729
|
+
const unclosed = { stop: 0, runs: new Map() };
|
|
709
730
|
let paragraph = { start: 0, end: -1, text: '' };
|
|
710
731
|
let i = 0;
|
|
711
732
|
while (i < body.length) {
|
|
712
|
-
const skipEnd =
|
|
733
|
+
const skipEnd = rawEnd(i) ?? blockEnd(i);
|
|
713
734
|
if (skipEnd !== undefined) {
|
|
714
735
|
openers.length = 0;
|
|
715
736
|
i = skipEnd;
|
|
716
737
|
continue;
|
|
717
738
|
}
|
|
718
|
-
const
|
|
739
|
+
const code = body.charCodeAt(i);
|
|
719
740
|
if (escapes(body, i)) {
|
|
720
741
|
i += 2;
|
|
721
742
|
continue;
|
|
722
743
|
}
|
|
723
|
-
if (
|
|
724
|
-
i = skipInlineCode(body, i, joins);
|
|
744
|
+
if (code === BACKTICK) {
|
|
745
|
+
i = skipInlineCode(body, i, joins, unclosed);
|
|
725
746
|
continue;
|
|
726
747
|
}
|
|
727
|
-
if (
|
|
748
|
+
if (code === LESS_THAN) {
|
|
728
749
|
if (i >= paragraph.end) {
|
|
729
750
|
const end = paragraphEnd(body, i, joins);
|
|
730
751
|
paragraph = { start: i, end, text: body.slice(i, end) };
|
|
@@ -736,18 +757,20 @@ export function linkInventory(body) {
|
|
|
736
757
|
continue;
|
|
737
758
|
}
|
|
738
759
|
}
|
|
739
|
-
if ((
|
|
760
|
+
if ((code === LINE_FEED && !joins.has(i)) ||
|
|
761
|
+
(code === CARRIAGE_RETURN && body.charCodeAt(i + 1) !== LINE_FEED))
|
|
740
762
|
openers.length = 0;
|
|
741
|
-
if (
|
|
763
|
+
if (code === OPEN_BRACKET ||
|
|
764
|
+
(code === EXCLAMATION && body.charCodeAt(i + 1) === OPEN_BRACKET)) {
|
|
742
765
|
const previous = openers.at(-1);
|
|
743
766
|
if (previous !== undefined)
|
|
744
767
|
previous.bracketAfter = true;
|
|
745
|
-
const image =
|
|
768
|
+
const image = code === EXCLAMATION;
|
|
746
769
|
openers.push({ at: image ? i + 1 : i, start: i, image, active: true, bracketAfter: false });
|
|
747
770
|
i += image ? 2 : 1;
|
|
748
771
|
continue;
|
|
749
772
|
}
|
|
750
|
-
if (
|
|
773
|
+
if (code === CLOSE_BRACKET) {
|
|
751
774
|
const opener = openers.pop();
|
|
752
775
|
const use = opener?.active ? closeLink(body, opener, i, definitions, joins) : null;
|
|
753
776
|
if (opener === undefined || use === null) {
|
|
@@ -766,9 +789,12 @@ export function linkInventory(body) {
|
|
|
766
789
|
}
|
|
767
790
|
return { uses, blocks };
|
|
768
791
|
}
|
|
769
|
-
export function
|
|
792
|
+
export function destinations(inventory) {
|
|
770
793
|
const byStart = new Map();
|
|
771
|
-
for (const use of
|
|
794
|
+
for (const use of inventory.uses)
|
|
772
795
|
byStart.set(use.destination.start, use.destination);
|
|
773
796
|
return [...byStart.values()].sort((left, right) => left.start - right.start);
|
|
774
797
|
}
|
|
798
|
+
export function hrefOccurrences(body) {
|
|
799
|
+
return destinations(linkInventory(body));
|
|
800
|
+
}
|
package/dist/paths.d.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
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
|
+
export declare function destinationPath(href: string): string | null;
|
|
5
|
+
export type RoomTarget = {
|
|
6
|
+
readonly handle: string;
|
|
7
|
+
readonly path: string;
|
|
8
|
+
};
|
|
4
9
|
export declare function classifyHref(from: string, href: string): {
|
|
5
10
|
kind: 'skip';
|
|
6
11
|
} | {
|
|
7
12
|
kind: 'path';
|
|
8
13
|
path: string;
|
|
9
|
-
} | {
|
|
14
|
+
} | ({
|
|
15
|
+
kind: 'room';
|
|
16
|
+
} & RoomTarget) | {
|
|
10
17
|
kind: 'invalid';
|
|
11
18
|
};
|
|
19
|
+
export declare function roomTarget(href: string): RoomTarget | null;
|
|
20
|
+
export declare function roomPath(href: string): string | null;
|
|
12
21
|
export declare function target(from: string, href: string): string | null;
|
|
13
22
|
export declare function retarget(href: string, to: string): string;
|
|
14
23
|
export declare function relative(from: string, target: string): string;
|
package/dist/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"
|
|
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,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
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { decodeNamedCharacterReference } from 'decode-named-character-reference';
|
|
2
|
+
import { decodeNumericCharacterReference } from 'micromark-util-decode-numeric-character-reference';
|
|
3
|
+
import { escapes } from './links.js';
|
|
1
4
|
export function dirname(path) {
|
|
2
5
|
const index = path.lastIndexOf('/');
|
|
3
6
|
return index === -1 ? '' : path.slice(0, index);
|
|
@@ -22,30 +25,129 @@ export function normalize(path) {
|
|
|
22
25
|
}
|
|
23
26
|
return parts.join('/');
|
|
24
27
|
}
|
|
28
|
+
const REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([A-Za-z][A-Za-z0-9]{0,31}));/y;
|
|
29
|
+
const PERCENT = /^%[0-9a-fA-F]{2}/;
|
|
30
|
+
function referenceAt(text, at) {
|
|
31
|
+
REFERENCE.lastIndex = at;
|
|
32
|
+
const match = REFERENCE.exec(text);
|
|
33
|
+
if (match === null)
|
|
34
|
+
return null;
|
|
35
|
+
const [whole, hex, decimal, name] = match;
|
|
36
|
+
const end = at + whole.length;
|
|
37
|
+
if (name !== undefined) {
|
|
38
|
+
const decoded = decodeNamedCharacterReference(name);
|
|
39
|
+
return decoded === false ? null : { text: decoded, end };
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
text: decodeNumericCharacterReference(hex ?? decimal, hex === undefined ? 10 : 16),
|
|
43
|
+
end,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function unescaped(written) {
|
|
47
|
+
let base = '';
|
|
48
|
+
let i = 0;
|
|
49
|
+
while (i < written.length) {
|
|
50
|
+
const escaped = escapes(written, i);
|
|
51
|
+
const reference = escaped || written[i] !== '&' ? null : referenceAt(written, i);
|
|
52
|
+
const text = escaped ? written[i + 1] : (reference?.text ?? written[i]);
|
|
53
|
+
if (text.startsWith('?') || text.startsWith('#'))
|
|
54
|
+
return { base, suffix: i };
|
|
55
|
+
base += text;
|
|
56
|
+
i = escaped ? i + 2 : (reference?.end ?? i + 1);
|
|
57
|
+
}
|
|
58
|
+
return { base, suffix: written.length };
|
|
59
|
+
}
|
|
60
|
+
function located(href) {
|
|
61
|
+
const written = href.trim();
|
|
62
|
+
const { base, suffix } = unescaped(written);
|
|
63
|
+
const url = base.replace(/[\t\n\r]/g, '').replace(/^[\u0000-\u0020]+/, '');
|
|
64
|
+
return { base: suffix === written.length ? url.replace(/[\u0000-\u0020]+$/, '') : url, suffix };
|
|
65
|
+
}
|
|
66
|
+
const ENCODED = /(?:%[0-9a-fA-F]{2})+/g;
|
|
67
|
+
function decodedRun(run) {
|
|
68
|
+
try {
|
|
69
|
+
return decodeURIComponent(run);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function destinationPath(href) {
|
|
76
|
+
const base = located(href).base;
|
|
77
|
+
let path = '';
|
|
78
|
+
let cursor = 0;
|
|
79
|
+
for (const match of base.matchAll(ENCODED)) {
|
|
80
|
+
const decoded = decodedRun(match[0]);
|
|
81
|
+
if (decoded === null)
|
|
82
|
+
return null;
|
|
83
|
+
path += base.slice(cursor, match.index) + decoded;
|
|
84
|
+
cursor = match.index + match[0].length;
|
|
85
|
+
}
|
|
86
|
+
return path + base.slice(cursor);
|
|
87
|
+
}
|
|
88
|
+
function written(path) {
|
|
89
|
+
let text = '';
|
|
90
|
+
for (let i = 0; i < path.length; i += 1) {
|
|
91
|
+
const char = path[i];
|
|
92
|
+
if (char === '?' || char === '#' || char < ' ')
|
|
93
|
+
text += encodeURIComponent(char);
|
|
94
|
+
else if (char === ' ' && (i === 0 || i === path.length - 1))
|
|
95
|
+
text += '%20';
|
|
96
|
+
else if (char === '%' && PERCENT.test(path.slice(i)))
|
|
97
|
+
text += '%25';
|
|
98
|
+
else if (escapes(path, i))
|
|
99
|
+
text += '%5C';
|
|
100
|
+
else if (char === '&' && referenceAt(path, i) !== null)
|
|
101
|
+
text += '%26';
|
|
102
|
+
else
|
|
103
|
+
text += char;
|
|
104
|
+
}
|
|
105
|
+
return text;
|
|
106
|
+
}
|
|
107
|
+
function roomTargetOf(path) {
|
|
108
|
+
if (!path.startsWith(SHELL_ROOMS))
|
|
109
|
+
return null;
|
|
110
|
+
const rest = path.slice(SHELL_ROOMS.length);
|
|
111
|
+
const slash = rest.indexOf('/');
|
|
112
|
+
const handle = rest.slice(0, slash);
|
|
113
|
+
if (slash <= 0 || handle === '.' || handle === '..')
|
|
114
|
+
return null;
|
|
115
|
+
const within = normalize(rest.slice(slash + 1));
|
|
116
|
+
return within === null || within === '' ? null : { handle, path: within };
|
|
117
|
+
}
|
|
25
118
|
export function classifyHref(from, href) {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
119
|
+
const base = located(href).base;
|
|
120
|
+
if (base === '')
|
|
28
121
|
return { kind: 'skip' };
|
|
29
|
-
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(
|
|
122
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(base))
|
|
30
123
|
return { kind: 'skip' };
|
|
31
|
-
|
|
124
|
+
const path = destinationPath(href);
|
|
125
|
+
if (path === null)
|
|
32
126
|
return { kind: 'invalid' };
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return { kind: '
|
|
36
|
-
|
|
127
|
+
if (path.startsWith('/')) {
|
|
128
|
+
const room = roomTargetOf(path);
|
|
129
|
+
return room === null ? { kind: 'invalid' } : { kind: 'room', ...room };
|
|
130
|
+
}
|
|
131
|
+
const resolved = normalize(join(dirname(from), path));
|
|
37
132
|
if (resolved === null || resolved === '')
|
|
38
133
|
return { kind: 'invalid' };
|
|
39
134
|
return { kind: 'path', path: resolved };
|
|
40
135
|
}
|
|
136
|
+
export function roomTarget(href) {
|
|
137
|
+
const path = destinationPath(href);
|
|
138
|
+
return path === null ? null : roomTargetOf(path);
|
|
139
|
+
}
|
|
140
|
+
export function roomPath(href) {
|
|
141
|
+
const room = roomTarget(href);
|
|
142
|
+
return room === null ? null : `${SHELL_ROOMS}${room.handle}/${room.path}`;
|
|
143
|
+
}
|
|
41
144
|
export function target(from, href) {
|
|
42
145
|
const resolved = classifyHref(from, href);
|
|
43
146
|
return resolved.kind === 'path' ? resolved.path : null;
|
|
44
147
|
}
|
|
45
148
|
export function retarget(href, to) {
|
|
46
149
|
const trimmed = href.trim();
|
|
47
|
-
|
|
48
|
-
return match === null ? to : to + trimmed.slice(match.index);
|
|
150
|
+
return written(to) + trimmed.slice(unescaped(trimmed).suffix);
|
|
49
151
|
}
|
|
50
152
|
export function relative(from, target) {
|
|
51
153
|
const base = dirname(from)
|
|
@@ -62,8 +164,9 @@ export function relative(from, target) {
|
|
|
62
164
|
export const SHELL_ROOMS = '/rooms/';
|
|
63
165
|
export function shellTarget(href, handle) {
|
|
64
166
|
const prefix = `${SHELL_ROOMS}${handle}/`;
|
|
65
|
-
|
|
167
|
+
const decoded = destinationPath(href);
|
|
168
|
+
if (decoded === null || !decoded.startsWith(prefix))
|
|
66
169
|
return null;
|
|
67
|
-
const path = normalize(
|
|
170
|
+
const path = normalize(decoded.slice(prefix.length));
|
|
68
171
|
return path === null || path === '' ? null : path;
|
|
69
172
|
}
|
package/dist/project.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type InputResult = {
|
|
|
15
15
|
readonly ok: false;
|
|
16
16
|
readonly refusal: Refusal;
|
|
17
17
|
};
|
|
18
|
+
export declare function firstEditFrom(edits: readonly Edit[], start: number): number;
|
|
18
19
|
export declare function rangeText(content: string, range: Extent, edits: readonly Edit[]): string;
|
|
19
20
|
export declare function projectionInput(document: Document, file: string, context: ProjectionContext): InputResult;
|
|
20
21
|
export declare function project(document: Document, file: string, context?: ProjectionContext): Projection;
|
package/dist/project.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG3F,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC;AAEzB,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG3F,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC;AAEzB,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AA0CtD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAS3E;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,MAAM,CAWxF;AA4BD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,GACzB,WAAW,CA+Bb;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAA2C,GACnD,UAAU,CAMZ"}
|
package/dist/project.js
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
import { memberFacts } from './definition.js';
|
|
2
|
-
import { frontmatter } from './document.js';
|
|
3
|
-
import {
|
|
4
|
-
import { target } from './paths.js';
|
|
2
|
+
import { frontmatter, inventoryOf } from './document.js';
|
|
3
|
+
import { roomTarget, target } from './paths.js';
|
|
5
4
|
import { refusal } from './refuse.js';
|
|
6
5
|
import { headingSpans } from './sections.js';
|
|
7
6
|
import { bodyStartOf } from './yaml.js';
|
|
8
|
-
function internalEdits(content, bodyStart, file, documentTargets) {
|
|
9
|
-
const inventory = linkInventory(content.slice(bodyStart));
|
|
7
|
+
function internalEdits(content, inventory, bodyStart, file, documentTargets) {
|
|
10
8
|
const internal = new Set();
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
for (const use of uses) {
|
|
9
|
+
const uses = inventory.uses
|
|
10
|
+
.filter((use) => {
|
|
14
11
|
const resolved = target(file, use.destination.href);
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
return resolved === null
|
|
13
|
+
? roomTarget(use.destination.href) !== null
|
|
14
|
+
: documentTargets.has(resolved);
|
|
15
|
+
})
|
|
16
|
+
.sort((left, right) => left.start - right.start);
|
|
17
|
+
const edits = [];
|
|
18
|
+
for (let index = uses.length - 1; index >= 0; index -= 1) {
|
|
19
|
+
const use = uses[index];
|
|
17
20
|
internal.add(use.destination.start);
|
|
18
21
|
const label = { start: bodyStart + use.labelStart, end: bodyStart + use.labelEnd };
|
|
19
|
-
const inner =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
const inner = [];
|
|
23
|
+
for (let nested = index + 1; nested < uses.length; nested += 1) {
|
|
24
|
+
const edit = edits[uses.length - 1 - nested];
|
|
25
|
+
if (edit.start >= label.end)
|
|
26
|
+
break;
|
|
27
|
+
if (edit.start >= label.start && edit.end <= label.end)
|
|
28
|
+
inner.push(edit);
|
|
29
|
+
}
|
|
22
30
|
edits.push({
|
|
23
31
|
start: bodyStart + use.start,
|
|
24
32
|
end: bodyStart + use.end,
|
|
@@ -32,10 +40,25 @@ function internalEdits(content, bodyStart, file, documentTargets) {
|
|
|
32
40
|
}
|
|
33
41
|
return edits.sort((left, right) => left.start - right.start);
|
|
34
42
|
}
|
|
43
|
+
export function firstEditFrom(edits, start) {
|
|
44
|
+
let low = 0;
|
|
45
|
+
let high = edits.length;
|
|
46
|
+
while (low < high) {
|
|
47
|
+
const middle = (low + high) >>> 1;
|
|
48
|
+
if (edits[middle].start < start)
|
|
49
|
+
low = middle + 1;
|
|
50
|
+
else
|
|
51
|
+
high = middle;
|
|
52
|
+
}
|
|
53
|
+
return low;
|
|
54
|
+
}
|
|
35
55
|
export function rangeText(content, range, edits) {
|
|
36
56
|
let text = '';
|
|
37
57
|
let cursor = range.start;
|
|
38
|
-
for (
|
|
58
|
+
for (let index = firstEditFrom(edits, range.start); index < edits.length; index += 1) {
|
|
59
|
+
const edit = edits[index];
|
|
60
|
+
if (edit.start > range.end)
|
|
61
|
+
break;
|
|
39
62
|
if (edit.start < cursor || edit.end > range.end)
|
|
40
63
|
continue;
|
|
41
64
|
text += content.slice(cursor, edit.start) + edit.text;
|
|
@@ -73,7 +96,7 @@ function freeTextValues(definition, document) {
|
|
|
73
96
|
export function projectionInput(document, file, context) {
|
|
74
97
|
const content = document.content;
|
|
75
98
|
const bodyStart = bodyStartOf(content);
|
|
76
|
-
const edits = internalEdits(content, bodyStart, file, new Set(context.documentTargets));
|
|
99
|
+
const edits = internalEdits(content, inventoryOf(document), bodyStart, file, new Set(context.documentTargets));
|
|
77
100
|
const declared = document.type;
|
|
78
101
|
if (declared === undefined || declared === 'any') {
|
|
79
102
|
return {
|
package/dist/references.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type Definition } from './definition.js';
|
|
2
|
-
import type {
|
|
3
|
-
export declare function references(document:
|
|
2
|
+
import type { Frontmatter, Reference } from './types.js';
|
|
3
|
+
export declare function references(document: Pick<Frontmatter, 'fields'>, definition: Definition): readonly Reference[];
|
|
4
4
|
//# sourceMappingURL=references.d.ts.map
|
package/dist/references.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA8BzD,wBAAgB,UAAU,CACxB,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,SAAS,SAAS,EAAE,CAItB"}
|
package/dist/references.js
CHANGED
|
@@ -5,7 +5,12 @@ function collect(value, facts, pointer, found) {
|
|
|
5
5
|
return;
|
|
6
6
|
if (typeof value === 'string') {
|
|
7
7
|
if (facts.reference !== undefined)
|
|
8
|
-
found.push({
|
|
8
|
+
found.push({
|
|
9
|
+
pointer,
|
|
10
|
+
value,
|
|
11
|
+
to: facts.reference,
|
|
12
|
+
...(facts.crossRoom === true ? { crossRoom: true } : {}),
|
|
13
|
+
});
|
|
9
14
|
return;
|
|
10
15
|
}
|
|
11
16
|
if (Array.isArray(value)) {
|
package/dist/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Validator } from '@cfworker/json-schema';
|
|
2
2
|
import { escapePointer, refTarget } from './definition.js';
|
|
3
|
-
import { MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD } from './fields.js';
|
|
3
|
+
import { MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD, TYPE_FIELD } from './fields.js';
|
|
4
4
|
import { interpretPlain, isRecord } from './yaml.js';
|
|
5
5
|
const STANDING_MAPS = ['properties', 'patternProperties'];
|
|
6
6
|
const STANDING = [
|
|
@@ -101,7 +101,7 @@ function compile(definition) {
|
|
|
101
101
|
const closedDefs = mapped(defs, (held) => closed(held, true, defs));
|
|
102
102
|
const declared = isRecord(root.properties) ? root.properties : {};
|
|
103
103
|
const properties = {
|
|
104
|
-
|
|
104
|
+
[TYPE_FIELD]: true,
|
|
105
105
|
[SITE_FIELD]: true,
|
|
106
106
|
[RECEIVED_FIELD]: true,
|
|
107
107
|
...(definition.memberDocument ? { [MEMBER_FIELD]: { type: 'string' } } : {}),
|