@metaobjectsdev/metadata 0.5.0-rc.1

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 (405) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +29 -0
  3. package/dist/attr-class-map.d.ts +26 -0
  4. package/dist/attr-class-map.d.ts.map +1 -0
  5. package/dist/attr-class-map.js +44 -0
  6. package/dist/attr-class-map.js.map +1 -0
  7. package/dist/attr-schema-validate.d.ts +9 -0
  8. package/dist/attr-schema-validate.d.ts.map +1 -0
  9. package/dist/attr-schema-validate.js +100 -0
  10. package/dist/attr-schema-validate.js.map +1 -0
  11. package/dist/constants.d.ts +208 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +419 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/core/attr/attr-constants.d.ts +12 -0
  16. package/dist/core/attr/attr-constants.d.ts.map +1 -0
  17. package/dist/core/attr/attr-constants.js +27 -0
  18. package/dist/core/attr/attr-constants.js.map +1 -0
  19. package/dist/core/attr/meta-attr-filter.d.ts +10 -0
  20. package/dist/core/attr/meta-attr-filter.d.ts.map +1 -0
  21. package/dist/core/attr/meta-attr-filter.js +56 -0
  22. package/dist/core/attr/meta-attr-filter.js.map +1 -0
  23. package/dist/core/attr/meta-attr-properties.d.ts +9 -0
  24. package/dist/core/attr/meta-attr-properties.d.ts.map +1 -0
  25. package/dist/core/attr/meta-attr-properties.js +22 -0
  26. package/dist/core/attr/meta-attr-properties.js.map +1 -0
  27. package/dist/core/attr/meta-attr-stringarray.d.ts +9 -0
  28. package/dist/core/attr/meta-attr-stringarray.d.ts.map +1 -0
  29. package/dist/core/attr/meta-attr-stringarray.js +29 -0
  30. package/dist/core/attr/meta-attr-stringarray.js.map +1 -0
  31. package/dist/core/attr/meta-attr.d.ts +37 -0
  32. package/dist/core/attr/meta-attr.d.ts.map +1 -0
  33. package/dist/core/attr/meta-attr.js +97 -0
  34. package/dist/core/attr/meta-attr.js.map +1 -0
  35. package/dist/core/export-json.d.ts +29 -0
  36. package/dist/core/export-json.d.ts.map +1 -0
  37. package/dist/core/export-json.js +45 -0
  38. package/dist/core/export-json.js.map +1 -0
  39. package/dist/core/field/field-constants.d.ts +40 -0
  40. package/dist/core/field/field-constants.d.ts.map +1 -0
  41. package/dist/core/field/field-constants.js +66 -0
  42. package/dist/core/field/field-constants.js.map +1 -0
  43. package/dist/core/field/field-schema.d.ts +6 -0
  44. package/dist/core/field/field-schema.d.ts.map +1 -0
  45. package/dist/core/field/field-schema.js +92 -0
  46. package/dist/core/field/field-schema.js.map +1 -0
  47. package/dist/core/field/meta-field.d.ts +50 -0
  48. package/dist/core/field/meta-field.d.ts.map +1 -0
  49. package/dist/core/field/meta-field.js +121 -0
  50. package/dist/core/field/meta-field.js.map +1 -0
  51. package/dist/core/file-meta-data-loader.d.ts +18 -0
  52. package/dist/core/file-meta-data-loader.d.ts.map +1 -0
  53. package/dist/core/file-meta-data-loader.js +81 -0
  54. package/dist/core/file-meta-data-loader.js.map +1 -0
  55. package/dist/core/file-source.d.ts +12 -0
  56. package/dist/core/file-source.d.ts.map +1 -0
  57. package/dist/core/file-source.js +46 -0
  58. package/dist/core/file-source.js.map +1 -0
  59. package/dist/core/identity/identity-constants.d.ts +19 -0
  60. package/dist/core/identity/identity-constants.d.ts.map +1 -0
  61. package/dist/core/identity/identity-constants.js +35 -0
  62. package/dist/core/identity/identity-constants.js.map +1 -0
  63. package/dist/core/identity/identity-schema.d.ts +6 -0
  64. package/dist/core/identity/identity-schema.d.ts.map +1 -0
  65. package/dist/core/identity/identity-schema.js +55 -0
  66. package/dist/core/identity/identity-schema.js.map +1 -0
  67. package/dist/core/identity/meta-identity.d.ts +71 -0
  68. package/dist/core/identity/meta-identity.d.ts.map +1 -0
  69. package/dist/core/identity/meta-identity.js +129 -0
  70. package/dist/core/identity/meta-identity.js.map +1 -0
  71. package/dist/core/index.d.ts +6 -0
  72. package/dist/core/index.d.ts.map +1 -0
  73. package/dist/core/index.js +11 -0
  74. package/dist/core/index.js.map +1 -0
  75. package/dist/core/object/meta-object.d.ts +39 -0
  76. package/dist/core/object/meta-object.d.ts.map +1 -0
  77. package/dist/core/object/meta-object.js +80 -0
  78. package/dist/core/object/meta-object.js.map +1 -0
  79. package/dist/core/object/object-constants.d.ts +5 -0
  80. package/dist/core/object/object-constants.d.ts.map +1 -0
  81. package/dist/core/object/object-constants.js +18 -0
  82. package/dist/core/object/object-constants.js.map +1 -0
  83. package/dist/core/object/object-schema.d.ts +4 -0
  84. package/dist/core/object/object-schema.d.ts.map +1 -0
  85. package/dist/core/object/object-schema.js +5 -0
  86. package/dist/core/object/object-schema.js.map +1 -0
  87. package/dist/core/parser-yaml.d.ts +3 -0
  88. package/dist/core/parser-yaml.d.ts.map +1 -0
  89. package/dist/core/parser-yaml.js +39 -0
  90. package/dist/core/parser-yaml.js.map +1 -0
  91. package/dist/core/query/query-constants.d.ts +20 -0
  92. package/dist/core/query/query-constants.d.ts.map +1 -0
  93. package/dist/core/query/query-constants.js +56 -0
  94. package/dist/core/query/query-constants.js.map +1 -0
  95. package/dist/core/relationship/find-reference.d.ts +22 -0
  96. package/dist/core/relationship/find-reference.d.ts.map +1 -0
  97. package/dist/core/relationship/find-reference.js +29 -0
  98. package/dist/core/relationship/find-reference.js.map +1 -0
  99. package/dist/core/relationship/meta-relationship.d.ts +11 -0
  100. package/dist/core/relationship/meta-relationship.d.ts.map +1 -0
  101. package/dist/core/relationship/meta-relationship.js +27 -0
  102. package/dist/core/relationship/meta-relationship.js.map +1 -0
  103. package/dist/core/relationship/relationship-constants.d.ts +14 -0
  104. package/dist/core/relationship/relationship-constants.d.ts.map +1 -0
  105. package/dist/core/relationship/relationship-constants.js +28 -0
  106. package/dist/core/relationship/relationship-constants.js.map +1 -0
  107. package/dist/core/relationship/relationship-schema.d.ts +4 -0
  108. package/dist/core/relationship/relationship-schema.d.ts.map +1 -0
  109. package/dist/core/relationship/relationship-schema.js +37 -0
  110. package/dist/core/relationship/relationship-schema.js.map +1 -0
  111. package/dist/core/validator/meta-validator.d.ts +29 -0
  112. package/dist/core/validator/meta-validator.d.ts.map +1 -0
  113. package/dist/core/validator/meta-validator.js +49 -0
  114. package/dist/core/validator/meta-validator.js.map +1 -0
  115. package/dist/core/validator/validator-constants.d.ts +11 -0
  116. package/dist/core/validator/validator-constants.d.ts.map +1 -0
  117. package/dist/core/validator/validator-constants.js +25 -0
  118. package/dist/core/validator/validator-constants.js.map +1 -0
  119. package/dist/core/validator/validator-schema.d.ts +4 -0
  120. package/dist/core/validator/validator-schema.d.ts.map +1 -0
  121. package/dist/core/validator/validator-schema.js +38 -0
  122. package/dist/core/validator/validator-schema.js.map +1 -0
  123. package/dist/core/yaml-desugar.d.ts +10 -0
  124. package/dist/core/yaml-desugar.d.ts.map +1 -0
  125. package/dist/core/yaml-desugar.js +99 -0
  126. package/dist/core/yaml-desugar.js.map +1 -0
  127. package/dist/core-attr-schemas.d.ts +22 -0
  128. package/dist/core-attr-schemas.d.ts.map +1 -0
  129. package/dist/core-attr-schemas.js +324 -0
  130. package/dist/core-attr-schemas.js.map +1 -0
  131. package/dist/core-types.d.ts +20 -0
  132. package/dist/core-types.d.ts.map +1 -0
  133. package/dist/core-types.js +225 -0
  134. package/dist/core-types.js.map +1 -0
  135. package/dist/data-converter.d.ts +17 -0
  136. package/dist/data-converter.d.ts.map +1 -0
  137. package/dist/data-converter.js +117 -0
  138. package/dist/data-converter.js.map +1 -0
  139. package/dist/data-type.d.ts +15 -0
  140. package/dist/data-type.d.ts.map +1 -0
  141. package/dist/data-type.js +25 -0
  142. package/dist/data-type.js.map +1 -0
  143. package/dist/db/db-attr-schemas.d.ts +8 -0
  144. package/dist/db/db-attr-schemas.d.ts.map +1 -0
  145. package/dist/db/db-attr-schemas.js +26 -0
  146. package/dist/db/db-attr-schemas.js.map +1 -0
  147. package/dist/db/db-provider.d.ts +3 -0
  148. package/dist/db/db-provider.d.ts.map +1 -0
  149. package/dist/db/db-provider.js +28 -0
  150. package/dist/db/db-provider.js.map +1 -0
  151. package/dist/errors.d.ts +26 -0
  152. package/dist/errors.d.ts.map +1 -0
  153. package/dist/errors.js +59 -0
  154. package/dist/errors.js.map +1 -0
  155. package/dist/index.d.ts +70 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +76 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/loader/meta-data-loader.d.ts +87 -0
  160. package/dist/loader/meta-data-loader.d.ts.map +1 -0
  161. package/dist/loader/meta-data-loader.js +232 -0
  162. package/dist/loader/meta-data-loader.js.map +1 -0
  163. package/dist/loader/meta-data-source.d.ts +23 -0
  164. package/dist/loader/meta-data-source.d.ts.map +1 -0
  165. package/dist/loader/meta-data-source.js +20 -0
  166. package/dist/loader/meta-data-source.js.map +1 -0
  167. package/dist/loader/validation-passes.d.ts +7 -0
  168. package/dist/loader/validation-passes.d.ts.map +1 -0
  169. package/dist/loader/validation-passes.js +244 -0
  170. package/dist/loader/validation-passes.js.map +1 -0
  171. package/dist/meta/find-reference.d.ts +22 -0
  172. package/dist/meta/find-reference.d.ts.map +1 -0
  173. package/dist/meta/find-reference.js +29 -0
  174. package/dist/meta/find-reference.js.map +1 -0
  175. package/dist/meta/meta-attr.d.ts +8 -0
  176. package/dist/meta/meta-attr.d.ts.map +1 -0
  177. package/dist/meta/meta-attr.js +17 -0
  178. package/dist/meta/meta-attr.js.map +1 -0
  179. package/dist/meta/meta-data.d.ts +107 -0
  180. package/dist/meta/meta-data.d.ts.map +1 -0
  181. package/dist/meta/meta-data.js +302 -0
  182. package/dist/meta/meta-data.js.map +1 -0
  183. package/dist/meta/meta-field.d.ts +48 -0
  184. package/dist/meta/meta-field.d.ts.map +1 -0
  185. package/dist/meta/meta-field.js +94 -0
  186. package/dist/meta/meta-field.js.map +1 -0
  187. package/dist/meta/meta-identity.d.ts +71 -0
  188. package/dist/meta/meta-identity.d.ts.map +1 -0
  189. package/dist/meta/meta-identity.js +129 -0
  190. package/dist/meta/meta-identity.js.map +1 -0
  191. package/dist/meta/meta-layout.d.ts +23 -0
  192. package/dist/meta/meta-layout.d.ts.map +1 -0
  193. package/dist/meta/meta-layout.js +45 -0
  194. package/dist/meta/meta-layout.js.map +1 -0
  195. package/dist/meta/meta-object.d.ts +40 -0
  196. package/dist/meta/meta-object.d.ts.map +1 -0
  197. package/dist/meta/meta-object.js +81 -0
  198. package/dist/meta/meta-object.js.map +1 -0
  199. package/dist/meta/meta-origin.d.ts +32 -0
  200. package/dist/meta/meta-origin.d.ts.map +1 -0
  201. package/dist/meta/meta-origin.js +55 -0
  202. package/dist/meta/meta-origin.js.map +1 -0
  203. package/dist/meta/meta-relationship.d.ts +11 -0
  204. package/dist/meta/meta-relationship.d.ts.map +1 -0
  205. package/dist/meta/meta-relationship.js +27 -0
  206. package/dist/meta/meta-relationship.js.map +1 -0
  207. package/dist/meta/meta-root.d.ts +12 -0
  208. package/dist/meta/meta-root.d.ts.map +1 -0
  209. package/dist/meta/meta-root.js +24 -0
  210. package/dist/meta/meta-root.js.map +1 -0
  211. package/dist/meta/meta-source.d.ts +18 -0
  212. package/dist/meta/meta-source.d.ts.map +1 -0
  213. package/dist/meta/meta-source.js +31 -0
  214. package/dist/meta/meta-source.js.map +1 -0
  215. package/dist/meta/meta-validator.d.ts +29 -0
  216. package/dist/meta/meta-validator.d.ts.map +1 -0
  217. package/dist/meta/meta-validator.js +49 -0
  218. package/dist/meta/meta-validator.js.map +1 -0
  219. package/dist/meta/meta-view.d.ts +4 -0
  220. package/dist/meta/meta-view.d.ts.map +1 -0
  221. package/dist/meta/meta-view.js +8 -0
  222. package/dist/meta/meta-view.js.map +1 -0
  223. package/dist/naming.d.ts +27 -0
  224. package/dist/naming.d.ts.map +1 -0
  225. package/dist/naming.js +72 -0
  226. package/dist/naming.js.map +1 -0
  227. package/dist/object-serializer.d.ts +10 -0
  228. package/dist/object-serializer.d.ts.map +1 -0
  229. package/dist/object-serializer.js +128 -0
  230. package/dist/object-serializer.js.map +1 -0
  231. package/dist/overlay.d.ts +2 -0
  232. package/dist/overlay.d.ts.map +1 -0
  233. package/dist/overlay.js +6 -0
  234. package/dist/overlay.js.map +1 -0
  235. package/dist/parser-core.d.ts +47 -0
  236. package/dist/parser-core.d.ts.map +1 -0
  237. package/dist/parser-core.js +516 -0
  238. package/dist/parser-core.js.map +1 -0
  239. package/dist/parser-json.d.ts +4 -0
  240. package/dist/parser-json.d.ts.map +1 -0
  241. package/dist/parser-json.js +19 -0
  242. package/dist/parser-json.js.map +1 -0
  243. package/dist/persistence/db/db-attr-schemas.d.ts +8 -0
  244. package/dist/persistence/db/db-attr-schemas.d.ts.map +1 -0
  245. package/dist/persistence/db/db-attr-schemas.js +28 -0
  246. package/dist/persistence/db/db-attr-schemas.js.map +1 -0
  247. package/dist/persistence/db/db-constants.d.ts +5 -0
  248. package/dist/persistence/db/db-constants.d.ts.map +1 -0
  249. package/dist/persistence/db/db-constants.js +6 -0
  250. package/dist/persistence/db/db-constants.js.map +1 -0
  251. package/dist/persistence/db/db-provider.d.ts +3 -0
  252. package/dist/persistence/db/db-provider.d.ts.map +1 -0
  253. package/dist/persistence/db/db-provider.js +29 -0
  254. package/dist/persistence/db/db-provider.js.map +1 -0
  255. package/dist/persistence/db/db-schema.d.ts +8 -0
  256. package/dist/persistence/db/db-schema.d.ts.map +1 -0
  257. package/dist/persistence/db/db-schema.js +27 -0
  258. package/dist/persistence/db/db-schema.js.map +1 -0
  259. package/dist/persistence/origin/meta-origin.d.ts +32 -0
  260. package/dist/persistence/origin/meta-origin.d.ts.map +1 -0
  261. package/dist/persistence/origin/meta-origin.js +55 -0
  262. package/dist/persistence/origin/meta-origin.js.map +1 -0
  263. package/dist/persistence/origin/origin-constants.d.ts +12 -0
  264. package/dist/persistence/origin/origin-constants.d.ts.map +1 -0
  265. package/dist/persistence/origin/origin-constants.js +27 -0
  266. package/dist/persistence/origin/origin-constants.js.map +1 -0
  267. package/dist/persistence/origin/origin-schema.d.ts +4 -0
  268. package/dist/persistence/origin/origin-schema.d.ts.map +1 -0
  269. package/dist/persistence/origin/origin-schema.js +49 -0
  270. package/dist/persistence/origin/origin-schema.js.map +1 -0
  271. package/dist/persistence/source/meta-source.d.ts +18 -0
  272. package/dist/persistence/source/meta-source.d.ts.map +1 -0
  273. package/dist/persistence/source/meta-source.js +31 -0
  274. package/dist/persistence/source/meta-source.js.map +1 -0
  275. package/dist/persistence/source/source-constants.d.ts +16 -0
  276. package/dist/persistence/source/source-constants.d.ts.map +1 -0
  277. package/dist/persistence/source/source-constants.js +28 -0
  278. package/dist/persistence/source/source-constants.js.map +1 -0
  279. package/dist/presentation/layout/layout-constants.d.ts +10 -0
  280. package/dist/presentation/layout/layout-constants.d.ts.map +1 -0
  281. package/dist/presentation/layout/layout-constants.js +21 -0
  282. package/dist/presentation/layout/layout-constants.js.map +1 -0
  283. package/dist/presentation/layout/layout-schema.d.ts +4 -0
  284. package/dist/presentation/layout/layout-schema.d.ts.map +1 -0
  285. package/dist/presentation/layout/layout-schema.js +46 -0
  286. package/dist/presentation/layout/layout-schema.js.map +1 -0
  287. package/dist/presentation/layout/meta-layout.d.ts +23 -0
  288. package/dist/presentation/layout/meta-layout.d.ts.map +1 -0
  289. package/dist/presentation/layout/meta-layout.js +47 -0
  290. package/dist/presentation/layout/meta-layout.js.map +1 -0
  291. package/dist/presentation/view/meta-view.d.ts +4 -0
  292. package/dist/presentation/view/meta-view.d.ts.map +1 -0
  293. package/dist/presentation/view/meta-view.js +8 -0
  294. package/dist/presentation/view/meta-view.js.map +1 -0
  295. package/dist/presentation/view/view-constants.d.ts +20 -0
  296. package/dist/presentation/view/view-constants.d.ts.map +1 -0
  297. package/dist/presentation/view/view-constants.js +47 -0
  298. package/dist/presentation/view/view-constants.js.map +1 -0
  299. package/dist/presentation/view/view-schema.d.ts +4 -0
  300. package/dist/presentation/view/view-schema.d.ts.map +1 -0
  301. package/dist/presentation/view/view-schema.js +15 -0
  302. package/dist/presentation/view/view-schema.js.map +1 -0
  303. package/dist/provider.d.ts +20 -0
  304. package/dist/provider.d.ts.map +1 -0
  305. package/dist/provider.js +58 -0
  306. package/dist/provider.js.map +1 -0
  307. package/dist/registry.d.ts +89 -0
  308. package/dist/registry.d.ts.map +1 -0
  309. package/dist/registry.js +107 -0
  310. package/dist/registry.js.map +1 -0
  311. package/dist/serializer-json.d.ts +16 -0
  312. package/dist/serializer-json.d.ts.map +1 -0
  313. package/dist/serializer-json.js +154 -0
  314. package/dist/serializer-json.js.map +1 -0
  315. package/dist/shared/base-types.d.ts +23 -0
  316. package/dist/shared/base-types.d.ts.map +1 -0
  317. package/dist/shared/base-types.js +43 -0
  318. package/dist/shared/base-types.js.map +1 -0
  319. package/dist/shared/meta-data.d.ts +123 -0
  320. package/dist/shared/meta-data.d.ts.map +1 -0
  321. package/dist/shared/meta-data.js +365 -0
  322. package/dist/shared/meta-data.js.map +1 -0
  323. package/dist/shared/meta-root.d.ts +12 -0
  324. package/dist/shared/meta-root.d.ts.map +1 -0
  325. package/dist/shared/meta-root.js +24 -0
  326. package/dist/shared/meta-root.js.map +1 -0
  327. package/dist/shared/structural.d.ts +20 -0
  328. package/dist/shared/structural.d.ts.map +1 -0
  329. package/dist/shared/structural.js +49 -0
  330. package/dist/shared/structural.js.map +1 -0
  331. package/dist/subtype-rules.d.ts +8 -0
  332. package/dist/subtype-rules.d.ts.map +1 -0
  333. package/dist/subtype-rules.js +34 -0
  334. package/dist/subtype-rules.js.map +1 -0
  335. package/dist/super-resolve.d.ts +34 -0
  336. package/dist/super-resolve.d.ts.map +1 -0
  337. package/dist/super-resolve.js +124 -0
  338. package/dist/super-resolve.js.map +1 -0
  339. package/package.json +50 -0
  340. package/src/attr-class-map.ts +64 -0
  341. package/src/attr-schema-validate.ts +134 -0
  342. package/src/core/attr/attr-constants.ts +31 -0
  343. package/src/core/attr/meta-attr-filter.ts +67 -0
  344. package/src/core/attr/meta-attr-properties.ts +26 -0
  345. package/src/core/attr/meta-attr-stringarray.ts +31 -0
  346. package/src/core/attr/meta-attr.ts +125 -0
  347. package/src/core/export-json.ts +66 -0
  348. package/src/core/field/field-constants.ts +79 -0
  349. package/src/core/field/field-schema.ts +121 -0
  350. package/src/core/field/meta-field.ts +179 -0
  351. package/src/core/file-meta-data-loader.ts +89 -0
  352. package/src/core/file-source.ts +52 -0
  353. package/src/core/identity/identity-constants.ts +44 -0
  354. package/src/core/identity/identity-schema.ts +80 -0
  355. package/src/core/identity/meta-identity.ts +148 -0
  356. package/src/core/index.ts +12 -0
  357. package/src/core/object/meta-object.ts +151 -0
  358. package/src/core/object/object-constants.ts +21 -0
  359. package/src/core/object/object-schema.ts +7 -0
  360. package/src/core/parser-yaml.ts +54 -0
  361. package/src/core/query/query-constants.ts +66 -0
  362. package/src/core/relationship/find-reference.ts +44 -0
  363. package/src/core/relationship/meta-relationship.ts +36 -0
  364. package/src/core/relationship/relationship-constants.ts +38 -0
  365. package/src/core/relationship/relationship-schema.ts +49 -0
  366. package/src/core/validator/meta-validator.ts +62 -0
  367. package/src/core/validator/validator-constants.ts +31 -0
  368. package/src/core/validator/validator-schema.ts +50 -0
  369. package/src/core/yaml-desugar.ts +145 -0
  370. package/src/core-types.ts +329 -0
  371. package/src/data-converter.ts +125 -0
  372. package/src/data-type.ts +33 -0
  373. package/src/errors.ts +68 -0
  374. package/src/index.ts +165 -0
  375. package/src/loader/meta-data-loader.ts +307 -0
  376. package/src/loader/meta-data-source.ts +35 -0
  377. package/src/loader/validation-passes.ts +370 -0
  378. package/src/naming.ts +86 -0
  379. package/src/object-serializer.ts +153 -0
  380. package/src/overlay.ts +5 -0
  381. package/src/parser-core.ts +815 -0
  382. package/src/parser-json.ts +28 -0
  383. package/src/persistence/db/db-constants.ts +6 -0
  384. package/src/persistence/db/db-provider.ts +36 -0
  385. package/src/persistence/db/db-schema.ts +40 -0
  386. package/src/persistence/origin/meta-origin.ts +67 -0
  387. package/src/persistence/origin/origin-constants.ts +35 -0
  388. package/src/persistence/origin/origin-schema.ts +66 -0
  389. package/src/persistence/source/meta-source.ts +38 -0
  390. package/src/persistence/source/source-constants.ts +35 -0
  391. package/src/presentation/layout/layout-constants.ts +27 -0
  392. package/src/presentation/layout/layout-schema.ts +62 -0
  393. package/src/presentation/layout/meta-layout.ts +61 -0
  394. package/src/presentation/view/meta-view.ts +8 -0
  395. package/src/presentation/view/view-constants.ts +53 -0
  396. package/src/presentation/view/view-schema.ts +21 -0
  397. package/src/provider.ts +85 -0
  398. package/src/registry.ts +190 -0
  399. package/src/serializer-json.ts +210 -0
  400. package/src/shared/base-types.ts +52 -0
  401. package/src/shared/meta-data.ts +443 -0
  402. package/src/shared/meta-root.ts +33 -0
  403. package/src/shared/structural.ts +62 -0
  404. package/src/subtype-rules.ts +56 -0
  405. package/src/super-resolve.ts +147 -0
@@ -0,0 +1,66 @@
1
+ // Query concern constants — filter operators, sort order values.
2
+ //
3
+ // NOTE: `query` is NOT a metamodel node type — it has no subtype, schema, or
4
+ // accessor. It's a cross-cutting vocabulary grouping for query/filter helpers
5
+ // consumed by both core/field (@filterable/@sortable) and presentation/layout
6
+ // (dataGrid @defaultSortOrder). Co-located here as the most foundational shared
7
+ // home; intentional, not an incomplete migration.
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Filter operators (Project D) — shared source of truth across server +
11
+ // codegen. Each subtype declares which operators are legal for fields of that
12
+ // type. Server allowlist generation + TS type generation + codegen-time grid
13
+ // validation all import from here.
14
+ // ---------------------------------------------------------------------------
15
+
16
+ // Individual operator constants — used by the parse-time desugar in
17
+ // parser-core.ts. Must stay in sync with FILTER_OPS below.
18
+ export const FILTER_OP_EQ = "eq";
19
+ export const FILTER_OP_NE = "ne";
20
+ export const FILTER_OP_GT = "gt";
21
+ export const FILTER_OP_GTE = "gte";
22
+ export const FILTER_OP_LT = "lt";
23
+ export const FILTER_OP_LTE = "lte";
24
+ export const FILTER_OP_IN = "in";
25
+ export const FILTER_OP_LIKE = "like";
26
+ export const FILTER_OP_IS_NULL = "isNull";
27
+
28
+ // Composition-key constants — used by desugarFilterObject in meta-attr-filter.ts.
29
+ export const FILTER_COMPOSE_OR = "or";
30
+ export const FILTER_COMPOSE_AND = "and";
31
+
32
+ export const FILTER_OPS = [
33
+ FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE,
34
+ FILTER_OP_IN, FILTER_OP_LIKE, FILTER_OP_IS_NULL,
35
+ ] as const;
36
+ export type FilterOp = (typeof FILTER_OPS)[number];
37
+
38
+ export const OPS_BY_SUBTYPE: Readonly<Record<string, readonly FilterOp[]>> = {
39
+ string: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_IN, FILTER_OP_LIKE, FILTER_OP_IS_NULL],
40
+ int: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
41
+ short: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
42
+ byte: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
43
+ long: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
44
+ double: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
45
+ float: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
46
+ decimal: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
47
+ boolean: [FILTER_OP_EQ, FILTER_OP_IS_NULL],
48
+ date: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
49
+ time: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
50
+ timestamp: [FILTER_OP_EQ, FILTER_OP_NE, FILTER_OP_GT, FILTER_OP_GTE, FILTER_OP_LT, FILTER_OP_LTE, FILTER_OP_IN, FILTER_OP_IS_NULL],
51
+ } as const;
52
+
53
+ export function opsForSubType(subType: string): readonly FilterOp[] {
54
+ return OPS_BY_SUBTYPE[subType] ?? [];
55
+ }
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Sort order values (used by @sortableDefaultOrder on fields and
59
+ // @defaultSortOrder on dataGrid layouts)
60
+ // ---------------------------------------------------------------------------
61
+
62
+ export const SORT_ORDER_ASC = "asc";
63
+ export const SORT_ORDER_DESC = "desc";
64
+
65
+ export const SORT_ORDER_VALUES = [SORT_ORDER_ASC, SORT_ORDER_DESC] as const;
66
+ export type SortOrderValue = (typeof SORT_ORDER_VALUES)[number];
@@ -0,0 +1,44 @@
1
+ // Cross-entity reference lookup — anchored to identity.reference declarations.
2
+ //
3
+ // Given a relationship-style query "is there a reference between A and B?",
4
+ // walk A's and B's identity.reference children to find the side that physically
5
+ // holds the reference. This is the single source of truth for FK direction
6
+ // across projection codegen, Drizzle schema emit, relations() blocks, and
7
+ // migration schema comparison.
8
+
9
+ import type { MetaObject } from "../object/meta-object.js";
10
+ import type { MetaReferenceIdentity } from "../identity/meta-identity.js";
11
+ import { stripPackage } from "../../naming.js";
12
+
13
+ export interface ReferenceLookup {
14
+ /** The entity whose identity.reference points at `other`. */
15
+ readonly holder: MetaObject;
16
+ /** The other side of the reference. */
17
+ readonly other: MetaObject;
18
+ /** The matching identity.reference declaration on `holder`. */
19
+ readonly referenceIdentity: MetaReferenceIdentity;
20
+ }
21
+
22
+ /**
23
+ * Find an identity.reference on either `a` or `b` whose @references targets the
24
+ * other side. Returns undefined if neither side declares one.
25
+ *
26
+ * Comparison is package-insensitive: `@references` may be a bare entity name
27
+ * ("User") or a fully-qualified one ("pkg::User"); both match `other.name`.
28
+ *
29
+ * If both sides declare references targeting each other (rare, but legal for
30
+ * mutual 1:1), returns the first found, walking `a` first.
31
+ */
32
+ export function findReferenceBetween(
33
+ a: MetaObject,
34
+ b: MetaObject,
35
+ ): ReferenceLookup | undefined {
36
+ for (const [holder, other] of [[a, b], [b, a]] as const) {
37
+ for (const ref of holder.referenceIdentities()) {
38
+ if (stripPackage(ref.targetEntity) === other.name) {
39
+ return { holder, other, referenceIdentity: ref };
40
+ }
41
+ }
42
+ }
43
+ return undefined;
44
+ }
@@ -0,0 +1,36 @@
1
+ // MetaRelationship — concrete node class for type=relationship nodes.
2
+ //
3
+ // Extends MetaData directly: no model wrapper, no metaOf() indirection.
4
+
5
+ import { MetaData } from "../../shared/meta-data.js";
6
+ import {
7
+ RELATIONSHIP_ATTR_CARDINALITY,
8
+ RELATIONSHIP_ATTR_OBJECT_REF,
9
+ RELATIONSHIP_ATTR_JOIN_ENTITY,
10
+ RELATIONSHIP_ATTR_JOIN_FIELDS,
11
+ } from "./relationship-constants.js";
12
+
13
+ export class MetaRelationship extends MetaData {
14
+ get cardinality(): string | undefined {
15
+ const v = this.ownAttr(RELATIONSHIP_ATTR_CARDINALITY);
16
+ return typeof v === "string" ? v : undefined;
17
+ }
18
+
19
+ /** FQN of the target object (e.g., "acme::vehicle::Car"). */
20
+ get objectRef(): string | undefined {
21
+ const v = this.ownAttr(RELATIONSHIP_ATTR_OBJECT_REF);
22
+ return typeof v === "string" ? v : undefined;
23
+ }
24
+
25
+ /** Join-table entity name for N:M relationships. */
26
+ get joinEntity(): string | undefined {
27
+ const v = this.ownAttr(RELATIONSHIP_ATTR_JOIN_ENTITY);
28
+ return typeof v === "string" ? v : undefined;
29
+ }
30
+
31
+ /** Join-table column names for N:M relationships. */
32
+ get joinFields(): string[] {
33
+ const f = this.ownAttr(RELATIONSHIP_ATTR_JOIN_FIELDS);
34
+ return Array.isArray(f) ? (f as string[]) : [];
35
+ }
36
+ }
@@ -0,0 +1,38 @@
1
+ // Relationship concern constants — subtypes, attr keys, and cardinality values.
2
+
3
+ import { SUBTYPE_BASE } from "../../shared/base-types.js";
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Relationship subtypes (4)
7
+ // ---------------------------------------------------------------------------
8
+
9
+ export const RELATIONSHIP_SUBTYPE_ASSOCIATION = "association";
10
+ export const RELATIONSHIP_SUBTYPE_AGGREGATION = "aggregation";
11
+ export const RELATIONSHIP_SUBTYPE_COMPOSITION = "composition";
12
+
13
+ export const RELATIONSHIP_SUBTYPES = [
14
+ SUBTYPE_BASE,
15
+ RELATIONSHIP_SUBTYPE_ASSOCIATION,
16
+ RELATIONSHIP_SUBTYPE_AGGREGATION,
17
+ RELATIONSHIP_SUBTYPE_COMPOSITION,
18
+ ] as const;
19
+ export type RelationshipSubType = (typeof RELATIONSHIP_SUBTYPES)[number];
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Relationship attrs
23
+ // ---------------------------------------------------------------------------
24
+
25
+ export const RELATIONSHIP_ATTR_CARDINALITY = "cardinality";
26
+ export const RELATIONSHIP_ATTR_OBJECT_REF = "objectRef";
27
+ export const RELATIONSHIP_ATTR_JOIN_ENTITY = "joinEntity"; // N:M cardinality
28
+ export const RELATIONSHIP_ATTR_JOIN_FIELDS = "joinFields"; // N:M cardinality
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Relationship cardinality values (for RELATIONSHIP_ATTR_CARDINALITY)
32
+ // ---------------------------------------------------------------------------
33
+
34
+ export const CARDINALITY_ONE = "one";
35
+ export const CARDINALITY_MANY = "many";
36
+
37
+ export const CARDINALITY_VALUES = [CARDINALITY_ONE, CARDINALITY_MANY] as const;
38
+ export type CardinalityValue = (typeof CARDINALITY_VALUES)[number];
@@ -0,0 +1,49 @@
1
+ // Relationship attribute schemas — attrs common to every relationship subtype.
2
+ // Consumed by registerCoreTypes().
3
+
4
+ import type { AttrSchema } from "../../registry.js";
5
+ import {
6
+ ATTR_SUBTYPE_STRING,
7
+ ATTR_SUBTYPE_STRINGARRAY,
8
+ } from "../attr/attr-constants.js";
9
+ import {
10
+ RELATIONSHIP_ATTR_CARDINALITY,
11
+ RELATIONSHIP_ATTR_OBJECT_REF,
12
+ RELATIONSHIP_ATTR_JOIN_ENTITY,
13
+ RELATIONSHIP_ATTR_JOIN_FIELDS,
14
+ } from "./relationship-constants.js";
15
+
16
+ /** Attrs common to every relationship subtype. */
17
+ export const relationshipAttrs: AttrSchema[] = [
18
+ {
19
+ name: RELATIONSHIP_ATTR_CARDINALITY,
20
+ valueType: ATTR_SUBTYPE_STRING,
21
+ required: false,
22
+ // No allowedValues: @cardinality is an open string at the metamodel level
23
+ // (MetaRelationship.cardinality returns `string | undefined`). The Java
24
+ // canonical fixtures use composite forms such as "many-to-one"; the
25
+ // CARDINALITY_VALUES ("one"/"many") constant is a TS codegen convenience,
26
+ // NOT a closed metamodel enum. A3 must not reject the Java-canonical values.
27
+ description:
28
+ "Cardinality of the relationship target (e.g. 'one', 'many', 'many-to-one').",
29
+ },
30
+ {
31
+ name: RELATIONSHIP_ATTR_OBJECT_REF,
32
+ valueType: ATTR_SUBTYPE_STRING,
33
+ required: false,
34
+ description:
35
+ "Name or fully-qualified name of the target object the relationship points to (e.g. 'Week' or 'acme::vehicle::Car').",
36
+ },
37
+ {
38
+ name: RELATIONSHIP_ATTR_JOIN_ENTITY,
39
+ valueType: ATTR_SUBTYPE_STRING,
40
+ required: false,
41
+ description: "Join-table entity name for N:M relationships.",
42
+ },
43
+ {
44
+ name: RELATIONSHIP_ATTR_JOIN_FIELDS,
45
+ valueType: ATTR_SUBTYPE_STRINGARRAY,
46
+ required: false,
47
+ description: "Join-table column names for N:M relationships.",
48
+ },
49
+ ];
@@ -0,0 +1,62 @@
1
+ // MetaValidator — concrete node class for type=validator nodes.
2
+ // Subtype classes (Required, Length, Regex, Numeric, Array) are co-located.
3
+ //
4
+ // Extends MetaData directly: no model wrapper, no metaOf() indirection.
5
+
6
+ import { MetaData } from "../../shared/meta-data.js";
7
+ import {
8
+ VALIDATOR_SUBTYPE_REQUIRED,
9
+ VALIDATOR_SUBTYPE_LENGTH,
10
+ VALIDATOR_SUBTYPE_REGEX,
11
+ VALIDATOR_ATTR_PATTERN,
12
+ VALIDATOR_ATTR_MIN,
13
+ VALIDATOR_ATTR_MAX,
14
+ } from "./validator-constants.js";
15
+
16
+ export class MetaValidator extends MetaData {
17
+ /**
18
+ * Numeric range — shared by length, numeric, and array validators.
19
+ * (Pattern moves to MetaRegexValidator; required validators have no extra attrs.)
20
+ */
21
+ get min(): number | undefined {
22
+ const v = this.ownAttr(VALIDATOR_ATTR_MIN);
23
+ return typeof v === "number" ? v : undefined;
24
+ }
25
+
26
+ get max(): number | undefined {
27
+ const v = this.ownAttr(VALIDATOR_ATTR_MAX);
28
+ return typeof v === "number" ? v : undefined;
29
+ }
30
+
31
+ isRequired(): boolean {
32
+ return this.subType === VALIDATOR_SUBTYPE_REQUIRED;
33
+ }
34
+
35
+ isLength(): boolean {
36
+ return this.subType === VALIDATOR_SUBTYPE_LENGTH;
37
+ }
38
+
39
+ isRegex(): boolean {
40
+ return this.subType === VALIDATOR_SUBTYPE_REGEX;
41
+ }
42
+ }
43
+
44
+ /** Required validator (no extra attrs; subtype class exists for instanceof narrowing). */
45
+ export class MetaRequiredValidator extends MetaValidator {}
46
+
47
+ /** Length validator: min/max are string/array length bounds. */
48
+ export class MetaLengthValidator extends MetaValidator {}
49
+
50
+ /** Regex validator: carries the pattern. */
51
+ export class MetaRegexValidator extends MetaValidator {
52
+ get pattern(): string | undefined {
53
+ const v = this.ownAttr(VALIDATOR_ATTR_PATTERN);
54
+ return typeof v === "string" ? v : undefined;
55
+ }
56
+ }
57
+
58
+ /** Numeric validator: min/max are value bounds. */
59
+ export class MetaNumericValidator extends MetaValidator {}
60
+
61
+ /** Array validator: min/max are element-count bounds. */
62
+ export class MetaArrayValidator extends MetaValidator {}
@@ -0,0 +1,31 @@
1
+ // Validator concern constants — subtypes and attr keys for the validator.* type family.
2
+
3
+ import { SUBTYPE_BASE } from "../../shared/base-types.js";
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Validator subtypes (6)
7
+ // ---------------------------------------------------------------------------
8
+
9
+ export const VALIDATOR_SUBTYPE_REQUIRED = "required";
10
+ export const VALIDATOR_SUBTYPE_LENGTH = "length";
11
+ export const VALIDATOR_SUBTYPE_REGEX = "regex";
12
+ export const VALIDATOR_SUBTYPE_NUMERIC = "numeric";
13
+ export const VALIDATOR_SUBTYPE_ARRAY = "array";
14
+
15
+ export const VALIDATOR_SUBTYPES = [
16
+ SUBTYPE_BASE,
17
+ VALIDATOR_SUBTYPE_REQUIRED,
18
+ VALIDATOR_SUBTYPE_LENGTH,
19
+ VALIDATOR_SUBTYPE_REGEX,
20
+ VALIDATOR_SUBTYPE_NUMERIC,
21
+ VALIDATOR_SUBTYPE_ARRAY,
22
+ ] as const;
23
+ export type ValidatorSubType = (typeof VALIDATOR_SUBTYPES)[number];
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Validator attr keys (used by codegen-ts when reading validator children)
27
+ // ---------------------------------------------------------------------------
28
+
29
+ export const VALIDATOR_ATTR_PATTERN = "pattern";
30
+ export const VALIDATOR_ATTR_MIN = "min";
31
+ export const VALIDATOR_ATTR_MAX = "max";
@@ -0,0 +1,50 @@
1
+ // Validator attribute schemas — per-subtype attr inventories for validator types.
2
+ // Consumed by registerCoreTypes().
3
+
4
+ import type { AttrSchema } from "../../registry.js";
5
+ import { ATTR_SUBTYPE_INT, ATTR_SUBTYPE_STRING } from "../attr/attr-constants.js";
6
+ import { SUBTYPE_BASE } from "../../shared/base-types.js";
7
+ import {
8
+ VALIDATOR_SUBTYPE_REQUIRED,
9
+ VALIDATOR_SUBTYPE_LENGTH,
10
+ VALIDATOR_SUBTYPE_REGEX,
11
+ VALIDATOR_SUBTYPE_NUMERIC,
12
+ VALIDATOR_SUBTYPE_ARRAY,
13
+ VALIDATOR_ATTR_PATTERN,
14
+ VALIDATOR_ATTR_MIN,
15
+ VALIDATOR_ATTR_MAX,
16
+ } from "./validator-constants.js";
17
+
18
+ /** @min / @max shared by length, numeric, array, and the base validator. */
19
+ const minMaxValidatorAttrs: AttrSchema[] = [
20
+ {
21
+ name: VALIDATOR_ATTR_MIN,
22
+ valueType: ATTR_SUBTYPE_INT,
23
+ required: false,
24
+ description: "Minimum allowed value (length, numeric value, or array element count depending on the validator subtype).",
25
+ },
26
+ {
27
+ name: VALIDATOR_ATTR_MAX,
28
+ valueType: ATTR_SUBTYPE_INT,
29
+ required: false,
30
+ description: "Maximum allowed value (length, numeric value, or array element count depending on the validator subtype).",
31
+ },
32
+ ];
33
+
34
+ /** Attrs per validator subtype. Required uses none; regex adds @pattern. */
35
+ export const VALIDATOR_ATTRS_MAP = new Map<string, AttrSchema[]>([
36
+ [SUBTYPE_BASE, [...minMaxValidatorAttrs]],
37
+ [VALIDATOR_SUBTYPE_REQUIRED, []],
38
+ [VALIDATOR_SUBTYPE_LENGTH, [...minMaxValidatorAttrs]],
39
+ [VALIDATOR_SUBTYPE_REGEX, [
40
+ ...minMaxValidatorAttrs,
41
+ {
42
+ name: VALIDATOR_ATTR_PATTERN,
43
+ valueType: ATTR_SUBTYPE_STRING,
44
+ required: false,
45
+ description: "Regular expression the value must match.",
46
+ },
47
+ ]],
48
+ [VALIDATOR_SUBTYPE_NUMERIC, [...minMaxValidatorAttrs]],
49
+ [VALIDATOR_SUBTYPE_ARRAY, [...minMaxValidatorAttrs]],
50
+ ]);
@@ -0,0 +1,145 @@
1
+ // YAML authoring → canonical desugar.
2
+ //
3
+ // desugar() turns the sugared authoring object (from yaml.parse) into the
4
+ // canonical-shaped object that buildTree (parser-core.ts) consumes. It applies
5
+ // the four format-spec sugar rules:
6
+ // 1. Fused key, subType omittable — a bare `type` key resolves to the type's
7
+ // registry default subType.
8
+ // 2. Scalar-or-map body — a scalar body becomes { name: <scalar> }.
9
+ // 3. Omit empties — absent keys stay absent; the desugar invents nothing.
10
+ // 4. `[]` arrays — a trailing `[]` on the key strips to isArray: true.
11
+ //
12
+ // Pure and total: it never throws. Malformed fragments are collected as error
13
+ // strings and a safe placeholder is substituted so buildTree does not
14
+ // double-report.
15
+
16
+ import type { TypeRegistry } from "../registry.js";
17
+ import {
18
+ RESERVED_KEY_CHILDREN,
19
+ RESERVED_KEY_NAME,
20
+ RESERVED_KEY_IS_ARRAY,
21
+ TYPE_SUBTYPE_SEPARATOR,
22
+ } from "../shared/structural.js";
23
+
24
+ const ARRAY_SUFFIX = "[]";
25
+
26
+ export interface DesugarResult {
27
+ /** The canonical-shaped object; `{}` when the document was unusable. */
28
+ canonical: Record<string, unknown>;
29
+ /** Collected desugar problems (never thrown). */
30
+ errors: string[];
31
+ }
32
+
33
+ /** Desugar a parsed-YAML authoring document into a canonical-shaped object. */
34
+ export function desugar(input: unknown, registry: TypeRegistry): DesugarResult {
35
+ const errors: string[] = [];
36
+ const node = desugarNode(input, registry, errors, "<root>");
37
+ return { canonical: node ?? {}, errors };
38
+ }
39
+
40
+ // Desugar one node — a single-key mapping { "type.subType": body }.
41
+ // Returns the canonical node object, or undefined if `input` is not a usable
42
+ // node (the caller substitutes a placeholder).
43
+ function desugarNode(
44
+ input: unknown,
45
+ registry: TypeRegistry,
46
+ errors: string[],
47
+ path: string,
48
+ ): Record<string, unknown> | undefined {
49
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
50
+ errors.push(`Node at ${path} must be a mapping with one type key`);
51
+ return undefined;
52
+ }
53
+
54
+ const entries = Object.keys(input as Record<string, unknown>);
55
+ if (entries.length !== 1) {
56
+ errors.push(
57
+ `Node at ${path} must have exactly one type key (found: ${
58
+ entries.length === 0 ? "none" : entries.join(", ")
59
+ })`,
60
+ );
61
+ return undefined;
62
+ }
63
+
64
+ const rawKey = entries[0]!;
65
+ const rawBody = (input as Record<string, unknown>)[rawKey];
66
+
67
+ // Rule 4: a trailing "[]" on the key → isArray.
68
+ let key = rawKey;
69
+ let isArray = false;
70
+ if (key.endsWith(ARRAY_SUFFIX)) {
71
+ key = key.slice(0, -ARRAY_SUFFIX.length);
72
+ isArray = true;
73
+ }
74
+
75
+ // Rule 1: a bare `type` key → the type's registry default subType.
76
+ const canonicalKey = resolveKey(key, registry, errors, path);
77
+
78
+ // Rule 2: a scalar body → { name: <scalar> }.
79
+ const body = desugarBody(rawBody, errors, path);
80
+
81
+ // Rule 4 (cont.): stamp isArray onto the canonical body.
82
+ if (isArray) body[RESERVED_KEY_IS_ARRAY] = true;
83
+
84
+ // Recurse into children.
85
+ const rawChildren = body[RESERVED_KEY_CHILDREN];
86
+ if (Array.isArray(rawChildren)) {
87
+ const children: unknown[] = [];
88
+ for (let i = 0; i < rawChildren.length; i++) {
89
+ const childPath = `${path}.${RESERVED_KEY_CHILDREN}[${i}]`;
90
+ const child = desugarNode(rawChildren[i], registry, errors, childPath);
91
+ // On a bad child keep an empty-object placeholder so sibling indices
92
+ // stay stable; the error is already collected.
93
+ children.push(child ?? {});
94
+ }
95
+ body[RESERVED_KEY_CHILDREN] = children;
96
+ }
97
+ // A non-array `children` value is left untouched — buildTree reports it.
98
+
99
+ return { [canonicalKey]: body };
100
+ }
101
+
102
+ // Rule 1 — resolve a possibly-bare key to a fused `type.subType` token.
103
+ function resolveKey(
104
+ key: string,
105
+ registry: TypeRegistry,
106
+ errors: string[],
107
+ path: string,
108
+ ): string {
109
+ if (key.includes(TYPE_SUBTYPE_SEPARATOR)) return key; // already fused
110
+ const subType = registry.defaultSubTypeOf(key);
111
+ if (subType === undefined) {
112
+ errors.push(
113
+ `Cannot resolve subType for bare type key '${key}' at ${path} — ` +
114
+ `type '${key}' has no default subType; write the full 'type.subType'`,
115
+ );
116
+ return key; // pass through; buildTree reports the unknown type
117
+ }
118
+ return `${key}${TYPE_SUBTYPE_SEPARATOR}${subType}`;
119
+ }
120
+
121
+ // Rule 2 — normalize a node body into a canonical mapping.
122
+ function desugarBody(
123
+ rawBody: unknown,
124
+ errors: string[],
125
+ path: string,
126
+ ): Record<string, unknown> {
127
+ if (
128
+ typeof rawBody === "string" ||
129
+ typeof rawBody === "number" ||
130
+ typeof rawBody === "boolean"
131
+ ) {
132
+ return { [RESERVED_KEY_NAME]: rawBody };
133
+ }
134
+ if (rawBody === null || rawBody === undefined) {
135
+ // An empty body (`field.string:` with nothing after) → an empty node.
136
+ return {};
137
+ }
138
+ if (Array.isArray(rawBody)) {
139
+ errors.push(`Node body at ${path} must be a scalar or mapping, not a list`);
140
+ return {};
141
+ }
142
+ // A mapping — shallow-copy so isArray / children replacement do not mutate
143
+ // the caller's parsed-YAML object.
144
+ return { ...(rawBody as Record<string, unknown>) };
145
+ }