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

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 (320) hide show
  1. package/API.md +300 -0
  2. package/README.md +34 -189
  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/condition.d.ts +137 -0
  7. package/dist/condition.d.ts.map +1 -0
  8. package/dist/condition.js +394 -0
  9. package/dist/definition.d.ts +42 -27
  10. package/dist/definition.d.ts.map +1 -1
  11. package/dist/definition.js +473 -152
  12. package/dist/divide.d.ts +3 -0
  13. package/dist/divide.d.ts.map +1 -0
  14. package/dist/divide.js +310 -0
  15. package/dist/document.d.ts +2 -0
  16. package/dist/document.d.ts.map +1 -1
  17. package/dist/document.js +89 -120
  18. package/dist/fields.d.ts +4 -0
  19. package/dist/fields.d.ts.map +1 -0
  20. package/dist/fields.js +3 -0
  21. package/dist/index.d.ts +9 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +6 -3
  24. package/dist/links.d.ts +1 -0
  25. package/dist/links.d.ts.map +1 -1
  26. package/dist/links.js +618 -224
  27. package/dist/paths.d.ts +2 -3
  28. package/dist/paths.d.ts.map +1 -1
  29. package/dist/paths.js +27 -37
  30. package/dist/profile.js +1 -3
  31. package/dist/project.d.ts +19 -1
  32. package/dist/project.d.ts.map +1 -1
  33. package/dist/project.js +77 -94
  34. package/dist/refuse.d.ts.map +1 -1
  35. package/dist/refuse.js +2 -10
  36. package/dist/schema.d.ts +7 -5
  37. package/dist/schema.d.ts.map +1 -1
  38. package/dist/schema.js +156 -41
  39. package/dist/sections.d.ts +2 -1
  40. package/dist/sections.d.ts.map +1 -1
  41. package/dist/sections.js +44 -66
  42. package/dist/types.d.ts +30 -2
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js +1 -3
  45. package/dist/validate.d.ts +3 -2
  46. package/dist/validate.d.ts.map +1 -1
  47. package/dist/validate.js +138 -141
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.d.ts.map +1 -1
  50. package/dist/version.js +1 -3
  51. package/dist/yaml.d.ts +2 -0
  52. package/dist/yaml.d.ts.map +1 -1
  53. package/dist/yaml.js +254 -190
  54. package/fixtures/README.md +85 -56
  55. package/fixtures/cases/absent-optional-field/library/companies/acme.md +4 -0
  56. package/fixtures/cases/absent-optional-field/library/deals/lead.md +6 -0
  57. package/fixtures/cases/absent-optional-field/schema.yaml +56 -0
  58. package/fixtures/cases/binary-any-reference/expected.json +1 -2
  59. package/fixtures/cases/binary-any-reference/schema.yaml +4 -0
  60. package/fixtures/cases/binary-document-collision/expected.json +1 -2
  61. package/fixtures/cases/binary-document-collision/schema.yaml +1 -0
  62. package/fixtures/cases/binary-link-outside-collection/expected.json +1 -2
  63. package/fixtures/cases/binary-link-outside-collection/schema.yaml +1 -0
  64. package/fixtures/cases/binary-prototype-reference/expected.json +1 -2
  65. package/fixtures/cases/binary-prototype-reference/schema.yaml +4 -0
  66. package/fixtures/cases/binary-typed-reference/expected.json +1 -2
  67. package/fixtures/cases/binary-typed-reference/schema.yaml +5 -0
  68. package/fixtures/cases/boolean-field/context.json +1 -0
  69. package/fixtures/cases/boolean-field/expected.json +6 -0
  70. package/fixtures/cases/boolean-field/library/companies/acme.md +4 -0
  71. package/fixtures/cases/boolean-field/library/deals/renewal.md +31 -0
  72. package/fixtures/cases/boolean-field/schema.yaml +56 -0
  73. package/fixtures/cases/bracketed-link-definition/schema.yaml +6 -0
  74. package/fixtures/cases/closed-nested-object/context.json +1 -0
  75. package/fixtures/cases/closed-nested-object/expected.json +6 -0
  76. package/fixtures/cases/closed-nested-object/library/companies/acme.md +4 -0
  77. package/fixtures/cases/closed-nested-object/library/deals/renewal.md +32 -0
  78. package/fixtures/cases/closed-nested-object/schema.yaml +56 -0
  79. package/fixtures/cases/composed-root-reference/context.json +1 -0
  80. package/fixtures/cases/composed-root-reference/expected.json +6 -0
  81. package/fixtures/cases/composed-root-reference/library/a.md +5 -0
  82. package/fixtures/cases/composed-root-reference/schema.yaml +13 -0
  83. package/fixtures/cases/date-time-format/context.json +1 -0
  84. package/fixtures/cases/date-time-format/expected.json +6 -0
  85. package/fixtures/cases/date-time-format/library/companies/acme.md +4 -0
  86. package/fixtures/cases/date-time-format/library/deals/renewal.md +31 -0
  87. package/fixtures/cases/date-time-format/schema.yaml +56 -0
  88. package/fixtures/cases/declared-binary-links/schema.yaml +1 -0
  89. package/fixtures/cases/default-unfilled/context.json +1 -0
  90. package/fixtures/cases/default-unfilled/expected.json +6 -0
  91. package/fixtures/cases/default-unfilled/library/companies/acme.md +4 -0
  92. package/fixtures/cases/default-unfilled/library/deals/renewal.md +29 -0
  93. package/fixtures/cases/default-unfilled/schema.yaml +56 -0
  94. package/fixtures/cases/defs-pattern/context.json +1 -0
  95. package/fixtures/cases/defs-pattern/expected.json +6 -0
  96. package/fixtures/cases/defs-pattern/library/companies/acme.md +4 -0
  97. package/fixtures/cases/defs-pattern/library/deals/renewal.md +31 -0
  98. package/fixtures/cases/defs-pattern/schema.yaml +56 -0
  99. package/fixtures/cases/dependent-rule/context.json +1 -0
  100. package/fixtures/cases/dependent-rule/expected.json +6 -0
  101. package/fixtures/cases/dependent-rule/library/companies/acme.md +4 -0
  102. package/fixtures/cases/dependent-rule/library/deals/renewal.md +30 -0
  103. package/fixtures/cases/dependent-rule/schema.yaml +56 -0
  104. package/fixtures/cases/duplicate-link-definition/schema.yaml +6 -0
  105. package/fixtures/cases/email-format/context.json +1 -0
  106. package/fixtures/cases/email-format/expected.json +6 -0
  107. package/fixtures/cases/email-format/library/companies/acme.md +4 -0
  108. package/fixtures/cases/email-format/library/deals/renewal.md +31 -0
  109. package/fixtures/cases/email-format/schema.yaml +56 -0
  110. package/fixtures/cases/fenced-link-definition/schema.yaml +6 -0
  111. package/fixtures/cases/field-enum/expected.json +2 -3
  112. package/fixtures/cases/field-enum/schema.yaml +7 -0
  113. package/fixtures/cases/frontmatter-schema/context.json +1 -0
  114. package/fixtures/cases/frontmatter-schema/expected.json +5 -0
  115. package/fixtures/cases/frontmatter-schema/schema.yaml +5 -0
  116. package/fixtures/cases/integer-field/context.json +1 -0
  117. package/fixtures/cases/integer-field/expected.json +6 -0
  118. package/fixtures/cases/integer-field/library/companies/acme.md +4 -0
  119. package/fixtures/cases/integer-field/library/deals/renewal.md +31 -0
  120. package/fixtures/cases/integer-field/schema.yaml +56 -0
  121. package/fixtures/cases/interrupted-link-definition/schema.yaml +1 -0
  122. package/fixtures/cases/json-schema-constructs/context.json +1 -0
  123. package/fixtures/cases/json-schema-constructs/expected.json +1 -0
  124. package/fixtures/cases/json-schema-constructs/library/companies/acme.md +4 -0
  125. package/fixtures/cases/json-schema-constructs/library/deals/renewal.md +31 -0
  126. package/fixtures/cases/json-schema-constructs/schema.yaml +56 -0
  127. package/fixtures/cases/list-of-objects-closed/context.json +1 -0
  128. package/fixtures/cases/list-of-objects-closed/expected.json +6 -0
  129. package/fixtures/cases/list-of-objects-closed/library/companies/acme.md +4 -0
  130. package/fixtures/cases/list-of-objects-closed/library/deals/renewal.md +32 -0
  131. package/fixtures/cases/list-of-objects-closed/schema.yaml +56 -0
  132. package/fixtures/cases/list-of-objects-item/context.json +1 -0
  133. package/fixtures/cases/list-of-objects-item/expected.json +6 -0
  134. package/fixtures/cases/list-of-objects-item/library/companies/acme.md +4 -0
  135. package/fixtures/cases/list-of-objects-item/library/deals/renewal.md +31 -0
  136. package/fixtures/cases/list-of-objects-item/schema.yaml +56 -0
  137. package/fixtures/cases/list-size/context.json +1 -0
  138. package/fixtures/cases/list-size/expected.json +6 -0
  139. package/fixtures/cases/list-size/library/companies/acme.md +4 -0
  140. package/fixtures/cases/list-size/library/deals/renewal.md +31 -0
  141. package/fixtures/cases/list-size/schema.yaml +56 -0
  142. package/fixtures/cases/long-fence-link-definition/schema.yaml +1 -0
  143. package/fixtures/cases/malformed-definition/expected.json +2 -4
  144. package/fixtures/cases/malformed-definition/schema.yaml +3 -0
  145. package/fixtures/cases/member-document/context.json +1 -0
  146. package/fixtures/cases/member-document/expected.json +1 -0
  147. package/fixtures/cases/member-document/library/people/ana.md +5 -0
  148. package/fixtures/cases/member-document/schema.yaml +5 -0
  149. package/fixtures/cases/missing-binary-image/expected.json +1 -2
  150. package/fixtures/cases/missing-binary-image/schema.yaml +1 -0
  151. package/fixtures/cases/missing-binary-link/expected.json +1 -2
  152. package/fixtures/cases/missing-binary-link/schema.yaml +1 -0
  153. package/fixtures/cases/missing-required-field/expected.json +2 -3
  154. package/fixtures/cases/missing-required-field/schema.yaml +7 -0
  155. package/fixtures/cases/missing-section-item-kind/expected.json +2 -4
  156. package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -0
  157. package/fixtures/cases/misspelled-key/context.json +1 -0
  158. package/fixtures/cases/misspelled-key/expected.json +6 -0
  159. package/fixtures/cases/misspelled-key/library/companies/acme.md +4 -0
  160. package/fixtures/cases/misspelled-key/library/deals/renewal.md +32 -0
  161. package/fixtures/cases/misspelled-key/schema.yaml +56 -0
  162. package/fixtures/cases/nested-defs/context.json +1 -0
  163. package/fixtures/cases/nested-defs/expected.json +6 -0
  164. package/fixtures/cases/nested-defs/library/deal.md +6 -0
  165. package/fixtures/cases/nested-defs/schema.yaml +11 -0
  166. package/fixtures/cases/nested-required-field/context.json +1 -0
  167. package/fixtures/cases/nested-required-field/expected.json +6 -0
  168. package/fixtures/cases/nested-required-field/library/companies/acme.md +4 -0
  169. package/fixtures/cases/nested-required-field/library/deals/renewal.md +30 -0
  170. package/fixtures/cases/nested-required-field/schema.yaml +56 -0
  171. package/fixtures/cases/null-refused/context.json +1 -0
  172. package/fixtures/cases/null-refused/expected.json +6 -0
  173. package/fixtures/cases/null-refused/library/companies/acme.md +4 -0
  174. package/fixtures/cases/null-refused/library/deals/renewal.md +31 -0
  175. package/fixtures/cases/null-refused/schema.yaml +56 -0
  176. package/fixtures/cases/numeric-range/context.json +1 -0
  177. package/fixtures/cases/numeric-range/expected.json +6 -0
  178. package/fixtures/cases/numeric-range/library/companies/acme.md +4 -0
  179. package/fixtures/cases/numeric-range/library/deals/renewal.md +31 -0
  180. package/fixtures/cases/numeric-range/schema.yaml +56 -0
  181. package/fixtures/cases/one-of-variant/context.json +1 -0
  182. package/fixtures/cases/one-of-variant/expected.json +6 -0
  183. package/fixtures/cases/one-of-variant/library/companies/acme.md +4 -0
  184. package/fixtures/cases/one-of-variant/library/deals/renewal.md +31 -0
  185. package/fixtures/cases/one-of-variant/schema.yaml +56 -0
  186. package/fixtures/cases/open-map-value/context.json +1 -0
  187. package/fixtures/cases/open-map-value/expected.json +6 -0
  188. package/fixtures/cases/open-map-value/library/companies/acme.md +4 -0
  189. package/fixtures/cases/open-map-value/library/deals/renewal.md +31 -0
  190. package/fixtures/cases/open-map-value/schema.yaml +56 -0
  191. package/fixtures/cases/paragraph-link-definition/schema.yaml +1 -0
  192. package/fixtures/cases/prototype-field/expected.json +2 -3
  193. package/fixtures/cases/prototype-field/schema.yaml +6 -0
  194. package/fixtures/cases/quoted-link-definition/expected.json +1 -2
  195. package/fixtures/cases/quoted-link-definition/schema.yaml +1 -0
  196. package/fixtures/cases/referenced-missing-file/expected.json +0 -1
  197. package/fixtures/cases/referenced-missing-file/schema.yaml +11 -0
  198. package/fixtures/cases/remote-ref/context.json +1 -0
  199. package/fixtures/cases/remote-ref/expected.json +5 -0
  200. package/fixtures/cases/remote-ref/schema.yaml +3 -0
  201. package/fixtures/cases/second-member-document/context.json +1 -0
  202. package/fixtures/cases/second-member-document/expected.json +5 -0
  203. package/fixtures/cases/second-member-document/schema.yaml +4 -0
  204. package/fixtures/cases/section-item-enum/context.json +1 -0
  205. package/fixtures/cases/section-item-enum/expected.json +6 -0
  206. package/fixtures/cases/section-item-enum/library/task.md +8 -0
  207. package/fixtures/cases/section-item-enum/schema.yaml +3 -0
  208. package/fixtures/cases/section-item-kind/context.json +1 -0
  209. package/fixtures/cases/section-item-kind/expected.json +6 -0
  210. package/fixtures/cases/section-item-kind/library/task.md +8 -0
  211. package/fixtures/cases/section-item-kind/schema.yaml +3 -0
  212. package/fixtures/cases/section-items/context.json +1 -0
  213. package/fixtures/cases/section-items/expected.json +1 -0
  214. package/fixtures/cases/section-items/library/other.md +3 -0
  215. package/fixtures/cases/section-items/library/page.md +42 -0
  216. package/fixtures/cases/section-items/schema.yaml +10 -0
  217. package/fixtures/cases/section-reference-path/context.json +1 -0
  218. package/fixtures/cases/section-reference-path/expected.json +6 -0
  219. package/fixtures/cases/section-reference-path/library/other.md +3 -0
  220. package/fixtures/cases/section-reference-path/library/page.md +7 -0
  221. package/fixtures/cases/section-reference-path/schema.yaml +3 -0
  222. package/fixtures/cases/section-reference-type/context.json +1 -0
  223. package/fixtures/cases/section-reference-type/expected.json +6 -0
  224. package/fixtures/cases/section-reference-type/library/note.md +1 -0
  225. package/fixtures/cases/section-reference-type/library/page.md +7 -0
  226. package/fixtures/cases/section-reference-type/schema.yaml +3 -0
  227. package/fixtures/cases/shortcut-reference-link/context.json +1 -0
  228. package/fixtures/cases/shortcut-reference-link/expected.json +5 -0
  229. package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
  230. package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
  231. package/fixtures/cases/string-length/context.json +1 -0
  232. package/fixtures/cases/string-length/expected.json +6 -0
  233. package/fixtures/cases/string-length/library/companies/acme.md +4 -0
  234. package/fixtures/cases/string-length/library/deals/renewal.md +31 -0
  235. package/fixtures/cases/string-length/schema.yaml +56 -0
  236. package/fixtures/cases/structured-section/expected.json +1 -2
  237. package/fixtures/cases/structured-section/schema.yaml +7 -0
  238. package/fixtures/cases/submission-keys/context.json +1 -0
  239. package/fixtures/cases/submission-keys/expected.json +1 -0
  240. package/fixtures/cases/submission-keys/library/notes/visitor.md +8 -0
  241. package/fixtures/cases/submission-keys/schema.yaml +4 -0
  242. package/fixtures/cases/text-field-kind/context.json +1 -0
  243. package/fixtures/cases/text-field-kind/expected.json +6 -0
  244. package/fixtures/cases/text-field-kind/library/page.md +4 -0
  245. package/fixtures/cases/text-field-kind/schema.yaml +4 -0
  246. package/fixtures/cases/truncated-link-definition/expected.json +1 -2
  247. package/fixtures/cases/truncated-link-definition/schema.yaml +1 -0
  248. package/fixtures/cases/types-folder-content/context.json +1 -0
  249. package/fixtures/cases/types-folder-content/expected.json +1 -0
  250. package/fixtures/cases/types-folder-content/library/types/task.md +4 -0
  251. package/fixtures/cases/types-folder-content/schema.yaml +4 -0
  252. package/fixtures/cases/unclosed-frontmatter/expected.json +1 -2
  253. package/fixtures/cases/undeclared-field/expected.json +2 -3
  254. package/fixtures/cases/undeclared-field/schema.yaml +6 -0
  255. package/fixtures/cases/unevaluated-items-closed/context.json +1 -0
  256. package/fixtures/cases/unevaluated-items-closed/expected.json +6 -0
  257. package/fixtures/cases/unevaluated-items-closed/library/trip.md +6 -0
  258. package/fixtures/cases/unevaluated-items-closed/schema.yaml +10 -0
  259. package/fixtures/cases/unknown-type/context.json +1 -0
  260. package/fixtures/cases/unknown-type/expected.json +6 -0
  261. package/fixtures/cases/unknown-type/library/item.md +3 -0
  262. package/fixtures/cases/unknown-type/schema.yaml +3 -0
  263. package/fixtures/cases/unlisted-reference-type/context.json +1 -0
  264. package/fixtures/cases/unlisted-reference-type/expected.json +5 -0
  265. package/fixtures/cases/unlisted-reference-type/schema.yaml +3 -0
  266. package/fixtures/cases/unresolved-link/expected.json +1 -2
  267. package/fixtures/cases/unresolved-link/schema.yaml +6 -0
  268. package/fixtures/cases/valid-typed-document/schema.yaml +16 -0
  269. package/fixtures/cases/wide-item-fence-link/schema.yaml +1 -0
  270. package/fixtures/division.json +409 -0
  271. package/fixtures/projection.json +90 -21
  272. package/package.json +3 -12
  273. package/dist/definition.js.map +0 -1
  274. package/dist/document.js.map +0 -1
  275. package/dist/index.js.map +0 -1
  276. package/dist/links.js.map +0 -1
  277. package/dist/paths.js.map +0 -1
  278. package/dist/profile.js.map +0 -1
  279. package/dist/project.js.map +0 -1
  280. package/dist/refuse.js.map +0 -1
  281. package/dist/schema.js.map +0 -1
  282. package/dist/sections.js.map +0 -1
  283. package/dist/types.js.map +0 -1
  284. package/dist/validate.js.map +0 -1
  285. package/dist/version.js.map +0 -1
  286. package/dist/yaml.js.map +0 -1
  287. package/fixtures/cases/binary-any-reference/library/types/note.md +0 -5
  288. package/fixtures/cases/binary-document-collision/library/types/note.md +0 -3
  289. package/fixtures/cases/binary-link-outside-collection/library/types/note.md +0 -3
  290. package/fixtures/cases/binary-prototype-reference/library/types/note.md +0 -5
  291. package/fixtures/cases/binary-typed-reference/library/types/note.md +0 -5
  292. package/fixtures/cases/binary-typed-reference/library/types/person.md +0 -3
  293. package/fixtures/cases/bracketed-link-definition/library/types/task.md +0 -7
  294. package/fixtures/cases/declared-binary-links/library/types/note.md +0 -3
  295. package/fixtures/cases/duplicate-link-definition/library/types/task.md +0 -7
  296. package/fixtures/cases/fenced-link-definition/library/types/task.md +0 -7
  297. package/fixtures/cases/field-enum/library/types/task.md +0 -8
  298. package/fixtures/cases/interrupted-link-definition/library/types/note.md +0 -3
  299. package/fixtures/cases/long-fence-link-definition/library/types/note.md +0 -3
  300. package/fixtures/cases/malformed-definition/library/types/task.md +0 -5
  301. package/fixtures/cases/missing-binary-image/library/types/note.md +0 -3
  302. package/fixtures/cases/missing-binary-link/library/types/note.md +0 -3
  303. package/fixtures/cases/missing-required-field/library/types/task.md +0 -8
  304. package/fixtures/cases/missing-section-item-kind/library/types/task.md +0 -7
  305. package/fixtures/cases/paragraph-link-definition/library/types/note.md +0 -3
  306. package/fixtures/cases/prd-definition/library/types/task.md +0 -16
  307. package/fixtures/cases/prototype-field/library/types/task.md +0 -7
  308. package/fixtures/cases/quoted-link-definition/library/types/note.md +0 -3
  309. package/fixtures/cases/referenced-missing-file/library/types/person.md +0 -5
  310. package/fixtures/cases/referenced-missing-file/library/types/task.md +0 -8
  311. package/fixtures/cases/structured-section/library/types/task.md +0 -8
  312. package/fixtures/cases/truncated-link-definition/library/types/note.md +0 -3
  313. package/fixtures/cases/undeclared-field/library/types/task.md +0 -7
  314. package/fixtures/cases/unresolved-link/library/types/task.md +0 -7
  315. package/fixtures/cases/valid-typed-document/library/types/person.md +0 -5
  316. package/fixtures/cases/valid-typed-document/library/types/task.md +0 -13
  317. package/fixtures/cases/wide-item-fence-link/library/types/note.md +0 -3
  318. package/markdown-syntax-profile.md +0 -9
  319. /package/fixtures/cases/{prd-definition → absent-optional-field}/context.json +0 -0
  320. /package/fixtures/cases/{prd-definition → absent-optional-field}/expected.json +0 -0
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
package/dist/types.d.ts CHANGED
@@ -1,10 +1,32 @@
1
+ import type { Definition } from './definition.js';
1
2
  export type Library = Readonly<Record<string, string>>;
3
+ export type VerifiedModel = {
4
+ readonly types: Readonly<Record<string, Definition>>;
5
+ };
6
+ export type ModelVerification = {
7
+ readonly verdict: 'accept';
8
+ readonly model: VerifiedModel;
9
+ } | {
10
+ readonly verdict: 'refuse';
11
+ readonly rule: string;
12
+ readonly location?: string;
13
+ };
2
14
  export type ValidationContext = {
3
15
  readonly binaryTargets: readonly string[];
4
16
  };
5
17
  export type ProjectionContext = {
6
18
  readonly documentTargets: readonly string[];
7
- readonly definition?: string;
19
+ readonly definition?: Definition;
20
+ };
21
+ export type DivisionContext = ProjectionContext & {
22
+ readonly budget: number;
23
+ };
24
+ export type Extent = {
25
+ readonly start: number;
26
+ readonly end: number;
27
+ };
28
+ export type Span = Extent & {
29
+ readonly text: string;
8
30
  };
9
31
  export type Document = {
10
32
  readonly content: string;
@@ -16,7 +38,6 @@ export type Document = {
16
38
  export type Refusal = {
17
39
  readonly file: string;
18
40
  readonly rule: string;
19
- readonly version: string;
20
41
  readonly location?: string;
21
42
  readonly referrers?: readonly string[];
22
43
  };
@@ -32,6 +53,13 @@ export type Projection = {
32
53
  readonly ok: false;
33
54
  readonly refusal: Refusal;
34
55
  };
56
+ export type Division = {
57
+ readonly ok: true;
58
+ readonly spans: readonly Span[];
59
+ } | {
60
+ readonly ok: false;
61
+ readonly refusal: Refusal;
62
+ };
35
63
  export type ParseResult = {
36
64
  readonly ok: true;
37
65
  readonly document: Document;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,3 +1 @@
1
- export { };
2
-
3
- //# sourceMappingURL=types.js.map
1
+ export {};
@@ -1,3 +1,4 @@
1
- import type { Library, Validation, ValidationContext } from './types.js';
2
- export declare function validate(library: Library, context?: ValidationContext): Validation;
1
+ import type { Library, ModelVerification, Validation, ValidationContext, VerifiedModel } from './types.js';
2
+ export declare function verify(schema: string): ModelVerification;
3
+ export declare function validate(library: Library, context?: ValidationContext, model?: VerifiedModel): Validation;
3
4
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAY,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAuCnF,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,iBAAyC,GACjD,UAAU,CAuHZ"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAGV,OAAO,EACP,iBAAiB,EAEjB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACd,MAAM,YAAY,CAAC;AA6EpB,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAQxD;AAED,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,iBAAyC,EAClD,KAAK,GAAE,aAA6B,GACnC,UAAU,CAwGZ"}
package/dist/validate.js CHANGED
@@ -1,183 +1,180 @@
1
- import { readDefinition } from './definition.js';
1
+ import { BUILT_IN_TYPE, escapePointer, readSchema, } from './definition.js';
2
2
  import { parse } from './document.js';
3
- import { hrefOccurrences } from './links.js';
4
- import { classifyHref, isTypesPath } from './paths.js';
3
+ import { hrefOccurrences, linkInventory } from './links.js';
4
+ import { classifyHref } from './paths.js';
5
5
  import { refusal } from './refuse.js';
6
- import { parseListSection } from './sections.js';
7
- import { validateFields } from './schema.js';
8
- import { bodyAfterFrontmatter } from './yaml.js';
6
+ import { fitsItem, frontmatterRefusal } from './schema.js';
7
+ import { headingSpans, listItems } from './sections.js';
8
+ import { bodyAfterFrontmatter, bodyStartOf } from './yaml.js';
9
9
  function refuse(file, rule, extra) {
10
- return {
11
- verdict: 'refuse',
12
- ...refusal(file, rule, extra)
13
- };
10
+ return { verdict: 'refuse', ...refusal(file, rule, extra) };
14
11
  }
15
- function instanceType(document, file) {
16
- if (isTypesPath(file)) return 'definition';
12
+ function instanceType(document) {
17
13
  const raw = document.fields.type;
18
- if (raw === undefined || raw === null) return 'any';
19
- if (typeof raw !== 'string' || raw === '') return 'invalid';
14
+ if (raw === undefined || raw === null)
15
+ return BUILT_IN_TYPE;
16
+ if (typeof raw !== 'string' || raw === '')
17
+ return null;
20
18
  return raw;
21
19
  }
22
- function referenceTargets(spec, value) {
23
- if (spec.kind === 'reference' && typeof value === 'string') return [
24
- value
25
- ];
26
- if (spec.kind === 'list' && spec.of.kind === 'reference' && Array.isArray(value)) {
27
- return value.filter((item)=>typeof item === 'string');
20
+ function fieldReferences(definition, document) {
21
+ const found = [];
22
+ for (const [name, facts] of Object.entries(definition.fields)) {
23
+ const value = document.fields[name];
24
+ const location = `/${escapePointer(name)}`;
25
+ if (facts.reference !== undefined && typeof value === 'string')
26
+ found.push({ location, to: facts.reference, target: value });
27
+ const items = facts.items;
28
+ if (items?.reference === undefined || !Array.isArray(value))
29
+ continue;
30
+ for (const [index, item] of value.entries()) {
31
+ if (typeof item === 'string')
32
+ found.push({ location: `${location}/${index}`, to: items.reference, target: item });
33
+ }
28
34
  }
29
- return [];
35
+ return found;
36
+ }
37
+ function reaches(file, href, to, documents, binaryTargets) {
38
+ const resolved = classifyHref(file, href);
39
+ if (resolved.kind !== 'path' || binaryTargets.has(resolved.path))
40
+ return false;
41
+ const held = documents.get(resolved.path);
42
+ return held === undefined || (held.ok && to.includes(held.document.type ?? BUILT_IN_TYPE));
30
43
  }
31
- function expectedReferenceType(spec) {
32
- if (spec.kind === 'reference') return spec.to;
33
- if (spec.kind === 'list' && spec.of.kind === 'reference') return spec.of.to;
34
- return null;
44
+ function itemHrefs(content, items) {
45
+ const bodyStart = bodyStartOf(content);
46
+ const { uses } = linkInventory(content.slice(bodyStart));
47
+ const hrefs = [];
48
+ for (const item of items) {
49
+ const link = uses.find((use) => bodyStart + use.start === item.start &&
50
+ bodyStart + use.end === item.end &&
51
+ content[item.start] === '[');
52
+ if (link === undefined)
53
+ return null;
54
+ hrefs.push(link.destination.href);
55
+ }
56
+ return hrefs;
35
57
  }
36
- function declaredTypeOf(content) {
37
- const parsed = parse(content);
38
- if (!parsed.ok) return undefined;
39
- return parsed.document.type ?? 'any';
58
+ export function verify(schema) {
59
+ const read = readSchema(schema);
60
+ if ('types' in read)
61
+ return { verdict: 'accept', model: read };
62
+ return {
63
+ verdict: 'refuse',
64
+ rule: read.rule,
65
+ ...(read.location === undefined ? {} : { location: read.location }),
66
+ };
40
67
  }
41
- export function validate(library, context = {
42
- binaryTargets: []
43
- }) {
68
+ export function validate(library, context = { binaryTargets: [] }, model = { types: {} }) {
44
69
  const binaryTargets = new Set(context.binaryTargets);
45
70
  const files = Object.keys(library).sort();
46
71
  const documents = new Map();
47
- for (const file of files){
48
- if (binaryTargets.has(file)) return refuse(file, 'binary-target-document');
72
+ for (const file of files) {
73
+ if (binaryTargets.has(file))
74
+ return refuse(file, 'binary-target-document');
49
75
  const parsed = parse(library[file], file);
50
76
  documents.set(file, parsed);
51
- if (!parsed.ok) return {
52
- verdict: 'refuse',
53
- ...parsed.refusal
54
- };
77
+ if (!parsed.ok)
78
+ return { verdict: 'refuse', ...parsed.refusal };
55
79
  }
56
- const definitions = new Map();
57
- for (const file of files){
58
- if (!isTypesPath(file)) continue;
80
+ const definitions = new Map(Object.entries(model.types));
81
+ const sectionReferences = new Map();
82
+ for (const file of files) {
59
83
  const parsed = documents.get(file);
60
- if (parsed === undefined || !parsed.ok) continue;
61
- const definition = readDefinition(file, parsed.document);
62
- if ('rule' in definition) return {
63
- verdict: 'refuse',
64
- ...definition
65
- };
66
- const existing = definitions.get(definition.name);
67
- if (existing !== undefined) return refuse(file, 'definition-duplicate', {
68
- location: definition.name
69
- });
70
- definitions.set(definition.name, definition);
71
- }
72
- for (const file of files){
73
- const parsed = documents.get(file);
74
- if (parsed === undefined || !parsed.ok) continue;
75
- const kind = instanceType(parsed.document, file);
76
- if (kind === 'any') continue;
77
- if (kind === 'invalid' || kind === 'definition') {
78
- if (kind === 'definition' && isTypesPath(file)) continue;
79
- return refuse(file, 'unknown-type', {
80
- location: 'type'
81
- });
82
- }
83
- const definition = definitions.get(kind);
84
- if (definition === undefined) return refuse(file, 'unknown-type', {
85
- location: 'type'
86
- });
87
- const fieldFailure = validateFields(definition.fields, parsed.document.fields);
84
+ if (parsed === undefined || !parsed.ok)
85
+ continue;
86
+ const kind = instanceType(parsed.document);
87
+ if (kind === BUILT_IN_TYPE)
88
+ continue;
89
+ const definition = kind === null ? undefined : definitions.get(kind);
90
+ if (definition === undefined)
91
+ return refuse(file, 'unknown-type', { location: '/type' });
92
+ const fieldFailure = frontmatterRefusal(definition, parsed.document.fields);
88
93
  if (fieldFailure !== undefined) {
89
- return refuse(file, fieldFailure.rule, {
90
- location: fieldFailure.field
91
- });
94
+ return refuse(file, fieldFailure.rule, { location: fieldFailure.location });
92
95
  }
93
- const declaredFields = new Set(Object.keys(definition.fields));
94
- const undeclared = Object.keys(parsed.document.fields).find((name)=>name !== 'type' && !declaredFields.has(name));
95
- if (undeclared !== undefined) return refuse(file, 'undeclared-field', {
96
- location: undeclared
97
- });
98
- for (const [name, spec] of Object.entries(definition.sections)){
99
- const body = parsed.document.sections[name];
100
- if (body === undefined) {
101
- if (spec.required) return refuse(file, 'required-section', {
102
- location: name
103
- });
96
+ const content = library[file];
97
+ const spans = headingSpans(content, bodyStartOf(content));
98
+ const references = [];
99
+ for (const [name, spec] of Object.entries(definition.sections)) {
100
+ const occurrences = spans.filter((one) => one.name === name);
101
+ if (occurrences.length === 0 && spec.required)
102
+ return refuse(file, 'required-section', { location: name });
103
+ if (spec.kind !== 'list')
104
104
  continue;
105
- }
106
- if (spec.kind === 'list' && !parseListSection(body)) {
107
- return refuse(file, 'structured-section', {
108
- location: name
109
- });
105
+ for (const span of occurrences) {
106
+ const items = listItems(content, span.bodyStart, span.bodyEnd);
107
+ if (items === null ||
108
+ items.some((item) => !fitsItem(definition, name, content.slice(item.start, item.end))))
109
+ return refuse(file, 'structured-section', { location: name });
110
+ if (spec.items.reference === undefined)
111
+ continue;
112
+ const hrefs = itemHrefs(content, items);
113
+ if (hrefs === null)
114
+ return refuse(file, 'structured-section', { location: name });
115
+ references.push({ section: name, to: spec.items.reference, hrefs });
110
116
  }
111
117
  }
118
+ sectionReferences.set(file, references);
112
119
  }
113
- for (const file of files){
120
+ for (const file of files) {
114
121
  const parsed = documents.get(file);
115
- if (parsed === undefined || !parsed.ok) continue;
116
- const kind = instanceType(parsed.document, file);
117
- if (kind === 'any' || kind === 'definition' || kind === 'invalid') continue;
122
+ if (parsed === undefined || !parsed.ok)
123
+ continue;
124
+ const kind = instanceType(parsed.document);
125
+ if (kind === null || kind === BUILT_IN_TYPE)
126
+ continue;
118
127
  const definition = definitions.get(kind);
119
- if (definition === undefined) continue;
120
- for (const [name, spec] of Object.entries(definition.fields)){
121
- const targets = referenceTargets(spec, parsed.document.fields[name]);
122
- const expected = expectedReferenceType(spec);
123
- if (expected === null) continue;
124
- for (const target of targets){
125
- const resolved = classifyHref(file, target);
126
- if (resolved.kind !== 'path' || binaryTargets.has(resolved.path)) return refuse(file, 'unresolved-reference', {
127
- location: name
128
- });
129
- if (!documents.has(resolved.path)) continue;
130
- const targetType = declaredTypeOf(library[resolved.path]);
131
- if (targetType !== expected) return refuse(file, 'unresolved-reference', {
132
- location: name
133
- });
134
- }
128
+ if (definition === undefined)
129
+ continue;
130
+ for (const { location, to, target } of fieldReferences(definition, parsed.document)) {
131
+ if (!reaches(file, target, to, documents, binaryTargets))
132
+ return refuse(file, 'unresolved-reference', { location });
135
133
  }
136
134
  const body = bodyAfterFrontmatter(library[file]);
137
- for (const occurrence of hrefOccurrences(body)){
135
+ for (const occurrence of hrefOccurrences(body)) {
138
136
  const resolved = classifyHref(file, occurrence.href);
139
- if (resolved.kind === 'skip') continue;
140
- if (resolved.kind === 'invalid' || !documents.has(resolved.path) && !binaryTargets.has(resolved.path)) {
137
+ if (resolved.kind === 'skip')
138
+ continue;
139
+ if (resolved.kind === 'invalid' ||
140
+ (!documents.has(resolved.path) && !binaryTargets.has(resolved.path))) {
141
141
  return refuse(file, 'unresolved-link');
142
142
  }
143
143
  }
144
+ for (const { section, to, hrefs } of sectionReferences.get(file)) {
145
+ for (const href of hrefs) {
146
+ if (!reaches(file, href, to, documents, binaryTargets))
147
+ return refuse(file, 'unresolved-reference', { location: section });
148
+ }
149
+ }
144
150
  }
145
151
  const missing = new Map();
146
- for (const file of files){
152
+ for (const file of files) {
147
153
  const parsed = documents.get(file);
148
- if (parsed === undefined || !parsed.ok) continue;
149
- const kind = instanceType(parsed.document, file);
150
- if (kind === 'any' || kind === 'definition' || kind === 'invalid') continue;
154
+ if (parsed === undefined || !parsed.ok)
155
+ continue;
156
+ const kind = instanceType(parsed.document);
157
+ if (kind === null || kind === BUILT_IN_TYPE)
158
+ continue;
151
159
  const definition = definitions.get(kind);
152
- if (definition === undefined) continue;
153
- for (const [name, spec] of Object.entries(definition.fields)){
154
- const expected = expectedReferenceType(spec);
155
- if (expected === null) continue;
156
- for (const target of referenceTargets(spec, parsed.document.fields[name])){
157
- const resolved = classifyHref(file, target);
158
- if (resolved.kind !== 'path') continue;
159
- if (documents.has(resolved.path)) continue;
160
- const referrers = missing.get(resolved.path) ?? [];
161
- referrers.push(file);
162
- missing.set(resolved.path, referrers);
163
- }
160
+ if (definition === undefined)
161
+ continue;
162
+ for (const { target } of fieldReferences(definition, parsed.document)) {
163
+ const resolved = classifyHref(file, target);
164
+ if (resolved.kind !== 'path')
165
+ continue;
166
+ if (documents.has(resolved.path))
167
+ continue;
168
+ const referrers = missing.get(resolved.path) ?? [];
169
+ referrers.push(file);
170
+ missing.set(resolved.path, referrers);
164
171
  }
165
172
  }
166
- const missingPaths = [
167
- ...missing.keys()
168
- ].sort();
173
+ const missingPaths = [...missing.keys()].sort();
169
174
  if (missingPaths.length > 0) {
170
175
  const path = missingPaths[0];
171
- const referrers = [
172
- ...new Set(missing.get(path) ?? [])
173
- ].sort();
174
- return refuse(path, 'referenced-missing-file', {
175
- referrers
176
- });
176
+ const referrers = [...new Set(missing.get(path) ?? [])].sort();
177
+ return refuse(path, 'referenced-missing-file', { referrers });
177
178
  }
178
- return {
179
- verdict: 'accept'
180
- };
179
+ return { verdict: 'accept' };
181
180
  }
182
-
183
- //# sourceMappingURL=validate.js.map
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.0-alpha.9";
1
+ export declare const VERSION = "0.1.0-alpha.19";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,mBAAmB,CAAC"}
package/dist/version.js CHANGED
@@ -1,3 +1 @@
1
- export const VERSION = '0.1.0-alpha.9';
2
-
3
- //# sourceMappingURL=version.js.map
1
+ export const VERSION = '0.1.0-alpha.19';
package/dist/yaml.d.ts CHANGED
@@ -27,11 +27,13 @@ export type YamlMap = {
27
27
  readonly end: number;
28
28
  };
29
29
  export type YamlNode = YamlScalar | YamlSeq | YamlMap;
30
+ export declare function interpretPlain(text: string): string | number | boolean | null;
30
31
  export declare function parseYamlMapping(text: string, start: number, end: number): YamlMap;
31
32
  export declare function jsValue(node: YamlNode): unknown;
32
33
  export declare function mapEntry(map: YamlMap, key: string): YamlEntry | undefined;
33
34
  export declare function isPlainSafe(text: string): boolean;
34
35
  export declare function serializeJs(value: unknown): string;
36
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
35
37
  export declare function serializeKey(name: string): string;
36
38
  export declare function bodyStartAfterYaml(content: string, yamlEnd: number): number;
37
39
  export declare function bodyStartOf(content: string): number;
@@ -1 +1 @@
1
- {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAGlC;CACF;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAqStD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAclF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAM/C;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEzE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMjD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqB9F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAQjE;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEzD"}
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"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"}