@agentshouse/mdmodel 0.1.0-alpha.9 → 0.1.0-c83456e1cebfb

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 (202) hide show
  1. package/API.md +298 -0
  2. package/README.md +29 -186
  3. package/dist/blocks.d.ts +11 -0
  4. package/dist/blocks.d.ts.map +1 -0
  5. package/dist/blocks.js +62 -0
  6. package/dist/definition.d.ts +7 -3
  7. package/dist/definition.d.ts.map +1 -1
  8. package/dist/definition.js +143 -134
  9. package/dist/divide.d.ts +3 -0
  10. package/dist/divide.d.ts.map +1 -0
  11. package/dist/divide.js +310 -0
  12. package/dist/document.d.ts +2 -0
  13. package/dist/document.d.ts.map +1 -1
  14. package/dist/document.js +89 -120
  15. package/dist/fields.d.ts +4 -0
  16. package/dist/fields.d.ts.map +1 -0
  17. package/dist/fields.js +3 -0
  18. package/dist/index.d.ts +6 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +4 -3
  21. package/dist/links.d.ts +1 -0
  22. package/dist/links.d.ts.map +1 -1
  23. package/dist/links.js +618 -224
  24. package/dist/paths.d.ts +2 -3
  25. package/dist/paths.d.ts.map +1 -1
  26. package/dist/paths.js +27 -37
  27. package/dist/profile.js +1 -3
  28. package/dist/project.d.ts +19 -1
  29. package/dist/project.d.ts.map +1 -1
  30. package/dist/project.js +75 -91
  31. package/dist/refuse.d.ts.map +1 -1
  32. package/dist/refuse.js +2 -10
  33. package/dist/schema.d.ts +2 -1
  34. package/dist/schema.d.ts.map +1 -1
  35. package/dist/schema.js +22 -33
  36. package/dist/sections.d.ts +2 -1
  37. package/dist/sections.d.ts.map +1 -1
  38. package/dist/sections.js +44 -66
  39. package/dist/types.d.ts +30 -2
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/types.js +1 -3
  42. package/dist/validate.d.ts +3 -2
  43. package/dist/validate.d.ts.map +1 -1
  44. package/dist/validate.js +145 -127
  45. package/dist/version.d.ts +1 -1
  46. package/dist/version.d.ts.map +1 -1
  47. package/dist/version.js +1 -3
  48. package/dist/yaml.d.ts +1 -0
  49. package/dist/yaml.d.ts.map +1 -1
  50. package/dist/yaml.js +195 -186
  51. package/fixtures/README.md +77 -53
  52. package/fixtures/cases/binary-any-reference/expected.json +0 -1
  53. package/fixtures/cases/binary-any-reference/schema.yaml +4 -0
  54. package/fixtures/cases/binary-document-collision/expected.json +1 -2
  55. package/fixtures/cases/binary-document-collision/schema.yaml +2 -0
  56. package/fixtures/cases/binary-link-outside-collection/expected.json +1 -2
  57. package/fixtures/cases/binary-link-outside-collection/schema.yaml +2 -0
  58. package/fixtures/cases/binary-prototype-reference/expected.json +0 -1
  59. package/fixtures/cases/binary-prototype-reference/schema.yaml +4 -0
  60. package/fixtures/cases/binary-typed-reference/expected.json +0 -1
  61. package/fixtures/cases/binary-typed-reference/schema.yaml +5 -0
  62. package/fixtures/cases/bracketed-link-definition/schema.yaml +6 -0
  63. package/fixtures/cases/declared-binary-links/schema.yaml +2 -0
  64. package/fixtures/cases/duplicate-link-definition/schema.yaml +6 -0
  65. package/fixtures/cases/fenced-link-definition/schema.yaml +6 -0
  66. package/fixtures/cases/field-enum/expected.json +1 -2
  67. package/fixtures/cases/field-enum/schema.yaml +7 -0
  68. package/fixtures/cases/frontmatter-schema/expected.json +5 -0
  69. package/fixtures/cases/frontmatter-schema/schema.yaml +6 -0
  70. package/fixtures/cases/interrupted-link-definition/schema.yaml +2 -0
  71. package/fixtures/cases/long-fence-link-definition/schema.yaml +2 -0
  72. package/fixtures/cases/malformed-definition/expected.json +2 -4
  73. package/fixtures/cases/malformed-definition/schema.yaml +4 -0
  74. package/fixtures/cases/member-document/context.json +1 -0
  75. package/fixtures/cases/member-document/library/people/ana.md +5 -0
  76. package/fixtures/cases/member-document/schema.yaml +5 -0
  77. package/fixtures/cases/missing-binary-image/expected.json +1 -2
  78. package/fixtures/cases/missing-binary-image/schema.yaml +2 -0
  79. package/fixtures/cases/missing-binary-link/expected.json +1 -2
  80. package/fixtures/cases/missing-binary-link/schema.yaml +2 -0
  81. package/fixtures/cases/missing-required-field/expected.json +1 -2
  82. package/fixtures/cases/missing-required-field/schema.yaml +7 -0
  83. package/fixtures/cases/missing-section-item-kind/expected.json +2 -4
  84. package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -0
  85. package/fixtures/cases/paragraph-link-definition/schema.yaml +2 -0
  86. package/fixtures/cases/prototype-field/expected.json +1 -2
  87. package/fixtures/cases/prototype-field/schema.yaml +6 -0
  88. package/fixtures/cases/quoted-link-definition/expected.json +1 -2
  89. package/fixtures/cases/quoted-link-definition/schema.yaml +2 -0
  90. package/fixtures/cases/referenced-missing-file/expected.json +0 -1
  91. package/fixtures/cases/referenced-missing-file/schema.yaml +10 -0
  92. package/fixtures/cases/second-member-document/context.json +1 -0
  93. package/fixtures/cases/second-member-document/expected.json +5 -0
  94. package/fixtures/cases/second-member-document/schema.yaml +5 -0
  95. package/fixtures/cases/section-item-enum/context.json +1 -0
  96. package/fixtures/cases/section-item-enum/expected.json +6 -0
  97. package/fixtures/cases/section-item-enum/library/task.md +8 -0
  98. package/fixtures/cases/section-item-enum/schema.yaml +4 -0
  99. package/fixtures/cases/section-item-kind/context.json +1 -0
  100. package/fixtures/cases/section-item-kind/expected.json +6 -0
  101. package/fixtures/cases/section-item-kind/library/task.md +8 -0
  102. package/fixtures/cases/section-item-kind/schema.yaml +4 -0
  103. package/fixtures/cases/section-items/context.json +1 -0
  104. package/fixtures/cases/section-items/expected.json +1 -0
  105. package/fixtures/cases/section-items/library/other.md +3 -0
  106. package/fixtures/cases/section-items/library/page.md +28 -0
  107. package/fixtures/cases/section-items/schema.yaml +8 -0
  108. package/fixtures/cases/section-reference-path/context.json +1 -0
  109. package/fixtures/cases/section-reference-path/expected.json +6 -0
  110. package/fixtures/cases/section-reference-path/library/other.md +3 -0
  111. package/fixtures/cases/section-reference-path/library/page.md +7 -0
  112. package/fixtures/cases/section-reference-path/schema.yaml +4 -0
  113. package/fixtures/cases/section-reference-type/context.json +1 -0
  114. package/fixtures/cases/section-reference-type/expected.json +6 -0
  115. package/fixtures/cases/section-reference-type/library/note.md +1 -0
  116. package/fixtures/cases/section-reference-type/library/page.md +7 -0
  117. package/fixtures/cases/section-reference-type/schema.yaml +4 -0
  118. package/fixtures/cases/shortcut-reference-link/context.json +1 -0
  119. package/fixtures/cases/shortcut-reference-link/expected.json +5 -0
  120. package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
  121. package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
  122. package/fixtures/cases/structured-section/expected.json +1 -2
  123. package/fixtures/cases/structured-section/schema.yaml +7 -0
  124. package/fixtures/cases/submission-keys/context.json +1 -0
  125. package/fixtures/cases/submission-keys/expected.json +1 -0
  126. package/fixtures/cases/submission-keys/library/notes/visitor.md +8 -0
  127. package/fixtures/cases/submission-keys/schema.yaml +4 -0
  128. package/fixtures/cases/text-field-kind/context.json +1 -0
  129. package/fixtures/cases/text-field-kind/expected.json +6 -0
  130. package/fixtures/cases/text-field-kind/library/page.md +4 -0
  131. package/fixtures/cases/text-field-kind/schema.yaml +4 -0
  132. package/fixtures/cases/truncated-link-definition/expected.json +1 -2
  133. package/fixtures/cases/truncated-link-definition/schema.yaml +2 -0
  134. package/fixtures/cases/types-folder-content/context.json +1 -0
  135. package/fixtures/cases/types-folder-content/expected.json +1 -0
  136. package/fixtures/cases/types-folder-content/library/types/task.md +4 -0
  137. package/fixtures/cases/types-folder-content/schema.yaml +4 -0
  138. package/fixtures/cases/unclosed-frontmatter/expected.json +1 -2
  139. package/fixtures/cases/undeclared-field/expected.json +1 -2
  140. package/fixtures/cases/undeclared-field/schema.yaml +6 -0
  141. package/fixtures/cases/unknown-type/context.json +1 -0
  142. package/fixtures/cases/unknown-type/expected.json +6 -0
  143. package/fixtures/cases/unknown-type/library/item.md +3 -0
  144. package/fixtures/cases/unknown-type/schema.yaml +4 -0
  145. package/fixtures/cases/unlisted-reference-type/context.json +1 -0
  146. package/fixtures/cases/unlisted-reference-type/expected.json +5 -0
  147. package/fixtures/cases/unlisted-reference-type/schema.yaml +4 -0
  148. package/fixtures/cases/unresolved-link/expected.json +1 -2
  149. package/fixtures/cases/unresolved-link/schema.yaml +6 -0
  150. package/fixtures/cases/valid-typed-document/schema.yaml +15 -0
  151. package/fixtures/cases/wide-item-fence-link/schema.yaml +2 -0
  152. package/fixtures/division.json +409 -0
  153. package/fixtures/projection.json +58 -21
  154. package/package.json +3 -12
  155. package/dist/definition.js.map +0 -1
  156. package/dist/document.js.map +0 -1
  157. package/dist/index.js.map +0 -1
  158. package/dist/links.js.map +0 -1
  159. package/dist/paths.js.map +0 -1
  160. package/dist/profile.js.map +0 -1
  161. package/dist/project.js.map +0 -1
  162. package/dist/refuse.js.map +0 -1
  163. package/dist/schema.js.map +0 -1
  164. package/dist/sections.js.map +0 -1
  165. package/dist/types.js.map +0 -1
  166. package/dist/validate.js.map +0 -1
  167. package/dist/version.js.map +0 -1
  168. package/dist/yaml.js.map +0 -1
  169. package/fixtures/cases/binary-any-reference/library/types/note.md +0 -5
  170. package/fixtures/cases/binary-document-collision/library/types/note.md +0 -3
  171. package/fixtures/cases/binary-link-outside-collection/library/types/note.md +0 -3
  172. package/fixtures/cases/binary-prototype-reference/library/types/note.md +0 -5
  173. package/fixtures/cases/binary-typed-reference/library/types/note.md +0 -5
  174. package/fixtures/cases/binary-typed-reference/library/types/person.md +0 -3
  175. package/fixtures/cases/bracketed-link-definition/library/types/task.md +0 -7
  176. package/fixtures/cases/declared-binary-links/library/types/note.md +0 -3
  177. package/fixtures/cases/duplicate-link-definition/library/types/task.md +0 -7
  178. package/fixtures/cases/fenced-link-definition/library/types/task.md +0 -7
  179. package/fixtures/cases/field-enum/library/types/task.md +0 -8
  180. package/fixtures/cases/interrupted-link-definition/library/types/note.md +0 -3
  181. package/fixtures/cases/long-fence-link-definition/library/types/note.md +0 -3
  182. package/fixtures/cases/malformed-definition/library/types/task.md +0 -5
  183. package/fixtures/cases/missing-binary-image/library/types/note.md +0 -3
  184. package/fixtures/cases/missing-binary-link/library/types/note.md +0 -3
  185. package/fixtures/cases/missing-required-field/library/types/task.md +0 -8
  186. package/fixtures/cases/missing-section-item-kind/library/types/task.md +0 -7
  187. package/fixtures/cases/paragraph-link-definition/library/types/note.md +0 -3
  188. package/fixtures/cases/prd-definition/library/types/task.md +0 -16
  189. package/fixtures/cases/prototype-field/library/types/task.md +0 -7
  190. package/fixtures/cases/quoted-link-definition/library/types/note.md +0 -3
  191. package/fixtures/cases/referenced-missing-file/library/types/person.md +0 -5
  192. package/fixtures/cases/referenced-missing-file/library/types/task.md +0 -8
  193. package/fixtures/cases/structured-section/library/types/task.md +0 -8
  194. package/fixtures/cases/truncated-link-definition/library/types/note.md +0 -3
  195. package/fixtures/cases/undeclared-field/library/types/task.md +0 -7
  196. package/fixtures/cases/unresolved-link/library/types/task.md +0 -7
  197. package/fixtures/cases/valid-typed-document/library/types/person.md +0 -5
  198. package/fixtures/cases/valid-typed-document/library/types/task.md +0 -13
  199. package/fixtures/cases/wide-item-fence-link/library/types/note.md +0 -3
  200. package/markdown-syntax-profile.md +0 -9
  201. /package/fixtures/cases/{prd-definition → frontmatter-schema}/context.json +0 -0
  202. /package/fixtures/cases/{prd-definition → member-document}/expected.json +0 -0
package/dist/paths.d.ts CHANGED
@@ -1,9 +1,6 @@
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 isTypesPath(path: string): boolean;
5
- export declare function typeNameFromPath(path: string): string;
6
- export declare function hrefSuffix(href: string): string;
7
4
  export declare function classifyHref(from: string, href: string): {
8
5
  kind: 'skip';
9
6
  } | {
@@ -12,4 +9,6 @@ export declare function classifyHref(from: string, href: string): {
12
9
  } | {
13
10
  kind: 'invalid';
14
11
  };
12
+ export declare function target(from: string, href: string): string | null;
13
+ export declare function retarget(href: string, to: string): string;
15
14
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,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;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,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,CAUzE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,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;AAED,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,CAUzE;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,CAIzD"}
package/dist/paths.js CHANGED
@@ -3,15 +3,18 @@ export function dirname(path) {
3
3
  return index === -1 ? '' : path.slice(0, index);
4
4
  }
5
5
  export function join(base, relative) {
6
- if (base === '') return relative;
6
+ if (base === '')
7
+ return relative;
7
8
  return `${base}/${relative}`;
8
9
  }
9
10
  export function normalize(path) {
10
11
  const parts = [];
11
- for (const part of path.split('/')){
12
- if (part === '' || part === '.') continue;
12
+ for (const part of path.split('/')) {
13
+ if (part === '' || part === '.')
14
+ continue;
13
15
  if (part === '..') {
14
- if (parts.length === 0) return null;
16
+ if (parts.length === 0)
17
+ return null;
15
18
  parts.pop();
16
19
  continue;
17
20
  }
@@ -19,41 +22,28 @@ export function normalize(path) {
19
22
  }
20
23
  return parts.join('/');
21
24
  }
22
- export function isTypesPath(path) {
23
- return path === 'types' || path.startsWith('types/');
24
- }
25
- export function typeNameFromPath(path) {
26
- const base = path.slice(path.lastIndexOf('/') + 1);
27
- return base.endsWith('.md') ? base.slice(0, -3) : base;
28
- }
29
- export function hrefSuffix(href) {
30
- const trimmed = href.trim();
31
- const match = /[?#]/.exec(trimmed);
32
- return match === null ? '' : trimmed.slice(match.index);
33
- }
34
25
  export function classifyHref(from, href) {
35
26
  const trimmed = href.trim();
36
- if (trimmed === '' || trimmed.startsWith('#')) return {
37
- kind: 'skip'
38
- };
39
- if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) return {
40
- kind: 'skip'
41
- };
42
- if (trimmed.startsWith('/')) return {
43
- kind: 'invalid'
44
- };
27
+ if (trimmed === '' || trimmed.startsWith('#'))
28
+ return { kind: 'skip' };
29
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed))
30
+ return { kind: 'skip' };
31
+ if (trimmed.startsWith('/'))
32
+ return { kind: 'invalid' };
45
33
  const bare = trimmed.replace(/[?#].*$/, '');
46
- if (bare === '') return {
47
- kind: 'skip'
48
- };
34
+ if (bare === '')
35
+ return { kind: 'skip' };
49
36
  const resolved = normalize(join(dirname(from), bare));
50
- if (resolved === null || resolved === '') return {
51
- kind: 'invalid'
52
- };
53
- return {
54
- kind: 'path',
55
- path: resolved
56
- };
37
+ if (resolved === null || resolved === '')
38
+ return { kind: 'invalid' };
39
+ return { kind: 'path', path: resolved };
40
+ }
41
+ export function target(from, href) {
42
+ const resolved = classifyHref(from, href);
43
+ return resolved.kind === 'path' ? resolved.path : null;
44
+ }
45
+ export function retarget(href, to) {
46
+ const trimmed = href.trim();
47
+ const match = /[?#]/.exec(trimmed);
48
+ return match === null ? to : to + trimmed.slice(match.index);
57
49
  }
58
-
59
- //# sourceMappingURL=paths.js.map
package/dist/profile.js CHANGED
@@ -1,7 +1,5 @@
1
1
  export const MARKDOWN_SYNTAX_PROFILE = {
2
2
  name: 'GitHub Flavored Markdown',
3
3
  spec: '0.29',
4
- url: 'https://github.github.com/gfm/'
4
+ url: 'https://github.github.com/gfm/',
5
5
  };
6
-
7
- //# sourceMappingURL=profile.js.map
package/dist/project.d.ts CHANGED
@@ -1,3 +1,21 @@
1
- import type { Document, Projection, ProjectionContext } from './types.js';
1
+ import type { Document, Extent, Projection, ProjectionContext, Refusal } from './types.js';
2
+ export type Piece = Extent & {
3
+ readonly text: string;
4
+ };
5
+ export type Edit = Piece;
6
+ export type Input = {
7
+ readonly values: readonly Piece[];
8
+ readonly ranges: readonly Extent[];
9
+ readonly edits: readonly Edit[];
10
+ };
11
+ export type InputResult = {
12
+ readonly ok: true;
13
+ readonly input: Input;
14
+ } | {
15
+ readonly ok: false;
16
+ readonly refusal: Refusal;
17
+ };
18
+ export declare function rangeText(content: string, range: Extent, edits: readonly Edit[]): string;
19
+ export declare function projectionInput(document: Document, file: string, context: ProjectionContext): InputResult;
2
20
  export declare function project(document: Document, file: string, context?: ProjectionContext): Projection;
3
21
  //# sourceMappingURL=project.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAgE1E,wBAAgB,OAAO,CACrB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAA2C,GACnD,UAAU,CA2BZ"}
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;AAmCtD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,MAAM,CASxF;AA8BD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,GACzB,WAAW,CAyBb;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAA2C,GACnD,UAAU,CAMZ"}
package/dist/project.js CHANGED
@@ -1,122 +1,106 @@
1
- import { readDefinition } from './definition.js';
2
- import { parse } from './document.js';
1
+ import { frontmatter } from './document.js';
3
2
  import { linkInventory } from './links.js';
4
- import { classifyHref } from './paths.js';
3
+ import { target } from './paths.js';
5
4
  import { refusal } from './refuse.js';
6
5
  import { headingSpans } from './sections.js';
7
- import { bodyStartOf } from './yaml.js';
8
- function internalEdits(body, file, documentTargets) {
9
- const inventory = linkInventory(body);
6
+ import { bodyStartOf, mapEntry } from './yaml.js';
7
+ function internalEdits(content, bodyStart, file, documentTargets) {
8
+ const inventory = linkInventory(content.slice(bodyStart));
10
9
  const internal = new Set();
11
10
  const edits = [];
12
- for (const use of inventory.uses){
13
- const resolved = classifyHref(file, use.destination.href);
14
- if (resolved.kind !== 'path' || !documentTargets.has(resolved.path)) continue;
11
+ const uses = [...inventory.uses].sort((left, right) => left.end - left.start - (right.end - right.start));
12
+ for (const use of uses) {
13
+ const resolved = target(file, use.destination.href);
14
+ if (resolved === null || !documentTargets.has(resolved))
15
+ continue;
15
16
  internal.add(use.destination.start);
17
+ const label = { start: bodyStart + use.labelStart, end: bodyStart + use.labelEnd };
18
+ const inner = edits
19
+ .filter((edit) => edit.start >= label.start && edit.end <= label.end)
20
+ .sort((left, right) => left.start - right.start);
16
21
  edits.push({
17
- start: use.start,
18
- end: use.end,
19
- text: body.slice(use.labelStart, use.labelEnd)
22
+ start: bodyStart + use.start,
23
+ end: bodyStart + use.end,
24
+ text: rangeText(content, label, inner),
20
25
  });
21
26
  }
22
- for (const block of inventory.blocks){
23
- if (!internal.has(block.destination.start)) continue;
24
- edits.push({
25
- start: block.start,
26
- end: block.end,
27
- text: ''
28
- });
27
+ for (const block of inventory.blocks) {
28
+ if (!internal.has(block.destination.start))
29
+ continue;
30
+ edits.push({ start: bodyStart + block.start, end: bodyStart + block.end, text: '' });
29
31
  }
30
- return edits.sort((left, right)=>left.start - right.start);
32
+ return edits.sort((left, right) => left.start - right.start);
31
33
  }
32
- function projected(body, spans, edits) {
34
+ export function rangeText(content, range, edits) {
33
35
  let text = '';
34
- for (const [from, to] of spans){
35
- let cursor = from;
36
- for (const edit of edits){
37
- if (edit.start < cursor || edit.end > to) continue;
38
- text += body.slice(cursor, edit.start) + edit.text;
39
- cursor = edit.end;
40
- }
41
- text += body.slice(cursor, to);
36
+ let cursor = range.start;
37
+ for (const edit of edits) {
38
+ if (edit.start < cursor || edit.end > range.end)
39
+ continue;
40
+ text += content.slice(cursor, edit.start) + edit.text;
41
+ cursor = edit.end;
42
42
  }
43
- return text;
43
+ return text + content.slice(cursor, range.end);
44
44
  }
45
45
  function structural(spec) {
46
46
  return spec.kind === 'list' && spec.of.kind !== 'text';
47
47
  }
48
- function freeText(definition, fields) {
49
- let text = '';
50
- for (const [name, spec] of Object.entries(definition.fields)){
51
- const value = fields[name];
48
+ function freeTextValues(definition, document) {
49
+ const root = frontmatter(document);
50
+ if (root === null)
51
+ return [];
52
+ const values = [];
53
+ for (const [name, spec] of Object.entries(definition.fields)) {
54
+ const entry = mapEntry(root, name);
55
+ if (entry === undefined)
56
+ continue;
57
+ const node = entry.value;
52
58
  if (spec.kind === 'text') {
53
- if (typeof value === 'string') text += `${value}\n\n`;
59
+ if (node.kind === 'scalar' && typeof node.value === 'string') {
60
+ values.push({ start: node.start, end: node.end, text: `${node.value}\n\n` });
61
+ }
62
+ continue;
63
+ }
64
+ if (spec.kind !== 'list' || spec.of.kind !== 'text' || node.kind !== 'seq')
54
65
  continue;
66
+ for (const item of node.items) {
67
+ if (item.kind === 'scalar' && typeof item.value === 'string') {
68
+ values.push({ start: item.start, end: item.end, text: `${item.value}\n\n` });
69
+ }
55
70
  }
56
- if (spec.kind !== 'list' || spec.of.kind !== 'text' || !Array.isArray(value)) continue;
57
- for (const item of value)if (typeof item === 'string') text += `${item}\n\n`;
58
71
  }
59
- return text;
72
+ return values;
60
73
  }
61
- export function project(document, file, context = {
62
- documentTargets: []
63
- }) {
64
- const bodyStart = bodyStartOf(document.content);
65
- const body = document.content.slice(bodyStart);
66
- const edits = internalEdits(body, file, new Set(context.documentTargets));
74
+ export function projectionInput(document, file, context) {
75
+ const content = document.content;
76
+ const bodyStart = bodyStartOf(content);
77
+ const edits = internalEdits(content, bodyStart, file, new Set(context.documentTargets));
67
78
  const declared = document.type;
68
79
  if (declared === undefined || declared === 'any') {
69
80
  return {
70
81
  ok: true,
71
- text: projected(body, [
72
- [
73
- 0,
74
- body.length
75
- ]
76
- ], edits)
82
+ input: { values: [], ranges: [{ start: bodyStart, end: content.length }], edits },
77
83
  };
78
84
  }
79
- const source = context.definition;
80
- if (source === undefined) {
81
- return {
82
- ok: false,
83
- refusal: refusal(file, 'unknown-type', {
84
- location: 'type'
85
- })
86
- };
85
+ const definition = context.definition;
86
+ if (definition === undefined) {
87
+ return { ok: false, refusal: refusal(file, 'unknown-type', { location: 'type' }) };
87
88
  }
88
- const definitionFile = `types/${declared}.md`;
89
- const parsed = parse(source, definitionFile);
90
- if (!parsed.ok) return {
91
- ok: false,
92
- refusal: parsed.refusal
93
- };
94
- const definition = readDefinition(definitionFile, parsed.document);
95
- if ('rule' in definition) return {
96
- ok: false,
97
- refusal: definition
98
- };
99
- const structure = new Set(Object.entries(definition.sections).flatMap(([name, spec])=>structural(spec) ? [
100
- name
101
- ] : []));
102
- const headings = headingSpans(document.content, bodyStart);
103
- const spans = [
104
- [
105
- 0,
106
- (headings[0]?.headingStart ?? document.content.length) - bodyStart
107
- ]
108
- ];
109
- for (const heading of headings){
110
- if (structure.has(heading.name)) continue;
111
- spans.push([
112
- heading.headingStart - bodyStart,
113
- heading.bodyEnd - bodyStart
114
- ]);
89
+ const structure = new Set(Object.entries(definition.sections).flatMap(([name, spec]) => (structural(spec) ? [name] : [])));
90
+ const headings = headingSpans(content, bodyStart);
91
+ const ranges = [{ start: bodyStart, end: headings[0]?.headingStart ?? content.length }];
92
+ for (const heading of headings) {
93
+ if (structure.has(heading.name))
94
+ continue;
95
+ ranges.push({ start: heading.headingStart, end: heading.bodyEnd });
115
96
  }
116
- return {
117
- ok: true,
118
- text: freeText(definition, document.fields) + projected(body, spans, edits)
119
- };
97
+ return { ok: true, input: { values: freeTextValues(definition, document), ranges, edits } };
98
+ }
99
+ export function project(document, file, context = { documentTargets: [] }) {
100
+ const result = projectionInput(document, file, context);
101
+ if (!result.ok)
102
+ return { ok: false, refusal: result.refusal };
103
+ const { values, ranges, edits } = result.input;
104
+ const prose = ranges.map((range) => rangeText(document.content, range, edits)).join('');
105
+ return { ok: true, text: values.map((value) => value.text).join('') + prose };
120
106
  }
121
-
122
- //# sourceMappingURL=project.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"refuse.d.ts","sourceRoot":"","sources":["../src/refuse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC3D,OAAO,CAQT"}
1
+ {"version":3,"file":"refuse.d.ts","sourceRoot":"","sources":["../src/refuse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC3D,OAAO,CAOT"}
package/dist/refuse.js CHANGED
@@ -1,16 +1,8 @@
1
- import { VERSION } from './version.js';
2
1
  export function refusal(file, rule, extra) {
3
2
  return {
4
3
  file,
5
4
  rule,
6
- version: VERSION,
7
- ...extra?.location === undefined ? {} : {
8
- location: extra.location
9
- },
10
- ...extra?.referrers === undefined ? {} : {
11
- referrers: extra.referrers
12
- }
5
+ ...(extra?.location === undefined ? {} : { location: extra.location }),
6
+ ...(extra?.referrers === undefined ? {} : { referrers: extra.referrers }),
13
7
  };
14
8
  }
15
-
16
- //# sourceMappingURL=refuse.js.map
package/dist/schema.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import type { FieldSpec } from './definition.js';
1
+ import type { FieldSpec, ScalarSpec } from './definition.js';
2
2
  export declare function validateFields(fields: Readonly<Record<string, FieldSpec>>, values: Readonly<Record<string, unknown>>): {
3
3
  field: string;
4
4
  rule: 'required-field' | 'field-enum' | 'field-kind';
5
5
  } | undefined;
6
+ export declare function fitsKind(spec: ScalarSpec, text: string): boolean;
6
7
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAC;AAmB7D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAC3C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,YAAY,CAAA;CAAE,GAAG,SAAS,CAUrF"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAoB7D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAC3C,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,YAAY,CAAA;CAAE,GAAG,SAAS,CAUrF;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhE"}
package/dist/schema.js CHANGED
@@ -1,48 +1,37 @@
1
1
  import { Validator } from '@cfworker/json-schema';
2
+ import { interpretPlain } from './yaml.js';
2
3
  function scalarSchema(spec) {
3
- if (spec.kind === 'text' || spec.kind === 'string' || spec.kind === 'reference') return {
4
- type: 'string'
5
- };
6
- if (spec.kind === 'number') return {
7
- type: 'number'
8
- };
9
- if (spec.kind === 'date') return {
10
- type: 'string',
11
- format: 'date'
12
- };
13
- return {
14
- type: 'string',
15
- enum: [
16
- ...spec.values
17
- ]
18
- };
4
+ if (spec.kind === 'text' || spec.kind === 'string' || spec.kind === 'reference')
5
+ return { type: 'string' };
6
+ if (spec.kind === 'number')
7
+ return { type: 'number' };
8
+ if (spec.kind === 'date')
9
+ return { type: 'string', format: 'date' };
10
+ return { type: 'string', enum: [...spec.values] };
19
11
  }
20
12
  function fieldSchema(spec) {
21
- if (spec.kind === 'list') return {
22
- type: 'array',
23
- items: scalarSchema(spec.of)
24
- };
13
+ if (spec.kind === 'list')
14
+ return { type: 'array', items: scalarSchema(spec.of) };
25
15
  return scalarSchema(spec);
26
16
  }
27
17
  function ruleFor(error) {
28
18
  return error.keyword === 'enum' ? 'field-enum' : 'field-kind';
29
19
  }
30
20
  export function validateFields(fields, values) {
31
- for (const [name, spec] of Object.entries(fields)){
32
- if (spec.required && values[name] === undefined) return {
33
- field: name,
34
- rule: 'required-field'
35
- };
21
+ for (const [name, spec] of Object.entries(fields)) {
22
+ if (spec.required && values[name] === undefined)
23
+ return { field: name, rule: 'required-field' };
36
24
  }
37
- for (const [name, spec] of Object.entries(fields)){
38
- if (values[name] === undefined) continue;
25
+ for (const [name, spec] of Object.entries(fields)) {
26
+ if (values[name] === undefined)
27
+ continue;
39
28
  const result = new Validator(fieldSchema(spec), '2020-12', false).validate(values[name]);
40
- if (!result.valid) return {
41
- field: name,
42
- rule: ruleFor(result.errors[0])
43
- };
29
+ if (!result.valid)
30
+ return { field: name, rule: ruleFor(result.errors[0]) };
44
31
  }
45
32
  return undefined;
46
33
  }
47
-
48
- //# sourceMappingURL=schema.js.map
34
+ export function fitsKind(spec, text) {
35
+ const value = spec.kind === 'number' ? interpretPlain(text) : text;
36
+ return new Validator(scalarSchema(spec), '2020-12', false).validate(value).valid;
37
+ }
@@ -1,3 +1,4 @@
1
+ import type { Extent } from './types.js';
1
2
  export type SectionSpan = {
2
3
  readonly name: string;
3
4
  readonly headingStart: number;
@@ -6,5 +7,5 @@ export type SectionSpan = {
6
7
  };
7
8
  export declare function headingSpans(content: string, bodyStart: number): SectionSpan[];
8
9
  export declare function sectionsRecord(spans: readonly SectionSpan[], content: string): Record<string, string>;
9
- export declare function parseListSection(body: string): boolean;
10
+ export declare function listItems(content: string, from: number, to: number): Extent[] | null;
10
11
  //# sourceMappingURL=sections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAqBF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAwB9E;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBtD"}
1
+ {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAIF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAc9E;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AASD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAoBpF"}
package/dist/sections.js CHANGED
@@ -1,79 +1,57 @@
1
- const H2 = /^##(?!#)[ \t]+(.+?)[ \t]*#*[ \t]*$/;
1
+ import { headingLines } from './blocks.js';
2
2
  const ITEM = /^([ \t]*)([-*+]|\d+[.)])[ \t]+/;
3
- function lineRange(content, from) {
4
- const nl = content.indexOf('\n', from);
5
- const end = nl === -1 ? content.length : nl;
6
- let line = content.slice(from, end);
7
- if (line.endsWith('\r')) line = line.slice(0, -1);
8
- return {
9
- line,
10
- start: from,
11
- next: nl === -1 ? content.length : nl + 1
12
- };
13
- }
14
- function fenceMarker(line) {
15
- let i = 0;
16
- while(i < 3 && (line[i] === ' ' || line[i] === '\t'))i += 1;
17
- if (line.startsWith('```', i)) return '```';
18
- if (line.startsWith('~~~', i)) return '~~~';
19
- return null;
20
- }
21
3
  export function headingSpans(content, bodyStart) {
22
4
  const found = [];
23
- let i = bodyStart;
24
- let fence = null;
25
- while(i < content.length){
26
- const { line, start, next } = lineRange(content, i);
27
- const marker = fenceMarker(line);
28
- if (fence !== null) {
29
- if (marker === fence) fence = null;
30
- } else if (marker !== null) {
31
- fence = marker;
32
- } else {
33
- const match = H2.exec(line);
34
- if (match !== null && match[1] !== undefined) {
35
- const name = match[1].trim();
36
- if (found.length > 0) found[found.length - 1] = {
37
- ...found[found.length - 1],
38
- bodyEnd: start
39
- };
40
- found.push({
41
- name,
42
- headingStart: start,
43
- bodyStart: next,
44
- bodyEnd: content.length
45
- });
46
- }
47
- }
48
- if (next === i) break;
49
- i = next;
5
+ for (const heading of headingLines(content, bodyStart, content.length)) {
6
+ if (heading.level !== 2)
7
+ continue;
8
+ if (found.length > 0)
9
+ found[found.length - 1] = { ...found[found.length - 1], bodyEnd: heading.start };
10
+ found.push({
11
+ name: heading.name,
12
+ headingStart: heading.start,
13
+ bodyStart: heading.next,
14
+ bodyEnd: content.length,
15
+ });
50
16
  }
51
17
  return found;
52
18
  }
53
19
  export function sectionsRecord(spans, content) {
54
20
  const record = Object.create(null);
55
- for (const span of spans){
56
- if (record[span.name] === undefined) record[span.name] = content.slice(span.bodyStart, span.bodyEnd);
21
+ for (const span of spans) {
22
+ if (record[span.name] === undefined)
23
+ record[span.name] = content.slice(span.bodyStart, span.bodyEnd);
57
24
  }
58
25
  return record;
59
26
  }
60
- export function parseListSection(body) {
61
- const lines = body.split(/\r?\n/);
62
- while(lines.length > 0 && lines[0].trim() === '')lines.shift();
63
- while(lines.length > 0 && lines[lines.length - 1].trim() === '')lines.pop();
64
- if (lines.length === 0) return true;
65
- const first = ITEM.exec(lines[0]);
66
- if (first === null || first[1] === undefined) return false;
67
- const indent = first[1].length;
68
- for (const line of lines){
69
- if (line.trim() === '') continue;
70
- const match = ITEM.exec(line);
71
- if (match !== null && match[1]?.length === indent) continue;
72
- const leading = /^\s*/.exec(line)?.[0].length ?? 0;
73
- if (leading > indent) continue;
74
- return false;
27
+ function trimmed(content, extent) {
28
+ let { start, end } = extent;
29
+ while (start < end && /\s/.test(content[start]))
30
+ start += 1;
31
+ while (end > start && /\s/.test(content[end - 1]))
32
+ end -= 1;
33
+ return { start, end };
34
+ }
35
+ export function listItems(content, from, to) {
36
+ const items = [];
37
+ let indent;
38
+ let start = from;
39
+ while (start < to) {
40
+ const newline = content.indexOf('\n', start);
41
+ const end = newline === -1 || newline >= to ? to : newline;
42
+ const line = content.slice(start, end);
43
+ start = end + 1;
44
+ if (line.trim() === '')
45
+ continue;
46
+ const item = ITEM.exec(line);
47
+ if (item !== null && (indent === undefined || item[1].length === indent)) {
48
+ indent = item[1].length;
49
+ items.push({ start: end - line.length + item[0].length, end });
50
+ continue;
51
+ }
52
+ if (indent === undefined || /^\s*/.exec(line)[0].length <= indent)
53
+ return null;
54
+ items[items.length - 1] = { start: items.at(-1).start, end };
75
55
  }
76
- return true;
56
+ return items.map((item) => trimmed(content, item));
77
57
  }
78
-
79
- //# sourceMappingURL=sections.js.map