@agentshouse/mdmodel 0.1.0-alpha.8 → 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 (323) hide show
  1. package/API.md +300 -0
  2. package/README.md +34 -175
  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 -25
  10. package/dist/definition.d.ts.map +1 -1
  11. package/dist/definition.js +473 -146
  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 +82 -73
  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 +45 -67
  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 -136
  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 +255 -191
  54. package/fixtures/README.md +85 -55
  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/context.json +1 -0
  156. package/fixtures/cases/missing-section-item-kind/expected.json +5 -0
  157. package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -0
  158. package/fixtures/cases/misspelled-key/context.json +1 -0
  159. package/fixtures/cases/misspelled-key/expected.json +6 -0
  160. package/fixtures/cases/misspelled-key/library/companies/acme.md +4 -0
  161. package/fixtures/cases/misspelled-key/library/deals/renewal.md +32 -0
  162. package/fixtures/cases/misspelled-key/schema.yaml +56 -0
  163. package/fixtures/cases/nested-defs/context.json +1 -0
  164. package/fixtures/cases/nested-defs/expected.json +6 -0
  165. package/fixtures/cases/nested-defs/library/deal.md +6 -0
  166. package/fixtures/cases/nested-defs/schema.yaml +11 -0
  167. package/fixtures/cases/nested-required-field/context.json +1 -0
  168. package/fixtures/cases/nested-required-field/expected.json +6 -0
  169. package/fixtures/cases/nested-required-field/library/companies/acme.md +4 -0
  170. package/fixtures/cases/nested-required-field/library/deals/renewal.md +30 -0
  171. package/fixtures/cases/nested-required-field/schema.yaml +56 -0
  172. package/fixtures/cases/null-refused/context.json +1 -0
  173. package/fixtures/cases/null-refused/expected.json +6 -0
  174. package/fixtures/cases/null-refused/library/companies/acme.md +4 -0
  175. package/fixtures/cases/null-refused/library/deals/renewal.md +31 -0
  176. package/fixtures/cases/null-refused/schema.yaml +56 -0
  177. package/fixtures/cases/numeric-range/context.json +1 -0
  178. package/fixtures/cases/numeric-range/expected.json +6 -0
  179. package/fixtures/cases/numeric-range/library/companies/acme.md +4 -0
  180. package/fixtures/cases/numeric-range/library/deals/renewal.md +31 -0
  181. package/fixtures/cases/numeric-range/schema.yaml +56 -0
  182. package/fixtures/cases/one-of-variant/context.json +1 -0
  183. package/fixtures/cases/one-of-variant/expected.json +6 -0
  184. package/fixtures/cases/one-of-variant/library/companies/acme.md +4 -0
  185. package/fixtures/cases/one-of-variant/library/deals/renewal.md +31 -0
  186. package/fixtures/cases/one-of-variant/schema.yaml +56 -0
  187. package/fixtures/cases/open-map-value/context.json +1 -0
  188. package/fixtures/cases/open-map-value/expected.json +6 -0
  189. package/fixtures/cases/open-map-value/library/companies/acme.md +4 -0
  190. package/fixtures/cases/open-map-value/library/deals/renewal.md +31 -0
  191. package/fixtures/cases/open-map-value/schema.yaml +56 -0
  192. package/fixtures/cases/paragraph-link-definition/schema.yaml +1 -0
  193. package/fixtures/cases/prototype-field/context.json +1 -0
  194. package/fixtures/cases/prototype-field/expected.json +6 -0
  195. package/fixtures/cases/prototype-field/library/item.md +9 -0
  196. package/fixtures/cases/prototype-field/schema.yaml +6 -0
  197. package/fixtures/cases/quoted-link-definition/expected.json +1 -2
  198. package/fixtures/cases/quoted-link-definition/schema.yaml +1 -0
  199. package/fixtures/cases/referenced-missing-file/expected.json +0 -1
  200. package/fixtures/cases/referenced-missing-file/schema.yaml +11 -0
  201. package/fixtures/cases/remote-ref/context.json +1 -0
  202. package/fixtures/cases/remote-ref/expected.json +5 -0
  203. package/fixtures/cases/remote-ref/schema.yaml +3 -0
  204. package/fixtures/cases/second-member-document/context.json +1 -0
  205. package/fixtures/cases/second-member-document/expected.json +5 -0
  206. package/fixtures/cases/second-member-document/schema.yaml +4 -0
  207. package/fixtures/cases/section-item-enum/context.json +1 -0
  208. package/fixtures/cases/section-item-enum/expected.json +6 -0
  209. package/fixtures/cases/section-item-enum/library/task.md +8 -0
  210. package/fixtures/cases/section-item-enum/schema.yaml +3 -0
  211. package/fixtures/cases/section-item-kind/context.json +1 -0
  212. package/fixtures/cases/section-item-kind/expected.json +6 -0
  213. package/fixtures/cases/section-item-kind/library/task.md +8 -0
  214. package/fixtures/cases/section-item-kind/schema.yaml +3 -0
  215. package/fixtures/cases/section-items/context.json +1 -0
  216. package/fixtures/cases/section-items/expected.json +1 -0
  217. package/fixtures/cases/section-items/library/other.md +3 -0
  218. package/fixtures/cases/section-items/library/page.md +42 -0
  219. package/fixtures/cases/section-items/schema.yaml +10 -0
  220. package/fixtures/cases/section-reference-path/context.json +1 -0
  221. package/fixtures/cases/section-reference-path/expected.json +6 -0
  222. package/fixtures/cases/section-reference-path/library/other.md +3 -0
  223. package/fixtures/cases/section-reference-path/library/page.md +7 -0
  224. package/fixtures/cases/section-reference-path/schema.yaml +3 -0
  225. package/fixtures/cases/section-reference-type/context.json +1 -0
  226. package/fixtures/cases/section-reference-type/expected.json +6 -0
  227. package/fixtures/cases/section-reference-type/library/note.md +1 -0
  228. package/fixtures/cases/section-reference-type/library/page.md +7 -0
  229. package/fixtures/cases/section-reference-type/schema.yaml +3 -0
  230. package/fixtures/cases/shortcut-reference-link/context.json +1 -0
  231. package/fixtures/cases/shortcut-reference-link/expected.json +5 -0
  232. package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
  233. package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
  234. package/fixtures/cases/string-length/context.json +1 -0
  235. package/fixtures/cases/string-length/expected.json +6 -0
  236. package/fixtures/cases/string-length/library/companies/acme.md +4 -0
  237. package/fixtures/cases/string-length/library/deals/renewal.md +31 -0
  238. package/fixtures/cases/string-length/schema.yaml +56 -0
  239. package/fixtures/cases/structured-section/expected.json +1 -2
  240. package/fixtures/cases/structured-section/schema.yaml +7 -0
  241. package/fixtures/cases/submission-keys/context.json +1 -0
  242. package/fixtures/cases/submission-keys/expected.json +1 -0
  243. package/fixtures/cases/submission-keys/library/notes/visitor.md +8 -0
  244. package/fixtures/cases/submission-keys/schema.yaml +4 -0
  245. package/fixtures/cases/text-field-kind/context.json +1 -0
  246. package/fixtures/cases/text-field-kind/expected.json +6 -0
  247. package/fixtures/cases/text-field-kind/library/page.md +4 -0
  248. package/fixtures/cases/text-field-kind/schema.yaml +4 -0
  249. package/fixtures/cases/truncated-link-definition/expected.json +1 -2
  250. package/fixtures/cases/truncated-link-definition/schema.yaml +1 -0
  251. package/fixtures/cases/types-folder-content/context.json +1 -0
  252. package/fixtures/cases/types-folder-content/expected.json +1 -0
  253. package/fixtures/cases/types-folder-content/library/types/task.md +4 -0
  254. package/fixtures/cases/types-folder-content/schema.yaml +4 -0
  255. package/fixtures/cases/unclosed-frontmatter/expected.json +1 -2
  256. package/fixtures/cases/undeclared-field/context.json +1 -0
  257. package/fixtures/cases/undeclared-field/expected.json +6 -0
  258. package/fixtures/cases/undeclared-field/library/item.md +9 -0
  259. package/fixtures/cases/undeclared-field/schema.yaml +6 -0
  260. package/fixtures/cases/unevaluated-items-closed/context.json +1 -0
  261. package/fixtures/cases/unevaluated-items-closed/expected.json +6 -0
  262. package/fixtures/cases/unevaluated-items-closed/library/trip.md +6 -0
  263. package/fixtures/cases/unevaluated-items-closed/schema.yaml +10 -0
  264. package/fixtures/cases/unknown-type/context.json +1 -0
  265. package/fixtures/cases/unknown-type/expected.json +6 -0
  266. package/fixtures/cases/unknown-type/library/item.md +3 -0
  267. package/fixtures/cases/unknown-type/schema.yaml +3 -0
  268. package/fixtures/cases/unlisted-reference-type/context.json +1 -0
  269. package/fixtures/cases/unlisted-reference-type/expected.json +5 -0
  270. package/fixtures/cases/unlisted-reference-type/schema.yaml +3 -0
  271. package/fixtures/cases/unresolved-link/expected.json +1 -2
  272. package/fixtures/cases/unresolved-link/schema.yaml +6 -0
  273. package/fixtures/cases/valid-typed-document/library/tasks/one.md +1 -0
  274. package/fixtures/cases/valid-typed-document/schema.yaml +16 -0
  275. package/fixtures/cases/wide-item-fence-link/schema.yaml +1 -0
  276. package/fixtures/division.json +409 -0
  277. package/fixtures/projection.json +109 -28
  278. package/package.json +3 -12
  279. package/dist/definition.js.map +0 -1
  280. package/dist/document.js.map +0 -1
  281. package/dist/index.js.map +0 -1
  282. package/dist/links.js.map +0 -1
  283. package/dist/paths.js.map +0 -1
  284. package/dist/profile.js.map +0 -1
  285. package/dist/project.js.map +0 -1
  286. package/dist/refuse.js.map +0 -1
  287. package/dist/schema.js.map +0 -1
  288. package/dist/sections.js.map +0 -1
  289. package/dist/types.js.map +0 -1
  290. package/dist/validate.js.map +0 -1
  291. package/dist/version.js.map +0 -1
  292. package/dist/yaml.js.map +0 -1
  293. package/fixtures/cases/binary-any-reference/library/types/note.md +0 -5
  294. package/fixtures/cases/binary-document-collision/library/types/note.md +0 -3
  295. package/fixtures/cases/binary-link-outside-collection/library/types/note.md +0 -3
  296. package/fixtures/cases/binary-prototype-reference/library/types/note.md +0 -5
  297. package/fixtures/cases/binary-typed-reference/library/types/note.md +0 -5
  298. package/fixtures/cases/binary-typed-reference/library/types/person.md +0 -3
  299. package/fixtures/cases/bracketed-link-definition/library/types/task.md +0 -7
  300. package/fixtures/cases/declared-binary-links/library/types/note.md +0 -3
  301. package/fixtures/cases/duplicate-link-definition/library/types/task.md +0 -7
  302. package/fixtures/cases/fenced-link-definition/library/types/task.md +0 -7
  303. package/fixtures/cases/field-enum/library/types/task.md +0 -8
  304. package/fixtures/cases/interrupted-link-definition/library/types/note.md +0 -3
  305. package/fixtures/cases/long-fence-link-definition/library/types/note.md +0 -3
  306. package/fixtures/cases/malformed-definition/library/types/task.md +0 -5
  307. package/fixtures/cases/missing-binary-image/library/types/note.md +0 -3
  308. package/fixtures/cases/missing-binary-link/library/types/note.md +0 -3
  309. package/fixtures/cases/missing-required-field/library/types/task.md +0 -8
  310. package/fixtures/cases/paragraph-link-definition/library/types/note.md +0 -3
  311. package/fixtures/cases/prd-definition/library/types/task.md +0 -15
  312. package/fixtures/cases/quoted-link-definition/library/types/note.md +0 -3
  313. package/fixtures/cases/referenced-missing-file/library/types/person.md +0 -5
  314. package/fixtures/cases/referenced-missing-file/library/types/task.md +0 -8
  315. package/fixtures/cases/structured-section/library/types/task.md +0 -8
  316. package/fixtures/cases/truncated-link-definition/library/types/note.md +0 -3
  317. package/fixtures/cases/unresolved-link/library/types/task.md +0 -7
  318. package/fixtures/cases/valid-typed-document/library/types/person.md +0 -5
  319. package/fixtures/cases/valid-typed-document/library/types/task.md +0 -12
  320. package/fixtures/cases/wide-item-fence-link/library/types/note.md +0 -3
  321. package/markdown-syntax-profile.md +0 -9
  322. /package/fixtures/cases/{prd-definition → absent-optional-field}/context.json +0 -0
  323. /package/fixtures/cases/{prd-definition → absent-optional-field}/expected.json +0 -0
@@ -0,0 +1,137 @@
1
+ import type { ValueFacts } from './definition.js';
2
+ import type { Document, VerifiedModel } from './types.js';
3
+ export type ConditionValue = string | number | boolean | {
4
+ readonly owner: true;
5
+ };
6
+ export type ConditionTest = {
7
+ readonly all: readonly ConditionTest[];
8
+ } | {
9
+ readonly any: readonly ConditionTest[];
10
+ } | {
11
+ readonly not: ConditionTest;
12
+ } | ({
13
+ readonly path: string;
14
+ } & ({
15
+ readonly eq: ConditionValue;
16
+ } | {
17
+ readonly in: readonly ConditionValue[];
18
+ } | {
19
+ readonly exists: boolean;
20
+ } | {
21
+ readonly contains: ConditionValue;
22
+ } | {
23
+ readonly gt: number | string;
24
+ } | {
25
+ readonly gte: number | string;
26
+ } | {
27
+ readonly lt: number | string;
28
+ } | {
29
+ readonly lte: number | string;
30
+ } | {
31
+ readonly prefix: string;
32
+ }));
33
+ export type ConditionScope = {
34
+ readonly type: string;
35
+ } | {
36
+ readonly folder: string;
37
+ } | {
38
+ readonly document: string;
39
+ };
40
+ type DocumentEventBase = {
41
+ readonly on: 'documents';
42
+ readonly scope: ConditionScope;
43
+ readonly by?: ConditionTest;
44
+ };
45
+ export type DocumentCondition = (DocumentEventBase & {
46
+ readonly mode: 'starts_matching';
47
+ readonly new_documents: boolean;
48
+ readonly match: ConditionTest;
49
+ }) | (DocumentEventBase & {
50
+ readonly mode: 'field_changes';
51
+ readonly field: string;
52
+ readonly from?: readonly ConditionValue[] | 'new';
53
+ readonly to?: readonly ConditionValue[] | 'deleted';
54
+ readonly match?: ConditionTest;
55
+ });
56
+ export type ItemCondition = {
57
+ readonly on: 'items';
58
+ readonly source?: string;
59
+ readonly address?: string;
60
+ readonly match?: ConditionTest;
61
+ };
62
+ export type CronCondition = {
63
+ readonly on: 'clock';
64
+ readonly cron: string;
65
+ readonly time_zone: string;
66
+ };
67
+ export type DateCondition = {
68
+ readonly on: 'clock';
69
+ readonly scope: {
70
+ readonly type: string;
71
+ };
72
+ readonly date: string;
73
+ readonly days: number;
74
+ readonly at: string;
75
+ readonly time_zone: string;
76
+ readonly match?: ConditionTest;
77
+ };
78
+ export type Condition = DocumentCondition | ItemCondition | CronCondition | DateCondition;
79
+ export type FactKind = 'string' | 'number' | 'boolean' | 'date' | 'time' | 'enum' | 'reference';
80
+ export type Fact = {
81
+ readonly kind: FactKind;
82
+ readonly value: Scalar | readonly Scalar[];
83
+ };
84
+ export type DocumentFacts = {
85
+ readonly id: string;
86
+ readonly path: string;
87
+ readonly type: string | null;
88
+ readonly fields: Readonly<Record<string, Fact>>;
89
+ readonly members: Readonly<Record<string, string | readonly string[]>>;
90
+ readonly prose: readonly string[];
91
+ readonly unreadable: readonly string[];
92
+ };
93
+ export declare const WRITE_DOORS: readonly ['browser', 'agent', 'client'];
94
+ export type WriteDoor = (typeof WRITE_DOORS)[number];
95
+ export type Actor = {
96
+ readonly user?: string;
97
+ readonly site?: string;
98
+ readonly door?: WriteDoor;
99
+ };
100
+ export type DocumentEvent = {
101
+ readonly before: DocumentFacts | null;
102
+ readonly after: DocumentFacts | null;
103
+ readonly changed: readonly string[];
104
+ readonly by: Actor;
105
+ };
106
+ export type ItemFacts = {
107
+ readonly delivery: string;
108
+ readonly source: string | null;
109
+ readonly address: string | null;
110
+ readonly has_attachment: boolean;
111
+ readonly provider: string | null;
112
+ readonly container: string | null;
113
+ readonly author: string | null;
114
+ readonly headers: Readonly<Record<string, string>>;
115
+ readonly json: {
116
+ readonly value: unknown;
117
+ } | null;
118
+ };
119
+ export type Resolved = {
120
+ readonly id: string;
121
+ readonly member?: string;
122
+ };
123
+ type Truth = boolean | undefined;
124
+ type Scalar = string | number | boolean;
125
+ export declare function factKind(facts: ValueFacts): FactKind | null;
126
+ export declare function facts(document: Document, at: {
127
+ readonly id: string;
128
+ readonly path: string;
129
+ }, model: VerifiedModel, resolve: (target: string) => Resolved | undefined): DocumentFacts;
130
+ export declare function dated(value: unknown): value is string;
131
+ export declare function instant(value: unknown): bigint | undefined;
132
+ export declare function pointed(value: unknown, pointer: string): unknown;
133
+ export declare function holds(test: ConditionTest, document: DocumentFacts, owner: string): Truth;
134
+ export declare function fires(condition: DocumentCondition, event: DocumentEvent, owner: string): boolean;
135
+ export declare function itemFires(condition: ItemCondition, item: ItemFacts, owner: string): boolean;
136
+ export {};
137
+ //# sourceMappingURL=condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.d.ts","sourceRoot":"","sources":["../src/condition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,394 @@
1
+ import { target } from './paths.js';
2
+ import { isRecord } from './yaml.js';
3
+ export const WRITE_DOORS = ['browser', 'agent', 'client'];
4
+ const DATE = /^\d{4}-\d{2}-\d{2}$/u;
5
+ const DATE_TIME = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(?:[Zz]|([+-])(\d{2}):(\d{2}))$/u;
6
+ const ARRAY_INDEX = /^(?:0|[1-9][0-9]*)$/u;
7
+ export function factKind(facts) {
8
+ if (facts.reference !== undefined)
9
+ return 'reference';
10
+ if (facts.values !== undefined)
11
+ return 'enum';
12
+ if (facts.type === 'number' || facts.type === 'integer')
13
+ return 'number';
14
+ if (facts.type === 'boolean')
15
+ return 'boolean';
16
+ if (facts.type !== 'string')
17
+ return null;
18
+ if (facts.format === 'date')
19
+ return 'date';
20
+ if (facts.format === 'date-time')
21
+ return 'time';
22
+ return 'string';
23
+ }
24
+ function referenced(model, facts) {
25
+ return (facts.reference ?? []).some((to) => Object.hasOwn(model.types, to) && model.types[to].memberDocument);
26
+ }
27
+ function fits(kind, facts, value) {
28
+ if (!scalar(value))
29
+ return false;
30
+ if (kind === 'enum')
31
+ return (facts.values ?? []).includes(value);
32
+ if (kind === 'number')
33
+ return typeof value === 'number';
34
+ if (kind === 'boolean')
35
+ return typeof value === 'boolean';
36
+ if (typeof value !== 'string')
37
+ return false;
38
+ if (kind === 'date')
39
+ return dated(value);
40
+ if (kind === 'time')
41
+ return instant(value) !== undefined;
42
+ return true;
43
+ }
44
+ function fitted(kind, facts, value, path, resolve) {
45
+ if (!fits(kind, facts, value))
46
+ return undefined;
47
+ if (kind !== 'reference')
48
+ return { value };
49
+ const reached = target(path, value);
50
+ return reached === null ? undefined : resolve(reached);
51
+ }
52
+ export function facts(document, at, model, resolve) {
53
+ const type = document.type ?? null;
54
+ const definition = type !== null && Object.hasOwn(model.types, type) ? model.types[type] : null;
55
+ const fields = {};
56
+ const members = {};
57
+ const prose = Object.keys(document.sections).map((heading) => `/sections/${heading}`);
58
+ const unreadable = [];
59
+ for (const [name, declared] of Object.entries(definition === null ? {} : definition.fields)) {
60
+ const value = document.fields[name];
61
+ if (value === undefined || value === null)
62
+ continue;
63
+ const list = declared.type === 'array';
64
+ const facts = list ? declared.items : declared;
65
+ const kind = facts === undefined || facts.prose ? null : factKind(facts);
66
+ if (kind === null) {
67
+ prose.push(`/fields/${name}`);
68
+ continue;
69
+ }
70
+ const items = list ? value : [value];
71
+ const held = Array.isArray(items)
72
+ ? items.map((item) => fitted(kind, facts, item, at.path, resolve))
73
+ : [undefined];
74
+ if (held.some((item) => item === undefined)) {
75
+ unreadable.push(`/fields/${name}`);
76
+ if (referenced(model, facts))
77
+ unreadable.push(`/members/${name}`);
78
+ continue;
79
+ }
80
+ const values = held.map((item) => ('id' in item ? item.id : item.value));
81
+ fields[name] = { kind, value: list ? values : values[0] };
82
+ if (!referenced(model, facts))
83
+ continue;
84
+ const bound = held.flatMap((item) => 'member' in item && item.member !== undefined ? [item.member] : []);
85
+ if (list)
86
+ members[name] = bound;
87
+ else if (bound[0] !== undefined)
88
+ members[name] = bound[0];
89
+ }
90
+ return {
91
+ id: at.id,
92
+ path: `/${at.path}`,
93
+ type,
94
+ fields,
95
+ members,
96
+ prose: prose.sort(),
97
+ unreadable: unreadable.sort(),
98
+ };
99
+ }
100
+ function readDocument(facts, path) {
101
+ if (path === '/path')
102
+ return { kind: 'path', value: facts.path };
103
+ if (path === '/type')
104
+ return facts.type === null ? undefined : { kind: 'string', value: facts.type };
105
+ if (facts.unreadable.includes(path))
106
+ return { kind: 'unreadable' };
107
+ if (facts.prose.includes(path))
108
+ return { kind: 'present' };
109
+ if (path.startsWith('/fields/')) {
110
+ const name = path.slice('/fields/'.length);
111
+ return Object.hasOwn(facts.fields, name) ? facts.fields[name] : undefined;
112
+ }
113
+ if (path.startsWith('/members/')) {
114
+ const name = path.slice('/members/'.length);
115
+ return Object.hasOwn(facts.members, name)
116
+ ? { kind: 'member', value: facts.members[name] }
117
+ : undefined;
118
+ }
119
+ return undefined;
120
+ }
121
+ function readActor(actor, path) {
122
+ const value = path === '/user'
123
+ ? actor.user
124
+ : path === '/site'
125
+ ? actor.site
126
+ : path === '/door'
127
+ ? actor.door
128
+ : undefined;
129
+ return value === undefined ? undefined : { kind: 'actor', value };
130
+ }
131
+ function plain(value) {
132
+ if (!isRecord(value))
133
+ return false;
134
+ const prototype = Object.getPrototypeOf(value);
135
+ return prototype === Object.prototype || prototype === null;
136
+ }
137
+ export function dated(value) {
138
+ return (typeof value === 'string' && DATE.test(value) && instant(`${value}T00:00:00Z`) !== undefined);
139
+ }
140
+ export function instant(value) {
141
+ if (typeof value !== 'string')
142
+ return undefined;
143
+ const parts = DATE_TIME.exec(value);
144
+ if (parts === null)
145
+ return undefined;
146
+ const [year, month, day, hour, minute, second, offsetHours, offsetMinutes] = [
147
+ 1, 2, 3, 4, 5, 6, 9, 10,
148
+ ].map((at) => Number(parts[at] ?? 0));
149
+ const at = new Date(0);
150
+ at.setUTCFullYear(year, month - 1, day);
151
+ at.setUTCHours(hour, minute, second);
152
+ if (at.getUTCFullYear() !== year ||
153
+ at.getUTCMonth() !== month - 1 ||
154
+ at.getUTCDate() !== day ||
155
+ at.getUTCHours() !== hour ||
156
+ at.getUTCMinutes() !== minute ||
157
+ offsetHours > 23 ||
158
+ offsetMinutes > 59)
159
+ return undefined;
160
+ const offset = (parts[8] === '-' ? -1 : 1) * (offsetHours * 60 + offsetMinutes);
161
+ const fraction = (parts[7] ?? '').padEnd(9, '0').slice(0, 9);
162
+ return (BigInt(at.getTime()) - BigInt(offset) * 60000n) * 1000000n + BigInt(fraction);
163
+ }
164
+ export function pointed(value, pointer) {
165
+ if (pointer === '')
166
+ return value;
167
+ let reached = value;
168
+ for (const part of pointer.slice(1).split('/')) {
169
+ const token = part.replaceAll('~1', '/').replaceAll('~0', '~');
170
+ if (Array.isArray(reached)) {
171
+ if (!ARRAY_INDEX.test(token))
172
+ return undefined;
173
+ reached = reached[Number(token)];
174
+ }
175
+ else if (plain(reached) && Object.hasOwn(reached, token)) {
176
+ reached = reached[token];
177
+ }
178
+ else {
179
+ return undefined;
180
+ }
181
+ }
182
+ return reached;
183
+ }
184
+ function scalar(value) {
185
+ return (typeof value === 'string' ||
186
+ typeof value === 'boolean' ||
187
+ (typeof value === 'number' && Number.isFinite(value)));
188
+ }
189
+ function jsonHeld(value) {
190
+ if (value === undefined)
191
+ return undefined;
192
+ if (typeof value === 'string')
193
+ return {
194
+ kind: dated(value) ? 'date' : instant(value) === undefined ? 'string' : 'time',
195
+ value,
196
+ };
197
+ if (typeof value === 'boolean')
198
+ return { kind: 'boolean', value };
199
+ if (scalar(value))
200
+ return { kind: 'number', value };
201
+ if (Array.isArray(value))
202
+ return { kind: 'list', value: value.filter(scalar) };
203
+ return { kind: 'present' };
204
+ }
205
+ function readItem(item, path) {
206
+ if (path.startsWith('/json/')) {
207
+ if (item.json === null)
208
+ return { kind: 'unreadable' };
209
+ return jsonHeld(pointed(item.json.value, path.slice('/json'.length)));
210
+ }
211
+ if (path.startsWith('/headers/')) {
212
+ const name = path.slice('/headers/'.length);
213
+ return Object.hasOwn(item.headers, name)
214
+ ? { kind: 'string', value: item.headers[name] }
215
+ : undefined;
216
+ }
217
+ if (path === '/has_attachment')
218
+ return { kind: 'boolean', value: item.has_attachment };
219
+ const value = path === '/delivery'
220
+ ? item.delivery
221
+ : path === '/source'
222
+ ? item.source
223
+ : path === '/provider'
224
+ ? item.provider
225
+ : path === '/container'
226
+ ? item.container
227
+ : path === '/author'
228
+ ? item.author
229
+ : null;
230
+ return value === null ? undefined : { kind: 'string', value };
231
+ }
232
+ function wanted(value, owner) {
233
+ return isRecord(value) && value.owner === true ? owner : value;
234
+ }
235
+ function equal(held, value, owner) {
236
+ if (held.kind === 'present' || Array.isArray(held.value))
237
+ return undefined;
238
+ const expected = wanted(value, owner);
239
+ if (typeof expected !== typeof held.value)
240
+ return undefined;
241
+ if (held.kind !== 'time')
242
+ return expected === held.value;
243
+ const left = instant(held.value);
244
+ const right = instant(expected);
245
+ return left === undefined || right === undefined ? undefined : left === right;
246
+ }
247
+ function sign(left, right) {
248
+ return left < right ? -1 : left > right ? 1 : 0;
249
+ }
250
+ function ordered(held, value, compare) {
251
+ if (held.kind === 'present' || Array.isArray(held.value))
252
+ return undefined;
253
+ if (held.kind === 'number') {
254
+ if (typeof value !== 'number' || typeof held.value !== 'number')
255
+ return undefined;
256
+ return compare(Math.sign(held.value - value));
257
+ }
258
+ if (held.kind === 'date') {
259
+ if (!dated(value) || !dated(held.value))
260
+ return undefined;
261
+ return compare(sign(held.value, value));
262
+ }
263
+ if (held.kind !== 'time')
264
+ return undefined;
265
+ const at = instant(held.value);
266
+ const wanted = instant(value);
267
+ if (at === undefined || wanted === undefined)
268
+ return undefined;
269
+ return compare(sign(at, wanted));
270
+ }
271
+ function anyOf(truths) {
272
+ if (truths.some((truth) => truth === true))
273
+ return true;
274
+ return truths.some((truth) => truth === undefined) ? undefined : false;
275
+ }
276
+ function allOf(truths) {
277
+ if (truths.some((truth) => truth === false))
278
+ return false;
279
+ return truths.some((truth) => truth === undefined) ? undefined : true;
280
+ }
281
+ function leaf(test, held, owner) {
282
+ if (held?.kind === 'unreadable')
283
+ return undefined;
284
+ if ('exists' in test)
285
+ return (held !== undefined) === test.exists;
286
+ if (held === undefined)
287
+ return undefined;
288
+ if ('eq' in test)
289
+ return equal(held, test.eq, owner);
290
+ if ('in' in test)
291
+ return anyOf(test.in.map((value) => equal(held, value, owner)));
292
+ if ('contains' in test) {
293
+ if (held.kind === 'present' || !Array.isArray(held.value))
294
+ return undefined;
295
+ const expected = wanted(test.contains, owner);
296
+ if (held.value.some((item) => item === expected))
297
+ return true;
298
+ if (held.kind === 'list')
299
+ return false;
300
+ return held.value.every((item) => typeof item === typeof expected) ? false : undefined;
301
+ }
302
+ if ('prefix' in test) {
303
+ if (held.kind === 'present' || typeof held.value !== 'string')
304
+ return undefined;
305
+ if (held.kind === 'number' || held.kind === 'reference' || held.kind === 'member')
306
+ return undefined;
307
+ return held.value.startsWith(test.prefix);
308
+ }
309
+ if ('gt' in test)
310
+ return ordered(held, test.gt, (sign) => sign > 0);
311
+ if ('gte' in test)
312
+ return ordered(held, test.gte, (sign) => sign >= 0);
313
+ if ('lt' in test)
314
+ return ordered(held, test.lt, (sign) => sign < 0);
315
+ return ordered(held, test.lte, (sign) => sign <= 0);
316
+ }
317
+ function evaluated(test, read, owner) {
318
+ if ('all' in test)
319
+ return allOf(test.all.map((part) => evaluated(part, read, owner)));
320
+ if ('any' in test)
321
+ return anyOf(test.any.map((part) => evaluated(part, read, owner)));
322
+ if ('not' in test) {
323
+ const truth = evaluated(test.not, read, owner);
324
+ return truth === undefined ? undefined : !truth;
325
+ }
326
+ return leaf(test, read(test.path), owner);
327
+ }
328
+ export function holds(test, document, owner) {
329
+ return evaluated(test, (path) => readDocument(document, path), owner);
330
+ }
331
+ function inScope(scope, document) {
332
+ if (document === null)
333
+ return false;
334
+ if ('type' in scope)
335
+ return document.type === scope.type;
336
+ if ('document' in scope)
337
+ return document.id === scope.document;
338
+ return scope.folder === '/' || document.path.startsWith(`${scope.folder}/`);
339
+ }
340
+ function matched(condition, test, document, owner) {
341
+ if (!inScope(condition.scope, document))
342
+ return false;
343
+ return test === undefined || holds(test, document, owner) === true;
344
+ }
345
+ function sameFact(left, right) {
346
+ return JSON.stringify(left) === JSON.stringify(right);
347
+ }
348
+ function among(values, document, field, owner) {
349
+ return holds({ path: field, in: values }, document, owner) === true;
350
+ }
351
+ function fieldChanged(condition, event, owner) {
352
+ const { field, from, to } = condition;
353
+ if (from === undefined && to === undefined && event.changed.includes(field))
354
+ return true;
355
+ if (!field.startsWith('/fields/'))
356
+ return false;
357
+ const name = field.slice('/fields/'.length);
358
+ const before = event.before?.fields[name];
359
+ const after = event.after?.fields[name];
360
+ if (before === undefined && after === undefined)
361
+ return false;
362
+ if (event.before !== null && event.after !== null && sameFact(before, after))
363
+ return false;
364
+ if (from === 'new'
365
+ ? event.before !== null
366
+ : from !== undefined && (event.before === null || !among(from, event.before, field, owner)))
367
+ return false;
368
+ if (to === 'deleted'
369
+ ? event.after !== null
370
+ : to !== undefined && (event.after === null || !among(to, event.after, field, owner)))
371
+ return false;
372
+ return true;
373
+ }
374
+ export function fires(condition, event, owner) {
375
+ if (condition.by !== undefined &&
376
+ evaluated(condition.by, (path) => readActor(event.by, path), owner) !== true)
377
+ return false;
378
+ if (condition.mode === 'starts_matching') {
379
+ if (event.before === null && !condition.new_documents)
380
+ return false;
381
+ return (matched(condition, condition.match, event.after, owner) &&
382
+ !matched(condition, condition.match, event.before, owner));
383
+ }
384
+ const side = event.after ?? event.before;
385
+ return matched(condition, condition.match, side, owner) && fieldChanged(condition, event, owner);
386
+ }
387
+ export function itemFires(condition, item, owner) {
388
+ if (condition.source !== undefined && item.source !== condition.source)
389
+ return false;
390
+ if (condition.address !== undefined && item.address !== condition.address)
391
+ return false;
392
+ return (condition.match === undefined ||
393
+ evaluated(condition.match, (path) => readItem(item, path), owner) === true);
394
+ }
@@ -1,36 +1,53 @@
1
- import type { Document, Refusal } from './types.js';
2
- export type ScalarSpec = {
3
- readonly kind: 'string';
4
- readonly required: boolean;
5
- } | {
6
- readonly kind: 'number';
7
- readonly required: boolean;
8
- } | {
9
- readonly kind: 'date';
10
- readonly required: boolean;
11
- } | {
12
- readonly kind: 'enum';
1
+ import type { VerifiedModel } from './types.js';
2
+ export type JsonType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
3
+ export type ValueFacts = {
4
+ readonly type?: JsonType;
5
+ readonly format?: string;
6
+ readonly values?: readonly unknown[];
7
+ readonly reference?: readonly string[];
8
+ readonly prose: boolean;
9
+ readonly items?: ValueFacts;
10
+ readonly properties?: Readonly<Record<string, ValueFacts>>;
11
+ readonly patterns?: readonly PatternFacts[];
12
+ readonly additional?: ValueFacts;
13
+ };
14
+ export type PatternFacts = {
15
+ readonly pattern: string;
16
+ readonly facts: ValueFacts;
17
+ };
18
+ export type SectionSpec = {
19
+ readonly kind: 'text';
13
20
  readonly required: boolean;
14
- readonly values: readonly string[];
15
21
  } | {
16
- readonly kind: 'reference';
17
- readonly required: boolean;
18
- readonly to: string;
19
- };
20
- export type FieldSpec = ScalarSpec | {
21
22
  readonly kind: 'list';
22
23
  readonly required: boolean;
23
- readonly of: ScalarSpec;
24
+ readonly items: ValueFacts;
24
25
  };
25
- export type SectionSpec = {
26
- readonly kind: 'text' | 'list';
27
- readonly required: boolean;
26
+ export type Shape = {
27
+ readonly schema: Readonly<Record<string, unknown>>;
28
+ readonly defs: Readonly<Record<string, unknown>>;
28
29
  };
29
30
  export type Definition = {
30
31
  readonly name: string;
31
- readonly file: string;
32
- readonly fields: Readonly<Record<string, FieldSpec>>;
32
+ readonly memberDocument: boolean;
33
+ readonly frontmatter: ValueFacts;
34
+ readonly fields: Readonly<Record<string, ValueFacts>>;
33
35
  readonly sections: Readonly<Record<string, SectionSpec>>;
36
+ readonly shape: Shape;
37
+ };
38
+ export type Failure = {
39
+ readonly rule: string;
40
+ readonly location?: string;
34
41
  };
35
- export declare function readDefinition(file: string, document: Document): Definition | Refusal;
42
+ export declare const JSON_TYPES: readonly JsonType[];
43
+ export declare const BUILT_IN_TYPE = "any";
44
+ export declare const ATTACHMENT = "attachment";
45
+ export declare function escapePointer(key: string): string;
46
+ export declare function refTarget(reference: string, defs: Readonly<Record<string, unknown>>): {
47
+ readonly name: string;
48
+ readonly node: unknown;
49
+ } | undefined;
50
+ export declare function valueFacts(node: unknown, defs: Readonly<Record<string, unknown>>): ValueFacts;
51
+ export declare function memberFacts(facts: ValueFacts, key: string): ValueFacts | undefined;
52
+ export declare function readSchema(text: string): VerifiedModel | Failure;
36
53
  //# sourceMappingURL=definition.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACzF;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,SAAS,GACjB,UAAU,GACV;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;CAC1D,CAAC;AA4FF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CA6BrF"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}