@shapecraft/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/dist/cjs/common/array.d.ts +3 -0
  2. package/dist/cjs/common/array.d.ts.map +1 -0
  3. package/dist/cjs/common/array.js +17 -0
  4. package/dist/cjs/common/array.js.map +1 -0
  5. package/dist/cjs/common/index.d.ts +6 -0
  6. package/dist/cjs/common/index.d.ts.map +1 -0
  7. package/dist/cjs/common/index.js +22 -0
  8. package/dist/cjs/common/index.js.map +1 -0
  9. package/dist/cjs/common/is.d.ts +5 -0
  10. package/dist/cjs/common/is.d.ts.map +1 -0
  11. package/dist/cjs/common/is.js +36 -0
  12. package/dist/cjs/common/is.js.map +1 -0
  13. package/dist/cjs/common/object.d.ts +4 -0
  14. package/dist/cjs/common/object.d.ts.map +1 -0
  15. package/dist/cjs/common/object.js +20 -0
  16. package/dist/cjs/common/object.js.map +1 -0
  17. package/dist/cjs/common/phantom.d.ts +2 -0
  18. package/dist/cjs/common/phantom.d.ts.map +1 -0
  19. package/dist/cjs/common/phantom.js +3 -0
  20. package/dist/cjs/common/phantom.js.map +1 -0
  21. package/dist/cjs/common/result.d.ts +22 -0
  22. package/dist/cjs/common/result.d.ts.map +1 -0
  23. package/dist/cjs/common/result.js +28 -0
  24. package/dist/cjs/common/result.js.map +1 -0
  25. package/dist/cjs/common/string.d.ts +3 -0
  26. package/dist/cjs/common/string.d.ts.map +1 -0
  27. package/dist/cjs/common/string.js +33 -0
  28. package/dist/cjs/common/string.js.map +1 -0
  29. package/dist/cjs/common/types.d.ts +14 -0
  30. package/dist/cjs/common/types.d.ts.map +1 -0
  31. package/dist/cjs/common/types.js +3 -0
  32. package/dist/cjs/common/types.js.map +1 -0
  33. package/dist/cjs/index.d.ts +2 -0
  34. package/dist/cjs/index.d.ts.map +1 -0
  35. package/dist/cjs/index.js +18 -0
  36. package/dist/cjs/index.js.map +1 -0
  37. package/dist/cjs/shape/annotate.d.ts +57 -0
  38. package/dist/cjs/shape/annotate.d.ts.map +1 -0
  39. package/dist/cjs/shape/annotate.js +37 -0
  40. package/dist/cjs/shape/annotate.js.map +1 -0
  41. package/dist/cjs/shape/annotation.d.ts +39 -0
  42. package/dist/cjs/shape/annotation.d.ts.map +1 -0
  43. package/dist/cjs/shape/annotation.js +3 -0
  44. package/dist/cjs/shape/annotation.js.map +1 -0
  45. package/dist/cjs/shape/base.d.ts +33 -0
  46. package/dist/cjs/shape/base.d.ts.map +1 -0
  47. package/dist/cjs/shape/base.js +26 -0
  48. package/dist/cjs/shape/base.js.map +1 -0
  49. package/dist/cjs/shape/builder.d.ts +168 -0
  50. package/dist/cjs/shape/builder.d.ts.map +1 -0
  51. package/dist/cjs/shape/builder.js +156 -0
  52. package/dist/cjs/shape/builder.js.map +1 -0
  53. package/dist/cjs/shape/error.d.ts +5 -0
  54. package/dist/cjs/shape/error.d.ts.map +1 -0
  55. package/dist/cjs/shape/error.js +3 -0
  56. package/dist/cjs/shape/error.js.map +1 -0
  57. package/dist/cjs/shape/index.d.ts +4 -0
  58. package/dist/cjs/shape/index.d.ts.map +1 -0
  59. package/dist/cjs/shape/index.js +20 -0
  60. package/dist/cjs/shape/index.js.map +1 -0
  61. package/dist/cjs/shape/number.d.ts +8 -0
  62. package/dist/cjs/shape/number.d.ts.map +1 -0
  63. package/dist/cjs/shape/number.js +123 -0
  64. package/dist/cjs/shape/number.js.map +1 -0
  65. package/dist/cjs/shape/shape.d.ts +150 -0
  66. package/dist/cjs/shape/shape.d.ts.map +1 -0
  67. package/dist/cjs/shape/shape.js +158 -0
  68. package/dist/cjs/shape/shape.js.map +1 -0
  69. package/dist/cjs/shape/tags.d.ts +4 -0
  70. package/dist/cjs/shape/tags.d.ts.map +1 -0
  71. package/dist/cjs/shape/tags.js +3 -0
  72. package/dist/cjs/shape/tags.js.map +1 -0
  73. package/dist/cjs/shape/transforms/index.d.ts +4 -0
  74. package/dist/cjs/shape/transforms/index.d.ts.map +1 -0
  75. package/dist/cjs/shape/transforms/index.js +20 -0
  76. package/dist/cjs/shape/transforms/index.js.map +1 -0
  77. package/dist/cjs/shape/transforms/json-schema/index.d.ts +3 -0
  78. package/dist/cjs/shape/transforms/json-schema/index.d.ts.map +1 -0
  79. package/dist/cjs/shape/transforms/json-schema/index.js +19 -0
  80. package/dist/cjs/shape/transforms/json-schema/index.js.map +1 -0
  81. package/dist/cjs/shape/transforms/json-schema/transform.d.ts +5 -0
  82. package/dist/cjs/shape/transforms/json-schema/transform.d.ts.map +1 -0
  83. package/dist/cjs/shape/transforms/json-schema/transform.js +739 -0
  84. package/dist/cjs/shape/transforms/json-schema/transform.js.map +1 -0
  85. package/dist/cjs/shape/transforms/json-schema/types.d.ts +87 -0
  86. package/dist/cjs/shape/transforms/json-schema/types.d.ts.map +1 -0
  87. package/dist/cjs/shape/transforms/json-schema/types.js +3 -0
  88. package/dist/cjs/shape/transforms/json-schema/types.js.map +1 -0
  89. package/dist/cjs/shape/transforms/sql/dialects/dialect.d.ts +51 -0
  90. package/dist/cjs/shape/transforms/sql/dialects/dialect.d.ts.map +1 -0
  91. package/dist/cjs/shape/transforms/sql/dialects/dialect.js +8 -0
  92. package/dist/cjs/shape/transforms/sql/dialects/dialect.js.map +1 -0
  93. package/dist/cjs/shape/transforms/sql/dialects/index.d.ts +7 -0
  94. package/dist/cjs/shape/transforms/sql/dialects/index.d.ts.map +1 -0
  95. package/dist/cjs/shape/transforms/sql/dialects/index.js +19 -0
  96. package/dist/cjs/shape/transforms/sql/dialects/index.js.map +1 -0
  97. package/dist/cjs/shape/transforms/sql/dialects/postgres.d.ts +8 -0
  98. package/dist/cjs/shape/transforms/sql/dialects/postgres.d.ts.map +1 -0
  99. package/dist/cjs/shape/transforms/sql/dialects/postgres.js +374 -0
  100. package/dist/cjs/shape/transforms/sql/dialects/postgres.js.map +1 -0
  101. package/dist/cjs/shape/transforms/sql/dialects/sqlite.d.ts +3 -0
  102. package/dist/cjs/shape/transforms/sql/dialects/sqlite.d.ts.map +1 -0
  103. package/dist/cjs/shape/transforms/sql/dialects/sqlite.js +318 -0
  104. package/dist/cjs/shape/transforms/sql/dialects/sqlite.js.map +1 -0
  105. package/dist/cjs/shape/transforms/sql/from-sql.d.ts +5 -0
  106. package/dist/cjs/shape/transforms/sql/from-sql.d.ts.map +1 -0
  107. package/dist/cjs/shape/transforms/sql/from-sql.js +201 -0
  108. package/dist/cjs/shape/transforms/sql/from-sql.js.map +1 -0
  109. package/dist/cjs/shape/transforms/sql/index.d.ts +4 -0
  110. package/dist/cjs/shape/transforms/sql/index.d.ts.map +1 -0
  111. package/dist/cjs/shape/transforms/sql/index.js +20 -0
  112. package/dist/cjs/shape/transforms/sql/index.js.map +1 -0
  113. package/dist/cjs/shape/transforms/sql/options.d.ts +6 -0
  114. package/dist/cjs/shape/transforms/sql/options.d.ts.map +1 -0
  115. package/dist/cjs/shape/transforms/sql/options.js +6 -0
  116. package/dist/cjs/shape/transforms/sql/options.js.map +1 -0
  117. package/dist/cjs/shape/transforms/sql/parser/check-decoder.d.ts +25 -0
  118. package/dist/cjs/shape/transforms/sql/parser/check-decoder.d.ts.map +1 -0
  119. package/dist/cjs/shape/transforms/sql/parser/check-decoder.js +417 -0
  120. package/dist/cjs/shape/transforms/sql/parser/check-decoder.js.map +1 -0
  121. package/dist/cjs/shape/transforms/sql/parser/create-domain.d.ts +11 -0
  122. package/dist/cjs/shape/transforms/sql/parser/create-domain.d.ts.map +1 -0
  123. package/dist/cjs/shape/transforms/sql/parser/create-domain.js +95 -0
  124. package/dist/cjs/shape/transforms/sql/parser/create-domain.js.map +1 -0
  125. package/dist/cjs/shape/transforms/sql/parser/create-table.d.ts +28 -0
  126. package/dist/cjs/shape/transforms/sql/parser/create-table.d.ts.map +1 -0
  127. package/dist/cjs/shape/transforms/sql/parser/create-table.js +744 -0
  128. package/dist/cjs/shape/transforms/sql/parser/create-table.js.map +1 -0
  129. package/dist/cjs/shape/transforms/sql/parser/create-type.d.ts +23 -0
  130. package/dist/cjs/shape/transforms/sql/parser/create-type.d.ts.map +1 -0
  131. package/dist/cjs/shape/transforms/sql/parser/create-type.js +76 -0
  132. package/dist/cjs/shape/transforms/sql/parser/create-type.js.map +1 -0
  133. package/dist/cjs/shape/transforms/sql/parser/cursor.d.ts +32 -0
  134. package/dist/cjs/shape/transforms/sql/parser/cursor.d.ts.map +1 -0
  135. package/dist/cjs/shape/transforms/sql/parser/cursor.js +168 -0
  136. package/dist/cjs/shape/transforms/sql/parser/cursor.js.map +1 -0
  137. package/dist/cjs/shape/transforms/sql/parser/default-decoder.d.ts +10 -0
  138. package/dist/cjs/shape/transforms/sql/parser/default-decoder.d.ts.map +1 -0
  139. package/dist/cjs/shape/transforms/sql/parser/default-decoder.js +125 -0
  140. package/dist/cjs/shape/transforms/sql/parser/default-decoder.js.map +1 -0
  141. package/dist/cjs/shape/transforms/sql/parser/lexer.d.ts +14 -0
  142. package/dist/cjs/shape/transforms/sql/parser/lexer.d.ts.map +1 -0
  143. package/dist/cjs/shape/transforms/sql/parser/lexer.js +259 -0
  144. package/dist/cjs/shape/transforms/sql/parser/lexer.js.map +1 -0
  145. package/dist/cjs/shape/transforms/sql/parser/pg-types.d.ts +21 -0
  146. package/dist/cjs/shape/transforms/sql/parser/pg-types.d.ts.map +1 -0
  147. package/dist/cjs/shape/transforms/sql/parser/pg-types.js +213 -0
  148. package/dist/cjs/shape/transforms/sql/parser/pg-types.js.map +1 -0
  149. package/dist/cjs/shape/transforms/sql/parser/sqlite-types.d.ts +8 -0
  150. package/dist/cjs/shape/transforms/sql/parser/sqlite-types.d.ts.map +1 -0
  151. package/dist/cjs/shape/transforms/sql/parser/sqlite-types.js +93 -0
  152. package/dist/cjs/shape/transforms/sql/parser/sqlite-types.js.map +1 -0
  153. package/dist/cjs/shape/transforms/sql/parser/statements.d.ts +9 -0
  154. package/dist/cjs/shape/transforms/sql/parser/statements.d.ts.map +1 -0
  155. package/dist/cjs/shape/transforms/sql/parser/statements.js +158 -0
  156. package/dist/cjs/shape/transforms/sql/parser/statements.js.map +1 -0
  157. package/dist/cjs/shape/transforms/sql/parser/type-spec.d.ts +12 -0
  158. package/dist/cjs/shape/transforms/sql/parser/type-spec.d.ts.map +1 -0
  159. package/dist/cjs/shape/transforms/sql/parser/type-spec.js +136 -0
  160. package/dist/cjs/shape/transforms/sql/parser/type-spec.js.map +1 -0
  161. package/dist/cjs/shape/transforms/sql/transform.d.ts +5 -0
  162. package/dist/cjs/shape/transforms/sql/transform.d.ts.map +1 -0
  163. package/dist/cjs/shape/transforms/sql/transform.js +262 -0
  164. package/dist/cjs/shape/transforms/sql/transform.js.map +1 -0
  165. package/dist/cjs/shape/transforms/typescript/index.d.ts +2 -0
  166. package/dist/cjs/shape/transforms/typescript/index.d.ts.map +1 -0
  167. package/dist/cjs/shape/transforms/typescript/index.js +18 -0
  168. package/dist/cjs/shape/transforms/typescript/index.js.map +1 -0
  169. package/dist/cjs/shape/transforms/typescript/transform.d.ts +3 -0
  170. package/dist/cjs/shape/transforms/typescript/transform.d.ts.map +1 -0
  171. package/dist/cjs/shape/transforms/typescript/transform.js +190 -0
  172. package/dist/cjs/shape/transforms/typescript/transform.js.map +1 -0
  173. package/dist/cjs/shape/validate.d.ts +7 -0
  174. package/dist/cjs/shape/validate.d.ts.map +1 -0
  175. package/dist/cjs/shape/validate.js +360 -0
  176. package/dist/cjs/shape/validate.js.map +1 -0
  177. package/dist/esm/common/array.d.ts +3 -0
  178. package/dist/esm/common/array.d.ts.map +1 -0
  179. package/dist/esm/common/array.js +12 -0
  180. package/dist/esm/common/array.js.map +1 -0
  181. package/dist/esm/common/index.d.ts +6 -0
  182. package/dist/esm/common/index.d.ts.map +1 -0
  183. package/dist/esm/common/index.js +6 -0
  184. package/dist/esm/common/index.js.map +1 -0
  185. package/dist/esm/common/is.d.ts +5 -0
  186. package/dist/esm/common/is.d.ts.map +1 -0
  187. package/dist/esm/common/is.js +29 -0
  188. package/dist/esm/common/is.js.map +1 -0
  189. package/dist/esm/common/object.d.ts +4 -0
  190. package/dist/esm/common/object.d.ts.map +1 -0
  191. package/dist/esm/common/object.js +15 -0
  192. package/dist/esm/common/object.js.map +1 -0
  193. package/dist/esm/common/phantom.d.ts +2 -0
  194. package/dist/esm/common/phantom.d.ts.map +1 -0
  195. package/dist/esm/common/phantom.js +2 -0
  196. package/dist/esm/common/phantom.js.map +1 -0
  197. package/dist/esm/common/result.d.ts +22 -0
  198. package/dist/esm/common/result.d.ts.map +1 -0
  199. package/dist/esm/common/result.js +25 -0
  200. package/dist/esm/common/result.js.map +1 -0
  201. package/dist/esm/common/string.d.ts +3 -0
  202. package/dist/esm/common/string.d.ts.map +1 -0
  203. package/dist/esm/common/string.js +28 -0
  204. package/dist/esm/common/string.js.map +1 -0
  205. package/dist/esm/common/types.d.ts +14 -0
  206. package/dist/esm/common/types.d.ts.map +1 -0
  207. package/dist/esm/common/types.js +2 -0
  208. package/dist/esm/common/types.js.map +1 -0
  209. package/dist/esm/index.d.ts +2 -0
  210. package/dist/esm/index.d.ts.map +1 -0
  211. package/dist/esm/index.js +2 -0
  212. package/dist/esm/index.js.map +1 -0
  213. package/dist/esm/shape/annotate.d.ts +57 -0
  214. package/dist/esm/shape/annotate.d.ts.map +1 -0
  215. package/dist/esm/shape/annotate.js +34 -0
  216. package/dist/esm/shape/annotate.js.map +1 -0
  217. package/dist/esm/shape/annotation.d.ts +39 -0
  218. package/dist/esm/shape/annotation.d.ts.map +1 -0
  219. package/dist/esm/shape/annotation.js +2 -0
  220. package/dist/esm/shape/annotation.js.map +1 -0
  221. package/dist/esm/shape/base.d.ts +33 -0
  222. package/dist/esm/shape/base.d.ts.map +1 -0
  223. package/dist/esm/shape/base.js +20 -0
  224. package/dist/esm/shape/base.js.map +1 -0
  225. package/dist/esm/shape/builder.d.ts +168 -0
  226. package/dist/esm/shape/builder.d.ts.map +1 -0
  227. package/dist/esm/shape/builder.js +146 -0
  228. package/dist/esm/shape/builder.js.map +1 -0
  229. package/dist/esm/shape/error.d.ts +5 -0
  230. package/dist/esm/shape/error.d.ts.map +1 -0
  231. package/dist/esm/shape/error.js +2 -0
  232. package/dist/esm/shape/error.js.map +1 -0
  233. package/dist/esm/shape/index.d.ts +4 -0
  234. package/dist/esm/shape/index.d.ts.map +1 -0
  235. package/dist/esm/shape/index.js +4 -0
  236. package/dist/esm/shape/index.js.map +1 -0
  237. package/dist/esm/shape/number.d.ts +8 -0
  238. package/dist/esm/shape/number.d.ts.map +1 -0
  239. package/dist/esm/shape/number.js +114 -0
  240. package/dist/esm/shape/number.js.map +1 -0
  241. package/dist/esm/shape/shape.d.ts +150 -0
  242. package/dist/esm/shape/shape.d.ts.map +1 -0
  243. package/dist/esm/shape/shape.js +121 -0
  244. package/dist/esm/shape/shape.js.map +1 -0
  245. package/dist/esm/shape/tags.d.ts +4 -0
  246. package/dist/esm/shape/tags.d.ts.map +1 -0
  247. package/dist/esm/shape/tags.js +2 -0
  248. package/dist/esm/shape/tags.js.map +1 -0
  249. package/dist/esm/shape/transforms/index.d.ts +4 -0
  250. package/dist/esm/shape/transforms/index.d.ts.map +1 -0
  251. package/dist/esm/shape/transforms/index.js +4 -0
  252. package/dist/esm/shape/transforms/index.js.map +1 -0
  253. package/dist/esm/shape/transforms/json-schema/index.d.ts +3 -0
  254. package/dist/esm/shape/transforms/json-schema/index.d.ts.map +1 -0
  255. package/dist/esm/shape/transforms/json-schema/index.js +3 -0
  256. package/dist/esm/shape/transforms/json-schema/index.js.map +1 -0
  257. package/dist/esm/shape/transforms/json-schema/transform.d.ts +5 -0
  258. package/dist/esm/shape/transforms/json-schema/transform.d.ts.map +1 -0
  259. package/dist/esm/shape/transforms/json-schema/transform.js +734 -0
  260. package/dist/esm/shape/transforms/json-schema/transform.js.map +1 -0
  261. package/dist/esm/shape/transforms/json-schema/types.d.ts +87 -0
  262. package/dist/esm/shape/transforms/json-schema/types.d.ts.map +1 -0
  263. package/dist/esm/shape/transforms/json-schema/types.js +2 -0
  264. package/dist/esm/shape/transforms/json-schema/types.js.map +1 -0
  265. package/dist/esm/shape/transforms/sql/dialects/dialect.d.ts +51 -0
  266. package/dist/esm/shape/transforms/sql/dialects/dialect.d.ts.map +1 -0
  267. package/dist/esm/shape/transforms/sql/dialects/dialect.js +3 -0
  268. package/dist/esm/shape/transforms/sql/dialects/dialect.js.map +1 -0
  269. package/dist/esm/shape/transforms/sql/dialects/index.d.ts +7 -0
  270. package/dist/esm/shape/transforms/sql/dialects/index.d.ts.map +1 -0
  271. package/dist/esm/shape/transforms/sql/dialects/index.js +12 -0
  272. package/dist/esm/shape/transforms/sql/dialects/index.js.map +1 -0
  273. package/dist/esm/shape/transforms/sql/dialects/postgres.d.ts +8 -0
  274. package/dist/esm/shape/transforms/sql/dialects/postgres.d.ts.map +1 -0
  275. package/dist/esm/shape/transforms/sql/dialects/postgres.js +370 -0
  276. package/dist/esm/shape/transforms/sql/dialects/postgres.js.map +1 -0
  277. package/dist/esm/shape/transforms/sql/dialects/sqlite.d.ts +3 -0
  278. package/dist/esm/shape/transforms/sql/dialects/sqlite.d.ts.map +1 -0
  279. package/dist/esm/shape/transforms/sql/dialects/sqlite.js +315 -0
  280. package/dist/esm/shape/transforms/sql/dialects/sqlite.js.map +1 -0
  281. package/dist/esm/shape/transforms/sql/from-sql.d.ts +5 -0
  282. package/dist/esm/shape/transforms/sql/from-sql.d.ts.map +1 -0
  283. package/dist/esm/shape/transforms/sql/from-sql.js +197 -0
  284. package/dist/esm/shape/transforms/sql/from-sql.js.map +1 -0
  285. package/dist/esm/shape/transforms/sql/index.d.ts +4 -0
  286. package/dist/esm/shape/transforms/sql/index.d.ts.map +1 -0
  287. package/dist/esm/shape/transforms/sql/index.js +4 -0
  288. package/dist/esm/shape/transforms/sql/index.js.map +1 -0
  289. package/dist/esm/shape/transforms/sql/options.d.ts +6 -0
  290. package/dist/esm/shape/transforms/sql/options.d.ts.map +1 -0
  291. package/dist/esm/shape/transforms/sql/options.js +2 -0
  292. package/dist/esm/shape/transforms/sql/options.js.map +1 -0
  293. package/dist/esm/shape/transforms/sql/parser/check-decoder.d.ts +25 -0
  294. package/dist/esm/shape/transforms/sql/parser/check-decoder.d.ts.map +1 -0
  295. package/dist/esm/shape/transforms/sql/parser/check-decoder.js +412 -0
  296. package/dist/esm/shape/transforms/sql/parser/check-decoder.js.map +1 -0
  297. package/dist/esm/shape/transforms/sql/parser/create-domain.d.ts +11 -0
  298. package/dist/esm/shape/transforms/sql/parser/create-domain.d.ts.map +1 -0
  299. package/dist/esm/shape/transforms/sql/parser/create-domain.js +91 -0
  300. package/dist/esm/shape/transforms/sql/parser/create-domain.js.map +1 -0
  301. package/dist/esm/shape/transforms/sql/parser/create-table.d.ts +28 -0
  302. package/dist/esm/shape/transforms/sql/parser/create-table.d.ts.map +1 -0
  303. package/dist/esm/shape/transforms/sql/parser/create-table.js +740 -0
  304. package/dist/esm/shape/transforms/sql/parser/create-table.js.map +1 -0
  305. package/dist/esm/shape/transforms/sql/parser/create-type.d.ts +23 -0
  306. package/dist/esm/shape/transforms/sql/parser/create-type.d.ts.map +1 -0
  307. package/dist/esm/shape/transforms/sql/parser/create-type.js +72 -0
  308. package/dist/esm/shape/transforms/sql/parser/create-type.js.map +1 -0
  309. package/dist/esm/shape/transforms/sql/parser/cursor.d.ts +32 -0
  310. package/dist/esm/shape/transforms/sql/parser/cursor.d.ts.map +1 -0
  311. package/dist/esm/shape/transforms/sql/parser/cursor.js +163 -0
  312. package/dist/esm/shape/transforms/sql/parser/cursor.js.map +1 -0
  313. package/dist/esm/shape/transforms/sql/parser/default-decoder.d.ts +10 -0
  314. package/dist/esm/shape/transforms/sql/parser/default-decoder.d.ts.map +1 -0
  315. package/dist/esm/shape/transforms/sql/parser/default-decoder.js +121 -0
  316. package/dist/esm/shape/transforms/sql/parser/default-decoder.js.map +1 -0
  317. package/dist/esm/shape/transforms/sql/parser/lexer.d.ts +14 -0
  318. package/dist/esm/shape/transforms/sql/parser/lexer.d.ts.map +1 -0
  319. package/dist/esm/shape/transforms/sql/parser/lexer.js +253 -0
  320. package/dist/esm/shape/transforms/sql/parser/lexer.js.map +1 -0
  321. package/dist/esm/shape/transforms/sql/parser/pg-types.d.ts +21 -0
  322. package/dist/esm/shape/transforms/sql/parser/pg-types.d.ts.map +1 -0
  323. package/dist/esm/shape/transforms/sql/parser/pg-types.js +208 -0
  324. package/dist/esm/shape/transforms/sql/parser/pg-types.js.map +1 -0
  325. package/dist/esm/shape/transforms/sql/parser/sqlite-types.d.ts +8 -0
  326. package/dist/esm/shape/transforms/sql/parser/sqlite-types.d.ts.map +1 -0
  327. package/dist/esm/shape/transforms/sql/parser/sqlite-types.js +89 -0
  328. package/dist/esm/shape/transforms/sql/parser/sqlite-types.js.map +1 -0
  329. package/dist/esm/shape/transforms/sql/parser/statements.d.ts +9 -0
  330. package/dist/esm/shape/transforms/sql/parser/statements.d.ts.map +1 -0
  331. package/dist/esm/shape/transforms/sql/parser/statements.js +153 -0
  332. package/dist/esm/shape/transforms/sql/parser/statements.js.map +1 -0
  333. package/dist/esm/shape/transforms/sql/parser/type-spec.d.ts +12 -0
  334. package/dist/esm/shape/transforms/sql/parser/type-spec.d.ts.map +1 -0
  335. package/dist/esm/shape/transforms/sql/parser/type-spec.js +130 -0
  336. package/dist/esm/shape/transforms/sql/parser/type-spec.js.map +1 -0
  337. package/dist/esm/shape/transforms/sql/transform.d.ts +5 -0
  338. package/dist/esm/shape/transforms/sql/transform.d.ts.map +1 -0
  339. package/dist/esm/shape/transforms/sql/transform.js +258 -0
  340. package/dist/esm/shape/transforms/sql/transform.js.map +1 -0
  341. package/dist/esm/shape/transforms/typescript/index.d.ts +2 -0
  342. package/dist/esm/shape/transforms/typescript/index.d.ts.map +1 -0
  343. package/dist/esm/shape/transforms/typescript/index.js +2 -0
  344. package/dist/esm/shape/transforms/typescript/index.js.map +1 -0
  345. package/dist/esm/shape/transforms/typescript/transform.d.ts +3 -0
  346. package/dist/esm/shape/transforms/typescript/transform.d.ts.map +1 -0
  347. package/dist/esm/shape/transforms/typescript/transform.js +186 -0
  348. package/dist/esm/shape/transforms/typescript/transform.js.map +1 -0
  349. package/dist/esm/shape/validate.d.ts +7 -0
  350. package/dist/esm/shape/validate.d.ts.map +1 -0
  351. package/dist/esm/shape/validate.js +355 -0
  352. package/dist/esm/shape/validate.js.map +1 -0
  353. package/dist/esm/src/common/array.d.ts +3 -0
  354. package/dist/esm/src/common/array.d.ts.map +1 -0
  355. package/dist/esm/src/common/array.js +12 -0
  356. package/dist/esm/src/common/array.js.map +1 -0
  357. package/dist/esm/src/common/index.d.ts +6 -0
  358. package/dist/esm/src/common/index.d.ts.map +1 -0
  359. package/dist/esm/src/common/index.js +6 -0
  360. package/dist/esm/src/common/index.js.map +1 -0
  361. package/dist/esm/src/common/is.d.ts +5 -0
  362. package/dist/esm/src/common/is.d.ts.map +1 -0
  363. package/dist/esm/src/common/is.js +29 -0
  364. package/dist/esm/src/common/is.js.map +1 -0
  365. package/dist/esm/src/common/object.d.ts +4 -0
  366. package/dist/esm/src/common/object.d.ts.map +1 -0
  367. package/dist/esm/src/common/object.js +15 -0
  368. package/dist/esm/src/common/object.js.map +1 -0
  369. package/dist/esm/src/common/phantom.d.ts +2 -0
  370. package/dist/esm/src/common/phantom.d.ts.map +1 -0
  371. package/dist/esm/src/common/phantom.js +2 -0
  372. package/dist/esm/src/common/phantom.js.map +1 -0
  373. package/dist/esm/src/common/result.d.ts +22 -0
  374. package/dist/esm/src/common/result.d.ts.map +1 -0
  375. package/dist/esm/src/common/result.js +25 -0
  376. package/dist/esm/src/common/result.js.map +1 -0
  377. package/dist/esm/src/common/string.d.ts +3 -0
  378. package/dist/esm/src/common/string.d.ts.map +1 -0
  379. package/dist/esm/src/common/string.js +28 -0
  380. package/dist/esm/src/common/string.js.map +1 -0
  381. package/dist/esm/src/common/types.d.ts +14 -0
  382. package/dist/esm/src/common/types.d.ts.map +1 -0
  383. package/dist/esm/src/common/types.js +2 -0
  384. package/dist/esm/src/common/types.js.map +1 -0
  385. package/dist/esm/src/index.d.ts +2 -0
  386. package/dist/esm/src/index.d.ts.map +1 -0
  387. package/dist/esm/src/index.js +2 -0
  388. package/dist/esm/src/index.js.map +1 -0
  389. package/dist/esm/src/shape/annotate.d.ts +57 -0
  390. package/dist/esm/src/shape/annotate.d.ts.map +1 -0
  391. package/dist/esm/src/shape/annotate.js +34 -0
  392. package/dist/esm/src/shape/annotate.js.map +1 -0
  393. package/dist/esm/src/shape/annotation.d.ts +39 -0
  394. package/dist/esm/src/shape/annotation.d.ts.map +1 -0
  395. package/dist/esm/src/shape/annotation.js +2 -0
  396. package/dist/esm/src/shape/annotation.js.map +1 -0
  397. package/dist/esm/src/shape/base.d.ts +33 -0
  398. package/dist/esm/src/shape/base.d.ts.map +1 -0
  399. package/dist/esm/src/shape/base.js +20 -0
  400. package/dist/esm/src/shape/base.js.map +1 -0
  401. package/dist/esm/src/shape/builder.d.ts +168 -0
  402. package/dist/esm/src/shape/builder.d.ts.map +1 -0
  403. package/dist/esm/src/shape/builder.js +146 -0
  404. package/dist/esm/src/shape/builder.js.map +1 -0
  405. package/dist/esm/src/shape/error.d.ts +5 -0
  406. package/dist/esm/src/shape/error.d.ts.map +1 -0
  407. package/dist/esm/src/shape/error.js +2 -0
  408. package/dist/esm/src/shape/error.js.map +1 -0
  409. package/dist/esm/src/shape/index.d.ts +4 -0
  410. package/dist/esm/src/shape/index.d.ts.map +1 -0
  411. package/dist/esm/src/shape/index.js +4 -0
  412. package/dist/esm/src/shape/index.js.map +1 -0
  413. package/dist/esm/src/shape/number.d.ts +8 -0
  414. package/dist/esm/src/shape/number.d.ts.map +1 -0
  415. package/dist/esm/src/shape/number.js +114 -0
  416. package/dist/esm/src/shape/number.js.map +1 -0
  417. package/dist/esm/src/shape/shape.d.ts +150 -0
  418. package/dist/esm/src/shape/shape.d.ts.map +1 -0
  419. package/dist/esm/src/shape/shape.js +121 -0
  420. package/dist/esm/src/shape/shape.js.map +1 -0
  421. package/dist/esm/src/shape/tags.d.ts +4 -0
  422. package/dist/esm/src/shape/tags.d.ts.map +1 -0
  423. package/dist/esm/src/shape/tags.js +2 -0
  424. package/dist/esm/src/shape/tags.js.map +1 -0
  425. package/dist/esm/src/shape/transforms/index.d.ts +4 -0
  426. package/dist/esm/src/shape/transforms/index.d.ts.map +1 -0
  427. package/dist/esm/src/shape/transforms/index.js +4 -0
  428. package/dist/esm/src/shape/transforms/index.js.map +1 -0
  429. package/dist/esm/src/shape/transforms/json-schema/index.d.ts +3 -0
  430. package/dist/esm/src/shape/transforms/json-schema/index.d.ts.map +1 -0
  431. package/dist/esm/src/shape/transforms/json-schema/index.js +3 -0
  432. package/dist/esm/src/shape/transforms/json-schema/index.js.map +1 -0
  433. package/dist/esm/src/shape/transforms/json-schema/transform.d.ts +5 -0
  434. package/dist/esm/src/shape/transforms/json-schema/transform.d.ts.map +1 -0
  435. package/dist/esm/src/shape/transforms/json-schema/transform.js +734 -0
  436. package/dist/esm/src/shape/transforms/json-schema/transform.js.map +1 -0
  437. package/dist/esm/src/shape/transforms/json-schema/types.d.ts +87 -0
  438. package/dist/esm/src/shape/transforms/json-schema/types.d.ts.map +1 -0
  439. package/dist/esm/src/shape/transforms/json-schema/types.js +2 -0
  440. package/dist/esm/src/shape/transforms/json-schema/types.js.map +1 -0
  441. package/dist/esm/src/shape/transforms/sql/dialects/dialect.d.ts +51 -0
  442. package/dist/esm/src/shape/transforms/sql/dialects/dialect.d.ts.map +1 -0
  443. package/dist/esm/src/shape/transforms/sql/dialects/dialect.js +3 -0
  444. package/dist/esm/src/shape/transforms/sql/dialects/dialect.js.map +1 -0
  445. package/dist/esm/src/shape/transforms/sql/dialects/index.d.ts +7 -0
  446. package/dist/esm/src/shape/transforms/sql/dialects/index.d.ts.map +1 -0
  447. package/dist/esm/src/shape/transforms/sql/dialects/index.js +12 -0
  448. package/dist/esm/src/shape/transforms/sql/dialects/index.js.map +1 -0
  449. package/dist/esm/src/shape/transforms/sql/dialects/postgres.d.ts +8 -0
  450. package/dist/esm/src/shape/transforms/sql/dialects/postgres.d.ts.map +1 -0
  451. package/dist/esm/src/shape/transforms/sql/dialects/postgres.js +370 -0
  452. package/dist/esm/src/shape/transforms/sql/dialects/postgres.js.map +1 -0
  453. package/dist/esm/src/shape/transforms/sql/dialects/sqlite.d.ts +3 -0
  454. package/dist/esm/src/shape/transforms/sql/dialects/sqlite.d.ts.map +1 -0
  455. package/dist/esm/src/shape/transforms/sql/dialects/sqlite.js +315 -0
  456. package/dist/esm/src/shape/transforms/sql/dialects/sqlite.js.map +1 -0
  457. package/dist/esm/src/shape/transforms/sql/from-sql.d.ts +5 -0
  458. package/dist/esm/src/shape/transforms/sql/from-sql.d.ts.map +1 -0
  459. package/dist/esm/src/shape/transforms/sql/from-sql.js +197 -0
  460. package/dist/esm/src/shape/transforms/sql/from-sql.js.map +1 -0
  461. package/dist/esm/src/shape/transforms/sql/index.d.ts +4 -0
  462. package/dist/esm/src/shape/transforms/sql/index.d.ts.map +1 -0
  463. package/dist/esm/src/shape/transforms/sql/index.js +4 -0
  464. package/dist/esm/src/shape/transforms/sql/index.js.map +1 -0
  465. package/dist/esm/src/shape/transforms/sql/options.d.ts +6 -0
  466. package/dist/esm/src/shape/transforms/sql/options.d.ts.map +1 -0
  467. package/dist/esm/src/shape/transforms/sql/options.js +2 -0
  468. package/dist/esm/src/shape/transforms/sql/options.js.map +1 -0
  469. package/dist/esm/src/shape/transforms/sql/parser/check-decoder.d.ts +25 -0
  470. package/dist/esm/src/shape/transforms/sql/parser/check-decoder.d.ts.map +1 -0
  471. package/dist/esm/src/shape/transforms/sql/parser/check-decoder.js +412 -0
  472. package/dist/esm/src/shape/transforms/sql/parser/check-decoder.js.map +1 -0
  473. package/dist/esm/src/shape/transforms/sql/parser/create-domain.d.ts +11 -0
  474. package/dist/esm/src/shape/transforms/sql/parser/create-domain.d.ts.map +1 -0
  475. package/dist/esm/src/shape/transforms/sql/parser/create-domain.js +91 -0
  476. package/dist/esm/src/shape/transforms/sql/parser/create-domain.js.map +1 -0
  477. package/dist/esm/src/shape/transforms/sql/parser/create-table.d.ts +28 -0
  478. package/dist/esm/src/shape/transforms/sql/parser/create-table.d.ts.map +1 -0
  479. package/dist/esm/src/shape/transforms/sql/parser/create-table.js +740 -0
  480. package/dist/esm/src/shape/transforms/sql/parser/create-table.js.map +1 -0
  481. package/dist/esm/src/shape/transforms/sql/parser/create-type.d.ts +23 -0
  482. package/dist/esm/src/shape/transforms/sql/parser/create-type.d.ts.map +1 -0
  483. package/dist/esm/src/shape/transforms/sql/parser/create-type.js +72 -0
  484. package/dist/esm/src/shape/transforms/sql/parser/create-type.js.map +1 -0
  485. package/dist/esm/src/shape/transforms/sql/parser/cursor.d.ts +32 -0
  486. package/dist/esm/src/shape/transforms/sql/parser/cursor.d.ts.map +1 -0
  487. package/dist/esm/src/shape/transforms/sql/parser/cursor.js +163 -0
  488. package/dist/esm/src/shape/transforms/sql/parser/cursor.js.map +1 -0
  489. package/dist/esm/src/shape/transforms/sql/parser/default-decoder.d.ts +10 -0
  490. package/dist/esm/src/shape/transforms/sql/parser/default-decoder.d.ts.map +1 -0
  491. package/dist/esm/src/shape/transforms/sql/parser/default-decoder.js +121 -0
  492. package/dist/esm/src/shape/transforms/sql/parser/default-decoder.js.map +1 -0
  493. package/dist/esm/src/shape/transforms/sql/parser/lexer.d.ts +14 -0
  494. package/dist/esm/src/shape/transforms/sql/parser/lexer.d.ts.map +1 -0
  495. package/dist/esm/src/shape/transforms/sql/parser/lexer.js +253 -0
  496. package/dist/esm/src/shape/transforms/sql/parser/lexer.js.map +1 -0
  497. package/dist/esm/src/shape/transforms/sql/parser/pg-types.d.ts +21 -0
  498. package/dist/esm/src/shape/transforms/sql/parser/pg-types.d.ts.map +1 -0
  499. package/dist/esm/src/shape/transforms/sql/parser/pg-types.js +208 -0
  500. package/dist/esm/src/shape/transforms/sql/parser/pg-types.js.map +1 -0
  501. package/dist/esm/src/shape/transforms/sql/parser/sqlite-types.d.ts +8 -0
  502. package/dist/esm/src/shape/transforms/sql/parser/sqlite-types.d.ts.map +1 -0
  503. package/dist/esm/src/shape/transforms/sql/parser/sqlite-types.js +89 -0
  504. package/dist/esm/src/shape/transforms/sql/parser/sqlite-types.js.map +1 -0
  505. package/dist/esm/src/shape/transforms/sql/parser/statements.d.ts +9 -0
  506. package/dist/esm/src/shape/transforms/sql/parser/statements.d.ts.map +1 -0
  507. package/dist/esm/src/shape/transforms/sql/parser/statements.js +153 -0
  508. package/dist/esm/src/shape/transforms/sql/parser/statements.js.map +1 -0
  509. package/dist/esm/src/shape/transforms/sql/parser/type-spec.d.ts +12 -0
  510. package/dist/esm/src/shape/transforms/sql/parser/type-spec.d.ts.map +1 -0
  511. package/dist/esm/src/shape/transforms/sql/parser/type-spec.js +130 -0
  512. package/dist/esm/src/shape/transforms/sql/parser/type-spec.js.map +1 -0
  513. package/dist/esm/src/shape/transforms/sql/transform.d.ts +5 -0
  514. package/dist/esm/src/shape/transforms/sql/transform.d.ts.map +1 -0
  515. package/dist/esm/src/shape/transforms/sql/transform.js +258 -0
  516. package/dist/esm/src/shape/transforms/sql/transform.js.map +1 -0
  517. package/dist/esm/src/shape/transforms/typescript/index.d.ts +2 -0
  518. package/dist/esm/src/shape/transforms/typescript/index.d.ts.map +1 -0
  519. package/dist/esm/src/shape/transforms/typescript/index.js +2 -0
  520. package/dist/esm/src/shape/transforms/typescript/index.js.map +1 -0
  521. package/dist/esm/src/shape/transforms/typescript/transform.d.ts +3 -0
  522. package/dist/esm/src/shape/transforms/typescript/transform.d.ts.map +1 -0
  523. package/dist/esm/src/shape/transforms/typescript/transform.js +186 -0
  524. package/dist/esm/src/shape/transforms/typescript/transform.js.map +1 -0
  525. package/dist/esm/src/shape/validate.d.ts +7 -0
  526. package/dist/esm/src/shape/validate.d.ts.map +1 -0
  527. package/dist/esm/src/shape/validate.js +355 -0
  528. package/dist/esm/src/shape/validate.js.map +1 -0
  529. package/package.json +40 -0
  530. package/src/common/array.test.ts +19 -0
  531. package/src/common/array.ts +15 -0
  532. package/src/common/index.ts +5 -0
  533. package/src/common/is.ts +23 -0
  534. package/src/common/object.ts +35 -0
  535. package/src/common/phantom.ts +1 -0
  536. package/src/common/result.ts +43 -0
  537. package/src/common/string.ts +28 -0
  538. package/src/common/types.ts +34 -0
  539. package/src/index.ts +1 -0
  540. package/src/shape/annotate.ts +139 -0
  541. package/src/shape/annotation.ts +47 -0
  542. package/src/shape/base.ts +71 -0
  543. package/src/shape/builder.test.ts +728 -0
  544. package/src/shape/builder.ts +475 -0
  545. package/src/shape/error.ts +4 -0
  546. package/src/shape/index.ts +3 -0
  547. package/src/shape/number.ts +118 -0
  548. package/src/shape/shape.test.ts +792 -0
  549. package/src/shape/shape.ts +377 -0
  550. package/src/shape/tags.ts +14 -0
  551. package/src/shape/transforms/index.ts +3 -0
  552. package/src/shape/transforms/json-schema/index.ts +2 -0
  553. package/src/shape/transforms/json-schema/transform.test.ts +850 -0
  554. package/src/shape/transforms/json-schema/transform.ts +882 -0
  555. package/src/shape/transforms/json-schema/types.ts +132 -0
  556. package/src/shape/transforms/sql/dialects/dialect.ts +89 -0
  557. package/src/shape/transforms/sql/dialects/index.ts +14 -0
  558. package/src/shape/transforms/sql/dialects/postgres.ts +392 -0
  559. package/src/shape/transforms/sql/dialects/sqlite.ts +333 -0
  560. package/src/shape/transforms/sql/from-sql.test.ts +704 -0
  561. package/src/shape/transforms/sql/from-sql.ts +210 -0
  562. package/src/shape/transforms/sql/index.ts +3 -0
  563. package/src/shape/transforms/sql/options.ts +6 -0
  564. package/src/shape/transforms/sql/parser/check-decoder.ts +457 -0
  565. package/src/shape/transforms/sql/parser/create-domain.ts +105 -0
  566. package/src/shape/transforms/sql/parser/create-table.ts +809 -0
  567. package/src/shape/transforms/sql/parser/create-type.ts +91 -0
  568. package/src/shape/transforms/sql/parser/cursor.ts +179 -0
  569. package/src/shape/transforms/sql/parser/default-decoder.ts +129 -0
  570. package/src/shape/transforms/sql/parser/lexer.ts +289 -0
  571. package/src/shape/transforms/sql/parser/pg-types.ts +247 -0
  572. package/src/shape/transforms/sql/parser/sqlite-types.ts +103 -0
  573. package/src/shape/transforms/sql/parser/statements.ts +127 -0
  574. package/src/shape/transforms/sql/parser/type-spec.ts +159 -0
  575. package/src/shape/transforms/sql/transform.sqlite.test.ts +448 -0
  576. package/src/shape/transforms/sql/transform.test.ts +880 -0
  577. package/src/shape/transforms/sql/transform.ts +295 -0
  578. package/src/shape/transforms/typescript/index.ts +1 -0
  579. package/src/shape/transforms/typescript/transform.ts +211 -0
  580. package/src/shape/tuple.test.ts +171 -0
  581. package/src/shape/validate.ts +413 -0
  582. package/tsconfig.cjs.json +11 -0
  583. package/tsconfig.esm.json +10 -0
  584. package/tsconfig.json +23 -0
@@ -0,0 +1,882 @@
1
+ import { annotate, shapes } from "../../shape";
2
+ import { NumberTag } from "../../tags";
3
+ import {
4
+ JSONSchema,
5
+ JSONSchemaDefinition,
6
+ JSONSchemaTypeName,
7
+ ShapecraftMeta,
8
+ } from "./types";
9
+
10
+ const INT_RANGES: Record<string, { minimum?: number; maximum?: number }> = {
11
+ int8: { minimum: -128, maximum: 127 },
12
+ uint8: { minimum: 0, maximum: 255 },
13
+ int16: { minimum: -32768, maximum: 32767 },
14
+ uint16: { minimum: 0, maximum: 65535 },
15
+ int32: { minimum: -2_147_483_648, maximum: 2_147_483_647 },
16
+ uint32: { minimum: 0, maximum: 4_294_967_295 },
17
+ int64: { minimum: Number.MIN_SAFE_INTEGER, maximum: Number.MAX_SAFE_INTEGER },
18
+ uint64: { minimum: 0, maximum: Number.MAX_SAFE_INTEGER },
19
+ int: {},
20
+ };
21
+
22
+ const FLOAT32_MAX = 3.4028234663852886e38;
23
+
24
+ const FLOAT_RANGES: Record<string, { minimum?: number; maximum?: number }> = {
25
+ float32: { minimum: -FLOAT32_MAX, maximum: FLOAT32_MAX },
26
+ float64: {},
27
+ float: {},
28
+ number: {},
29
+ };
30
+
31
+ const numberTagRange = (
32
+ tag: NumberTag,
33
+ ): { type: "integer" | "number"; minimum?: number; maximum?: number } => {
34
+ if (tag in INT_RANGES) return { type: "integer", ...(INT_RANGES[tag] ?? {}) };
35
+ return { type: "number", ...(FLOAT_RANGES[tag] ?? {}) };
36
+ };
37
+
38
+ const attachMeta = (out: JSONSchema, meta: ShapecraftMeta): JSONSchema =>
39
+ Object.keys(meta).length === 0 ? out : { ...out, "x-shapecraft": meta };
40
+
41
+ const isLiteralScalar = (s: shapes.Shape): boolean =>
42
+ (s.type === "string" || s.type === "number" || s.type === "boolean") &&
43
+ s.literal === true;
44
+
45
+ type ModuleCtx = {
46
+ tablesByName: Record<string, shapes.ShapeMapping>;
47
+ anchorOf: Record<string, string | undefined>;
48
+ };
49
+
50
+ const refTo = (tableName: string, ctx: ModuleCtx): string => {
51
+ const anchor = ctx.anchorOf[tableName];
52
+ return anchor !== undefined ? `#${anchor}` : `#/$defs/${tableName}`;
53
+ };
54
+
55
+ const convert = (
56
+ shape: shapes.Shape,
57
+ topLevel: boolean,
58
+ modCtx?: ModuleCtx,
59
+ ): JSONSchema => {
60
+ if (
61
+ modCtx !== undefined &&
62
+ shape.anno.foreign !== undefined &&
63
+ shape.anno.foreign.table in modCtx.tablesByName
64
+ ) {
65
+ return { $ref: refTo(shape.anno.foreign.table, modCtx) };
66
+ }
67
+
68
+ const meta: ShapecraftMeta = {};
69
+ if (shape.anno.unique) meta.unique = true;
70
+ if (shape.anno.primary) meta.primary = true;
71
+ if (shape.anno.foreign) meta.foreign = shape.anno.foreign;
72
+ if (topLevel && shape.anno.optional) meta.optional = true;
73
+
74
+ let out: JSONSchema = {};
75
+ switch (shape.type) {
76
+ case "string": {
77
+ if (shape.literal) {
78
+ out = { const: shape.input as string };
79
+ break;
80
+ }
81
+ out = { type: "string" };
82
+ if (shape.anno.min !== undefined) out.minLength = shape.anno.min;
83
+ if (shape.anno.max !== undefined) out.maxLength = shape.anno.max;
84
+ if (shape.anno.pattern !== undefined) {
85
+ out.pattern =
86
+ shape.anno.pattern instanceof RegExp ?
87
+ shape.anno.pattern.source
88
+ : shape.anno.pattern;
89
+ }
90
+ if (shape.anno.format !== undefined) out.format = shape.anno.format;
91
+ break;
92
+ }
93
+ case "number": {
94
+ if (shape.literal) {
95
+ out = { const: shape.input as number };
96
+ break;
97
+ }
98
+ const r = numberTagRange(shape.tag);
99
+ out = { type: r.type };
100
+ if (r.minimum !== undefined) out.minimum = r.minimum;
101
+ if (r.maximum !== undefined) out.maximum = r.maximum;
102
+ if (shape.anno.min !== undefined)
103
+ out.minimum =
104
+ out.minimum === undefined ?
105
+ shape.anno.min
106
+ : Math.max(out.minimum, shape.anno.min);
107
+ if (shape.anno.max !== undefined)
108
+ out.maximum =
109
+ out.maximum === undefined ?
110
+ shape.anno.max
111
+ : Math.min(out.maximum, shape.anno.max);
112
+ meta.numberTag = shape.tag;
113
+ break;
114
+ }
115
+ case "boolean": {
116
+ out =
117
+ shape.literal ? { const: shape.input as boolean } : { type: "boolean" };
118
+ break;
119
+ }
120
+ case "nil":
121
+ out = { type: "null" };
122
+ break;
123
+ case "undefined":
124
+ out = {};
125
+ meta.kind = "undefined";
126
+ break;
127
+ case "unknown":
128
+ out = {};
129
+ break;
130
+ case "date":
131
+ out = { type: "string", format: "date-time" };
132
+ meta.kind = "date";
133
+ break;
134
+ case "binary":
135
+ out = { type: "string", contentEncoding: "base64" };
136
+ meta.kind = "binary";
137
+ break;
138
+ case "array": {
139
+ out = { type: "array", items: convert(shape.input, false, modCtx) };
140
+ if (shape.anno.min !== undefined) out.minItems = shape.anno.min;
141
+ if (shape.anno.max !== undefined) out.maxItems = shape.anno.max;
142
+ if (shape.anno.uniqueItems) out.uniqueItems = true;
143
+ break;
144
+ }
145
+ case "vector": {
146
+ out = {
147
+ type: "array",
148
+ items: convert(shape.input.format, false, modCtx),
149
+ minItems: shape.input.dims,
150
+ maxItems: shape.input.dims,
151
+ };
152
+ meta.kind = "vector";
153
+ meta.vectorDims = shape.input.dims;
154
+ break;
155
+ }
156
+ case "tuple": {
157
+ out = {
158
+ type: "array",
159
+ prefixItems: shape.input.map((s) => convert(s, false, modCtx)),
160
+ minItems: shape.input.length,
161
+ maxItems: shape.input.length,
162
+ };
163
+ meta.kind = "tuple";
164
+ meta.tupleLen = shape.input.length;
165
+ break;
166
+ }
167
+ case "range": {
168
+ const itemSchema = convert(shape.input, false, modCtx);
169
+ out = {
170
+ type: "object",
171
+ properties: {
172
+ lower: { anyOf: [itemSchema, { type: "null" }] },
173
+ upper: { anyOf: [itemSchema, { type: "null" }] },
174
+ lowerInclusive: { type: "boolean" },
175
+ upperInclusive: { type: "boolean" },
176
+ },
177
+ required: ["lower", "upper", "lowerInclusive", "upperInclusive"],
178
+ additionalProperties: false,
179
+ };
180
+ meta.kind = "range";
181
+ break;
182
+ }
183
+ case "mapping": {
184
+ const properties: Record<string, JSONSchema> = {};
185
+ const required: string[] = [];
186
+ for (const [k, child] of Object.entries(shape.input)) {
187
+ properties[k] = convert(child, false, modCtx);
188
+ if (!child.anno.optional) required.push(k);
189
+ }
190
+ out = { type: "object", properties, additionalProperties: false };
191
+ if (required.length > 0) out.required = required;
192
+ break;
193
+ }
194
+ case "record": {
195
+ const [keyShape, valShape] = shape.input;
196
+ out = {
197
+ type: "object",
198
+ additionalProperties: convert(valShape, false, modCtx),
199
+ };
200
+ if (keyShape.type === "string" && keyShape.anno.pattern !== undefined) {
201
+ const src =
202
+ keyShape.anno.pattern instanceof RegExp ?
203
+ keyShape.anno.pattern.source
204
+ : keyShape.anno.pattern;
205
+ out.propertyNames = { type: "string", pattern: src };
206
+ } else if (keyShape.type === "number") {
207
+ out.propertyNames = { type: "string", pattern: "^-?\\d+(\\.\\d+)?$" };
208
+ }
209
+ break;
210
+ }
211
+ case "union": {
212
+ const variants = Array.from(shape.input) as shapes.Shape[];
213
+ if (variants.length > 0 && variants.every(isLiteralScalar)) {
214
+ out = {
215
+ enum: variants.map(
216
+ (v) =>
217
+ (
218
+ v as
219
+ | shapes.ShapeString
220
+ | shapes.ShapeNumber
221
+ | shapes.ShapeBoolean
222
+ ).input as string | number | boolean,
223
+ ),
224
+ };
225
+ } else {
226
+ out = { anyOf: variants.map((v) => convert(v, false, modCtx)) };
227
+ }
228
+ break;
229
+ }
230
+ case "module": {
231
+ const tablesByName: Record<string, shapes.ShapeMapping> = {};
232
+ const anchorOf: Record<string, string | undefined> = {};
233
+ for (const [k, table] of Object.entries(shape.input)) {
234
+ tablesByName[k] = table;
235
+ const a = table.anno.meta?.anchor;
236
+ anchorOf[k] = typeof a === "string" ? a : undefined;
237
+ }
238
+ const ctx: ModuleCtx = { tablesByName, anchorOf };
239
+ const defs: Record<string, JSONSchema> = {};
240
+ for (const [k, table] of Object.entries(shape.input)) {
241
+ const sub = convert(table, false, ctx);
242
+ const anchor = anchorOf[k];
243
+ defs[k] = anchor !== undefined ? { $anchor: anchor, ...sub } : sub;
244
+ }
245
+ out = { $defs: defs };
246
+ break;
247
+ }
248
+ }
249
+
250
+ if (shape.anno.title !== undefined) out.title = shape.anno.title;
251
+ if (shape.anno.description !== undefined)
252
+ out.description = shape.anno.description;
253
+
254
+ return attachMeta(out, meta);
255
+ };
256
+
257
+ export const toJSONSchema = (shape: shapes.Shape): JSONSchema =>
258
+ convert(shape, true);
259
+
260
+ const numberByTag = (tag: NumberTag): shapes.ShapeNumber => {
261
+ switch (tag) {
262
+ case "int":
263
+ return shapes.int();
264
+ case "int8":
265
+ return shapes.int8();
266
+ case "uint8":
267
+ return shapes.uint8();
268
+ case "int16":
269
+ return shapes.int16();
270
+ case "uint16":
271
+ return shapes.uint16();
272
+ case "int32":
273
+ return shapes.int32();
274
+ case "uint32":
275
+ return shapes.uint32();
276
+ case "int64":
277
+ return shapes.int64();
278
+ case "uint64":
279
+ return shapes.uint64();
280
+ case "float":
281
+ return shapes.float();
282
+ case "float32":
283
+ return shapes.float32();
284
+ case "float64":
285
+ return shapes.float64();
286
+ default:
287
+ return shapes.number();
288
+ }
289
+ };
290
+
291
+ const naturalRangeForTag = (
292
+ tag: NumberTag,
293
+ ): { minimum?: number; maximum?: number } => {
294
+ if (tag in INT_RANGES) return INT_RANGES[tag] ?? {};
295
+ return FLOAT_RANGES[tag] ?? {};
296
+ };
297
+
298
+ const asSchema = (def: JSONSchemaDefinition | undefined): JSONSchema => {
299
+ if (def === undefined || def === true) return {};
300
+ if (def === false) return {};
301
+ return def;
302
+ };
303
+
304
+ // JSON Schema doesn't require `type` — when `properties`/`items` are present,
305
+ // the type is implied. Infer it so we don't fall through to `unknown`.
306
+ const effectiveType = (s: JSONSchema): JSONSchemaTypeName | undefined => {
307
+ if (typeof s.type === "string") return s.type;
308
+ if (Array.isArray(s.type) && s.type.length > 0) return s.type[0];
309
+ if (
310
+ s.properties !== undefined ||
311
+ s.additionalProperties !== undefined ||
312
+ s.patternProperties !== undefined ||
313
+ s.required !== undefined ||
314
+ s.propertyNames !== undefined ||
315
+ s.minProperties !== undefined ||
316
+ s.maxProperties !== undefined
317
+ )
318
+ return "object";
319
+ if (
320
+ s.items !== undefined ||
321
+ s.uniqueItems !== undefined ||
322
+ s.minItems !== undefined ||
323
+ s.maxItems !== undefined
324
+ )
325
+ return "array";
326
+ return undefined;
327
+ };
328
+
329
+ const literalFromValue = (v: unknown): shapes.Shape => {
330
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
331
+ return shapes.literal(v);
332
+ if (v === null) return shapes.nil();
333
+ return shapes.unknown();
334
+ };
335
+
336
+ // oneOf/anyOf variants are often refinements on a sibling `type` (e.g.
337
+ // `{type: "string", oneOf: [{format: "ipv4"}, ...]}`). Inherit the parent's
338
+ // effective type into variants that don't declare their own, so each variant
339
+ // resolves to a real shape rather than `unknown`. Drop any variants that
340
+ // still resolve to `unknown` after that, and fall back to type-based handling
341
+ // if nothing substantive survives.
342
+ const combinatorBase = (
343
+ schema: JSONSchema,
344
+ idx: RefIndex | undefined,
345
+ ): shapes.Shape | undefined => {
346
+ const variantsRaw = schema.anyOf ?? schema.oneOf;
347
+ if (variantsRaw === undefined || variantsRaw.length === 0) return undefined;
348
+ const parentType = effectiveType(schema);
349
+ const all = variantsRaw.map((v) => {
350
+ const vs = asSchema(v);
351
+ const merged: JSONSchema =
352
+ (
353
+ vs.type === undefined &&
354
+ parentType !== undefined &&
355
+ vs.$ref === undefined
356
+ ) ?
357
+ { type: parentType, ...vs }
358
+ : vs;
359
+ return convertFrom(merged, false, idx);
360
+ });
361
+ const substantive = all.filter((s) => s.type !== "unknown");
362
+ if (substantive.length === 0) return undefined;
363
+ if (substantive.length === 1) return substantive[0];
364
+ return shapes.union(substantive);
365
+ };
366
+
367
+ const convertFrom = (
368
+ schema: JSONSchema,
369
+ topLevel: boolean,
370
+ idx?: RefIndex,
371
+ ): shapes.Shape => {
372
+ if (idx !== undefined && typeof schema.$ref === "string") {
373
+ const key = resolveRef(schema.$ref, idx);
374
+ const target = key !== null ? idx.defs[key] : undefined;
375
+ if (target !== undefined) return convertFrom(target, false, idx);
376
+ return shapes.unknown();
377
+ }
378
+
379
+ const meta: ShapecraftMeta = schema["x-shapecraft"] ?? {};
380
+
381
+ let base: shapes.Shape;
382
+ const combinator = combinatorBase(schema, idx);
383
+
384
+ if (schema.const !== undefined) {
385
+ base = literalFromValue(schema.const);
386
+ } else if (
387
+ schema.enum !== undefined &&
388
+ Array.isArray(schema.enum) &&
389
+ schema.enum.length > 0
390
+ ) {
391
+ base = shapes.union(schema.enum.map(literalFromValue));
392
+ } else if (combinator !== undefined) {
393
+ base = combinator;
394
+ } else if (meta.kind === "undefined") {
395
+ base = shapes.notDefined();
396
+ } else if (meta.kind === "date") {
397
+ base = shapes.date();
398
+ } else if (meta.kind === "binary") {
399
+ base = shapes.binary();
400
+ } else if (meta.kind === "vector") {
401
+ const itemSchema = asSchema(
402
+ Array.isArray(schema.items) ? schema.items[0] : schema.items,
403
+ );
404
+ const itemTag = itemSchema["x-shapecraft"]?.numberTag ?? "number";
405
+ const format = numberByTag(itemTag);
406
+ const dims = meta.vectorDims ?? schema.minItems ?? 0;
407
+ base = shapes.vector(dims, format);
408
+ } else if (
409
+ meta.kind === "tuple" ||
410
+ Array.isArray(schema.prefixItems) ||
411
+ (Array.isArray(schema.items) && schema.items.length >= 2)
412
+ ) {
413
+ const items =
414
+ schema.prefixItems ?? (Array.isArray(schema.items) ? schema.items : []);
415
+ base = shapes.tuple(
416
+ ...items.map((s) => convertFrom(asSchema(s), false, idx)),
417
+ );
418
+ } else if (meta.kind === "range") {
419
+ const lowerDef = schema.properties?.["lower"];
420
+ const lowerSchema = asSchema(lowerDef);
421
+ const variants = lowerSchema.anyOf ?? lowerSchema.oneOf ?? undefined;
422
+ const inner =
423
+ variants !== undefined ?
424
+ (variants.map((v) => asSchema(v)).find((v) => v.type !== "null") ?? {})
425
+ : lowerSchema;
426
+ base = shapes.range(convertFrom(inner, false, idx));
427
+ } else {
428
+ switch (effectiveType(schema)) {
429
+ case "null":
430
+ base = shapes.nil();
431
+ break;
432
+ case "boolean":
433
+ base = shapes.boolean();
434
+ break;
435
+ case "string": {
436
+ if (
437
+ schema.format === "date-time" ||
438
+ schema.format === "date" ||
439
+ schema.format === "timestamp" ||
440
+ schema.format === "time"
441
+ ) {
442
+ base = shapes.date();
443
+ } else if (schema.contentEncoding === "base64") {
444
+ base = shapes.binary();
445
+ } else {
446
+ let s: shapes.ShapeString = shapes.string();
447
+ if (schema.pattern !== undefined)
448
+ s = annotate.pattern(s, schema.pattern);
449
+ if (schema.minLength !== undefined)
450
+ s = annotate.min(s, schema.minLength);
451
+ if (schema.maxLength !== undefined)
452
+ s = annotate.max(s, schema.maxLength);
453
+ if (schema.format !== undefined)
454
+ s = annotate.format(s, schema.format);
455
+ base = s;
456
+ }
457
+ break;
458
+ }
459
+ case "integer":
460
+ case "number": {
461
+ const tag: NumberTag =
462
+ meta.numberTag ?? (schema.type === "integer" ? "int" : "number");
463
+ let n: shapes.ShapeNumber = numberByTag(tag);
464
+ const natural = naturalRangeForTag(tag);
465
+ if (
466
+ schema.minimum !== undefined &&
467
+ (natural.minimum === undefined || schema.minimum !== natural.minimum)
468
+ )
469
+ n = annotate.min(n, schema.minimum);
470
+ if (
471
+ schema.maximum !== undefined &&
472
+ (natural.maximum === undefined || schema.maximum !== natural.maximum)
473
+ )
474
+ n = annotate.max(n, schema.maximum);
475
+ base = n;
476
+ break;
477
+ }
478
+ case "array": {
479
+ const itemSchema = asSchema(
480
+ Array.isArray(schema.items) ? schema.items[0] : schema.items,
481
+ );
482
+ let a: shapes.ShapeArray = shapes.array(
483
+ convertFrom(itemSchema, false, idx),
484
+ );
485
+ if (schema.minItems !== undefined) a = annotate.min(a, schema.minItems);
486
+ if (schema.maxItems !== undefined) a = annotate.max(a, schema.maxItems);
487
+ if (schema.uniqueItems === true) a = annotate.uniqueItems(a);
488
+ base = a;
489
+ break;
490
+ }
491
+ case "object": {
492
+ if (schema.properties !== undefined) {
493
+ const required = new Set(schema.required ?? []);
494
+ const rec: Record<string, shapes.Shape> = {};
495
+ for (const [k, v] of Object.entries(schema.properties)) {
496
+ let child = convertFrom(asSchema(v), false, idx);
497
+ if (!required.has(k)) child = annotate.optional(child);
498
+ rec[k] = child;
499
+ }
500
+ base = shapes.mapping(rec);
501
+ } else if (
502
+ schema.additionalProperties !== undefined &&
503
+ schema.additionalProperties !== false
504
+ ) {
505
+ const valShape = convertFrom(
506
+ asSchema(schema.additionalProperties),
507
+ false,
508
+ idx,
509
+ );
510
+ const pn =
511
+ (
512
+ schema.propertyNames !== undefined &&
513
+ schema.propertyNames !== true &&
514
+ schema.propertyNames !== false
515
+ ) ?
516
+ schema.propertyNames
517
+ : undefined;
518
+ let keyShape: shapes.ShapeKeyable;
519
+ if (pn?.pattern === "^-?\\d+(\\.\\d+)?$") {
520
+ keyShape = shapes.number();
521
+ } else if (pn?.pattern !== undefined) {
522
+ keyShape = annotate.pattern(shapes.string(), pn.pattern);
523
+ } else {
524
+ keyShape = shapes.string();
525
+ }
526
+ base = shapes.record(keyShape, valShape);
527
+ } else {
528
+ base = shapes.unknown();
529
+ }
530
+ break;
531
+ }
532
+ default:
533
+ base = shapes.unknown();
534
+ }
535
+ }
536
+
537
+ if (meta.unique === true) base = annotate.unique(base);
538
+ if (meta.primary === true) base = annotate.primary(base);
539
+ if (meta.foreign !== undefined)
540
+ base = annotate.foreign(base, meta.foreign.table, meta.foreign.column);
541
+ if (topLevel && meta.optional === true) base = annotate.optional(base);
542
+ if (schema.title !== undefined) base = annotate.titled(base, schema.title);
543
+ if (schema.description !== undefined)
544
+ base = annotate.described(base, schema.description);
545
+
546
+ return base;
547
+ };
548
+
549
+ type RefIndex = {
550
+ defs: Record<string, JSONSchema>;
551
+ byAnchor: Map<string, string>;
552
+ byPath: Map<string, string>;
553
+ };
554
+
555
+ type PkInfo = {
556
+ column: string;
557
+ shape: shapes.Shape;
558
+ autoInjected: boolean;
559
+ };
560
+
561
+ type PkRegistry = Record<string, PkInfo>;
562
+
563
+ type JunctionSpec = {
564
+ parentTable: string;
565
+ property: string;
566
+ refTable: string;
567
+ };
568
+
569
+ const buildRefIndex = (schema: JSONSchema): RefIndex => {
570
+ const defs: Record<string, JSONSchema> = {};
571
+ const byAnchor = new Map<string, string>();
572
+ const byPath = new Map<string, string>();
573
+ const collect = (
574
+ rawDefs: Record<string, JSONSchemaDefinition> | undefined,
575
+ pathPrefix: string,
576
+ ) => {
577
+ if (rawDefs === undefined) return;
578
+ for (const [key, defDef] of Object.entries(rawDefs)) {
579
+ if (typeof defDef !== "object" || defDef === null) continue;
580
+ const def = defDef as JSONSchema;
581
+ if (defs[key] === undefined) defs[key] = def;
582
+ byPath.set(`${pathPrefix}${key}`, key);
583
+ if (def.$anchor !== undefined) byAnchor.set(def.$anchor, key);
584
+ }
585
+ };
586
+ collect(schema.$defs, "#/$defs/");
587
+ collect(schema.definitions, "#/definitions/");
588
+ return { defs, byAnchor, byPath };
589
+ };
590
+
591
+ const resolveRef = (ref: string, idx: RefIndex): string | null => {
592
+ if (ref.startsWith("#/$defs/") || ref.startsWith("#/definitions/"))
593
+ return idx.byPath.get(ref) ?? null;
594
+ if (ref.startsWith("#") && !ref.startsWith("#/"))
595
+ return idx.byAnchor.get(ref.slice(1)) ?? null;
596
+ return null;
597
+ };
598
+
599
+ const detectPkPropertyName = (
600
+ defName: string,
601
+ def: JSONSchema,
602
+ ): string | null => {
603
+ const required = new Set(def.required ?? []);
604
+ const props = def.properties ?? {};
605
+ const lower = defName.toLowerCase();
606
+ const candidates = ["id", `${lower}id`, `${lower}_id`];
607
+ for (const cand of candidates) {
608
+ for (const propName of Object.keys(props)) {
609
+ if (propName.toLowerCase() === cand && required.has(propName))
610
+ return propName;
611
+ }
612
+ }
613
+ return null;
614
+ };
615
+
616
+ const bareTypeShape = (s: shapes.Shape): shapes.Shape => {
617
+ switch (s.type) {
618
+ case "number":
619
+ return numberByTag(s.tag);
620
+ case "string":
621
+ return shapes.string();
622
+ case "boolean":
623
+ return shapes.boolean();
624
+ case "date":
625
+ return shapes.date();
626
+ case "binary":
627
+ return shapes.binary();
628
+ default:
629
+ return s;
630
+ }
631
+ };
632
+
633
+ const lastSegment = (id: string): string => {
634
+ const slash = id.lastIndexOf("/");
635
+ const tail = slash >= 0 ? id.slice(slash + 1) : id;
636
+ const dot = tail.indexOf(".");
637
+ return dot >= 0 ? tail.slice(0, dot) : tail;
638
+ };
639
+
640
+ const topLevelTableName = (schema: JSONSchema): string => {
641
+ if (typeof schema.title === "string" && schema.title.length > 0)
642
+ return schema.title;
643
+ if (typeof schema.$id === "string" && schema.$id.length > 0)
644
+ return lastSegment(schema.$id);
645
+ return "root";
646
+ };
647
+
648
+ const buildPkInfo = (
649
+ defKey: string,
650
+ def: JSONSchema,
651
+ idx: RefIndex,
652
+ ): PkInfo => {
653
+ const pkName = detectPkPropertyName(defKey, def);
654
+ if (pkName !== null) {
655
+ const propSchema = asSchema(def.properties?.[pkName]);
656
+ const propShape = convertFrom(propSchema, false, idx);
657
+ return {
658
+ column: pkName,
659
+ shape: bareTypeShape(propShape),
660
+ autoInjected: false,
661
+ };
662
+ }
663
+ const props = def.properties ?? {};
664
+ const hasLiteralId = Object.keys(props).some((n) => n.toLowerCase() === "id");
665
+ if (hasLiteralId) {
666
+ throw new Error(
667
+ `def '${defKey}' has an 'id' field that doesn't qualify as PK (not in required[])`,
668
+ );
669
+ }
670
+ return {
671
+ column: "id",
672
+ shape: shapes.int64(),
673
+ autoInjected: true,
674
+ };
675
+ };
676
+
677
+ const convertDefToTable = (
678
+ defKey: string,
679
+ def: JSONSchema,
680
+ idx: RefIndex,
681
+ pkRegistry: PkRegistry,
682
+ junctions: JunctionSpec[],
683
+ ): shapes.ShapeMapping => {
684
+ const required = new Set(def.required ?? []);
685
+ const props = def.properties ?? {};
686
+ const pkInfo = pkRegistry[defKey];
687
+
688
+ const rec: Record<string, shapes.Shape> = {};
689
+
690
+ if (pkInfo !== undefined && pkInfo.autoInjected) {
691
+ rec[pkInfo.column] = annotate.autoIncremented(
692
+ annotate.primary(shapes.int64()),
693
+ );
694
+ }
695
+
696
+ for (const [propName, propSchemaRaw] of Object.entries(props)) {
697
+ const propSchema = asSchema(propSchemaRaw);
698
+
699
+ if (typeof propSchema.$ref === "string") {
700
+ const targetKey = resolveRef(propSchema.$ref, idx);
701
+ const targetDef = targetKey !== null ? idx.defs[targetKey] : undefined;
702
+ if (targetKey === null || targetDef === undefined) {
703
+ let s: shapes.Shape = shapes.unknown();
704
+ if (!required.has(propName)) s = annotate.optional(s);
705
+ rec[propName] = s;
706
+ continue;
707
+ }
708
+ if (targetDef.type === "object") {
709
+ const targetPk = pkRegistry[targetKey];
710
+ if (targetPk === undefined || targetPk.shape.type === "unknown") {
711
+ throw new Error(
712
+ `def '${defKey}': $ref target '${targetKey}' has no usable PK type for FK`,
713
+ );
714
+ }
715
+ let fk: shapes.Shape = annotate.foreign(
716
+ bareTypeShape(targetPk.shape),
717
+ targetKey,
718
+ targetPk.column,
719
+ );
720
+ if (!required.has(propName)) fk = annotate.optional(fk);
721
+ rec[propName] = fk;
722
+ continue;
723
+ }
724
+ let inlined = convertFrom(targetDef, false, idx);
725
+ if (!required.has(propName)) inlined = annotate.optional(inlined);
726
+ rec[propName] = inlined;
727
+ continue;
728
+ }
729
+
730
+ if (propSchema.type === "array") {
731
+ const itemSchema = asSchema(
732
+ Array.isArray(propSchema.items) ?
733
+ propSchema.items[0]
734
+ : propSchema.items,
735
+ );
736
+ if (typeof itemSchema.$ref === "string") {
737
+ const targetKey = resolveRef(itemSchema.$ref, idx);
738
+ const targetDef = targetKey !== null ? idx.defs[targetKey] : undefined;
739
+ if (
740
+ targetKey !== null &&
741
+ targetDef !== undefined &&
742
+ targetDef.type === "object" &&
743
+ pkRegistry[targetKey] !== undefined
744
+ ) {
745
+ junctions.push({
746
+ parentTable: defKey,
747
+ property: propName,
748
+ refTable: targetKey,
749
+ });
750
+ continue;
751
+ }
752
+ }
753
+ }
754
+
755
+ if (
756
+ pkInfo !== undefined &&
757
+ !pkInfo.autoInjected &&
758
+ propName === pkInfo.column
759
+ ) {
760
+ rec[propName] = annotate.primary(bareTypeShape(pkInfo.shape));
761
+ continue;
762
+ }
763
+
764
+ let child = convertFrom(propSchema, false, idx);
765
+ if (!required.has(propName)) child = annotate.optional(child);
766
+ rec[propName] = child;
767
+ }
768
+
769
+ let mapping: shapes.ShapeMapping = shapes.mapping(rec);
770
+ mapping = annotate.titled(mapping, defKey) as shapes.ShapeMapping;
771
+ if (typeof def.$anchor === "string") {
772
+ mapping = annotate.meta(mapping, {
773
+ anchor: def.$anchor,
774
+ }) as shapes.ShapeMapping;
775
+ }
776
+ if (typeof def.description === "string") {
777
+ mapping = annotate.described(
778
+ mapping,
779
+ def.description,
780
+ ) as shapes.ShapeMapping;
781
+ }
782
+ return mapping;
783
+ };
784
+
785
+ const buildJunctionTable = (
786
+ spec: JunctionSpec,
787
+ pkRegistry: PkRegistry,
788
+ ): { name: string; mapping: shapes.ShapeMapping } => {
789
+ const parentPk = pkRegistry[spec.parentTable];
790
+ const refPk = pkRegistry[spec.refTable];
791
+ if (parentPk === undefined || refPk === undefined) {
792
+ throw new Error(
793
+ `junction table ${spec.parentTable}_${spec.property}: missing PK for endpoint`,
794
+ );
795
+ }
796
+ const name = `${spec.parentTable}_${spec.property}`;
797
+ const parentCol = `${spec.parentTable}_id`;
798
+ const refCol = `${spec.property}_id`;
799
+
800
+ const parentFk = annotate.primary(
801
+ annotate.foreign(
802
+ bareTypeShape(parentPk.shape),
803
+ spec.parentTable,
804
+ parentPk.column,
805
+ ),
806
+ );
807
+ const refFk = annotate.primary(
808
+ annotate.foreign(bareTypeShape(refPk.shape), spec.refTable, refPk.column),
809
+ );
810
+
811
+ const rec: Record<string, shapes.Shape> =
812
+ parentCol === refCol ?
813
+ // self-ref edge case: column-name collision impossible because we use
814
+ // `${property}_id` for the second column. If somehow they still match,
815
+ // fall back to a numeric suffix.
816
+ { [parentCol]: parentFk, [`${refCol}_2`]: refFk }
817
+ : { [parentCol]: parentFk, [refCol]: refFk };
818
+
819
+ let mapping: shapes.ShapeMapping = shapes.mapping(rec);
820
+ mapping = annotate.titled(mapping, name) as shapes.ShapeMapping;
821
+ mapping = annotate.meta(mapping, { junction: true }) as shapes.ShapeMapping;
822
+ return { name, mapping };
823
+ };
824
+
825
+ const convertFromModule = (schema: JSONSchema): shapes.ShapeModule => {
826
+ const idx = buildRefIndex(schema);
827
+
828
+ const pkRegistry: PkRegistry = {};
829
+ for (const [defKey, def] of Object.entries(idx.defs)) {
830
+ if (def.type !== "object") continue;
831
+ pkRegistry[defKey] = buildPkInfo(defKey, def, idx);
832
+ }
833
+
834
+ const hasTopLevelObject =
835
+ schema.type === "object" && schema.properties !== undefined;
836
+ let topLevelKey: string | null = null;
837
+ if (hasTopLevelObject) {
838
+ topLevelKey = topLevelTableName(schema);
839
+ if (topLevelKey in pkRegistry) {
840
+ throw new Error(
841
+ `top-level table name '${topLevelKey}' collides with a $defs key`,
842
+ );
843
+ }
844
+ pkRegistry[topLevelKey] = buildPkInfo(topLevelKey, schema, idx);
845
+ }
846
+
847
+ const tables: Record<string, shapes.ShapeMapping> = {};
848
+ const junctions: JunctionSpec[] = [];
849
+
850
+ for (const [defKey, def] of Object.entries(idx.defs)) {
851
+ if (def.type !== "object") continue;
852
+ tables[defKey] = convertDefToTable(defKey, def, idx, pkRegistry, junctions);
853
+ }
854
+
855
+ if (topLevelKey !== null) {
856
+ tables[topLevelKey] = convertDefToTable(
857
+ topLevelKey,
858
+ schema,
859
+ idx,
860
+ pkRegistry,
861
+ junctions,
862
+ );
863
+ }
864
+
865
+ for (const spec of junctions) {
866
+ const { name, mapping } = buildJunctionTable(spec, pkRegistry);
867
+ tables[name] = mapping;
868
+ }
869
+
870
+ let mod: shapes.ShapeModule = shapes.module(tables);
871
+ if (typeof schema.title === "string")
872
+ mod = annotate.titled(mod, schema.title) as shapes.ShapeModule;
873
+ if (typeof schema.description === "string")
874
+ mod = annotate.described(mod, schema.description) as shapes.ShapeModule;
875
+ return mod;
876
+ };
877
+
878
+ export const fromJSONSchema = (schema: JSONSchema): shapes.Shape => {
879
+ if (schema.$defs !== undefined || schema.definitions !== undefined)
880
+ return convertFromModule(schema);
881
+ return convertFrom(schema, true);
882
+ };