@bettercms-ai/kit 0.1.1 → 2.0.0

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 (1100) hide show
  1. package/README.md +22 -16
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/adapters/dock-values.d.ts +28 -0
  4. package/dist/adapters/dock-values.js +41 -0
  5. package/dist/adapters/dock-values.js.map +1 -0
  6. package/dist/adapters/icons.d.ts +15 -0
  7. package/dist/adapters/icons.js +27 -0
  8. package/dist/adapters/icons.js.map +1 -0
  9. package/dist/adapters/lossy.d.ts +326 -0
  10. package/dist/adapters/lossy.js +414 -0
  11. package/dist/adapters/lossy.js.map +1 -0
  12. package/dist/adapters/prod-types.d.ts +546 -0
  13. package/dist/adapters/prod-types.js +714 -0
  14. package/dist/adapters/prod-types.js.map +1 -0
  15. package/dist/adapters/schema.d.ts +154 -0
  16. package/dist/adapters/schema.js +3020 -0
  17. package/dist/adapters/schema.js.map +1 -0
  18. package/dist/adapters/values.d.ts +221 -0
  19. package/dist/adapters/values.js +623 -0
  20. package/dist/adapters/values.js.map +1 -0
  21. package/dist/brand/logo.d.ts +17 -0
  22. package/dist/brand/logo.js +96 -0
  23. package/dist/brand/logo.js.map +1 -0
  24. package/dist/context.d.ts +359 -0
  25. package/dist/context.js +217 -0
  26. package/dist/context.js.map +1 -0
  27. package/dist/controls/button.d.ts +72 -0
  28. package/dist/controls/button.js +578 -0
  29. package/dist/controls/button.js.map +1 -0
  30. package/dist/controls/c1.d.ts +11 -0
  31. package/dist/controls/c1.js +24 -0
  32. package/dist/controls/c1.js.map +1 -0
  33. package/dist/controls/c2.d.ts +10 -0
  34. package/dist/controls/c2.js +19 -0
  35. package/dist/controls/c2.js.map +1 -0
  36. package/dist/controls/choice.d.ts +44 -0
  37. package/dist/controls/choice.js +463 -0
  38. package/dist/controls/choice.js.map +1 -0
  39. package/dist/controls/code-register.d.ts +1 -0
  40. package/dist/controls/code-register.js +8 -0
  41. package/dist/controls/code-register.js.map +1 -0
  42. package/dist/controls/code.d.ts +42 -0
  43. package/dist/controls/code.js +397 -0
  44. package/dist/controls/code.js.map +1 -0
  45. package/dist/controls/color.d.ts +5 -0
  46. package/dist/controls/color.js +130 -0
  47. package/dist/controls/color.js.map +1 -0
  48. package/dist/controls/component-services.d.ts +156 -0
  49. package/dist/controls/component-services.js +7 -0
  50. package/dist/controls/component-services.js.map +1 -0
  51. package/dist/controls/date-register.d.ts +1 -0
  52. package/dist/controls/date-register.js +9 -0
  53. package/dist/controls/date-register.js.map +1 -0
  54. package/dist/controls/date-zone.d.ts +104 -0
  55. package/dist/controls/date-zone.js +278 -0
  56. package/dist/controls/date-zone.js.map +1 -0
  57. package/dist/controls/date.d.ts +7 -0
  58. package/dist/controls/date.js +466 -0
  59. package/dist/controls/date.js.map +1 -0
  60. package/dist/controls/form-picker-register.d.ts +1 -0
  61. package/dist/controls/form-picker-register.js +19 -0
  62. package/dist/controls/form-picker-register.js.map +1 -0
  63. package/dist/controls/form-picker.d.ts +43 -0
  64. package/dist/controls/form-picker.js +85 -0
  65. package/dist/controls/form-picker.js.map +1 -0
  66. package/dist/controls/icon-register.d.ts +1 -0
  67. package/dist/controls/icon-register.js +8 -0
  68. package/dist/controls/icon-register.js.map +1 -0
  69. package/dist/controls/icon.d.ts +40 -0
  70. package/dist/controls/icon.js +360 -0
  71. package/dist/controls/icon.js.map +1 -0
  72. package/dist/controls/index.d.ts +5 -0
  73. package/dist/controls/index.js +38 -0
  74. package/dist/controls/index.js.map +1 -0
  75. package/dist/controls/json-register.d.ts +1 -0
  76. package/dist/controls/json-register.js +8 -0
  77. package/dist/controls/json-register.js.map +1 -0
  78. package/dist/controls/json.d.ts +2 -0
  79. package/dist/controls/json.js +82 -0
  80. package/dist/controls/json.js.map +1 -0
  81. package/dist/controls/link.d.ts +260 -0
  82. package/dist/controls/link.js +1186 -0
  83. package/dist/controls/link.js.map +1 -0
  84. package/dist/controls/location-register.d.ts +1 -0
  85. package/dist/controls/location-register.js +8 -0
  86. package/dist/controls/location-register.js.map +1 -0
  87. package/dist/controls/location.d.ts +16 -0
  88. package/dist/controls/location.js +221 -0
  89. package/dist/controls/location.js.map +1 -0
  90. package/dist/controls/media-register.d.ts +1 -0
  91. package/dist/controls/media-register.js +12 -0
  92. package/dist/controls/media-register.js.map +1 -0
  93. package/dist/controls/media-services.d.ts +46 -0
  94. package/dist/controls/media-services.js +0 -0
  95. package/dist/controls/media.d.ts +104 -0
  96. package/dist/controls/media.js +1396 -0
  97. package/dist/controls/media.js.map +1 -0
  98. package/dist/controls/number.d.ts +22 -0
  99. package/dist/controls/number.js +196 -0
  100. package/dist/controls/number.js.map +1 -0
  101. package/dist/controls/reference-register.d.ts +1 -0
  102. package/dist/controls/reference-register.js +10 -0
  103. package/dist/controls/reference-register.js.map +1 -0
  104. package/dist/controls/reference-services.d.ts +58 -0
  105. package/dist/controls/reference-services.js +0 -0
  106. package/dist/controls/reference.d.ts +23 -0
  107. package/dist/controls/reference.js +777 -0
  108. package/dist/controls/reference.js.map +1 -0
  109. package/dist/controls/rich-text/blocks.d.ts +49 -0
  110. package/dist/controls/rich-text/blocks.js +1859 -0
  111. package/dist/controls/rich-text/blocks.js.map +1 -0
  112. package/dist/controls/rich-text/catalog.d.ts +101 -0
  113. package/dist/controls/rich-text/catalog.js +623 -0
  114. package/dist/controls/rich-text/catalog.js.map +1 -0
  115. package/dist/controls/rich-text/codec.d.ts +64 -0
  116. package/dist/controls/rich-text/codec.js +34 -0
  117. package/dist/controls/rich-text/codec.js.map +1 -0
  118. package/dist/controls/rich-text/component-card.d.ts +14 -0
  119. package/dist/controls/rich-text/component-card.js +1024 -0
  120. package/dist/controls/rich-text/component-card.js.map +1 -0
  121. package/dist/controls/rich-text/component-panel.d.ts +47 -0
  122. package/dist/controls/rich-text/component-panel.js +141 -0
  123. package/dist/controls/rich-text/component-panel.js.map +1 -0
  124. package/dist/controls/rich-text/control.d.ts +20 -0
  125. package/dist/controls/rich-text/control.js +296 -0
  126. package/dist/controls/rich-text/control.js.map +1 -0
  127. package/dist/controls/rich-text/dom.d.ts +233 -0
  128. package/dist/controls/rich-text/dom.js +1019 -0
  129. package/dist/controls/rich-text/dom.js.map +1 -0
  130. package/dist/controls/rich-text/editor.d.ts +57 -0
  131. package/dist/controls/rich-text/editor.js +1630 -0
  132. package/dist/controls/rich-text/editor.js.map +1 -0
  133. package/dist/controls/rich-text/floating.d.ts +28 -0
  134. package/dist/controls/rich-text/floating.js +154 -0
  135. package/dist/controls/rich-text/floating.js.map +1 -0
  136. package/dist/controls/rich-text/index.d.ts +1 -0
  137. package/dist/controls/rich-text/index.js +12 -0
  138. package/dist/controls/rich-text/index.js.map +1 -0
  139. package/dist/controls/rich-text/link-form.d.ts +13 -0
  140. package/dist/controls/rich-text/link-form.js +147 -0
  141. package/dist/controls/rich-text/link-form.js.map +1 -0
  142. package/dist/controls/rich-text/markdown.d.ts +6 -0
  143. package/dist/controls/rich-text/markdown.js +181 -0
  144. package/dist/controls/rich-text/markdown.js.map +1 -0
  145. package/dist/controls/rich-text/ops.d.ts +35 -0
  146. package/dist/controls/rich-text/ops.js +316 -0
  147. package/dist/controls/rich-text/ops.js.map +1 -0
  148. package/dist/controls/rich-text/plain.d.ts +17 -0
  149. package/dist/controls/rich-text/plain.js +44 -0
  150. package/dist/controls/rich-text/plain.js.map +1 -0
  151. package/dist/controls/rich-text/toolbar.d.ts +89 -0
  152. package/dist/controls/rich-text/toolbar.js +343 -0
  153. package/dist/controls/rich-text/toolbar.js.map +1 -0
  154. package/dist/controls/scale.d.ts +56 -0
  155. package/dist/controls/scale.js +563 -0
  156. package/dist/controls/scale.js.map +1 -0
  157. package/dist/controls/slot-register.d.ts +1 -0
  158. package/dist/controls/slot-register.js +16 -0
  159. package/dist/controls/slot-register.js.map +1 -0
  160. package/dist/controls/slot-services.d.ts +122 -0
  161. package/dist/controls/slot-services.js +155 -0
  162. package/dist/controls/slot-services.js.map +1 -0
  163. package/dist/controls/slot.d.ts +33 -0
  164. package/dist/controls/slot.js +366 -0
  165. package/dist/controls/slot.js.map +1 -0
  166. package/dist/controls/table/index.d.ts +1 -0
  167. package/dist/controls/table/index.js +12 -0
  168. package/dist/controls/table/index.js.map +1 -0
  169. package/dist/controls/table/prod.d.ts +21 -0
  170. package/dist/controls/table/prod.js +79 -0
  171. package/dist/controls/table/prod.js.map +1 -0
  172. package/dist/controls/table/refs.d.ts +50 -0
  173. package/dist/controls/table/refs.js +79 -0
  174. package/dist/controls/table/refs.js.map +1 -0
  175. package/dist/controls/table/stored.d.ts +15 -0
  176. package/dist/controls/table/stored.js +44 -0
  177. package/dist/controls/table/stored.js.map +1 -0
  178. package/dist/controls/table/table-editor.d.ts +103 -0
  179. package/dist/controls/table/table-editor.js +2725 -0
  180. package/dist/controls/table/table-editor.js.map +1 -0
  181. package/dist/controls/table/table-link.d.ts +24 -0
  182. package/dist/controls/table/table-link.js +180 -0
  183. package/dist/controls/table/table-link.js.map +1 -0
  184. package/dist/controls/table/table.d.ts +9 -0
  185. package/dist/controls/table/table.js +103 -0
  186. package/dist/controls/table/table.js.map +1 -0
  187. package/dist/controls/text.d.ts +17 -0
  188. package/dist/controls/text.js +322 -0
  189. package/dist/controls/text.js.map +1 -0
  190. package/dist/controls/unknown-value.d.ts +17 -0
  191. package/dist/controls/unknown-value.js +66 -0
  192. package/dist/controls/unknown-value.js.map +1 -0
  193. package/dist/core/core.d.ts +63 -0
  194. package/dist/core/core.js +171 -0
  195. package/dist/core/core.js.map +1 -0
  196. package/dist/core/facets.d.ts +347 -0
  197. package/dist/core/facets.js +334 -0
  198. package/dist/core/facets.js.map +1 -0
  199. package/dist/core/index.d.ts +3 -0
  200. package/dist/core/index.js +3 -0
  201. package/dist/engine/array.d.ts +101 -0
  202. package/dist/engine/array.js +906 -0
  203. package/dist/engine/array.js.map +1 -0
  204. package/dist/engine/bits.d.ts +24 -0
  205. package/dist/engine/bits.js +60 -0
  206. package/dist/engine/bits.js.map +1 -0
  207. package/dist/engine/breadcrumb.d.ts +45 -0
  208. package/dist/engine/breadcrumb.js +63 -0
  209. package/dist/engine/breadcrumb.js.map +1 -0
  210. package/dist/engine/expand.d.ts +66 -0
  211. package/dist/engine/expand.js +153 -0
  212. package/dist/engine/expand.js.map +1 -0
  213. package/dist/engine/field-list.d.ts +20 -0
  214. package/dist/engine/field-list.js +19 -0
  215. package/dist/engine/field-list.js.map +1 -0
  216. package/dist/engine/field-shell.d.ts +49 -0
  217. package/dist/engine/field-shell.js +988 -0
  218. package/dist/engine/field-shell.js.map +1 -0
  219. package/dist/engine/frame.d.ts +122 -0
  220. package/dist/engine/frame.js +601 -0
  221. package/dist/engine/frame.js.map +1 -0
  222. package/dist/engine/group-summary.d.ts +5 -0
  223. package/dist/engine/group-summary.js +70 -0
  224. package/dist/engine/group-summary.js.map +1 -0
  225. package/dist/engine/grouping.d.ts +238 -0
  226. package/dist/engine/grouping.js +996 -0
  227. package/dist/engine/grouping.js.map +1 -0
  228. package/dist/engine/item-list.d.ts +99 -0
  229. package/dist/engine/item-list.js +725 -0
  230. package/dist/engine/item-list.js.map +1 -0
  231. package/dist/engine/kit-field.d.ts +72 -0
  232. package/dist/engine/kit-field.js +558 -0
  233. package/dist/engine/kit-field.js.map +1 -0
  234. package/dist/engine/schema-form.d.ts +116 -0
  235. package/dist/engine/schema-form.js +462 -0
  236. package/dist/engine/schema-form.js.map +1 -0
  237. package/dist/engine/slot.d.ts +13 -0
  238. package/dist/engine/slot.js +216 -0
  239. package/dist/engine/slot.js.map +1 -0
  240. package/dist/index.d.ts +45 -3139
  241. package/dist/index.js +47 -2036
  242. package/dist/index.js.map +1 -0
  243. package/dist/kit.css +75 -0
  244. package/dist/lib/cn.d.ts +4 -0
  245. package/dist/lib/cn.js +56 -0
  246. package/dist/lib/cn.js.map +1 -0
  247. package/dist/lib/columns.d.ts +14 -0
  248. package/dist/lib/columns.js +30 -0
  249. package/dist/lib/columns.js.map +1 -0
  250. package/dist/lib/frames.d.ts +36 -0
  251. package/dist/lib/frames.js +214 -0
  252. package/dist/lib/frames.js.map +1 -0
  253. package/dist/lib/icon-image.d.ts +10 -0
  254. package/dist/lib/icon-image.js +8 -0
  255. package/dist/lib/icon-image.js.map +1 -0
  256. package/dist/lib/icons.d.ts +16 -0
  257. package/dist/lib/icons.js +173 -0
  258. package/dist/lib/icons.js.map +1 -0
  259. package/dist/lib/input-modality.d.ts +11 -0
  260. package/dist/lib/input-modality.js +47 -0
  261. package/dist/lib/input-modality.js.map +1 -0
  262. package/dist/lib/key-event.d.ts +11 -0
  263. package/dist/lib/key-event.js +16 -0
  264. package/dist/lib/key-event.js.map +1 -0
  265. package/dist/lib/path.d.ts +29 -0
  266. package/dist/lib/path.js +66 -0
  267. package/dist/lib/path.js.map +1 -0
  268. package/dist/lib/schema.d.ts +80 -0
  269. package/dist/lib/schema.js +384 -0
  270. package/dist/lib/schema.js.map +1 -0
  271. package/dist/lib/utils.d.ts +7 -0
  272. package/dist/lib/utils.js +37 -0
  273. package/dist/lib/utils.js.map +1 -0
  274. package/dist/lib/validate.d.ts +30 -0
  275. package/dist/lib/validate.js +224 -0
  276. package/dist/lib/validate.js.map +1 -0
  277. package/dist/library/analysis.d.ts +23 -0
  278. package/dist/library/analysis.js +160 -0
  279. package/dist/library/analysis.js.map +1 -0
  280. package/dist/library/catalog.d.ts +57 -0
  281. package/dist/library/catalog.js +307 -0
  282. package/dist/library/catalog.js.map +1 -0
  283. package/dist/library/coreNotes.d.ts +8 -0
  284. package/dist/library/coreNotes.js +111 -0
  285. package/dist/library/coreNotes.js.map +1 -0
  286. package/dist/library/coverage.d.ts +40 -0
  287. package/dist/library/coverage.js +59 -0
  288. package/dist/library/coverage.js.map +1 -0
  289. package/dist/library/entries/advanced.entries.d.ts +2 -0
  290. package/dist/library/entries/advanced.entries.js +6579 -0
  291. package/dist/library/entries/advanced.entries.js.map +1 -0
  292. package/dist/library/entries/commerce.entries.d.ts +2 -0
  293. package/dist/library/entries/commerce.entries.js +4140 -0
  294. package/dist/library/entries/commerce.entries.js.map +1 -0
  295. package/dist/library/entries/company.entries.d.ts +2 -0
  296. package/dist/library/entries/company.entries.js +2731 -0
  297. package/dist/library/entries/company.entries.js.map +1 -0
  298. package/dist/library/entries/conversion.entries.d.ts +2 -0
  299. package/dist/library/entries/conversion.entries.js +3707 -0
  300. package/dist/library/entries/conversion.entries.js.map +1 -0
  301. package/dist/library/entries/data.entries.d.ts +7 -0
  302. package/dist/library/entries/data.entries.js +4613 -0
  303. package/dist/library/entries/data.entries.js.map +1 -0
  304. package/dist/library/entries/events.entries.d.ts +2 -0
  305. package/dist/library/entries/events.entries.js +3428 -0
  306. package/dist/library/entries/events.entries.js.map +1 -0
  307. package/dist/library/entries/features.entries.d.ts +2 -0
  308. package/dist/library/entries/features.entries.js +3157 -0
  309. package/dist/library/entries/features.entries.js.map +1 -0
  310. package/dist/library/entries/heroes.entries.d.ts +2 -0
  311. package/dist/library/entries/heroes.entries.js +3401 -0
  312. package/dist/library/entries/heroes.entries.js.map +1 -0
  313. package/dist/library/entries/index.d.ts +3 -0
  314. package/dist/library/entries/index.js +35 -0
  315. package/dist/library/entries/index.js.map +1 -0
  316. package/dist/library/entries/listings.entries.d.ts +2 -0
  317. package/dist/library/entries/listings.entries.js +2976 -0
  318. package/dist/library/entries/listings.entries.js.map +1 -0
  319. package/dist/library/entries/longform.entries.d.ts +2 -0
  320. package/dist/library/entries/longform.entries.js +4227 -0
  321. package/dist/library/entries/longform.entries.js.map +1 -0
  322. package/dist/library/entries/media.entries.d.ts +2 -0
  323. package/dist/library/entries/media.entries.js +2781 -0
  324. package/dist/library/entries/media.entries.js.map +1 -0
  325. package/dist/library/entries/navigation.entries.d.ts +2 -0
  326. package/dist/library/entries/navigation.entries.js +4011 -0
  327. package/dist/library/entries/navigation.entries.js.map +1 -0
  328. package/dist/library/entries/pricing.entries.d.ts +2 -0
  329. package/dist/library/entries/pricing.entries.js +2383 -0
  330. package/dist/library/entries/pricing.entries.js.map +1 -0
  331. package/dist/library/entries/social-proof.entries.d.ts +2 -0
  332. package/dist/library/entries/social-proof.entries.js +2297 -0
  333. package/dist/library/entries/social-proof.entries.js.map +1 -0
  334. package/dist/library/examples/bento.d.ts +92 -0
  335. package/dist/library/examples/bento.js +201 -0
  336. package/dist/library/examples/bento.js.map +1 -0
  337. package/dist/library/examples/blocks.d.ts +14 -0
  338. package/dist/library/examples/blocks.js +313 -0
  339. package/dist/library/examples/blocks.js.map +1 -0
  340. package/dist/library/examples/faq.d.ts +28 -0
  341. package/dist/library/examples/faq.js +230 -0
  342. package/dist/library/examples/faq.js.map +1 -0
  343. package/dist/library/examples/hero.d.ts +43 -0
  344. package/dist/library/examples/hero.js +222 -0
  345. package/dist/library/examples/hero.js.map +1 -0
  346. package/dist/library/examples/index.d.ts +36 -0
  347. package/dist/library/examples/index.js +109 -0
  348. package/dist/library/examples/index.js.map +1 -0
  349. package/dist/library/examples/journalStory.d.ts +93 -0
  350. package/dist/library/examples/journalStory.js +338 -0
  351. package/dist/library/examples/journalStory.js.map +1 -0
  352. package/dist/library/examples/megaMenu.d.ts +134 -0
  353. package/dist/library/examples/megaMenu.js +442 -0
  354. package/dist/library/examples/megaMenu.js.map +1 -0
  355. package/dist/library/examples/pricing.d.ts +103 -0
  356. package/dist/library/examples/pricing.js +479 -0
  357. package/dist/library/examples/pricing.js.map +1 -0
  358. package/dist/library/examples/tabs.d.ts +87 -0
  359. package/dist/library/examples/tabs.js +180 -0
  360. package/dist/library/examples/tabs.js.map +1 -0
  361. package/dist/library/export.d.ts +42 -0
  362. package/dist/library/export.js +80 -0
  363. package/dist/library/export.js.map +1 -0
  364. package/dist/library/index.d.ts +13 -0
  365. package/dist/library/index.js +6 -0
  366. package/dist/library/kit-catalog.json +1510 -0
  367. package/dist/library/types.d.ts +42 -0
  368. package/dist/library/types.js +0 -0
  369. package/dist/schema/adapters.d.ts +28 -0
  370. package/dist/schema/adapters.js +492 -0
  371. package/dist/schema/adapters.js.map +1 -0
  372. package/dist/schema/help.d.ts +27 -0
  373. package/dist/schema/help.js +56 -0
  374. package/dist/schema/help.js.map +1 -0
  375. package/dist/schema/scale.d.ts +69 -0
  376. package/dist/schema/scale.js +250 -0
  377. package/dist/schema/scale.js.map +1 -0
  378. package/dist/schema/sources.d.ts +103 -0
  379. package/dist/schema/sources.js +65 -0
  380. package/dist/schema/sources.js.map +1 -0
  381. package/dist/schema/table.d.ts +319 -0
  382. package/dist/schema/table.js +1199 -0
  383. package/dist/schema/table.js.map +1 -0
  384. package/dist/schema/types.d.ts +297 -0
  385. package/dist/schema/types.js +14 -0
  386. package/dist/schema/types.js.map +1 -0
  387. package/dist/styles.css +2 -0
  388. package/dist/table/table-view.d.ts +14 -0
  389. package/dist/table/table-view.js +140 -0
  390. package/dist/table/table-view.js.map +1 -0
  391. package/dist/table/table.css +73 -0
  392. package/dist/testing/corpus.d.ts +63 -0
  393. package/dist/testing/corpus.js +129 -0
  394. package/dist/testing/corpus.js.map +1 -0
  395. package/dist/testing/test-form.d.ts +11 -0
  396. package/dist/testing/test-form.js +38 -0
  397. package/dist/testing/test-form.js.map +1 -0
  398. package/dist/theme.css +345 -0
  399. package/dist/theme.d.ts +20 -1504
  400. package/dist/theme.js +43 -4126
  401. package/dist/theme.js.map +1 -0
  402. package/dist/tokens.css +542 -0
  403. package/dist/types.d.ts +17 -0
  404. package/dist/types.js +0 -0
  405. package/dist/ui/action-tray.d.ts +54 -0
  406. package/dist/ui/action-tray.js +154 -0
  407. package/dist/ui/action-tray.js.map +1 -0
  408. package/dist/ui/autocomplete.d.ts +30 -0
  409. package/dist/ui/autocomplete.js +139 -0
  410. package/dist/ui/autocomplete.js.map +1 -0
  411. package/dist/ui/button.d.ts +57 -0
  412. package/dist/ui/button.js +201 -0
  413. package/dist/ui/button.js.map +1 -0
  414. package/dist/ui/choice-switch.d.ts +36 -0
  415. package/dist/ui/choice-switch.js +57 -0
  416. package/dist/ui/choice-switch.js.map +1 -0
  417. package/dist/ui/controls.d.ts +83 -0
  418. package/dist/ui/controls.js +331 -0
  419. package/dist/ui/controls.js.map +1 -0
  420. package/dist/ui/display.d.ts +163 -0
  421. package/dist/ui/display.js +455 -0
  422. package/dist/ui/display.js.map +1 -0
  423. package/dist/ui/expanded-editor-modal.d.ts +26 -0
  424. package/dist/ui/expanded-editor-modal.js +140 -0
  425. package/dist/ui/expanded-editor-modal.js.map +1 -0
  426. package/dist/ui/field-context.d.ts +12 -0
  427. package/dist/ui/field-context.js +23 -0
  428. package/dist/ui/field-context.js.map +1 -0
  429. package/dist/ui/floating-panel.d.ts +152 -0
  430. package/dist/ui/floating-panel.js +928 -0
  431. package/dist/ui/floating-panel.js.map +1 -0
  432. package/dist/ui/index.d.ts +16 -0
  433. package/dist/ui/index.js +18 -0
  434. package/dist/ui/input.d.ts +78 -0
  435. package/dist/ui/input.js +250 -0
  436. package/dist/ui/input.js.map +1 -0
  437. package/dist/ui/mode-bar.d.ts +31 -0
  438. package/dist/ui/mode-bar.js +65 -0
  439. package/dist/ui/mode-bar.js.map +1 -0
  440. package/dist/ui/overlay.d.ts +195 -0
  441. package/dist/ui/overlay.js +697 -0
  442. package/dist/ui/overlay.js.map +1 -0
  443. package/dist/ui/path-crumbs.d.ts +90 -0
  444. package/dist/ui/path-crumbs.js +566 -0
  445. package/dist/ui/path-crumbs.js.map +1 -0
  446. package/dist/ui/presence.d.ts +16 -0
  447. package/dist/ui/presence.js +65 -0
  448. package/dist/ui/presence.js.map +1 -0
  449. package/dist/ui/select.d.ts +66 -0
  450. package/dist/ui/select.js +407 -0
  451. package/dist/ui/select.js.map +1 -0
  452. package/dist/ui/shortcut-hint.d.ts +14 -0
  453. package/dist/ui/shortcut-hint.js +35 -0
  454. package/dist/ui/shortcut-hint.js.map +1 -0
  455. package/dist/ui/spinner.d.ts +24 -0
  456. package/dist/ui/spinner.js +42 -0
  457. package/dist/ui/spinner.js.map +1 -0
  458. package/dist/ui/split-button.d.ts +32 -0
  459. package/dist/ui/split-button.js +60 -0
  460. package/dist/ui/split-button.js.map +1 -0
  461. package/dist/ui/surfaces.d.ts +23 -0
  462. package/dist/ui/surfaces.js +26 -0
  463. package/dist/ui/surfaces.js.map +1 -0
  464. package/dist/ui/tab.d.ts +38 -0
  465. package/dist/ui/tab.js +87 -0
  466. package/dist/ui/tab.js.map +1 -0
  467. package/dist/ui/toast.d.ts +20 -0
  468. package/dist/ui/toast.js +115 -0
  469. package/dist/ui/toast.js.map +1 -0
  470. package/dist/ui/tooltip-root.d.ts +13 -0
  471. package/dist/ui/tooltip-root.js +77 -0
  472. package/dist/ui/tooltip-root.js.map +1 -0
  473. package/dist/ui/variants.d.ts +15 -0
  474. package/dist/ui/variants.js +14 -0
  475. package/dist/ui/variants.js.map +1 -0
  476. package/package.json +76 -50
  477. package/LICENSE +0 -21
  478. package/dist/_chunks-cjs/_visual-editing.js +0 -5898
  479. package/dist/_chunks-cjs/refractor.js +0 -22
  480. package/dist/_chunks-es/_visual-editing.mjs +0 -5904
  481. package/dist/_chunks-es/refractor.mjs +0 -25
  482. package/dist/_color.d.mts +0 -119
  483. package/dist/_color.d.ts +0 -119
  484. package/dist/_color.js +0 -1412
  485. package/dist/_color.mjs +0 -1411
  486. package/dist/_visual-editing.d.mts +0 -1126
  487. package/dist/_visual-editing.d.ts +0 -1126
  488. package/dist/_visual-editing.js +0 -30
  489. package/dist/_visual-editing.mjs +0 -30
  490. package/dist/index.d.mts +0 -3140
  491. package/dist/index.mjs +0 -2044
  492. package/dist/theme.d.mts +0 -1506
  493. package/dist/theme.mjs +0 -4126
  494. package/exports/_visual-editing.ts +0 -31
  495. package/exports/index.ts +0 -1
  496. package/exports/theme.ts +0 -1
  497. package/src/color/index.d.mts +0 -119
  498. package/src/color/index.mjs +0 -1411
  499. package/src/core/__workshop__/constants.ts +0 -293
  500. package/src/core/_compat.ts +0 -264
  501. package/src/core/components/autocomplete/__mocks__/apiStore.ts +0 -49
  502. package/src/core/components/autocomplete/__mocks__/countries.ts +0 -245
  503. package/src/core/components/autocomplete/__workshop__/async.tsx +0 -156
  504. package/src/core/components/autocomplete/__workshop__/constrainedHeight.tsx +0 -137
  505. package/src/core/components/autocomplete/__workshop__/custom.tsx +0 -89
  506. package/src/core/components/autocomplete/__workshop__/example.tsx +0 -79
  507. package/src/core/components/autocomplete/__workshop__/focusAndBlur.tsx +0 -36
  508. package/src/core/components/autocomplete/__workshop__/fullscreen.tsx +0 -294
  509. package/src/core/components/autocomplete/__workshop__/index.ts +0 -39
  510. package/src/core/components/autocomplete/__workshop__/types.ts +0 -4
  511. package/src/core/components/autocomplete/autocomplete.styles.tsx +0 -39
  512. package/src/core/components/autocomplete/autocomplete.tsx +0 -767
  513. package/src/core/components/autocomplete/autocompleteOption.tsx +0 -45
  514. package/src/core/components/autocomplete/autocompleteReducer.ts +0 -47
  515. package/src/core/components/autocomplete/constants.ts +0 -28
  516. package/src/core/components/autocomplete/index.ts +0 -2
  517. package/src/core/components/autocomplete/types.ts +0 -108
  518. package/src/core/components/breadcrumbs/__workshop__/example.tsx +0 -62
  519. package/src/core/components/breadcrumbs/__workshop__/index.ts +0 -14
  520. package/src/core/components/breadcrumbs/breadcrumbs.styles.ts +0 -18
  521. package/src/core/components/breadcrumbs/breadcrumbs.test.tsx +0 -51
  522. package/src/core/components/breadcrumbs/breadcrumbs.tsx +0 -133
  523. package/src/core/components/breadcrumbs/index.ts +0 -1
  524. package/src/core/components/dialog/__workshop__/activate.tsx +0 -134
  525. package/src/core/components/dialog/__workshop__/autoFocus.tsx +0 -29
  526. package/src/core/components/dialog/__workshop__/index.ts +0 -19
  527. package/src/core/components/dialog/__workshop__/layering.tsx +0 -41
  528. package/src/core/components/dialog/__workshop__/nested.tsx +0 -72
  529. package/src/core/components/dialog/__workshop__/onScroll.tsx +0 -39
  530. package/src/core/components/dialog/__workshop__/panes.tsx +0 -82
  531. package/src/core/components/dialog/__workshop__/position.tsx +0 -30
  532. package/src/core/components/dialog/__workshop__/props.tsx +0 -75
  533. package/src/core/components/dialog/__workshop__/provider.tsx +0 -11
  534. package/src/core/components/dialog/__workshop__/wrapped.tsx +0 -76
  535. package/src/core/components/dialog/dialog.tsx +0 -430
  536. package/src/core/components/dialog/dialogContext.ts +0 -20
  537. package/src/core/components/dialog/dialogProvider.tsx +0 -35
  538. package/src/core/components/dialog/index.ts +0 -4
  539. package/src/core/components/dialog/styles.ts +0 -77
  540. package/src/core/components/dialog/useDialog.ts +0 -11
  541. package/src/core/components/hotkeys/__workshop__/index.ts +0 -14
  542. package/src/core/components/hotkeys/__workshop__/plain.tsx +0 -9
  543. package/src/core/components/hotkeys/hotkeys.test.tsx +0 -42
  544. package/src/core/components/hotkeys/hotkeys.tsx +0 -66
  545. package/src/core/components/hotkeys/index.ts +0 -1
  546. package/src/core/components/index.ts +0 -9
  547. package/src/core/components/menu/__workshop__/asComponent.tsx +0 -45
  548. package/src/core/components/menu/__workshop__/avatarMenu.tsx +0 -51
  549. package/src/core/components/menu/__workshop__/closableMenuButton.tsx +0 -46
  550. package/src/core/components/menu/__workshop__/constrainedInBoundary.tsx +0 -134
  551. package/src/core/components/menu/__workshop__/customMenuItem.tsx +0 -45
  552. package/src/core/components/menu/__workshop__/customSelectedState.tsx +0 -39
  553. package/src/core/components/menu/__workshop__/disableFocusOnClose.tsx +0 -40
  554. package/src/core/components/menu/__workshop__/groups.tsx +0 -156
  555. package/src/core/components/menu/__workshop__/index.ts +0 -89
  556. package/src/core/components/menu/__workshop__/menuButton.tsx +0 -80
  557. package/src/core/components/menu/__workshop__/menuGroupRight.tsx +0 -58
  558. package/src/core/components/menu/__workshop__/nestedMenu.tsx +0 -22
  559. package/src/core/components/menu/__workshop__/onCloseMenuButton.tsx +0 -41
  560. package/src/core/components/menu/__workshop__/selectedItem.tsx +0 -69
  561. package/src/core/components/menu/__workshop__/shouldFocus.tsx +0 -47
  562. package/src/core/components/menu/__workshop__/tones.tsx +0 -25
  563. package/src/core/components/menu/__workshop__/withoutArrow.tsx +0 -32
  564. package/src/core/components/menu/helpers.ts +0 -82
  565. package/src/core/components/menu/index.ts +0 -5
  566. package/src/core/components/menu/menu.spacing.test.tsx +0 -63
  567. package/src/core/components/menu/menu.test.tsx +0 -125
  568. package/src/core/components/menu/menu.tsx +0 -178
  569. package/src/core/components/menu/menuButton.tsx +0 -268
  570. package/src/core/components/menu/menuContext.ts +0 -18
  571. package/src/core/components/menu/menuDivider.ts +0 -23
  572. package/src/core/components/menu/menuGroup.spacing.test.tsx +0 -63
  573. package/src/core/components/menu/menuGroup.tsx +0 -233
  574. package/src/core/components/menu/menuItem.spacing.test.tsx +0 -59
  575. package/src/core/components/menu/menuItem.tsx +0 -197
  576. package/src/core/components/menu/useMenu.ts +0 -21
  577. package/src/core/components/menu/useMenuController.ts +0 -231
  578. package/src/core/components/skeleton/__workshop__/delay.tsx +0 -70
  579. package/src/core/components/skeleton/__workshop__/index.ts +0 -11
  580. package/src/core/components/skeleton/__workshop__/skeleton.tsx +0 -64
  581. package/src/core/components/skeleton/index.ts +0 -2
  582. package/src/core/components/skeleton/skeleton.tsx +0 -57
  583. package/src/core/components/skeleton/styles.ts +0 -50
  584. package/src/core/components/skeleton/textSkeleton.tsx +0 -122
  585. package/src/core/components/tab/__workshop__/example.tsx +0 -79
  586. package/src/core/components/tab/__workshop__/index.ts +0 -14
  587. package/src/core/components/tab/index.ts +0 -3
  588. package/src/core/components/tab/tab.tsx +0 -101
  589. package/src/core/components/tab/tabList.test.tsx +0 -48
  590. package/src/core/components/tab/tabList.tsx +0 -70
  591. package/src/core/components/tab/tabPanel.tsx +0 -39
  592. package/src/core/components/toast/__workshop__/hook.tsx +0 -71
  593. package/src/core/components/toast/__workshop__/index.ts +0 -19
  594. package/src/core/components/toast/__workshop__/toast.tsx +0 -26
  595. package/src/core/components/toast/index.ts +0 -4
  596. package/src/core/components/toast/styles.ts +0 -77
  597. package/src/core/components/toast/toast.test.tsx +0 -101
  598. package/src/core/components/toast/toast.tsx +0 -198
  599. package/src/core/components/toast/toastContext.ts +0 -7
  600. package/src/core/components/toast/toastLayer.tsx +0 -51
  601. package/src/core/components/toast/toastProvider.tsx +0 -113
  602. package/src/core/components/toast/toastState.ts +0 -6
  603. package/src/core/components/toast/types.ts +0 -26
  604. package/src/core/components/toast/useToast.ts +0 -25
  605. package/src/core/components/tree/__workshop__/basic.perf.ts +0 -19
  606. package/src/core/components/tree/__workshop__/basic.tsx +0 -105
  607. package/src/core/components/tree/__workshop__/index.ts +0 -21
  608. package/src/core/components/tree/__workshop__/tabFromElement.tsx +0 -84
  609. package/src/core/components/tree/helpers.ts +0 -105
  610. package/src/core/components/tree/index.ts +0 -4
  611. package/src/core/components/tree/style.ts +0 -105
  612. package/src/core/components/tree/tree.test.tsx +0 -55
  613. package/src/core/components/tree/tree.tsx +0 -240
  614. package/src/core/components/tree/treeContext.ts +0 -10
  615. package/src/core/components/tree/treeGroup.tsx +0 -28
  616. package/src/core/components/tree/treeItem.test.tsx +0 -65
  617. package/src/core/components/tree/treeItem.tsx +0 -224
  618. package/src/core/components/tree/types.ts +0 -25
  619. package/src/core/components/tree/useTree.ts +0 -17
  620. package/src/core/constants.ts +0 -79
  621. package/src/core/helpers/animation.ts +0 -27
  622. package/src/core/helpers/element.ts +0 -55
  623. package/src/core/helpers/focus.ts +0 -100
  624. package/src/core/helpers/index.ts +0 -4
  625. package/src/core/helpers/scroll.ts +0 -15
  626. package/src/core/hooks/index.ts +0 -12
  627. package/src/core/hooks/useArrayProp.ts +0 -17
  628. package/src/core/hooks/useClickOutside.test.tsx +0 -482
  629. package/src/core/hooks/useClickOutside.ts +0 -118
  630. package/src/core/hooks/useClickOutsideEvent.test.tsx +0 -115
  631. package/src/core/hooks/useClickOutsideEvent.ts +0 -73
  632. package/src/core/hooks/useCustomValidity.ts +0 -13
  633. package/src/core/hooks/useDelayed.test.ts +0 -88
  634. package/src/core/hooks/useDelayedState.ts +0 -36
  635. package/src/core/hooks/useElementRect/__workshop__/example.tsx +0 -32
  636. package/src/core/hooks/useElementRect/__workshop__/index.ts +0 -14
  637. package/src/core/hooks/useElementRect/index.ts +0 -1
  638. package/src/core/hooks/useElementRect/useElementRect.ts +0 -13
  639. package/src/core/hooks/useElementSize.ts +0 -19
  640. package/src/core/hooks/useForwardedRef.ts +0 -19
  641. package/src/core/hooks/useGlobalKeyDown.ts +0 -24
  642. package/src/core/hooks/useIsomorphicEffect.ts +0 -7
  643. package/src/core/hooks/useMatchMedia.ts +0 -28
  644. package/src/core/hooks/useMediaIndex/__workshop__/index.ts +0 -14
  645. package/src/core/hooks/useMediaIndex/__workshop__/test.tsx +0 -14
  646. package/src/core/hooks/useMediaIndex/index.ts +0 -1
  647. package/src/core/hooks/useMediaIndex/useMediaIndex.test.tsx +0 -36
  648. package/src/core/hooks/useMediaIndex/useMediaIndex.ts +0 -102
  649. package/src/core/hooks/useMounted.ts +0 -15
  650. package/src/core/hooks/usePrefersDark.hydration.test.tsx +0 -56
  651. package/src/core/hooks/usePrefersDark.test.tsx +0 -19
  652. package/src/core/hooks/usePrefersDark.ts +0 -16
  653. package/src/core/hooks/usePrefersReducedMotion.hydration.test.tsx +0 -56
  654. package/src/core/hooks/usePrefersReducedMotion.test.tsx +0 -19
  655. package/src/core/hooks/usePrefersReducedMotion.ts +0 -16
  656. package/src/core/index.ts +0 -10
  657. package/src/core/lib/createGlobalScopedContext.ts +0 -36
  658. package/src/core/lib/globalScope.ts +0 -19
  659. package/src/core/lib/isRecord.ts +0 -3
  660. package/src/core/middleware/origin.ts +0 -47
  661. package/src/core/observers/elementSizeObserver.ts +0 -116
  662. package/src/core/observers/index.ts +0 -2
  663. package/src/core/observers/resizeObserver.ts +0 -9
  664. package/src/core/primitives/_selectable/index.ts +0 -1
  665. package/src/core/primitives/_selectable/selectable.tsx +0 -15
  666. package/src/core/primitives/_selectable/style.ts +0 -115
  667. package/src/core/primitives/avatar/__workshop__/asButton.tsx +0 -14
  668. package/src/core/primitives/avatar/__workshop__/index.ts +0 -29
  669. package/src/core/primitives/avatar/__workshop__/stack.tsx +0 -25
  670. package/src/core/primitives/avatar/__workshop__/withinButton.tsx +0 -63
  671. package/src/core/primitives/avatar/__workshop__/withinMenuItem.tsx +0 -70
  672. package/src/core/primitives/avatar/avatar.tsx +0 -200
  673. package/src/core/primitives/avatar/avatarCounter.tsx +0 -91
  674. package/src/core/primitives/avatar/avatarStack.tsx +0 -100
  675. package/src/core/primitives/avatar/index.ts +0 -4
  676. package/src/core/primitives/avatar/styles.ts +0 -167
  677. package/src/core/primitives/avatar/types.ts +0 -17
  678. package/src/core/primitives/badge/__workshop__/index.ts +0 -19
  679. package/src/core/primitives/badge/__workshop__/props.tsx +0 -30
  680. package/src/core/primitives/badge/__workshop__/tones.tsx +0 -21
  681. package/src/core/primitives/badge/badge.test.tsx +0 -16
  682. package/src/core/primitives/badge/badge.tsx +0 -70
  683. package/src/core/primitives/badge/index.ts +0 -1
  684. package/src/core/primitives/badge/styles.ts +0 -20
  685. package/src/core/primitives/badge/types.ts +0 -8
  686. package/src/core/primitives/box/__workshop__/asComponent.tsx +0 -31
  687. package/src/core/primitives/box/__workshop__/index.ts +0 -24
  688. package/src/core/primitives/box/__workshop__/props.tsx +0 -20
  689. package/src/core/primitives/box/__workshop__/responsive.tsx +0 -20
  690. package/src/core/primitives/box/box.test.tsx +0 -142
  691. package/src/core/primitives/box/box.tsx +0 -154
  692. package/src/core/primitives/box/index.ts +0 -1
  693. package/src/core/primitives/button/__workshop__/custom.tsx +0 -51
  694. package/src/core/primitives/button/__workshop__/customIcons.tsx +0 -30
  695. package/src/core/primitives/button/__workshop__/disabled.tsx +0 -74
  696. package/src/core/primitives/button/__workshop__/index.ts +0 -59
  697. package/src/core/primitives/button/__workshop__/labelUploadButton.tsx +0 -36
  698. package/src/core/primitives/button/__workshop__/mixedChildren.tsx +0 -12
  699. package/src/core/primitives/button/__workshop__/props.tsx +0 -55
  700. package/src/core/primitives/button/__workshop__/stacked.tsx +0 -58
  701. package/src/core/primitives/button/__workshop__/styled1.tsx +0 -17
  702. package/src/core/primitives/button/__workshop__/styled2.tsx +0 -19
  703. package/src/core/primitives/button/__workshop__/uploadButton.tsx +0 -28
  704. package/src/core/primitives/button/button.test.tsx +0 -82
  705. package/src/core/primitives/button/button.tsx +0 -210
  706. package/src/core/primitives/button/index.ts +0 -1
  707. package/src/core/primitives/button/styles.ts +0 -117
  708. package/src/core/primitives/card/__workshop__/allTones.tsx +0 -25
  709. package/src/core/primitives/card/__workshop__/asButton.tsx +0 -107
  710. package/src/core/primitives/card/__workshop__/asComponent.tsx +0 -27
  711. package/src/core/primitives/card/__workshop__/checkered.tsx +0 -26
  712. package/src/core/primitives/card/__workshop__/index.ts +0 -18
  713. package/src/core/primitives/card/__workshop__/interactive.tsx +0 -30
  714. package/src/core/primitives/card/__workshop__/listNavigation.tsx +0 -80
  715. package/src/core/primitives/card/__workshop__/props.tsx +0 -53
  716. package/src/core/primitives/card/__workshop__/selected.tsx +0 -94
  717. package/src/core/primitives/card/__workshop__/styled.tsx +0 -14
  718. package/src/core/primitives/card/card.tsx +0 -128
  719. package/src/core/primitives/card/index.ts +0 -2
  720. package/src/core/primitives/card/styles.ts +0 -147
  721. package/src/core/primitives/card/types.ts +0 -11
  722. package/src/core/primitives/checkbox/__workshop__/example.tsx +0 -25
  723. package/src/core/primitives/checkbox/__workshop__/index.ts +0 -13
  724. package/src/core/primitives/checkbox/__workshop__/props.tsx +0 -33
  725. package/src/core/primitives/checkbox/__workshop__/readOnly.tsx +0 -16
  726. package/src/core/primitives/checkbox/__workshop__/tones.tsx +0 -28
  727. package/src/core/primitives/checkbox/checkbox.tsx +0 -73
  728. package/src/core/primitives/checkbox/index.ts +0 -1
  729. package/src/core/primitives/checkbox/styles.ts +0 -128
  730. package/src/core/primitives/code/__workshop__/index.ts +0 -19
  731. package/src/core/primitives/code/__workshop__/opticalAlignment.tsx +0 -48
  732. package/src/core/primitives/code/__workshop__/props.tsx +0 -21
  733. package/src/core/primitives/code/code.tsx +0 -55
  734. package/src/core/primitives/code/index.ts +0 -1
  735. package/src/core/primitives/code/refractor.tsx +0 -20
  736. package/src/core/primitives/code/styles.ts +0 -77
  737. package/src/core/primitives/container/__workshop__/example.tsx +0 -20
  738. package/src/core/primitives/container/__workshop__/index.ts +0 -8
  739. package/src/core/primitives/container/container.tsx +0 -54
  740. package/src/core/primitives/container/index.ts +0 -2
  741. package/src/core/primitives/container/styles.ts +0 -23
  742. package/src/core/primitives/container/types.ts +0 -6
  743. package/src/core/primitives/flex/__workshop__/example.tsx +0 -34
  744. package/src/core/primitives/flex/__workshop__/gap.tsx +0 -25
  745. package/src/core/primitives/flex/__workshop__/index.ts +0 -11
  746. package/src/core/primitives/flex/flex.tsx +0 -64
  747. package/src/core/primitives/flex/index.ts +0 -1
  748. package/src/core/primitives/grid/__workshop__/index.ts +0 -10
  749. package/src/core/primitives/grid/__workshop__/responsive.tsx +0 -54
  750. package/src/core/primitives/grid/grid.test.tsx +0 -80
  751. package/src/core/primitives/grid/grid.tsx +0 -74
  752. package/src/core/primitives/grid/index.ts +0 -1
  753. package/src/core/primitives/heading/__workshop__/index.ts +0 -19
  754. package/src/core/primitives/heading/__workshop__/opticalAlignment.tsx +0 -54
  755. package/src/core/primitives/heading/__workshop__/plain.tsx +0 -32
  756. package/src/core/primitives/heading/heading.tsx +0 -88
  757. package/src/core/primitives/heading/index.ts +0 -1
  758. package/src/core/primitives/heading/styles.ts +0 -64
  759. package/src/core/primitives/heading/types.ts +0 -7
  760. package/src/core/primitives/index.ts +0 -27
  761. package/src/core/primitives/inline/__workshop__/index.ts +0 -8
  762. package/src/core/primitives/inline/__workshop__/plain.tsx +0 -27
  763. package/src/core/primitives/inline/index.ts +0 -1
  764. package/src/core/primitives/inline/inline.test.tsx +0 -51
  765. package/src/core/primitives/inline/inline.tsx +0 -63
  766. package/src/core/primitives/inline/styles.ts +0 -32
  767. package/src/core/primitives/inline/types.ts +0 -6
  768. package/src/core/primitives/kbd/__workshop__/index.ts +0 -8
  769. package/src/core/primitives/kbd/__workshop__/plain.tsx +0 -9
  770. package/src/core/primitives/kbd/index.ts +0 -1
  771. package/src/core/primitives/kbd/kbd.tsx +0 -69
  772. package/src/core/primitives/label/__workshop__/index.ts +0 -19
  773. package/src/core/primitives/label/__workshop__/opticalAlignment.tsx +0 -48
  774. package/src/core/primitives/label/__workshop__/plain.tsx +0 -24
  775. package/src/core/primitives/label/index.ts +0 -1
  776. package/src/core/primitives/label/label.tsx +0 -87
  777. package/src/core/primitives/label/styles.ts +0 -45
  778. package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +0 -77
  779. package/src/core/primitives/popover/__workshop__/MarginsStory.tsx +0 -31
  780. package/src/core/primitives/popover/__workshop__/MatchReferenceWidthStory.tsx +0 -32
  781. package/src/core/primitives/popover/__workshop__/OpenOnMountStory.tsx +0 -11
  782. package/src/core/primitives/popover/__workshop__/PlainStory.tsx +0 -71
  783. package/src/core/primitives/popover/__workshop__/RecursiveStory.tsx +0 -71
  784. package/src/core/primitives/popover/__workshop__/SidePanelStory.tsx +0 -89
  785. package/src/core/primitives/popover/__workshop__/TestStory.tsx +0 -97
  786. package/src/core/primitives/popover/__workshop__/index.ts +0 -49
  787. package/src/core/primitives/popover/constants.ts +0 -22
  788. package/src/core/primitives/popover/floating-ui/size.ts +0 -99
  789. package/src/core/primitives/popover/helpers.ts +0 -31
  790. package/src/core/primitives/popover/index.ts +0 -2
  791. package/src/core/primitives/popover/popover.tsx +0 -511
  792. package/src/core/primitives/popover/popoverCard.tsx +0 -166
  793. package/src/core/primitives/popover/types.ts +0 -7
  794. package/src/core/primitives/radio/__workshop__/example.tsx +0 -63
  795. package/src/core/primitives/radio/__workshop__/index.ts +0 -11
  796. package/src/core/primitives/radio/__workshop__/plain.tsx +0 -28
  797. package/src/core/primitives/radio/index.ts +0 -1
  798. package/src/core/primitives/radio/radio.tsx +0 -51
  799. package/src/core/primitives/radio/styles.ts +0 -117
  800. package/src/core/primitives/select/__workshop__/index.ts +0 -11
  801. package/src/core/primitives/select/__workshop__/plain.tsx +0 -27
  802. package/src/core/primitives/select/__workshop__/readOnly.tsx +0 -23
  803. package/src/core/primitives/select/index.ts +0 -1
  804. package/src/core/primitives/select/select.test.tsx +0 -52
  805. package/src/core/primitives/select/select.tsx +0 -94
  806. package/src/core/primitives/select/styles.ts +0 -166
  807. package/src/core/primitives/spinner/__workshop__/Props.tsx +0 -15
  808. package/src/core/primitives/spinner/__workshop__/index.ts +0 -14
  809. package/src/core/primitives/spinner/index.ts +0 -1
  810. package/src/core/primitives/spinner/spinner.tsx +0 -46
  811. package/src/core/primitives/stack/__workshop__/index.ts +0 -14
  812. package/src/core/primitives/stack/__workshop__/plain.tsx +0 -32
  813. package/src/core/primitives/stack/index.ts +0 -1
  814. package/src/core/primitives/stack/stack.test.tsx +0 -57
  815. package/src/core/primitives/stack/stack.tsx +0 -57
  816. package/src/core/primitives/stack/styles.ts +0 -32
  817. package/src/core/primitives/switch/__workshop__/example.tsx +0 -23
  818. package/src/core/primitives/switch/__workshop__/index.ts +0 -11
  819. package/src/core/primitives/switch/__workshop__/props.tsx +0 -21
  820. package/src/core/primitives/switch/index.ts +0 -1
  821. package/src/core/primitives/switch/styles.ts +0 -173
  822. package/src/core/primitives/switch/switch.tsx +0 -68
  823. package/src/core/primitives/text/__workshop__/colored.tsx +0 -30
  824. package/src/core/primitives/text/__workshop__/example.tsx +0 -39
  825. package/src/core/primitives/text/__workshop__/index.ts +0 -24
  826. package/src/core/primitives/text/__workshop__/opticalAlignment.tsx +0 -48
  827. package/src/core/primitives/text/index.ts +0 -1
  828. package/src/core/primitives/text/styles.ts +0 -74
  829. package/src/core/primitives/text/text.tsx +0 -89
  830. package/src/core/primitives/textArea/__workshop__/index.ts +0 -14
  831. package/src/core/primitives/textArea/__workshop__/plain.tsx +0 -50
  832. package/src/core/primitives/textArea/index.ts +0 -1
  833. package/src/core/primitives/textArea/textArea.tsx +0 -120
  834. package/src/core/primitives/textInput/__workshop__/clearButton.tsx +0 -30
  835. package/src/core/primitives/textInput/__workshop__/customValidity.tsx +0 -17
  836. package/src/core/primitives/textInput/__workshop__/index.ts +0 -44
  837. package/src/core/primitives/textInput/__workshop__/plain.tsx +0 -98
  838. package/src/core/primitives/textInput/__workshop__/readOnly.tsx +0 -9
  839. package/src/core/primitives/textInput/__workshop__/states.tsx +0 -53
  840. package/src/core/primitives/textInput/__workshop__/tones.tsx +0 -277
  841. package/src/core/primitives/textInput/__workshop__/typed.tsx +0 -23
  842. package/src/core/primitives/textInput/index.ts +0 -1
  843. package/src/core/primitives/textInput/textInput.test.tsx +0 -48
  844. package/src/core/primitives/textInput/textInput.tsx +0 -395
  845. package/src/core/primitives/tooltip/__workshop__/customPortal.tsx +0 -102
  846. package/src/core/primitives/tooltip/__workshop__/index.ts +0 -29
  847. package/src/core/primitives/tooltip/__workshop__/overflowingBoundary.tsx +0 -74
  848. package/src/core/primitives/tooltip/__workshop__/props.tsx +0 -107
  849. package/src/core/primitives/tooltip/__workshop__/resizableBoundary.tsx +0 -86
  850. package/src/core/primitives/tooltip/constants.ts +0 -23
  851. package/src/core/primitives/tooltip/index.ts +0 -2
  852. package/src/core/primitives/tooltip/tooltip.test.tsx +0 -452
  853. package/src/core/primitives/tooltip/tooltip.tsx +0 -495
  854. package/src/core/primitives/tooltip/tooltipCard.tsx +0 -109
  855. package/src/core/primitives/tooltip/tooltipDelayGroup/index.ts +0 -4
  856. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupContext.tsx +0 -11
  857. package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx +0 -57
  858. package/src/core/primitives/tooltip/tooltipDelayGroup/types.ts +0 -10
  859. package/src/core/primitives/tooltip/tooltipDelayGroup/useTooltipDelayGroup.ts +0 -13
  860. package/src/core/primitives/types.ts +0 -179
  861. package/src/core/styles/border/borderStyle.ts +0 -56
  862. package/src/core/styles/border/index.ts +0 -2
  863. package/src/core/styles/border/types.ts +0 -10
  864. package/src/core/styles/box/boxStyle.ts +0 -69
  865. package/src/core/styles/box/index.ts +0 -2
  866. package/src/core/styles/box/types.ts +0 -11
  867. package/src/core/styles/card/_cardColorStyle.ts +0 -108
  868. package/src/core/styles/card/index.ts +0 -1
  869. package/src/core/styles/flex/flexItemStyle.ts +0 -27
  870. package/src/core/styles/flex/flexStyle.ts +0 -70
  871. package/src/core/styles/flex/index.ts +0 -3
  872. package/src/core/styles/flex/types.ts +0 -25
  873. package/src/core/styles/focusRing/index.ts +0 -25
  874. package/src/core/styles/font/codeFontStyle.ts +0 -13
  875. package/src/core/styles/font/headingFontStyle.ts +0 -13
  876. package/src/core/styles/font/index.ts +0 -6
  877. package/src/core/styles/font/labelFontStyle.ts +0 -13
  878. package/src/core/styles/font/responsiveFont.ts +0 -103
  879. package/src/core/styles/font/textAlignStyle.ts +0 -19
  880. package/src/core/styles/font/textFontStyle.ts +0 -13
  881. package/src/core/styles/font/types.ts +0 -35
  882. package/src/core/styles/grid/gridItemStyle.ts +0 -82
  883. package/src/core/styles/grid/gridStyle.ts +0 -108
  884. package/src/core/styles/grid/index.ts +0 -3
  885. package/src/core/styles/grid/types.ts +0 -37
  886. package/src/core/styles/helpers.ts +0 -72
  887. package/src/core/styles/index.ts +0 -5
  888. package/src/core/styles/input/index.ts +0 -2
  889. package/src/core/styles/input/responsiveInputPaddingStyle.ts +0 -78
  890. package/src/core/styles/input/textInputStyle.ts +0 -263
  891. package/src/core/styles/internal.ts +0 -12
  892. package/src/core/styles/margin/index.ts +0 -2
  893. package/src/core/styles/margin/marginStyle.ts +0 -21
  894. package/src/core/styles/margin/marginsStyle.test.ts +0 -33
  895. package/src/core/styles/margin/types.ts +0 -9
  896. package/src/core/styles/padding/index.ts +0 -2
  897. package/src/core/styles/padding/paddingStyle.test.ts +0 -33
  898. package/src/core/styles/padding/paddingStyle.ts +0 -21
  899. package/src/core/styles/padding/types.ts +0 -12
  900. package/src/core/styles/radius/index.ts +0 -2
  901. package/src/core/styles/radius/radiusStyle.ts +0 -23
  902. package/src/core/styles/radius/types.ts +0 -8
  903. package/src/core/styles/shadow/index.ts +0 -2
  904. package/src/core/styles/shadow/shadowStyle.ts +0 -29
  905. package/src/core/styles/shadow/types.ts +0 -6
  906. package/src/core/styles/types.ts +0 -8
  907. package/src/core/theme/__workshop__/build/Root.tsx +0 -367
  908. package/src/core/theme/__workshop__/build/helpers.ts +0 -46
  909. package/src/core/theme/__workshop__/build/story.tsx +0 -465
  910. package/src/core/theme/__workshop__/canvas.tsx +0 -352
  911. package/src/core/theme/__workshop__/color.tsx +0 -62
  912. package/src/core/theme/__workshop__/debug/story.tsx +0 -408
  913. package/src/core/theme/__workshop__/index.ts +0 -39
  914. package/src/core/theme/__workshop__/layer.tsx +0 -78
  915. package/src/core/theme/__workshop__/nestedProvider.tsx +0 -15
  916. package/src/core/theme/index.ts +0 -5
  917. package/src/core/theme/theme.test.tsx +0 -73
  918. package/src/core/theme/themeColorProvider.tsx +0 -29
  919. package/src/core/theme/themeContext.ts +0 -10
  920. package/src/core/theme/themeProvider.tsx +0 -62
  921. package/src/core/theme/types.ts +0 -12
  922. package/src/core/theme/useRootTheme.ts +0 -17
  923. package/src/core/theme/useTheme.ts +0 -16
  924. package/src/core/types/avatar.ts +0 -14
  925. package/src/core/types/badge.ts +0 -12
  926. package/src/core/types/box.ts +0 -19
  927. package/src/core/types/button.ts +0 -21
  928. package/src/core/types/card.ts +0 -6
  929. package/src/core/types/component.ts +0 -32
  930. package/src/core/types/dialog.ts +0 -4
  931. package/src/core/types/flex.ts +0 -30
  932. package/src/core/types/grid.ts +0 -14
  933. package/src/core/types/gridItem.ts +0 -29
  934. package/src/core/types/index.ts +0 -15
  935. package/src/core/types/placement.ts +0 -18
  936. package/src/core/types/popover.ts +0 -4
  937. package/src/core/types/radius.ts +0 -4
  938. package/src/core/types/selectable.ts +0 -6
  939. package/src/core/types/text.ts +0 -4
  940. package/src/core/utils/arrow/arrow.tsx +0 -123
  941. package/src/core/utils/arrow/cmds.ts +0 -91
  942. package/src/core/utils/arrow/index.ts +0 -1
  943. package/src/core/utils/boundaryElement/__workshop__/index.ts +0 -14
  944. package/src/core/utils/boundaryElement/__workshop__/plain.tsx +0 -19
  945. package/src/core/utils/boundaryElement/boundaryElement.test.tsx +0 -100
  946. package/src/core/utils/boundaryElement/boundaryElementContext.ts +0 -7
  947. package/src/core/utils/boundaryElement/boundaryElementProvider.tsx +0 -24
  948. package/src/core/utils/boundaryElement/index.ts +0 -3
  949. package/src/core/utils/boundaryElement/types.ts +0 -7
  950. package/src/core/utils/boundaryElement/useBoundaryElement.ts +0 -26
  951. package/src/core/utils/conditionalWrapper/conditionalWrapper.tsx +0 -21
  952. package/src/core/utils/conditionalWrapper/index.ts +0 -1
  953. package/src/core/utils/elementQuery/__workshop__/customMedia.tsx +0 -30
  954. package/src/core/utils/elementQuery/__workshop__/index.ts +0 -14
  955. package/src/core/utils/elementQuery/elementQuery.tsx +0 -53
  956. package/src/core/utils/elementQuery/helpers.ts +0 -27
  957. package/src/core/utils/elementQuery/index.ts +0 -1
  958. package/src/core/utils/errorBoundary.tsx +0 -48
  959. package/src/core/utils/getElementRef.ts +0 -26
  960. package/src/core/utils/index.ts +0 -9
  961. package/src/core/utils/layer/__workshop__/_debug.tsx +0 -17
  962. package/src/core/utils/layer/__workshop__/index.ts +0 -24
  963. package/src/core/utils/layer/__workshop__/multipleRoots.tsx +0 -49
  964. package/src/core/utils/layer/__workshop__/nested.tsx +0 -98
  965. package/src/core/utils/layer/__workshop__/responsiveZOffset.tsx +0 -13
  966. package/src/core/utils/layer/getLayerContext.test.ts +0 -30
  967. package/src/core/utils/layer/getLayerContext.ts +0 -21
  968. package/src/core/utils/layer/index.ts +0 -4
  969. package/src/core/utils/layer/layer.test.tsx +0 -108
  970. package/src/core/utils/layer/layer.tsx +0 -98
  971. package/src/core/utils/layer/layerContext.ts +0 -7
  972. package/src/core/utils/layer/layerProvider.tsx +0 -111
  973. package/src/core/utils/layer/types.ts +0 -9
  974. package/src/core/utils/layer/useLayer.ts +0 -26
  975. package/src/core/utils/portal/__workshop__/index.ts +0 -14
  976. package/src/core/utils/portal/__workshop__/named.tsx +0 -63
  977. package/src/core/utils/portal/index.ts +0 -4
  978. package/src/core/utils/portal/portal.test.tsx +0 -103
  979. package/src/core/utils/portal/portal.ts +0 -32
  980. package/src/core/utils/portal/portalContext.ts +0 -31
  981. package/src/core/utils/portal/portalProvider.tsx +0 -47
  982. package/src/core/utils/portal/types.ts +0 -9
  983. package/src/core/utils/portal/usePortal.ts +0 -25
  984. package/src/core/utils/spanWithTextOverflow.tsx +0 -10
  985. package/src/core/utils/srOnly/index.ts +0 -1
  986. package/src/core/utils/srOnly/srOnly.tsx +0 -36
  987. package/src/core/utils/virtualList/__workshop__/changingProps.tsx +0 -36
  988. package/src/core/utils/virtualList/__workshop__/elementScroll.tsx +0 -24
  989. package/src/core/utils/virtualList/__workshop__/index.ts +0 -29
  990. package/src/core/utils/virtualList/__workshop__/infiniteList.tsx +0 -48
  991. package/src/core/utils/virtualList/__workshop__/windowScrolll.tsx +0 -22
  992. package/src/core/utils/virtualList/index.ts +0 -1
  993. package/src/core/utils/virtualList/virtualList.tsx +0 -200
  994. package/src/theme/build/_deprecated/color/_selectable/createSelectableTones.ts +0 -76
  995. package/src/theme/build/_deprecated/color/_solid/createSolidTones.ts +0 -54
  996. package/src/theme/build/_deprecated/color/button/createButtonModes.ts +0 -22
  997. package/src/theme/build/_deprecated/color/button/createButtonTones.ts +0 -55
  998. package/src/theme/build/_deprecated/color/card/createCardStates.ts +0 -60
  999. package/src/theme/build/_deprecated/color/color.test.ts +0 -63
  1000. package/src/theme/build/_deprecated/color/defaults.ts +0 -390
  1001. package/src/theme/build/_deprecated/color/factory.ts +0 -142
  1002. package/src/theme/build/_deprecated/color/index.ts +0 -1
  1003. package/src/theme/build/_deprecated/color/input/createInputModes.ts +0 -81
  1004. package/src/theme/build/_deprecated/color/muted/createMuted.ts +0 -54
  1005. package/src/theme/build/_deprecated/color/spot/createSpot.ts +0 -20
  1006. package/src/theme/build/buildColorTheme.test.ts +0 -183
  1007. package/src/theme/build/buildColorTheme.ts +0 -499
  1008. package/src/theme/build/buildTheme.test.ts +0 -87
  1009. package/src/theme/build/buildTheme.ts +0 -36
  1010. package/src/theme/build/colorToken/colorToken.ts +0 -19
  1011. package/src/theme/build/colorToken/compileColorToken.ts +0 -21
  1012. package/src/theme/build/colorToken/index.ts +0 -2
  1013. package/src/theme/build/colorToken/types.ts +0 -6
  1014. package/src/theme/build/index.ts +0 -3
  1015. package/src/theme/build/lib/color-fns/blend/index.ts +0 -3
  1016. package/src/theme/build/lib/color-fns/blend/mix.ts +0 -21
  1017. package/src/theme/build/lib/color-fns/blend/multiply.ts +0 -18
  1018. package/src/theme/build/lib/color-fns/blend/screen.ts +0 -18
  1019. package/src/theme/build/lib/color-fns/color-fns.test.ts +0 -68
  1020. package/src/theme/build/lib/color-fns/contrastRatio.ts +0 -31
  1021. package/src/theme/build/lib/color-fns/convert.ts +0 -150
  1022. package/src/theme/build/lib/color-fns/index.ts +0 -6
  1023. package/src/theme/build/lib/color-fns/parse.ts +0 -60
  1024. package/src/theme/build/lib/color-fns/rgba.ts +0 -10
  1025. package/src/theme/build/lib/color-fns/types.ts +0 -28
  1026. package/src/theme/build/lib/isRecord.ts +0 -3
  1027. package/src/theme/build/lib/lazy.ts +0 -30
  1028. package/src/theme/build/lib/utils.ts +0 -19
  1029. package/src/theme/build/merge.ts +0 -26
  1030. package/src/theme/build/mixThemeColor.test.ts +0 -21
  1031. package/src/theme/build/mixThemeColor.ts +0 -53
  1032. package/src/theme/build/renderColorTheme.ts +0 -532
  1033. package/src/theme/build/renderColorValue.ts +0 -85
  1034. package/src/theme/build/resolveColorTokens.ts +0 -268
  1035. package/src/theme/build/theme.test.ts +0 -27
  1036. package/src/theme/config/helpers.ts +0 -55
  1037. package/src/theme/config/index.ts +0 -4
  1038. package/src/theme/config/system.ts +0 -115
  1039. package/src/theme/config/tokens/color/index.ts +0 -1
  1040. package/src/theme/config/tokens/color/types.ts +0 -133
  1041. package/src/theme/config/tokens/index.ts +0 -4
  1042. package/src/theme/config/tokens/parseTokenKey.test.ts +0 -64
  1043. package/src/theme/config/tokens/parseTokenKey.ts +0 -67
  1044. package/src/theme/config/tokens/parseTokenValue.test.ts +0 -42
  1045. package/src/theme/config/tokens/parseTokenValue.ts +0 -133
  1046. package/src/theme/config/tokens/types.ts +0 -53
  1047. package/src/theme/config/types.ts +0 -46
  1048. package/src/theme/defaults/colorPalette.ts +0 -5
  1049. package/src/theme/defaults/colorTokens.ts +0 -648
  1050. package/src/theme/defaults/config.ts +0 -84
  1051. package/src/theme/defaults/fonts.ts +0 -227
  1052. package/src/theme/getScopedTheme.ts +0 -98
  1053. package/src/theme/index.ts +0 -5
  1054. package/src/theme/system/avatar.ts +0 -14
  1055. package/src/theme/system/color/_constants.ts +0 -45
  1056. package/src/theme/system/color/_helpers.ts +0 -24
  1057. package/src/theme/system/color/_system.ts +0 -40
  1058. package/src/theme/system/color/avatar.ts +0 -15
  1059. package/src/theme/system/color/badge.ts +0 -16
  1060. package/src/theme/system/color/button.ts +0 -17
  1061. package/src/theme/system/color/color.ts +0 -34
  1062. package/src/theme/system/color/index.ts +0 -13
  1063. package/src/theme/system/color/input.ts +0 -25
  1064. package/src/theme/system/color/kbd.ts +0 -8
  1065. package/src/theme/system/color/selectable.ts +0 -12
  1066. package/src/theme/system/color/shadow.ts +0 -7
  1067. package/src/theme/system/color/state.ts +0 -43
  1068. package/src/theme/system/color/syntax.ts +0 -41
  1069. package/src/theme/system/css.ts +0 -14
  1070. package/src/theme/system/focusRing.ts +0 -7
  1071. package/src/theme/system/font.ts +0 -52
  1072. package/src/theme/system/index.ts +0 -11
  1073. package/src/theme/system/input.ts +0 -33
  1074. package/src/theme/system/layer.ts +0 -8
  1075. package/src/theme/system/shadow.ts +0 -19
  1076. package/src/theme/system/styles.ts +0 -13
  1077. package/src/theme/system/theme.ts +0 -138
  1078. package/src/theme/system/v0/avatar.ts +0 -10
  1079. package/src/theme/system/v0/color/_generic.ts +0 -35
  1080. package/src/theme/system/v0/color/_system.ts +0 -17
  1081. package/src/theme/system/v0/color/base.ts +0 -21
  1082. package/src/theme/system/v0/color/button.ts +0 -42
  1083. package/src/theme/system/v0/color/card.ts +0 -19
  1084. package/src/theme/system/v0/color/color.ts +0 -40
  1085. package/src/theme/system/v0/color/index.ts +0 -11
  1086. package/src/theme/system/v0/color/input.ts +0 -34
  1087. package/src/theme/system/v0/color/muted.ts +0 -26
  1088. package/src/theme/system/v0/color/selectable.ts +0 -31
  1089. package/src/theme/system/v0/color/solid.ts +0 -26
  1090. package/src/theme/system/v0/color/spot.ts +0 -13
  1091. package/src/theme/system/v0/index.ts +0 -3
  1092. package/src/theme/system/v0/input.ts +0 -23
  1093. package/src/theme/versioning/getTheme_v2.ts +0 -57
  1094. package/src/theme/versioning/index.ts +0 -5
  1095. package/src/theme/versioning/is_v0.ts +0 -6
  1096. package/src/theme/versioning/is_v2.ts +0 -6
  1097. package/src/theme/versioning/themeColor_v0_v2.ts +0 -243
  1098. package/src/theme/versioning/themeColor_v2_v2_9.ts +0 -49
  1099. package/src/theme/versioning/v0_v2.ts +0 -94
  1100. package/src/theme/versioning/v2_v0.ts +0 -135
@@ -0,0 +1,3020 @@
1
+ import { CATALOG, FEATURES, isHostConfigKey } from "./lossy.js";
2
+ import { CONTROL_TYPES, HELP_MORE_MAX, ITEM_NAME_RE, UI_CONTROLS } from "./prod-types.js";
3
+ import { dockIconOf, tablerIconOf } from "./icons.js";
4
+ import { slotChildrenFromStored, slotChildrenToStored } from "../controls/slot-services.js";
5
+ import { isDataTableProp, tableConfigFromOptions, tableOptionsFromConfig } from "../controls/table/prod.js";
6
+ import { buttonFromProd, buttonToProd, datetimeFromProd, datetimeToProd, imageFromProd, imageToProd, isCropRect, linkFromProd, linkToProd, listFromProd, listToProd, ratingFromProd, ratingToProd, referenceFromProd, referenceToProd, scaleFromProd, scaleToProd, typedRowsFromProd, typedRowsToProd, videoFromProd, videoToProd, zoneListFromProd, zoneListToProd } from "./values.js";
7
+ //#region src/adapters/schema.ts
8
+ var isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
9
+ function deepEqual(a, b) {
10
+ if (a === b) return true;
11
+ if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((x, i) => deepEqual(x, b[i]));
12
+ if (!isObj(a) || !isObj(b)) return false;
13
+ return [...new Set([...Object.keys(a), ...Object.keys(b)].filter((k) => a[k] !== void 0 || b[k] !== void 0))].every((k) => deepEqual(a[k], b[k]));
14
+ }
15
+ var singular = (t) => t.endsWith("ies") ? `${t.slice(0, -3)}y` : t.endsWith("s") && !t.endsWith("ss") ? t.slice(0, -1) : t;
16
+ var kebab = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "schema";
17
+ var camel = (s) => s.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
18
+ /** The slug a V2 schema name is stored under (a component's, when the host seeds a /kit block): `textBlock` → `text-block`. */
19
+ var schemaSlugOf = kebab;
20
+ var capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
21
+ var ZONE_NAMES = new Set(typeof Intl.supportedValuesOf === "function" ? [...Intl.supportedValuesOf("timeZone"), "UTC"] : ["UTC"]);
22
+ /** An IANA zone name (isTimeZoneName): ICU's canonical list, or a current name Intl itself accepts (Asia/Kolkata). */
23
+ var isZone = (z) => {
24
+ if (ZONE_NAMES.has(z)) return true;
25
+ if (!/^[A-Za-z]+(?:\/[A-Za-z0-9_+-]+)+$/.test(z)) return false;
26
+ try {
27
+ new Intl.DateTimeFormat("en", { timeZone: z });
28
+ return true;
29
+ } catch {
30
+ return false;
31
+ }
32
+ };
33
+ /** The item type of a single-type array, as both directions name it when prod has no name for it. */
34
+ var conventionItem = (fieldName, fieldTitle, itemLabel) => ({
35
+ name: singular(fieldName),
36
+ title: itemLabel ?? singular(fieldTitle)
37
+ });
38
+ /** A condition's value as the sibling's type reads it (prod stores rule values as strings). */
39
+ function coerceRuleValue(siblingType, s) {
40
+ if (siblingType === "boolean") return s === "true" ? true : s === "false" ? false : s;
41
+ if ((siblingType === "number" || siblingType === "rating") && s.trim() !== "" && Number.isFinite(Number(s))) return Number(s);
42
+ return s;
43
+ }
44
+ /** V2 primitive types → the same-valued prod field type (fields lane). */
45
+ var FIELD_TYPE = {
46
+ string: "text",
47
+ text: "longtext",
48
+ richtext: "richtext",
49
+ number: "number",
50
+ rating: "rating",
51
+ boolean: "boolean",
52
+ slug: "slug",
53
+ email: "email",
54
+ date: "date",
55
+ datetime: "datetime",
56
+ color: "color",
57
+ select: "select",
58
+ multiselect: "multiselect",
59
+ tags: "tags",
60
+ image: "image",
61
+ file: "file",
62
+ icon: "icon",
63
+ link: "link",
64
+ button: "button",
65
+ reference: "reference",
66
+ json: "json",
67
+ geopoint: "location",
68
+ url: "text",
69
+ code: "code",
70
+ video: "video"
71
+ };
72
+ /** V2 primitive types → prop types. */
73
+ var PROP_TYPE = {
74
+ string: "text",
75
+ text: "longtext",
76
+ video: "video",
77
+ richtext: "richtext",
78
+ number: "number",
79
+ rating: "rating",
80
+ boolean: "boolean",
81
+ slug: "slug",
82
+ email: "email",
83
+ date: "date",
84
+ datetime: "datetime",
85
+ color: "color",
86
+ select: "select",
87
+ multiselect: "multiselect",
88
+ tags: "tags",
89
+ image: "image",
90
+ file: "file",
91
+ icon: "icon",
92
+ link: "link",
93
+ button: "button",
94
+ json: "json",
95
+ geopoint: "location",
96
+ url: "url",
97
+ code: "code"
98
+ };
99
+ /** Field types whose `config` the backend parses strictly (unknown keys stripped or refused). */
100
+ var STRICT_CONFIG = /* @__PURE__ */ new Set([
101
+ "array",
102
+ "reference",
103
+ "multi-reference",
104
+ "multiReference",
105
+ "date",
106
+ "datetime",
107
+ "component-ref",
108
+ "modular",
109
+ "sections",
110
+ "tags",
111
+ "rating",
112
+ "code",
113
+ "video",
114
+ "table",
115
+ "slot"
116
+ ]);
117
+ /** V2 list item types → prod `config.itemType` (ARRAY_ITEM_TYPES); a V2 `text` item reads back as `string`. */
118
+ var PRIM_ITEM = {
119
+ string: "text",
120
+ text: "text",
121
+ number: "number",
122
+ date: "date",
123
+ image: "image",
124
+ link: "link",
125
+ richtext: "richtext"
126
+ };
127
+ var ENTRY_TARGET = (t) => ![
128
+ "page",
129
+ "form",
130
+ "shopify",
131
+ "collection"
132
+ ].includes(t);
133
+ /** The non-entry targets a prop reference stores in config.targets (backend reference-target-config.ts REF_TARGET_KINDS). */
134
+ var REF_TARGET_KINDS = [
135
+ "page",
136
+ "form",
137
+ "collection"
138
+ ];
139
+ /**
140
+ * A prop reference whose only target is Shopify (backend reference-target-config.ts UNSUPPORTED_TARGETS refuses it by
141
+ * name) is stored as locked text holding the id (a list of them: a list of text), so the value stays the plain gid
142
+ * string V2 holds. This lock reason is the marker the read side turns back into V2's reference (allowed deviation
143
+ * "shopify reference").
144
+ */
145
+ var SHOPIFY_REF_LOCK = "A Shopify product id. No Shopify integration backs a reference in BetterCMS yet, so the id is kept as it is.";
146
+ var shopifyOnly = (r) => !!r?.to?.length && r.to.every((t) => t === "shopify");
147
+ /** backend REFERENCE_FILTER_MAX; parameters ($x) and the parent document (^) are refused there (reference_filter_invalid). */
148
+ var REFERENCE_FILTER_MAX = 500;
149
+ var filterKept = (f) => typeof f === "string" && f.trim() !== "" && f.length <= REFERENCE_FILTER_MAX && !/[$^]/.test(f);
150
+ /** The old rating: a number with ui.control "rating" and these bounds read back as no `numeric` (read side only). */
151
+ var RATING_CONFIG = {
152
+ min: 0,
153
+ max: 5,
154
+ step: .5
155
+ };
156
+ /**
157
+ * A V2 rating sets no step and holds any number on its scale (a 4.8 average). Prod's unset step is 1, which refuses
158
+ * 4.8 (rating_value_invalid), so a rating with no step is written with step 0.1 (≤ RATING_MAX_STOPS stops on a 1–10
159
+ * scale) and that step reads back as none; a prod rating with no step reads back as its real step, 1.
160
+ */
161
+ var V2_RATING_STEP = .1;
162
+ /**
163
+ * V2 block-picker category (KitCategory, and the core examples' own) → the nearest prod ComponentCategory. A category
164
+ * with no row has no prod twin; the server defaults the component to "custom".
165
+ */
166
+ var CATEGORY_TO_PROD = {
167
+ "Navigation & chrome": "navbar",
168
+ Heroes: "hero",
169
+ "Features & storytelling": "content",
170
+ "Social proof": "social-proof",
171
+ "Media & galleries": "content",
172
+ Commerce: "conversion",
173
+ "Pricing & plans": "conversion",
174
+ "Conversion & forms": "conversion",
175
+ "Listings & feeds": "content",
176
+ "Long-form & docs": "content",
177
+ "Company & people": "content",
178
+ "Events & places": "content",
179
+ "Data & interactive": "section",
180
+ Navigation: "navbar",
181
+ Hero: "hero",
182
+ Content: "content",
183
+ Layout: "section"
184
+ };
185
+ /** The field types a kind:'block' model may hold (backend block-model-mapping.ts FIELD_PRIMITIVE). */
186
+ var BLOCK_FIELD_TYPES = /* @__PURE__ */ new Set([
187
+ "text",
188
+ "longtext",
189
+ "richtext",
190
+ "image",
191
+ "link",
192
+ "slug",
193
+ "email",
194
+ "phone",
195
+ "color",
196
+ "select",
197
+ "number",
198
+ "rating",
199
+ "date",
200
+ "datetime",
201
+ "boolean"
202
+ ]);
203
+ /** A slot prop's config.minItems / maxItems cap (SLOT_ITEMS_CAP, componentPropDefSchema). */
204
+ var SLOT_ITEMS_CAP = 50;
205
+ /** A table prop's rows and an array prop's items: their config.minItems / maxItems cap (LIST_ITEMS_CAP). */
206
+ var LIST_ITEMS_CAP = 500;
207
+ /** backend slotAllowIssues: a slot's config.allow holds 1–50 block names of 1–64 characters, no repeats. */
208
+ var SLOT_ALLOW_MAX = 50;
209
+ var SLOT_ALLOW_NAME_MAX = 64;
210
+ /** Backend dock-vocabulary.ts SLIDER_MAX_STOPS: a slider's (max − min) / step. */
211
+ var SLIDER_MAX_STOPS = 1e3;
212
+ /**
213
+ * The field types prod's unique flag accepts (uniqueFlagRules): a comparable scalar (UNIQUE_FIELD_TYPES, no two entries
214
+ * share it; a reference only to one model) or a list (UNIQUE_ITEMS_FIELD_TYPES, no item repeats).
215
+ */
216
+ var UNIQUE_TYPES = /* @__PURE__ */ new Set([
217
+ "text",
218
+ "longtext",
219
+ "slug",
220
+ "email",
221
+ "phone",
222
+ "link",
223
+ "number",
224
+ "select",
225
+ "reference",
226
+ "date",
227
+ "array",
228
+ "multiselect",
229
+ "tags",
230
+ "multi-reference"
231
+ ]);
232
+ /** Prop types whose value is a list (UNIQUE_LIST_PROP_TYPES), and the sub-field types a table row compares (UNIQUE_ROW_PROP_TYPES). */
233
+ var UNIQUE_LIST_PROPS = /* @__PURE__ */ new Set([
234
+ "multiselect",
235
+ "tags",
236
+ "multi-reference",
237
+ "table",
238
+ "array"
239
+ ]);
240
+ var UNIQUE_ROW_PROPS = /* @__PURE__ */ new Set([
241
+ "text",
242
+ "url",
243
+ "slug",
244
+ "email",
245
+ "phone",
246
+ "number",
247
+ "select",
248
+ "date"
249
+ ]);
250
+ /** Types measured by minLength / maxLength (fields: LENGTH_FIELD_TYPES; props: LENGTH_TWIN), and those that take a pattern. */
251
+ var LENGTH_FIELDS = /* @__PURE__ */ new Set([
252
+ "text",
253
+ "longtext",
254
+ "richtext",
255
+ "document"
256
+ ]);
257
+ var LENGTH_PROPS = /* @__PURE__ */ new Set([
258
+ "text",
259
+ "url",
260
+ "longtext",
261
+ "richtext"
262
+ ]);
263
+ var PATTERN_TYPES = /* @__PURE__ */ new Set([
264
+ "text",
265
+ "longtext",
266
+ "url"
267
+ ]);
268
+ /**
269
+ * Leaf types whose value is an object a dotted preview path may read into (previewPathProblem OBJECT_VALUE_TYPES), and the
270
+ * keys an image or video value holds (LEAF_VALUE_KEYS). V2 reads `image.alt`; prod stores the key as `altText`.
271
+ */
272
+ var OBJECT_VALUE_TYPES = /* @__PURE__ */ new Set([
273
+ "image",
274
+ "link",
275
+ "button",
276
+ "file",
277
+ "video",
278
+ "location",
279
+ "json",
280
+ "code",
281
+ "reference",
282
+ "multi-reference"
283
+ ]);
284
+ var LEAF_VALUE_KEYS = {
285
+ image: [
286
+ "id",
287
+ "url",
288
+ "name",
289
+ "altText",
290
+ "width",
291
+ "height",
292
+ "focal",
293
+ "crop"
294
+ ],
295
+ video: [
296
+ "url",
297
+ "poster",
298
+ "autoplay",
299
+ "loop",
300
+ "transcript"
301
+ ]
302
+ };
303
+ var IMAGE_PATH_KEY = { alt: "altText" };
304
+ /** The keys of a data table's value a preview path may end on (previewPathProblem `<table>.caption` / `.notes`). */
305
+ var TABLE_PATH_KEYS = ["caption", "notes"];
306
+ var lose = (ctx, path, feature) => ctx.lossy.push({
307
+ path,
308
+ feature,
309
+ reason: FEATURES[feature].reason
310
+ });
311
+ var cat = (ctx, path, feature) => ctx.catalog.push({
312
+ path,
313
+ feature,
314
+ reason: CATALOG[feature]
315
+ });
316
+ /** Keys every type keeps, including a field degraded to json. */
317
+ var COMMON_KEYS = /* @__PURE__ */ new Set([
318
+ "name",
319
+ "title",
320
+ "type",
321
+ "description",
322
+ "helpMore",
323
+ "initialValue",
324
+ "validation",
325
+ "fieldset",
326
+ "group",
327
+ "hidden",
328
+ "readOnly",
329
+ "access",
330
+ "lockReason",
331
+ "advanced",
332
+ "localized",
333
+ "ai",
334
+ "placeholder",
335
+ "archived"
336
+ ]);
337
+ /** Types a slot setting may not be (backend slotSettingsHardening, and a model slot's SLOT_SETTINGS_NESTING: leaf fields only). */
338
+ var SETTING_NESTING_TYPES = /* @__PURE__ */ new Set([
339
+ "object",
340
+ "group",
341
+ "array",
342
+ "table",
343
+ "slot",
344
+ "form",
345
+ "modular"
346
+ ]);
347
+ /** backend slotSettingsHardening: at most this many per-child settings. */
348
+ var SLOT_SETTINGS_MAX = 20;
349
+ /** backend ITEM_TYPE_NAME (what a row's `_type` holds), and an item type label's cap. */
350
+ var ITEM_TYPE_NAME = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;
351
+ var ITEM_TYPE_LABEL_MAX = 120;
352
+ function shapeOf(f, lv, ctx, top, nest) {
353
+ const shape = shapeOfField(f, lv, ctx, top);
354
+ if (nest === "setting" && SETTING_NESTING_TYPES.has(shape.type)) return {
355
+ kind: "json",
356
+ type: "json",
357
+ feature: "slotSettings"
358
+ };
359
+ return shape;
360
+ }
361
+ /** backend content.ts keyRuleProblem: keys a resolver would misread (KEY_RESERVED), and a key's format (KEY_FORMAT). */
362
+ var MODEL_RESERVED_KEYS = /* @__PURE__ */ new Set([
363
+ "derived",
364
+ "layout",
365
+ "page"
366
+ ]);
367
+ /** The key a model field is stored under: a reserved or malformed V2 name, renamed. */
368
+ function modelKeyOf(name) {
369
+ let k = name.replace(/^_+/, "").replace(/[^A-Za-z0-9_-]/g, "");
370
+ if (!/^[A-Za-z]/.test(k)) k = `f${k}`;
371
+ return MODEL_RESERVED_KEYS.has(k) ? `${k}Field` : k;
372
+ }
373
+ /** A slot's V2 allow list as the backend keeps it: 1–50 distinct block names of 1–64 characters (slotAllowIssues). */
374
+ var slotAllowOk = (allow) => Array.isArray(allow) && allow.length >= 1 && allow.length <= SLOT_ALLOW_MAX && new Set(allow).size === allow.length && allow.every((n) => typeof n === "string" && n === n.trim() && n.length >= 1 && n.length <= SLOT_ALLOW_NAME_MAX);
375
+ function shapeOfField(f, lv, ctx, top) {
376
+ const props = ctx.lane === "props";
377
+ const deep = lv >= 10;
378
+ const of = Array.isArray(f.of) ? f.of : void 0;
379
+ /** a prop reference names a content model or a page / form / collection target (refTargetNamed): with none it is stored as json */
380
+ const noEntry = (r) => props && !(r?.to ?? []).some((t) => ENTRY_TARGET(t) || REF_TARGET_KINDS.includes(t));
381
+ switch (f.type) {
382
+ case "object": return deep ? {
383
+ kind: "json",
384
+ type: "json",
385
+ feature: "depth>10"
386
+ } : {
387
+ kind: "object",
388
+ type: "object"
389
+ };
390
+ case "array": {
391
+ if (of && of.length > 1 && of.every((i) => i.type === "object")) {
392
+ if (!props) return {
393
+ kind: "modular",
394
+ type: "modular",
395
+ items: of
396
+ };
397
+ return deep ? {
398
+ kind: "json",
399
+ type: "json",
400
+ feature: "depth>10"
401
+ } : {
402
+ kind: "types",
403
+ type: "table",
404
+ items: of
405
+ };
406
+ }
407
+ if (!of || of.length !== 1) return {
408
+ kind: "json",
409
+ type: "json",
410
+ feature: of ? "type:polymorphic-array" : "type:slot"
411
+ };
412
+ const item = of[0];
413
+ if (item.type === "object") return deep ? {
414
+ kind: "json",
415
+ type: "json",
416
+ feature: "depth>10"
417
+ } : {
418
+ kind: "zones",
419
+ type: props ? "table" : "array",
420
+ item
421
+ };
422
+ if (item.type === "reference" && shopifyOnly(item.reference)) return {
423
+ kind: "itemType",
424
+ type: "array",
425
+ item,
426
+ itemType: "text",
427
+ shopify: true
428
+ };
429
+ if (item.type === "reference") return noEntry(item.reference) ? {
430
+ kind: "json",
431
+ type: "json",
432
+ feature: "reference target"
433
+ } : {
434
+ kind: "refs",
435
+ type: "multi-reference",
436
+ item
437
+ };
438
+ const prim = PRIM_ITEM[item.type];
439
+ if (prim) return {
440
+ kind: "itemType",
441
+ type: "array",
442
+ item,
443
+ itemType: prim
444
+ };
445
+ return {
446
+ kind: "json",
447
+ type: "json",
448
+ feature: "type:primitive-array"
449
+ };
450
+ }
451
+ case "slot":
452
+ if (!props && !slotAllowOk(f.of?.allow)) return {
453
+ kind: "json",
454
+ type: "json",
455
+ feature: "type:slot"
456
+ };
457
+ return {
458
+ kind: "slot",
459
+ type: "slot"
460
+ };
461
+ case "table": return {
462
+ kind: "leaf",
463
+ type: "table"
464
+ };
465
+ case "reference":
466
+ if (props && top && f.reference?.to?.length === 1 && f.reference.to[0] === "form" && !f.reference.filter) return {
467
+ kind: "leaf",
468
+ type: "form"
469
+ };
470
+ if (shopifyOnly(f.reference)) return {
471
+ kind: "leaf",
472
+ type: "text",
473
+ shopify: true
474
+ };
475
+ return noEntry(f.reference) ? {
476
+ kind: "json",
477
+ type: "json",
478
+ feature: "reference target"
479
+ } : {
480
+ kind: "leaf",
481
+ type: "reference"
482
+ };
483
+ default: {
484
+ const t = props ? PROP_TYPE[f.type] : FIELD_TYPE[f.type];
485
+ return t ? {
486
+ kind: "leaf",
487
+ type: t
488
+ } : {
489
+ kind: "json",
490
+ type: "json",
491
+ feature: "unsupported key"
492
+ };
493
+ }
494
+ }
495
+ }
496
+ var trunc = (ctx, at, s, max, feature) => {
497
+ if (s.length <= max) return s;
498
+ lose(ctx, at, feature);
499
+ return s.slice(0, max);
500
+ };
501
+ function convertField(f, at, lv, ctx, siblings, top, inTable = false, inItem = false, inSetting = false) {
502
+ const props = ctx.lane === "props";
503
+ const shape = shapeOf(f, lv, ctx, top, inTable ? "rows" : inItem ? "item" : inSetting ? "setting" : void 0);
504
+ const node = {
505
+ key: f.name,
506
+ label: f.title,
507
+ type: shape.type,
508
+ config: {},
509
+ ui: {}
510
+ };
511
+ const twins = siblings.slice(0, Math.max(0, siblings.indexOf(f))).filter((s) => s.name === f.name).length;
512
+ if (twins) {
513
+ node.key = `${f.name}_${twins + 1}`;
514
+ lose(ctx, `${at}/name`, "duplicate name");
515
+ } else if (!props && modelKeyOf(f.name) !== f.name) {
516
+ node.key = modelKeyOf(f.name);
517
+ lose(ctx, `${at}/name`, "reserved name");
518
+ }
519
+ const nesting = shape.kind === "object" || shape.kind === "zones" || shape.kind === "types";
520
+ /** a list of items (objects, block models, item types, scalars or entries): ui.itemLabel names one item */
521
+ const listy = shape.kind === "zones" || shape.kind === "modular" || shape.kind === "types" || shape.kind === "itemType" || shape.kind === "refs";
522
+ const looseConfig = props || !STRICT_CONFIG.has(shape.type);
523
+ if (shape.kind === "json") lose(ctx, `${at}/type`, shape.feature);
524
+ const shopify = (shape.kind === "leaf" || shape.kind === "itemType") && shape.shopify === true;
525
+ if (shopify) {
526
+ if (f.readOnly !== true) lose(ctx, `${at}/readOnly`, "shopify reference");
527
+ node.readOnly = true;
528
+ node.lockReason = SHOPIFY_REF_LOCK;
529
+ }
530
+ if (!props && f.type === "url") node.config.inputType = "url";
531
+ if (shape.type === "datetime" && !props) node.config.includeTime = true;
532
+ if (shape.kind === "leaf" && shape.type === "table") node.config.mode = "data";
533
+ if (shape.kind === "types") node.config.mode = "types";
534
+ if (shape.kind === "slot" && props) node.config.multiple = true;
535
+ if (listy) {
536
+ const label = f.itemNoun !== void 0 ? capitalize(f.itemNoun) : props && shape.kind === "zones" && shape.item.title !== conventionItem(f.name, f.title).title ? shape.item.title : void 0;
537
+ if (label !== void 0 && label.length <= 24) node.ui.itemLabel = label;
538
+ }
539
+ const devLock = f.access?.edit === "schema.manage" && !!f.lockReason;
540
+ for (const k of Object.keys(f)) {
541
+ if (f[k] === void 0) continue;
542
+ const p = `${at}/${k}`;
543
+ if (shape.kind === "json" && !COMMON_KEYS.has(k)) {
544
+ lose(ctx, p, shape.feature);
545
+ continue;
546
+ }
547
+ if (shopify && (k === "reference" || k === "readOnly")) continue;
548
+ if (shopify && (k === "access" || k === "lockReason")) {
549
+ lose(ctx, p, "shopify reference");
550
+ continue;
551
+ }
552
+ switch (k) {
553
+ case "name":
554
+ case "title":
555
+ case "type": break;
556
+ case "description":
557
+ node.helpText = trunc(ctx, p, f.description, props ? 200 : 500, "help>limit");
558
+ break;
559
+ case "helpMore":
560
+ node.helpMore = trunc(ctx, p, f.helpMore, HELP_MORE_MAX, "help>limit");
561
+ break;
562
+ case "placeholder":
563
+ if (props) node.placeholder = trunc(ctx, p, f.placeholder, 120, "help>limit");
564
+ else if (looseConfig) node.placeholder = f.placeholder;
565
+ else node.ui.placeholder = trunc(ctx, p, f.placeholder, 120, "help>limit");
566
+ break;
567
+ case "initialValue":
568
+ if (props && (shape.type === "reference" || shape.type === "multi-reference" || shape.kind === "slot")) cat(ctx, p, "seeded instance");
569
+ else node.defaultValue = defaultToProd(f, shape, f.initialValue, p, ctx, lv, top);
570
+ break;
571
+ case "validation":
572
+ validationToProd(f, shape, node, p, ctx, inTable, top);
573
+ break;
574
+ case "options":
575
+ optionsToProd(f, shape, node, p, ctx);
576
+ break;
577
+ case "layout":
578
+ layoutToProd(f, shape, node, p, ctx);
579
+ break;
580
+ case "fields":
581
+ if (shape.kind === "object") node.children = f.fields.map((c, i) => convertField(c, `${p}/${i}`, lv + 1, ctx, f.fields, false));
582
+ else lose(ctx, p, "unsupported key");
583
+ break;
584
+ case "of":
585
+ ofToProd(f, shape, node, p, lv, ctx);
586
+ break;
587
+ case "openMode":
588
+ if (nesting || props && shape.type === "code") node.openMode = f.openMode;
589
+ else lose(ctx, p, "openMode");
590
+ break;
591
+ case "preview":
592
+ if (shape.kind === "object") node.ui.preview = previewToProd(f.preview, f.fields ?? [], p, ctx);
593
+ else lose(ctx, p, "unsupported key");
594
+ break;
595
+ case "fieldset":
596
+ case "group": break;
597
+ case "hidden":
598
+ if (typeof f.hidden === "boolean") node.ui.hidden = f.hidden;
599
+ else {
600
+ const showIf = conditionToShowIf(f.hidden, p, siblings, ctx, props && top);
601
+ if (showIf) node.showIf = showIf;
602
+ }
603
+ break;
604
+ case "readOnly":
605
+ if (f.readOnly === true && !devLock) node.readOnly = true;
606
+ else lose(ctx, p, "access");
607
+ break;
608
+ case "access": {
609
+ const access = {};
610
+ for (const [ak, av] of Object.entries(f.access)) {
611
+ if (av === void 0) continue;
612
+ if (ak === "view" && av === "schema.view") access.view = av;
613
+ else if (ak === "edit" && av === "schema.manage") access.edit = av;
614
+ else lose(ctx, `${p}/${ak}`, "access");
615
+ }
616
+ if (Object.keys(access).length) node.ui.access = access;
617
+ if (devLock) node.readOnly = "developer";
618
+ break;
619
+ }
620
+ case "lockReason":
621
+ node.lockReason = trunc(ctx, p, f.lockReason, 200, "help>limit");
622
+ break;
623
+ case "localized":
624
+ node.localized = f.localized;
625
+ break;
626
+ case "archived":
627
+ if (f.archived) node.archived = true;
628
+ break;
629
+ case "advanced":
630
+ node.advanced = f.advanced;
631
+ break;
632
+ case "ai":
633
+ cat(ctx, p, "ai");
634
+ break;
635
+ case "reference":
636
+ if (shape.kind === "leaf" && shape.type === "reference") referenceToConfig(f.reference, node, p, ctx);
637
+ else if (shape.type !== "form") lose(ctx, p, "unsupported key");
638
+ break;
639
+ case "numeric":
640
+ numericToProd(f, node, p, ctx);
641
+ break;
642
+ case "scale":
643
+ if (shape.type === "number") scaleToConfig(f.scale, node, p, ctx);
644
+ else lose(ctx, p, "unsupported key");
645
+ break;
646
+ case "icon": {
647
+ const dock = shape.kind === "object" || shape.kind === "modular" || shape.kind === "types" ? dockIconOf(f.icon) : void 0;
648
+ if (dock) node.ui.icon = dock;
649
+ else lose(ctx, p, "icon");
650
+ break;
651
+ }
652
+ case "rows":
653
+ if ((shape.type === "text" || shape.type === "longtext") && isWhole(f.rows, 1, 40)) node.ui.rows = f.rows;
654
+ else lose(ctx, p, "rows");
655
+ break;
656
+ case "synced": {
657
+ const from = f.synced.from;
658
+ if (typeof from === "string" && from === from.trim() && from.length >= 1 && from.length <= 64 && Object.keys(f.synced).every((x) => x === "from")) node.ui.synced = { from };
659
+ else lose(ctx, p, "synced");
660
+ break;
661
+ }
662
+ case "slotSettings":
663
+ if (shape.kind === "slot") slotSettingsToProd(f.slotSettings, node, p, lv, ctx);
664
+ else lose(ctx, p, "slotSettings");
665
+ break;
666
+ case "itemNoun":
667
+ if (!listy || node.ui.itemLabel?.toLowerCase() !== f.itemNoun) lose(ctx, p, "itemNoun");
668
+ break;
669
+ case "arrayLayout":
670
+ if (shape.kind === "zones" || shape.kind === "modular" || shape.kind === "types") node.ui.layout = f.arrayLayout;
671
+ else if ((shape.kind === "itemType" || shape.kind === "refs") && f.arrayLayout === "grid") node.ui.layout = "gallery";
672
+ else lose(ctx, p, "layout");
673
+ break;
674
+ case "valueShape":
675
+ if (shape.type === "link" || shape.type === "image" || shape.type === "button") node.ui.valueShape = f.valueShape;
676
+ else lose(ctx, p, "valueShape");
677
+ break;
678
+ case "linkHref":
679
+ if (typeof f.linkHref === "string" && f.linkHref) node.config.linkHref = f.linkHref;
680
+ else lose(ctx, p, "unsupported key");
681
+ break;
682
+ case "svgOnly":
683
+ if (shape.type === "image" && f.svgOnly === true) node.config.media = "icon";
684
+ else if (f.svgOnly !== false) lose(ctx, p, "unsupported key");
685
+ break;
686
+ case "timezone":
687
+ if (shape.type === "date" || shape.type === "datetime") {
688
+ const tz = f.timezone;
689
+ const zone = typeof tz === "boolean" || tz === "site" ? tz : typeof tz === "string" && tz.startsWith("fixed:") && isZone(tz.slice(6)) ? tz.slice(6) : void 0;
690
+ if (zone !== void 0) node.config.timezone = zone;
691
+ else lose(ctx, p, "timezone");
692
+ } else lose(ctx, p, "unsupported key");
693
+ break;
694
+ case "language":
695
+ if (shape.type === "code" && typeof f.language === "string") node.config.language = f.language;
696
+ else lose(ctx, p, "unsupported key");
697
+ break;
698
+ case "languages":
699
+ if (shape.type === "code" && Array.isArray(f.languages) && f.languages.every((l) => typeof l === "string")) node.config.languages = [...f.languages];
700
+ else lose(ctx, p, "unsupported key");
701
+ break;
702
+ case "table":
703
+ if (shape.kind === "leaf" && shape.type === "table") Object.assign(node.config, tableConfigFromOptions(f.table));
704
+ else lose(ctx, p, "type:table");
705
+ break;
706
+ default: lose(ctx, p, "unsupported key");
707
+ }
708
+ }
709
+ if (props && f.description === void 0) node.helpText = null;
710
+ if (f.itemNoun === void 0 && shape.kind === "zones" && node.ui.itemLabel !== void 0) cat(ctx, `${at}/itemNoun`, "itemNoun (derived)");
711
+ placeInSet(f, node, at, ctx, top, siblings);
712
+ if (f.type === "rating" && node.type === "rating" && f.numeric?.step === void 0) {
713
+ const lo = typeof node.config.min === "number" ? node.config.min : 0;
714
+ const stops = ((typeof node.config.max === "number" ? node.config.max : 5) - lo) / V2_RATING_STEP;
715
+ if (Math.abs(stops - Math.round(stops)) < 1e-9 && Math.round(stops) <= 100) node.config.step = V2_RATING_STEP;
716
+ }
717
+ if (node.ui.control === "slider" && !sliderOk(node.config)) {
718
+ delete node.ui.control;
719
+ lose(ctx, `${at}/layout`, "layout");
720
+ }
721
+ return node;
722
+ }
723
+ var isWhole = (n, lo = 0, hi = Infinity) => typeof n === "number" && Number.isInteger(n) && n >= lo && n <= hi;
724
+ var compiles = (re) => {
725
+ try {
726
+ new RegExp(re);
727
+ return true;
728
+ } catch {
729
+ return false;
730
+ }
731
+ };
732
+ var ratingIsDefault = (c) => c.min === RATING_CONFIG.min && c.max === RATING_CONFIG.max && c.step === RATING_CONFIG.step;
733
+ /** Backend controlHardening: a slider spans min < max; a set step is > 0 with at most SLIDER_MAX_STOPS stops. */
734
+ function sliderOk({ min, max, step }) {
735
+ if (!(typeof min === "number" && typeof max === "number" && min < max)) return false;
736
+ return step === void 0 || typeof step === "number" && step > 0 && (max - min) / step <= SLIDER_MAX_STOPS;
737
+ }
738
+ /** Where a field sits: its tab (fields lane) or prop group (props lane). */
739
+ function placeInSet(f, node, at, ctx, top, siblings) {
740
+ if (ctx.lane === "props") {
741
+ if (!top) {
742
+ if (f.group !== void 0) {
743
+ if (ctx.keptTabs.has(f.group)) node.ui.tab = { id: f.group };
744
+ else lose(ctx, `${at}/group`, "group (nested)");
745
+ }
746
+ } else {
747
+ const t = ctx.propTabs.get(f);
748
+ if (t?.loss) lose(ctx, `${at}/group`, t.loss);
749
+ if (t?.tab) node.ui.tab = ctx.definedTabs.has(t.tab.id) ? { id: t.tab.id } : (ctx.definedTabs.add(t.tab.id), t.tab);
750
+ }
751
+ if (f.fieldset === void 0) return;
752
+ const set = ctx.propSets.get(f.fieldset);
753
+ if (!set) return lose(ctx, `${at}/fieldset`, "fieldset collision");
754
+ let defined = ctx.definedGroups.get(siblings);
755
+ if (!defined) ctx.definedGroups.set(siblings, defined = /* @__PURE__ */ new Set());
756
+ if (defined.has(set.name)) node.ui.group = { id: set.name };
757
+ else {
758
+ defined.add(set.name);
759
+ node.ui.group = propGroupOf(set, ctx);
760
+ }
761
+ return;
762
+ }
763
+ const set = f.fieldset !== void 0 && ctx.sets.has(f.fieldset) ? f.fieldset : void 0;
764
+ if (f.fieldset !== void 0 && !set) lose(ctx, `${at}/fieldset`, "fieldset collision");
765
+ if (!top) {
766
+ if (f.group !== void 0) lose(ctx, `${at}/group`, "group (nested)");
767
+ if (set) node.fieldsetId = set;
768
+ return;
769
+ }
770
+ const tab = set ? ctx.sets.get(set) : void 0;
771
+ if (f.group !== void 0 && !ctx.tabs.has(f.group)) lose(ctx, `${at}/group`, ctx.droppedTabs.get(f.group) ?? "unsupported key");
772
+ else if (set && tab !== f.group) lose(ctx, `${at}/group`, "fieldset spans groups");
773
+ node.fieldsetId = set ?? (f.group !== void 0 && ctx.tabs.has(f.group) ? f.group : void 0);
774
+ }
775
+ /** A V2 fieldset as the inline prop group its first member defines (what propSetsFor found unstorable is named there). */
776
+ function propGroupOf(s, ctx) {
777
+ const g = {
778
+ id: s.name,
779
+ label: s.title.slice(0, 32),
780
+ kind: "group"
781
+ };
782
+ if (s.collapsed !== void 0) g.collapsed = s.collapsed;
783
+ if (groupDescriptionOk(s.description)) g.description = s.description;
784
+ if (s.columns !== void 0) g.columns = s.columns;
785
+ if (s.collapsible !== void 0) g.collapsible = s.collapsible;
786
+ if (s.layout !== void 0) g.layout = s.layout;
787
+ if (ctx.groupOrder) g.order = Math.min(99, ctx.propOrder.get(s.name) ?? 0);
788
+ return g;
789
+ }
790
+ var groupDescriptionOk = (d) => typeof d === "string" && d === d.trim() && d.length >= 1 && d.length <= 200;
791
+ /** The zone a datetime field fixes, if any (what lets a stored instant read back with its [Zone]). */
792
+ var fixedZone = (f) => typeof f.timezone === "string" && f.timezone.startsWith("fixed:") ? f.timezone.slice(6) : void 0;
793
+ /**
794
+ * A field default: forward through the value adapters, then read back the way toTypeSchema will; every leaf that does
795
+ * not come back is named (so the lossy list matches what the read side really returns). Objects and list rows go
796
+ * through their child fields' adapters too.
797
+ */
798
+ function defaultToProd(f, shape, v, at, ctx, lv, top) {
799
+ const plan = writePlan(f, shape, lv, ctx, top);
800
+ const out = planToProd(plan, v);
801
+ for (const d of diffPaths(v, planFromProd(plan, out))) lose(ctx, `${at}${d}`, "default value");
802
+ return out;
803
+ }
804
+ var AS_IS = { k: "as-is" };
805
+ /** The write side's plan, from the V2 field and the shape it is stored as. */
806
+ function writePlan(f, shape, lv, ctx, top) {
807
+ const kids = (fields, nest) => new Map(fields.map((c) => [c.name, writePlan(c, shapeOf(c, lv + 1, ctx, false, nest), lv + 1, ctx, false)]));
808
+ switch (shape.kind) {
809
+ case "json": return AS_IS;
810
+ case "itemType": return shape.itemType === "image" || shape.itemType === "link" ? {
811
+ k: "list",
812
+ item: shape.itemType
813
+ } : AS_IS;
814
+ case "object": return {
815
+ k: "object",
816
+ fields: kids(f.fields ?? [])
817
+ };
818
+ case "zones": return {
819
+ k: "rows",
820
+ zoned: ctx.lane === "fields",
821
+ fields: kids(shape.item.fields ?? [], ctx.lane === "props" ? "rows" : void 0)
822
+ };
823
+ case "types": return {
824
+ k: "types",
825
+ types: new Map(shape.items.map((i) => [i.name, kids(i.fields ?? [], "item")]))
826
+ };
827
+ case "slot": return ctx.lane === "fields" ? { k: "blocks" } : AS_IS;
828
+ case "modular": {
829
+ const top1 = (fields) => new Map(fields.map((c) => [c.name, writePlan(c, shapeOf(c, 1, ctx, false), 1, ctx, false)]));
830
+ return {
831
+ k: "modular",
832
+ types: new Map(shape.items.map((i) => [i.name, top1(i.fields ?? [])]))
833
+ };
834
+ }
835
+ case "refs": return { k: "refs" };
836
+ case "leaf":
837
+ if (shape.shopify) return AS_IS;
838
+ if (f.type === "link" || f.type === "url") return { k: "link" };
839
+ if (f.type === "button" || f.type === "image") return { k: f.type };
840
+ if (f.type === "datetime") return {
841
+ k: "datetime",
842
+ zone: fixedZone(f)
843
+ };
844
+ if (f.type === "reference") return { k: top && shape.type === "form" ? "form" : "ref" };
845
+ return leafPlan(f, shape.type);
846
+ }
847
+ }
848
+ /** The plan of a leaf whose value needs its own adapter but no link / reference handling (both directions agree). */
849
+ function leafPlan(f, prodType) {
850
+ if (f.type === "video") return { k: "video" };
851
+ if (f.type === "rating") return {
852
+ k: "rating",
853
+ scale: {
854
+ min: f.numeric?.min,
855
+ max: f.numeric?.max,
856
+ step: f.numeric?.step ?? V2_RATING_STEP
857
+ }
858
+ };
859
+ if (f.type === "number" && f.scale) return {
860
+ k: "scale",
861
+ scale: f.scale
862
+ };
863
+ return prodType === "number" ? { k: "number" } : AS_IS;
864
+ }
865
+ /**
866
+ * The read side's plan, from the V2 field read back (`zoned`: lists read from an array's repeatable zone and groups
867
+ * read from its non-repeatable zone; `modular`: lists read from a modular field, whose item fields live in their block
868
+ * models and pass as stored).
869
+ */
870
+ function readPlan(f, prodType, zoned, modular, types, slots, blocks) {
871
+ const kids = (fields) => new Map(fields.map((c) => [c.name, readPlan(c, "", zoned, modular, types, slots, blocks)]));
872
+ switch (f.type) {
873
+ case "link":
874
+ case "url": return { k: "link" };
875
+ case "button":
876
+ case "image": return { k: f.type };
877
+ case "datetime": return {
878
+ k: "datetime",
879
+ zone: fixedZone(f)
880
+ };
881
+ case "date": return { k: "date" };
882
+ case "reference":
883
+ if (shopifyOnly(f.reference)) return AS_IS;
884
+ return { k: prodType === "form" ? "form" : "ref" };
885
+ case "object": return {
886
+ k: "object",
887
+ ...zoned.has(f) ? { zoned: true } : {},
888
+ fields: kids(f.fields ?? [])
889
+ };
890
+ case "slot":
891
+ if (blocks?.has(f)) return { k: "blocks" };
892
+ return slots?.has(f) ? {
893
+ k: "slot",
894
+ multiple: slots.get(f)
895
+ } : AS_IS;
896
+ case "array": {
897
+ if (modular.has(f)) return {
898
+ k: "modular",
899
+ types: new Map((Array.isArray(f.of) ? f.of : []).map((i) => [i.name, kids(i.fields ?? [])]))
900
+ };
901
+ if (types?.has(f)) return {
902
+ k: "types",
903
+ types: new Map((Array.isArray(f.of) ? f.of : []).map((i) => [i.name, kids(i.fields ?? [])]))
904
+ };
905
+ const item = Array.isArray(f.of) && f.of.length === 1 ? f.of[0] : void 0;
906
+ if (item?.type === "object") return {
907
+ k: "rows",
908
+ zoned: zoned.has(f),
909
+ fields: kids(item.fields ?? [])
910
+ };
911
+ if (item?.type === "image" || item?.type === "link") return {
912
+ k: "list",
913
+ item: item.type
914
+ };
915
+ return item?.type === "reference" && !shopifyOnly(item.reference) ? { k: "refs" } : AS_IS;
916
+ }
917
+ default: return leafPlan(f, prodType);
918
+ }
919
+ }
920
+ /**
921
+ * The plan for ONE leaf field read from prod type `prodType` (a link, an image, a reference…), for a host that edits a
922
+ * single field's value outside a whole read (the dock's legacy controls). Objects and lists need the read's own plan
923
+ * (`ToTypeSchemaOptions.plans`), which knows which lists are zoned or modular.
924
+ */
925
+ function leafValuePlan(f, prodType) {
926
+ return readPlan(f, prodType, /* @__PURE__ */ new WeakSet(), /* @__PURE__ */ new WeakSet());
927
+ }
928
+ /**
929
+ * A V2 value → what prod stores. `lost` (optional) collects every V2 key prod cannot keep, as a path under the value
930
+ * ("cta/style", "(value)" for the value itself): a caller that finds any must refuse the write and name them.
931
+ */
932
+ function planToProd(plan, v, lost, at = "") {
933
+ if (v === void 0) return void 0;
934
+ const take = (r) => {
935
+ if (lost) for (const l of r.lost) lost.push(at ? `${at}/${l}` : l);
936
+ return r.value;
937
+ };
938
+ const under = (k) => at ? `${at}/${k}` : String(k);
939
+ switch (plan.k) {
940
+ case "link": return take(linkToProd(v));
941
+ case "button": return take(buttonToProd(v));
942
+ case "image": return take(imageToProd(v));
943
+ case "datetime": return take(datetimeToProd(v, { zone: plan.zone }));
944
+ case "form": return take(referenceToProd(v, { to: "form" }));
945
+ case "ref":
946
+ case "refs": return take(referenceToProd(v));
947
+ case "number":
948
+ if (typeof v === "number" || v === null) return v;
949
+ lost?.push(at || "(value)");
950
+ return;
951
+ case "video": return take(videoToProd(v));
952
+ case "list": return take(listToProd(v, plan.item));
953
+ case "scale": return take(scaleToProd(v, plan.scale));
954
+ case "rating": return take(ratingToProd(v, plan.scale));
955
+ case "object": {
956
+ const out = mapKeys(v, plan.fields, (p, x, k) => planToProd(p, x, lost, under(k)));
957
+ return plan.zoned && isObj(out) ? { nonRepeatable: out } : out;
958
+ }
959
+ case "rows": {
960
+ if (!Array.isArray(v)) return v;
961
+ const rows = v.map((row, i) => mapKeys(row, plan.fields, (p, x, k) => planToProd(p, x, lost, `${under(i)}/${k}`)));
962
+ return plan.zoned ? zoneListToProd(rows) : rows;
963
+ }
964
+ case "modular":
965
+ if (!Array.isArray(v)) return v;
966
+ return v.map((row, i) => {
967
+ if (!isObj(row) || typeof row._type !== "string") return row;
968
+ const { _key, _type, ...rest } = row;
969
+ const fields = plan.types.get(_type);
970
+ return {
971
+ __id: typeof _key === "string" && _key ? _key : `${kebab(_type)}-${i + 1}`,
972
+ __type: kebab(_type),
973
+ data: fields ? mapKeys(rest, fields, (p, x, k) => planToProd(p, x, lost, `${under(i)}/${k}`)) : rest
974
+ };
975
+ });
976
+ case "blocks": return Array.isArray(v) ? v.map((c) => isObj(c) && typeof c._type === "string" ? {
977
+ ...c,
978
+ _type: kebab(c._type)
979
+ } : c) : v;
980
+ case "slot": {
981
+ const kids = (type) => plan.child?.(type);
982
+ return slotChildrenToStored(plan.family ? childVariantsToTypes(v, plan.family) : v, plan.multiple !== false, (type, values, i) => {
983
+ const fields = kids(type);
984
+ return fields ? mapKeys(values, fields, (p, x, k) => planToProd(p, x, lost, `${under(i)}/${k}`)) : values;
985
+ }, (rel) => lost?.push(under(rel)));
986
+ }
987
+ case "types": return take(typedRowsToProd(v, (row, i) => {
988
+ const fields = plan.types.get(row._type);
989
+ return fields ? mapKeys(row, fields, (p, x, k) => planToProd(p, x, lost, `${under(i)}/${k}`)) : row;
990
+ }));
991
+ default: return v;
992
+ }
993
+ }
994
+ /** The keys the kit reads back from a stored image object (imageFromProd) and writes again (imageToProd). */
995
+ var IMAGE_KIT_KEYS = /* @__PURE__ */ new Set([
996
+ "url",
997
+ "id",
998
+ "name",
999
+ "altText",
1000
+ "focal"
1001
+ ]);
1002
+ /**
1003
+ * Every key of a stored image the kit cannot hand back. A crop rect is read back as it is (imageFromProd), and an older
1004
+ * `{ src, alt }` value reads as its url and alt text, so neither is a loss (QA item 3); a malformed crop, or a key the
1005
+ * kit does not model, is.
1006
+ */
1007
+ function imageStoredLoss(v, rel, loss) {
1008
+ if (!isObj(v)) return;
1009
+ const legacy = typeof v.url !== "string" && typeof v.src === "string";
1010
+ for (const [k, x] of Object.entries(v)) {
1011
+ if (IMAGE_KIT_KEYS.has(k) || x === void 0) continue;
1012
+ if (legacy && k === "src") continue;
1013
+ if (k === "alt" && typeof x === "string" && v.altText === void 0) continue;
1014
+ if (k === "crop") {
1015
+ if (x != null && !isCropRect(x)) loss(`${rel}/crop`, "A saved crop the kit can't read; editing the image would drop it.");
1016
+ } else loss(`${rel}/${k}`, `The image's saved "${k}" is not kept by the kit; editing the image would drop it.`);
1017
+ }
1018
+ }
1019
+ var datedLossReason = (v) => isObj(v) && ("date" in v || "time" in v || "timezone" in v) ? "A stored date-time in the older {date,time,timezone} form; the kit can't read it, so editing it would replace it." : "A stored date/time that is not an ISO string can't be read by the kit; editing it would replace it.";
1020
+ /** A stored prod value → the V2 value. `loss(rel, reason)`: what the prod value carries that the V2 value cannot (rel is
1021
+ * under the value, "/0/modelSlug"); a caller that hears any must not write the value back through V2. */
1022
+ function planFromProd(plan, v, loss, rel = "") {
1023
+ if (v === void 0) return void 0;
1024
+ switch (plan.k) {
1025
+ case "link": return linkFromProd(v);
1026
+ case "button": return buttonFromProd(v);
1027
+ case "image":
1028
+ if (loss) imageStoredLoss(v, rel, loss);
1029
+ return imageFromProd(v);
1030
+ case "datetime":
1031
+ case "date":
1032
+ if (loss && v !== null && typeof v !== "string") loss(rel || "(value)", datedLossReason(v));
1033
+ return plan.k === "date" ? v : datetimeFromProd(v, { zone: plan.zone });
1034
+ case "video": return videoFromProd(v);
1035
+ case "list":
1036
+ if (loss && plan.item === "image" && Array.isArray(v)) v.forEach((x, i) => imageStoredLoss(x, `${rel}/${i}`, loss));
1037
+ return listFromProd(v, plan.item);
1038
+ case "scale": return scaleFromProd(v);
1039
+ case "rating": return ratingFromProd(v, plan.scale);
1040
+ case "form": return referenceFromProd(v);
1041
+ case "ref":
1042
+ case "refs":
1043
+ if (loss) {
1044
+ for (const [i, x] of (Array.isArray(v) ? v : [v]).entries()) if (isObj(x) && x.modelSlug !== void 0) loss(`${rel}${Array.isArray(v) ? `/${i}` : ""}/modelSlug`, "A V2 reference stores the target id; the polymorphic modelSlug is dropped.");
1045
+ else if (isObj(x) && referenceFromProd(x) === null) loss(`${rel}${Array.isArray(v) ? `/${i}` : ""}` || "(value)", "A stored reference the kit can't read; editing it would drop it.");
1046
+ }
1047
+ return referenceFromProd(v);
1048
+ case "object": {
1049
+ const env = plan.zoned && isObj(v) && "nonRepeatable" in v ? v : void 0;
1050
+ if (env && loss) {
1051
+ for (const k of Object.keys(env)) if (k !== "nonRepeatable" && env[k] !== void 0) loss(`${rel}/${k}`, `The group's saved "${k}" is not one of its fields; editing the group would drop it.`);
1052
+ }
1053
+ const at = env ? `${rel}/nonRepeatable` : rel;
1054
+ return mapKeys(env ? isObj(env.nonRepeatable) ? env.nonRepeatable : {} : v, plan.fields, (p, x, k) => planFromProd(p, x, loss, `${at}/${k}`));
1055
+ }
1056
+ case "rows": {
1057
+ const rows = plan.zoned ? zoneListFromProd(v) : v;
1058
+ return Array.isArray(rows) ? rows.map((row, i) => mapKeys(row, plan.fields, (p, x, k) => planFromProd(p, x, loss, `${rel}/${i}/${k}`))) : rows;
1059
+ }
1060
+ case "modular": return Array.isArray(v) ? v.map((row, i) => {
1061
+ if (!isObj(row) || typeof row.__type !== "string") return row;
1062
+ const data = isObj(row.data) ? row.data : {};
1063
+ const fields = plan.types.get(camel(row.__type));
1064
+ const back = fields ? mapKeys(data, fields, (p, x, k) => planFromProd(p, x, loss, `${rel}/${i}/${k}`)) : data;
1065
+ return {
1066
+ _key: row.__id,
1067
+ _type: camel(row.__type),
1068
+ ...back
1069
+ };
1070
+ }) : v;
1071
+ case "blocks": return Array.isArray(v) ? v.map((c) => isObj(c) && typeof c._type === "string" ? {
1072
+ ...c,
1073
+ _type: camel(c._type)
1074
+ } : c) : v;
1075
+ case "slot": return slotChildrenFromStored(v, (type, values, i) => {
1076
+ const fields = plan.child?.(type);
1077
+ const read = fields ? mapKeys(values, fields, (p, x, k) => planFromProd(p, x, loss, `${rel}/${i}/${k}`)) : values;
1078
+ const variant = plan.family?.(type)?.current;
1079
+ return variant === void 0 ? read : {
1080
+ ...read,
1081
+ _variant: variant
1082
+ };
1083
+ }, (i, reason) => loss?.(`${rel}/${i}`, reason));
1084
+ case "types": return typedRowsFromProd(v, (row, i) => {
1085
+ const fields = plan.types.get(row._type);
1086
+ if (!fields) {
1087
+ loss?.(`${rel}/${i}/_type`, `A stored row of item type "${row._type}", which this list no longer declares; editing the list would drop it.`);
1088
+ return row;
1089
+ }
1090
+ return mapKeys(row, fields, (p, x, k) => planFromProd(p, x, loss, `${rel}/${i}/${k}`));
1091
+ });
1092
+ default: return v;
1093
+ }
1094
+ }
1095
+ /** Each key of an object value through its child field's plan; keys with no field ride along as they are. */
1096
+ function mapKeys(v, fields, fn) {
1097
+ if (!isObj(v)) return v;
1098
+ const out = {};
1099
+ for (const [k, x] of Object.entries(v)) {
1100
+ const plan = fields.get(k);
1101
+ const y = plan ? fn(plan, x, k) : x;
1102
+ if (y !== void 0) out[k] = y;
1103
+ }
1104
+ return out;
1105
+ }
1106
+ /** Every leaf (a JSON pointer under the value, "" for the value itself) where `a` and `b` differ; undefined = absent. */
1107
+ function diffPaths(a, b, path = "", out = []) {
1108
+ if (deepEqual(a, b)) return out;
1109
+ if ((isObj(a) || a === void 0) && (isObj(b) || b === void 0) && (a !== void 0 || b !== void 0)) {
1110
+ const A = a ?? {};
1111
+ const B = b ?? {};
1112
+ for (const k of /* @__PURE__ */ new Set([...Object.keys(A), ...Object.keys(B)])) diffPaths(A[k], B[k], `${path}/${k}`, out);
1113
+ } else if (Array.isArray(a) && Array.isArray(b)) for (let i = 0; i < Math.max(a.length, b.length); i++) diffPaths(a[i], b[i], `${path}/${i}`, out);
1114
+ else out.push(path);
1115
+ return out;
1116
+ }
1117
+ function validationToProd(f, shape, node, at, ctx, inTable, top) {
1118
+ const props = ctx.lane === "props";
1119
+ const val = f.validation;
1120
+ const t = shape.type;
1121
+ const leaf = shape.kind === "leaf";
1122
+ const lengthy = leaf && (props ? LENGTH_PROPS : LENGTH_FIELDS).has(t);
1123
+ const patternOk = leaf && (props ? PATTERN_TYPES : LENGTH_FIELDS).has(t) && t !== "richtext" && t !== "document" && typeof val.pattern === "string" && val.pattern.length <= 200 && compiles(val.pattern);
1124
+ /** the pair each key bounds, so a min over its max is named rather than refused at save */
1125
+ const pairs = [];
1126
+ const set = (key, n, feature, lo, hi) => {
1127
+ node.config[key] = n;
1128
+ if (!pairs.some((x) => x[0] === lo)) pairs.push([
1129
+ lo,
1130
+ hi,
1131
+ `${at}/min`,
1132
+ `${at}/max`,
1133
+ feature
1134
+ ]);
1135
+ };
1136
+ for (const k of Object.keys(val)) {
1137
+ const v = val[k];
1138
+ if (v === void 0) continue;
1139
+ const p = `${at}/${k}`;
1140
+ if (shape.kind === "json" && k !== "required" && k !== "recommendedMax") {
1141
+ lose(ctx, p, shape.feature);
1142
+ continue;
1143
+ }
1144
+ switch (k) {
1145
+ case "required":
1146
+ node.required = val.required;
1147
+ break;
1148
+ case "min":
1149
+ case "max": {
1150
+ const n = v;
1151
+ const lo = k === "min";
1152
+ if (lengthy) {
1153
+ if (isWhole(n)) set(lo ? "minLength" : "maxLength", n, "validation.length", "minLength", "maxLength");
1154
+ else lose(ctx, p, "validation.length");
1155
+ } else if (t === "number") {
1156
+ const b = node.config.validation ??= {};
1157
+ b[k] = n;
1158
+ } else if (t === "rating") lose(ctx, p, "rating bounds");
1159
+ else if (shape.kind === "zones" || shape.kind === "modular" || shape.kind === "types" || shape.kind === "slot" || shape.kind === "itemType") {
1160
+ const cap = shape.kind === "slot" ? SLOT_ITEMS_CAP : LIST_ITEMS_CAP;
1161
+ if (props && top || shape.kind === "slot" ? isWhole(n, lo ? 0 : 1, cap) : isWhole(n)) set(lo ? "minItems" : "maxItems", n, "validation.items", "minItems", "maxItems");
1162
+ else lose(ctx, p, "validation.items");
1163
+ } else if (shape.kind === "refs" || t === "multiselect" || t === "tags") {
1164
+ if (t === "tags" ? isWhole(n, lo ? 0 : 1, 500) : isWhole(n)) set(k, n, "validation.items", "min", "max");
1165
+ else lose(ctx, p, "validation.items");
1166
+ } else lose(ctx, p, "validation.length");
1167
+ break;
1168
+ }
1169
+ case "recommendedMax":
1170
+ if (isWhole(v, 1)) node.recommendedMax = v;
1171
+ else lose(ctx, p, "validation.recommendedMax");
1172
+ break;
1173
+ case "pattern":
1174
+ if (patternOk) node.config.pattern = v;
1175
+ else lose(ctx, p, "validation.pattern");
1176
+ break;
1177
+ case "patternMessage":
1178
+ if (patternOk && typeof v === "string" && v.trim() !== "" && v.length <= 200) node.config.patternMessage = v;
1179
+ else lose(ctx, p, "validation.patternMessage");
1180
+ break;
1181
+ case "unique":
1182
+ if (val.unique === false) node.unique = false;
1183
+ else if (shape.kind === "types") lose(ctx, p, "validation.unique");
1184
+ else if (props) {
1185
+ if (UNIQUE_LIST_PROPS.has(t) || inTable && UNIQUE_ROW_PROPS.has(t)) node.unique = true;
1186
+ else cat(ctx, p, "not applicable (props)");
1187
+ } else {
1188
+ const polymorphic = t === "reference" && (f.reference?.to ?? []).filter(ENTRY_TARGET).length > 1;
1189
+ if (UNIQUE_TYPES.has(t) && !polymorphic) node.unique = true;
1190
+ else lose(ctx, p, "validation.unique");
1191
+ }
1192
+ break;
1193
+ default: lose(ctx, p, "unsupported key");
1194
+ }
1195
+ }
1196
+ const b = node.config.validation;
1197
+ if (b && b.min !== void 0 && b.max !== void 0 && b.min > b.max) {
1198
+ delete node.config.validation;
1199
+ lose(ctx, `${at}/min`, "validation.items");
1200
+ lose(ctx, `${at}/max`, "validation.items");
1201
+ }
1202
+ for (const [lo, hi, pLo, pHi, feature] of pairs) {
1203
+ const a = node.config[lo];
1204
+ const z = node.config[hi];
1205
+ if (typeof a === "number" && typeof z === "number" && a > z) {
1206
+ delete node.config[lo];
1207
+ delete node.config[hi];
1208
+ lose(ctx, pLo, feature);
1209
+ lose(ctx, pHi, feature);
1210
+ }
1211
+ }
1212
+ }
1213
+ function optionsToProd(f, shape, node, at, ctx) {
1214
+ if (shape.type !== "select" && shape.type !== "multiselect" && shape.type !== "tags") return lose(ctx, at, "unsupported key");
1215
+ const opts = f.options;
1216
+ const icons = opts.map((o) => o.icon === void 0 ? void 0 : dockIconOf(o.icon));
1217
+ const allIcons = opts.every((o, i) => o.icon === void 0 || icons[i] !== void 0);
1218
+ node.options = opts.map((o, i) => {
1219
+ const out = {
1220
+ label: o.label,
1221
+ value: o.value
1222
+ };
1223
+ if (o.icon !== void 0) {
1224
+ if (allIcons) out.icon = icons[i];
1225
+ else lose(ctx, `${at}/${i}/icon`, "option icon");
1226
+ }
1227
+ const d = o.description;
1228
+ if (d !== void 0) {
1229
+ if (typeof d === "string" && d.trim() !== "" && !/[\r\n]/.test(d) && d.length <= 140) out.description = d;
1230
+ else lose(ctx, `${at}/${i}/description`, "option description");
1231
+ }
1232
+ for (const k of Object.keys(o)) if (![
1233
+ "value",
1234
+ "label",
1235
+ "icon",
1236
+ "description"
1237
+ ].includes(k)) lose(ctx, `${at}/${i}/${k}`, "unsupported key");
1238
+ return out;
1239
+ });
1240
+ }
1241
+ /** V2 layouts → prod ui.control (a leaf's control) or ui.layout (a list's rows); dock-vocabulary.ts controlHardening rules. */
1242
+ function layoutToProd(f, shape, node, at, ctx) {
1243
+ const l = f.layout;
1244
+ const t = shape.type;
1245
+ const n = f.options?.length ?? 0;
1246
+ if (l === "segmented" && t === "select") {
1247
+ if (n >= 2 && n <= 4) node.ui.control = "segmented";
1248
+ else if (n >= 5) cat(ctx, at, "segmented fallback");
1249
+ else lose(ctx, at, "layout");
1250
+ } else if (l === "slider" && t === "number" && f.type === "number") node.ui.control = "slider";
1251
+ else if (UI_CONTROLS.includes(l) && l !== "segmented" && l !== "slider" && CONTROL_TYPES[l]?.includes(t)) node.ui.control = l;
1252
+ else if (l === "list" && (shape.kind === "zones" || shape.kind === "itemType" || shape.kind === "modular" || shape.kind === "types" || shape.kind === "refs") && f.arrayLayout === void 0) node.ui.layout = "rows";
1253
+ else lose(ctx, at, "layout");
1254
+ }
1255
+ /** The prod type a V2 field is stored as, for a preview path reading into it (no loss is reported). */
1256
+ function storedType(f, ctx) {
1257
+ return shapeOf(f, 1, {
1258
+ ...ctx,
1259
+ lossy: [],
1260
+ catalog: []
1261
+ }, false).type;
1262
+ }
1263
+ /** The V2 fields a preview path segment may name below `f` (an object's fields, a list's item fields), or null for a leaf. */
1264
+ function previewKids(f) {
1265
+ if (f.type === "object") return f.fields ?? [];
1266
+ if (f.type === "array" && Array.isArray(f.of) && f.of.length === 1 && f.of[0].type === "object") return f.of[0].fields ?? [];
1267
+ return null;
1268
+ }
1269
+ /**
1270
+ * A V2 preview path → the path prod stores (previewPathProblem): the first segment a child, each later one a child of the
1271
+ * node before it, or a key of an object-valued leaf (`image.alt` is stored `image.altText`). undefined: no prod form.
1272
+ */
1273
+ function previewPathToProd(path, children, ctx) {
1274
+ const segs = path.split(".");
1275
+ let node = children.find((c) => c.name === segs[0]);
1276
+ if (!node) return void 0;
1277
+ const out = [segs[0]];
1278
+ for (let i = 1; i < segs.length; i++) {
1279
+ const kids = previewKids(node);
1280
+ if (kids) {
1281
+ const next = kids.find((c) => c.name === segs[i]);
1282
+ if (!next) return void 0;
1283
+ out.push(segs[i]);
1284
+ node = next;
1285
+ continue;
1286
+ }
1287
+ if (node.type === "table") return TABLE_PATH_KEYS.includes(segs[i]) && i === segs.length - 1 ? [...out, segs[i]].join(".") : void 0;
1288
+ const type = storedType(node, ctx);
1289
+ if (!OBJECT_VALUE_TYPES.has(type)) return void 0;
1290
+ const key = type === "image" ? IMAGE_PATH_KEY[segs[i]] ?? segs[i] : segs[i];
1291
+ if (LEAF_VALUE_KEYS[type] && !LEAF_VALUE_KEYS[type].includes(key)) return void 0;
1292
+ return [
1293
+ ...out,
1294
+ key,
1295
+ ...segs.slice(i + 1)
1296
+ ].join(".");
1297
+ }
1298
+ return out.join(".");
1299
+ }
1300
+ function previewToProd(pv, children, at, ctx) {
1301
+ const out = {};
1302
+ for (const k of Object.keys(pv)) {
1303
+ const v = pv[k];
1304
+ if (v === void 0) continue;
1305
+ if (k === "title" || k === "subtitle" || k === "media") {
1306
+ const stored = previewPathToProd(v, children, ctx);
1307
+ if (stored !== void 0) out[k] = stored;
1308
+ else lose(ctx, `${at}/${k}`, "preview path");
1309
+ } else if (k === "fallback") {
1310
+ const t = v.trim();
1311
+ if (t && t === v && t.length <= 60) out.fallback = v;
1312
+ else lose(ctx, `${at}/${k}`, "help>limit");
1313
+ } else if (k === "icon") {
1314
+ const dock = dockIconOf(v);
1315
+ if (dock) out.icon = dock;
1316
+ else lose(ctx, `${at}/${k}`, "preview icon");
1317
+ } else lose(ctx, `${at}/${k}`, "unsupported key");
1318
+ }
1319
+ return out;
1320
+ }
1321
+ /**
1322
+ * A V2 dotted document preview path (`slides.0.heading`, `default.heading`) the backend keeps (componentPreviewRefusals
1323
+ * previewPathOfProps): its head a top-level prop, an index segment stepping into an item of a list, the rest a path
1324
+ * previewPathToProd stores unchanged (a renamed key, `image.alt` → `altText`, has no stored form here).
1325
+ */
1326
+ function documentPreviewPathOk(path, keys, fields, ctx) {
1327
+ const segs = path.split(".");
1328
+ if (segs.length < 2 || !keys.has(segs[0])) return false;
1329
+ const head = fields.find((f) => f.name === segs[0]);
1330
+ if (!head) return false;
1331
+ const polyOf = (f) => f.type === "array" && Array.isArray(f.of) && f.of.length > 1 && f.of.every((o) => o.type === "object") ? f.of : void 0;
1332
+ let node = head;
1333
+ const kept = [segs[0]];
1334
+ let poly = false;
1335
+ for (let i = 1; i < segs.length; i++) {
1336
+ const seg = segs[i];
1337
+ if (/^\d+$/.test(seg) && (node.type === "array" || node.type === "multiselect" || node.type === "tags")) continue;
1338
+ const types = polyOf(node);
1339
+ const kids = types ? types.flatMap((o) => o.fields ?? []) : previewKids(node);
1340
+ if (!kids) {
1341
+ kept.push(...segs.slice(i));
1342
+ break;
1343
+ }
1344
+ const next = kids.find((c) => c.name === seg);
1345
+ if (!next) return false;
1346
+ if (types) poly = true;
1347
+ kept.push(seg);
1348
+ node = next;
1349
+ }
1350
+ if (poly) return true;
1351
+ const clean = kept.join(".");
1352
+ return previewPathToProd(clean, fields, ctx) === clean;
1353
+ }
1354
+ /**
1355
+ * A V2 schema's document-level preview → component.preview (BE componentPreviewSchema): `title` / `subtitle` / `media`
1356
+ * kept when they name a top-level prop key or a dotted path into one (else preview_key_unknown; a catalog note: the row
1357
+ * reads the first text),
1358
+ * `fallback` trimmed and at most COMPONENT_PREVIEW_FALLBACK_MAX, `icon` a dock icon.
1359
+ */
1360
+ function componentPreviewToProd(pv, keys, fields, at, ctx) {
1361
+ const out = {};
1362
+ for (const k of Object.keys(pv)) {
1363
+ const v = pv[k];
1364
+ if (v === void 0) continue;
1365
+ if (k === "title" || k === "subtitle" || k === "media") {
1366
+ if ((keys.has(v) || documentPreviewPathOk(v, keys, fields, ctx)) && v.length <= 64) out[k] = v;
1367
+ else cat(ctx, `${at}/${k}`, "document preview path");
1368
+ } else if (k === "fallback") {
1369
+ const t = v.trim();
1370
+ if (t && t === v && t.length <= 120) out.fallback = v;
1371
+ else lose(ctx, `${at}/${k}`, "help>limit");
1372
+ } else if (k === "icon") {
1373
+ const dock = dockIconOf(v);
1374
+ if (dock) out.icon = dock;
1375
+ else lose(ctx, `${at}/${k}`, "preview icon");
1376
+ } else lose(ctx, `${at}/${k}`, "unsupported key");
1377
+ }
1378
+ return out;
1379
+ }
1380
+ /** A list item's name and title: the convention, else ui.itemName / ui.itemTitle (chromeUiProblems). */
1381
+ function itemIdentity(item, conv, node, ip, ctx) {
1382
+ if (item.name !== conv.name) {
1383
+ if (ITEM_NAME_RE.test(item.name)) node.ui.itemName = item.name;
1384
+ else lose(ctx, `${ip}/name`, "item identity");
1385
+ }
1386
+ if (item.title !== conv.title) {
1387
+ const t = item.title;
1388
+ if (t === t.trim() && t.length >= 1 && t.length <= 60) node.ui.itemTitle = t;
1389
+ else lose(ctx, `${ip}/title`, "item identity");
1390
+ }
1391
+ }
1392
+ function ofToProd(f, shape, node, at, lv, ctx) {
1393
+ if (shape.kind === "json" || shape.kind === "leaf" || shape.kind === "object") return lose(ctx, at, "unsupported key");
1394
+ if (shape.kind === "modular") {
1395
+ node.config.blockSlugs = shape.items.map((i) => kebab(i.name));
1396
+ shape.items.forEach((item, i) => blockModelFor(item, `${at}/${i}`, ctx, node));
1397
+ return;
1398
+ }
1399
+ if (shape.kind === "types") return itemTypesToProd(shape.items, node, at, lv, ctx);
1400
+ if (shape.kind === "slot") {
1401
+ const of = f.of;
1402
+ for (const k of Object.keys(of)) {
1403
+ if (of[k] === void 0) continue;
1404
+ if (k === "allow" && ctx.lane === "fields") {
1405
+ node.config.blockSlugs = of.allow.map(kebab);
1406
+ of.allow.forEach((n, i) => camel(kebab(n)) !== n && lose(ctx, `${at}/allow/${i}`, "type name"));
1407
+ } else if (k === "allow") {
1408
+ if (slotAllowOk(of.allow)) node.config.allow = [...of.allow];
1409
+ else cat(ctx, `${at}/allow`, "slot allow");
1410
+ } else if (k !== "type" || of.type !== "block") lose(ctx, `${at}/${k}`, "unsupported key");
1411
+ }
1412
+ return;
1413
+ }
1414
+ const item = shape.item;
1415
+ const ip = `${at}/0`;
1416
+ if (shape.kind === "zones") {
1417
+ const fields = item.fields ?? [];
1418
+ node.zoned = true;
1419
+ node.children = fields.map((c, i) => convertField(c, `${ip}/fields/${i}`, lv + 1, ctx, fields, false, ctx.lane === "props"));
1420
+ itemIdentity(item, conventionItem(f.name, f.title, node.ui.itemLabel), node, ip, ctx);
1421
+ for (const k of Object.keys(item)) {
1422
+ if (item[k] === void 0) continue;
1423
+ const p = `${ip}/${k}`;
1424
+ if (k === "type" || k === "fields" || k === "name" || k === "title") continue;
1425
+ if (k === "preview") node.ui.preview = previewToProd(item.preview, fields, p, ctx);
1426
+ else if (k === "icon") {
1427
+ const dock = f.icon === void 0 ? dockIconOf(item.icon) : void 0;
1428
+ if (dock) node.ui.icon = dock;
1429
+ else lose(ctx, p, "item icon");
1430
+ } else if (k === "openMode") cat(ctx, p, "item openMode");
1431
+ else lose(ctx, p, "item identity");
1432
+ }
1433
+ return;
1434
+ }
1435
+ if (shape.kind === "itemType") node.config.itemType = shape.itemType;
1436
+ itemIdentity(item, conventionItem(f.name, f.title), node, ip, ctx);
1437
+ const settings = {};
1438
+ const scalars = shape.kind === "itemType" && !shape.shopify && ctx.lane === "props";
1439
+ for (const k of Object.keys(item)) {
1440
+ const v = item[k];
1441
+ if (v === void 0) continue;
1442
+ const p = `${ip}/${k}`;
1443
+ if (k === "name" || k === "title") continue;
1444
+ if (k === "type") {
1445
+ if (shape.kind === "itemType" && shape.shopify) continue;
1446
+ if (shape.kind === "itemType" && item.type === "text") lose(ctx, p, "item settings");
1447
+ } else if (k === "reference" && shape.kind === "refs") referenceToConfig(item.reference, node, p, ctx);
1448
+ else if (k === "reference" && shape.kind === "itemType" && shape.shopify) continue;
1449
+ else if (scalars && k === "description" && typeof v === "string" && v.trim() === v && v.length >= 1 && v.length <= 200) settings.helpText = v;
1450
+ else if (scalars && k === "localized" && typeof v === "boolean") settings.localized = v;
1451
+ else if (scalars && k === "validation") itemValidationToProd(item, shape.itemType, settings, p, ctx);
1452
+ else lose(ctx, p, "item settings");
1453
+ }
1454
+ if (nonEmpty(settings)) node.config.item = settings;
1455
+ }
1456
+ /** A scalar list item's V2 validation → config.item: required, a text / rich text item's length, a text item's pattern. */
1457
+ function itemValidationToProd(item, itemType, out, at, ctx) {
1458
+ const val = item.validation;
1459
+ const lengthy = itemType === "text" || itemType === "richtext";
1460
+ for (const k of Object.keys(val)) {
1461
+ const v = val[k];
1462
+ if (v === void 0) continue;
1463
+ if (k === "required" && typeof v === "boolean") out.required = v;
1464
+ else if ((k === "min" || k === "max") && lengthy && isWhole(v)) out[k === "min" ? "minLength" : "maxLength"] = v;
1465
+ else if (k === "pattern" && itemType === "text" && typeof v === "string" && v.length <= 200 && compiles(v)) out.pattern = v;
1466
+ else if (k === "patternMessage" && typeof v === "string" && v.trim() !== "" && v.length <= 200) out.patternMessage = v;
1467
+ else lose(ctx, `${at}/${k}`, "item settings");
1468
+ }
1469
+ if (out.minLength !== void 0 && out.maxLength !== void 0 && out.minLength > out.maxLength) {
1470
+ delete out.minLength;
1471
+ delete out.maxLength;
1472
+ lose(ctx, `${at}/min`, "item settings");
1473
+ }
1474
+ if (out.patternMessage !== void 0 && out.pattern === void 0) {
1475
+ delete out.patternMessage;
1476
+ lose(ctx, `${at}/patternMessage`, "item settings");
1477
+ }
1478
+ }
1479
+ /** A slot's per-child settings → config.slotSettings: leaf sub-fields, at most SLOT_SETTINGS_MAX (slotSettingsHardening). */
1480
+ function slotSettingsToProd(settings, node, at, lv, ctx) {
1481
+ const kept = settings.slice(0, SLOT_SETTINGS_MAX);
1482
+ if (settings.length > SLOT_SETTINGS_MAX) settings.slice(SLOT_SETTINGS_MAX).forEach((_, i) => lose(ctx, `${at}/${SLOT_SETTINGS_MAX + i}`, "slotSettings"));
1483
+ node.slotSettings = kept.map((c, i) => convertField(c, `${at}/${i}`, lv + 1, ctx, kept, false, false, false, true));
1484
+ }
1485
+ /**
1486
+ * A polymorphic list's item types → config.itemTypes `{ name, label, fields }`: the name is what a row's `_type` holds,
1487
+ * the title its label, its icon and row preview `icon` / `preview` (paths over its own fields). One prod cannot name is
1488
+ * not stored, which moves the ones after it up a place, so the whole list is named.
1489
+ */
1490
+ function itemTypesToProd(items, node, at, lv, ctx) {
1491
+ const names = /* @__PURE__ */ new Set();
1492
+ node.itemTypes = [];
1493
+ let dropped = false;
1494
+ items.forEach((item, i) => {
1495
+ const ip = `${at}/${i}`;
1496
+ const fields = item.fields ?? [];
1497
+ const why = !ITEM_TYPE_NAME.test(item.name) || !fields.length ? "item identity" : names.has(item.name) ? "duplicate name" : void 0;
1498
+ if (why) {
1499
+ lose(ctx, ip, why);
1500
+ dropped = true;
1501
+ return;
1502
+ }
1503
+ names.add(item.name);
1504
+ const label = trunc(ctx, `${ip}/title`, item.title, ITEM_TYPE_LABEL_MAX, "item identity");
1505
+ const children = fields.map((c, j) => convertField(c, `${ip}/fields/${j}`, lv + 1, ctx, fields, false, false, true));
1506
+ const type = {
1507
+ name: item.name,
1508
+ label,
1509
+ children
1510
+ };
1511
+ for (const k of Object.keys(item)) {
1512
+ if (item[k] === void 0 || k === "name" || k === "title" || k === "type" || k === "fields") continue;
1513
+ const p = `${ip}/${k}`;
1514
+ if (k === "preview") {
1515
+ const preview = previewToProd(item.preview, fields, p, ctx);
1516
+ if (nonEmpty(preview)) type.preview = preview;
1517
+ } else if (k === "icon") {
1518
+ const dock = dockIconOf(item.icon);
1519
+ if (dock) type.icon = dock;
1520
+ else lose(ctx, p, "item icon");
1521
+ } else if (k === "openMode") cat(ctx, p, "item openMode");
1522
+ else lose(ctx, p, "item identity");
1523
+ }
1524
+ node.itemTypes.push(type);
1525
+ });
1526
+ if (dropped && node.itemTypes.length < items.length && node.itemTypes.length) lose(ctx, at, "item identity");
1527
+ }
1528
+ /**
1529
+ * A modular item type → the kind:'block' model its rows are stored against: the item title is the model name, its fields
1530
+ * the model's top-level fields. A block model holds only fields a block primitive renders; any other is not stored. The
1531
+ * item's icon and preview are how its rows read in THIS field: the field's ui.blocks, by slug.
1532
+ */
1533
+ function blockModelFor(item, at, ctx, list) {
1534
+ const start = ctx.lossy.length;
1535
+ const startCat = ctx.catalog.length;
1536
+ const slug = kebab(item.name);
1537
+ const sub = {
1538
+ ...ctx,
1539
+ tabs: /* @__PURE__ */ new Set(),
1540
+ droppedTabs: /* @__PURE__ */ new Map(),
1541
+ sets: /* @__PURE__ */ new Map()
1542
+ };
1543
+ const fields = item.fields ?? [];
1544
+ const kept = [];
1545
+ const chrome = {};
1546
+ for (const k of Object.keys(item)) {
1547
+ const p = `${at}/${k}`;
1548
+ if (item[k] === void 0 || k === "type" || k === "title") continue;
1549
+ if (k === "name") {
1550
+ if (camel(slug) !== item.name) lose(ctx, p, "item identity");
1551
+ } else if (k === "fields") {
1552
+ let dropped = false;
1553
+ let shifted = false;
1554
+ fields.forEach((c, j) => {
1555
+ const fp = `${p}/${j}`;
1556
+ const mark = ctx.lossy.length;
1557
+ const markCat = ctx.catalog.length;
1558
+ const node = convertField(c, fp, 1, sub, fields, false);
1559
+ if (BLOCK_FIELD_TYPES.has(node.type)) {
1560
+ kept.push(emitField(node));
1561
+ if (dropped && !shifted) {
1562
+ shifted = true;
1563
+ lose(ctx, p, "block model field");
1564
+ }
1565
+ return;
1566
+ }
1567
+ ctx.lossy.length = mark;
1568
+ ctx.catalog.length = markCat;
1569
+ dropped = true;
1570
+ lose(ctx, fp, "block model field");
1571
+ });
1572
+ } else if (k === "openMode") cat(ctx, p, "item openMode");
1573
+ else if (k === "icon") {
1574
+ const dock = dockIconOf(item.icon);
1575
+ if (dock) chrome.icon = dock;
1576
+ else lose(ctx, p, "item icon");
1577
+ } else if (k === "preview") chrome.preview = previewToProd(item.preview, fields, p, ctx);
1578
+ else lose(ctx, p, "item identity");
1579
+ }
1580
+ const model = {
1581
+ name: item.title,
1582
+ slug,
1583
+ kind: "block",
1584
+ fields: kept
1585
+ };
1586
+ const prev = ctx.blockModels.get(slug);
1587
+ const keep = () => {
1588
+ if (!nonEmpty(chrome) || list.ui.blocks?.[slug]) return;
1589
+ list.ui.blocks = {
1590
+ ...list.ui.blocks,
1591
+ [slug]: chrome
1592
+ };
1593
+ };
1594
+ if (!prev) {
1595
+ ctx.blockModels.set(slug, model);
1596
+ return keep();
1597
+ }
1598
+ if (deepEqual(prev, model)) return keep();
1599
+ ctx.lossy.length = start;
1600
+ ctx.catalog.length = startCat;
1601
+ lose(ctx, at, "duplicate name");
1602
+ }
1603
+ /**
1604
+ * A reference's targets: entry models → contentModelId / polymorphic + allowedModelSlugs; page, form and collection →
1605
+ * config.targets and the filter → config.filter (backend refTargetKeys, both lanes). Read back, entry models come first,
1606
+ * then the targets.
1607
+ */
1608
+ function referenceToConfig(ref, node, at, ctx) {
1609
+ const to = ref.to ?? [];
1610
+ const entries = to.filter(ENTRY_TARGET);
1611
+ const targets = to.filter((t) => REF_TARGET_KINDS.includes(t));
1612
+ const kept = entries.length + targets.length;
1613
+ if (kept < to.length) lose(ctx, kept || !to.length ? `${at}/to` : at, "shopify reference");
1614
+ else if (to.join() !== [...entries, ...targets].join()) lose(ctx, `${at}/to`, "reference order");
1615
+ if (entries.length === 1) node.config.contentModelId = entries[0];
1616
+ else if (entries.length > 1) Object.assign(node.config, {
1617
+ polymorphic: true,
1618
+ allowedModelSlugs: entries
1619
+ });
1620
+ if (targets.length) node.config.targets = targets;
1621
+ if (ref.filter !== void 0) {
1622
+ if (filterKept(ref.filter)) node.config.filter = ref.filter;
1623
+ else lose(ctx, `${at}/filter`, "reference filter");
1624
+ }
1625
+ for (const k of Object.keys(ref)) if (k !== "to" && k !== "filter") lose(ctx, `${at}/${k}`, "unsupported key");
1626
+ }
1627
+ function numericToProd(f, node, at, ctx) {
1628
+ if (f.type !== "number" && f.type !== "rating") return lose(ctx, at, "unsupported key");
1629
+ const n = f.numeric;
1630
+ const lo = n.min ?? 0;
1631
+ const hi = n.max ?? 5;
1632
+ const st = n.step ?? (f.type === "rating" ? V2_RATING_STEP : 1);
1633
+ const stops = (hi - lo) / st;
1634
+ const ratingOk = (n.min === void 0 || Number.isFinite(n.min) && n.min >= 0) && (n.max === void 0 || isWhole(n.max, 1, 10)) && (n.step === void 0 || Number.isFinite(n.step) && n.step > 0) && lo < hi && Math.abs(stops - Math.round(stops)) < 1e-9 && Math.round(stops) <= 100;
1635
+ for (const k of Object.keys(n)) {
1636
+ const v = n[k];
1637
+ if (v === void 0) continue;
1638
+ const p = `${at}/${k}`;
1639
+ if (k === "unit") {
1640
+ const u = v;
1641
+ if (f.type === "number" && typeof u === "string" && u.trim() !== "" && u.length <= 24) node.config.unit = u;
1642
+ else lose(ctx, p, "numeric unit");
1643
+ } else if (k === "min" || k === "max" || k === "step") {
1644
+ if (f.type === "number") node.config[k] = v;
1645
+ else if (ratingOk) node.config[k] = v;
1646
+ else lose(ctx, p, "rating bounds");
1647
+ } else lose(ctx, p, "unsupported key");
1648
+ }
1649
+ }
1650
+ var SCALE_UNIT_SET = /* @__PURE__ */ new Set([
1651
+ "px",
1652
+ "%",
1653
+ "rem",
1654
+ "em",
1655
+ "vw",
1656
+ "vh"
1657
+ ]);
1658
+ var unitsOk = (u) => Array.isArray(u) && u.length >= 1 && u.every((x) => SCALE_UNIT_SET.has(x));
1659
+ var boundOk = (b) => b === void 0 || typeof b === "number" && Number.isFinite(b) || isObj(b) && Object.entries(b).every(([k, x]) => SCALE_UNIT_SET.has(k) && typeof x === "number");
1660
+ var textOk = (s, max) => typeof s === "string" && s.length >= 1 && s.length <= max;
1661
+ /** A V2 scale → config.scale (numberScaleSchema): steps, units, presets and the custom escape hatch, each held to its rules. */
1662
+ function scaleToConfig(s, node, at, ctx) {
1663
+ const steps = s.steps;
1664
+ let outSteps;
1665
+ if (Array.isArray(steps)) {
1666
+ if (!(steps.length >= 1 && steps.length <= 50 && new Set(steps.map((x) => x.value)).size === steps.length && steps.every((x) => typeof x.value === "string" && x.value === x.value.trim() && textOk(x.value, 32) && textOk(x.label, 24) && (x.title === void 0 || textOk(x.title, 60)) && (x.css === void 0 || textOk(x.css, 60)) && (x.px === void 0 || typeof x.px === "number" && Number.isFinite(x.px)) && Object.keys(x).every((k) => [
1667
+ "value",
1668
+ "label",
1669
+ "title",
1670
+ "px",
1671
+ "css"
1672
+ ].includes(k))))) return lose(ctx, at, "scale rules");
1673
+ outSteps = steps.map((x) => ({ ...x }));
1674
+ } else {
1675
+ if (!(steps.min < steps.max) || steps.step !== void 0 && !(steps.step > 0)) return lose(ctx, at, "scale rules");
1676
+ outSteps = {
1677
+ min: steps.min,
1678
+ max: steps.max,
1679
+ ...steps.step !== void 0 ? { step: steps.step } : {}
1680
+ };
1681
+ }
1682
+ const out = { steps: outSteps };
1683
+ const tokens = Array.isArray(steps) ? new Set(steps.map((x) => x.value)) : void 0;
1684
+ const c = s.allowCustom;
1685
+ const customOk = c === void 0 || typeof c === "boolean" || typeof c === "object" && c !== null && boundOk(c.min) && boundOk(c.max) && (c.units === void 0 || unitsOk(c.units)) && (c.step === void 0 || c.step > 0) && Object.keys(c).every((x) => [
1686
+ "min",
1687
+ "max",
1688
+ "units",
1689
+ "step"
1690
+ ].includes(x));
1691
+ for (const k of Object.keys(s)) {
1692
+ const v = s[k];
1693
+ if (v === void 0 || k === "steps") continue;
1694
+ const p = `${at}/${k}`;
1695
+ if (k === "units") {
1696
+ if (unitsOk(v)) out.units = [...v];
1697
+ else lose(ctx, p, "scale rules");
1698
+ } else if (k === "defaultUnit") {
1699
+ if (SCALE_UNIT_SET.has(v)) out.defaultUnit = s.defaultUnit;
1700
+ else lose(ctx, p, "scale rules");
1701
+ } else if (k === "allowCustom") {
1702
+ if (customOk) out.allowCustom = typeof c === "boolean" ? c : JSON.parse(JSON.stringify(c));
1703
+ else lose(ctx, p, "scale rules");
1704
+ } else if (k === "presets") {
1705
+ const presets = s.presets;
1706
+ if (presets.length <= 20 && presets.every((x) => {
1707
+ if (x.label !== void 0 && !textOk(x.label, 24)) return false;
1708
+ if (Object.keys(x).some((y) => y !== "label" && y !== "value")) return false;
1709
+ const pv = x.value;
1710
+ if (typeof pv === "number") return Number.isFinite(pv);
1711
+ if (typeof pv === "string") return textOk(pv, 32) && !!tokens?.has(pv);
1712
+ return isObj(pv) && typeof pv.value === "number" && SCALE_UNIT_SET.has(pv.unit) && Object.keys(pv).length === 2 && customOk && !!s.allowCustom;
1713
+ })) out.presets = presets.map((x) => ({
1714
+ ...x.label !== void 0 ? { label: x.label } : {},
1715
+ value: typeof x.value === "object" ? { ...x.value } : x.value
1716
+ }));
1717
+ else lose(ctx, p, "scale rules");
1718
+ } else lose(ctx, p, "unsupported key");
1719
+ }
1720
+ node.config.scale = out;
1721
+ }
1722
+ /** V2 operator → prod showIf op (the legacy `equals` / `notEmpty` forms read as is / is one of / has a value). */
1723
+ var SHOW_IF_OP = {
1724
+ is: "eq",
1725
+ isNot: "neq",
1726
+ in: "in",
1727
+ notIn: "notIn",
1728
+ empty: "empty",
1729
+ notEmpty: "notEmpty",
1730
+ gt: "gt",
1731
+ lt: "lt"
1732
+ };
1733
+ var VALUELESS = /* @__PURE__ */ new Set([
1734
+ "empty",
1735
+ "notEmpty",
1736
+ "isSet"
1737
+ ]);
1738
+ function conditionToShowIf(h, at, siblings, ctx, variantOk) {
1739
+ const rules = [];
1740
+ for (const [i, r] of [h, ...h.also ?? []].entries()) {
1741
+ const rule = conditionRule(r, i === 0, siblings, variantOk);
1742
+ if (!rule) return void lose(ctx, at, "condition");
1743
+ rules.push(rule);
1744
+ }
1745
+ if (h.match !== void 0 && h.match !== "all" && h.match !== "any") return void lose(ctx, at, "condition");
1746
+ return {
1747
+ match: h.match ?? "all",
1748
+ rules
1749
+ };
1750
+ }
1751
+ /** One V2 rule as a prod rule, or null when prod cannot hold it (a scope, a non-sibling, a value showIf cannot test). */
1752
+ function conditionRule(r, head, siblings, variantOk) {
1753
+ const variant = variantOk && r.field === "_variant";
1754
+ if (!r.field || r.scope !== void 0 || !variant && !siblings.some((s) => s.name === r.field)) return null;
1755
+ const allowed = head ? [
1756
+ "field",
1757
+ "equals",
1758
+ "notEmpty",
1759
+ "op",
1760
+ "value",
1761
+ "also",
1762
+ "match"
1763
+ ] : [
1764
+ "field",
1765
+ "equals",
1766
+ "notEmpty",
1767
+ "op",
1768
+ "value"
1769
+ ];
1770
+ if (Object.keys(r).some((k) => !allowed.includes(k) && r[k] !== void 0)) return null;
1771
+ if ([
1772
+ r.op !== void 0,
1773
+ r.equals !== void 0,
1774
+ r.notEmpty !== void 0
1775
+ ].filter(Boolean).length !== 1) return null;
1776
+ if (r.notEmpty !== void 0) return r.notEmpty === true ? {
1777
+ field: r.field,
1778
+ op: "notEmpty"
1779
+ } : null;
1780
+ const target = r.op !== void 0 ? r.value : r.equals;
1781
+ const op = r.op !== void 0 ? SHOW_IF_OP[r.op] : Array.isArray(target) ? "in" : "eq";
1782
+ if (!op) return null;
1783
+ if (VALUELESS.has(op)) return r.value === void 0 ? {
1784
+ field: r.field,
1785
+ op
1786
+ } : null;
1787
+ const sibType = variant ? void 0 : siblings.find((s) => s.name === r.field)?.type;
1788
+ if (op === "gt" || op === "lt") return typeof target === "number" && Number.isFinite(target) ? {
1789
+ field: r.field,
1790
+ op,
1791
+ value: String(target)
1792
+ } : null;
1793
+ const list = Array.isArray(target) ? target : [target];
1794
+ const strs = [];
1795
+ for (const v of list) {
1796
+ if (![
1797
+ "string",
1798
+ "number",
1799
+ "boolean"
1800
+ ].includes(typeof v)) return null;
1801
+ const s = String(v);
1802
+ if (coerceRuleValue(sibType, s) !== v) return null;
1803
+ strs.push(s);
1804
+ }
1805
+ if (op === "in" || op === "notIn") return {
1806
+ field: r.field,
1807
+ op,
1808
+ value: strs
1809
+ };
1810
+ return Array.isArray(target) ? strs.length ? {
1811
+ field: r.field,
1812
+ op: op === "eq" ? "in" : "notIn",
1813
+ value: strs
1814
+ } : null : {
1815
+ field: r.field,
1816
+ op,
1817
+ value: strs[0]
1818
+ };
1819
+ }
1820
+ var nonEmpty = (o) => Object.keys(o).length ? o : void 0;
1821
+ function common(n) {
1822
+ const out = {
1823
+ key: n.key,
1824
+ label: n.label,
1825
+ type: n.type
1826
+ };
1827
+ for (const k of [
1828
+ "helpText",
1829
+ "required",
1830
+ "defaultValue",
1831
+ "showIf",
1832
+ "helpMore",
1833
+ "advanced",
1834
+ "recommendedMax",
1835
+ "openMode",
1836
+ "localized",
1837
+ "archived"
1838
+ ]) if (n[k] !== void 0) out[k] = n[k];
1839
+ return out;
1840
+ }
1841
+ function emitField(n) {
1842
+ const out = common(n);
1843
+ if (n.unique !== void 0) out.unique = n.unique;
1844
+ if (n.readOnly !== void 0) out.readOnly = n.readOnly;
1845
+ if (n.lockReason !== void 0) out.lockReason = n.lockReason;
1846
+ if (n.fieldsetId !== void 0) out.fieldsetId = n.fieldsetId;
1847
+ const config = { ...n.config };
1848
+ if (n.placeholder !== void 0) config.placeholder = n.placeholder;
1849
+ if (n.type === "select" && n.options) out.options = n.options;
1850
+ if ((n.type === "multiselect" || n.type === "tags") && n.options) config.options = n.options;
1851
+ if (n.type === "object") out.fields = (n.children ?? []).map(emitField);
1852
+ if (n.slotSettings) config.slotSettings = n.slotSettings.map(emitField);
1853
+ if (n.zoned) {
1854
+ const { minItems, maxItems, ...rest } = config;
1855
+ out.config = {
1856
+ ...rest,
1857
+ zones: { repeatable: {
1858
+ fields: (n.children ?? []).map(emitField),
1859
+ ...minItems !== void 0 ? { minItems } : {},
1860
+ ...maxItems !== void 0 ? { maxItems } : {}
1861
+ } }
1862
+ };
1863
+ } else if (nonEmpty(config)) out.config = config;
1864
+ const ui = nonEmpty(n.ui);
1865
+ if (ui) out.ui = ui;
1866
+ return out;
1867
+ }
1868
+ function emitProp(n) {
1869
+ const out = common(n);
1870
+ if (n.unique !== void 0) out.unique = n.unique;
1871
+ if (n.readOnly !== void 0) out.readOnly = n.readOnly;
1872
+ if (n.lockReason !== void 0) out.lockReason = n.lockReason;
1873
+ if (n.placeholder !== void 0) out.placeholder = n.placeholder;
1874
+ const config = { ...n.config };
1875
+ if (n.options) config.options = n.options;
1876
+ if (n.children) config.fields = n.children.map(emitSubField);
1877
+ if (n.itemTypes) config.itemTypes = emitItemTypes(n.itemTypes);
1878
+ if (n.slotSettings) config.slotSettings = n.slotSettings.map(emitSubField);
1879
+ if (nonEmpty(config)) out.config = config;
1880
+ const ui = nonEmpty(n.ui);
1881
+ if (ui) out.ui = ui;
1882
+ return out;
1883
+ }
1884
+ function emitSubField(n) {
1885
+ const out = common(n);
1886
+ if (n.unique !== void 0) out.unique = n.unique;
1887
+ if (n.readOnly !== void 0) out.readOnly = n.readOnly;
1888
+ if (n.lockReason !== void 0) out.lockReason = n.lockReason;
1889
+ if (n.placeholder !== void 0) out.placeholder = n.placeholder;
1890
+ if (n.options) out.options = n.options;
1891
+ if (n.children) out.fields = n.children.map(emitSubField);
1892
+ const config = { ...n.config };
1893
+ if (n.itemTypes) config.itemTypes = emitItemTypes(n.itemTypes);
1894
+ if (n.slotSettings) config.slotSettings = n.slotSettings.map(emitSubField);
1895
+ if (nonEmpty(config)) out.config = config;
1896
+ const ui = nonEmpty(n.ui);
1897
+ if (ui) out.ui = ui;
1898
+ return out;
1899
+ }
1900
+ /** A polymorphic list's item types as the backend stores them: `{ name, label, fields }` (typesTableHardening). */
1901
+ var emitItemTypes = (types) => types.map((t) => ({
1902
+ name: t.name,
1903
+ label: t.label,
1904
+ fields: t.children.map(emitSubField),
1905
+ ...t.icon ? { icon: t.icon } : {},
1906
+ ...t.preview ? { preview: t.preview } : {}
1907
+ }));
1908
+ function fromTypeSchema(v2, target) {
1909
+ const ctx = {
1910
+ lane: target,
1911
+ lossy: [],
1912
+ catalog: [],
1913
+ tabs: /* @__PURE__ */ new Set(),
1914
+ droppedTabs: /* @__PURE__ */ new Map(),
1915
+ sets: /* @__PURE__ */ new Map(),
1916
+ propSets: /* @__PURE__ */ new Map(),
1917
+ definedGroups: /* @__PURE__ */ new WeakMap(),
1918
+ propOrder: /* @__PURE__ */ new Map(),
1919
+ groupOrder: false,
1920
+ propTabs: /* @__PURE__ */ new Map(),
1921
+ definedTabs: /* @__PURE__ */ new Set(),
1922
+ keptTabs: /* @__PURE__ */ new Set(),
1923
+ declaredTabs: [],
1924
+ blockModels: /* @__PURE__ */ new Map()
1925
+ };
1926
+ const props = target === "props";
1927
+ const slug = kebab(v2.name);
1928
+ const category = v2.category !== void 0 ? CATEGORY_TO_PROD[v2.category] : void 0;
1929
+ const fieldsets = [];
1930
+ for (const k of Object.keys(v2)) {
1931
+ if (v2[k] === void 0) continue;
1932
+ const p = `/${k}`;
1933
+ switch (k) {
1934
+ case "name":
1935
+ if (camel(slug) !== v2.name) lose(ctx, p, "type name");
1936
+ break;
1937
+ case "title":
1938
+ case "description":
1939
+ case "fields":
1940
+ case "fieldsets":
1941
+ case "groups": break;
1942
+ case "kind":
1943
+ if (props && v2.kind !== "block") cat(ctx, p, v2.kind === "global" ? "kind:global" : "kind:entry (props)");
1944
+ else if (!props && v2.kind !== "entry") cat(ctx, p, v2.kind === "global" ? "kind:global" : v2.kind === "page" ? "kind:page" : v2.kind === "block" ? "kind:block (fields)" : "kind:object");
1945
+ break;
1946
+ case "icon":
1947
+ if (!props || !dockIconOf(v2.icon)) cat(ctx, p, "block icon");
1948
+ break;
1949
+ case "preview":
1950
+ if (!props) cat(ctx, p, "document preview");
1951
+ break;
1952
+ case "variants":
1953
+ cat(ctx, p, "variants");
1954
+ break;
1955
+ case "category":
1956
+ if (!props || !category || capitalize(category) !== v2.category) cat(ctx, p, "category");
1957
+ break;
1958
+ case "placement":
1959
+ cat(ctx, p, "block placement");
1960
+ break;
1961
+ case "initialValue":
1962
+ cat(ctx, p, "seeded instance");
1963
+ break;
1964
+ default: lose(ctx, p, "unsupported key");
1965
+ }
1966
+ }
1967
+ if (props) {
1968
+ propTabsFor(v2, ctx);
1969
+ propSetsFor(v2, ctx);
1970
+ } else fieldsetsFor(v2, ctx, fieldsets);
1971
+ const nodes = v2.fields.map((f, i) => convertField(f, `/fields/${i}`, 1, ctx, v2.fields, true));
1972
+ if (props) {
1973
+ const component = {
1974
+ name: v2.title,
1975
+ slug,
1976
+ props: nodes.map(emitProp)
1977
+ };
1978
+ if (v2.description !== void 0) component.description = v2.description;
1979
+ if (category) component.category = category;
1980
+ const icon = v2.icon === void 0 ? void 0 : dockIconOf(v2.icon);
1981
+ if (icon) component.icon = icon;
1982
+ if (v2.preview !== void 0) {
1983
+ const preview = componentPreviewToProd(v2.preview, new Set(component.props.map((x) => x.key)), v2.fields, "/preview", ctx);
1984
+ if (Object.keys(preview).length) component.preview = preview;
1985
+ }
1986
+ if (ctx.declaredTabs.length) component.tabs = ctx.declaredTabs.map((t) => ({ ...t }));
1987
+ return {
1988
+ schema: component,
1989
+ blockModels: [],
1990
+ lossy: ctx.lossy,
1991
+ catalog: ctx.catalog
1992
+ };
1993
+ }
1994
+ const model = {
1995
+ name: v2.title,
1996
+ slug,
1997
+ fields: nodes.map(emitField)
1998
+ };
1999
+ if (v2.description !== void 0) model.description = v2.description;
2000
+ model.kind = "model";
2001
+ if (fieldsets.length) model.fieldsets = fieldsets;
2002
+ return {
2003
+ schema: model,
2004
+ blockModels: [...ctx.blockModels.values()],
2005
+ lossy: ctx.lossy,
2006
+ catalog: ctx.catalog
2007
+ };
2008
+ }
2009
+ /** Fields lane: V2 groups → `kind: "tab"` fieldsets, V2 fieldsets → `kind: "group"` fieldsets in the tab their members share. */
2010
+ function fieldsetsFor(v2, ctx, out) {
2011
+ const names = /* @__PURE__ */ new Set();
2012
+ let firstDrop;
2013
+ let shifted = false;
2014
+ (v2.groups ?? []).forEach((g, i) => {
2015
+ const p = `/groups/${i}`;
2016
+ const stored = g.title.slice(0, 40);
2017
+ const folded = stored.trim().toLowerCase();
2018
+ const drop = (why) => {
2019
+ if (!ctx.tabs.has(g.name) && !ctx.droppedTabs.has(g.name)) ctx.droppedTabs.set(g.name, why);
2020
+ firstDrop ??= why;
2021
+ lose(ctx, p, why);
2022
+ };
2023
+ if (ctx.tabs.has(g.name) || names.has(folded)) return drop("group name collision");
2024
+ if (out.length >= 3) return drop("groups>3");
2025
+ names.add(folded);
2026
+ const tab = {
2027
+ id: g.name,
2028
+ name: stored,
2029
+ kind: "tab"
2030
+ };
2031
+ if (g.title.length > 40) lose(ctx, `${p}/title`, "group name>40");
2032
+ if (g.icon !== void 0) {
2033
+ const dock = dockIconOf(g.icon);
2034
+ if (dock) tab.icon = dock;
2035
+ else lose(ctx, `${p}/icon`, "group icon");
2036
+ }
2037
+ if (i === 0 ? g.default !== true : g.default !== void 0) lose(ctx, `${p}/default`, "group default");
2038
+ for (const k of Object.keys(g)) if (![
2039
+ "name",
2040
+ "title",
2041
+ "icon",
2042
+ "default"
2043
+ ].includes(k) && g[k] !== void 0) lose(ctx, `${p}/${k}`, "unsupported key");
2044
+ ctx.tabs.add(g.name);
2045
+ out.push(tab);
2046
+ if (firstDrop && !shifted) {
2047
+ shifted = true;
2048
+ lose(ctx, "/groups", firstDrop);
2049
+ }
2050
+ });
2051
+ (v2.fieldsets ?? []).forEach((fs, i) => {
2052
+ const p = `/fieldsets/${i}`;
2053
+ if (ctx.tabs.has(fs.name) || ctx.droppedTabs.has(fs.name) || ctx.sets.has(fs.name) || out.length >= 30) return lose(ctx, p, "fieldset collision");
2054
+ const tally = /* @__PURE__ */ new Map();
2055
+ for (const f of v2.fields) if (f.fieldset === fs.name) tally.set(f.group, (tally.get(f.group) ?? 0) + 1);
2056
+ const best = [...tally.entries()].sort((a, b) => b[1] - a[1])[0]?.[0];
2057
+ const tab = best !== void 0 && ctx.tabs.has(best) ? best : void 0;
2058
+ const set = {
2059
+ id: fs.name,
2060
+ name: fs.title.slice(0, 60),
2061
+ kind: "group"
2062
+ };
2063
+ if (fs.title.length > 60) lose(ctx, `${p}/title`, "fieldset name>limit");
2064
+ if (tab) set.tab = tab;
2065
+ for (const k of Object.keys(fs)) {
2066
+ const v = fs[k];
2067
+ if (v === void 0 || k === "name" || k === "title") continue;
2068
+ if (k === "description") {
2069
+ if (v.length <= 500) set.description = v;
2070
+ else lose(ctx, `${p}/${k}`, "help>limit");
2071
+ } else if (k === "collapsed" || k === "collapsible" || k === "columns" || k === "layout") set[k] = v;
2072
+ else lose(ctx, `${p}/${k}`, "unsupported key");
2073
+ }
2074
+ ctx.sets.set(fs.name, tab);
2075
+ out.push(set);
2076
+ });
2077
+ }
2078
+ /**
2079
+ * Props lane: V2 groups → each top-level prop's `ui.tab`, defined on the first prop in it (label, icon, and `order` when
2080
+ * the V2 order differs from where each tab is first used). A field with no group sits in the V2 default group; a group
2081
+ * not stored puts its fields in the default tab; a fieldset's top-level members share the tab most of them sit in
2082
+ * (prop_group_split_tabs). No groups → no tab anywhere, so a component without tabs stores as before.
2083
+ */
2084
+ function propTabsFor(v2, ctx) {
2085
+ const groups = v2.groups ?? [];
2086
+ const kept = [];
2087
+ const dropped = /* @__PURE__ */ new Map();
2088
+ const labels = /* @__PURE__ */ new Set();
2089
+ groups.forEach((g, i) => {
2090
+ const p = `/groups/${i}`;
2091
+ const drop = (why) => {
2092
+ if (!kept.some((k) => k.g.name === g.name) && !dropped.has(g.name)) dropped.set(g.name, why);
2093
+ lose(ctx, p, why);
2094
+ };
2095
+ const label = g.title.slice(0, 40).trim();
2096
+ const folded = label.toLowerCase();
2097
+ if (kept.some((k) => k.g.name === g.name) || labels.has(folded)) return drop("group name collision");
2098
+ if (kept.length >= 8 || g.name.length < 1 || g.name.length > 40) return drop("prop tab limit");
2099
+ if (!label) return drop("group title");
2100
+ labels.add(folded);
2101
+ const tab = {
2102
+ id: g.name,
2103
+ label
2104
+ };
2105
+ if (label !== g.title.trim()) lose(ctx, `${p}/title`, "group name>40");
2106
+ else if (label !== g.title) lose(ctx, `${p}/title`, "group title");
2107
+ if (g.icon !== void 0) {
2108
+ const dock = dockIconOf(g.icon);
2109
+ if (dock) tab.icon = dock;
2110
+ else lose(ctx, `${p}/icon`, "group icon");
2111
+ }
2112
+ if (i === 0 ? g.default !== true : g.default !== void 0) lose(ctx, `${p}/default`, "group default");
2113
+ for (const k of Object.keys(g)) if (![
2114
+ "name",
2115
+ "title",
2116
+ "icon",
2117
+ "default"
2118
+ ].includes(k) && g[k] !== void 0) lose(ctx, `${p}/${k}`, "unsupported key");
2119
+ kept.push({
2120
+ g,
2121
+ i,
2122
+ tab
2123
+ });
2124
+ });
2125
+ const isKept = (name) => name !== void 0 && kept.some((k) => k.g.name === name);
2126
+ const v2Default = (groups.find((g) => g.default) ?? groups[0])?.name;
2127
+ const fallback = isKept(v2Default) ? v2Default : kept[0]?.g.name;
2128
+ const place = /* @__PURE__ */ new Map();
2129
+ for (const f of v2.fields) {
2130
+ const want = f.group ?? v2Default;
2131
+ if (isKept(want)) place.set(f, { tab: want });
2132
+ else if (f.group !== void 0 || want !== void 0) place.set(f, {
2133
+ tab: fallback,
2134
+ loss: dropped.get(want) ?? "unsupported key"
2135
+ });
2136
+ }
2137
+ if (!kept.length) {
2138
+ for (const [f, t] of place) if (f.group !== void 0) ctx.propTabs.set(f, { loss: t.loss });
2139
+ return;
2140
+ }
2141
+ const tally = /* @__PURE__ */ new Map();
2142
+ for (const f of v2.fields) {
2143
+ if (f.fieldset === void 0) continue;
2144
+ const t = tally.get(f.fieldset) ?? /* @__PURE__ */ new Map();
2145
+ t.set(place.get(f)?.tab, (t.get(place.get(f)?.tab) ?? 0) + 1);
2146
+ tally.set(f.fieldset, t);
2147
+ }
2148
+ for (const f of v2.fields) {
2149
+ const counts = f.fieldset !== void 0 ? tally.get(f.fieldset) : void 0;
2150
+ if (!counts) continue;
2151
+ const best = [...counts.entries()].sort((a, b) => b[1] - a[1])[0][0];
2152
+ const cur = place.get(f);
2153
+ if (cur?.tab !== best) place.set(f, {
2154
+ tab: best,
2155
+ loss: cur?.loss ?? "fieldset spans groups"
2156
+ });
2157
+ }
2158
+ const firstUse = [];
2159
+ for (const f of v2.fields) {
2160
+ const t = place.get(f)?.tab;
2161
+ if (t !== void 0 && !firstUse.includes(t)) firstUse.push(t);
2162
+ }
2163
+ const used = kept.filter((k) => firstUse.includes(k.g.name));
2164
+ const unused = kept.filter((k) => !firstUse.includes(k.g.name));
2165
+ for (const k of kept) ctx.keptTabs.add(k.g.name);
2166
+ const firstGap = groups.findIndex((g) => !kept.some((k) => k.g === g));
2167
+ if (firstGap >= 0 && kept.some((k) => k.i > firstGap)) {
2168
+ const g = groups[firstGap];
2169
+ lose(ctx, "/groups", dropped.get(g.name) ?? "unsupported key");
2170
+ }
2171
+ const ordered = unused.length > 0 || used.some((k, i) => k.g.name !== firstUse[i]);
2172
+ kept.forEach((k, i) => {
2173
+ if (ordered) k.tab.order = Math.min(99, i);
2174
+ });
2175
+ ctx.declaredTabs = unused.map((k) => k.tab);
2176
+ for (const [f, t] of place) {
2177
+ const k = used.find((u) => u.g.name === t.tab);
2178
+ if (k) ctx.propTabs.set(f, {
2179
+ tab: k.tab,
2180
+ loss: t.loss
2181
+ });
2182
+ else if (t.loss) ctx.propTabs.set(f, { loss: t.loss });
2183
+ }
2184
+ }
2185
+ /**
2186
+ * Props lane: a V2 fieldset is an inline ui.group, defined on the first prop (at each level, sub-fields too) that uses
2187
+ * it. A fieldset no prop uses has nothing to be defined on; when the V2 order differs from where each group is first
2188
+ * met (depth first, a prop before its sub-fields: how propsToTypeSchema meets them), every group carries its `order`.
2189
+ */
2190
+ function propSetsFor(v2, ctx) {
2191
+ const sets = v2.fieldsets ?? [];
2192
+ const named = new Set(sets.map((s) => s.name));
2193
+ const firstSeen = [];
2194
+ const undeclared = [];
2195
+ const visit = (fields, lv) => {
2196
+ for (const f of fields) {
2197
+ if (f.fieldset !== void 0 && !firstSeen.includes(f.fieldset)) {
2198
+ firstSeen.push(f.fieldset);
2199
+ if (!named.has(f.fieldset)) undeclared.push(f.fieldset);
2200
+ }
2201
+ if (lv >= 10) continue;
2202
+ const kids = previewKids(f);
2203
+ if (kids) visit(kids, lv + 1);
2204
+ }
2205
+ };
2206
+ visit(v2.fields, 1);
2207
+ const derived = undeclared.map((name) => ({
2208
+ name,
2209
+ title: name
2210
+ }));
2211
+ const declaredUsed = sets.filter((s) => firstSeen.includes(s.name)).length;
2212
+ derived.forEach((s, j) => {
2213
+ ctx.propSets.set(s.name, s);
2214
+ ctx.propOrder.set(s.name, sets.length + j);
2215
+ cat(ctx, `/fieldsets/${declaredUsed + j}`, "fieldset (derived)");
2216
+ });
2217
+ if (!sets.length && !derived.length) return;
2218
+ ctx.groupOrder = [...sets, ...derived].filter((s) => firstSeen.includes(s.name)).some((s, i) => s.name !== firstSeen[i]);
2219
+ let gap = false;
2220
+ sets.forEach((s, i) => {
2221
+ ctx.propSets.set(s.name, s);
2222
+ ctx.propOrder.set(s.name, i);
2223
+ if (!firstSeen.includes(s.name)) {
2224
+ gap = true;
2225
+ return lose(ctx, `/fieldsets/${i}`, "fieldset (props)");
2226
+ }
2227
+ if (gap) {
2228
+ gap = false;
2229
+ lose(ctx, "/fieldsets", "fieldset (props)");
2230
+ }
2231
+ for (const k of Object.keys(s)) {
2232
+ if (s[k] === void 0 || k === "name" || k === "collapsed" || k === "columns" || k === "collapsible" || k === "layout") continue;
2233
+ if (k === "title") {
2234
+ if (s.title.length > 32) lose(ctx, `/fieldsets/${i}/title`, "fieldset name>limit");
2235
+ } else if (k === "description") {
2236
+ if (!groupDescriptionOk(s.description)) lose(ctx, `/fieldsets/${i}/description`, "help>limit");
2237
+ } else lose(ctx, `/fieldsets/${i}/${k}`, "unsupported key");
2238
+ }
2239
+ });
2240
+ }
2241
+ function readField(f) {
2242
+ const cfg = { ...f.config ?? {} };
2243
+ const n = {
2244
+ ...f,
2245
+ config: cfg,
2246
+ ui: { ...f.ui ?? {} }
2247
+ };
2248
+ if (typeof cfg.placeholder === "string") {
2249
+ n.placeholder = cfg.placeholder;
2250
+ delete cfg.placeholder;
2251
+ }
2252
+ if (n.placeholder === void 0 && typeof n.ui.placeholder === "string") n.placeholder = n.ui.placeholder;
2253
+ delete n.ui.placeholder;
2254
+ if ((f.type === "multiselect" || f.type === "tags") && cfg.options) {
2255
+ n.options = cfg.options;
2256
+ delete cfg.options;
2257
+ }
2258
+ n.fields = f.fields?.map(readField);
2259
+ if (f.type === "array" && !cfg.zones && Array.isArray(cfg.fields)) {
2260
+ n.fields = [...n.fields ?? [], ...cfg.fields.map(readField)];
2261
+ delete cfg.fields;
2262
+ }
2263
+ if (cfg.zones) {
2264
+ const z = cfg.zones;
2265
+ n.zones = {
2266
+ ...z.nonRepeatable ? { nonRepeatable: z.nonRepeatable.map(readField) } : {},
2267
+ ...z.repeatable ? { repeatable: {
2268
+ ...z.repeatable,
2269
+ fields: z.repeatable.fields.map(readField)
2270
+ } } : {}
2271
+ };
2272
+ delete cfg.zones;
2273
+ }
2274
+ return n;
2275
+ }
2276
+ function readProp(p) {
2277
+ const { config, fields, options, ...rest } = p;
2278
+ const cfg = { ...config ?? {} };
2279
+ const n = {
2280
+ ...rest,
2281
+ config: cfg,
2282
+ ui: { ...p.ui ?? {} }
2283
+ };
2284
+ const opts = cfg.options ?? options;
2285
+ if (opts) n.options = opts;
2286
+ delete cfg.options;
2287
+ const kids = cfg.fields ?? fields;
2288
+ if (kids) n.fields = kids.map(readProp);
2289
+ delete cfg.fields;
2290
+ return n;
2291
+ }
2292
+ /** A stored choice → the V2 option: a dock icon reads back as the kit's Tabler name, the description as itself. */
2293
+ var optionsFromProd = (opts) => opts.map((o) => {
2294
+ if (typeof o === "string") return {
2295
+ value: o,
2296
+ label: o
2297
+ };
2298
+ const out = {
2299
+ value: o.value,
2300
+ label: o.label
2301
+ };
2302
+ if (typeof o.icon === "string") out.icon = tablerIconOf(o.icon);
2303
+ if (typeof o.description === "string") out.description = o.description;
2304
+ return out;
2305
+ });
2306
+ function scaleFromConfig(s, at, ctx) {
2307
+ const steps = s.steps;
2308
+ const out = !Array.isArray(steps) ? { steps: {
2309
+ min: steps.min,
2310
+ max: steps.max,
2311
+ ...steps.step !== void 0 ? { step: steps.step } : {}
2312
+ } } : steps.some((x) => typeof x.value === "string") ? { steps: steps.map((x) => ({ ...x })) } : (ctx.onLoss(`${at}/steps`, "scale steps", "Numeric step lists read back as token steps named by their number."), { steps: steps.map((x) => ({
2313
+ value: String(x.value),
2314
+ label: x.label ?? String(x.value),
2315
+ px: x.value
2316
+ })) });
2317
+ if (s.units) out.units = s.units;
2318
+ if (s.defaultUnit) out.defaultUnit = s.defaultUnit;
2319
+ if (s.allowCustom !== void 0) out.allowCustom = isObj(s.allowCustom) ? JSON.parse(JSON.stringify(s.allowCustom)) : s.allowCustom;
2320
+ if (s.presets) out.presets = s.presets.map((p) => ({
2321
+ ...p.label !== void 0 ? { label: p.label } : {},
2322
+ value: typeof p.value === "object" ? { ...p.value } : p.value
2323
+ }));
2324
+ return out;
2325
+ }
2326
+ /**
2327
+ * Slot children with each `_variant` written as the family member that places it (`_type`): the variant the child's
2328
+ * component already is drops, another member swaps in. A variant no member places stays, and the write names it lost.
2329
+ */
2330
+ function childVariantsToTypes(v, family) {
2331
+ if (!Array.isArray(v)) return v;
2332
+ return v.map((c) => {
2333
+ if (!isObj(c) || typeof c._variant !== "string") return c;
2334
+ const own = family(typeof c._type === "string" ? c._type : "");
2335
+ const { _variant: _gone, ...rest } = c;
2336
+ if (own?.current === c._variant) return rest;
2337
+ const member = own?.member(c._variant);
2338
+ if (!member) return c;
2339
+ return {
2340
+ ...rest,
2341
+ _type: member
2342
+ };
2343
+ });
2344
+ }
2345
+ /** The prod children a preview path segment may name below a node (an object's, a list's rows'), or null for a leaf. */
2346
+ var readKids = (n) => n.zones ? [...n.zones.nonRepeatable ?? [], ...n.zones.repeatable?.fields ?? []] : n.fields && [
2347
+ "object",
2348
+ "group",
2349
+ "repeater",
2350
+ "table",
2351
+ "array"
2352
+ ].includes(n.type) ? n.fields : null;
2353
+ /** A stored preview path → the V2 path: `image.altText` reads as `image.alt`, the rest as it is. */
2354
+ function previewPathFromProd(path, children) {
2355
+ const segs = path.split(".");
2356
+ let node = children.find((c) => c.key === segs[0]);
2357
+ for (let i = 1; node && i < segs.length; i++) {
2358
+ const kids = readKids(node);
2359
+ if (kids) {
2360
+ node = kids.find((c) => c.key === segs[i]);
2361
+ continue;
2362
+ }
2363
+ if (node.type === "image") {
2364
+ const back = Object.entries(IMAGE_PATH_KEY).find(([, stored]) => stored === segs[i])?.[0];
2365
+ if (back) segs[i] = back;
2366
+ }
2367
+ break;
2368
+ }
2369
+ return segs.join(".");
2370
+ }
2371
+ function previewFromProd(pv, children) {
2372
+ const out = { ...pv };
2373
+ for (const k of [
2374
+ "title",
2375
+ "subtitle",
2376
+ "media"
2377
+ ]) if (typeof pv[k] === "string") out[k] = previewPathFromProd(pv[k], children);
2378
+ if (typeof pv.icon === "string") out.icon = tablerIconOf(pv.icon);
2379
+ return out;
2380
+ }
2381
+ function showIfToCondition(s, siblings, at, ctx) {
2382
+ const conds = [];
2383
+ for (const r of s.rules) {
2384
+ const c = showIfRuleToCondition(r, siblings);
2385
+ if (!c) return void ctx.onLoss(at, "condition", `V2 conditions have no "${r.op}" with this value; the field always shows.`);
2386
+ conds.push(c);
2387
+ }
2388
+ if (!conds.length) return void 0;
2389
+ const [head, ...also] = conds;
2390
+ return {
2391
+ ...head,
2392
+ ...also.length ? { also } : {},
2393
+ ...s.match === "any" && conds.length > 1 ? { match: "any" } : {}
2394
+ };
2395
+ }
2396
+ /** One prod rule as a V2 rule: eq / in / isSet keep V2's legacy forms, the rest name their `op`. */
2397
+ function showIfRuleToCondition(r, siblings) {
2398
+ const sib = siblings.find((x) => x.key === r.field);
2399
+ const t = sib?.type === "number" ? "number" : sib?.type;
2400
+ const read = (v) => coerceRuleValue(t, v);
2401
+ const list = (Array.isArray(r.value) ? r.value : [r.value ?? ""]).map(read);
2402
+ switch (r.op) {
2403
+ case "eq": return Array.isArray(r.value) ? {
2404
+ field: r.field,
2405
+ equals: r.value.map(read)
2406
+ } : {
2407
+ field: r.field,
2408
+ equals: read(r.value ?? "")
2409
+ };
2410
+ case "in": return {
2411
+ field: r.field,
2412
+ equals: list
2413
+ };
2414
+ case "isSet":
2415
+ case "notEmpty": return {
2416
+ field: r.field,
2417
+ notEmpty: true
2418
+ };
2419
+ case "empty": return {
2420
+ field: r.field,
2421
+ op: "empty"
2422
+ };
2423
+ case "neq": return {
2424
+ field: r.field,
2425
+ op: "isNot",
2426
+ value: Array.isArray(r.value) ? list : read(r.value ?? "")
2427
+ };
2428
+ case "notIn": return {
2429
+ field: r.field,
2430
+ op: "notIn",
2431
+ value: list
2432
+ };
2433
+ case "gt":
2434
+ case "lt": {
2435
+ const n = Number(r.value);
2436
+ return typeof r.value === "string" && r.value.trim() !== "" && Number.isFinite(n) ? {
2437
+ field: r.field,
2438
+ op: r.op,
2439
+ value: n
2440
+ } : void 0;
2441
+ }
2442
+ default: return;
2443
+ }
2444
+ }
2445
+ function v2Type(n, at, ctx) {
2446
+ switch (n.type) {
2447
+ case "text": return n.config.inputType === "url" ? "url" : "string";
2448
+ case "longtext": return "text";
2449
+ case "document":
2450
+ ctx.onLoss(`${at}/type`, "document", "A document (article body) reads as rich text.");
2451
+ return "richtext";
2452
+ case "phone":
2453
+ ctx.onLoss(`${at}/type`, "phone", "V2 has no phone type; it reads as a string.");
2454
+ return "string";
2455
+ case "location": return "geopoint";
2456
+ case "number": return n.ui.control === "rating" ? "rating" : "number";
2457
+ case "select": return n.config.multiSelect === true ? "multiselect" : "select";
2458
+ case "multiselect": return n.config.allowCustom === true ? "tags" : "multiselect";
2459
+ case "group":
2460
+ case "object": return "object";
2461
+ case "repeater":
2462
+ case "table":
2463
+ case "array":
2464
+ case "multi-reference":
2465
+ case "multiReference":
2466
+ case "modular": return "array";
2467
+ case "form": return "reference";
2468
+ case "component-ref":
2469
+ case "sections":
2470
+ case "slot":
2471
+ ctx.onLoss(`${at}/type`, n.type, "This prod type stores component or block instances V2 cannot edit; it reads as json.");
2472
+ return "json";
2473
+ default: return n.type;
2474
+ }
2475
+ }
2476
+ function readToV2(n, at, siblings, ctx, top, lane) {
2477
+ /** a data table holds one TableValue: the V2 `table` field, not a list of rows. A prop says so (config.mode "data");
2478
+ * a field's table is always one (BE tableFieldSchema: `mode` is optional there and can only be "data") */
2479
+ const dataTable = isDataTableProp(n) || lane === "fields" && n.type === "table";
2480
+ /** a slot prop: component instances, read as the V2 slot (its children `{ _key, _type, _settings?, ...props }`) */
2481
+ const slotProp = lane === "props" && n.type === "slot";
2482
+ /** a model slot field: inline children of the kind:'block' models config.blockSlugs names */
2483
+ const blockSlot = lane === "fields" && n.type === "slot";
2484
+ const type = dataTable ? "table" : slotProp || blockSlot ? "slot" : v2Type(n, at, ctx);
2485
+ const f = {
2486
+ name: n.key,
2487
+ title: n.label,
2488
+ type
2489
+ };
2490
+ const cfg = n.config;
2491
+ const val = {};
2492
+ const loss = (k, feature, reason) => ctx.onLoss(`${at}/${k}`, feature, reason);
2493
+ if (typeof n.helpText === "string") f.description = n.helpText;
2494
+ if (n.helpMore !== void 0) f.helpMore = n.helpMore;
2495
+ if (n.placeholder !== void 0) f.placeholder = n.placeholder;
2496
+ if (n.required !== void 0) val.required = n.required;
2497
+ if (n.unique !== void 0) val.unique = n.unique;
2498
+ if (n.recommendedMax !== void 0) val.recommendedMax = n.recommendedMax;
2499
+ if (n.advanced !== void 0) f.advanced = n.advanced;
2500
+ if (n.openMode !== void 0) f.openMode = n.openMode;
2501
+ if (n.readOnly === true) f.readOnly = true;
2502
+ if (n.archived === true) f.archived = true;
2503
+ if (n.ui.access) f.access = { ...n.ui.access };
2504
+ else if (n.readOnly === "developer") f.access = { edit: "schema.manage" };
2505
+ if (n.lockReason !== void 0) f.lockReason = n.lockReason;
2506
+ const shopify = n.readOnly === true && n.lockReason === "A Shopify product id. No Shopify integration backs a reference in BetterCMS yet, so the id is kept as it is." && (n.type === "text" || n.type === "array" && n.config.itemType === "text");
2507
+ if (shopify) {
2508
+ delete f.lockReason;
2509
+ if (n.type === "text") {
2510
+ f.type = "reference";
2511
+ f.reference = { to: ["shopify"] };
2512
+ }
2513
+ }
2514
+ if (n.localized !== void 0) f.localized = n.localized;
2515
+ if (n.ui.hidden !== void 0) f.hidden = n.ui.hidden;
2516
+ if (n.ui.rows !== void 0) f.rows = n.ui.rows;
2517
+ if (n.ui.synced !== void 0) f.synced = { ...n.ui.synced };
2518
+ if (n.ui.valueShape !== void 0) f.valueShape = n.ui.valueShape;
2519
+ if (n.showIf) {
2520
+ const c = showIfToCondition(n.showIf, siblings, `${at}/showIf`, ctx);
2521
+ if (c) f.hidden = c;
2522
+ }
2523
+ if (n.placement !== void 0) loss("placement", "placement", "V2 has no editor placement; the field renders in the form.");
2524
+ if (n.searchable === false) loss("searchable", "searchable", "V2 has no search-index flag.");
2525
+ if (n.ui.collapsed !== void 0) loss("ui/collapsed", "ui.collapsed", "V2 fields have no start-collapsed flag.");
2526
+ if (n.ui.reorderable !== void 0) loss("ui/reorderable", "ui.reorderable", "V2 lists are always reorderable.");
2527
+ if (n.ui.input !== void 0) loss("ui/input", "ui.input", "Custom dock inputs are a dock feature V2 has no key for.");
2528
+ if (n.fieldsetId !== void 0) {
2529
+ const set = ctx.sets.get(n.fieldsetId);
2530
+ if (set?.kind === "tab") {
2531
+ if (top) f.group = set.id;
2532
+ else loss("fieldsetId", "fieldset", "Only top-level V2 fields sit in a tab; this nested field's tab is dropped.");
2533
+ } else if (set) {
2534
+ f.fieldset = set.id;
2535
+ if (top && set.tab !== void 0) f.group = set.tab;
2536
+ } else loss("fieldsetId", "fieldset", `No fieldset "${n.fieldsetId}" exists on this model; the membership is dropped.`);
2537
+ }
2538
+ if (lane === "props" && n.ui.group) f.fieldset = n.ui.group.id;
2539
+ if (lane === "props" && n.ui.tab) f.group = n.ui.tab.id;
2540
+ for (const k of [
2541
+ "target",
2542
+ "stale",
2543
+ "origin"
2544
+ ]) if (n[k] !== void 0) loss(k, k, k === "target" ? "A prop's target (where it writes in the component) is binding, not schema: V2 has no key for it, so the host keeps it." : `V2 has no "${k}" key.`);
2545
+ const used = /* @__PURE__ */ new Set([
2546
+ "placeholder",
2547
+ "zones",
2548
+ "options",
2549
+ "fields"
2550
+ ]);
2551
+ const usedUi = /* @__PURE__ */ new Set([
2552
+ "collapsed",
2553
+ "reorderable",
2554
+ "input",
2555
+ "access",
2556
+ "hidden",
2557
+ "rows",
2558
+ "synced",
2559
+ "valueShape"
2560
+ ]);
2561
+ const use = (...k) => k.forEach((x) => used.add(x));
2562
+ const useUi = (...k) => k.forEach((x) => usedUi.add(x));
2563
+ if (lane === "props") useUi("group");
2564
+ if (lane === "props") useUi("tab");
2565
+ if ([
2566
+ "text",
2567
+ "longtext",
2568
+ "url",
2569
+ "richtext",
2570
+ "document"
2571
+ ].includes(n.type)) {
2572
+ use("minLength", "maxLength", "pattern", "patternMessage", "inputType");
2573
+ if (typeof cfg.minLength === "number") val.min = cfg.minLength;
2574
+ if (typeof cfg.maxLength === "number") val.max = cfg.maxLength;
2575
+ if (typeof cfg.pattern === "string") val.pattern = cfg.pattern;
2576
+ if (typeof cfg.patternMessage === "string") val.patternMessage = cfg.patternMessage;
2577
+ }
2578
+ if (type === "number" || type === "rating") {
2579
+ const numeric = {};
2580
+ for (const k of [
2581
+ "min",
2582
+ "max",
2583
+ "step"
2584
+ ]) if (typeof cfg[k] === "number") numeric[k] = cfg[k];
2585
+ if (n.type === "rating") {
2586
+ if (numeric.step === V2_RATING_STEP) delete numeric.step;
2587
+ else if (numeric.step === void 0) numeric.step = 1;
2588
+ }
2589
+ const ratingDefault = type === "rating" && n.type === "number" && ratingIsDefault(numeric);
2590
+ if (typeof cfg.unit === "string") numeric.unit = cfg.unit;
2591
+ if (Object.keys(numeric).length && !ratingDefault) f.numeric = numeric;
2592
+ const bounds = cfg.validation;
2593
+ if (isObj(bounds)) {
2594
+ for (const k of ["min", "max"]) if (typeof bounds[k] === "number") val[k] = bounds[k];
2595
+ }
2596
+ if (cfg.scale) f.scale = scaleFromConfig(cfg.scale, `${at}/config/scale`, ctx);
2597
+ if (n.ui.control === "slider") f.layout = "slider";
2598
+ use("min", "max", "step", "scale", "unit", "validation");
2599
+ if (n.ui.control === "slider" || n.ui.control === "rating") useUi("control");
2600
+ }
2601
+ const control = n.ui.control;
2602
+ if (control !== void 0 && control !== "slider" && control !== "rating" && (control === "segmented" ? type === "select" : CONTROL_TYPES[control]?.includes(type))) {
2603
+ f.layout = control;
2604
+ useUi("control");
2605
+ }
2606
+ if (n.type === "select") use("multiSelect");
2607
+ if (n.type === "image") {
2608
+ use("media");
2609
+ if (cfg.media === "icon") f.svgOnly = true;
2610
+ }
2611
+ if (typeof cfg.linkHref === "string" && cfg.linkHref) f.linkHref = cfg.linkHref;
2612
+ use("linkHref");
2613
+ if ((type === "select" || type === "multiselect" || type === "tags") && n.options) f.options = optionsFromProd(n.options);
2614
+ if (type === "multiselect" || type === "tags") {
2615
+ if (typeof cfg.min === "number") val.min = cfg.min;
2616
+ if (typeof cfg.max === "number") val.max = cfg.max;
2617
+ use("min", "max", "allowCustom");
2618
+ }
2619
+ if (n.type === "code") {
2620
+ if (typeof cfg.language === "string") f.language = cfg.language;
2621
+ else if (cfg.language !== void 0) loss("config/language", "code language", "The field's language is not a string; it is dropped.");
2622
+ if (Array.isArray(cfg.languages) && cfg.languages.every((l) => typeof l === "string")) f.languages = [...cfg.languages];
2623
+ else if (cfg.languages !== void 0) loss("config/languages", "code language", "The field's languages are not a list of names; they are dropped.");
2624
+ use("language", "languages");
2625
+ }
2626
+ if (n.type === "tags" && cfg.allowCustom === false) loss("config/allowCustom", "tags closed", "V2 tags always take free entry; a closed tags list reads as open tags.");
2627
+ if (type === "date" || type === "datetime") use("timezone", "includeTime");
2628
+ if ((type === "date" || type === "datetime") && typeof cfg.timezone === "string") f.timezone = cfg.timezone === "site" ? "site" : `fixed:${cfg.timezone}`;
2629
+ if ((type === "date" || type === "datetime") && typeof cfg.timezone === "boolean") f.timezone = cfg.timezone;
2630
+ if (n.type === "reference" || n.type === "multi-reference" || n.type === "multiReference") use("contentModelId", "polymorphic", "allowedModelSlugs", "targets", "filter");
2631
+ if (n.type === "reference") {
2632
+ const ref = referenceFromConfig(cfg);
2633
+ if (ref) f.reference = ref;
2634
+ }
2635
+ if (n.type === "form") f.reference = { to: ["form"] };
2636
+ if (n.type === "object" || n.type === "group") {
2637
+ f.fields = (n.fields ?? []).map((c, i) => readToV2(c, `${at}/fields/${i}`, n.fields ?? [], ctx, false, lane));
2638
+ if (n.ui.preview) f.preview = previewFromProd(n.ui.preview, n.fields ?? []);
2639
+ if (n.ui.icon) f.icon = tablerIconOf(n.ui.icon);
2640
+ useUi("preview", "icon");
2641
+ }
2642
+ if (n.type === "array" && n.zones?.nonRepeatable) {
2643
+ const nr = n.zones.nonRepeatable;
2644
+ const fields = nr.map((c, i) => readToV2(c, `${at}/config/zones/nonRepeatable/${i}`, nr, ctx, false, lane));
2645
+ if (n.zones.repeatable) {
2646
+ const kids = [{
2647
+ name: "nonRepeatable",
2648
+ title: n.label,
2649
+ type: "object",
2650
+ fields
2651
+ }, listOf(n, n.zones.repeatable.fields, "repeatable", `${at}/config/zones/repeatable`, ctx, lane)];
2652
+ ctx.onLoss(`${at}/config/zones`, "zone envelope", "A zone pair reads as an object with nonRepeatable and repeatable children, matching its stored {nonRepeatable, repeatable} value.");
2653
+ Object.assign(f, {
2654
+ type: "object",
2655
+ fields: kids
2656
+ });
2657
+ } else {
2658
+ Object.assign(f, {
2659
+ type: "object",
2660
+ fields
2661
+ });
2662
+ ctx.zoned.add(f);
2663
+ }
2664
+ } else if (slotProp) {
2665
+ const ids = Array.isArray(cfg.componentIds) ? cfg.componentIds.filter((x) => typeof x === "string") : [];
2666
+ const names = Array.isArray(cfg.allow) ? cfg.allow.filter((x) => typeof x === "string") : [];
2667
+ f.of = ids.length ? {
2668
+ type: "block",
2669
+ allow: ids
2670
+ } : names.length ? {
2671
+ type: "block",
2672
+ allow: names
2673
+ } : { type: "block" };
2674
+ ctx.slots.set(f, cfg.multiple === true);
2675
+ const settings = Array.isArray(cfg.slotSettings) ? cfg.slotSettings.map(readProp) : [];
2676
+ if (settings.length) f.slotSettings = settings.map((c, k) => readToV2(c, `${at}/config/slotSettings/${k}`, settings, ctx, false, lane));
2677
+ if (cfg.multiple !== true) {
2678
+ val.max = 1;
2679
+ loss("config/multiple", "slot single", "A single slot holds one component instance; V2 reads it as a slot of at most one block.");
2680
+ } else {
2681
+ if (typeof cfg.minItems === "number") val.min = cfg.minItems;
2682
+ if (typeof cfg.maxItems === "number") val.max = cfg.maxItems;
2683
+ }
2684
+ use("multiple", "componentIds", "allow", "minItems", "maxItems", "slotSettings");
2685
+ } else if (blockSlot) {
2686
+ const slugs = Array.isArray(cfg.blockSlugs) ? cfg.blockSlugs.filter((x) => typeof x === "string") : [];
2687
+ f.of = slugs.length ? {
2688
+ type: "block",
2689
+ allow: slugs.map(camel)
2690
+ } : { type: "block" };
2691
+ ctx.blocks.add(f);
2692
+ const settings = Array.isArray(cfg.slotSettings) ? cfg.slotSettings.map(readField) : [];
2693
+ if (settings.length) f.slotSettings = settings.map((c, k) => readToV2(c, `${at}/config/slotSettings/${k}`, settings, ctx, false, lane));
2694
+ if (typeof cfg.minItems === "number") val.min = cfg.minItems;
2695
+ if (typeof cfg.maxItems === "number") val.max = cfg.maxItems;
2696
+ use("blockSlugs", "minItems", "maxItems", "slotSettings");
2697
+ } else if (lane === "props" && n.type === "table" && cfg.mode === "types") {
2698
+ f.of = (Array.isArray(cfg.itemTypes) ? cfg.itemTypes : []).map((t, j) => {
2699
+ const kids = (t.fields ?? []).map(readProp);
2700
+ const item = {
2701
+ name: t.name,
2702
+ title: t.label ?? t.name,
2703
+ type: "object",
2704
+ fields: kids.map((c, k) => readToV2(c, `${at}/config/itemTypes/${j}/fields/${k}`, kids, ctx, false, lane))
2705
+ };
2706
+ if (t.icon) item.icon = tablerIconOf(t.icon);
2707
+ if (t.preview) item.preview = previewFromProd(t.preview, kids);
2708
+ return item;
2709
+ });
2710
+ ctx.types.add(f);
2711
+ if (n.ui.itemLabel !== void 0) f.itemNoun = n.ui.itemLabel.toLowerCase();
2712
+ if (n.ui.icon) f.icon = tablerIconOf(n.ui.icon);
2713
+ const l = n.ui.layout;
2714
+ if (l === "grid" || l === "list") f.arrayLayout = l;
2715
+ else if (l === "rows") f.layout = "list";
2716
+ else if (l) loss("ui/layout", "ui.layout", `V2 has no "${l}" layout for a list of item types.`);
2717
+ if (typeof cfg.minItems === "number") val.min = cfg.minItems;
2718
+ if (typeof cfg.maxItems === "number") val.max = cfg.maxItems;
2719
+ use("mode", "itemTypes", "minItems", "maxItems");
2720
+ useUi("itemLabel", "icon", "layout");
2721
+ } else if (dataTable) {
2722
+ f.table = tableOptionsFromConfig(cfg);
2723
+ use("mode", "columnTypes", "lockColumns", "requireCaption", "allowGroups", "allowFootnotes", "allowNote", "minRows", "maxRows", "maxColumns", "settings", "jsonLd");
2724
+ } else if (n.type === "array" && (n.zones?.repeatable || !n.zones && !cfg.itemType && n.fields?.length) || n.type === "repeater" || n.type === "table") {
2725
+ const list = listOf(n, n.zones?.repeatable?.fields ?? n.fields ?? [], n.key, at, ctx, lane);
2726
+ useUi("preview", "icon", "itemLabel", "layout", "itemName", "itemTitle");
2727
+ if (n.zones?.repeatable) ctx.zoned.add(f);
2728
+ f.of = list.of;
2729
+ if (list.itemNoun !== void 0) f.itemNoun = list.itemNoun;
2730
+ if (list.arrayLayout) f.arrayLayout = list.arrayLayout;
2731
+ if (list.layout) f.layout = list.layout;
2732
+ const r = n.zones?.repeatable ?? (n.type === "table" ? {
2733
+ minItems: cfg.minItems,
2734
+ maxItems: cfg.maxItems
2735
+ } : void 0);
2736
+ if (typeof r?.minItems === "number") val.min = r.minItems;
2737
+ if (typeof r?.maxItems === "number") val.max = r.maxItems;
2738
+ if (n.type === "table") use("minItems", "maxItems");
2739
+ } else if (n.type === "array" && cfg.itemType) {
2740
+ f.of = [shopify ? {
2741
+ ...itemOf(n),
2742
+ type: "reference",
2743
+ reference: { to: ["shopify"] }
2744
+ } : {
2745
+ ...itemOf(n),
2746
+ type: cfg.itemType === "text" ? "string" : cfg.itemType,
2747
+ ...itemSettingsFromProd(cfg.item)
2748
+ }];
2749
+ leafListChrome(n, f, loss, "a list of scalars");
2750
+ if (typeof cfg.minItems === "number") val.min = cfg.minItems;
2751
+ if (typeof cfg.maxItems === "number") val.max = cfg.maxItems;
2752
+ use("itemType", "minItems", "maxItems", "item");
2753
+ useUi("layout", "itemLabel", "itemName", "itemTitle");
2754
+ } else if (n.type === "modular") {
2755
+ const slugs = cfg.blockSlugs ?? [];
2756
+ f.of = slugs.map((s, j) => {
2757
+ const bm = ctx.blockModels.get(s);
2758
+ const chrome = n.ui.blocks?.[s];
2759
+ const kids = bm ? bm.fields.map(readField) : [];
2760
+ const item = bm ? {
2761
+ name: camel(s),
2762
+ title: bm.name,
2763
+ type: "object",
2764
+ fields: kids.map((c, k) => readToV2(c, `${at}/of/${j}/fields/${k}`, kids, ctx, false, lane))
2765
+ } : {
2766
+ name: camel(s),
2767
+ title: camel(s),
2768
+ type: "object",
2769
+ fields: []
2770
+ };
2771
+ if (chrome?.icon) item.icon = tablerIconOf(chrome.icon);
2772
+ if (chrome?.preview) item.preview = previewFromProd(chrome.preview, kids);
2773
+ return item;
2774
+ });
2775
+ const missing = slugs.filter((s) => !ctx.blockModels.has(s));
2776
+ if (missing.length) ctx.onLoss(`${at}/config/blockSlugs`, "block models", `Each item type is its own block model; ${missing.join(", ")} was not passed, so its fields read as none.`);
2777
+ ctx.modular.add(f);
2778
+ if (n.ui.itemLabel) f.itemNoun = n.ui.itemLabel.toLowerCase();
2779
+ if (n.ui.icon) f.icon = tablerIconOf(n.ui.icon);
2780
+ const l = n.ui.layout;
2781
+ if (l === "grid" || l === "list") f.arrayLayout = l;
2782
+ else if (l === "rows") f.layout = "list";
2783
+ else if (l) loss("ui/layout", "ui.layout", `V2 has no "${l}" layout for a list of blocks.`);
2784
+ if (typeof cfg.minItems === "number") val.min = cfg.minItems;
2785
+ if (typeof cfg.maxItems === "number") val.max = cfg.maxItems;
2786
+ use("blockSlugs", "minItems", "maxItems");
2787
+ useUi("itemLabel", "icon", "layout", "blocks");
2788
+ } else if (n.type === "multi-reference" || n.type === "multiReference") {
2789
+ const ref = referenceFromConfig(cfg);
2790
+ f.of = [{
2791
+ ...itemOf(n),
2792
+ type: "reference",
2793
+ ...ref ? { reference: ref } : {}
2794
+ }];
2795
+ leafListChrome(n, f, loss, "a list of entries");
2796
+ if (typeof cfg.min === "number") val.min = cfg.min;
2797
+ if (typeof cfg.max === "number") val.max = cfg.max;
2798
+ use("min", "max");
2799
+ useUi("layout", "itemLabel", "itemName", "itemTitle");
2800
+ }
2801
+ if (n.type === "array" && n.zones?.nonRepeatable && n.zones.repeatable) useUi("preview", "icon", "itemLabel", "layout");
2802
+ for (const [k, x] of Object.entries(cfg)) {
2803
+ if (x === void 0 || used.has(k)) continue;
2804
+ if (isHostConfigKey(n.type, k) || isHostConfigKey(type, k)) loss(`config/${k}`, "host config", CATALOG["host config"]);
2805
+ else loss(`config/${k}`, "config", `V2 has no "${k}" setting on a ${type} field.`);
2806
+ }
2807
+ for (const [k, x] of Object.entries(n.ui)) if (x !== void 0 && !usedUi.has(k)) loss(`ui/${k}`, `ui.${k}`, `V2 has no ui.${k} on a ${type} field.`);
2808
+ if (n.defaultValue !== void 0 || top && ctx.plans) {
2809
+ const plan = readPlan(f, n.type, ctx.zoned, ctx.modular, ctx.types, ctx.slots, ctx.blocks);
2810
+ if (top) ctx.plans?.set(f.name, plan);
2811
+ if (n.defaultValue !== void 0) f.initialValue = planFromProd(plan, n.defaultValue, (rel, reason) => loss(`defaultValue${rel}`, "stored value", reason));
2812
+ }
2813
+ if (Object.keys(val).length) f.validation = val;
2814
+ return f;
2815
+ }
2816
+ /** config.item → the V2 item field's description, localized flag and validation (in V2's key order). */
2817
+ function itemSettingsFromProd(item) {
2818
+ if (!isObj(item)) return {};
2819
+ const s = item;
2820
+ const out = {};
2821
+ const val = {};
2822
+ if (s.required !== void 0) val.required = s.required;
2823
+ if (s.minLength !== void 0) val.min = s.minLength;
2824
+ if (s.maxLength !== void 0) val.max = s.maxLength;
2825
+ if (s.pattern !== void 0) val.pattern = s.pattern;
2826
+ if (s.patternMessage !== void 0) val.patternMessage = s.patternMessage;
2827
+ if (Object.keys(val).length) out.validation = val;
2828
+ if (s.localized !== void 0) out.localized = s.localized;
2829
+ if (s.helpText !== void 0) out.description = s.helpText;
2830
+ return out;
2831
+ }
2832
+ /** A reference config → the V2 `reference`: entry models first, then config.targets; config.filter as written. */
2833
+ function referenceFromConfig(cfg) {
2834
+ const entries = cfg.polymorphic ? cfg.allowedModelSlugs ?? [] : cfg.contentModelId ? [cfg.contentModelId] : [];
2835
+ const targets = Array.isArray(cfg.targets) ? cfg.targets.filter((t) => typeof t === "string") : [];
2836
+ const to = [...entries, ...targets];
2837
+ if (!to.length && typeof cfg.filter !== "string") return void 0;
2838
+ return {
2839
+ to,
2840
+ ...typeof cfg.filter === "string" ? { filter: cfg.filter } : {}
2841
+ };
2842
+ }
2843
+ /** A list of scalars or entries: its item's name and title (ui.itemName / ui.itemTitle, else the convention). */
2844
+ var itemOf = (n) => {
2845
+ const conv = conventionItem(n.key, n.label);
2846
+ return {
2847
+ name: n.ui.itemName ?? conv.name,
2848
+ title: n.ui.itemTitle ?? conv.title
2849
+ };
2850
+ };
2851
+ /** A list of scalars or entries: the noun (ui.itemLabel) and its layout (rows → list, gallery → grid tiles). */
2852
+ function leafListChrome(n, f, loss, what) {
2853
+ if (n.ui.itemLabel !== void 0) f.itemNoun = n.ui.itemLabel.toLowerCase();
2854
+ const l = n.ui.layout;
2855
+ if (l === "rows") f.layout = "list";
2856
+ else if (l === "gallery") f.arrayLayout = "grid";
2857
+ else if (l) loss("ui/layout", "ui.layout", `V2 has no "${l}" layout for ${what}.`);
2858
+ }
2859
+ /** A list of object rows (zones.repeatable, legacy repeater, prop table) → the V2 array's single item type. */
2860
+ function listOf(n, kids, name, at, ctx, lane) {
2861
+ const conv = conventionItem(name, n.label, n.ui.itemLabel);
2862
+ const item = {
2863
+ name: n.ui.itemName ?? conv.name,
2864
+ title: n.ui.itemTitle ?? conv.title,
2865
+ type: "object",
2866
+ fields: kids.map((c, i) => readToV2(c, `${at}/fields/${i}`, kids, ctx, false, lane))
2867
+ };
2868
+ if (n.ui.preview) item.preview = previewFromProd(n.ui.preview, kids);
2869
+ if (n.ui.icon) item.icon = tablerIconOf(n.ui.icon);
2870
+ const out = {
2871
+ name,
2872
+ title: n.label,
2873
+ type: "array",
2874
+ of: [item]
2875
+ };
2876
+ if (n.ui.itemLabel !== void 0) out.itemNoun = n.ui.itemLabel.toLowerCase();
2877
+ const l = n.ui.layout;
2878
+ if (l === "grid" || l === "list") out.arrayLayout = l;
2879
+ else if (l === "rows") out.layout = "list";
2880
+ else if (l) ctx.onLoss(`${at}/ui/layout`, "ui.layout", `V2 has no "${l}" layout for rows.`);
2881
+ return out;
2882
+ }
2883
+ /** A prod content model (both dialects) → TypeSchema. */
2884
+ function toTypeSchema(model, opts = {}) {
2885
+ const ctx = {
2886
+ onLoss: (path, feature, reason) => opts.onLoss?.({
2887
+ path,
2888
+ feature,
2889
+ reason
2890
+ }),
2891
+ sets: /* @__PURE__ */ new Map(),
2892
+ zoned: /* @__PURE__ */ new WeakSet(),
2893
+ modular: /* @__PURE__ */ new WeakSet(),
2894
+ types: /* @__PURE__ */ new WeakSet(),
2895
+ slots: /* @__PURE__ */ new WeakMap(),
2896
+ blocks: /* @__PURE__ */ new WeakSet(),
2897
+ blockModels: new Map((opts.blockModels ?? []).map((m) => [m.slug, m])),
2898
+ plans: opts.plans
2899
+ };
2900
+ const sets = model.fieldsets ?? [];
2901
+ const groups = [];
2902
+ const fieldsets = [];
2903
+ sets.forEach((s, i) => {
2904
+ ctx.sets.set(s.id, s);
2905
+ if (s.kind === "tab") {
2906
+ const g = {
2907
+ name: s.id,
2908
+ title: s.name
2909
+ };
2910
+ if (s.icon) g.icon = tablerIconOf(s.icon);
2911
+ if (groups.length === 0) g.default = true;
2912
+ groups.push(g);
2913
+ return;
2914
+ }
2915
+ const fs = {
2916
+ name: s.id,
2917
+ title: s.name
2918
+ };
2919
+ if (s.description !== void 0) fs.description = s.description;
2920
+ for (const k of [
2921
+ "collapsed",
2922
+ "collapsible",
2923
+ "columns",
2924
+ "layout"
2925
+ ]) if (s[k] !== void 0) fs[k] = s[k];
2926
+ if (s.kind === "row") ctx.onLoss(`/fieldsets/${i}/kind`, "fieldset row", "V2 has no row fieldset; it reads as a section.");
2927
+ if (s.icon !== void 0) ctx.onLoss(`/fieldsets/${i}/icon`, "fieldset icon", "V2 sections have no icon.");
2928
+ fieldsets.push(fs);
2929
+ });
2930
+ const nodes = model.fields.map(readField);
2931
+ const out = {
2932
+ name: camel(model.slug),
2933
+ title: model.name,
2934
+ kind: model.kind === "block" ? "block" : "entry",
2935
+ fields: nodes.map((n, i) => readToV2(n, `/fields/${i}`, nodes, ctx, true, "fields"))
2936
+ };
2937
+ if (model.description !== void 0) out.description = model.description;
2938
+ if (fieldsets.length) out.fieldsets = fieldsets;
2939
+ if (groups.length) out.groups = groups;
2940
+ return out;
2941
+ }
2942
+ /** A prod component's props → TypeSchema (kind "block"); prop groups read back as fieldsets. */
2943
+ function propsToTypeSchema(component, opts = {}) {
2944
+ const ctx = {
2945
+ onLoss: (path, feature, reason) => opts.onLoss?.({
2946
+ path,
2947
+ feature,
2948
+ reason
2949
+ }),
2950
+ sets: /* @__PURE__ */ new Map(),
2951
+ zoned: /* @__PURE__ */ new WeakSet(),
2952
+ modular: /* @__PURE__ */ new WeakSet(),
2953
+ types: /* @__PURE__ */ new WeakSet(),
2954
+ slots: /* @__PURE__ */ new WeakMap(),
2955
+ blocks: /* @__PURE__ */ new WeakSet(),
2956
+ blockModels: new Map((opts.blockModels ?? []).map((m) => [m.slug, m])),
2957
+ plans: opts.plans
2958
+ };
2959
+ const nodes = component.props.map(readProp);
2960
+ const fieldsets = [];
2961
+ const order = /* @__PURE__ */ new Map();
2962
+ const visit = (list, at) => list.forEach((n, i) => {
2963
+ const g = n.ui.group;
2964
+ if (g && !fieldsets.some((s) => s.name === g.id)) {
2965
+ const fs = {
2966
+ name: g.id,
2967
+ title: g.label ?? g.id
2968
+ };
2969
+ if (g.description !== void 0) fs.description = g.description;
2970
+ if (g.collapsed !== void 0) fs.collapsed = g.collapsed;
2971
+ if (g.columns !== void 0) fs.columns = g.columns;
2972
+ if (g.collapsible !== void 0) fs.collapsible = g.collapsible;
2973
+ if (g.layout !== void 0) fs.layout = g.layout;
2974
+ if (typeof g.order === "number") order.set(g.id, g.order);
2975
+ if (g.kind === "row") ctx.onLoss(`${at}/${i}/ui/group/kind`, "fieldset row", "V2 has no row fieldset; it reads as a section.");
2976
+ if (g.icon !== void 0) ctx.onLoss(`${at}/${i}/ui/group/icon`, "fieldset icon", "V2 sections have no icon.");
2977
+ fieldsets.push(fs);
2978
+ }
2979
+ if (n.fields) visit(n.fields, `${at}/${i}/fields`);
2980
+ });
2981
+ visit(nodes, "/fields");
2982
+ if (order.size) {
2983
+ const at = new Map(fieldsets.map((s, i) => [s.name, i]));
2984
+ fieldsets.sort((a, b) => (order.get(a.name) ?? at.get(a.name)) - (order.get(b.name) ?? at.get(b.name)));
2985
+ }
2986
+ const groups = [];
2987
+ const tabOrder = /* @__PURE__ */ new Map();
2988
+ for (const t of [...nodes.map((n) => n.ui.tab), ...component.tabs ?? []]) {
2989
+ if (!t || groups.some((g) => g.name === t.id)) continue;
2990
+ const g = {
2991
+ name: t.id,
2992
+ title: t.label ?? t.id
2993
+ };
2994
+ if (t.icon) g.icon = tablerIconOf(t.icon);
2995
+ if (typeof t.order === "number") tabOrder.set(t.id, t.order);
2996
+ groups.push(g);
2997
+ }
2998
+ if (tabOrder.size) {
2999
+ const at = new Map(groups.map((g, i) => [g.name, i]));
3000
+ groups.sort((a, b) => (tabOrder.get(a.name) ?? at.get(a.name)) - (tabOrder.get(b.name) ?? at.get(b.name)));
3001
+ }
3002
+ if (groups.length) groups[0].default = true;
3003
+ const out = {
3004
+ name: camel(component.slug),
3005
+ title: component.name,
3006
+ kind: "block",
3007
+ fields: nodes.map((n, i) => readToV2(n, `/fields/${i}`, nodes, ctx, true, "props"))
3008
+ };
3009
+ if (component.description !== void 0 && component.description !== null) out.description = component.description;
3010
+ if (component.category !== void 0 && component.category !== "custom") out.category = capitalize(component.category);
3011
+ if (component.icon) out.icon = tablerIconOf(component.icon);
3012
+ if (component.preview) out.preview = previewFromProd(component.preview, nodes);
3013
+ if (fieldsets.length) out.fieldsets = fieldsets;
3014
+ if (groups.length) out.groups = groups;
3015
+ return out;
3016
+ }
3017
+ //#endregion
3018
+ export { CATEGORY_TO_PROD, SHOPIFY_REF_LOCK, fromTypeSchema, leafValuePlan, planFromProd, planToProd, propsToTypeSchema, schemaSlugOf, toTypeSchema };
3019
+
3020
+ //# sourceMappingURL=schema.js.map