@es-joy/jsoe 0.24.3 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (524) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.ncurc.cjs +2 -2
  3. package/CHANGES.md +51 -0
  4. package/README.md +23 -13
  5. package/badges/coverage-badge.svg +1 -1
  6. package/dist/eslint.config.d.ts +3 -0
  7. package/dist/eslint.config.d.ts.map +1 -0
  8. package/dist/formatAndTypeChoices.d.ts +28 -30
  9. package/dist/formatAndTypeChoices.d.ts.map +1 -1
  10. package/dist/formats/indexedDBKey.d.ts.map +1 -1
  11. package/dist/formats/schema.d.ts +46 -3
  12. package/dist/formats/schema.d.ts.map +1 -1
  13. package/dist/formats/structuredCloning.d.ts +3 -0
  14. package/dist/formats/structuredCloning.d.ts.map +1 -1
  15. package/dist/formats.d.ts +24 -6
  16. package/dist/formats.d.ts.map +1 -1
  17. package/dist/fundamentalTypes/BooleanObjectType.d.ts.map +1 -1
  18. package/dist/fundamentalTypes/NumberObjectType.d.ts.map +1 -1
  19. package/dist/fundamentalTypes/StringObjectType.d.ts.map +1 -1
  20. package/dist/fundamentalTypes/arrayReferenceType.d.ts.map +1 -1
  21. package/dist/fundamentalTypes/arrayType.d.ts +7 -0
  22. package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
  23. package/dist/fundamentalTypes/bigintObjectType.d.ts.map +1 -1
  24. package/dist/fundamentalTypes/bigintType.d.ts +10 -0
  25. package/dist/fundamentalTypes/bigintType.d.ts.map +1 -1
  26. package/dist/fundamentalTypes/blobType.d.ts.map +1 -1
  27. package/dist/fundamentalTypes/booleanType.d.ts.map +1 -1
  28. package/dist/fundamentalTypes/catchType.d.ts +2 -2
  29. package/dist/fundamentalTypes/catchType.d.ts.map +1 -1
  30. package/dist/fundamentalTypes/dateType.d.ts.map +1 -1
  31. package/dist/fundamentalTypes/domexceptionType.d.ts.map +1 -1
  32. package/dist/fundamentalTypes/enumType.d.ts +2 -2
  33. package/dist/fundamentalTypes/enumType.d.ts.map +1 -1
  34. package/dist/fundamentalTypes/errorType.d.ts.map +1 -1
  35. package/dist/fundamentalTypes/fileType.d.ts +6 -0
  36. package/dist/fundamentalTypes/fileType.d.ts.map +1 -1
  37. package/dist/fundamentalTypes/functionType.d.ts.map +1 -1
  38. package/dist/fundamentalTypes/literalType.d.ts +3 -2
  39. package/dist/fundamentalTypes/literalType.d.ts.map +1 -1
  40. package/dist/fundamentalTypes/looseRecordType.d.ts +6 -0
  41. package/dist/fundamentalTypes/looseRecordType.d.ts.map +1 -0
  42. package/dist/fundamentalTypes/nanType.d.ts.map +1 -1
  43. package/dist/fundamentalTypes/neverType.d.ts +2 -2
  44. package/dist/fundamentalTypes/neverType.d.ts.map +1 -1
  45. package/dist/fundamentalTypes/noneditableType.d.ts.map +1 -1
  46. package/dist/fundamentalTypes/nullType.d.ts.map +1 -1
  47. package/dist/fundamentalTypes/numberType.d.ts.map +1 -1
  48. package/dist/fundamentalTypes/promiseType.d.ts.map +1 -1
  49. package/dist/fundamentalTypes/regexpType.d.ts.map +1 -1
  50. package/dist/fundamentalTypes/stringType.d.ts.map +1 -1
  51. package/dist/fundamentalTypes/symbolType.d.ts.map +1 -1
  52. package/dist/fundamentalTypes/undefinedType.d.ts.map +1 -1
  53. package/dist/fundamentalTypes/voidType.d.ts +2 -2
  54. package/dist/fundamentalTypes/voidType.d.ts.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +6 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/rollup.config.d.ts +30 -0
  59. package/dist/rollup.config.d.ts.map +1 -0
  60. package/dist/server.d.ts +2 -0
  61. package/dist/server.d.ts.map +1 -0
  62. package/dist/src/formatAndTypeChoices.d.ts +108 -0
  63. package/dist/src/formatAndTypeChoices.d.ts.map +1 -0
  64. package/dist/src/formats/arbitraryJS.d.ts +4 -0
  65. package/dist/src/formats/arbitraryJS.d.ts.map +1 -0
  66. package/dist/src/formats/indexedDBKey.d.ts +4 -0
  67. package/dist/src/formats/indexedDBKey.d.ts.map +1 -0
  68. package/dist/src/formats/json.d.ts +4 -0
  69. package/dist/src/formats/json.d.ts.map +1 -0
  70. package/dist/src/formats/schema.d.ts +17 -0
  71. package/dist/src/formats/schema.d.ts.map +1 -0
  72. package/dist/src/formats/structuredCloning.d.ts +19 -0
  73. package/dist/src/formats/structuredCloning.d.ts.map +1 -0
  74. package/dist/src/formats.d.ts +135 -0
  75. package/dist/src/formats.d.ts.map +1 -0
  76. package/dist/src/fundamentalTypes/BooleanObjectType.d.ts +8 -0
  77. package/dist/src/fundamentalTypes/BooleanObjectType.d.ts.map +1 -0
  78. package/dist/src/fundamentalTypes/NumberObjectType.d.ts +6 -0
  79. package/dist/src/fundamentalTypes/NumberObjectType.d.ts.map +1 -0
  80. package/dist/src/fundamentalTypes/StringObjectType.d.ts +6 -0
  81. package/dist/src/fundamentalTypes/StringObjectType.d.ts.map +1 -0
  82. package/dist/src/fundamentalTypes/arrayReferenceType.d.ts +8 -0
  83. package/dist/src/fundamentalTypes/arrayReferenceType.d.ts.map +1 -0
  84. package/dist/src/fundamentalTypes/arrayType.d.ts +29 -0
  85. package/dist/src/fundamentalTypes/arrayType.d.ts.map +1 -0
  86. package/dist/src/fundamentalTypes/bigintObjectType.d.ts +6 -0
  87. package/dist/src/fundamentalTypes/bigintObjectType.d.ts.map +1 -0
  88. package/dist/src/fundamentalTypes/bigintType.d.ts +6 -0
  89. package/dist/src/fundamentalTypes/bigintType.d.ts.map +1 -0
  90. package/dist/src/fundamentalTypes/blobType.d.ts +11 -0
  91. package/dist/src/fundamentalTypes/blobType.d.ts.map +1 -0
  92. package/dist/src/fundamentalTypes/booleanType.d.ts +8 -0
  93. package/dist/src/fundamentalTypes/booleanType.d.ts.map +1 -0
  94. package/dist/src/fundamentalTypes/catchType.d.ts +6 -0
  95. package/dist/src/fundamentalTypes/catchType.d.ts.map +1 -0
  96. package/dist/src/fundamentalTypes/dateType.d.ts +26 -0
  97. package/dist/src/fundamentalTypes/dateType.d.ts.map +1 -0
  98. package/dist/src/fundamentalTypes/domexceptionType.d.ts +6 -0
  99. package/dist/src/fundamentalTypes/domexceptionType.d.ts.map +1 -0
  100. package/dist/src/fundamentalTypes/enumType.d.ts +6 -0
  101. package/dist/src/fundamentalTypes/enumType.d.ts.map +1 -0
  102. package/dist/src/fundamentalTypes/errorType.d.ts +6 -0
  103. package/dist/src/fundamentalTypes/errorType.d.ts.map +1 -0
  104. package/dist/src/fundamentalTypes/fileType.d.ts +13 -0
  105. package/dist/src/fundamentalTypes/fileType.d.ts.map +1 -0
  106. package/dist/src/fundamentalTypes/filelistType.d.ts +6 -0
  107. package/dist/src/fundamentalTypes/filelistType.d.ts.map +1 -0
  108. package/dist/src/fundamentalTypes/functionType.d.ts +7 -0
  109. package/dist/src/fundamentalTypes/functionType.d.ts.map +1 -0
  110. package/dist/src/fundamentalTypes/literalType.d.ts +6 -0
  111. package/dist/src/fundamentalTypes/literalType.d.ts.map +1 -0
  112. package/dist/src/fundamentalTypes/mapType.d.ts +6 -0
  113. package/dist/src/fundamentalTypes/mapType.d.ts.map +1 -0
  114. package/dist/src/fundamentalTypes/nanType.d.ts +6 -0
  115. package/dist/src/fundamentalTypes/nanType.d.ts.map +1 -0
  116. package/dist/src/fundamentalTypes/neverType.d.ts +6 -0
  117. package/dist/src/fundamentalTypes/neverType.d.ts.map +1 -0
  118. package/dist/src/fundamentalTypes/noneditableType.d.ts +6 -0
  119. package/dist/src/fundamentalTypes/noneditableType.d.ts.map +1 -0
  120. package/dist/src/fundamentalTypes/nullType.d.ts +6 -0
  121. package/dist/src/fundamentalTypes/nullType.d.ts.map +1 -0
  122. package/dist/src/fundamentalTypes/numberType.d.ts +6 -0
  123. package/dist/src/fundamentalTypes/numberType.d.ts.map +1 -0
  124. package/dist/src/fundamentalTypes/objectReferenceType.d.ts +8 -0
  125. package/dist/src/fundamentalTypes/objectReferenceType.d.ts.map +1 -0
  126. package/dist/src/fundamentalTypes/objectType.d.ts +6 -0
  127. package/dist/src/fundamentalTypes/objectType.d.ts.map +1 -0
  128. package/dist/src/fundamentalTypes/promiseType.d.ts +6 -0
  129. package/dist/src/fundamentalTypes/promiseType.d.ts.map +1 -0
  130. package/dist/src/fundamentalTypes/recordType.d.ts +6 -0
  131. package/dist/src/fundamentalTypes/recordType.d.ts.map +1 -0
  132. package/dist/src/fundamentalTypes/regexpType.d.ts +8 -0
  133. package/dist/src/fundamentalTypes/regexpType.d.ts.map +1 -0
  134. package/dist/src/fundamentalTypes/setType.d.ts +6 -0
  135. package/dist/src/fundamentalTypes/setType.d.ts.map +1 -0
  136. package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts +6 -0
  137. package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -0
  138. package/dist/src/fundamentalTypes/stringType.d.ts +6 -0
  139. package/dist/src/fundamentalTypes/stringType.d.ts.map +1 -0
  140. package/dist/src/fundamentalTypes/symbolType.d.ts +8 -0
  141. package/dist/src/fundamentalTypes/symbolType.d.ts.map +1 -0
  142. package/dist/src/fundamentalTypes/tupleType.d.ts +6 -0
  143. package/dist/src/fundamentalTypes/tupleType.d.ts.map +1 -0
  144. package/dist/src/fundamentalTypes/undefinedType.d.ts +6 -0
  145. package/dist/src/fundamentalTypes/undefinedType.d.ts.map +1 -0
  146. package/dist/src/fundamentalTypes/voidType.d.ts +6 -0
  147. package/dist/src/fundamentalTypes/voidType.d.ts.map +1 -0
  148. package/dist/src/index.d.ts +12 -0
  149. package/dist/src/index.d.ts.map +1 -0
  150. package/dist/src/subTypes/blobHTMLType.d.ts +20 -0
  151. package/dist/src/subTypes/blobHTMLType.d.ts.map +1 -0
  152. package/dist/src/subTypes/falseType.d.ts +8 -0
  153. package/dist/src/subTypes/falseType.d.ts.map +1 -0
  154. package/dist/src/subTypes/trueType.d.ts +8 -0
  155. package/dist/src/subTypes/trueType.d.ts.map +1 -0
  156. package/dist/src/superTypes/SpecialNumberType.d.ts +6 -0
  157. package/dist/src/superTypes/SpecialNumberType.d.ts.map +1 -0
  158. package/dist/src/superTypes/SpecialRealNumberType.d.ts +6 -0
  159. package/dist/src/superTypes/SpecialRealNumberType.d.ts.map +1 -0
  160. package/dist/src/superTypes/buffersourceType.d.ts +8 -0
  161. package/dist/src/superTypes/buffersourceType.d.ts.map +1 -0
  162. package/dist/src/superTypes/dommatrixType.d.ts +6 -0
  163. package/dist/src/superTypes/dommatrixType.d.ts.map +1 -0
  164. package/dist/src/superTypes/dompointType.d.ts +6 -0
  165. package/dist/src/superTypes/dompointType.d.ts.map +1 -0
  166. package/dist/src/superTypes/domrectType.d.ts +6 -0
  167. package/dist/src/superTypes/domrectType.d.ts.map +1 -0
  168. package/dist/src/superTypes/errorsSpecialType.d.ts +8 -0
  169. package/dist/src/superTypes/errorsSpecialType.d.ts.map +1 -0
  170. package/dist/src/typeChoices.d.ts +140 -0
  171. package/dist/src/typeChoices.d.ts.map +1 -0
  172. package/dist/src/types.d.ts +758 -0
  173. package/dist/src/types.d.ts.map +1 -0
  174. package/dist/src/utils/FileList.d.ts +26 -0
  175. package/dist/src/utils/FileList.d.ts.map +1 -0
  176. package/dist/src/utils/dialogs.d.ts +111 -0
  177. package/dist/src/utils/dialogs.d.ts.map +1 -0
  178. package/dist/src/utils/jsonPointer.d.ts +46 -0
  179. package/dist/src/utils/jsonPointer.d.ts.map +1 -0
  180. package/dist/src/utils/media.d.ts +18 -0
  181. package/dist/src/utils/media.d.ts.map +1 -0
  182. package/dist/src/utils/objects.d.ts +16 -0
  183. package/dist/src/utils/objects.d.ts.map +1 -0
  184. package/dist/src/utils/templateUtils.d.ts +59 -0
  185. package/dist/src/utils/templateUtils.d.ts.map +1 -0
  186. package/dist/src/utils/types.d.ts +2 -0
  187. package/dist/src/utils/types.d.ts.map +1 -0
  188. package/dist/src/vendor-imports.d.ts +4 -0
  189. package/dist/src/vendor-imports.d.ts.map +1 -0
  190. package/dist/subTypes/blobHTMLType.d.ts.map +1 -1
  191. package/dist/superTypes/SpecialRealNumberType.d.ts.map +1 -1
  192. package/dist/superTypes/buffersourceType.d.ts.map +1 -1
  193. package/dist/superTypes/dommatrixType.d.ts.map +1 -1
  194. package/dist/superTypes/dompointType.d.ts.map +1 -1
  195. package/dist/superTypes/domrectType.d.ts.map +1 -1
  196. package/dist/superTypes/errorsSpecialType.d.ts.map +1 -1
  197. package/dist/typeChoices.d.ts +21 -87
  198. package/dist/typeChoices.d.ts.map +1 -1
  199. package/dist/types.d.ts +90 -64
  200. package/dist/types.d.ts.map +1 -1
  201. package/dist/utils/FileList.d.ts +4 -3
  202. package/dist/utils/FileList.d.ts.map +1 -1
  203. package/dist/utils/dialogs.d.ts +4 -4
  204. package/dist/utils/dialogs.d.ts.map +1 -1
  205. package/dist/utils/media.d.ts.map +1 -1
  206. package/dist/utils/schemaMeta.d.ts +92 -0
  207. package/dist/utils/schemaMeta.d.ts.map +1 -0
  208. package/dist/utils/templateUtils.d.ts +3 -3
  209. package/dist/utils/templateUtils.d.ts.map +1 -1
  210. package/dist/utils/timing.d.ts +2 -0
  211. package/dist/utils/timing.d.ts.map +1 -0
  212. package/dist/utils/types.d.ts +1 -0
  213. package/dist/utils/types.d.ts.map +1 -1
  214. package/dist/vendor-imports.d.ts +3 -1
  215. package/docs/proposals/schema-meta.md +233 -0
  216. package/eslint.config.js +51 -4
  217. package/licenseInfo.json +1 -1
  218. package/package.json +52 -42
  219. package/pnpm-workspace.yaml +57 -0
  220. package/rollup.config.js +20 -18
  221. package/server.js +3 -3
  222. package/src/deepEqual.js.map +1 -1
  223. package/src/formatAndTypeChoices.js +62 -58
  224. package/src/formats/indexedDBKey.js +3 -4
  225. package/src/formats/schema.js +824 -475
  226. package/src/formats/structuredCloning.js +189 -79
  227. package/src/formats.js +17 -5
  228. package/src/fundamentalTypes/BooleanObjectType.js +4 -5
  229. package/src/fundamentalTypes/NumberObjectType.js +4 -4
  230. package/src/fundamentalTypes/StringObjectType.js +3 -4
  231. package/src/fundamentalTypes/arrayReferenceType.js +0 -2
  232. package/src/fundamentalTypes/arrayType.js +624 -389
  233. package/src/fundamentalTypes/bigintObjectType.js +3 -2
  234. package/src/fundamentalTypes/bigintType.js +79 -17
  235. package/src/fundamentalTypes/blobType.js +35 -35
  236. package/src/fundamentalTypes/booleanType.js +16 -8
  237. package/src/fundamentalTypes/dateType.js +6 -8
  238. package/src/fundamentalTypes/domexceptionType.js +5 -4
  239. package/src/fundamentalTypes/errorType.js +39 -32
  240. package/src/fundamentalTypes/fileType.js +238 -52
  241. package/src/fundamentalTypes/functionType.js +61 -41
  242. package/src/fundamentalTypes/nanType.js +5 -4
  243. package/src/fundamentalTypes/noneditableType.js +4 -3
  244. package/src/fundamentalTypes/nullType.js +3 -2
  245. package/src/fundamentalTypes/numberType.js +72 -20
  246. package/src/fundamentalTypes/promiseType.js +16 -40
  247. package/src/fundamentalTypes/regexpType.js +7 -13
  248. package/src/fundamentalTypes/stringType.js +176 -110
  249. package/src/fundamentalTypes/symbolType.js +3 -2
  250. package/src/fundamentalTypes/undefinedType.js +3 -2
  251. package/src/index.js +6 -5
  252. package/src/jsoe.css +107 -8
  253. package/src/subTypes/blobHTMLType.js +23 -10
  254. package/src/superTypes/SpecialNumberType.js +6 -6
  255. package/src/superTypes/SpecialRealNumberType.js +10 -9
  256. package/src/superTypes/buffersourceType.js +86 -75
  257. package/src/superTypes/dommatrixType.js +6 -5
  258. package/src/superTypes/dompointType.js +6 -5
  259. package/src/superTypes/domrectType.js +6 -5
  260. package/src/superTypes/errorsSpecialType.js +54 -35
  261. package/src/typeChoices.js +399 -54
  262. package/src/types.js +157 -97
  263. package/src/utils/FileList.js +3 -3
  264. package/src/utils/dialogs.js +5 -7
  265. package/src/utils/jsonPointer.js +1 -1
  266. package/src/utils/media.js +1 -0
  267. package/src/utils/schemaMeta.js +257 -0
  268. package/src/utils/templateUtils.js +3 -3
  269. package/src/utils/timing.js +12 -0
  270. package/src/utils/types.js +19 -0
  271. package/src/vendor-imports.js +10 -2
  272. package/tsconfig.json +2 -0
  273. package/vendor/acorn/dist/acorn.d.mts +46 -5
  274. package/vendor/acorn/dist/acorn.d.ts +46 -5
  275. package/vendor/acorn/dist/acorn.js +394 -117
  276. package/vendor/acorn/dist/acorn.mjs +394 -117
  277. package/vendor/acorn/dist/bin.js +1 -1
  278. package/vendor/jamilih/dist/{jml-es.js → jml.mjs} +590 -312
  279. package/vendor/jamilih/package.json +1 -1
  280. package/vendor/mime/dist/types/other.js +719 -0
  281. package/vendor/mime/dist/types/standard.js +366 -0
  282. package/vendor/typeson-registry/dist/index.js +519 -99
  283. package/vendor/zod/classic/checks.d.ts +1 -0
  284. package/vendor/zod/classic/checks.js +1 -0
  285. package/vendor/zod/classic/coerce.d.ts +17 -0
  286. package/vendor/zod/classic/coerce.js +17 -0
  287. package/vendor/zod/classic/compat.d.ts +48 -0
  288. package/vendor/zod/classic/compat.js +31 -0
  289. package/vendor/zod/classic/deep-partial.d.ts +14 -0
  290. package/vendor/zod/classic/deep-partial.js +13 -0
  291. package/vendor/zod/classic/errors.d.ts +29 -0
  292. package/vendor/zod/classic/errors.js +57 -0
  293. package/vendor/zod/classic/external.d.ts +19 -0
  294. package/vendor/zod/classic/external.js +17 -0
  295. package/vendor/zod/classic/from-json-schema.d.ts +12 -0
  296. package/vendor/zod/classic/from-json-schema.js +660 -0
  297. package/vendor/zod/classic/in-out.d.ts +8 -0
  298. package/vendor/zod/classic/in-out.js +36 -0
  299. package/vendor/zod/classic/index.d.ts +3 -0
  300. package/vendor/zod/classic/index.js +4 -0
  301. package/vendor/zod/classic/iso.d.ts +7 -0
  302. package/vendor/zod/classic/iso.js +15 -0
  303. package/vendor/zod/classic/package.json +7 -0
  304. package/vendor/zod/classic/parse.d.ts +44 -0
  305. package/vendor/zod/classic/parse.js +16 -0
  306. package/vendor/zod/classic/schemas.d.ts +802 -0
  307. package/vendor/zod/classic/schemas.js +1491 -0
  308. package/vendor/zod/core/api.d.ts +329 -0
  309. package/vendor/zod/core/api.js +1104 -0
  310. package/vendor/zod/core/checks.d.ts +278 -0
  311. package/vendor/zod/core/checks.js +581 -0
  312. package/vendor/zod/core/compile.d.ts +51 -0
  313. package/vendor/zod/core/compile.js +1783 -0
  314. package/vendor/zod/core/core.d.ts +82 -0
  315. package/vendor/zod/core/core.js +141 -0
  316. package/vendor/zod/core/doc.d.ts +16 -0
  317. package/vendor/zod/core/doc.js +33 -0
  318. package/vendor/zod/core/errors.d.ts +225 -0
  319. package/vendor/zod/core/errors.js +270 -0
  320. package/vendor/zod/core/index.d.ts +19 -0
  321. package/vendor/zod/core/index.js +19 -0
  322. package/vendor/zod/core/json-schema-generator.d.ts +65 -0
  323. package/vendor/zod/core/json-schema-generator.js +99 -0
  324. package/vendor/zod/core/json-schema-processors.d.ts +49 -0
  325. package/vendor/zod/core/json-schema-processors.js +747 -0
  326. package/vendor/zod/core/json-schema.d.ts +89 -0
  327. package/vendor/zod/core/memoizer.d.ts +15 -0
  328. package/vendor/zod/core/memoizer.js +265 -0
  329. package/vendor/zod/core/package.json +7 -0
  330. package/vendor/zod/core/parse.d.ts +52 -0
  331. package/vendor/zod/core/parse.js +154 -0
  332. package/vendor/zod/core/regexes.d.ts +87 -0
  333. package/vendor/zod/core/regexes.js +150 -0
  334. package/vendor/zod/core/registries.d.ts +35 -0
  335. package/vendor/zod/core/registries.js +51 -0
  336. package/vendor/zod/core/schemas.d.ts +1253 -0
  337. package/vendor/zod/core/schemas.js +2440 -0
  338. package/vendor/zod/core/standard-schema.d.ts +126 -0
  339. package/vendor/zod/core/to-json-schema.d.ts +153 -0
  340. package/vendor/zod/core/to-json-schema.js +650 -0
  341. package/vendor/zod/core/util.d.ts +257 -0
  342. package/vendor/zod/core/util.js +846 -0
  343. package/vendor/zod/core/versions.d.ts +5 -0
  344. package/vendor/zod/core/versions.js +5 -0
  345. package/vendor/zod/core/visit.d.ts +30 -0
  346. package/vendor/zod/core/visit.js +169 -0
  347. package/vendor/zod/index.d.ts +3 -0
  348. package/vendor/zod/index.js +4 -0
  349. package/vendor/zod/locales/ar.d.ts +4 -0
  350. package/vendor/zod/locales/ar.js +109 -0
  351. package/vendor/zod/locales/az.d.ts +4 -0
  352. package/vendor/zod/locales/az.js +108 -0
  353. package/vendor/zod/locales/be.d.ts +4 -0
  354. package/vendor/zod/locales/be.js +166 -0
  355. package/vendor/zod/locales/bg.d.ts +4 -0
  356. package/vendor/zod/locales/bg.js +123 -0
  357. package/vendor/zod/locales/bn.d.ts +4 -0
  358. package/vendor/zod/locales/bn.js +111 -0
  359. package/vendor/zod/locales/ca.d.ts +4 -0
  360. package/vendor/zod/locales/ca.js +110 -0
  361. package/vendor/zod/locales/ckb.d.ts +4 -0
  362. package/vendor/zod/locales/ckb.js +131 -0
  363. package/vendor/zod/locales/cs.d.ts +4 -0
  364. package/vendor/zod/locales/cs.js +114 -0
  365. package/vendor/zod/locales/da.d.ts +4 -0
  366. package/vendor/zod/locales/da.js +118 -0
  367. package/vendor/zod/locales/de.d.ts +4 -0
  368. package/vendor/zod/locales/de.js +111 -0
  369. package/vendor/zod/locales/el.d.ts +4 -0
  370. package/vendor/zod/locales/el.js +110 -0
  371. package/vendor/zod/locales/en.d.ts +4 -0
  372. package/vendor/zod/locales/en.js +123 -0
  373. package/vendor/zod/locales/eo.d.ts +4 -0
  374. package/vendor/zod/locales/eo.js +112 -0
  375. package/vendor/zod/locales/es.d.ts +4 -0
  376. package/vendor/zod/locales/es.js +134 -0
  377. package/vendor/zod/locales/fa.d.ts +4 -0
  378. package/vendor/zod/locales/fa.js +117 -0
  379. package/vendor/zod/locales/fi.d.ts +4 -0
  380. package/vendor/zod/locales/fi.js +115 -0
  381. package/vendor/zod/locales/fr-CA.d.ts +4 -0
  382. package/vendor/zod/locales/fr-CA.js +110 -0
  383. package/vendor/zod/locales/fr.d.ts +4 -0
  384. package/vendor/zod/locales/fr.js +127 -0
  385. package/vendor/zod/locales/gu.d.ts +4 -0
  386. package/vendor/zod/locales/gu.js +111 -0
  387. package/vendor/zod/locales/he.d.ts +4 -0
  388. package/vendor/zod/locales/he.js +219 -0
  389. package/vendor/zod/locales/hi.d.ts +4 -0
  390. package/vendor/zod/locales/hi.js +109 -0
  391. package/vendor/zod/locales/hr.d.ts +4 -0
  392. package/vendor/zod/locales/hr.js +124 -0
  393. package/vendor/zod/locales/hu.d.ts +4 -0
  394. package/vendor/zod/locales/hu.js +111 -0
  395. package/vendor/zod/locales/hy.d.ts +4 -0
  396. package/vendor/zod/locales/hy.js +156 -0
  397. package/vendor/zod/locales/id.d.ts +4 -0
  398. package/vendor/zod/locales/id.js +109 -0
  399. package/vendor/zod/locales/index.d.ts +62 -0
  400. package/vendor/zod/locales/index.js +62 -0
  401. package/vendor/zod/locales/is.d.ts +4 -0
  402. package/vendor/zod/locales/is.js +112 -0
  403. package/vendor/zod/locales/it.d.ts +4 -0
  404. package/vendor/zod/locales/it.js +111 -0
  405. package/vendor/zod/locales/ja.d.ts +4 -0
  406. package/vendor/zod/locales/ja.js +110 -0
  407. package/vendor/zod/locales/ka.d.ts +4 -0
  408. package/vendor/zod/locales/ka.js +115 -0
  409. package/vendor/zod/locales/kh.d.ts +5 -0
  410. package/vendor/zod/locales/kh.js +5 -0
  411. package/vendor/zod/locales/km.d.ts +4 -0
  412. package/vendor/zod/locales/km.js +113 -0
  413. package/vendor/zod/locales/kn.d.ts +4 -0
  414. package/vendor/zod/locales/kn.js +114 -0
  415. package/vendor/zod/locales/ko.d.ts +4 -0
  416. package/vendor/zod/locales/ko.js +114 -0
  417. package/vendor/zod/locales/lt.d.ts +4 -0
  418. package/vendor/zod/locales/lt.js +205 -0
  419. package/vendor/zod/locales/mk.d.ts +4 -0
  420. package/vendor/zod/locales/mk.js +112 -0
  421. package/vendor/zod/locales/ms.d.ts +4 -0
  422. package/vendor/zod/locales/ms.js +110 -0
  423. package/vendor/zod/locales/ne.d.ts +4 -0
  424. package/vendor/zod/locales/ne.js +109 -0
  425. package/vendor/zod/locales/nl.d.ts +4 -0
  426. package/vendor/zod/locales/nl.js +113 -0
  427. package/vendor/zod/locales/nn.d.ts +4 -0
  428. package/vendor/zod/locales/nn.js +111 -0
  429. package/vendor/zod/locales/no.d.ts +4 -0
  430. package/vendor/zod/locales/no.js +111 -0
  431. package/vendor/zod/locales/ota.d.ts +4 -0
  432. package/vendor/zod/locales/ota.js +112 -0
  433. package/vendor/zod/locales/package.json +7 -0
  434. package/vendor/zod/locales/pl.d.ts +4 -0
  435. package/vendor/zod/locales/pl.js +112 -0
  436. package/vendor/zod/locales/ps.d.ts +4 -0
  437. package/vendor/zod/locales/ps.js +117 -0
  438. package/vendor/zod/locales/pt-BR.d.ts +4 -0
  439. package/vendor/zod/locales/pt-BR.js +141 -0
  440. package/vendor/zod/locales/pt.d.ts +4 -0
  441. package/vendor/zod/locales/pt.js +140 -0
  442. package/vendor/zod/locales/ro.d.ts +4 -0
  443. package/vendor/zod/locales/ro.js +120 -0
  444. package/vendor/zod/locales/ru.d.ts +4 -0
  445. package/vendor/zod/locales/ru.js +166 -0
  446. package/vendor/zod/locales/sk.d.ts +4 -0
  447. package/vendor/zod/locales/sk.js +114 -0
  448. package/vendor/zod/locales/sl.d.ts +4 -0
  449. package/vendor/zod/locales/sl.js +112 -0
  450. package/vendor/zod/locales/sv.d.ts +4 -0
  451. package/vendor/zod/locales/sv.js +113 -0
  452. package/vendor/zod/locales/ta.d.ts +4 -0
  453. package/vendor/zod/locales/ta.js +113 -0
  454. package/vendor/zod/locales/th.d.ts +4 -0
  455. package/vendor/zod/locales/th.js +113 -0
  456. package/vendor/zod/locales/tk.d.ts +4 -0
  457. package/vendor/zod/locales/tk.js +105 -0
  458. package/vendor/zod/locales/tr.d.ts +4 -0
  459. package/vendor/zod/locales/tr.js +108 -0
  460. package/vendor/zod/locales/ua.d.ts +5 -0
  461. package/vendor/zod/locales/ua.js +5 -0
  462. package/vendor/zod/locales/uk.d.ts +4 -0
  463. package/vendor/zod/locales/uk.js +111 -0
  464. package/vendor/zod/locales/ur.d.ts +4 -0
  465. package/vendor/zod/locales/ur.js +113 -0
  466. package/vendor/zod/locales/uz.d.ts +4 -0
  467. package/vendor/zod/locales/uz.js +111 -0
  468. package/vendor/zod/locales/vi.d.ts +4 -0
  469. package/vendor/zod/locales/vi.js +111 -0
  470. package/vendor/zod/locales/yo.d.ts +4 -0
  471. package/vendor/zod/locales/yo.js +110 -0
  472. package/vendor/zod/locales/zh-CN.d.ts +4 -0
  473. package/vendor/zod/locales/zh-CN.js +112 -0
  474. package/vendor/zod/locales/zh-TW.d.ts +4 -0
  475. package/vendor/zod/locales/zh-TW.js +110 -0
  476. package/vendor/zod/mini/checks.d.ts +1 -0
  477. package/vendor/zod/mini/checks.js +1 -0
  478. package/vendor/zod/mini/coerce.d.ts +7 -0
  479. package/vendor/zod/mini/coerce.js +22 -0
  480. package/vendor/zod/mini/deep-partial.d.ts +14 -0
  481. package/vendor/zod/mini/deep-partial.js +13 -0
  482. package/vendor/zod/mini/external.d.ts +16 -0
  483. package/vendor/zod/mini/external.js +16 -0
  484. package/vendor/zod/mini/in-out.d.ts +8 -0
  485. package/vendor/zod/mini/in-out.js +36 -0
  486. package/vendor/zod/mini/index.d.ts +3 -0
  487. package/vendor/zod/mini/index.js +3 -0
  488. package/vendor/zod/mini/iso.d.ts +22 -0
  489. package/vendor/zod/mini/iso.js +34 -0
  490. package/vendor/zod/mini/package.json +7 -0
  491. package/vendor/zod/mini/parse.d.ts +1 -0
  492. package/vendor/zod/mini/parse.js +1 -0
  493. package/vendor/zod/mini/schemas.d.ts +475 -0
  494. package/vendor/zod/mini/schemas.js +987 -0
  495. package/vendor/zod/package.json +7 -0
  496. package/vendor/zodexy/dist/esm/index.js +1274 -0
  497. package/vendor/zodexy/dist/index.js +1088 -0
  498. package/vendor/zodexy/dist/schema.zodexy.json +1036 -0
  499. package/dist/fundamentalTypes/nativeEnumType.d.ts +0 -6
  500. package/dist/fundamentalTypes/nativeEnumType.d.ts.map +0 -1
  501. package/src/fundamentalTypes/catchType.js +0 -140
  502. package/src/fundamentalTypes/enumType.js +0 -52
  503. package/src/fundamentalTypes/literalType.js +0 -81
  504. package/src/fundamentalTypes/nativeEnumType.js +0 -157
  505. package/src/fundamentalTypes/neverType.js +0 -49
  506. package/src/fundamentalTypes/recordType.js +0 -42
  507. package/src/fundamentalTypes/tupleType.js +0 -39
  508. package/src/fundamentalTypes/voidType.js +0 -48
  509. package/vendor/zod/lib/index.mjs +0 -4236
  510. package/vendor/zodex/dist/esm/dezerialize.d.ts +0 -26
  511. package/vendor/zodex/dist/esm/dezerialize.js +0 -393
  512. package/vendor/zodex/dist/esm/index.d.ts +0 -9
  513. package/vendor/zodex/dist/esm/index.js +0 -4
  514. package/vendor/zodex/dist/esm/infer.d.ts +0 -29
  515. package/vendor/zodex/dist/esm/package.json +0 -1
  516. package/vendor/zodex/dist/esm/types.d.ts +0 -201
  517. package/vendor/zodex/dist/esm/types.js +0 -13
  518. package/vendor/zodex/dist/esm/ui.d.ts +0 -23
  519. package/vendor/zodex/dist/esm/ui.js +0 -10
  520. package/vendor/zodex/dist/esm/zerialize.d.ts +0 -50
  521. package/vendor/zodex/dist/esm/zerialize.js +0 -417
  522. package/vendor/zodex/dist/esm/zod-types.d.ts +0 -11
  523. /package/vendor/{zodex/dist/esm/infer.js → zod/core/json-schema.js} +0 -0
  524. /package/vendor/{zodex/dist/esm/zod-types.js → zod/core/standard-schema.js} +0 -0
@@ -1,15 +1,32 @@
1
1
  import {jml, nbsp} from '../vendor-imports.js';
2
2
 
3
3
  import {getPropertyValueFromLegend} from '../types.js';
4
+ import {recordKeyConforms} from '../formats/schema.js';
4
5
  import {$e, $$e, U, DOM} from '../utils/templateUtils.js';
6
+ import {
7
+ schemaLabel, lastTypeChild, deprecatedClassSuffix
8
+ } from '../utils/schemaMeta.js';
5
9
  import dialogs from '../utils/dialogs.js';
6
10
  import {
7
11
  resolveJSONPointer, getJSONPointerParts, reduceJSONPointerParts
8
12
  } from '../utils/jsonPointer.js';
9
13
  import FileList from '../utils/FileList.js';
14
+ import {isUnionLike} from '../utils/types.js';
10
15
 
11
16
  let optionalPropertyId = 0;
12
17
 
18
+ /**
19
+ * @callback AddAndSetArrayElement
20
+ * @param {{
21
+ * propName: string,
22
+ * type: import('../types.js').AvailableType,
23
+ * value: import('../formats.js').StructuredCloneValue,
24
+ * bringIntoFocus: boolean,
25
+ * schemaContent: import('../formats/schema.js').ZodexSchema,
26
+ * }} cfg
27
+ * @returns {Element}
28
+ */
29
+
13
30
  /**
14
31
  * @typedef {number} Integer
15
32
  */
@@ -111,14 +128,11 @@ const arrayType = {
111
128
  const state = sparse
112
129
  ? 'arrayNonindexKeys'
113
130
  // ? 'sparseArrays'
114
- : (this.array && !this.record ? 'array' : 'object');
131
+ : (this.array ? 'array' : 'object');
115
132
  /** @type {{[key: (string|number)]: any}} */
116
- const retObj = this.array && !this.record ? [] : {};
133
+ const retObj = this.array ? [] : {};
117
134
  /* istanbul ignore next -- Unreachable? */
118
- let stringVal = innerContents !== undefined
119
- ? innerContents
120
- /* istanbul ignore next -- Unreachable? */
121
- : s;
135
+ let stringVal = innerContents;
122
136
 
123
137
  /**
124
138
  * @param {boolean} beginOnly
@@ -141,7 +155,7 @@ const arrayType = {
141
155
  }
142
156
  return false;
143
157
  };
144
- if (this.array && !this.record) {
158
+ if (this.array) {
145
159
  let idx = 0;
146
160
  const parse = () => {
147
161
  if (!stringVal) {
@@ -190,6 +204,7 @@ const arrayType = {
190
204
  : this.map
191
205
  ? new Map(/** @type {Array<any>} */ (retObj))
192
206
  : this.filelist
207
+ // @ts-expect-error -- Virtual API
193
208
  ? new FileList(retObj)
194
209
  : retObj,
195
210
  remnant: stringVal
@@ -212,7 +227,12 @@ const arrayType = {
212
227
  return;
213
228
  }
214
229
  const [, prop, propHadQuotes] = propAndColon;
215
- const pr = prop !== undefined ? prop : propHadQuotes;
230
+ // `prop` (the unquoted-key alternative) is either a non-empty string or
231
+ // `undefined`; when it did not match, the key came in quoted and its
232
+ // text (possibly `''`) is in `propHadQuotes`. A `prop !== ''` test
233
+ // wrongly lets `undefined` through, so a quoted key like `"c"` becomes
234
+ // the string `"undefined"`.
235
+ const pr = prop ?? propHadQuotes;
216
236
  stringVal = stringVal.slice(propAndColon[0].length);
217
237
  let v, beginOnly, assign;
218
238
  try {
@@ -232,7 +252,6 @@ const arrayType = {
232
252
  }
233
253
  // console.log('vvv', stringVal, beginOnly, v);
234
254
  if (assign) {
235
- // eslint-disable-next-line @stylistic/max-len -- Long
236
255
  /** @type {{[key: string]: import('../formats.js').StructuredCloneValue}} */ (
237
256
  retObj
238
257
  )[pr] = v;
@@ -259,21 +278,32 @@ const arrayType = {
259
278
  * $getMapKeySelects: GetMapKeySelects
260
279
  * }}
261
280
  */ ($e(root, '.arrayItems'));
281
+ /* istanbul ignore if -- Async guard */
282
+ if (!arrayItems) {
283
+ // The `.arrayItems` container may not exist yet if `getValue` is
284
+ // reached (e.g. via a synchronous `validate`) before an async
285
+ // `setValue` has finished building the UI.
286
+ throw new Error('Not yet instantiated');
287
+ }
262
288
  const fieldsets = [...arrayItems.children];
263
289
 
290
+ // A `record` schema renders through the `object` type but, like a `Map`,
291
+ // builds its entries from key-type selectors; it is flagged on the root.
292
+ const isRecord = root.dataset.record === 'true';
293
+
264
294
  /**
265
295
  * @type {({[key: string]: any})|any[]}
266
296
  */
267
- const ret = root.dataset.type === 'object'
297
+ const ret = !isRecord && root.dataset.type === 'object'
268
298
  ? {}
269
299
  : !this.sparse
270
300
  ? []
271
- : Array.from({length: Number.parseInt(
301
+ : Array.from({length: Math.trunc(Number(
272
302
  /** @type {HTMLInputElement} */ (DOM.filterChildElements(
273
303
  root,
274
304
  ['div', 'div', 'label', 'input']
275
305
  )[0]).value
276
- )});
306
+ ))});
277
307
 
278
308
  // Todo: Should this be renamed per return arguments to
279
309
  // `getRefOrVal` or is it ok?
@@ -359,6 +389,7 @@ const arrayType = {
359
389
  );
360
390
  }
361
391
  return this.filelist
392
+ // @ts-expect-error -- Virtual API
362
393
  ? new FileList(ret)
363
394
  : this.set && Array.isArray(ret)
364
395
  ? new Set(ret)
@@ -367,13 +398,11 @@ const arrayType = {
367
398
  const key = select.$getValue();
368
399
  return [key, /** @type {any[]} */ (ret)[idx]];
369
400
  }))
370
- : this.record
401
+ : isRecord
371
402
  ? arrayItems.$getMapKeySelects().reduce((obj, select, idx) => {
372
403
  const key = select.$getValue();
373
- const val = /** @type {any[]} */ (ret)[idx];
374
- obj[key] = val;
404
+ obj[key] = /** @type {any[]} */ (ret)[idx];
375
405
  // Todo: Reenable for native enums
376
- // The nature of native enums
377
406
  // if (typeof val === 'number') {
378
407
  // obj[val] = key;
379
408
  // }
@@ -392,6 +421,12 @@ const arrayType = {
392
421
 
393
422
  const parentType = type;
394
423
 
424
+ // `record`/`tuple` are not distinct types; they are `object`/`array` whose
425
+ // associated schema refines them. Detect the refinement from the schema.
426
+ const recordMode = specificSchemaObject?.type === 'record' ||
427
+ specificSchemaObject?.type === 'looseRecord';
428
+ const tupleMode = specificSchemaObject?.type === 'tuple';
429
+
395
430
  /**
396
431
  * @param {{
397
432
  * itemIndex: number,
@@ -404,67 +439,83 @@ const arrayType = {
404
439
  /* className, type, arrayItems, */
405
440
  itemIndex, typeNamespace, propName
406
441
  }) => {
407
- const tupleItem = /** @type {import('zodex').SzTuple} */ (
442
+ const tupleItem = /** @type {import('zodexy').SzTuple} */ (
408
443
  specificSchemaObject
409
444
  )?.items?.[itemIndex];
410
- const restItem = /** @type {import('zodex').SzTuple} */ (
445
+ const restItem = /** @type {import('zodexy').SzTuple} */ (
411
446
  specificSchemaObject
412
447
  )?.rest;
413
448
  return ['legend', [
414
- this.array && type !== 'record'
415
- ? /** @type {import('zodex').SzArray} */ (
449
+ !recordMode && this.array
450
+ ? schemaLabel(/** @type {import('zodexy').SzArray} */ (
416
451
  specificSchemaObject
417
- )?.element?.description ??
418
- ((type === 'set' && /** @type {import('zodex').SzSet} */ (
452
+ )?.element) ??
453
+ ((type === 'set' && schemaLabel(/** @type {import('zodexy').SzSet} */ (
419
454
  specificSchemaObject
420
- )?.value?.description)
421
- ? /** @type {import('zodex').SzSet} */ (
455
+ )?.value))
456
+ ? schemaLabel(/** @type {import('zodexy').SzSet} */ (
422
457
  specificSchemaObject
423
- )?.value?.description
458
+ )?.value)
424
459
  : (
425
- tupleItem?.description ?? restItem?.description
460
+ schemaLabel(tupleItem) ?? schemaLabel(restItem)
426
461
  )) ?? 'Item'
427
462
  : specificSchemaObject ? '' : 'Property',
428
463
  specificSchemaObject ? '' : ':',
429
464
  nbsp.repeat(2),
430
465
  ['span', {
431
466
  class: `propertyName-${typeNamespace}`,
432
- title: type === 'record' && /** @type {import('zodex').SzRecord} */ (
467
+ title: recordMode && schemaLabel(/** @type {import('zodexy').SzRecord} */ (
433
468
  specificSchemaObject
434
- )?.key?.description
435
- ? /** @type {import('zodex').SzRecord} */ (
469
+ )?.key)
470
+ ? schemaLabel(/** @type {import('zodexy').SzRecord} */ (
436
471
  specificSchemaObject
437
- )?.key?.description
472
+ )?.key)
438
473
  : specificSchemaObject ? propName : undefined
439
474
  }, [
440
475
  propName !== undefined
441
- ? /** @type {import('zodex').SzObject} */ (
476
+ ? schemaLabel(/** @type {import('zodexy').SzObject} */ (
442
477
  specificSchemaObject
443
- )?.properties?.[propName]?.description ?? propName
444
- // eslint-disable-next-line @stylistic/max-len -- Long
478
+ )?.properties?.[propName]) ?? propName
445
479
  /* istanbul ignore next -- Won't reach here as typeson will always give keypath? */
446
480
  : itemIndex
447
481
  ]]
448
482
  ]];
449
483
  };
450
- const div = jml('div', /** @type {import('jamilih').JamilihAttributes} */ ({
484
+
485
+ /**
486
+ * @typedef {HTMLDivElement & {
487
+ * $addAndSetArrayElement: AddAndSetArrayElement,
488
+ * $addMapElement: () => HTMLFieldSetElement,
489
+ * $addArrayElement: (cfg: {propName: string}) => HTMLFieldSetElement,
490
+ * $getArrayItems: () => HTMLElement,
491
+ * _lastFieldset?: HTMLFieldSetElement|null
492
+ * }} ArrayHolder
493
+ */
494
+
495
+ /**
496
+ * @callback AddMapElement
497
+ * @returns {HTMLFieldSetElement}
498
+ */
499
+
500
+ const div = jml('div', {
451
501
  class: 'arrayHolder',
452
- dataset: {type},
502
+ // `record`/`tuple` render through `object`/`array`; flag the refinement
503
+ // for `getValue` (which has no schema in scope) and for styling/tests.
504
+ dataset: {
505
+ type,
506
+ ...(recordMode ? {record: 'true'} : {}),
507
+ ...(tupleMode ? {tuple: 'true'} : {})
508
+ },
453
509
  $custom: {
454
510
  /**
455
- * @param {{
456
- * propName: string,
457
- * type: import('../types.js').AvailableType,
458
- * value: import('../formats.js').StructuredCloneValue,
459
- * bringIntoFocus: boolean,
460
- * schemaContent: import('../formats/schema.js').ZodexSchema,
461
- * }} cfg
462
- * @returns {Element}
511
+ * @this {ArrayHolder}
512
+ * @param {Parameters<AddAndSetArrayElement>[0]} cfg
463
513
  */
464
- $addAndSetArrayElement ({
465
- propName, type, value, bringIntoFocus,
466
- schemaContent
467
- }) {
514
+ $addAndSetArrayElement (cfg) {
515
+ const {
516
+ propName, type, value, bringIntoFocus,
517
+ schemaContent
518
+ } = cfg;
468
519
  if (parentType === 'map') {
469
520
  const root = types.getUIForModeAndType({
470
521
  resultType,
@@ -481,15 +532,15 @@ const arrayType = {
481
532
  const keyFieldset = jml(
482
533
  'fieldset', [
483
534
  ['legend', {
484
- title: /** @type {import('zodex').SzMap<any, any>} */ (
535
+ title: schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
485
536
  specificSchemaObject
486
- )?.key?.description
537
+ )?.key)
487
538
  ? '(map key)'
488
539
  : undefined
489
540
  }, [
490
- /** @type {import('zodex').SzMap<any, any>} */ (
541
+ schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
491
542
  specificSchemaObject
492
- )?.key?.description ?? 'Key'
543
+ )?.key) ?? 'Key'
493
544
  ]]
494
545
  ], fieldset
495
546
  );
@@ -498,15 +549,15 @@ const arrayType = {
498
549
  const valueFieldset = jml(
499
550
  'fieldset', [
500
551
  ['legend', {
501
- title: /** @type {import('zodex').SzMap<any, any>} */ (
552
+ title: schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
502
553
  specificSchemaObject
503
- )?.value?.description
554
+ )?.value)
504
555
  ? '(map value)'
505
556
  : undefined
506
557
  }, [
507
- /** @type {import('zodex').SzMap<any, any>} */ (
558
+ schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
508
559
  specificSchemaObject
509
- )?.value?.description ??
560
+ )?.value) ??
510
561
  'Value'
511
562
  ]]
512
563
  ], this._lastFieldset
@@ -533,7 +584,8 @@ const arrayType = {
533
584
  return root;
534
585
  },
535
586
  /**
536
- * @returns {HTMLFieldSetElement}
587
+ * @this {ArrayHolder}
588
+ * @type {AddMapElement}
537
589
  */
538
590
  $addMapElement () {
539
591
  itemIndex++;
@@ -552,10 +604,12 @@ const arrayType = {
552
604
  return fieldset;
553
605
  },
554
606
  /**
607
+ * @this {ArrayHolder}
555
608
  * @param {{propName: string}} cfg
556
609
  * @returns {HTMLFieldSetElement}
557
610
  */
558
- $addArrayElement ({propName}) {
611
+ $addArrayElement (cfg) {
612
+ const {propName} = cfg;
559
613
  itemIndex++;
560
614
  const arrayItems = this.$getArrayItems();
561
615
  // const className = `${type}Item`;
@@ -571,13 +625,19 @@ const arrayType = {
571
625
  ], arrayItems);
572
626
  return fieldset;
573
627
  },
628
+ /**
629
+ * @this {ArrayHolder}
630
+ * @returns {HTMLElement}
631
+ */
574
632
  $getArrayItems () {
575
- return this.lastElementChild.lastElementChild;
633
+ return /** @type {HTMLElement} */ (
634
+ /** @type {Element} */ (lastTypeChild(this)).lastElementChild
635
+ );
576
636
  }
577
637
  }
578
- }), [
638
+ }, [
579
639
  ['span', {
580
- title: specificSchemaObject?.description
640
+ title: schemaLabel(specificSchemaObject)
581
641
  }, [
582
642
  specificSchemaObject
583
643
  ? '—'
@@ -600,7 +660,7 @@ const arrayType = {
600
660
  ).textContent = arrayContents.hidden ? '+' : '-';
601
661
  }}}, ['-']],
602
662
  ['div', {class: 'arrayContents'}, [
603
- this.array && type !== 'record'
663
+ !recordMode && this.array
604
664
  ? ['div', {
605
665
  title: specificSchemaObject
606
666
  ? (type === 'filelist'
@@ -609,18 +669,18 @@ const arrayType = {
609
669
  ? '(a Set)'
610
670
  : type === 'map'
611
671
  ? '(a Map)'
612
- : type === 'tuple'
672
+ : tupleMode
613
673
  ? '(a tuple)'
614
674
  : '(an Array)')
615
675
  : undefined
616
676
  }, [
617
677
  type === 'filelist'
618
- ? (specificSchemaObject?.description ?? 'FileList') + ' length: '
678
+ ? (schemaLabel(specificSchemaObject) ?? 'FileList') + ' length: '
619
679
  : type === 'set'
620
- ? (specificSchemaObject?.description ?? 'Set') + ' size: '
680
+ ? (schemaLabel(specificSchemaObject) ?? 'Set') + ' size: '
621
681
  : type === 'map'
622
- ? (specificSchemaObject?.description ?? 'Map') + ' size: '
623
- : (specificSchemaObject?.description ?? 'Array') +
682
+ ? (schemaLabel(specificSchemaObject) ?? 'Map') + ' size: '
683
+ : (schemaLabel(specificSchemaObject) ?? 'Array') +
624
684
  ' length: ',
625
685
  ['span', [
626
686
  (value && (type === 'set' || type === 'map')
@@ -628,8 +688,8 @@ const arrayType = {
628
688
  : value.length) || 0
629
689
  ]]
630
690
  ]]
631
- : (type === 'record'
632
- ? specificSchemaObject?.description ?? 'Record'
691
+ : (recordMode
692
+ ? schemaLabel(specificSchemaObject) ?? 'Record'
633
693
  : ''),
634
694
  ['div', {
635
695
  class: 'arrayItems'
@@ -653,20 +713,55 @@ const arrayType = {
653
713
  const {sparse} = this;
654
714
  // eslint-disable-next-line consistent-this -- Clearer
655
715
  const parentTypeObject = this;
716
+
717
+ // `record`/`tuple` are not distinct types; they are `object`/`array` whose
718
+ // associated schema refines them (map-style key/value controls for a
719
+ // record, positional `items`/`rest` for a tuple). Detect the refinement
720
+ // from the schema.
721
+ const recordMode = specificSchemaObject?.type === 'record' ||
722
+ specificSchemaObject?.type === 'looseRecord';
723
+ const tupleMode = specificSchemaObject?.type === 'tuple';
724
+
725
+ // A `record` refines `object` but, for legend numbering/reordering, behaves
726
+ // like the array-based types did when it was its own (`array: true`) type.
727
+ const parentIsArrayLike = parentTypeObject.array || recordMode;
728
+
729
+ // Keep the historical per-item CSS class names (`recordItem`, `tupleItem`)
730
+ // even though the root type is now `object`/`array`.
731
+ const itemType = recordMode ? 'record' : tupleMode ? 'tuple' : type;
732
+
656
733
  const itemAdjust = type === 'object' ? 1 : 0;
657
734
  let itemIndex = itemAdjust - 1;
658
735
  const editableProperties = type !== 'array' &&
659
736
  type !== 'set' && type !== 'map' && type !== 'filelist' &&
660
- type !== 'tuple' && type !== 'record'; // arrayNonindexKeys and object?
661
- const mapProperties = type === 'map' || type === 'record';
737
+ !tupleMode && !recordMode; // arrayNonindexKeys and object?
738
+ const mapProperties = type === 'map' || recordMode;
662
739
 
663
- const elementDesc = /** @type {import('zodex').SzArray} */ (
740
+ /**
741
+ * @param {string} message
742
+ * @returns {string}
743
+ */
744
+ const getSchemaValidationMessage = (message) => {
745
+ return types.getValidationMessage({
746
+ message,
747
+ schema: specificSchemaObject,
748
+ typeSpecific: true
749
+ }) ?? message;
750
+ };
751
+
752
+ const elementDesc = schemaLabel(/** @type {import('zodexy').SzArray} */ (
664
753
  specificSchemaObject
665
- )?.element?.description ?? (type === 'set'
666
- ? /** @type {import('zodex').SzSet} */ (
754
+ )?.element) ?? (type === 'set'
755
+ ? schemaLabel(/** @type {import('zodexy').SzSet} */ (
667
756
  specificSchemaObject
668
- )?.value?.description
669
- : undefined);
757
+ )?.value)
758
+ : type === 'filelist'
759
+ ? schemaLabel(/** @type {import('zodexy').SzArray} */ (
760
+ /** @type {import('zodexy').SzCodec} */ (
761
+ specificSchemaObject
762
+ )?.output
763
+ )?.element)
764
+ : undefined);
670
765
 
671
766
  /**
672
767
  * @param {HTMLInputElement} input
@@ -674,10 +769,12 @@ const arrayType = {
674
769
  * @returns {void}
675
770
  */
676
771
  const bringFocus = (input, alwaysFocus) => {
677
- if (bringIntoFocus || alwaysFocus) {
678
- input.scrollIntoView();
679
- input.focus();
772
+ if (!(bringIntoFocus || alwaysFocus)) {
773
+ return;
680
774
  }
775
+
776
+ input.scrollIntoView();
777
+ input.focus();
681
778
  };
682
779
 
683
780
  /**
@@ -700,31 +797,38 @@ const arrayType = {
700
797
  if (!swapGroup || swapGroup.nodeName.toLowerCase() !== 'fieldset') {
701
798
  return;
702
799
  }
703
- if (!sparse && (!specificSchemaObject || parentTypeObject.array)) {
800
+ if (!sparse && (!specificSchemaObject || parentIsArrayLike)) {
801
+ // The item-count element is `span.${itemType}Item`, but its depth in the
802
+ // legend differs by layout: a plain array puts it directly under
803
+ // `<legend>`, while `object`/`arrayNonindexKeys` nest it inside a
804
+ // `span.…_propertyHolder` wrapper. Try the nested path first (added in
805
+ // the object-property swap fix) and fall back to the direct child.
704
806
  const swapCountElem = DOM.filterChildElements(
705
- swapGroup, ['legend', 'span', `.${type}Item`]
807
+ swapGroup, ['legend', 'span', `.${itemType}Item`]
808
+ )[0] ?? DOM.filterChildElements(
809
+ swapGroup, ['legend', `.${itemType}Item`]
810
+ )[0];
811
+ const baseCountElem = DOM.filterChildElements(
812
+ group, ['legend', 'span', `.${itemType}Item`]
813
+ )[0] ?? DOM.filterChildElements(
814
+ group, ['legend', `.${itemType}Item`]
706
815
  )[0];
707
- const baseCountElem = DOM.filterChildElements(group, [
708
- 'legend', 'span', `.${type}Item`
709
- ])[0];
710
816
 
711
817
  const swap = swapCountElem.textContent;
712
818
  const base = baseCountElem.textContent;
713
819
  swapCountElem.textContent = base;
714
820
  baseCountElem.textContent = swap;
715
821
  } else {
716
- // eslint-disable-next-line @stylistic/max-len -- Long
717
822
  const swapCountElem = /** @type {HTMLInputElement & {$parseInt: ParseInt}} */
718
823
  (/**
719
- * @type {HTMLFieldSetElement & {$getPropertyInput: GetPropertyInput}}
720
- */ (
824
+ * @type {HTMLFieldSetElement & {$getPropertyInput: GetPropertyInput}}
825
+ */ (
721
826
  group
722
827
  ).$getPropertyInput());
723
- // eslint-disable-next-line @stylistic/max-len -- Long
724
828
  const baseCountElem = /** @type {HTMLInputElement & {$parseInt: ParseInt}} */
725
829
  (/**
726
- * @type {HTMLFieldSetElement & {$getPropertyInput: GetPropertyInput}}
727
- */ (
830
+ * @type {HTMLFieldSetElement & {$getPropertyInput: GetPropertyInput}}
831
+ */ (
728
832
  swapGroup
729
833
  ).$getPropertyInput());
730
834
  if (typeof swapCountElem.$parseInt() === 'number' ||
@@ -748,7 +852,6 @@ const arrayType = {
748
852
  group.before(swapGroup);
749
853
  }
750
854
  types.validateAllReferences({
751
- // eslint-disable-next-line object-shorthand -- TS
752
855
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
753
856
  }); // Needed
754
857
 
@@ -762,17 +865,18 @@ const arrayType = {
762
865
  * @this {HTMLDivElement & {$swapGroup: SwapGroup}}
763
866
  */
764
867
  const $redrawMoveArrows = function () {
765
- if (type === 'tuple') { // Don't want to move non-rest items at least
868
+ if (tupleMode) { // Don't want to move non-rest items at least
766
869
  return;
767
870
  }
768
871
  DOM.filterChildElements(this, [
769
- 'fieldset', `.${type}Item-arrowHolder-${typeNamespace}`
872
+ 'fieldset', `.${itemType}Item-arrowHolder-${typeNamespace}`
770
873
  ]).forEach((holder, j, arr) => {
771
874
  DOM.removeChildren(holder);
772
- let up = true, down = true;
773
875
  if (arr.length === 1) { // Nowhere to move
774
876
  return;
775
877
  }
878
+
879
+ let up = true, down = true;
776
880
  if (j === 0) {
777
881
  up = false;
778
882
  } else if (j === arr.length - 1) {
@@ -820,6 +924,8 @@ const arrayType = {
820
924
  }
821
925
 
822
926
  // Others may be ok (or problematic) now too
927
+
928
+ // eslint-disable-next-line unicorn/no-unused-array-method-return -- Short-circuiting
823
929
  propertyNameInputs.some((input, /* typeNamespace, */ _i, arr) => {
824
930
  const invalidStr = arr.some((item) => {
825
931
  return input !== item && input.value === item.value;
@@ -863,8 +969,8 @@ const arrayType = {
863
969
  * typeNamespace: string|undefined,
864
970
  * arrayItems: ArrayItems,
865
971
  * propName: string|undefined,
866
- * required?: true,
867
- * schema?: import('zodex').SzType
972
+ * required?: boolean,
973
+ * schema?: import('zodexy').SzType
868
974
  * }} cfg
869
975
  * @returns {import('jamilih').JamilihArray}
870
976
  */
@@ -872,65 +978,23 @@ const arrayType = {
872
978
  className, splice, itemIndex, /* type, */ typeNamespace,
873
979
  arrayItems, propName, required, schema
874
980
  }) => {
875
- /**
876
- * @callback ValidateLength
877
- * @param {boolean} [avoidDialog]
878
- * @returns {Promise<void>}
879
- */
880
-
881
- /**
882
- * @type {ValidateLength}
883
- * @this {HTMLInputElement & {
884
- * $validateLength: ValidateLength
885
- * }}
886
- */
887
- const $validateLength = async function (avoidDialog) {
888
- if (!sparse) {
889
- return;
890
- }
891
- const inputsExceedingLength = arrayItems.$inputsExceedingLength();
892
- const exceedsLength = inputsExceedingLength.length;
893
- if (avoidDialog || !exceedsLength || !(/^\d+$/u).test(this.value)) {
894
- return;
895
- }
896
- await dialogs.confirm({
897
- message: 'You are attempting to add an (integer-based) ' +
898
- 'array item beyond the length. Click "Ok" to allow to ' +
899
- 'permit and extend the array length or "Cancel" otherwise.'
900
- });
901
- const arrLengthInput =
902
- /** @type {HTMLInputElement & {$oldvalue: string}} */ (
903
- $e(
904
- /** @type {HTMLElement} */ (arrayItems.previousElementSibling),
905
- 'input'
906
- )
907
- );
908
- const highest = /** @type {number} */ (inputsExceedingLength.map(
909
- (i) => Number.parseInt(i.value)
910
- ).sort().at(-1));
911
- arrLengthInput.value = String(highest + 1);
912
- arrLengthInput.$oldvalue = String(highest + 1);
913
- // Does have potential side effects calling `$inputsExceedingLength`
914
- this.$validateLength(true);
915
- };
916
981
  if (mapProperties) {
917
982
  const keyTypeSelection =
918
983
  /** @type {import('../typeChoices.js').BuildTypeChoices} */ (
919
984
  buildTypeChoices
920
985
  )({
921
- value: propName !== undefined && type === 'record'
986
+ value: propName !== undefined && recordMode
922
987
  ? propName
923
988
  : undefined,
924
- setValue: propName !== undefined && type === 'record',
989
+ setValue: propName !== undefined && recordMode,
925
990
  // Needed as false when map value supplied
926
- autoTrigger: propName === undefined || type === 'record',
927
- // eslint-disable-next-line object-shorthand -- TS
991
+ autoTrigger: propName === undefined || recordMode,
928
992
  format: /** @type {import('../formats.js').AvailableFormat} */ (
929
993
  format
930
994
  ),
931
995
  schemaOriginal: schemaContent,
932
996
  // Can also be a `Record`
933
- schemaContent: /** @type {import('zodex').SzMap<any, any>} */ (
997
+ schemaContent: /** @type {import('zodexy').SzMap<any, any>} */ (
934
998
  specificSchemaObject
935
999
  )?.key,
936
1000
  typeNamespace: 'key-type-choices-only'
@@ -940,25 +1004,25 @@ const arrayType = {
940
1004
  class: 'mapKey',
941
1005
  title: (
942
1006
  type === 'map' &&
943
- /** @type {import('zodex').SzMap<any, any>} */ (
1007
+ schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
944
1008
  specificSchemaObject
945
- )?.key?.description
1009
+ )?.key)
946
1010
  )
947
1011
  ? '(map key)'
948
- : type === 'record' &&
949
- /** @type {import('zodex').SzRecord} */ (
1012
+ : recordMode &&
1013
+ schemaLabel(/** @type {import('zodexy').SzRecord} */ (
950
1014
  specificSchemaObject
951
- )?.key?.description
1015
+ )?.key)
952
1016
  ? '(record key)'
953
1017
  : undefined
954
1018
  }, [
955
1019
  type === 'map'
956
- ? /** @type {import('zodex').SzMap<any, any>} */ (
1020
+ ? schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
957
1021
  specificSchemaObject
958
- )?.key?.description ?? 'Map key'
959
- : /** @type {import('zodex').SzRecord} */ (
1022
+ )?.key) ?? 'Map key'
1023
+ : schemaLabel(/** @type {import('zodexy').SzRecord} */ (
960
1024
  specificSchemaObject
961
- )?.key?.description ?? 'Record key',
1025
+ )?.key) ?? 'Record key',
962
1026
  ' '
963
1027
  ]],
964
1028
  ['span', {
@@ -981,7 +1045,6 @@ const arrayType = {
981
1045
 
982
1046
  // Needed?
983
1047
  types.validateAllReferences({
984
- // eslint-disable-next-line object-shorthand -- TS
985
1048
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
986
1049
  });
987
1050
  }, true]
@@ -1023,19 +1086,63 @@ const arrayType = {
1023
1086
  `Duplicate ${type === 'map' ? 'Map' : 'Record'} key value`
1024
1087
  );
1025
1088
  control.reportValidity();
1026
- });
1089
+ }, 0);
1027
1090
  }
1028
1091
  }
1029
1092
  }, keyTypeSelection.domArray]
1030
1093
  ]];
1031
1094
  }
1095
+
1096
+ /**
1097
+ * @callback ValidateLength
1098
+ * @param {boolean} [avoidDialog]
1099
+ * @returns {Promise<void>}
1100
+ */
1101
+
1102
+ /**
1103
+ * @type {ValidateLength}
1104
+ * @this {HTMLInputElement & {
1105
+ * $validateLength: ValidateLength
1106
+ * }}
1107
+ */
1108
+ const $validateLength = async function (avoidDialog) {
1109
+ if (!sparse) {
1110
+ return;
1111
+ }
1112
+ const inputsExceedingLength = arrayItems.$inputsExceedingLength();
1113
+ const exceedsLength = inputsExceedingLength.length;
1114
+ if (avoidDialog || !exceedsLength || !(/^\d+$/u).test(this.value)) {
1115
+ return;
1116
+ }
1117
+ await dialogs.confirm({
1118
+ message: 'You are attempting to add an (integer-based) ' +
1119
+ 'array item beyond the length. Click "Ok" to allow to ' +
1120
+ 'permit and extend the array length or "Cancel" otherwise.'
1121
+ });
1122
+ const arrLengthInput =
1123
+ /** @type {HTMLInputElement & {$oldvalue: string}} */ (
1124
+ $e(
1125
+ /** @type {HTMLElement} */ (arrayItems.previousElementSibling),
1126
+ 'input'
1127
+ )
1128
+ );
1129
+ const highest = Math.max(...inputsExceedingLength.map(
1130
+ (i) => Math.trunc(Number(i.value))
1131
+ ));
1132
+ arrLengthInput.value = String(highest + 1);
1133
+ arrLengthInput.$oldvalue = String(highest + 1);
1134
+ // Does have potential side effects calling `$inputsExceedingLength`
1135
+ this.$validateLength(true);
1136
+ };
1137
+
1032
1138
  if (editableProperties) {
1033
1139
  // console.log('PROPNAME', propName, schema, specificSchemaObject);
1034
- const description = /** @type {import('zodex').SzObject} */ (
1140
+ const propSchemaForMeta = /** @type {import('zodexy').SzObject} */ (
1035
1141
  specificSchemaObject
1036
- )?.properties?.[/** @type {string} */ (propName)]?.description;
1142
+ )?.properties?.[/** @type {string} */ (propName)];
1143
+ const description = schemaLabel(propSchemaForMeta);
1037
1144
  const optionalProperties = Object.entries(
1038
- /** @type {import('zodex').SzObject} */ (
1145
+ /** @type {import('zodexy').SzObject} */ (
1039
1146
  specificSchemaObject
1040
1147
  )?.properties ?? {}
1041
1148
  ).map(([prop, val]) => {
@@ -1052,7 +1159,9 @@ const arrayType = {
1052
1159
  : (propName !== undefined ? propName : itemIndex)
1053
1160
  )
1054
1161
  : propName || '';
1055
- return /** @type {import('jamilih').JamilihArray} */ (['legend', [
1162
+ return /** @type {import('jamilih').JamilihArray} */ (['legend', {
1163
+ class: deprecatedClassSuffix(propSchemaForMeta).trim()
1164
+ }, [
1056
1165
  sparse
1057
1166
  ? elementDesc ?? 'Item'
1058
1167
  : {'#': required
@@ -1071,19 +1180,20 @@ const arrayType = {
1071
1180
  ...(specificSchemaObject && propName) // Optional but has name
1072
1181
  ? [
1073
1182
  ['b', [
1074
- /** @type {import('zodex').SzObject} */
1075
- (specificSchemaObject)?.properties?.[
1076
- propName
1077
- ]
1078
- ? /** @type {import('zodex').SzObject} */ (
1079
- specificSchemaObject
1080
- )?.properties?.[
1081
- propName
1082
- ]?.description ?? propName
1083
- : /** @type {import('zodex').SzObject} */ (
1084
- specificSchemaObject
1085
- /* istanbul ignore next -- Guard */
1086
- )?.catchall?.description ?? propName
1183
+ (() => {
1184
+ const propSchema =
1185
+ /** @type {import('zodexy').SzObject} */ (
1186
+ specificSchemaObject
1187
+ )?.properties?.[propName];
1188
+ return propSchema
1189
+ ? schemaLabel(propSchema) ?? propName
1190
+ : schemaLabel(
1191
+ /** @type {import('zodexy').SzObject} */ (
1192
+ specificSchemaObject
1193
+ /* istanbul ignore next -- Guard */
1194
+ )?.catchall
1195
+ ) ?? propName;
1196
+ })()
1087
1197
  ]]
1088
1198
  ]
1089
1199
  : [
@@ -1121,11 +1231,11 @@ const arrayType = {
1121
1231
  */
1122
1232
  $custom: {
1123
1233
  /**
1124
- * @type {Validate}
1125
1234
  * @this {HTMLInputElement & {
1126
1235
  * $validateLength: ValidateLength,
1127
1236
  * $validateLegend: ValidateLegend
1128
1237
  * }}
1238
+ * @type {Validate}
1129
1239
  */
1130
1240
  async $validate () {
1131
1241
  try {
@@ -1139,7 +1249,6 @@ const arrayType = {
1139
1249
  // Todo (low): We could make this more efficient by waiting
1140
1250
  // until all added (when pre-populating)
1141
1251
  types.validateAllReferences({
1142
- // eslint-disable-next-line object-shorthand -- TS
1143
1252
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
1144
1253
  }); // Needed
1145
1254
  } catch {}
@@ -1153,28 +1262,29 @@ const arrayType = {
1153
1262
  if (!(/^\d+$/u).test(this.value)) {
1154
1263
  return false;
1155
1264
  }
1156
- return Number.parseInt(this.value);
1265
+ return Math.trunc(Number(this.value));
1157
1266
  },
1158
1267
  $validateLegend,
1159
1268
  $arrayItems: arrayItems,
1160
1269
  $validateLength,
1161
1270
  /**
1162
- * @type {Resort}
1163
1271
  * @this {HTMLInputElement}
1272
+ * @param {Parameters<Resort>[0]} cfg
1164
1273
  */
1165
- $resort ({alwaysFocus}) {
1274
+ $resort (cfg) {
1275
+ const {alwaysFocus} = cfg;
1166
1276
  const inputs = /**
1167
- * @type {(HTMLInputElement & {
1168
- * $parseInt: ParseInt
1169
- * })[]}
1170
- */
1277
+ * @type {(HTMLInputElement & {
1278
+ * $parseInt: ParseInt
1279
+ * })[]}
1280
+ */
1171
1281
  (/**
1172
- * @type {HTMLInputElement & {
1173
- * $arrayItems: HTMLDivElement & {
1174
- * $getPropertyInputs: GetPropertyInputs
1175
- * }
1176
- * }}
1177
- */ (
1282
+ * @type {HTMLInputElement & {
1283
+ * $arrayItems: HTMLDivElement & {
1284
+ * $getPropertyInputs: GetPropertyInputs
1285
+ * }
1286
+ * }}
1287
+ */ (
1178
1288
  this
1179
1289
  ).$arrayItems.$getPropertyInputs());
1180
1290
  if (inputs.length === 1) {
@@ -1188,12 +1298,13 @@ const arrayType = {
1188
1298
  el.closest('fieldset')
1189
1299
  );
1190
1300
  const thisFieldset = getFieldset(this);
1191
- // eslint-disable-next-line @stylistic/max-len -- Long
1192
1301
  const intVal = /** @type {HTMLInputElement & {$parseInt: ParseInt}} */ (
1193
1302
  this
1194
1303
  ).$parseInt();
1195
1304
  if (intVal === false) {
1196
- inputs.reverse().some((input) => {
1305
+ inputs.reverse();
1306
+ // eslint-disable-next-line unicorn/no-unused-array-method-return -- Short-circuiting
1307
+ inputs.some((input) => {
1197
1308
  if (input === this) { // No need to search further
1198
1309
  return true;
1199
1310
  }
@@ -1223,6 +1334,7 @@ const arrayType = {
1223
1334
  */
1224
1335
  let nearest;
1225
1336
 
1337
+ // eslint-disable-next-line unicorn/no-unused-array-method-return -- Short-circuiting
1226
1338
  inputs.some((input) => {
1227
1339
  if (input === this) {
1228
1340
  return false;
@@ -1246,8 +1358,13 @@ const arrayType = {
1246
1358
  return latest ? a > b : a < b;
1247
1359
  };
1248
1360
  if (cmp(intVal, intValOlder) &&
1249
- (!nearest || cmp(
1250
- intValOlder, Number.parseInt(nearest.value)
1361
+ // A non-numeric `nearest` (e.g. an unset/blank property
1362
+ // name) must not compare as `0`; keep the pre-existing
1363
+ // `parseInt`-style behavior of treating it as `NaN` so
1364
+ // the comparison below is skipped.
1365
+ (!nearest || (
1366
+ (/^\d+$/u).test(nearest.value) &&
1367
+ cmp(intValOlder, Math.trunc(Number(nearest.value)))
1251
1368
  ))
1252
1369
  ) {
1253
1370
  nearest = input;
@@ -1268,7 +1385,7 @@ const arrayType = {
1268
1385
  getFieldset(nearest)[method](thisFieldset);
1269
1386
  bringFocus(this, alwaysFocus);
1270
1387
  arrayItems.$redrawMoveArrows();
1271
- });
1388
+ }, 0);
1272
1389
  return true;
1273
1390
  };
1274
1391
  if (!getNearest()) {
@@ -1290,19 +1407,15 @@ const arrayType = {
1290
1407
  }`)
1291
1408
  );
1292
1409
  DOM.removeChildren(propHolder);
1410
+ const propSchema = /** @type {import('zodexy').SzObject} */ (
1411
+ specificSchemaObject
1412
+ )?.properties?.[this.value];
1293
1413
  jml('b', [
1294
- /** @type {import('zodex').SzObject} */
1295
- (specificSchemaObject)?.properties?.[
1296
- this.value
1297
- ]
1298
- ? /** @type {import('zodex').SzObject} */ (
1414
+ propSchema
1415
+ ? schemaLabel(propSchema) ?? this.value
1416
+ : schemaLabel(/** @type {import('zodexy').SzObject} */ (
1299
1417
  specificSchemaObject
1300
- )?.properties?.[
1301
- this.value
1302
- ]?.description ?? this.value
1303
- : /** @type {import('zodex').SzObject} */ (
1304
- specificSchemaObject
1305
- )?.catchall?.description ?? this.value
1418
+ )?.catchall) ?? this.value
1306
1419
  ], propHolder);
1307
1420
  },
1308
1421
  /**
@@ -1313,7 +1426,7 @@ const arrayType = {
1313
1426
  * }}
1314
1427
  */
1315
1428
  change (e) {
1316
- const neverProperty = /** @type {import('zodex').SzObject} */ (
1429
+ const neverProperty = /** @type {import('zodexy').SzObject} */ (
1317
1430
  specificSchemaObject
1318
1431
  )?.properties?.[
1319
1432
  /** @type {string} */ (this.value)
@@ -1333,9 +1446,9 @@ const arrayType = {
1333
1446
 
1334
1447
  if (
1335
1448
  !dataListValues.includes(this.value) &&
1336
- /** @type {import('zodex').SzObject} */ (
1449
+ /** @type {import('zodexy').SzObject} */ (
1337
1450
  specificSchemaObject
1338
- ).unknownKeys === 'strict'
1451
+ ).catchall?.type === 'never'
1339
1452
  ) {
1340
1453
  this.setCustomValidity('Bad value');
1341
1454
  this.reportValidity();
@@ -1369,9 +1482,9 @@ const arrayType = {
1369
1482
  ...buildTypeChoicesForProperty({
1370
1483
  propName: this.value,
1371
1484
  schema:
1372
- /** @type {import('zodex').SzObject} */
1485
+ /** @type {import('zodexy').SzObject} */
1373
1486
  (specificSchemaObject)?.properties?.[this.value] ??
1374
- /** @type {import('zodex').SzObject} */ (
1487
+ /** @type {import('zodexy').SzObject} */ (
1375
1488
  specificSchemaObject
1376
1489
  )?.catchall ??
1377
1490
  {type: 'any'}
@@ -1404,23 +1517,25 @@ const arrayType = {
1404
1517
  ]]);
1405
1518
  }
1406
1519
 
1407
- const fileDesc = /** @type {import('zodex').SzEffect} */ (
1408
- specificSchemaObject
1409
- )?.inner?.description;
1520
+ const fileDesc = type === 'filelist'
1521
+ ? schemaLabel(specificSchemaObject)
1522
+ : undefined;
1410
1523
 
1411
- return /** @type {import('jamilih').JamilihArray} */ (['legend', [
1524
+ return /** @type {import('jamilih').JamilihArray} */ (['legend', {
1525
+ class: deprecatedClassSuffix(schema).trim()
1526
+ }, [
1412
1527
  elementDesc
1413
1528
  ? ''
1414
1529
  : fileDesc
1415
1530
  ? `${fileDesc} `
1416
- : schema?.description
1417
- ? `${schema?.description} `
1418
- : type === 'tuple' && /** @type {import('zodex').SzTuple} */ (
1531
+ : schemaLabel(schema)
1532
+ ? `${schemaLabel(schema)} `
1533
+ : tupleMode && schemaLabel(/** @type {import('zodexy').SzTuple} */ (
1419
1534
  specificSchemaObject
1420
- )?.rest?.description
1421
- ? `${/** @type {import('zodex').SzTuple} */ (
1535
+ )?.rest)
1536
+ ? `${schemaLabel(/** @type {import('zodexy').SzTuple} */ (
1422
1537
  specificSchemaObject
1423
- )?.rest?.description} `
1538
+ )?.rest)} `
1424
1539
  : 'Item ',
1425
1540
  ['span', {
1426
1541
  dataset: {prop: true, array: true},
@@ -1443,7 +1558,6 @@ const arrayType = {
1443
1558
  */
1444
1559
  const decrementItemIndex = (arrayItems) => {
1445
1560
  if (sparse) {
1446
- // eslint-disable-next-line @stylistic/max-len -- Long
1447
1561
  itemIndex = /** @type {(HTMLInputElement & {$parseInt: ParseInt})[]} */ (
1448
1562
  arrayItems.$getPropertyInputs()
1449
1563
  ).reduce(
@@ -1458,10 +1572,69 @@ const arrayType = {
1458
1572
  }
1459
1573
  };
1460
1574
 
1575
+ /**
1576
+ * Resolves the schema to use for a child (property/item) type-chooser.
1577
+ * @param {string|undefined} propName
1578
+ * @param {import('zodexy').SzType|undefined} schema Per-item schema (tuples)
1579
+ * @returns {import('zodexy').SzType|undefined}
1580
+ */
1581
+ const getChildSchema = (propName, schema) => {
1582
+ if (schema) {
1583
+ return schema;
1584
+ }
1585
+ if (tupleMode) {
1586
+ return /** @type {import('zodexy').SzTuple} */ (
1587
+ specificSchemaObject
1588
+ ).rest;
1589
+ }
1590
+ if (recordMode) {
1591
+ const recordSchema =
1592
+ /** @type {import('zodexy').SzLooseRecord<any, any>} */ (
1593
+ specificSchemaObject
1594
+ );
1595
+ // A `looseRecord` only applies its `value` schema to entries whose key
1596
+ // satisfies the `key` schema; Zod passes any other entry through
1597
+ // untyped, so its control is offered the unconstrained type choice
1598
+ // rather than being pinned to `value`.
1599
+ if (specificSchemaObject?.type === 'looseRecord' &&
1600
+ !recordKeyConforms(types, recordSchema.key, propName)) {
1601
+ return /** @type {import('zodexy').SzType} */ ({type: 'unknown'});
1602
+ }
1603
+ return recordSchema?.value;
1604
+ }
1605
+ if (mapProperties) {
1606
+ return /** @type {import('zodexy').SzMap<any, any>} */ (
1607
+ specificSchemaObject
1608
+ )?.value;
1609
+ }
1610
+ if (type === 'set') {
1611
+ return /** @type {import('zodexy').SzSet} */ (
1612
+ specificSchemaObject
1613
+ )?.value;
1614
+ }
1615
+ // This is a hack specifically for filelist; the desired solution
1616
+ // was: https://github.com/colinhacks/zod/issues/6413
1617
+ if (type === 'filelist') {
1618
+ return /** @type {import('zodexy').SzArray} */ (
1619
+ /** @type {import('zodexy').SzCodec} */ (
1620
+ specificSchemaObject
1621
+ )?.output
1622
+ )?.element;
1623
+ }
1624
+ if (type === 'array' || type === 'arrayNonindexKeys') {
1625
+ return /** @type {import('zodexy').SzArray} */ (
1626
+ specificSchemaObject
1627
+ )?.element;
1628
+ }
1629
+ return /** @type {import('zodexy').SzObject} */ (
1630
+ specificSchemaObject
1631
+ )?.properties?.[/** @type {string} */ (propName)];
1632
+ };
1633
+
1461
1634
  /**
1462
1635
  * @param {{
1463
1636
  * propName: string|undefined,
1464
- * schema?: import('zodex').SzType,
1637
+ * schema?: import('zodexy').SzType,
1465
1638
  * schemaIdx?: number,
1466
1639
  * autoTrigger?: boolean
1467
1640
  * }} cfg
@@ -1474,39 +1647,23 @@ const arrayType = {
1474
1647
  )({
1475
1648
  autoTrigger,
1476
1649
  // resultType,
1477
- // eslint-disable-next-line object-shorthand -- TS
1478
1650
  topRoot: /** @type {HTMLDivElement} */ (topRoot),
1479
- // eslint-disable-next-line object-shorthand -- TS
1480
1651
  format: /** @type {import('../formats.js').AvailableFormat} */ (format),
1481
1652
  schemaOriginal: schemaContent,
1482
1653
  schemaIdx,
1483
- schemaContent: schema || type === 'tuple'
1484
- ? (schema ?? /** @type {import('zodex').SzTuple} */ (
1485
- specificSchemaObject
1486
- ).rest)
1487
- : mapProperties
1488
- // Can also be a `Record`
1489
- ? /** @type {import('zodex').SzMap<any, any>} */ (
1490
- specificSchemaObject
1491
- )?.value
1492
- : type === 'set'
1493
- ? /** @type {import('zodex').SzSet} */ (
1494
- specificSchemaObject
1495
- )?.value
1496
- : type === 'filelist'
1497
- ? /** @type {import('zodex').SzEffect} */ (
1498
- specificSchemaObject
1499
- )?.inner
1500
- : type === 'array' || type === 'arrayNonindexKeys'
1501
- ? /** @type {import('zodex').SzArray} */ (
1502
- specificSchemaObject
1503
- )?.element
1504
- : /** @type {import('zodex').SzObject} */ (
1505
- specificSchemaObject
1506
- )?.properties?.[/** @type {string} */ (propName)],
1654
+ schemaContent: getChildSchema(propName, schema),
1655
+ // A tuple renders through `array` (so `type` is `'array'` here), but
1656
+ // its children are schema-constrained by the positional `items` and
1657
+ // `rest` schemas. `schema.js` short-circuits `state === 'array'` and
1658
+ // discards the child schema (a leftover from when arrays had no
1659
+ // per-child schema); pass the `arrayNonindexKeys` state real zodexy
1660
+ // arrays already use so the child schema is honored (and a
1661
+ // single-type child auto-renders).
1507
1662
  state: parentTypeObject.filelist
1508
1663
  ? 'filelistArray'
1509
- : forcedState ?? type,
1664
+ : tupleMode
1665
+ ? 'arrayNonindexKeys'
1666
+ : forcedState ?? type,
1510
1667
  // itemIndex,
1511
1668
  typeNamespace
1512
1669
  }).domArray;
@@ -1517,61 +1674,87 @@ const arrayType = {
1517
1674
  * @returns {boolean}
1518
1675
  */
1519
1676
  function preventAdding (offset = 0) {
1520
- switch (type) {
1521
- case 'tuple':
1522
- if (/** @type {import('zodex').SzTuple} */ (
1677
+ if (tupleMode) {
1678
+ if (/** @type {import('zodexy').SzTuple} */ (
1523
1679
  specificSchemaObject
1524
1680
  )?.rest?.type === 'never') {
1525
1681
  dialogs.alert(
1526
- 'Tuple has rest type "never", so one cannot add to it.'
1682
+ getSchemaValidationMessage(
1683
+ 'Tuple has rest type "never", so one cannot add to it.'
1684
+ )
1527
1685
  );
1528
1686
  return true;
1529
1687
  }
1530
1688
  if (
1531
- /** @type {import('zodex').SzTuple} */ (
1689
+ /** @type {import('zodexy').SzTuple} */ (
1532
1690
  specificSchemaObject
1533
1691
  )?.items?.[0]?.type === 'never'
1534
1692
  ) {
1535
1693
  dialogs.alert(
1536
- 'Tuple has items type "never", so one cannot add to it.'
1694
+ getSchemaValidationMessage(
1695
+ 'Tuple has items type "never", so one cannot add to it.'
1696
+ )
1537
1697
  );
1538
1698
  return true;
1539
1699
  }
1540
- break;
1700
+ return false;
1701
+ }
1702
+ switch (type) {
1541
1703
  case 'set': {
1542
- if (/** @type {import('zodex').SzSet} */ (
1704
+ if (/** @type {import('zodexy').SzSet} */ (
1543
1705
  specificSchemaObject
1544
1706
  )?.value?.type === 'never') {
1545
- dialogs.alert('Set has type "never", so one cannot add to it.');
1707
+ dialogs.alert(getSchemaValidationMessage(
1708
+ 'Set has type "never", so one cannot add to it.'
1709
+ ));
1546
1710
  return true;
1547
1711
  }
1548
1712
 
1549
- const {maxSize} = /** @type {import('zodex').SzSet} */ (
1713
+ const {maxSize} = /** @type {import('zodexy').SzSet} */ (
1550
1714
  specificSchemaObject
1551
1715
  ) ?? {};
1552
1716
  if (maxSize !== undefined &&
1553
1717
  [...arrayItems.children].length + offset > maxSize
1554
1718
  ) {
1555
- dialogs.alert(`You cannot add beyond the \`maxSize\` of the Set`);
1719
+ dialogs.alert(getSchemaValidationMessage(
1720
+ `You cannot add beyond the \`maxSize\` of the Set`
1721
+ ));
1722
+ return true;
1723
+ }
1724
+ break;
1725
+ } case 'map': {
1726
+ const {max} = /** @type {import('zodexy').SzMap<any, any>} */ (
1727
+ specificSchemaObject
1728
+ ) ?? {};
1729
+ if (max !== undefined &&
1730
+ [...arrayItems.children].length + offset > max
1731
+ ) {
1732
+ dialogs.alert(getSchemaValidationMessage(
1733
+ `You cannot add beyond the \`max\` of the Map`
1734
+ ));
1556
1735
  return true;
1557
1736
  }
1558
1737
  break;
1559
1738
  } case 'array': case 'arrayNonindexKeys': {
1560
- if (/** @type {import('zodex').SzArray} */ (
1739
+ if (/** @type {import('zodexy').SzArray} */ (
1561
1740
  specificSchemaObject
1562
1741
  )?.element?.type === 'never') {
1563
- dialogs.alert('Array has type "never", so one cannot add to it.');
1742
+ dialogs.alert(getSchemaValidationMessage(
1743
+ 'Array has type "never", so one cannot add to it.'
1744
+ ));
1564
1745
  return true;
1565
1746
  }
1566
1747
 
1567
- const {maxLength} = /** @type {import('zodex').SzArray} */ (
1748
+ const {maxLength} = /** @type {import('zodexy').SzArray} */ (
1568
1749
  specificSchemaObject
1569
1750
  ) ?? {};
1570
1751
 
1571
1752
  if (maxLength !== undefined &&
1572
1753
  arrayItems.$getArrayLength() + offset > maxLength
1573
1754
  ) {
1574
- dialogs.alert(`You cannot add beyond the \`maxLength\` of the array`);
1755
+ dialogs.alert(getSchemaValidationMessage(
1756
+ `You cannot add beyond the \`maxLength\` of the array`
1757
+ ));
1575
1758
  return true;
1576
1759
  }
1577
1760
  break;
@@ -1588,9 +1771,9 @@ const arrayType = {
1588
1771
  * propName?: string,
1589
1772
  * splice?: "append"|number,
1590
1773
  * alwaysFocus?: true
1591
- * required?: true
1774
+ * required?: boolean
1592
1775
  * autoTrigger?: boolean,
1593
- * schema?: import('zodex').SzType,
1776
+ * schema?: import('zodexy').SzType,
1594
1777
  * schemaIdx?: number
1595
1778
  * }} cfg
1596
1779
  * @returns {void}
@@ -1610,16 +1793,14 @@ const arrayType = {
1610
1793
  const arrayItems = this.$getArrayItems();
1611
1794
  if (sparse) {
1612
1795
  if (propName) {
1613
- const intVal = propName.match(/^\d+$/u) && Number.parseInt(propName);
1796
+ const intVal = propName.match(/^\d+$/u) && Math.trunc(Number(propName));
1614
1797
  if (typeof intVal === 'number') {
1615
1798
  itemIndex = intVal;
1616
1799
  }
1617
1800
  } else if (typeof splice === 'number') {
1618
1801
  itemIndex = splice + 1;
1619
1802
  } else if (typeof splice !== 'string') {
1620
- // eslint-disable-next-line @stylistic/max-len -- Long
1621
1803
  itemIndex = /** @type {(HTMLInputElement & {$parseInt: ParseInt})[]} */ (
1622
- // eslint-disable-next-line @stylistic/max-len -- Long
1623
1804
  /** @type {HTMLDivElement & {$getPropertyInputs: GetPropertyInputs}} */
1624
1805
  (arrayItems).$getPropertyInputs()
1625
1806
  ).reduce(
@@ -1634,7 +1815,7 @@ const arrayType = {
1634
1815
  itemIndex++;
1635
1816
  }
1636
1817
  const thisButton = this; // eslint-disable-line consistent-this -- Clarity
1637
- const className = `${type}Item`;
1818
+ const className = `${itemType}Item`;
1638
1819
  const fieldset = jml('fieldset',
1639
1820
  {
1640
1821
  dataset: required ? {required: 'required'} : {},
@@ -1653,7 +1834,6 @@ const arrayType = {
1653
1834
  root,
1654
1835
  stateObj: {
1655
1836
  types,
1656
- // eslint-disable-next-line object-shorthand -- TS
1657
1837
  formats:
1658
1838
  /** @type {import('../formats.js').default} */ (
1659
1839
  formats
@@ -1694,7 +1874,7 @@ const arrayType = {
1694
1874
  'Duplicate Set value'
1695
1875
  );
1696
1876
  control.reportValidity();
1697
- });
1877
+ }, 10);
1698
1878
  }, true]
1699
1879
  },
1700
1880
  $custom: {
@@ -1733,29 +1913,29 @@ const arrayType = {
1733
1913
  ['span', {
1734
1914
  class: 'mapValue',
1735
1915
  title: type === 'map' &&
1736
- /** @type {import('zodex').SzMap<any, any>} */ (
1916
+ schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
1737
1917
  specificSchemaObject
1738
- )?.value?.description
1918
+ )?.value)
1739
1919
  ? '(map value)'
1740
- : type === 'record' &&
1741
- /** @type {import('zodex').SzRecord} */ (
1920
+ : recordMode &&
1921
+ schemaLabel(/** @type {import('zodexy').SzRecord} */ (
1742
1922
  specificSchemaObject
1743
- )?.value?.description
1923
+ )?.value)
1744
1924
  ? '(record value)'
1745
1925
  : undefined
1746
1926
  }, [
1747
1927
  type === 'map'
1748
- ? /** @type {import('zodex').SzMap<any, any>} */ (
1928
+ ? schemaLabel(/** @type {import('zodexy').SzMap<any, any>} */ (
1749
1929
  specificSchemaObject
1750
- )?.value?.description ?? 'Map value'
1751
- : type === 'record'
1752
- ? /** @type {import('zodex').SzRecord} */ (
1930
+ )?.value) ?? 'Map value'
1931
+ : recordMode
1932
+ ? schemaLabel(/** @type {import('zodexy').SzRecord} */ (
1753
1933
  specificSchemaObject
1754
- )?.value?.description ?? 'Record value'
1934
+ )?.value) ?? 'Record value'
1755
1935
  : '',
1756
1936
  ' '
1757
1937
  ]],
1758
- ...(specificSchemaObject && !propName && !parentTypeObject.array
1938
+ ...(specificSchemaObject && !propName && !parentIsArrayLike
1759
1939
  ? [jml('span', {
1760
1940
  className: `optionalProperties-placeholder${optionalPropertyId}`
1761
1941
  })]
@@ -1765,10 +1945,10 @@ const arrayType = {
1765
1945
  ['span', {className: 'property-placeholder'}],
1766
1946
  nbsp.repeat(2),
1767
1947
  ['button', {
1768
- disabled: type === 'tuple' && required &&
1948
+ disabled: tupleMode && required &&
1769
1949
  // The last item of a tuple can have content after it, but earlier
1770
1950
  // items cannot
1771
- /** @type {import('zodex').SzTuple} */
1951
+ /** @type {import('zodexy').SzTuple} */
1772
1952
  (specificSchemaObject)?.items?.length - 1 > itemIndex,
1773
1953
  $on: {click (/** @type {Event} */ e) {
1774
1954
  e.preventDefault();
@@ -1808,8 +1988,8 @@ const arrayType = {
1808
1988
  // Because schemas (with descriptions?) don't use className for
1809
1989
  // property count (and the else block will rewrite the
1810
1990
  // property name)
1811
- (specificSchemaObject || schema) &&
1812
- !parentTypeObject.array
1991
+ !parentIsArrayLike &&
1992
+ (specificSchemaObject || schema)
1813
1993
  )) {
1814
1994
  const newPrevInput = /** @type {HTMLInputElement} */ (
1815
1995
  newArrayFieldset.$getPropertyInput()
@@ -1829,16 +2009,12 @@ const arrayType = {
1829
2009
  // Maybe not needed as addition (without renumbering)
1830
2010
  // wouldn't yet add type
1831
2011
  types.validateAllReferences({
1832
- // eslint-disable-next-line object-shorthand -- TS
1833
2012
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
1834
2013
  });
1835
2014
  arrayItems.$redrawMoveArrows();
1836
2015
  }}
1837
2016
  }, ['+']],
1838
- /**
1839
- * @type {import('jamilih').JamilihArray}
1840
- */
1841
- ([
2017
+ [
1842
2018
  'button',
1843
2019
  {
1844
2020
  disabled: required,
@@ -1849,7 +2025,7 @@ const arrayType = {
1849
2025
  fieldset.remove();
1850
2026
  decrementItemIndex(arrayItems);
1851
2027
  if (!sparse &&
1852
- (!specificSchemaObject || parentTypeObject.array)
2028
+ (!specificSchemaObject || parentIsArrayLike)
1853
2029
  ) {
1854
2030
  DOM.filterChildElements(arrayItems, [
1855
2031
  'fieldset', 'legend', '.' + className
@@ -1861,7 +2037,6 @@ const arrayType = {
1861
2037
  }
1862
2038
  // Maybe not needed as removal would remove circular
1863
2039
  types.validateAllReferences({
1864
- // eslint-disable-next-line object-shorthand -- TS
1865
2040
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
1866
2041
  });
1867
2042
 
@@ -1874,9 +2049,9 @@ const arrayType = {
1874
2049
  }
1875
2050
  }
1876
2051
  }, ['x']
1877
- ]),
2052
+ ],
1878
2053
  ['span', {
1879
- class: `${type}Item-arrowHolder-${typeNamespace}`
2054
+ class: `${itemType}Item-arrowHolder-${typeNamespace}`
1880
2055
  }, []]
1881
2056
  ]}, fieldset);
1882
2057
 
@@ -1930,7 +2105,7 @@ const arrayType = {
1930
2105
  (input) => input.value.match(/^\d+$/u)
1931
2106
  ).filter((input) => {
1932
2107
  // We cycle through all elements to set the proper validity on them
1933
- const val = Number.parseInt(input.value);
2108
+ const val = Math.trunc(Number(input.value));
1934
2109
  const exceedsLength = val > highestExpectedIndex;
1935
2110
  input.setCustomValidity(
1936
2111
  exceedsLength
@@ -1953,13 +2128,13 @@ const arrayType = {
1953
2128
  */
1954
2129
  $getArrayItems () {
1955
2130
  const prevSibling = /**
1956
- * @type {HTMLDivElement & {
1957
- * $inputsExceedingLength: InputsExceedingLength,
1958
- * $getPropertyInputs: GetPropertyInputs,
1959
- * $redrawMoveArrows: RedrawMoveArrows,
1960
- * $getMapKeySelects: GetMapKeySelects
1961
- * }}
1962
- */ (this.previousElementSibling);
2131
+ * @type {HTMLDivElement & {
2132
+ * $inputsExceedingLength: InputsExceedingLength,
2133
+ * $getPropertyInputs: GetPropertyInputs,
2134
+ * $redrawMoveArrows: RedrawMoveArrows,
2135
+ * $getMapKeySelects: GetMapKeySelects
2136
+ * }}
2137
+ */ (this.previousElementSibling);
1963
2138
  return prevSibling;
1964
2139
  }
1965
2140
  },
@@ -1980,7 +2155,6 @@ const arrayType = {
1980
2155
  // Maybe not needed as addition (without renumbering)
1981
2156
  // wouldn't yet add type
1982
2157
  types.validateAllReferences({
1983
- // eslint-disable-next-line object-shorthand -- TS
1984
2158
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
1985
2159
  });
1986
2160
  }}
@@ -2047,37 +2221,44 @@ const arrayType = {
2047
2221
  */ (
2048
2222
  $e(div, '.arrayLength')
2049
2223
  );
2050
- arrayLengthInput.value = String(Number.parseInt(
2051
- arrayLengthInput.value
2052
- ) + 1);
2224
+ arrayLengthInput.value = String(Math.trunc(Number(arrayLengthInput.value)) + 1);
2053
2225
  }
2054
2226
  });
2055
2227
  // Maybe not needed as removal would remove circular
2056
2228
  types.validateAllReferences({
2057
- // eslint-disable-next-line object-shorthand -- TS
2058
2229
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
2059
2230
  });
2060
2231
  } else {
2061
- const element = /** @type {import('zodex').SzArray} */ (
2232
+ const element = /** @type {import('zodexy').SzArray} */ (
2062
2233
  specificSchemaObject
2063
2234
  )?.element;
2064
2235
  if (!['void', 'undefined'].includes(
2065
2236
  element?.type
2066
2237
  ) && (
2067
- element?.type !== 'union' ||
2068
- /** @type {import('zodex').SzUnion} */
2238
+ !isUnionLike(element?.type) ||
2239
+ /** @type {import('zodexy').SzUnion} */
2069
2240
  (element)?.options?.every((option) => {
2070
2241
  return !['void', 'undefined'].includes(option.type);
2071
2242
  })
2072
2243
  )) {
2073
- const diff = Number.parseInt(this.value) -
2074
- Number.parseInt(this.$oldvalue ?? this.defaultValue);
2244
+ // On the first length change there is no prior value to
2245
+ // grow from: `$oldvalue` is unset and the `<input>` has
2246
+ // no `value` attribute, so `defaultValue` is `''`. Only
2247
+ // auto-add items when there is a numeric baseline to
2248
+ // measure the increase against (previously this fell out
2249
+ // naturally because `parseInt('')` is `NaN`, making
2250
+ // `diff` `NaN` and the loop a no-op; `Number('')` is
2251
+ // `0`, so the guard must now be explicit).
2252
+ const prev = this.$oldvalue ?? this.defaultValue;
2253
+ const diff = (/^\d+$/u).test(prev)
2254
+ ? Math.trunc(Number(this.value)) - Math.trunc(Number(prev))
2255
+ : 0;
2075
2256
  for (let i = 0; i < diff; i++) {
2076
2257
  // Timeout needed by Cypress at least or will get
2077
2258
  // validation triggered which prevents moving forward
2078
2259
  setTimeout(() => {
2079
2260
  div.$addArrayElement({});
2080
- });
2261
+ }, 0);
2081
2262
  }
2082
2263
  }
2083
2264
  }
@@ -2159,7 +2340,6 @@ const arrayType = {
2159
2340
  this.closest('.arrayContents')
2160
2341
  );
2161
2342
  const arrayItems =
2162
- // eslint-disable-next-line @stylistic/max-len -- Long
2163
2343
  /** @type {HTMLDivElement & {$getPropertyInputs: GetPropertyInputs;}} */ (
2164
2344
  $e(/** @type {HTMLElement} */ (arrayContents), '.arrayItems')
2165
2345
  );
@@ -2167,14 +2347,12 @@ const arrayType = {
2167
2347
  if (lastElement && !lastElement.matches('[data-required]')) {
2168
2348
  lastElement.remove();
2169
2349
  decrementItemIndex(arrayItems);
2170
- // eslint-disable-next-line @stylistic/max-len -- Long
2171
2350
  /** @type {HTMLDivElement & {$redrawMoveArrows: RedrawMoveArrows}} */ (
2172
2351
  $e(/** @type {HTMLElement} */ (arrayContents), '.arrayItems')
2173
2352
  ).$redrawMoveArrows();
2174
2353
  }
2175
2354
  // Maybe not needed as removal would remove circular
2176
2355
  types.validateAllReferences({
2177
- // eslint-disable-next-line object-shorthand -- TS
2178
2356
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
2179
2357
  });
2180
2358
  }}}, ['- Last item']],
@@ -2184,7 +2362,6 @@ const arrayType = {
2184
2362
  /** @type {HTMLElement} */ (this).closest('.arrayContents')
2185
2363
  );
2186
2364
  const arrayItems =
2187
- // eslint-disable-next-line @stylistic/max-len -- Long
2188
2365
  /** @type {HTMLDivElement & {$getPropertyInputs: GetPropertyInputs}} */ ($e(
2189
2366
  arrayContents,
2190
2367
  '.arrayItems'
@@ -2206,7 +2383,6 @@ const arrayType = {
2206
2383
  }
2207
2384
  // Maybe not needed as removal would remove circular
2208
2385
  types.validateAllReferences({
2209
- // eslint-disable-next-line object-shorthand -- TS
2210
2386
  topRoot: /** @type {HTMLDivElement} */ (topRoot)
2211
2387
  });
2212
2388
  }}}, ['x All']]
@@ -2215,26 +2391,49 @@ const arrayType = {
2215
2391
 
2216
2392
  const parentType = type;
2217
2393
 
2394
+ /**
2395
+ * @typedef {() => HTMLElement} GetAddArrayElement
2396
+ */
2397
+
2398
+ /**
2399
+ * @typedef {HTMLDivElement & {
2400
+ * $addAndSetArrayElement:
2401
+ * import('../formats/structuredCloning.js').AddAndSetArrayElement,
2402
+ * $addArrayElement: AddArrayElement,
2403
+ * $getArrayItems: GetArrayItems,
2404
+ * $getAddArrayElement: GetAddArrayElement,
2405
+ * $getTypeChoices: () => HTMLSelectElement & {
2406
+ * $setType: import('../typeChoices.js').SetType,
2407
+ * $getTypeRoot: import('../formatAndTypeChoices.js').TypeRootGetter
2408
+ * }
2409
+ * }} DivArrayOrObjectHolder
2410
+ */
2411
+
2218
2412
  const div =
2219
2413
  /**
2220
- * @type {HTMLDivElement & {
2221
- * $addAndSetArrayElement:
2222
- * import('../formats/structuredCloning.js').AddAndSetArrayElement,
2223
- * $addArrayElement: AddArrayElement
2224
- * $getArrayItems: GetArrayItems,
2225
- * $getMapKeySelects?: GetMapKeySelects
2226
- * }}
2414
+ * @type {DivArrayOrObjectHolder}
2227
2415
  */ (
2228
- jml('div', /** @type {import('jamilih').JamilihAttributes} */ ({
2229
- dataset: {type},
2416
+ jml('div', {
2417
+ // `record`/`tuple` render through `object`/`array`; flag the
2418
+ // refinement for `getValue` (no schema in scope) and styling/tests.
2419
+ dataset: {
2420
+ type,
2421
+ ...(recordMode ? {record: 'true'} : {}),
2422
+ ...(tupleMode ? {tuple: 'true'} : {})
2423
+ },
2230
2424
  // is: 'array-or-object-editor',
2231
2425
  $custom: {
2232
- // eslint-disable-next-line @stylistic/max-len -- Long
2233
- /** @type {import('../formats/structuredCloning.js').AddAndSetArrayElement} */
2234
- $addAndSetArrayElement ({
2235
- propName, type, value, bringIntoFocus, setAValue,
2236
- schemaContent: schema, schemaIdx, mustBeOptional
2237
- }) {
2426
+ /**
2427
+ * @this {DivArrayOrObjectHolder}
2428
+ * @param {Parameters<
2429
+ * import('../formats/structuredCloning.js').AddAndSetArrayElement
2430
+ * >[0]} cfg
2431
+ */
2432
+ $addAndSetArrayElement (cfg) {
2433
+ const {
2434
+ propName, type, value, bringIntoFocus, setAValue,
2435
+ schemaContent: schema, schemaIdx, mustBeOptional
2436
+ } = cfg;
2238
2437
  if (parentType === 'map') {
2239
2438
  if (propName === '0') {
2240
2439
  this.$addArrayElement({
@@ -2244,12 +2443,12 @@ const arrayType = {
2244
2443
  });
2245
2444
  const arrayItems = this.$getArrayItems();
2246
2445
  const keyTypeChoices = /**
2247
- * @type {HTMLSelectElement & {
2248
- * $setType: import('../typeChoices.js').SetType,
2249
- * $getTypeRoot: import('../formatAndTypeChoices.js').
2250
- * TypeRootGetter
2251
- * }}
2252
- */ (DOM.filterChildElements(
2446
+ * @type {HTMLSelectElement & {
2447
+ * $setType: import('../typeChoices.js').SetType,
2448
+ * $getTypeRoot: import('../formatAndTypeChoices.js').
2449
+ * TypeRootGetter
2450
+ * }}
2451
+ */ (DOM.filterChildElements(
2253
2452
  arrayItems,
2254
2453
  [
2255
2454
  'fieldset:last-of-type', 'legend',
@@ -2264,7 +2463,7 @@ const arrayType = {
2264
2463
  // The key may itself be a map, etc.
2265
2464
  return keyTypeChoices.$getTypeRoot();
2266
2465
  }
2267
- } else if (parentType === 'record') {
2466
+ } else if (recordMode) {
2268
2467
  this.$addArrayElement({
2269
2468
  propName, autoTrigger: false,
2270
2469
  required: false
@@ -2282,8 +2481,10 @@ const arrayType = {
2282
2481
  typeChoices.$setType({
2283
2482
  type, baseValue: value, bringIntoFocus,
2284
2483
  specificSchema:
2285
- schema?.type === 'union' && schemaIdx !== undefined
2286
- ? schema.options[schemaIdx]
2484
+ schemaIdx !== undefined && isUnionLike(schema?.type)
2485
+ ? /** @type {import('zodexy').SzUnion} */ (
2486
+ schema
2487
+ ).options[schemaIdx]
2287
2488
  : schema,
2288
2489
  avoidReport: true
2289
2490
  });
@@ -2298,11 +2499,13 @@ const arrayType = {
2298
2499
  types.getTypeObject(type)
2299
2500
  );
2300
2501
  if (typeObj.setValue) {
2301
- typeObj.setValue({root, value});
2502
+ typeObj.setValue({
2503
+ root: /** @type {HTMLDivElement} */ (root), value
2504
+ });
2302
2505
  }
2303
2506
  }
2304
2507
  types.validate({
2305
- type, root, topRoot,
2508
+ type, root: /** @type {HTMLDivElement} */ (root), topRoot,
2306
2509
  // We don't want focus when values auto-added
2307
2510
  avoidReport: true
2308
2511
  });
@@ -2310,26 +2513,28 @@ const arrayType = {
2310
2513
  },
2311
2514
 
2312
2515
  /**
2313
- * @typedef {() => Element} GetAddArrayElement
2516
+ * @this {DivArrayOrObjectHolder}
2517
+ * @type {GetAddArrayElement}
2314
2518
  */
2315
-
2316
- /** @type {GetAddArrayElement} */
2317
2519
  $getAddArrayElement () {
2318
- const el = this.
2319
- lastElementChild.firstElementChild.nextElementSibling;
2320
- return sparse ? el.nextElementSibling : el;
2520
+ const el = /** @type {Element} */ (
2521
+ /** @type {Element} */ (
2522
+ lastTypeChild(this)
2523
+ ).firstElementChild
2524
+ ).nextElementSibling;
2525
+ return /** @type {HTMLElement} */ (
2526
+ sparse ? el?.nextElementSibling : el
2527
+ );
2321
2528
  },
2322
2529
  /**
2323
- * @type {AddArrayElement}
2324
- * @this {HTMLDivElement & {
2325
- * $getAddArrayElement: GetAddArrayElement
2326
- * }}
2530
+ * @this {DivArrayOrObjectHolder}
2531
+ * @param {Parameters<AddArrayElement>[0]} cfg
2327
2532
  */
2328
- // @ts-expect-error TS is apparently getting wrong $addArrayElement
2329
- $addArrayElement ({
2330
- propName, splice, alwaysFocus, required, schema, schemaIdx,
2331
- autoTrigger
2332
- }) {
2533
+ $addArrayElement (cfg) {
2534
+ const {
2535
+ propName, splice, alwaysFocus, required, schema, schemaIdx,
2536
+ autoTrigger
2537
+ } = cfg;
2333
2538
  const addArrayElement = this.$getAddArrayElement();
2334
2539
  /**
2335
2540
  * @type {HTMLButtonElement & {
@@ -2343,16 +2548,36 @@ const arrayType = {
2343
2548
  autoTrigger
2344
2549
  });
2345
2550
  },
2551
+ /**
2552
+ * @this {DivArrayOrObjectHolder}
2553
+ * @type {GetArrayItems}
2554
+ */
2346
2555
  $getArrayItems () {
2347
- const addArrayElement = this.$getAddArrayElement();
2348
- return addArrayElement.previousElementSibling;
2556
+ return /** @type {ReturnType<GetArrayItems>} */ (
2557
+ this.$getAddArrayElement().previousElementSibling
2558
+ );
2349
2559
  },
2560
+ /**
2561
+ * @this {DivArrayOrObjectHolder}
2562
+ * @returns {HTMLSelectElement & {
2563
+ * $setType: import('../typeChoices.js').SetType,
2564
+ * $getTypeRoot: import('../formatAndTypeChoices.js').TypeRootGetter
2565
+ * }}
2566
+ */
2350
2567
  $getTypeChoices () {
2351
2568
  const arrayItems = this.$getArrayItems();
2352
- return $e(
2353
- arrayItems.lastElementChild,
2354
- `fieldset > .typeChoices-${typeNamespace}` // Avoid keys
2355
- );
2569
+ const typeChoices =
2570
+ /**
2571
+ * @type {HTMLSelectElement & {
2572
+ * $setType: import('../typeChoices.js').SetType,
2573
+ * $getTypeRoot: import('../formatAndTypeChoices.js').
2574
+ * TypeRootGetter
2575
+ * }}
2576
+ */ ($e(
2577
+ /** @type {Element} */ (arrayItems.lastElementChild),
2578
+ `fieldset > .typeChoices-${typeNamespace}` // Avoid keys
2579
+ ));
2580
+ return typeChoices;
2356
2581
  }
2357
2582
  },
2358
2583
  $on: {
@@ -2375,11 +2600,11 @@ const arrayType = {
2375
2600
  }
2376
2601
  }
2377
2602
  }
2378
- }), /** @type {import('jamilih').JamilihChildren} */ ([
2603
+ }, /** @type {import('jamilih').JamilihChildren} */ ([
2379
2604
  [specificSchemaObject ? 'span' : 'b', {
2380
- title: specificSchemaObject?.description ?? (DOM.initialCaps(
2605
+ title: schemaLabel(specificSchemaObject) ?? (DOM.initialCaps(
2381
2606
  /** @type {import('../types.js').AvailableType} */
2382
- (type)
2607
+ (itemType)
2383
2608
  ).replace(/s$/u, ''))
2384
2609
  }, [
2385
2610
  specificSchemaObject
@@ -2412,7 +2637,12 @@ const arrayType = {
2412
2637
  type: 'file',
2413
2638
  value: file,
2414
2639
  bringIntoFocus: false,
2415
- setAValue: true
2640
+ setAValue: true,
2641
+ schemaContent: /** @type {import('zodexy').SzArray} */ (
2642
+ /** @type {import('zodexy').SzCodec} */ (
2643
+ specificSchemaObject
2644
+ )?.output
2645
+ )?.element
2416
2646
  });
2417
2647
  }
2418
2648
  }
@@ -2423,16 +2653,29 @@ const arrayType = {
2423
2653
  arrayContents
2424
2654
  ]))
2425
2655
  );
2426
- topRoot = topRoot || div;
2656
+ topRoot ||= div;
2427
2657
 
2428
- if (!objectValue && specificSchemaObject) {
2658
+ if (!objectValue && specificSchemaObject && tupleMode) {
2659
+ // See comment referencing `arrayType.js` in `typeChoices.js`
2660
+ if (!schemaFallingBack) {
2661
+ const specificSchemaObj = /** @type {import('zodexy').SzTuple} */ (
2662
+ specificSchemaObject
2663
+ );
2664
+ if (specificSchemaObj?.items?.[0]?.type !== 'never') {
2665
+ for (const schema of specificSchemaObj.items) {
2666
+ div.$addArrayElement({schema, required: true});
2667
+ }
2668
+ }
2669
+ }
2670
+ } else if (!objectValue && specificSchemaObject) {
2429
2671
  switch (type) {
2430
2672
  case 'object': {
2431
2673
  // See comment referencing `arrayType.js` in `typeChoices.js`
2432
2674
  if (!schemaFallingBack) {
2433
2675
  for (const [prop, val] of
2676
+ // eslint-disable-next-line unicorn/no-unreadable-for-of-expression -- Convenient
2434
2677
  Object.entries(
2435
- /** @type {import('zodex').SzObject} */ (
2678
+ /** @type {import('zodexy').SzObject} */ (
2436
2679
  specificSchemaObject
2437
2680
  /* istanbul ignore next -- Should always have `properties` */
2438
2681
  ).properties ?? {}
@@ -2445,27 +2688,9 @@ const arrayType = {
2445
2688
  }
2446
2689
  break;
2447
2690
  }
2448
- case 'tuple': {
2449
- // See comment referencing `arrayType.js` in `typeChoices.js`
2450
- if (!schemaFallingBack) {
2451
- const specificSchemaObj = /** @type {import('zodex').SzTuple} */ (
2452
- specificSchemaObject
2453
- );
2454
- if (
2455
- /** @type {import('zodex').SzTuple} */ (
2456
- specificSchemaObject
2457
- )?.items?.[0]?.type !== 'never'
2458
- ) {
2459
- for (const schema of specificSchemaObj.items) {
2460
- div.$addArrayElement({schema, required: true});
2461
- }
2462
- }
2463
- }
2464
- break;
2465
- }
2466
2691
  // case 'array': // None with schemas?
2467
2692
  case 'arrayNonindexKeys': {
2468
- const {minLength = 0} = /** @type {import('zodex').SzArray} */ (
2693
+ const {minLength = 0} = /** @type {import('zodexy').SzArray} */ (
2469
2694
  specificSchemaObject
2470
2695
  );
2471
2696
  const arrayLengthInput =
@@ -2482,7 +2707,7 @@ const arrayType = {
2482
2707
  } case 'set': {
2483
2708
  // See comment referencing `arrayType.js` in `typeChoices.js`
2484
2709
  if (!schemaFallingBack) {
2485
- const {minSize = 0} = /** @type {import('zodex').SzSet} */ (
2710
+ const {minSize = 0} = /** @type {import('zodexy').SzSet} */ (
2486
2711
  specificSchemaObject
2487
2712
  );
2488
2713
  for (let i = 0; i < minSize; i++) {
@@ -2490,6 +2715,16 @@ const arrayType = {
2490
2715
  }
2491
2716
  }
2492
2717
  break;
2718
+ } case 'map': {
2719
+ if (!schemaFallingBack) {
2720
+ const {min = 0} = /** @type {import('zodexy').SzMap<any, any>} */ (
2721
+ specificSchemaObject
2722
+ );
2723
+ for (let i = 0; i < min; i++) {
2724
+ div.$addArrayElement({required: true});
2725
+ }
2726
+ }
2727
+ break;
2493
2728
  } default:
2494
2729
  break;
2495
2730
  }