joist-codegen 2.3.0-next.9 → 2.3.0-next.91

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 (420) hide show
  1. package/build/EntityDbMetadata.cjs +642 -0
  2. package/build/EntityDbMetadata.cjs.map +1 -0
  3. package/build/EntityDbMetadata.d.cts +299 -0
  4. package/build/EntityDbMetadata.d.cts.map +1 -0
  5. package/build/EntityDbMetadata.d.mts +299 -0
  6. package/build/EntityDbMetadata.d.mts.map +1 -0
  7. package/build/EntityDbMetadata.js +519 -661
  8. package/build/EntityDbMetadata.js.map +1 -1
  9. package/build/_virtual/_rolldown/runtime.cjs +23 -0
  10. package/build/_virtual/_rolldown/runtime.js +5 -0
  11. package/build/assignTags.cjs +45 -0
  12. package/build/assignTags.cjs.map +1 -0
  13. package/build/{assignTags.d.ts → assignTags.d.cts} +8 -4
  14. package/build/assignTags.d.cts.map +1 -0
  15. package/build/assignTags.d.mts +16 -0
  16. package/build/assignTags.d.mts.map +1 -0
  17. package/build/assignTags.js +37 -59
  18. package/build/assignTags.js.map +1 -1
  19. package/build/codemods/Codemod.cjs +2 -0
  20. package/build/codemods/Codemod.d.cts +17 -0
  21. package/build/codemods/Codemod.d.cts.map +1 -0
  22. package/build/codemods/Codemod.d.mts +17 -0
  23. package/build/codemods/Codemod.d.mts.map +1 -0
  24. package/build/codemods/Codemod.js +2 -3
  25. package/build/codemods/JscodeshiftMod.cjs +42 -0
  26. package/build/codemods/JscodeshiftMod.cjs.map +1 -0
  27. package/build/codemods/JscodeshiftMod.d.cts +14 -0
  28. package/build/codemods/JscodeshiftMod.d.cts.map +1 -0
  29. package/build/codemods/JscodeshiftMod.d.mts +14 -0
  30. package/build/codemods/JscodeshiftMod.d.mts.map +1 -0
  31. package/build/codemods/JscodeshiftMod.js +33 -33
  32. package/build/codemods/JscodeshiftMod.js.map +1 -1
  33. package/build/codemods/codemod_0001-rename_has_async_property.cjs +30 -0
  34. package/build/codemods/codemod_0001-rename_has_async_property.cjs.map +1 -0
  35. package/build/codemods/codemod_0001-rename_has_async_property.d.cts +9 -0
  36. package/build/codemods/codemod_0001-rename_has_async_property.d.cts.map +1 -0
  37. package/build/codemods/codemod_0001-rename_has_async_property.d.mts +9 -0
  38. package/build/codemods/codemod_0001-rename_has_async_property.d.mts.map +1 -0
  39. package/build/codemods/codemod_0001-rename_has_async_property.js +21 -25
  40. package/build/codemods/codemod_0001-rename_has_async_property.js.map +1 -1
  41. package/build/codemods/codemod_0002-rename_async_query_fields.cjs +50 -0
  42. package/build/codemods/codemod_0002-rename_async_query_fields.cjs.map +1 -0
  43. package/build/codemods/codemod_0002-rename_async_query_fields.d.cts +9 -0
  44. package/build/codemods/codemod_0002-rename_async_query_fields.d.cts.map +1 -0
  45. package/build/codemods/codemod_0002-rename_async_query_fields.d.mts +9 -0
  46. package/build/codemods/codemod_0002-rename_async_query_fields.d.mts.map +1 -0
  47. package/build/codemods/codemod_0002-rename_async_query_fields.js +38 -52
  48. package/build/codemods/codemod_0002-rename_async_query_fields.js.map +1 -1
  49. package/build/codemods/codemod_0003-rename_find_paginated.cjs +25 -0
  50. package/build/codemods/codemod_0003-rename_find_paginated.cjs.map +1 -0
  51. package/build/codemods/codemod_0003-rename_find_paginated.d.cts +9 -0
  52. package/build/codemods/codemod_0003-rename_find_paginated.d.cts.map +1 -0
  53. package/build/codemods/codemod_0003-rename_find_paginated.d.mts +9 -0
  54. package/build/codemods/codemod_0003-rename_find_paginated.d.mts.map +1 -0
  55. package/build/codemods/codemod_0003-rename_find_paginated.js +17 -26
  56. package/build/codemods/codemod_0003-rename_find_paginated.js.map +1 -1
  57. package/build/codemods/index.cjs +49 -0
  58. package/build/codemods/index.cjs.map +1 -0
  59. package/build/codemods/index.d.cts +12 -0
  60. package/build/codemods/index.d.cts.map +1 -0
  61. package/build/codemods/index.d.mts +12 -0
  62. package/build/codemods/index.d.mts.map +1 -0
  63. package/build/codemods/index.js +34 -42
  64. package/build/codemods/index.js.map +1 -1
  65. package/build/config.cjs +377 -0
  66. package/build/config.cjs.map +1 -0
  67. package/build/config.d.cts +181 -0
  68. package/build/config.d.cts.map +1 -0
  69. package/build/config.d.mts +181 -0
  70. package/build/config.d.mts.map +1 -0
  71. package/build/config.js +309 -347
  72. package/build/config.js.map +1 -1
  73. package/build/docs/cache.cjs +62 -0
  74. package/build/docs/cache.cjs.map +1 -0
  75. package/build/docs/cache.d.cts +17 -0
  76. package/build/docs/cache.d.cts.map +1 -0
  77. package/build/docs/cache.d.mts +17 -0
  78. package/build/docs/cache.d.mts.map +1 -0
  79. package/build/docs/cache.js +52 -53
  80. package/build/docs/cache.js.map +1 -1
  81. package/build/docs/generate-metadata-docs.cjs +32 -0
  82. package/build/docs/generate-metadata-docs.cjs.map +1 -0
  83. package/build/docs/generate-metadata-docs.d.cts +9 -0
  84. package/build/docs/generate-metadata-docs.d.cts.map +1 -0
  85. package/build/docs/generate-metadata-docs.d.mts +9 -0
  86. package/build/docs/generate-metadata-docs.d.mts.map +1 -0
  87. package/build/docs/generate-metadata-docs.js +19 -24
  88. package/build/docs/generate-metadata-docs.js.map +1 -1
  89. package/build/docs/index.cjs +90 -0
  90. package/build/docs/index.cjs.map +1 -0
  91. package/build/docs/index.d.cts +16 -0
  92. package/build/docs/index.d.cts.map +1 -0
  93. package/build/docs/index.d.mts +16 -0
  94. package/build/docs/index.d.mts.map +1 -0
  95. package/build/docs/index.js +75 -80
  96. package/build/docs/index.js.map +1 -1
  97. package/build/docs/markdown.cjs +181 -0
  98. package/build/docs/markdown.cjs.map +1 -0
  99. package/build/docs/{markdown.d.ts → markdown.d.cts} +14 -12
  100. package/build/docs/markdown.d.cts.map +1 -0
  101. package/build/docs/markdown.d.mts +32 -0
  102. package/build/docs/markdown.d.mts.map +1 -0
  103. package/build/docs/markdown.js +152 -220
  104. package/build/docs/markdown.js.map +1 -1
  105. package/build/docs/parsing.cjs +117 -0
  106. package/build/docs/parsing.cjs.map +1 -0
  107. package/build/docs/parsing.d.cts +48 -0
  108. package/build/docs/parsing.d.cts.map +1 -0
  109. package/build/docs/parsing.d.mts +48 -0
  110. package/build/docs/parsing.d.mts.map +1 -0
  111. package/build/docs/parsing.js +89 -88
  112. package/build/docs/parsing.js.map +1 -1
  113. package/build/findEntityScopes.cjs +119 -0
  114. package/build/findEntityScopes.cjs.map +1 -0
  115. package/build/findEntityScopes.d.cts +14 -0
  116. package/build/findEntityScopes.d.cts.map +1 -0
  117. package/build/findEntityScopes.d.mts +14 -0
  118. package/build/findEntityScopes.d.mts.map +1 -0
  119. package/build/findEntityScopes.js +83 -111
  120. package/build/findEntityScopes.js.map +1 -1
  121. package/build/foreignKeyOrdering.cjs +52 -0
  122. package/build/foreignKeyOrdering.cjs.map +1 -0
  123. package/build/foreignKeyOrdering.d.cts +8 -0
  124. package/build/foreignKeyOrdering.d.cts.map +1 -0
  125. package/build/foreignKeyOrdering.d.mts +8 -0
  126. package/build/foreignKeyOrdering.d.mts.map +1 -0
  127. package/build/foreignKeyOrdering.js +46 -55
  128. package/build/foreignKeyOrdering.js.map +1 -1
  129. package/build/generate.cjs +128 -0
  130. package/build/generate.cjs.map +1 -0
  131. package/build/generate.d.cts +17 -0
  132. package/build/generate.d.cts.map +1 -0
  133. package/build/generate.d.mts +17 -0
  134. package/build/generate.d.mts.map +1 -0
  135. package/build/generate.js +111 -124
  136. package/build/generate.js.map +1 -1
  137. package/build/generateEntitiesFile.cjs +46 -0
  138. package/build/generateEntitiesFile.cjs.map +1 -0
  139. package/build/generateEntitiesFile.d.cts +11 -0
  140. package/build/generateEntitiesFile.d.cts.map +1 -0
  141. package/build/generateEntitiesFile.d.mts +11 -0
  142. package/build/generateEntitiesFile.d.mts.map +1 -0
  143. package/build/generateEntitiesFile.js +28 -25
  144. package/build/generateEntitiesFile.js.map +1 -1
  145. package/build/generateEntityCodegenFile.cjs +1010 -0
  146. package/build/generateEntityCodegenFile.cjs.map +1 -0
  147. package/build/generateEntityCodegenFile.d.cts +16 -0
  148. package/build/generateEntityCodegenFile.d.cts.map +1 -0
  149. package/build/generateEntityCodegenFile.d.mts +16 -0
  150. package/build/generateEntityCodegenFile.d.mts.map +1 -0
  151. package/build/generateEntityCodegenFile.js +793 -827
  152. package/build/generateEntityCodegenFile.js.map +1 -1
  153. package/build/generateEntityFile.cjs +23 -0
  154. package/build/generateEntityFile.cjs.map +1 -0
  155. package/build/generateEntityFile.d.cts +9 -0
  156. package/build/generateEntityFile.d.cts.map +1 -0
  157. package/build/generateEntityFile.d.mts +9 -0
  158. package/build/generateEntityFile.d.mts.map +1 -0
  159. package/build/generateEntityFile.js +11 -8
  160. package/build/generateEntityFile.js.map +1 -1
  161. package/build/generateEntityTestFile.cjs +25 -0
  162. package/build/generateEntityTestFile.cjs.map +1 -0
  163. package/build/generateEntityTestFile.d.cts +9 -0
  164. package/build/generateEntityTestFile.d.cts.map +1 -0
  165. package/build/generateEntityTestFile.d.mts +9 -0
  166. package/build/generateEntityTestFile.d.mts.map +1 -0
  167. package/build/generateEntityTestFile.js +10 -7
  168. package/build/generateEntityTestFile.js.map +1 -1
  169. package/build/generateEnumFile.cjs +73 -0
  170. package/build/generateEnumFile.cjs.map +1 -0
  171. package/build/generateEnumFile.d.cts +9 -0
  172. package/build/generateEnumFile.d.cts.map +1 -0
  173. package/build/generateEnumFile.d.mts +9 -0
  174. package/build/generateEnumFile.d.mts.map +1 -0
  175. package/build/generateEnumFile.js +33 -43
  176. package/build/generateEnumFile.js.map +1 -1
  177. package/build/generateFactoriesFiles.cjs +28 -0
  178. package/build/generateFactoriesFiles.cjs.map +1 -0
  179. package/build/generateFactoriesFiles.d.cts +7 -0
  180. package/build/generateFactoriesFiles.d.cts.map +1 -0
  181. package/build/generateFactoriesFiles.d.mts +7 -0
  182. package/build/generateFactoriesFiles.d.mts.map +1 -0
  183. package/build/generateFactoriesFiles.js +21 -16
  184. package/build/generateFactoriesFiles.js.map +1 -1
  185. package/build/generateFlushFunction.cjs +61 -0
  186. package/build/generateFlushFunction.cjs.map +1 -0
  187. package/build/{generateFlushFunction.d.ts → generateFlushFunction.d.cts} +8 -5
  188. package/build/generateFlushFunction.d.cts.map +1 -0
  189. package/build/generateFlushFunction.d.mts +23 -0
  190. package/build/generateFlushFunction.d.mts.map +1 -0
  191. package/build/generateFlushFunction.js +32 -78
  192. package/build/generateFlushFunction.js.map +1 -1
  193. package/build/generateMetadataFile.cjs +307 -0
  194. package/build/generateMetadataFile.cjs.map +1 -0
  195. package/build/generateMetadataFile.d.cts +10 -0
  196. package/build/generateMetadataFile.d.cts.map +1 -0
  197. package/build/generateMetadataFile.d.mts +10 -0
  198. package/build/generateMetadataFile.d.mts.map +1 -0
  199. package/build/generateMetadataFile.js +148 -156
  200. package/build/generateMetadataFile.js.map +1 -1
  201. package/build/generatePgEnumFile.cjs +21 -0
  202. package/build/generatePgEnumFile.cjs.map +1 -0
  203. package/build/generatePgEnumFile.d.cts +9 -0
  204. package/build/generatePgEnumFile.d.cts.map +1 -0
  205. package/build/generatePgEnumFile.d.mts +9 -0
  206. package/build/generatePgEnumFile.d.mts.map +1 -0
  207. package/build/generatePgEnumFile.js +12 -9
  208. package/build/generatePgEnumFile.js.map +1 -1
  209. package/build/index.cjs +135 -0
  210. package/build/index.cjs.map +1 -0
  211. package/build/index.d.cts +12 -0
  212. package/build/index.d.cts.map +1 -0
  213. package/build/index.d.mts +12 -0
  214. package/build/index.d.mts.map +1 -0
  215. package/build/index.js +108 -127
  216. package/build/index.js.map +1 -1
  217. package/build/inheritance.cjs +257 -0
  218. package/build/inheritance.cjs.map +1 -0
  219. package/build/inheritance.d.cts +13 -0
  220. package/build/inheritance.d.cts.map +1 -0
  221. package/build/inheritance.d.mts +13 -0
  222. package/build/inheritance.d.mts.map +1 -0
  223. package/build/inheritance.js +237 -247
  224. package/build/inheritance.js.map +1 -1
  225. package/build/installSkills.cjs +68 -0
  226. package/build/installSkills.cjs.map +1 -0
  227. package/build/installSkills.d.cts +16 -0
  228. package/build/installSkills.d.cts.map +1 -0
  229. package/build/installSkills.d.mts +16 -0
  230. package/build/installSkills.d.mts.map +1 -0
  231. package/build/installSkills.js +67 -0
  232. package/build/installSkills.js.map +1 -0
  233. package/build/keywords.cjs +7 -0
  234. package/build/keywords.cjs.map +1 -0
  235. package/build/keywords.d.cts +5 -0
  236. package/build/keywords.d.cts.map +1 -0
  237. package/build/keywords.d.mts +5 -0
  238. package/build/keywords.d.mts.map +1 -0
  239. package/build/keywords.js +5 -4
  240. package/build/keywords.js.map +1 -1
  241. package/build/loadMetadata.cjs +39 -0
  242. package/build/loadMetadata.cjs.map +1 -0
  243. package/build/loadMetadata.d.cts +31 -0
  244. package/build/loadMetadata.d.cts.map +1 -0
  245. package/build/loadMetadata.d.mts +31 -0
  246. package/build/loadMetadata.d.mts.map +1 -0
  247. package/build/loadMetadata.js +32 -39
  248. package/build/loadMetadata.js.map +1 -1
  249. package/build/logger.cjs +28 -0
  250. package/build/logger.cjs.map +1 -0
  251. package/build/logger.d.cts +13 -0
  252. package/build/logger.d.cts.map +1 -0
  253. package/build/logger.d.mts +13 -0
  254. package/build/logger.d.mts.map +1 -0
  255. package/build/logger.js +17 -16
  256. package/build/logger.js.map +1 -1
  257. package/build/scanEntityFiles.cjs +46 -0
  258. package/build/scanEntityFiles.cjs.map +1 -0
  259. package/build/scanEntityFiles.d.cts +8 -0
  260. package/build/scanEntityFiles.d.cts.map +1 -0
  261. package/build/scanEntityFiles.d.mts +8 -0
  262. package/build/scanEntityFiles.d.mts.map +1 -0
  263. package/build/scanEntityFiles.js +37 -42
  264. package/build/scanEntityFiles.js.map +1 -1
  265. package/build/sortForeignKeys.cjs +99 -0
  266. package/build/sortForeignKeys.cjs.map +1 -0
  267. package/build/{sortForeignKeys.d.ts → sortForeignKeys.d.cts} +8 -5
  268. package/build/sortForeignKeys.d.cts.map +1 -0
  269. package/build/sortForeignKeys.d.mts +35 -0
  270. package/build/sortForeignKeys.d.mts.map +1 -0
  271. package/build/sortForeignKeys.js +88 -117
  272. package/build/sortForeignKeys.js.map +1 -1
  273. package/build/symbols.cjs +238 -0
  274. package/build/symbols.cjs.map +1 -0
  275. package/build/symbols.d.cts +120 -0
  276. package/build/symbols.d.cts.map +1 -0
  277. package/build/symbols.d.mts +120 -0
  278. package/build/symbols.d.mts.map +1 -0
  279. package/build/symbols.js +121 -113
  280. package/build/symbols.js.map +1 -1
  281. package/build/tsdoc.cjs +22 -0
  282. package/build/tsdoc.cjs.map +1 -0
  283. package/build/tsdoc.d.cts +15 -0
  284. package/build/tsdoc.d.cts.map +1 -0
  285. package/build/tsdoc.d.mts +15 -0
  286. package/build/tsdoc.d.mts.map +1 -0
  287. package/build/tsdoc.js +18 -15
  288. package/build/tsdoc.js.map +1 -1
  289. package/build/utils.cjs +173 -0
  290. package/build/utils.cjs.map +1 -0
  291. package/build/utils.d.cts +34 -0
  292. package/build/utils.d.cts.map +1 -0
  293. package/build/utils.d.mts +34 -0
  294. package/build/utils.d.mts.map +1 -0
  295. package/build/utils.js +112 -166
  296. package/build/utils.js.map +1 -1
  297. package/build/write-json-schema.cjs +23 -0
  298. package/build/write-json-schema.cjs.map +1 -0
  299. package/build/write-json-schema.d.cts +1 -0
  300. package/build/write-json-schema.d.mts +1 -0
  301. package/build/write-json-schema.js +19 -13
  302. package/build/write-json-schema.js.map +1 -1
  303. package/package.json +37 -17
  304. package/skills/joist-docs/SKILL.md +142 -0
  305. package/skills/joist-em-basics/SKILL.md +114 -0
  306. package/skills/joist-partial-updates/SKILL.md +352 -0
  307. package/skills/joist-reactive-hints/SKILL.md +150 -0
  308. package/skills/joist-test-factories/SKILL.md +397 -0
  309. package/skills/joist-upsert/SKILL.md +95 -0
  310. package/build/EntityDbMetadata.d.ts +0 -269
  311. package/build/EntityDbMetadata.d.ts.map +0 -1
  312. package/build/EntityDbMetadata.test.d.ts +0 -2
  313. package/build/EntityDbMetadata.test.d.ts.map +0 -1
  314. package/build/EntityDbMetadata.test.js +0 -211
  315. package/build/EntityDbMetadata.test.js.map +0 -1
  316. package/build/assignTags.d.ts.map +0 -1
  317. package/build/codemods/Codemod.d.ts +0 -14
  318. package/build/codemods/Codemod.d.ts.map +0 -1
  319. package/build/codemods/Codemod.js.map +0 -1
  320. package/build/codemods/JscodeshiftMod.d.ts +0 -11
  321. package/build/codemods/JscodeshiftMod.d.ts.map +0 -1
  322. package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.d.ts +0 -2
  323. package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.d.ts.map +0 -1
  324. package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.js +0 -9
  325. package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.js.map +0 -1
  326. package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.d.ts +0 -2
  327. package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.d.ts.map +0 -1
  328. package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.js +0 -9
  329. package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.js.map +0 -1
  330. package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.d.ts +0 -2
  331. package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.d.ts.map +0 -1
  332. package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.js +0 -9
  333. package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.js.map +0 -1
  334. package/build/codemods/codemod_0001-rename_has_async_property.d.ts +0 -7
  335. package/build/codemods/codemod_0001-rename_has_async_property.d.ts.map +0 -1
  336. package/build/codemods/codemod_0002-rename_async_query_fields.d.ts +0 -7
  337. package/build/codemods/codemod_0002-rename_async_query_fields.d.ts.map +0 -1
  338. package/build/codemods/codemod_0003-rename_find_paginated.d.ts +0 -7
  339. package/build/codemods/codemod_0003-rename_find_paginated.d.ts.map +0 -1
  340. package/build/codemods/index.d.ts +0 -9
  341. package/build/codemods/index.d.ts.map +0 -1
  342. package/build/codemods/index.test.d.ts +0 -2
  343. package/build/codemods/index.test.d.ts.map +0 -1
  344. package/build/codemods/index.test.js +0 -24
  345. package/build/codemods/index.test.js.map +0 -1
  346. package/build/config.d.ts +0 -167
  347. package/build/config.d.ts.map +0 -1
  348. package/build/config.test.d.ts +0 -2
  349. package/build/config.test.d.ts.map +0 -1
  350. package/build/config.test.js +0 -78
  351. package/build/config.test.js.map +0 -1
  352. package/build/docs/cache.d.ts +0 -14
  353. package/build/docs/cache.d.ts.map +0 -1
  354. package/build/docs/cache.test.d.ts +0 -2
  355. package/build/docs/cache.test.d.ts.map +0 -1
  356. package/build/docs/cache.test.js +0 -47
  357. package/build/docs/cache.test.js.map +0 -1
  358. package/build/docs/generate-metadata-docs.d.ts +0 -6
  359. package/build/docs/generate-metadata-docs.d.ts.map +0 -1
  360. package/build/docs/index.d.ts +0 -9
  361. package/build/docs/index.d.ts.map +0 -1
  362. package/build/docs/index.test.d.ts +0 -2
  363. package/build/docs/index.test.d.ts.map +0 -1
  364. package/build/docs/index.test.js +0 -100
  365. package/build/docs/index.test.js.map +0 -1
  366. package/build/docs/markdown.d.ts.map +0 -1
  367. package/build/docs/markdown.test.d.ts +0 -2
  368. package/build/docs/markdown.test.d.ts.map +0 -1
  369. package/build/docs/markdown.test.js +0 -280
  370. package/build/docs/markdown.test.js.map +0 -1
  371. package/build/docs/parsing.d.ts +0 -42
  372. package/build/docs/parsing.d.ts.map +0 -1
  373. package/build/docs/parsing.test.d.ts +0 -2
  374. package/build/docs/parsing.test.d.ts.map +0 -1
  375. package/build/docs/parsing.test.js +0 -190
  376. package/build/docs/parsing.test.js.map +0 -1
  377. package/build/findEntityScopes.d.ts +0 -11
  378. package/build/findEntityScopes.d.ts.map +0 -1
  379. package/build/foreignKeyOrdering.d.ts +0 -3
  380. package/build/foreignKeyOrdering.d.ts.map +0 -1
  381. package/build/generate.d.ts +0 -12
  382. package/build/generate.d.ts.map +0 -1
  383. package/build/generateEntitiesFile.d.ts +0 -7
  384. package/build/generateEntitiesFile.d.ts.map +0 -1
  385. package/build/generateEntityCodegenFile.d.ts +0 -11
  386. package/build/generateEntityCodegenFile.d.ts.map +0 -1
  387. package/build/generateEntityFile.d.ts +0 -6
  388. package/build/generateEntityFile.d.ts.map +0 -1
  389. package/build/generateEntityTestFile.d.ts +0 -6
  390. package/build/generateEntityTestFile.d.ts.map +0 -1
  391. package/build/generateEnumFile.d.ts +0 -5
  392. package/build/generateEnumFile.d.ts.map +0 -1
  393. package/build/generateFactoriesFiles.d.ts +0 -4
  394. package/build/generateFactoriesFiles.d.ts.map +0 -1
  395. package/build/generateFlushFunction.d.ts.map +0 -1
  396. package/build/generateMetadataFile.d.ts +0 -5
  397. package/build/generateMetadataFile.d.ts.map +0 -1
  398. package/build/generatePgEnumFile.d.ts +0 -5
  399. package/build/generatePgEnumFile.d.ts.map +0 -1
  400. package/build/index.d.ts +0 -11
  401. package/build/index.d.ts.map +0 -1
  402. package/build/inheritance.d.ts +0 -10
  403. package/build/inheritance.d.ts.map +0 -1
  404. package/build/keywords.d.ts +0 -2
  405. package/build/keywords.d.ts.map +0 -1
  406. package/build/loadMetadata.d.ts +0 -26
  407. package/build/loadMetadata.d.ts.map +0 -1
  408. package/build/logger.d.ts +0 -10
  409. package/build/logger.d.ts.map +0 -1
  410. package/build/scanEntityFiles.d.ts +0 -5
  411. package/build/scanEntityFiles.d.ts.map +0 -1
  412. package/build/sortForeignKeys.d.ts.map +0 -1
  413. package/build/symbols.d.ts +0 -108
  414. package/build/symbols.d.ts.map +0 -1
  415. package/build/tsdoc.d.ts +0 -12
  416. package/build/tsdoc.d.ts.map +0 -1
  417. package/build/utils.d.ts +0 -31
  418. package/build/utils.d.ts.map +0 -1
  419. package/build/write-json-schema.d.ts +0 -2
  420. package/build/write-json-schema.d.ts.map +0 -1
@@ -1,99 +1,82 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateEntityCodegenFile = generateEntityCodegenFile;
4
- exports.getIdType = getIdType;
5
- const change_case_1 = require("change-case");
6
- const pluralize_1 = require("pluralize");
7
- const ts_poet_1 = require("ts-poet");
8
- const inheritance_1 = require("./inheritance");
9
- const keywords_1 = require("./keywords");
10
- const symbols_1 = require("./symbols");
11
- const tsdoc_1 = require("./tsdoc");
12
- const utils_1 = require("./utils");
1
+ import { assertNever, fail, uncapitalize } from "./utils.js";
2
+ import { getStiEntities } from "./inheritance.js";
3
+ import "./config.js";
4
+ import { buildJSDocBlock, generatedTag } from "./docs/parsing.js";
5
+ import "./docs/index.js";
6
+ import "./findEntityScopes.js";
7
+ import { keywords } from "./keywords.js";
8
+ import { BaseEntity, BooleanFilter, BooleanGraphQLFilter, Changes, Collection, ConfigApi, DeepPartialOrNull, EntityFilter, EntityGraphQLFilter, EntityManager, EntityMetadata, EnumCollection, FieldsOf, FilterOf, Flavor, GraphQLFilterOf, IdOf, JsonPayload, LargeCollection, LazyField, Lens, LoadHint, Loaded, ManyToOneReference, MaybeAbstractEntityConstructor, OneToOneReference, OptsOf, OrderBy, PartialOrNull, PolymorphicReference, ProjectEntity, ReactiveField, ReactiveManyToMany, ReactiveManyToManyOtherSide, ReactiveReference, ReadOnlyCollection, RelationsOf, SSAssert, Scope, TaggedId, ToJsonHint, ValueFilter, ValueGraphQLFilter, Zod, cannotBeUpdated, failNoIdYet, getField, hasEnumCollection, hasLargeMany, hasLargeManyToMany, hasLazyField, hasMany, hasManyToMany, hasOne, hasOnePolymorphic, hasOneToOne, hasReactiveManyToManyOtherSide, hasRecursiveChildren, hasRecursiveM2m, hasRecursiveParents, isEntity, isLoaded, loadLens, mustBeSubType, newChangesProxy, newRequiredLazyFieldRule, newRequiredRule, newScopeFn, nowUTC, setField, setOpts, toIdOf, toJSON, updatePartial } from "./symbols.js";
9
+ import { tsdocComments } from "./tsdoc.js";
10
+ import "./EntityDbMetadata.js";
11
+ import { camelCase, pascalCase } from "change-case";
12
+ import pluralize from "pluralize";
13
+ import { code, imp, joinCode } from "ts-poet";
14
+ //#region src/generateEntityCodegenFile.ts
15
+ const { plural } = pluralize;
13
16
  /** Creates the base class with the boilerplate annotations. */
14
- function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = []) {
15
- const { entitiesByName: metasByName } = dbMeta;
16
- const { entity, tagName } = meta;
17
- const entityName = entity.name;
18
- // Avoid using `do` as a variable name b/c it's a reserved keyword
19
- const varName = keywords_1.keywords.includes(tagName) ? (0, utils_1.uncapitalize)(entityName) : tagName;
20
- const primitives = createPrimitives(meta, entity); // Add the primitives
21
- primitives.push(...createRegularEnums(meta, entity)); // Add ManyToOne enums
22
- primitives.push(...createArrayEnums(meta)); // Add integer[] enums
23
- primitives.push(...createPgEnums(meta)); // Add native enums
24
- const relations = createRelations(config, meta, entity);
25
- const configName = `${(0, change_case_1.camelCase)(entityName)}Config`;
26
- const scopeFnName = `${(0, change_case_1.camelCase)(entityName)}Scope`;
27
- const metadata = (0, ts_poet_1.imp)(`${(0, change_case_1.camelCase)(entityName)}Meta@./entities.ts`);
28
- const contextType = config.contextType ? (0, ts_poet_1.imp)(`t:${config.contextType}`) : "{}";
29
- const factoryMethod = (0, ts_poet_1.imp)(`new${entity.name}@./entities.ts`);
30
- // If we're not tagged-strings, detag on the way out of id
31
- const idMaybeCode = config.idType === "tagged-string"
32
- ? (0, ts_poet_1.code) `return this.idTaggedMaybe;`
33
- : (0, ts_poet_1.code) `return ${symbols_1.toIdOf}(${metadata}, this.idTaggedMaybe);`;
34
- const idType = getIdType(config);
35
- const maybeIsSoftDeleted = meta.deletedAt
36
- ? (0, ts_poet_1.code) `
17
+ function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = [], docs) {
18
+ const { entitiesByName: metasByName } = dbMeta;
19
+ const { entity, tagName } = meta;
20
+ const entityName = entity.name;
21
+ const fieldDocs = docs?.fields ?? {};
22
+ const varName = keywords.includes(tagName) ? uncapitalize(entityName) : tagName;
23
+ const primitives = createPrimitives(meta, entity, fieldDocs);
24
+ primitives.push(...createRegularEnums(meta, entity, fieldDocs));
25
+ primitives.push(...createArrayEnums(meta, fieldDocs));
26
+ primitives.push(...createPgEnums(meta, fieldDocs));
27
+ const relations = createRelations(config, meta, entity);
28
+ const configName = `${camelCase(entityName)}Config`;
29
+ const scopeFnName = `${camelCase(entityName)}Scope`;
30
+ const metadata = imp(`${camelCase(entityName)}Meta@./entities.ts`);
31
+ const contextType = config.contextType ? imp(`t:${config.contextType}`) : "{}";
32
+ const factoryMethod = imp(`new${entity.name}@./entities.ts`);
33
+ const idMaybeCode = config.idType === "tagged-string" ? code`return this.idTaggedMaybe;` : code`return ${toIdOf}(${metadata}, this.idTaggedMaybe);`;
34
+ const idType = getIdType(config);
35
+ const maybeSoftDeleteMethods = meta.deletedAt ? code`
37
36
  get isSoftDeletedEntity(): boolean {
38
37
  return this.${meta.deletedAt.fieldName} !== undefined;
39
38
  }
40
- `
41
- : "";
42
- // Set up the codegen artifacts to extend from the base type if necessary
43
- const baseEntity = dbMeta.entities.find((e) => e.name === meta.baseClassName);
44
- const subEntities = dbMeta.entities.filter((e) => e.baseClassName === meta.name);
45
- const base = baseEntity?.entity.typeSymbol ?? (0, ts_poet_1.code) `${symbols_1.BaseEntity}<${symbols_1.EntityManager}, ${idType}>`;
46
- const maybeBaseFields = baseEntity
47
- ? (0, ts_poet_1.code) `extends ${(0, ts_poet_1.imp)("t:" + baseEntity.entity.fieldsName + "@./entities.ts")}`
48
- : "";
49
- const maybeBaseOpts = baseEntity ? (0, ts_poet_1.code) `extends ${baseEntity.entity.optsType}` : "";
50
- const maybeBaseIdOpts = baseEntity
51
- ? (0, ts_poet_1.code) `extends ${(0, ts_poet_1.imp)("t:" + baseEntity.entity.idsOptsName + "@./entities.ts")}`
52
- : "";
53
- const maybeBaseFilter = baseEntity
54
- ? (0, ts_poet_1.code) `extends ${(0, ts_poet_1.imp)("t:" + baseEntity.entity.filterName + "@./entities.ts")}`
55
- : "";
56
- const maybeBaseGqlFilter = baseEntity
57
- ? (0, ts_poet_1.code) `extends ${(0, ts_poet_1.imp)("t:" + baseEntity.entity.graphqlFilterName + "@./entities.ts")}`
58
- : "";
59
- const maybeBaseOrder = baseEntity ? (0, ts_poet_1.code) `extends ${baseEntity.entity.orderType}` : "";
60
- const maybePreventBaseTypeInstantiation = meta.abstract
61
- ? (0, ts_poet_1.code) `
39
+
40
+ softDelete(): void {
41
+ if (this.isSoftDeletedEntity) return;
42
+ this.${meta.deletedAt.fieldName} = ${nowUTCCall(config, meta.deletedAt)};
43
+ }
44
+ ` : "";
45
+ const baseEntity = dbMeta.entities.find((e) => e.name === meta.baseClassName);
46
+ const subEntities = dbMeta.entities.filter((e) => e.baseClassName === meta.name);
47
+ const base = baseEntity?.entity.typeSymbol ?? code`${BaseEntity}<${EntityManager}, ${idType}>`;
48
+ const maybeBaseFields = baseEntity ? code`extends Omit<${imp("t:" + baseEntity.entity.fieldsName + "@./entities.ts")}, "id"${[
49
+ ...meta.primitives,
50
+ ...meta.enums,
51
+ ...meta.pgEnums,
52
+ ...meta.manyToOnes
53
+ ].filter((field) => [
54
+ ...baseEntity.primitives,
55
+ ...baseEntity.enums,
56
+ ...baseEntity.pgEnums,
57
+ ...baseEntity.manyToOnes
58
+ ].some((baseField) => baseField.fieldName === field.fieldName)).map((field) => code` | "${field.fieldName}"`)}>` : "";
59
+ const maybeBaseOpts = baseEntity ? code`extends ${baseEntity.entity.optsType}` : "";
60
+ const physical = meta.physicalMetadata ?? meta;
61
+ const sharedTable = meta.inheritanceType === "sti" && baseEntity;
62
+ const columns = sharedTable ? {} : generateColumnsType(physical);
63
+ const maybeBaseColumns = sharedTable ? code`extends ${imp(`t:${baseEntity.name}Columns@./entities.ts`)}` : "";
64
+ const maybeBaseIdOpts = baseEntity ? code`extends ${imp("t:" + baseEntity.entity.idsOptsName + "@./entities.ts")}` : "";
65
+ const maybeBaseFilter = baseEntity ? code`extends ${imp("t:" + baseEntity.entity.filterName + "@./entities.ts")}` : "";
66
+ const maybeBaseGqlFilter = baseEntity ? code`extends ${imp("t:" + baseEntity.entity.graphqlFilterName + "@./entities.ts")}` : "";
67
+ const maybeBaseOrder = baseEntity ? code`extends ${baseEntity.entity.orderType}` : "";
68
+ meta.abstract && code`
62
69
  if (this.constructor === ${entity.type} && !(em as any).fakeInstance) {
63
70
  throw new Error(\`${entity.type} must be instantiated via a subtype\`);
64
- }`
65
- : "";
66
- let maybeOtherTypeChanges;
67
- if (subEntities.length > 0) {
68
- maybeOtherTypeChanges = (0, ts_poet_1.joinCode)(
69
- // Pass `K = keyof Publisher | keyof SmallPublisher | keyof LargePublisher` to `changes` so that
70
- // our subtypes can have `SmallPublisher.changes(): Changes<SmallPublisher>` be covariant, which
71
- // will break if it adds a key to `Changes.fields` that `Publisher.changes()` does not include.
72
- //
73
- // type A1 = { foo: 1 | 2 };
74
- // type A2 = { foo: 1 | 2 | 3 };
75
- // type A3 = A2 extends A1 ? 1 : 2;
76
- //
77
- // A3 will be 2 because the extra 3 breaks code written against A1.foo.
78
- //
79
- // So essentially we're pre-emptively our subtypes "3".
80
- [
81
- (0, ts_poet_1.code) `, `,
82
- ...[meta, ...subEntities].map((e) => (0, ts_poet_1.code) `keyof (${symbols_1.FieldsOf}<${e.entity.type}> & ${symbols_1.RelationsOf}<${e.entity.type}>)`),
83
- ], { on: "|" });
84
- }
85
- else {
86
- maybeOtherTypeChanges = "";
87
- }
88
- let maybeOtherLoaded;
89
- if (baseEntity) {
90
- maybeOtherLoaded = (0, ts_poet_1.code) `| ${baseEntity.entity.type}`;
91
- }
92
- else {
93
- maybeOtherLoaded = "";
94
- }
95
- return (0, ts_poet_1.code) `
96
- export type ${entity.idName} = ${symbols_1.Flavor}<${idType}, "${baseEntity ? baseEntity.name : entityName}">;
71
+ }`;
72
+ let maybeOtherTypeChanges;
73
+ if (subEntities.length > 0) maybeOtherTypeChanges = joinCode([code`, `, ...[meta, ...subEntities].map((e) => code`keyof (${FieldsOf}<${e.entity.type}> & ${RelationsOf}<${e.entity.type}>)`)], { on: "|" });
74
+ else maybeOtherTypeChanges = "";
75
+ let maybeOtherLoaded;
76
+ if (baseEntity) maybeOtherLoaded = code`| ${baseEntity.entity.type}`;
77
+ else maybeOtherLoaded = "";
78
+ return code`
79
+ export type ${entity.idName} = ${Flavor}<${idType}, "${baseEntity ? baseEntity.name : entityName}">;
97
80
 
98
81
  ${generatePolymorphicTypes(meta)}
99
82
 
@@ -101,6 +84,10 @@ function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = []) {
101
84
  ${generateFieldsType(meta, idType)}
102
85
  }
103
86
 
87
+ export interface ${entityName}Columns ${maybeBaseColumns} {
88
+ ${Object.entries(columns).map(([name, descriptor]) => code`${JSON.stringify(name)}: ${descriptor};`)}
89
+ }
90
+
104
91
  export interface ${entity.optsName} ${maybeBaseOpts} {
105
92
  ${generateOptsFields(meta)}
106
93
  }
@@ -126,14 +113,14 @@ function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = []) {
126
113
  }
127
114
 
128
115
  export interface ${entity.scopesName} {
129
- ${scopeMembers.map((member) => (0, ts_poet_1.code) `${member.name}: ${member.type};`)}
116
+ ${scopeMembers.map((member) => code`${member.name}: ${member.type};`)}
130
117
  }
131
118
 
132
- export type ${entity.scopeName} = ${symbols_1.Scope}<${entity.type}, ${entity.scopesName}>;
119
+ export type ${entity.scopeName} = ${Scope}<${entity.type}, ${entity.scopesName}>;
133
120
 
134
- export const ${configName} = new ${symbols_1.ConfigApi}<${entity.type}, ${contextType}>();
121
+ export const ${configName} = new ${ConfigApi}<${entity.type}, ${contextType}>();
135
122
 
136
- export const ${scopeFnName} = ${symbols_1.newScopeFn}<${entity.type}, ${entity.scopeName}>("${entityName}");
123
+ export const ${scopeFnName} = ${newScopeFn}<${entity.type}, ${entity.scopeName}>("${entityName}");
137
124
 
138
125
  ${generateDefaultValidationRules(dbMeta, meta, configName)}
139
126
  ${generateDefaultValues(config, meta, configName)};
@@ -147,6 +134,9 @@ function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = []) {
147
134
  orderType: ${entity.orderName};
148
135
  optsType: ${entity.optsName};
149
136
  fieldsType: ${entity.fieldsName};
137
+ columnsType: ${entityName}Columns;
138
+ inheritanceType: ${meta.inheritanceType ? code`"${meta.inheritanceType}"` : "never"};
139
+ supportsEmExecute: ${!meta.inheritanceType && meta.supportsEmExecute === true};
150
140
  optIdsType: ${entity.idsOptsName};
151
141
  factoryExtrasType: ${entity.factoryExtrasName};
152
142
  factoryOptsType: Parameters<typeof ${factoryMethod}>[1];
@@ -154,887 +144,863 @@ function generateEntityCodegenFile(config, dbMeta, meta, scopeMembers = []) {
154
144
  }
155
145
  }
156
146
 
157
- export abstract class ${entityName}Codegen extends ${base} implements ${symbols_1.ProjectEntity} {
147
+ export abstract class ${entityName}Codegen extends ${base} implements ${ProjectEntity} {
158
148
  static readonly tagName = "${tagName}";
159
- static readonly metadata: ${symbols_1.EntityMetadata}<${entity.type}>;
149
+ static readonly metadata: ${EntityMetadata}<${entity.type}>;
160
150
 
161
151
  declare readonly __type: {
162
152
  ${baseEntity ? `0: "${baseEntity.name}",` : ""}
163
153
  ${baseEntity ? 1 : 0}: "${entityName}",
164
154
  };
165
155
 
166
- ${relations
167
- .filter((r) => r.kind === "abstract")
168
- .map((r) => {
169
- return (0, ts_poet_1.code) `${r.line}${maybeComment(r.comment)}`;
170
- })}
171
- ${relations
172
- .filter((r) => r.kind === "concrete")
173
- .map((r) => {
174
- return (0, ts_poet_1.code) `readonly ${r.fieldName}: ${r.decl} = ${r.init};${maybeComment(r.comment)}`;
175
- })}
176
- ${relations
177
- .filter((r) => r.kind === "super")
178
- .map((r) => {
179
- return (0, ts_poet_1.code) `declare readonly ${r.fieldName}: ${r.decl};${maybeComment(r.comment)}`;
180
- })}
156
+ ${relations.filter((r) => r.kind === "abstract").map((r) => {
157
+ return code`${relationDocBlock(fieldDocs, r.fieldName, entityName)}${r.line}${maybeComment(r.comment)}`;
158
+ })}
159
+ ${relations.filter((r) => r.kind === "concrete").map((r) => {
160
+ return code`${relationDocBlock(fieldDocs, r.fieldName, entityName)}readonly ${r.fieldName}: ${r.decl} = ${r.init};${maybeComment(r.comment)}`;
161
+ })}
162
+ ${relations.filter((r) => r.kind === "super").map((r) => {
163
+ return code`${relationDocBlock(fieldDocs, r.fieldName, entityName)}declare readonly ${r.fieldName}: ${r.decl};${maybeComment(r.comment)}`;
164
+ })}
181
165
 
182
166
  get id(): ${entity.idName} {
183
- return this.idMaybe || ${symbols_1.failNoIdYet}("${entityName}");
167
+ return this.idMaybe || ${failNoIdYet}("${entityName}");
184
168
  }
185
169
 
186
170
  get idMaybe(): ${entity.idName} | undefined {
187
171
  ${idMaybeCode}
188
172
  }
189
173
 
190
- get idTagged(): ${symbols_1.TaggedId} {
191
- return this.idTaggedMaybe || ${symbols_1.failNoIdYet}("${entityName}");
174
+ get idTagged(): ${TaggedId} {
175
+ return this.idTaggedMaybe || ${failNoIdYet}("${entityName}");
192
176
  }
193
177
 
194
- get idTaggedMaybe(): ${symbols_1.TaggedId} | undefined {
195
- return ${symbols_1.getField}(this, "id");
178
+ get idTaggedMaybe(): ${TaggedId} | undefined {
179
+ return ${getField}(this, "id");
196
180
  }
197
181
 
198
182
  ${primitives}
199
183
 
200
- ${tsdoc_1.tsdocComments.entity.setPartial}
184
+ ${tsdocComments.entity.setPartial}
201
185
  set(opts: Partial<${entity.optsName}>): void {
202
- ${symbols_1.setOpts}(this as any as ${entityName}, opts);
186
+ ${setOpts}(this as any as ${entityName}, opts);
203
187
  }
204
188
 
205
- ${tsdoc_1.tsdocComments.entity.setPartial}
206
- setPartial(opts: ${symbols_1.PartialOrNull}<${entity.optsName}>): void {
207
- ${symbols_1.setOpts}(this as any as ${entityName}, opts as ${symbols_1.OptsOf}<${entityName}>, { partial: true });
189
+ ${tsdocComments.entity.setPartial}
190
+ setPartial(opts: ${PartialOrNull}<${entity.optsName}>): void {
191
+ ${setOpts}(this as any as ${entityName}, opts as ${OptsOf}<${entityName}>, { partial: true });
208
192
  }
209
193
 
210
- ${tsdoc_1.tsdocComments.entity.setDeepPartial}
211
- setDeepPartial(opts: ${symbols_1.DeepPartialOrNull}<${entityName}>): Promise<void> {
212
- return ${symbols_1.updatePartial}(this as any as ${entityName}, opts);
194
+ ${tsdocComments.entity.setDeepPartial}
195
+ setDeepPartial(opts: ${DeepPartialOrNull}<${entityName}>): Promise<void> {
196
+ return ${updatePartial}(this as any as ${entityName}, opts);
213
197
  }
214
198
 
215
- ${tsdoc_1.tsdocComments.entity.changes}
216
- get changes(): ${symbols_1.Changes}<${entityName}${maybeOtherTypeChanges}> {
217
- return ${symbols_1.newChangesProxy}(this) as any;
199
+ ${tsdocComments.entity.changes}
200
+ get changes(): ${Changes}<${entityName}${maybeOtherTypeChanges}> {
201
+ return ${newChangesProxy}(this) as any;
218
202
  }
219
203
 
220
- ${maybeIsSoftDeleted}
204
+ ${maybeSoftDeleteMethods}
221
205
 
222
- ${tsdoc_1.tsdocComments.entity.load}
223
- load<U, V>(fn: (lens: ${symbols_1.Lens}<${entity.type}>) => ${symbols_1.Lens}<U, V>, opts: { sql?: boolean } = {}): Promise<V> {
224
- return ${symbols_1.loadLens}(this as any as ${entityName}, fn, opts);
206
+ ${tsdocComments.entity.load}
207
+ load<U, V>(fn: (lens: ${Lens}<${entity.type}>) => ${Lens}<U, V>, opts: { sql?: boolean } = {}): Promise<V> {
208
+ return ${loadLens}(this as any as ${entityName}, fn, opts);
225
209
  }
226
210
 
227
- ${tsdoc_1.tsdocComments.entity.populate}
228
- populate<const H extends ${symbols_1.LoadHint}<${entityName}>>(hint: H): Promise<${symbols_1.Loaded}<${entityName}, H>>;
229
- populate<const H extends ${symbols_1.LoadHint}<${entityName}>>(opts: { hint: H, forceReload?: boolean }): Promise<${symbols_1.Loaded}<${entityName}, H>>;
230
- populate<const H extends ${symbols_1.LoadHint}<${entityName}>, V>(hint: H, fn: (${varName}: Loaded<${entityName}, H>) => V): Promise<V>;
231
- populate<const H extends ${symbols_1.LoadHint}<${entityName}>, V>(opts: { hint: H, forceReload?: boolean }, fn: (${varName}: Loaded<${entityName}, H>) => V): Promise<V>;
232
- populate<const H extends ${symbols_1.LoadHint}<${entityName}>, V>(hintOrOpts: any, fn?: (${varName}: Loaded<${entityName}, H>) => V): Promise<${symbols_1.Loaded}<${entityName}, H> | V> {
211
+ ${tsdocComments.entity.populate}
212
+ populate<const H extends ${LoadHint}<${entityName}>>(hint: H): Promise<${Loaded}<${entityName}, H>>;
213
+ populate<const H extends ${LoadHint}<${entityName}>>(opts: { hint: H, forceReload?: boolean }): Promise<${Loaded}<${entityName}, H>>;
214
+ populate<const H extends ${LoadHint}<${entityName}>, V>(hint: H, fn: (${varName}: Loaded<${entityName}, H>) => V): Promise<V>;
215
+ populate<const H extends ${LoadHint}<${entityName}>, V>(opts: { hint: H, forceReload?: boolean }, fn: (${varName}: Loaded<${entityName}, H>) => V): Promise<V>;
216
+ populate<const H extends ${LoadHint}<${entityName}>, V>(hintOrOpts: any, fn?: (${varName}: Loaded<${entityName}, H>) => V): Promise<${Loaded}<${entityName}, H> | V> {
233
217
  return this.em.populate(this as any as ${entityName}, hintOrOpts, fn);
234
218
  }
235
219
 
236
- ${tsdoc_1.tsdocComments.entity.isLoaded}
237
- isLoaded<const H extends ${symbols_1.LoadHint}<${entityName}>>(hint: H): this is ${symbols_1.Loaded}<${entityName}${maybeOtherLoaded}, H> {
238
- return ${symbols_1.isLoaded}(this as any as ${entityName}, hint);
220
+ ${tsdocComments.entity.isLoaded}
221
+ isLoaded<const H extends ${LoadHint}<${entityName}>>(hint: H): this is ${Loaded}<${entityName}${maybeOtherLoaded}, H> {
222
+ return ${isLoaded}(this as any as ${entityName}, hint);
239
223
  }
240
224
 
241
- ${tsdoc_1.tsdocComments.entity.toJSON}
225
+ ${tsdocComments.entity.toJSON}
242
226
  toJSON(): object;
243
- toJSON<const H extends ${symbols_1.ToJsonHint}<${entityName}>>(hint: H): Promise<${symbols_1.JsonPayload}<${entityName}, H>>;
227
+ toJSON<const H extends ${ToJsonHint}<${entityName}>>(hint: H): Promise<${JsonPayload}<${entityName}, H>>;
244
228
  toJSON(hint?: any): object {
245
- return !hint || typeof hint === "string" ? super.toJSON() : ${symbols_1.toJSON}(this, hint);
229
+ return !hint || typeof hint === "string" ? super.toJSON() : ${toJSON}(this, hint);
246
230
  }
247
231
  }
248
232
  `;
249
233
  }
250
234
  function fieldHasDefaultValue(field) {
251
- let { columnDefault } = field;
252
- // If there's no default at all, return false
253
- if (columnDefault === null) {
254
- return false;
255
- }
256
- // Even though default is defined as a `number | boolean | string | null`, in reality pg-structure
257
- // only ever returns a `string | null`, so we handle that here
258
- columnDefault = columnDefault.toString();
259
- const fieldType = field.kind === "primitive" ? field.fieldType : "number";
260
- // Try to validate that we actually got a primitive value and not arbitrary SQL
261
- return ((fieldType === "number" && !isNaN(parseInt(columnDefault))) ||
262
- (fieldType === "bigint" && !isNaN(parseInt(columnDefault))) ||
263
- (fieldType === "string" && /^'.*'$/.test(columnDefault)) ||
264
- (fieldType === "boolean" && ["true", "false"].includes(columnDefault)));
235
+ let { columnDefault } = field;
236
+ if (columnDefault === null) return false;
237
+ columnDefault = columnDefault.toString();
238
+ const fieldType = field.kind === "primitive" ? field.fieldType : "number";
239
+ return fieldType === "number" && !isNaN(parseInt(columnDefault)) || fieldType === "bigint" && !isNaN(parseInt(columnDefault)) || fieldType === "string" && /^'.*'$/.test(columnDefault) || fieldType === "boolean" && ["true", "false"].includes(columnDefault);
265
240
  }
266
241
  function generatePolymorphicTypes(meta) {
267
- return meta.polymorphics.flatMap((pf) => [
268
- (0, ts_poet_1.code) `export type ${pf.fieldType} = ${pf.components.map((c) => (0, ts_poet_1.code) `| ${c.otherEntity.type}`)};`,
269
- (0, ts_poet_1.code) `export function get${pf.fieldType}Constructors(): ${symbols_1.MaybeAbstractEntityConstructor}<${pf.fieldType}>[] {
270
- return [${pf.components.map((c) => (0, ts_poet_1.code) `${c.otherEntity.typeSymbol},`)}];
242
+ return meta.polymorphics.flatMap((pf) => [
243
+ code`export type ${pf.fieldType} = ${pf.components.map((c) => code`| ${c.otherEntity.type}`)};`,
244
+ code`export function get${pf.fieldType}Constructors(): ${MaybeAbstractEntityConstructor}<${pf.fieldType}>[] {
245
+ return [${pf.components.map((c) => code`${c.otherEntity.typeSymbol},`)}];
271
246
  }`,
272
- (0, ts_poet_1.code) `export function is${pf.fieldType}(maybeEntity: unknown): maybeEntity is ${pf.fieldType} {
273
- return ${symbols_1.isEntity}(maybeEntity) && get${pf.fieldType}Constructors().some((type) => maybeEntity instanceof type);
274
- }`,
275
- ]);
247
+ code`export function is${pf.fieldType}(maybeEntity: unknown): maybeEntity is ${pf.fieldType} {
248
+ return ${isEntity}(maybeEntity) && get${pf.fieldType}Constructors().some((type) => maybeEntity instanceof type);
249
+ }`
250
+ ]);
276
251
  }
277
252
  function generateDefaultValues(config, meta, configName) {
278
- // Skip sync defaults b/c we'll just stomp the getter; leave async in case they're RQFs
279
- // where the row must fundamentally be inserted with a dummy value before the real value is calced.
280
- function notSync(field) {
281
- return "derived" in field && field.derived !== "sync";
282
- }
283
- const primitives = meta.primitives
284
- .filter((field) => fieldHasDefaultValue(field))
285
- .filter(notSync)
286
- .map(({ fieldName, columnDefault }) => {
287
- return (0, ts_poet_1.code) `${configName}.setDefault("${fieldName}", ${columnDefault});`;
288
- });
289
- const pgEnums = meta.pgEnums
290
- .filter((field) => !!field.columnDefault)
291
- .map(({ fieldName, columnDefault }) => {
292
- return (0, ts_poet_1.code) `${configName}.setDefault("${fieldName}", ${columnDefault});`;
293
- });
294
- const enums = meta.enums
295
- .filter((field) => !!field.columnDefault && !field.isArray)
296
- .filter(notSync)
297
- .map(({ fieldName, columnDefault, enumRows, enumType, columnName }) => {
298
- const defaultRow = enumRows.find((r) => r.id === Number(columnDefault)) ||
299
- (0, utils_1.fail)(`Invalid default value ${columnDefault} for ${meta.tableName}.${columnName}`);
300
- return (0, ts_poet_1.code) `${configName}.setDefault("${fieldName}", ${enumType}.${(0, change_case_1.pascalCase)(defaultRow.code)});`;
301
- });
302
- return [...primitives, ...enums, ...pgEnums];
253
+ function notSync(field) {
254
+ return "derived" in field && field.derived !== "sync";
255
+ }
256
+ const primitives = meta.primitives.filter((field) => fieldHasDefaultValue(field)).filter(notSync).map(({ fieldName, columnDefault }) => {
257
+ return code`${configName}.setDefault("${fieldName}", ${columnDefault});`;
258
+ });
259
+ const pgEnums = meta.pgEnums.filter((field) => !!field.columnDefault).map(({ fieldName, columnDefault }) => {
260
+ return code`${configName}.setDefault("${fieldName}", ${columnDefault});`;
261
+ });
262
+ const enums = meta.enums.filter((field) => !!field.columnDefault && !field.isArray).filter(notSync).map(({ fieldName, columnDefault, enumRows, enumType, columnName }) => {
263
+ const defaultRow = enumRows.find((r) => r.id === Number(columnDefault)) || fail(`Invalid default value ${columnDefault} for ${meta.tableName}.${columnName}`);
264
+ return code`${configName}.setDefault("${fieldName}", ${enumType}.${pascalCase(defaultRow.code)});`;
265
+ });
266
+ return [
267
+ ...primitives,
268
+ ...enums,
269
+ ...pgEnums
270
+ ];
303
271
  }
304
272
  function generateDefaultValidationRules(db, meta, configName) {
305
- // Add required rules for all not-null columns
306
- const fields = [...meta.primitives, ...meta.enums, ...meta.manyToOnes, ...meta.polymorphics];
307
- const rules = fields
308
- .filter((p) => p.notNull)
309
- .map((p) => {
310
- const { fieldName } = p;
311
- const isReactive = "derived" in p && p.derived === "async";
312
- if (isReactive) {
313
- return (0, ts_poet_1.code) `${configName}.addRule("${fieldName}", ${symbols_1.newRequiredRule}("${fieldName}"));`;
314
- }
315
- else {
316
- return (0, ts_poet_1.code) `${configName}.addRule(${symbols_1.newRequiredRule}("${fieldName}"));`;
317
- }
318
- });
319
- // Add STI discriminator cannot change
320
- if (meta.stiDiscriminatorField) {
321
- const field = meta.enums.find((e) => e.fieldName === meta.stiDiscriminatorField) ?? (0, utils_1.fail)("STI field not found");
322
- rules.push((0, ts_poet_1.code) `${configName}.addRule(${symbols_1.cannotBeUpdated}("${field.fieldName}"));`);
323
- }
324
- // Add STI type must match
325
- const stiEntities = (0, inheritance_1.getStiEntities)(db.entities);
326
- if (stiEntities.size > 0) {
327
- for (const m2o of meta.manyToOnes) {
328
- // The `m2o.otherEntity` may already be pointing at the subtype, but stiEntities has subtypes in it as well...
329
- const target = stiEntities.get(m2o.otherEntity.name);
330
- if (target && m2o.otherEntity.name !== target.base.name) {
331
- rules.push((0, ts_poet_1.code) `${configName}.addRule("${m2o.fieldName}", ${symbols_1.mustBeSubType}("${m2o.fieldName}"));`);
332
- }
333
- }
334
- }
335
- // Add subtype specialization must match
336
- if (meta.baseType) {
337
- meta.manyToOnes
338
- .filter((m2o) => meta.baseType?.manyToOnes?.find((o) => o.fieldName === m2o.fieldName && o.otherEntity.name !== m2o.otherEntity.name))
339
- .forEach((m2o) => {
340
- rules.push((0, ts_poet_1.code) `${configName}.addRule("${m2o.fieldName}", ${symbols_1.mustBeSubType}("${m2o.fieldName}"));`);
341
- });
342
- }
343
- return rules;
273
+ const rules = [
274
+ ...meta.primitives,
275
+ ...meta.enums,
276
+ ...meta.manyToOnes,
277
+ ...meta.polymorphics
278
+ ].filter((p) => p.notNull).map((p) => {
279
+ const { fieldName } = p;
280
+ const isReactive = "derived" in p && p.derived === "async";
281
+ if ("lazy" in p && p.lazy) return code`${configName}.addRule(${newRequiredLazyFieldRule}("${fieldName}"));`;
282
+ else if (isReactive) return code`${configName}.addRule("${fieldName}", ${newRequiredRule}("${fieldName}"));`;
283
+ else return code`${configName}.addRule(${newRequiredRule}("${fieldName}"));`;
284
+ });
285
+ if (meta.stiDiscriminatorField) {
286
+ const field = meta.enums.find((e) => e.fieldName === meta.stiDiscriminatorField) ?? fail("STI field not found");
287
+ rules.push(code`${configName}.addRule(${cannotBeUpdated}("${field.fieldName}"));`);
288
+ }
289
+ const stiEntities = getStiEntities(db.entities);
290
+ if (stiEntities.size > 0) for (const m2o of meta.manyToOnes) {
291
+ const target = stiEntities.get(m2o.otherEntity.name);
292
+ if (target && m2o.otherEntity.name !== target.base.name) rules.push(code`${configName}.addRule("${m2o.fieldName}", ${mustBeSubType}("${m2o.fieldName}"));`);
293
+ }
294
+ if (meta.baseType) meta.manyToOnes.filter((m2o) => meta.baseType?.manyToOnes?.find((o) => o.fieldName === m2o.fieldName && o.otherEntity.name !== m2o.otherEntity.name)).forEach((m2o) => {
295
+ rules.push(code`${configName}.addRule("${m2o.fieldName}", ${mustBeSubType}("${m2o.fieldName}"));`);
296
+ });
297
+ return rules;
344
298
  }
345
- // Make our opts type
346
299
  function generateOptsFields(meta) {
347
- const primitives = meta.primitives.map((field) => {
348
- const { fieldName, fieldType, notNull, derived } = field;
349
- if (derived)
350
- return (0, ts_poet_1.code) ``;
351
- return (0, ts_poet_1.code) `${fieldName}${maybeOptionalOrDefault(field)}: ${fieldType}${maybeUnionNull(notNull)};`;
352
- });
353
- const enums = meta.enums.map((field) => {
354
- const { fieldName, enumType, notNull, isArray, derived } = field;
355
- if (meta.stiDiscriminatorField === fieldName || derived) {
356
- // Don't include the discriminator as an opt b/c we'll infer it from the instance type
357
- return (0, ts_poet_1.code) ``;
358
- }
359
- else if (isArray) {
360
- // Arrays are always optional and we'll default to `[]`
361
- return (0, ts_poet_1.code) `${fieldName}?: ${enumType}[];`;
362
- }
363
- else {
364
- return (0, ts_poet_1.code) `${fieldName}${maybeOptionalOrDefault(field)}: ${enumType}${maybeUnionNull(notNull)};`;
365
- }
366
- });
367
- const pgEnums = meta.pgEnums.map((field) => {
368
- const { fieldName, enumType, notNull } = field;
369
- return (0, ts_poet_1.code) `${fieldName}${maybeOptionalOrDefault(field)}: ${enumType}${maybeUnionNull(notNull)};`;
370
- });
371
- const m2o = meta.manyToOnes
372
- .filter(({ derived }) => !derived) // Skip ReactiveReferences (derived m2o)
373
- // If a `group: { subType: SmallPublisherGroup }` is specializing this relation, that's
374
- // fine for most things, but not the `SmallPublisherOpts`, b/c it will break the contravariance
375
- // of `Publisher.setOpts` and `SmallPublisher.setOpts`
376
- .filter(({ fieldName }) => !meta.baseType?.manyToOnes.find((o) => o.fieldName === fieldName))
377
- .map((field) => {
378
- const { fieldName, otherEntity, notNull } = field;
379
- const maybeNull = maybeUnionNull(notNull);
380
- return (0, ts_poet_1.code) `${fieldName}${maybeOptionalOrDefault(field)}: ${otherEntity.type} | ${otherEntity.idType} ${maybeNull};`;
381
- });
382
- const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
383
- return (0, ts_poet_1.code) `${fieldName}?: ${otherEntity.type} | null;`;
384
- });
385
- const o2m = meta.oneToManys.map(({ fieldName, otherEntity }) => {
386
- return (0, ts_poet_1.code) `${fieldName}?: ${otherEntity.type}[];`;
387
- });
388
- const m2m = meta.manyToManys
389
- .filter(({ derived }) => !derived) // Skip ReactiveManyToManys
390
- .map(({ fieldName, otherEntity }) => {
391
- return (0, ts_poet_1.code) `${fieldName}?: ${otherEntity.type}[];`;
392
- });
393
- const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
394
- return (0, ts_poet_1.code) `${fieldName}?: ${enumType}[];`;
395
- });
396
- const polys = meta.polymorphics.map((field) => {
397
- const { fieldName, notNull, fieldType } = field;
398
- return (0, ts_poet_1.code) `${fieldName}${maybeOptionalOrDefault(field)}: ${fieldType};`;
399
- });
400
- return [...primitives, ...enums, ...pgEnums, ...m2o, ...polys, ...o2o, ...o2m, ...m2m, ...m2mEnum];
300
+ const primitives = meta.primitives.map((field) => {
301
+ const { fieldName, fieldType, notNull, derived } = field;
302
+ if (derived) return code``;
303
+ return code`${fieldName}${maybeOptionalOrDefault(field)}: ${fieldType}${maybeUnionNull(notNull)};`;
304
+ });
305
+ const enums = meta.enums.map((field) => {
306
+ const { fieldName, enumType, notNull, isArray, derived } = field;
307
+ if (meta.stiDiscriminatorField === fieldName || derived) return code``;
308
+ else if (isArray) return code`${fieldName}?: ${enumType}[];`;
309
+ else return code`${fieldName}${maybeOptionalOrDefault(field)}: ${enumType}${maybeUnionNull(notNull)};`;
310
+ });
311
+ const pgEnums = meta.pgEnums.map((field) => {
312
+ const { fieldName, enumType, notNull } = field;
313
+ return code`${fieldName}${maybeOptionalOrDefault(field)}: ${enumType}${maybeUnionNull(notNull)};`;
314
+ });
315
+ const m2o = meta.manyToOnes.filter(({ derived }) => !derived).filter(({ fieldName }) => !meta.baseType?.manyToOnes.find((o) => o.fieldName === fieldName)).map((field) => {
316
+ const { fieldName, otherEntity, notNull } = field;
317
+ const maybeNull = maybeUnionNull(notNull);
318
+ return code`${fieldName}${maybeOptionalOrDefault(field)}: ${otherEntity.type} | ${otherEntity.idType} ${maybeNull};`;
319
+ });
320
+ const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
321
+ return code`${fieldName}?: ${otherEntity.type} | null;`;
322
+ });
323
+ const o2m = meta.oneToManys.map(({ fieldName, otherEntity }) => {
324
+ return code`${fieldName}?: ${otherEntity.type}[];`;
325
+ });
326
+ const m2m = meta.manyToManys.filter(({ derived }) => !derived).map(({ fieldName, otherEntity }) => {
327
+ return code`${fieldName}?: ${otherEntity.type}[];`;
328
+ });
329
+ const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
330
+ return code`${fieldName}?: ${enumType}[];`;
331
+ });
332
+ const polys = meta.polymorphics.map((field) => {
333
+ const { fieldName, notNull, fieldType } = field;
334
+ return code`${fieldName}${maybeOptionalOrDefault(field)}: ${fieldType};`;
335
+ });
336
+ return [
337
+ ...primitives,
338
+ ...enums,
339
+ ...pgEnums,
340
+ ...m2o,
341
+ ...polys,
342
+ ...o2o,
343
+ ...o2m,
344
+ ...m2m,
345
+ ...m2mEnum
346
+ ];
401
347
  }
402
- // Make our fields type
403
348
  function generateFieldsType(meta, idType) {
404
- const id = (0, ts_poet_1.code) `id: { kind: "primitive"; type: ${idType}; unique: ${true}; nullable: never };`;
405
- const primitives = meta.primitives.map((field) => {
406
- const { fieldName, fieldType, notNull, unique, derived } = field;
407
- return (0, ts_poet_1.code) `${fieldName}: { kind: "primitive"; type: ${fieldType}; unique: ${unique}; nullable: ${undefinedOrNever(notNull)}, derived: ${derived !== false} };`;
408
- });
409
- const enums = meta.enums.map((field) => {
410
- const { fieldName, enumType, notNull, isArray } = field;
411
- if (isArray) {
412
- // Arrays are always optional and we'll default to `[]`
413
- return (0, ts_poet_1.code) `${fieldName}: { kind: "enum"; type: ${enumType}[]; nullable: never };`;
414
- }
415
- else {
416
- return (0, ts_poet_1.code) `${fieldName}: { kind: "enum"; type: ${enumType}; nullable: ${undefinedOrNever(notNull)} };`;
417
- }
418
- });
419
- const pgEnums = meta.pgEnums.map(({ fieldName, enumType, notNull }) => {
420
- const nullable = undefinedOrNever(notNull);
421
- return (0, ts_poet_1.code) `${fieldName}: { kind: "enum"; type: ${enumType}; nullable: ${nullable}; native: true };`;
422
- });
423
- const m2o = meta.manyToOnes.map(({ fieldName, otherEntity, notNull, derived }) => {
424
- return (0, ts_poet_1.code) `${fieldName}: { kind: "m2o"; type: ${otherEntity.type}; nullable: ${undefinedOrNever(notNull)}, derived: ${derived !== false} };`;
425
- });
426
- const polys = meta.polymorphics.map(({ fieldName, notNull, fieldType }) => {
427
- return (0, ts_poet_1.code) `${fieldName}: { kind: "poly"; type: ${fieldType}; nullable: ${undefinedOrNever(notNull)} };`;
428
- });
429
- const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
430
- return (0, ts_poet_1.code) `${fieldName}: { kind: "m2m"; type: ${otherEntity.type} };`;
431
- });
432
- const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
433
- return (0, ts_poet_1.code) `${fieldName}: { kind: "m2mEnum"; type: ${enumType} };`;
434
- });
435
- const o2m = meta.oneToManys.map(({ fieldName, otherEntity }) => {
436
- return (0, ts_poet_1.code) `${fieldName}: { kind: "o2m"; type: ${otherEntity.type} };`;
437
- });
438
- const lo2m = meta.largeOneToManys.map(({ fieldName, otherEntity }) => {
439
- return (0, ts_poet_1.code) `${fieldName}: { kind: "o2m"; type: ${otherEntity.type} };`;
440
- });
441
- return [id, ...primitives, ...enums, ...pgEnums, ...m2o, ...polys, ...m2m, ...m2mEnum, ...o2m, ...lo2m];
349
+ const id = code`id: { kind: "primitive"; type: ${idType}; unique: ${true}; nullable: never; };`;
350
+ const primitives = meta.primitives.map((field) => {
351
+ const { fieldName, fieldType, notNull, unique, derived } = field;
352
+ return code`${fieldName}: { kind: "primitive"; type: ${fieldType}; unique: ${unique}; nullable: ${undefinedOrNever(notNull)}, derived: ${derived !== false}; };`;
353
+ });
354
+ const enums = meta.enums.map((field) => {
355
+ const { fieldName, enumType, notNull, isArray } = field;
356
+ if (isArray) return code`${fieldName}: { kind: "enum"; type: ${enumType}[]; nullable: never; };`;
357
+ else return code`${fieldName}: { kind: "enum"; type: ${enumType}; nullable: ${undefinedOrNever(notNull)}; };`;
358
+ });
359
+ const pgEnums = meta.pgEnums.map((field) => {
360
+ const { fieldName, enumType, notNull } = field;
361
+ const nullable = undefinedOrNever(notNull);
362
+ return code`${fieldName}: { kind: "enum"; type: ${enumType}; nullable: ${nullable}; native: true; };`;
363
+ });
364
+ const m2o = meta.manyToOnes.map((field) => {
365
+ const { fieldName, otherEntity, notNull, derived } = field;
366
+ return code`${fieldName}: { kind: "m2o"; type: ${otherEntity.type}; nullable: ${undefinedOrNever(notNull)}, derived: ${derived !== false}; };`;
367
+ });
368
+ const polys = meta.polymorphics.map((field) => {
369
+ const { fieldName, notNull, fieldType } = field;
370
+ return code`${fieldName}: { kind: "poly"; type: ${fieldType}; nullable: ${undefinedOrNever(notNull)} };`;
371
+ });
372
+ const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
373
+ return code`${fieldName}: { kind: "m2m"; type: ${otherEntity.type} };`;
374
+ });
375
+ const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
376
+ return code`${fieldName}: { kind: "m2mEnum"; type: ${enumType} };`;
377
+ });
378
+ const o2m = meta.oneToManys.map(({ fieldName, otherEntity }) => {
379
+ return code`${fieldName}: { kind: "o2m"; type: ${otherEntity.type} };`;
380
+ });
381
+ const o2o = meta.oneToOnes.map((field) => {
382
+ return code`${field.fieldName}: { kind: "o2o"; type: ${field.otherEntity.type} };`;
383
+ });
384
+ const lo2m = meta.largeOneToManys.map(({ fieldName, otherEntity }) => {
385
+ return code`${fieldName}: { kind: "o2m"; type: ${otherEntity.type} };`;
386
+ });
387
+ return [
388
+ id,
389
+ ...primitives,
390
+ ...enums,
391
+ ...pgEnums,
392
+ ...m2o,
393
+ ...polys,
394
+ ...m2m,
395
+ ...m2mEnum,
396
+ ...o2m,
397
+ ...o2o,
398
+ ...lo2m
399
+ ];
400
+ }
401
+ /**
402
+ * Emits physical columns with domain value types and database nullability.
403
+ * I.e. Comment.parent_book_id is an optional Book reference, not the CommentParent union.
404
+ * fieldName identifies direct local domain filters; polymorphic components have no eligible name.
405
+ * Polymorphic component writes remain unsupported, so their policies are conservative.
406
+ */
407
+ function generateColumnsType(meta) {
408
+ const columns = { id: code`{ fieldName: "id"; type: ${IdOf}<${meta.entity.type}>; entity: ${meta.entity.type}; ${columnPolicyType(meta, meta.primaryKey)} }` };
409
+ for (const field of [
410
+ ...meta.primitives,
411
+ ...meta.enums,
412
+ ...meta.pgEnums,
413
+ ...meta.manyToOnes
414
+ ]) {
415
+ const policy = code`fieldName: "${field.fieldName}"; ${columnPolicyType(meta, field)}`;
416
+ if (field.kind === "primitive") columns[field.columnName] = code`{ type: ${field.fieldType}; ${policy} }`;
417
+ else if (field.kind === "m2o") columns[field.columnName] = code`{ type: ${IdOf}<${field.otherEntity.type}>; entity: ${field.otherEntity.type}; ${policy} }`;
418
+ else {
419
+ const array = field.kind === "enum" && field.isArray ? "[]" : "";
420
+ columns[field.columnName] = code`{ type: ${field.enumType}${array}; ${policy} }`;
421
+ }
422
+ }
423
+ for (const field of meta.polymorphics) for (const component of field.components) columns[component.columnName] = code`{ fieldName: never; type: ${IdOf}<${component.otherEntity.type}>; entity: ${component.otherEntity.type}; nullable: true; insert: "never"; update: false; }`;
424
+ return columns;
425
+ }
426
+ /** Emits SQL write policy without using ORM defaults or derived-field restrictions. */
427
+ function columnPolicyType(meta, column) {
428
+ const primaryKey = column === meta.primaryKey ? meta.primaryKey.columnType : void 0;
429
+ const insert = column.columnGenerated ? "never" : !column.columnNotNull || column.columnDefault != null || column === meta.createdAt || column === meta.updatedAt || primaryKey === "int" || primaryKey === "bigint" ? "optional" : "required";
430
+ return code`nullable: ${!column.columnNotNull}; insert: "${insert}"; update: ${!primaryKey && !column.columnGenerated};`;
442
431
  }
443
- // We know the OptIds types are only used in partials, so we make everything optional.
444
- // This especially needs to be the case b/c both `book: ...` and `bookId: ...` will be
445
- // in the partial type and of course the caller will only be setting one.
446
432
  function generateOptIdsFields(meta) {
447
- const m2o = meta.manyToOnes
448
- .filter(({ derived }) => !derived) // Skip ReactiveReferences
449
- .map(({ fieldName, otherEntity }) => {
450
- return (0, ts_poet_1.code) `${fieldName}Id?: ${otherEntity.idType} | null;`;
451
- });
452
- const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
453
- return (0, ts_poet_1.code) `${fieldName}Id?: ${otherEntity.idType} | null;`;
454
- });
455
- const o2m = meta.oneToManys.map(({ singularName, otherEntity }) => {
456
- return (0, ts_poet_1.code) `${singularName}Ids?: ${otherEntity.idType}[] | null;`;
457
- });
458
- const m2m = meta.manyToManys
459
- .filter(({ derived }) => !derived) // Skip ReactiveManyToManys
460
- .map(({ singularName, otherEntity }) => {
461
- return (0, ts_poet_1.code) `${singularName}Ids?: ${otherEntity.idType}[] | null;`;
462
- });
463
- const polys = meta.polymorphics.map(({ fieldName, fieldType }) => {
464
- return (0, ts_poet_1.code) `${fieldName}Id?: ${symbols_1.IdOf}<${fieldType}> | null;`;
465
- });
466
- return [...m2o, ...polys, ...o2o, ...o2m, ...m2m];
433
+ const m2o = meta.manyToOnes.filter(({ derived }) => !derived).map(({ fieldName, otherEntity }) => {
434
+ return code`${fieldName}Id?: ${otherEntity.idType} | null;`;
435
+ });
436
+ const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
437
+ return code`${fieldName}Id?: ${otherEntity.idType} | null;`;
438
+ });
439
+ const o2m = meta.oneToManys.map(({ singularName, otherEntity }) => {
440
+ return code`${singularName}Ids?: ${otherEntity.idType}[] | null;`;
441
+ });
442
+ const m2m = meta.manyToManys.filter(({ derived }) => !derived).map(({ singularName, otherEntity }) => {
443
+ return code`${singularName}Ids?: ${otherEntity.idType}[] | null;`;
444
+ });
445
+ const polys = meta.polymorphics.map(({ fieldName, fieldType }) => {
446
+ return code`${fieldName}Id?: ${IdOf}<${fieldType}> | null;`;
447
+ });
448
+ return [
449
+ ...m2o,
450
+ ...polys,
451
+ ...o2o,
452
+ ...o2m,
453
+ ...m2m
454
+ ];
467
455
  }
468
456
  function generateFilterFields(metasByName, meta) {
469
- // Always allow filtering on null to do "child.id is null" for detecting "has no children"
470
- const maybeId = meta.baseClassName ? [] : [(0, ts_poet_1.code) `id?: ${symbols_1.ValueFilter}<${meta.entity.idName}, never> | null;`];
471
- const primitives = meta.primitives.map(({ fieldName, fieldType, notNull }) => {
472
- if (fieldType === "boolean") {
473
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.BooleanFilter}<${nullOrNever(notNull)}>;`;
474
- }
475
- else {
476
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueFilter}<${fieldType}, ${nullOrNever(notNull)}>;`;
477
- }
478
- });
479
- const enums = meta.enums.map(({ fieldName, enumType, notNull, isArray }) => {
480
- const maybeArray = isArray ? "[]" : "";
481
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueFilter}<${enumType}${maybeArray}, ${nullOrNever(notNull)}>;`;
482
- });
483
- const pgEnums = meta.pgEnums.map(({ fieldName, enumType, notNull }) => {
484
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueFilter}<${enumType}, ${nullOrNever(notNull)}>;`;
485
- });
486
- const m2o = meta.manyToOnes.flatMap(({ fieldName, otherEntity, notNull }) => {
487
- const otherMeta = metasByName[otherEntity.name] ?? (0, utils_1.fail)(`Could not find metadata for ${otherEntity.name}`);
488
- return [
489
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.FilterOf}<${otherEntity.type}>, ${nullOrNever(notNull)}>;`,
490
- ...otherMeta.subTypes.map((st) => {
491
- return (0, ts_poet_1.code) `${fieldName}${st.name}?: ${symbols_1.EntityFilter}<${st.entity.type}, ${st.entity.idType}, ${symbols_1.FilterOf}<${st.entity.type}>, ${nullOrNever(notNull)}>;`;
492
- }),
493
- ];
494
- });
495
- const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
496
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.FilterOf}<${otherEntity.type}>, null | undefined>;`;
497
- });
498
- const o2m = meta.oneToManys.flatMap(({ fieldName, otherEntity, otherColumnNotNull }) => {
499
- const otherMeta = metasByName[otherEntity.name] ?? (0, utils_1.fail)(`Could not find metadata for ${otherEntity.name}`);
500
- return [
501
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.FilterOf}<${otherEntity.type}>, null | undefined>;`,
502
- ...otherMeta.subTypes.map((st) => {
503
- return (0, ts_poet_1.code) `${fieldName}${st.name}?: ${symbols_1.EntityFilter}<${st.entity.type}, ${st.entity.idType}, ${symbols_1.FilterOf}<${st.entity.type}>, ${nullOrNever(otherColumnNotNull)}>;`;
504
- }),
505
- ];
506
- });
507
- const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
508
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.FilterOf}<${otherEntity.type}>, null | undefined>;`;
509
- });
510
- // Enum m2m filters are membership filters, e.g. `{ logoColors: Color.Red }` / `{ logoColors: [Red, Green] }`.
511
- const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
512
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueFilter}<${enumType}, null | undefined>;`;
513
- });
514
- const polys = meta.polymorphics.flatMap(({ fieldName, fieldType, components, notNull }) => {
515
- return [
516
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityFilter}<${fieldType}, ${symbols_1.IdOf}<${fieldType}>, never, ${nullOrNever(notNull)}>;`,
517
- ...components.map((comp) => {
518
- const { type } = comp.otherEntity;
519
- return (0, ts_poet_1.code) `${fieldName}${type}?: ${symbols_1.EntityFilter}<${type}, ${symbols_1.IdOf}<${type}>, ${symbols_1.FilterOf}<${type}>, null>;`;
520
- }),
521
- ];
522
- });
523
- return [...maybeId, ...primitives, ...enums, ...pgEnums, ...m2o, ...o2o, ...o2m, ...m2m, ...m2mEnum, ...polys];
457
+ const maybeId = meta.baseClassName ? [] : [code`id?: ${ValueFilter}<${meta.entity.idName}, never> | null;`];
458
+ const primitives = meta.primitives.map(({ fieldName, fieldType, notNull }) => {
459
+ if (fieldType === "boolean") return code`${fieldName}?: ${BooleanFilter}<${nullOrNever(notNull)}>;`;
460
+ else return code`${fieldName}?: ${ValueFilter}<${fieldType}, ${nullOrNever(notNull)}>;`;
461
+ });
462
+ const enums = meta.enums.map(({ fieldName, enumType, notNull, isArray }) => {
463
+ return code`${fieldName}?: ${ValueFilter}<${enumType}${isArray ? "[]" : ""}, ${nullOrNever(notNull)}>;`;
464
+ });
465
+ const pgEnums = meta.pgEnums.map(({ fieldName, enumType, notNull }) => {
466
+ return code`${fieldName}?: ${ValueFilter}<${enumType}, ${nullOrNever(notNull)}>;`;
467
+ });
468
+ const m2o = meta.manyToOnes.flatMap(({ fieldName, otherEntity, notNull }) => {
469
+ const otherMeta = metasByName[otherEntity.name] ?? fail(`Could not find metadata for ${otherEntity.name}`);
470
+ return [code`${fieldName}?: ${EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${FilterOf}<${otherEntity.type}>, ${nullOrNever(notNull)}>;`, ...otherMeta.subTypes.map((st) => {
471
+ return code`${fieldName}${st.name}?: ${EntityFilter}<${st.entity.type}, ${st.entity.idType}, ${FilterOf}<${st.entity.type}>, ${nullOrNever(notNull)}>;`;
472
+ })];
473
+ });
474
+ const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
475
+ return code`${fieldName}?: ${EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${FilterOf}<${otherEntity.type}>, null | undefined>;`;
476
+ });
477
+ const o2m = meta.oneToManys.flatMap(({ fieldName, otherEntity, otherColumnNotNull }) => {
478
+ const otherMeta = metasByName[otherEntity.name] ?? fail(`Could not find metadata for ${otherEntity.name}`);
479
+ return [code`${fieldName}?: ${EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${FilterOf}<${otherEntity.type}>, null | undefined>;`, ...otherMeta.subTypes.map((st) => {
480
+ return code`${fieldName}${st.name}?: ${EntityFilter}<${st.entity.type}, ${st.entity.idType}, ${FilterOf}<${st.entity.type}>, ${nullOrNever(otherColumnNotNull)}>;`;
481
+ })];
482
+ });
483
+ const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
484
+ return code`${fieldName}?: ${EntityFilter}<${otherEntity.type}, ${otherEntity.idType}, ${FilterOf}<${otherEntity.type}>, null | undefined>;`;
485
+ });
486
+ const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
487
+ return code`${fieldName}?: ${ValueFilter}<${enumType}, null | undefined>;`;
488
+ });
489
+ const polys = meta.polymorphics.flatMap(({ fieldName, fieldType, components, notNull }) => {
490
+ return [code`${fieldName}?: ${EntityFilter}<${fieldType}, ${IdOf}<${fieldType}>, never, ${nullOrNever(notNull)}>;`, ...components.map((comp) => {
491
+ const { type } = comp.otherEntity;
492
+ return code`${fieldName}${type}?: ${EntityFilter}<${type}, ${IdOf}<${type}>, ${FilterOf}<${type}>, null>;`;
493
+ })];
494
+ });
495
+ return [
496
+ ...maybeId,
497
+ ...primitives,
498
+ ...enums,
499
+ ...pgEnums,
500
+ ...m2o,
501
+ ...o2o,
502
+ ...o2m,
503
+ ...m2m,
504
+ ...m2mEnum,
505
+ ...polys
506
+ ];
524
507
  }
525
508
  function generateGraphQLFilterFields(metasByName, meta) {
526
- const maybeId = meta.baseClassName ? [] : [(0, ts_poet_1.code) `id?: ${symbols_1.ValueGraphQLFilter}<${meta.entity.idName}>;`];
527
- const primitives = meta.primitives.map(({ fieldName, fieldType }) => {
528
- if (fieldType === "boolean") {
529
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.BooleanGraphQLFilter};`;
530
- }
531
- else {
532
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueGraphQLFilter}<${fieldType}>;`;
533
- }
534
- });
535
- const enums = meta.enums.map(({ fieldName, enumType, isArray }) => {
536
- const maybeArray = isArray ? "[]" : "";
537
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueGraphQLFilter}<${enumType}${maybeArray}>;`;
538
- });
539
- const pgEnums = meta.pgEnums.map(({ fieldName, enumType }) => {
540
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueGraphQLFilter}<${enumType}>;`;
541
- });
542
- const m2o = meta.manyToOnes.flatMap(({ fieldName, otherEntity, notNull }) => {
543
- const otherMeta = metasByName[otherEntity.name];
544
- return [
545
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.GraphQLFilterOf}<${otherEntity.type}>, ${nullOrNever(notNull)}>;`,
546
- (0, ts_poet_1.code) `${fieldName}Id?: ${symbols_1.ValueGraphQLFilter}<${otherEntity.idType}>;`,
547
- ...otherMeta.subTypes.map((st) => {
548
- return (0, ts_poet_1.code) `${fieldName}${st.name}?: ${symbols_1.EntityGraphQLFilter}<${st.entity.type}, ${st.entity.idType}, ${symbols_1.GraphQLFilterOf}<${st.entity.type}>, ${nullOrNever(notNull)}>;`;
549
- }),
550
- ];
551
- });
552
- const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
553
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`;
554
- });
555
- const o2m = meta.oneToManys.flatMap(({ fieldName, otherEntity, otherColumnNotNull }) => {
556
- const otherMeta = metasByName[otherEntity.name] ?? (0, utils_1.fail)(`Could not find metadata for ${otherEntity.name}`);
557
- return [
558
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`,
559
- ...otherMeta.subTypes.map((st) => {
560
- return (0, ts_poet_1.code) `${fieldName}${st.name}?: ${symbols_1.EntityGraphQLFilter}<${st.entity.type}, ${st.entity.idType}, ${symbols_1.GraphQLFilterOf}<${st.entity.type}>, ${nullOrNever(otherColumnNotNull)}>;`;
561
- }),
562
- ];
563
- });
564
- const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
565
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${symbols_1.GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`;
566
- });
567
- const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
568
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.ValueGraphQLFilter}<${enumType}>;`;
569
- });
570
- const polys = meta.polymorphics.flatMap(({ fieldName, fieldType, components, notNull }) => {
571
- return [
572
- (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.EntityGraphQLFilter}<${fieldType}, ${symbols_1.IdOf}<${fieldType}>, never, ${nullOrNever(notNull)}>;`,
573
- (0, ts_poet_1.code) `${fieldName}Id?: ${symbols_1.ValueGraphQLFilter}<${symbols_1.IdOf}<${fieldType}>>;`,
574
- ...components.map((comp) => {
575
- const { type } = comp.otherEntity;
576
- return (0, ts_poet_1.code) `${fieldName}${type}?: ${symbols_1.EntityGraphQLFilter}<${type}, ${symbols_1.IdOf}<${type}>, ${symbols_1.FilterOf}<${type}>, null>;`;
577
- }),
578
- ];
579
- });
580
- return [...maybeId, ...primitives, ...enums, ...pgEnums, ...m2o, ...o2o, ...o2m, ...m2m, ...m2mEnum, ...polys];
509
+ const maybeId = meta.baseClassName ? [] : [code`id?: ${ValueGraphQLFilter}<${meta.entity.idName}>;`];
510
+ const primitives = meta.primitives.map(({ fieldName, fieldType }) => {
511
+ if (fieldType === "boolean") return code`${fieldName}?: ${BooleanGraphQLFilter};`;
512
+ else return code`${fieldName}?: ${ValueGraphQLFilter}<${fieldType}>;`;
513
+ });
514
+ const enums = meta.enums.map(({ fieldName, enumType, isArray }) => {
515
+ return code`${fieldName}?: ${ValueGraphQLFilter}<${enumType}${isArray ? "[]" : ""}>;`;
516
+ });
517
+ const pgEnums = meta.pgEnums.map(({ fieldName, enumType }) => {
518
+ return code`${fieldName}?: ${ValueGraphQLFilter}<${enumType}>;`;
519
+ });
520
+ const m2o = meta.manyToOnes.flatMap(({ fieldName, otherEntity, notNull }) => {
521
+ const otherMeta = metasByName[otherEntity.name];
522
+ return [
523
+ code`${fieldName}?: ${EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${GraphQLFilterOf}<${otherEntity.type}>, ${nullOrNever(notNull)}>;`,
524
+ code`${fieldName}Id?: ${ValueGraphQLFilter}<${otherEntity.idType}>;`,
525
+ ...otherMeta.subTypes.map((st) => {
526
+ return code`${fieldName}${st.name}?: ${EntityGraphQLFilter}<${st.entity.type}, ${st.entity.idType}, ${GraphQLFilterOf}<${st.entity.type}>, ${nullOrNever(notNull)}>;`;
527
+ })
528
+ ];
529
+ });
530
+ const o2o = meta.oneToOnes.map(({ fieldName, otherEntity }) => {
531
+ return code`${fieldName}?: ${EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`;
532
+ });
533
+ const o2m = meta.oneToManys.flatMap(({ fieldName, otherEntity, otherColumnNotNull }) => {
534
+ const otherMeta = metasByName[otherEntity.name] ?? fail(`Could not find metadata for ${otherEntity.name}`);
535
+ return [code`${fieldName}?: ${EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`, ...otherMeta.subTypes.map((st) => {
536
+ return code`${fieldName}${st.name}?: ${EntityGraphQLFilter}<${st.entity.type}, ${st.entity.idType}, ${GraphQLFilterOf}<${st.entity.type}>, ${nullOrNever(otherColumnNotNull)}>;`;
537
+ })];
538
+ });
539
+ const m2m = meta.manyToManys.map(({ fieldName, otherEntity }) => {
540
+ return code`${fieldName}?: ${EntityGraphQLFilter}<${otherEntity.type}, ${otherEntity.idType}, ${GraphQLFilterOf}<${otherEntity.type}>, null | undefined>;`;
541
+ });
542
+ const m2mEnum = meta.manyToManyEnums.map(({ fieldName, enumType }) => {
543
+ return code`${fieldName}?: ${ValueGraphQLFilter}<${enumType}>;`;
544
+ });
545
+ const polys = meta.polymorphics.flatMap(({ fieldName, fieldType, components, notNull }) => {
546
+ return [
547
+ code`${fieldName}?: ${EntityGraphQLFilter}<${fieldType}, ${IdOf}<${fieldType}>, never, ${nullOrNever(notNull)}>;`,
548
+ code`${fieldName}Id?: ${ValueGraphQLFilter}<${IdOf}<${fieldType}>>;`,
549
+ ...components.map((comp) => {
550
+ const { type } = comp.otherEntity;
551
+ return code`${fieldName}${type}?: ${EntityGraphQLFilter}<${type}, ${IdOf}<${type}>, ${FilterOf}<${type}>, null>;`;
552
+ })
553
+ ];
554
+ });
555
+ return [
556
+ ...maybeId,
557
+ ...primitives,
558
+ ...enums,
559
+ ...pgEnums,
560
+ ...m2o,
561
+ ...o2o,
562
+ ...o2m,
563
+ ...m2m,
564
+ ...m2mEnum,
565
+ ...polys
566
+ ];
581
567
  }
582
568
  function generateOrderFields(meta) {
583
- const maybeId = meta.baseClassName ? [] : [(0, ts_poet_1.code) `id?: ${symbols_1.OrderBy};`];
584
- const primitives = meta.primitives.map(({ fieldName }) => {
585
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.OrderBy};`;
586
- });
587
- const enums = meta.enums.map(({ fieldName }) => {
588
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.OrderBy};`;
589
- });
590
- const pgEnums = meta.pgEnums.map(({ fieldName }) => {
591
- return (0, ts_poet_1.code) `${fieldName}?: ${symbols_1.OrderBy};`;
592
- });
593
- const m2o = meta.manyToOnes.map(({ fieldName, otherEntity }) => {
594
- return (0, ts_poet_1.code) `${fieldName}?: ${otherEntity.orderType};`;
595
- });
596
- return [...maybeId, ...primitives, ...enums, ...pgEnums, ...m2o];
569
+ const maybeId = meta.baseClassName ? [] : [code`id?: ${OrderBy};`];
570
+ const primitives = meta.primitives.map(({ fieldName }) => {
571
+ return code`${fieldName}?: ${OrderBy};`;
572
+ });
573
+ const enums = meta.enums.map(({ fieldName }) => {
574
+ return code`${fieldName}?: ${OrderBy};`;
575
+ });
576
+ const pgEnums = meta.pgEnums.map(({ fieldName }) => {
577
+ return code`${fieldName}?: ${OrderBy};`;
578
+ });
579
+ const m2o = meta.manyToOnes.map(({ fieldName, otherEntity }) => {
580
+ return code`${fieldName}?: ${otherEntity.orderType};`;
581
+ });
582
+ return [
583
+ ...maybeId,
584
+ ...primitives,
585
+ ...enums,
586
+ ...pgEnums,
587
+ ...m2o
588
+ ];
597
589
  }
598
590
  function generateFactoryExtrasType(meta) {
599
- function withName(fieldName) {
600
- return `with${fieldName[0].toUpperCase() + fieldName.substring(1)}`;
601
- }
602
- const primitives = meta.primitives
603
- .filter((f) => f.derived === "async")
604
- .map((field) => {
605
- const { fieldName, fieldType, notNull } = field;
606
- return (0, ts_poet_1.code) `${withName(fieldName)}?: ${fieldType}${maybeUnionNull(notNull)};`;
607
- });
608
- const enums = meta.enums
609
- .filter((f) => f.derived === "async")
610
- .map((field) => {
611
- const { fieldName, enumType, notNull, isArray } = field;
612
- if (isArray) {
613
- return (0, ts_poet_1.code) `${withName(fieldName)}?: ${enumType}[];`;
614
- }
615
- else {
616
- return (0, ts_poet_1.code) `${withName(fieldName)}?: ${enumType}${maybeUnionNull(notNull)};`;
617
- }
618
- });
619
- return [...primitives, ...enums];
591
+ function withName(fieldName) {
592
+ return `with${fieldName[0].toUpperCase() + fieldName.substring(1)}`;
593
+ }
594
+ const primitives = meta.primitives.filter((f) => f.derived === "async").map((field) => {
595
+ const { fieldName, fieldType, notNull } = field;
596
+ return code`${withName(fieldName)}?: ${fieldType}${maybeUnionNull(notNull)};`;
597
+ });
598
+ const enums = meta.enums.filter((f) => f.derived === "async").map((field) => {
599
+ const { fieldName, enumType, notNull, isArray } = field;
600
+ if (isArray) return code`${withName(fieldName)}?: ${enumType}[];`;
601
+ else return code`${withName(fieldName)}?: ${enumType}${maybeUnionNull(notNull)};`;
602
+ });
603
+ return [...primitives, ...enums];
620
604
  }
621
- function createPrimitives(meta, entity) {
622
- const primitives = meta.primitives.map((p) => {
623
- const { fieldName, fieldType, notNull } = p;
624
- const maybeOptional = notNull ? "" : " | undefined";
625
- let getter;
626
- if (p.derived === "async") {
627
- getter = (0, ts_poet_1.code) `
628
- abstract readonly ${fieldName}: ${symbols_1.ReactiveField}<${entity.name}, ${p.fieldType}${maybeOptional}>;
605
+ function createPrimitives(meta, entity, fieldDocs) {
606
+ return meta.primitives.map((p) => {
607
+ const { fieldName, fieldType, notNull } = p;
608
+ const maybeOptional = notNull ? "" : " | undefined";
609
+ if (p.lazy) return code``;
610
+ let getter;
611
+ if (p.derived === "async") getter = code`
612
+ abstract readonly ${fieldName}: ${ReactiveField}<${entity.name}, ${p.fieldType}${maybeOptional}>;
629
613
  `;
630
- }
631
- else if (p.derived === "sync") {
632
- getter = (0, ts_poet_1.code) `
614
+ else if (p.derived === "sync") getter = code`
633
615
  abstract get ${fieldName}(): ${fieldType}${maybeOptional};
634
616
  `;
635
- }
636
- else if (p.zodSchema) {
637
- getter = (0, ts_poet_1.code) `
638
- get ${fieldName}(): ${symbols_1.Zod}.output<typeof ${p.zodSchema}>${maybeOptional} {
639
- return ${symbols_1.getField}(this, "${fieldName}");
617
+ else if (p.zodSchema) getter = code`
618
+ get ${fieldName}(): ${Zod}.output<typeof ${p.zodSchema}>${maybeOptional} {
619
+ return ${getField}(this, "${fieldName}");
640
620
  }
641
621
  `;
642
- }
643
- else {
644
- getter = (0, ts_poet_1.code) `
622
+ else getter = code`
645
623
  get ${fieldName}(): ${fieldType}${maybeOptional} {
646
- return ${symbols_1.getField}(this, "${fieldName}");
624
+ return ${getField}(this, "${fieldName}");
647
625
  }
648
626
  `;
649
- }
650
- let setter;
651
- // ...technically we should be checking a list of JS keywords
652
- const paramName = keywords_1.keywords.includes(fieldName) ? "value" : fieldName;
653
- if (p.protected) {
654
- // TODO Allow making the getter to be protected as well. And so probably remove it
655
- // from the Opts as well. Wonder how that works for required protected fields?
656
- //
657
- // We have to use a method of `set${fieldName}` because TS enforces getters/setters to have
658
- // same access level and currently we're leaving the getter as public.
659
- setter = (0, ts_poet_1.code) `
660
- protected set${(0, change_case_1.pascalCase)(fieldName)}(${paramName}: ${fieldType}${maybeOptional}) {
661
- ${symbols_1.setField}(this, "${fieldName}", ${paramName});
627
+ let setter;
628
+ const paramName = keywords.includes(fieldName) ? "value" : fieldName;
629
+ if (p.protected) setter = code`
630
+ protected set${pascalCase(fieldName)}(${paramName}: ${fieldType}${maybeOptional}) {
631
+ ${setField}(this, "${fieldName}", ${paramName});
662
632
  }
663
633
  `;
664
- }
665
- else if (p.derived) {
666
- setter = "";
667
- }
668
- else if (p.superstruct) {
669
- // We use `value` as the param name to not potentially conflict with the
670
- // name of the imported superstruct const that is passed to assert.
671
- setter = (0, ts_poet_1.code) `
634
+ else if (p.derived) setter = "";
635
+ else if (p.superstruct) setter = code`
672
636
  set ${fieldName}(value: ${fieldType}${maybeOptional}) {
673
637
  if (value) {
674
- ${symbols_1.SSAssert}(value, ${p.superstruct});
638
+ ${SSAssert}(value, ${p.superstruct});
675
639
  }
676
- ${symbols_1.setField}(this, "${fieldName}", value);
640
+ ${setField}(this, "${fieldName}", value);
677
641
  }
678
642
  `;
679
- }
680
- else if (p.zodSchema) {
681
- // We use `value` as the param name to not potentially conflict with the
682
- // name of the imported zod schema that is passed to parse.
683
- setter = (0, ts_poet_1.code) `
684
- set ${fieldName}(value: ${symbols_1.Zod}.input<typeof ${p.zodSchema}>${maybeOptional}) {
643
+ else if (p.zodSchema) setter = code`
644
+ set ${fieldName}(value: ${Zod}.input<typeof ${p.zodSchema}>${maybeOptional}) {
685
645
  if (value) {
686
- ${symbols_1.setField}(this, "${fieldName}", ${p.zodSchema}.parse(value));
646
+ ${setField}(this, "${fieldName}", ${p.zodSchema}.parse(value));
687
647
  } else {
688
- ${symbols_1.setField}(this, "${fieldName}", value);
648
+ ${setField}(this, "${fieldName}", value);
689
649
  }
690
650
  }
691
651
  `;
692
- }
693
- else {
694
- setter = (0, ts_poet_1.code) `
652
+ else setter = code`
695
653
  set ${fieldName}(${paramName}: ${fieldType}${maybeOptional}) {
696
- ${symbols_1.setField}(this, "${fieldName}", ${paramName});
654
+ ${setField}(this, "${fieldName}", ${paramName});
697
655
  }
698
656
  `;
699
- }
700
- return (0, ts_poet_1.code) `${getter} ${setter}`;
701
- });
702
- return primitives;
657
+ return code`${fieldDocBlock(fieldDocs, fieldName, entity.name)}${getter} ${setter}`;
658
+ });
703
659
  }
704
- function createRegularEnums(meta, entity) {
705
- return meta.enums
706
- .filter((e) => !e.isArray)
707
- .flatMap((e) => {
708
- const { fieldName, enumType, enumDetailType, enumDetailsType, notNull, enumRows, derived } = e;
709
- const maybeOptional = notNull ? "" : " | undefined";
710
- const getByCode = (0, ts_poet_1.code) `${enumDetailType}.getByCode(this.${fieldName})`;
711
- let getter;
712
- if (derived === "async") {
713
- getter = (0, ts_poet_1.code) `
714
- abstract readonly ${fieldName}: ${symbols_1.ReactiveField}<${entity.name}, ${enumType}${maybeOptional}>;
660
+ function createRegularEnums(meta, entity, fieldDocs) {
661
+ return meta.enums.filter((e) => !e.isArray).flatMap((e) => {
662
+ const { fieldName, enumType, enumDetailType, enumDetailsType, notNull, enumRows, derived } = e;
663
+ const maybeOptional = notNull ? "" : " | undefined";
664
+ const getByCode = code`${enumDetailType}.getByCode(this.${fieldName})`;
665
+ let getter;
666
+ if (derived === "async") getter = code`
667
+ abstract readonly ${fieldName}: ${ReactiveField}<${entity.name}, ${enumType}${maybeOptional}>;
715
668
  `;
716
- }
717
- else if (derived === "sync") {
718
- getter = (0, ts_poet_1.code) `
669
+ else if (derived === "sync") getter = code`
719
670
  abstract get ${fieldName}(): ${enumType}${maybeOptional};
720
671
  `;
721
- }
722
- else {
723
- getter = (0, ts_poet_1.code) `
672
+ else getter = code`
724
673
  get ${fieldName}(): ${enumType}${maybeOptional} {
725
- return ${symbols_1.getField}(this, "${fieldName}");
674
+ return ${getField}(this, "${fieldName}");
726
675
  }
727
676
 
728
677
  get ${fieldName}Details(): ${enumDetailsType}${maybeOptional} {
729
- return ${notNull ? getByCode : (0, ts_poet_1.code) `this.${fieldName} ? ${getByCode} : undefined`};
678
+ return ${notNull ? getByCode : code`this.${fieldName} ? ${getByCode} : undefined`};
730
679
  }
731
680
  `;
732
- }
733
- let setter;
734
- if (derived) {
735
- setter = (0, ts_poet_1.code) ``;
736
- }
737
- else {
738
- setter = (0, ts_poet_1.code) `
681
+ let setter;
682
+ if (derived) setter = code``;
683
+ else setter = code`
739
684
  set ${fieldName}(${fieldName}: ${enumType}${maybeOptional}) {
740
- ${symbols_1.setField}(this, "${fieldName}", ${fieldName});
685
+ ${setField}(this, "${fieldName}", ${fieldName});
741
686
  }
742
687
  `;
743
- }
744
- const codes = new Set(enumRows.map((r) => r.code));
745
- const shouldPrefixAccessors = meta.enums
746
- .filter((other) => other !== e)
747
- .some((other) => other.enumRows.some((r) => codes.has(r.code)));
748
- const accessors = enumRows.map((row) => (0, ts_poet_1.code) `
749
- get is${shouldPrefixAccessors ? (0, change_case_1.pascalCase)(fieldName) : ""}${(0, change_case_1.pascalCase)(row.code)}(): boolean {
750
- return ${symbols_1.getField}(this, "${fieldName}") === ${enumType}.${(0, change_case_1.pascalCase)(row.code)};
688
+ const codes = new Set(enumRows.map((r) => r.code));
689
+ const shouldPrefixAccessors = meta.enums.filter((other) => other !== e).some((other) => other.enumRows.some((r) => codes.has(r.code)));
690
+ const accessors = enumRows.map((row) => code`
691
+ get is${shouldPrefixAccessors ? pascalCase(fieldName) : ""}${pascalCase(row.code)}(): boolean {
692
+ return ${getField}(this, "${fieldName}") === ${enumType}.${pascalCase(row.code)};
751
693
  }
752
694
  `);
753
- return [getter, setter, ...accessors];
754
- });
695
+ return [
696
+ code`${fieldDocBlock(fieldDocs, fieldName, entity.name)}${getter}`,
697
+ setter,
698
+ ...accessors
699
+ ];
700
+ });
755
701
  }
756
- function createArrayEnums(meta) {
757
- return meta.enums
758
- .filter((e) => e.isArray)
759
- .flatMap((e) => {
760
- const { fieldName, enumType, enumDetailType, enumDetailsType, enumRows } = e;
761
- const getter = (0, ts_poet_1.code) `
702
+ function createArrayEnums(meta, fieldDocs) {
703
+ return meta.enums.filter((e) => e.isArray).flatMap((e) => {
704
+ const { fieldName, enumType, enumDetailType, enumDetailsType, enumRows } = e;
705
+ const getter = code`
762
706
  get ${fieldName}(): ${enumType}[] {
763
- return ${symbols_1.getField}(this, "${fieldName}") || [];
707
+ return ${getField}(this, "${fieldName}") || [];
764
708
  }
765
709
 
766
710
  get ${fieldName}Details(): ${enumDetailsType}[] {
767
711
  return this.${fieldName}.map(code => ${enumDetailType}.getByCode(code));
768
712
  }
769
713
  `;
770
- const setter = (0, ts_poet_1.code) `
714
+ const setter = code`
771
715
  set ${fieldName}(${fieldName}: ${enumType}[]) {
772
- ${symbols_1.setField}(this, "${fieldName}", ${fieldName});
716
+ ${setField}(this, "${fieldName}", ${fieldName});
773
717
  }
774
718
  `;
775
- const codes = new Set(enumRows.map((r) => r.code));
776
- const shouldPrefixAccessors = meta.enums
777
- .filter((other) => other !== e)
778
- .some((other) => other.enumRows.some((r) => codes.has(r.code)));
779
- const accessors = enumRows.map((row) => (0, ts_poet_1.code) `
780
- get is${shouldPrefixAccessors ? (0, change_case_1.pascalCase)(fieldName) : ""}${(0, change_case_1.pascalCase)(row.code)}(): boolean {
781
- return this.${fieldName}.includes(${enumType}.${(0, change_case_1.pascalCase)(row.code)});
719
+ const codes = new Set(enumRows.map((r) => r.code));
720
+ const shouldPrefixAccessors = meta.enums.filter((other) => other !== e).some((other) => other.enumRows.some((r) => codes.has(r.code)));
721
+ const accessors = enumRows.map((row) => code`
722
+ get is${shouldPrefixAccessors ? pascalCase(fieldName) : ""}${pascalCase(row.code)}(): boolean {
723
+ return this.${fieldName}.includes(${enumType}.${pascalCase(row.code)});
782
724
  }
783
725
  `);
784
- return [getter, setter, ...accessors];
785
- });
726
+ return [
727
+ code`${fieldDocBlock(fieldDocs, fieldName, meta.entity.name)}${getter}`,
728
+ setter,
729
+ ...accessors
730
+ ];
731
+ });
786
732
  }
787
- function createPgEnums(meta) {
788
- return meta.pgEnums.flatMap((e) => {
789
- const { fieldName, enumType, enumValues, notNull } = e;
790
- const maybeOptional = notNull ? "" : " | undefined";
791
- const getter = (0, ts_poet_1.code) `
733
+ function createPgEnums(meta, fieldDocs) {
734
+ return meta.pgEnums.flatMap((e) => {
735
+ const { fieldName, enumType, enumValues, notNull } = e;
736
+ const maybeOptional = notNull ? "" : " | undefined";
737
+ const getter = code`
792
738
  get ${fieldName}(): ${enumType}${maybeOptional} {
793
- return ${symbols_1.getField}(this, "${fieldName}");
739
+ return ${getField}(this, "${fieldName}");
794
740
  }
795
741
  `;
796
- const setter = (0, ts_poet_1.code) `
742
+ const setter = code`
797
743
  set ${fieldName}(${fieldName}: ${enumType}${maybeOptional}) {
798
- ${symbols_1.setField}(this, "${fieldName}", ${fieldName});
744
+ ${setField}(this, "${fieldName}", ${fieldName});
799
745
  }
800
746
  `;
801
- const codes = new Set(enumValues);
802
- const shouldPrefixAccessors = meta.pgEnums
803
- .filter((other) => other !== e)
804
- .some((other) => other.enumValues.some((r) => codes.has(r)));
805
- const accessors = enumValues.map((row) => (0, ts_poet_1.code) `
806
- get is${shouldPrefixAccessors ? (0, change_case_1.pascalCase)(fieldName) : ""}${(0, change_case_1.pascalCase)(row)}(): boolean {
807
- return this.${fieldName} === ${enumType}.${(0, change_case_1.pascalCase)(row)};
747
+ const codes = new Set(enumValues);
748
+ const shouldPrefixAccessors = meta.pgEnums.filter((other) => other !== e).some((other) => other.enumValues.some((r) => codes.has(r)));
749
+ const accessors = enumValues.map((row) => code`
750
+ get is${shouldPrefixAccessors ? pascalCase(fieldName) : ""}${pascalCase(row)}(): boolean {
751
+ return this.${fieldName} === ${enumType}.${pascalCase(row)};
808
752
  }
809
753
  `);
810
- return [getter, setter, ...accessors];
811
- });
754
+ return [
755
+ code`${fieldDocBlock(fieldDocs, fieldName, meta.entity.name)}${getter}`,
756
+ setter,
757
+ ...accessors
758
+ ];
759
+ });
812
760
  }
813
761
  function createRelations(config, meta, entity) {
814
- // Add ManyToOne entities
815
- const m2o = meta.manyToOnes.map((m2o) => {
816
- const { fieldName, otherEntity, otherFieldName, notNull } = m2o;
817
- const maybeOptional = notNull ? "never" : "undefined";
818
- if (m2o.derived === "async") {
819
- const line = (0, ts_poet_1.code) `abstract readonly ${fieldName}: ${symbols_1.ReactiveReference}<${entity.name}, ${otherEntity.type}, ${maybeOptional}>;`;
820
- return { kind: "abstract", line };
821
- }
822
- const decl = (0, ts_poet_1.code) `${symbols_1.ManyToOneReference}<${entity.type}, ${otherEntity.type}, ${maybeOptional}>`;
823
- const init = (0, ts_poet_1.code) `${symbols_1.hasOne}()`;
824
- return { kind: "concrete", fieldName, decl, init };
825
- });
826
- // Specialize
827
- const m2oBase = meta.baseType?.manyToOnes
828
- // Skip m2os that are already specialized to a different otherEntity, i.e. `SmallPublisher.group: SmallPublisherGroup`
829
- .filter((m2o) => !meta.manyToOnes.find((o) => o.fieldName === m2o.fieldName))
830
- // Don't specialize hasReactiveReferences b/c they're fields, not getters
831
- .filter((m2o) => m2o.derived !== "async")
832
- .map((m2o) => {
833
- const { fieldName, otherEntity, notNull } = m2o;
834
- const maybeOptional = notNull ? "never" : "undefined";
835
- const decl = (0, ts_poet_1.code) `${symbols_1.ManyToOneReference}<${entity.type}, ${otherEntity.type}, ${maybeOptional}>`;
836
- return { kind: "super", fieldName, decl };
837
- }) ?? [];
838
- // Add any recursive ManyToOne entities
839
- const m2oRecursive = meta.manyToOnes
840
- .filter((m2o) => m2o.otherEntity.name === meta.name)
841
- // Allow disabling recursive relations
842
- .filter((m2o) =>
843
- // STI subtypes don't have their own key in config.entities (stripped by stripStiPlaceholders),
844
- // so look up the base class name to find skipRecursiveRelations config
845
- !(config.entities[meta.inheritanceType == "sti" && meta.baseClassName ? meta.baseClassName : meta.name]
846
- ?.relations?.[m2o.fieldName]?.skipRecursiveRelations === true))
847
- // Skip ReactiveReferences because they don't have an `other` side for us to use
848
- .filter((m2o) => !m2o.derived)
849
- .flatMap((m2o) => {
850
- const { fieldName: m2oName, otherFieldName, otherEntity } = m2o;
851
- const parentsField = `${(0, pluralize_1.plural)(m2oName)}Recursive`;
852
- const maybeOneToOne = meta.oneToOnes.find((o2o) => o2o.fieldName === otherFieldName);
853
- const childrenField = maybeOneToOne ? `${(0, pluralize_1.plural)(otherFieldName)}Recursive` : `${otherFieldName}Recursive`;
854
- return [
855
- {
856
- kind: "concrete",
857
- fieldName: parentsField,
858
- decl: (0, ts_poet_1.code) `${symbols_1.ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
859
- init: (0, ts_poet_1.code) `${symbols_1.hasRecursiveParents}("${m2oName}", "${childrenField}")`,
860
- },
861
- {
862
- kind: "concrete",
863
- fieldName: childrenField,
864
- decl: (0, ts_poet_1.code) `${symbols_1.ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
865
- init: (0, ts_poet_1.code) `${symbols_1.hasRecursiveChildren}("${otherFieldName}", "${parentsField}")`,
866
- },
867
- ];
868
- });
869
- // Add any recursive ManyToMany entities (self-referential m2m)
870
- const m2mRecursive = meta.manyToManys
871
- .filter((m2m) => m2m.otherEntity.name === meta.name)
872
- .filter((m2m) => !m2m.derived)
873
- // STI subtypes don't have their own key in config.entities (stripped by stripStiPlaceholders),
874
- // so look up the base class name to find skipRecursiveRelations config
875
- .filter((m2m) => !(config.entities[meta.inheritanceType == "sti" && meta.baseClassName ? meta.baseClassName : meta.name]
876
- ?.relations?.[m2m.fieldName]?.skipRecursiveRelations === true))
877
- .map((m2m) => {
878
- const { fieldName, otherFieldName, otherEntity } = m2m;
879
- return {
880
- kind: "concrete",
881
- fieldName: `${fieldName}Recursive`,
882
- decl: (0, ts_poet_1.code) `${symbols_1.ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
883
- init: (0, ts_poet_1.code) `${symbols_1.hasRecursiveM2m}("${fieldName}", "${otherFieldName}Recursive")`,
884
- };
885
- });
886
- // Add OneToMany
887
- const o2m = meta.oneToManys.map((o2m) => {
888
- const { fieldName, otherEntity } = o2m;
889
- const decl = (0, ts_poet_1.code) `${symbols_1.Collection}<${entity.type}, ${otherEntity.type}>`;
890
- const init = (0, ts_poet_1.code) `${symbols_1.hasMany}()`;
891
- return { kind: "concrete", fieldName, decl, init };
892
- });
893
- // Specialize
894
- const o2mBase = meta.baseType?.oneToManys
895
- // Skip o2ms that are already specialized to a different otherEntity, i.e. `SmallPublisherGroup.publishers: SmallPublisher`
896
- .filter((o2m) => !meta.oneToManys.find((o) => o.fieldName === o2m.fieldName))
897
- .map((o2m) => {
898
- const { fieldName, otherEntity } = o2m;
899
- const decl = (0, ts_poet_1.code) `${symbols_1.Collection}<${entity.type}, ${otherEntity.type}>`;
900
- return { kind: "super", fieldName, decl };
901
- }) ?? [];
902
- // Add large OneToMany
903
- const lo2m = meta.largeOneToManys.map((o2m) => {
904
- const { fieldName, otherEntity } = o2m;
905
- const decl = (0, ts_poet_1.code) `${symbols_1.LargeCollection}<${entity.type}, ${otherEntity.type}>`;
906
- const init = (0, ts_poet_1.code) `${symbols_1.hasLargeMany}()`;
907
- return { kind: "concrete", fieldName, decl, init };
908
- });
909
- // Add OneToOne
910
- const o2o = meta.oneToOnes.map((o2o) => {
911
- const { fieldName, otherEntity } = o2o;
912
- const decl = (0, ts_poet_1.code) `${symbols_1.OneToOneReference}<${entity.type}, ${otherEntity.type}>`;
913
- const init = (0, ts_poet_1.code) `${symbols_1.hasOneToOne}()`;
914
- return { kind: "concrete", fieldName, decl, init };
915
- });
916
- // Specialize
917
- const o2oBase = meta.baseType?.oneToOnes.map((o2o) => {
918
- const { fieldName, otherEntity } = o2o;
919
- const decl = (0, ts_poet_1.code) `${symbols_1.OneToOneReference}<${entity.type}, ${otherEntity.type}>`;
920
- return { kind: "super", fieldName, decl };
921
- }) ?? [];
922
- // Add ManyToMany
923
- const m2m = meta.manyToManys.map((m2m) => {
924
- const { fieldName, otherEntity } = m2m;
925
- const comment = `// ${m2m.joinTableName} ${m2m.columnName} ${m2m.otherColumnName}`;
926
- if (m2m.derived === "async") {
927
- const line = (0, ts_poet_1.code) `abstract readonly ${fieldName}: ${symbols_1.ReactiveManyToMany}<${entity.name}, ${otherEntity.type}>;`;
928
- return { kind: "abstract", line, comment };
929
- }
930
- else if (m2m.derived === "otherSide") {
931
- const decl = (0, ts_poet_1.code) `${symbols_1.ReactiveManyToManyOtherSide}<${entity.type}, ${otherEntity.type}>`;
932
- const init = (0, ts_poet_1.code) `${symbols_1.hasReactiveManyToManyOtherSide}()`;
933
- return { kind: "concrete", fieldName, decl, init, comment };
934
- }
935
- else if (!m2m.derived) {
936
- const decl = (0, ts_poet_1.code) `${symbols_1.Collection}<${entity.type}, ${otherEntity.type}>`;
937
- const init = (0, ts_poet_1.code) `${symbols_1.hasManyToMany}()`;
938
- return { kind: "concrete", fieldName, decl, init, comment };
939
- }
940
- else {
941
- (0, utils_1.assertNever)(m2m.derived);
942
- }
943
- });
944
- // Specialize
945
- const m2mBase = meta.baseType?.manyToManys
946
- // Don't specialize hasReactiveManyToMany or hasReactiveManyToManyOtherSide b/c they're fields, not getters
947
- .filter((m2m) => !m2m.derived)
948
- .map((m2m) => {
949
- const { fieldName, otherEntity } = m2m;
950
- const decl = (0, ts_poet_1.code) `${symbols_1.Collection}<${entity.type}, ${otherEntity.type}>`;
951
- return { kind: "super", fieldName, decl };
952
- }) ?? [];
953
- // Add enum-backed ManyToMany (i.e. `Publisher.logoColors`)
954
- const m2mEnum = meta.manyToManyEnums.map((m2m) => {
955
- const { fieldName, enumType } = m2m;
956
- const comment = `// ${m2m.joinTableName} ${m2m.columnName} ${m2m.otherColumnName}`;
957
- const decl = (0, ts_poet_1.code) `${symbols_1.EnumCollection}<${entity.type}, ${enumType}>`;
958
- const init = (0, ts_poet_1.code) `${symbols_1.hasEnumCollection}()`;
959
- return { kind: "concrete", fieldName, decl, init, comment };
960
- });
961
- const m2mEnumBase = meta.baseType?.manyToManyEnums.map((m2m) => {
962
- const { fieldName, enumType } = m2m;
963
- const decl = (0, ts_poet_1.code) `${symbols_1.EnumCollection}<${entity.type}, ${enumType}>`;
964
- return { kind: "super", fieldName, decl };
965
- }) ?? [];
966
- // Add large ManyToMany
967
- const lm2m = meta.largeManyToManys.map((m2m) => {
968
- const { joinTableName, fieldName, columnName, otherEntity, otherFieldName, otherColumnName } = m2m;
969
- const decl = (0, ts_poet_1.code) `${symbols_1.LargeCollection}<${entity.type}, ${otherEntity.type}>`;
970
- const init = (0, ts_poet_1.code) `
971
- ${symbols_1.hasLargeManyToMany}(
762
+ const m2o = meta.manyToOnes.map((m2o) => {
763
+ const { fieldName, otherEntity, otherFieldName, notNull } = m2o;
764
+ const maybeOptional = notNull ? "never" : "undefined";
765
+ if (m2o.derived === "async") return {
766
+ kind: "abstract",
767
+ fieldName,
768
+ line: code`abstract readonly ${fieldName}: ${ReactiveReference}<${entity.name}, ${otherEntity.type}, ${maybeOptional}>;`
769
+ };
770
+ return {
771
+ kind: "concrete",
772
+ fieldName,
773
+ decl: code`${ManyToOneReference}<${entity.type}, ${otherEntity.type}, ${maybeOptional}>`,
774
+ init: code`${hasOne}()`
775
+ };
776
+ });
777
+ const m2oBase = meta.baseType?.manyToOnes.filter((m2o) => !meta.manyToOnes.find((o) => o.fieldName === m2o.fieldName)).filter((m2o) => m2o.derived !== "async").map((m2o) => {
778
+ const { fieldName, otherEntity, notNull } = m2o;
779
+ const maybeOptional = notNull ? "never" : "undefined";
780
+ return {
781
+ kind: "super",
782
+ fieldName,
783
+ decl: code`${ManyToOneReference}<${entity.type}, ${otherEntity.type}, ${maybeOptional}>`
784
+ };
785
+ }) ?? [];
786
+ const m2oRecursive = meta.manyToOnes.filter((m2o) => m2o.otherEntity.name === meta.name).filter((m2o) => !(config.entities[meta.inheritanceType == "sti" && meta.baseClassName ? meta.baseClassName : meta.name]?.relations?.[m2o.fieldName]?.skipRecursiveRelations === true)).filter((m2o) => !m2o.derived).flatMap((m2o) => {
787
+ const { fieldName: m2oName, otherFieldName, otherEntity } = m2o;
788
+ const parentsField = `${plural(m2oName)}Recursive`;
789
+ const childrenField = meta.oneToOnes.find((o2o) => o2o.fieldName === otherFieldName) ? `${plural(otherFieldName)}Recursive` : `${otherFieldName}Recursive`;
790
+ return [{
791
+ kind: "concrete",
792
+ fieldName: parentsField,
793
+ decl: code`${ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
794
+ init: code`${hasRecursiveParents}("${m2oName}", "${childrenField}")`
795
+ }, {
796
+ kind: "concrete",
797
+ fieldName: childrenField,
798
+ decl: code`${ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
799
+ init: code`${hasRecursiveChildren}("${otherFieldName}", "${parentsField}")`
800
+ }];
801
+ });
802
+ const m2mRecursive = meta.manyToManys.filter((m2m) => m2m.otherEntity.name === meta.name).filter((m2m) => !m2m.derived).filter((m2m) => !(config.entities[meta.inheritanceType == "sti" && meta.baseClassName ? meta.baseClassName : meta.name]?.relations?.[m2m.fieldName]?.skipRecursiveRelations === true)).map((m2m) => {
803
+ const { fieldName, otherFieldName, otherEntity } = m2m;
804
+ return {
805
+ kind: "concrete",
806
+ fieldName: `${fieldName}Recursive`,
807
+ decl: code`${ReadOnlyCollection}<${entity.type}, ${otherEntity.type}>`,
808
+ init: code`${hasRecursiveM2m}("${fieldName}", "${otherFieldName}Recursive")`
809
+ };
810
+ });
811
+ return [
812
+ meta.oneToManys.map((o2m) => {
813
+ const { fieldName, otherEntity } = o2m;
814
+ return {
815
+ kind: "concrete",
816
+ fieldName,
817
+ decl: code`${Collection}<${entity.type}, ${otherEntity.type}>`,
818
+ init: code`${hasMany}()`
819
+ };
820
+ }),
821
+ meta.baseType?.oneToManys.filter((o2m) => !meta.oneToManys.find((o) => o.fieldName === o2m.fieldName)).map((o2m) => {
822
+ const { fieldName, otherEntity } = o2m;
823
+ return {
824
+ kind: "super",
825
+ fieldName,
826
+ decl: code`${Collection}<${entity.type}, ${otherEntity.type}>`
827
+ };
828
+ }) ?? [],
829
+ meta.largeOneToManys.map((o2m) => {
830
+ const { fieldName, otherEntity } = o2m;
831
+ return {
832
+ kind: "concrete",
833
+ fieldName,
834
+ decl: code`${LargeCollection}<${entity.type}, ${otherEntity.type}>`,
835
+ init: code`${hasLargeMany}()`
836
+ };
837
+ }),
838
+ m2o,
839
+ m2oBase,
840
+ m2oRecursive,
841
+ m2mRecursive,
842
+ meta.oneToOnes.map((o2o) => {
843
+ const { fieldName, otherEntity } = o2o;
844
+ return {
845
+ kind: "concrete",
846
+ fieldName,
847
+ decl: code`${OneToOneReference}<${entity.type}, ${otherEntity.type}>`,
848
+ init: code`${hasOneToOne}()`
849
+ };
850
+ }),
851
+ meta.baseType?.oneToOnes.map((o2o) => {
852
+ const { fieldName, otherEntity } = o2o;
853
+ return {
854
+ kind: "super",
855
+ fieldName,
856
+ decl: code`${OneToOneReference}<${entity.type}, ${otherEntity.type}>`
857
+ };
858
+ }) ?? [],
859
+ meta.manyToManys.map((m2m) => {
860
+ const { fieldName, otherEntity } = m2m;
861
+ const comment = `// ${m2m.joinTableName} ${m2m.columnName} ${m2m.otherColumnName}`;
862
+ if (m2m.derived === "async") return {
863
+ kind: "abstract",
864
+ fieldName,
865
+ line: code`abstract readonly ${fieldName}: ${ReactiveManyToMany}<${entity.name}, ${otherEntity.type}>;`,
866
+ comment
867
+ };
868
+ else if (m2m.derived === "otherSide") return {
869
+ kind: "concrete",
870
+ fieldName,
871
+ decl: code`${ReactiveManyToManyOtherSide}<${entity.type}, ${otherEntity.type}>`,
872
+ init: code`${hasReactiveManyToManyOtherSide}()`,
873
+ comment
874
+ };
875
+ else if (!m2m.derived) return {
876
+ kind: "concrete",
877
+ fieldName,
878
+ decl: code`${Collection}<${entity.type}, ${otherEntity.type}>`,
879
+ init: code`${hasManyToMany}()`,
880
+ comment
881
+ };
882
+ else assertNever(m2m.derived);
883
+ }),
884
+ meta.baseType?.manyToManys.filter((m2m) => !m2m.derived).map((m2m) => {
885
+ const { fieldName, otherEntity } = m2m;
886
+ return {
887
+ kind: "super",
888
+ fieldName,
889
+ decl: code`${Collection}<${entity.type}, ${otherEntity.type}>`
890
+ };
891
+ }) ?? [],
892
+ meta.manyToManyEnums.map((m2m) => {
893
+ const { fieldName, enumType } = m2m;
894
+ const comment = `// ${m2m.joinTableName} ${m2m.columnName} ${m2m.otherColumnName}`;
895
+ return {
896
+ kind: "concrete",
897
+ fieldName,
898
+ decl: code`${EnumCollection}<${entity.type}, ${enumType}>`,
899
+ init: code`${hasEnumCollection}()`,
900
+ comment
901
+ };
902
+ }),
903
+ meta.baseType?.manyToManyEnums.map((m2m) => {
904
+ const { fieldName, enumType } = m2m;
905
+ return {
906
+ kind: "super",
907
+ fieldName,
908
+ decl: code`${EnumCollection}<${entity.type}, ${enumType}>`
909
+ };
910
+ }) ?? [],
911
+ meta.largeManyToManys.map((m2m) => {
912
+ const { joinTableName, fieldName, columnName, otherEntity, otherFieldName, otherColumnName } = m2m;
913
+ return {
914
+ kind: "concrete",
915
+ fieldName,
916
+ decl: code`${LargeCollection}<${entity.type}, ${otherEntity.type}>`,
917
+ init: code`
918
+ ${hasLargeManyToMany}(
972
919
  "${joinTableName}",
973
920
  "${columnName}",
974
921
  "${otherFieldName}",
975
922
  "${otherColumnName}",
976
923
  ${m2m.hasJoinTableId},
977
924
  );
978
- `;
979
- return { kind: "concrete", fieldName, decl, init };
980
- });
981
- // Add Polymorphic
982
- const polymorphic = meta.polymorphics.map((p) => {
983
- const { fieldName, notNull, fieldType } = p;
984
- const maybeOptional = notNull ? "never" : "undefined";
985
- const decl = (0, ts_poet_1.code) `${symbols_1.PolymorphicReference}<${entity.type}, ${fieldType}, ${maybeOptional}>`;
986
- const init = (0, ts_poet_1.code) `${symbols_1.hasOnePolymorphic}()`;
987
- return { kind: "concrete", fieldName, decl, init };
988
- });
989
- return [
990
- o2m,
991
- o2mBase,
992
- lo2m,
993
- m2o,
994
- m2oBase,
995
- m2oRecursive,
996
- m2mRecursive,
997
- o2o,
998
- o2oBase,
999
- m2m,
1000
- m2mBase,
1001
- m2mEnum,
1002
- m2mEnumBase,
1003
- lm2m,
1004
- polymorphic,
1005
- ].flat();
925
+ `
926
+ };
927
+ }),
928
+ meta.polymorphics.map((p) => {
929
+ const { fieldName, notNull, fieldType } = p;
930
+ const maybeOptional = notNull ? "never" : "undefined";
931
+ return {
932
+ kind: "concrete",
933
+ fieldName,
934
+ decl: code`${PolymorphicReference}<${entity.type}, ${fieldType}, ${maybeOptional}>`,
935
+ init: code`${hasOnePolymorphic}()`
936
+ };
937
+ }),
938
+ meta.primitives.filter((p) => p.lazy).map((p) => {
939
+ const { fieldName, fieldType, notNull } = p;
940
+ const maybeOptional = notNull ? "" : " | undefined";
941
+ return {
942
+ kind: "concrete",
943
+ fieldName,
944
+ decl: code`${LazyField}<${entity.type}, ${fieldType}${maybeOptional}>`,
945
+ init: code`${hasLazyField}()`
946
+ };
947
+ })
948
+ ].flat();
1006
949
  }
1007
950
  /** Makes the field required if there is a `NOT NULL` and no db-or-config default. */
1008
951
  function maybeOptionalOrDefault(field) {
1009
- const hasDefault = (field.kind !== "m2o" && field.kind !== "poly" && fieldHasDefaultValue(field)) || field.hasConfigDefault;
1010
- return !field.notNull || hasDefault ? "?" : "";
952
+ const hasDefault = field.kind !== "m2o" && field.kind !== "poly" && fieldHasDefaultValue(field) || field.hasConfigDefault;
953
+ return !field.notNull || hasDefault ? "?" : "";
1011
954
  }
1012
955
  function maybeUnionNull(notNull) {
1013
- return notNull ? "" : " | null";
1014
- }
1015
- function maybeUndefined(notNull) {
1016
- return notNull ? "" : " | undefined";
956
+ return notNull ? "" : " | null";
1017
957
  }
1018
958
  function undefinedOrNever(notNull) {
1019
- return notNull ? "never" : "undefined";
959
+ return notNull ? "never" : "undefined";
1020
960
  }
1021
961
  function nullOrNever(notNull) {
1022
- return notNull ? "never" : "null";
962
+ return notNull ? "never" : "null";
963
+ }
964
+ /** Returns the nowUTC call for the deleted-at field's generated timestamp type. */
965
+ function nowUTCCall(config, field) {
966
+ if (!config.temporal) return code`${nowUTC}()`;
967
+ switch (field.columnType) {
968
+ case "date": return code`${nowUTC}("plainDate")`;
969
+ case "timestamp without time zone": return code`${nowUTC}("plainDateTime")`;
970
+ case "timestamp with time zone": return code`${nowUTC}("zonedDateTime")`;
971
+ default: return fail(`Unsupported deleted-at column type ${field.columnType}`);
972
+ }
1023
973
  }
1024
974
  /** Prefixes the comment with a newline, so it gets its own line. */
1025
975
  function maybeComment(comment) {
1026
- return comment ? ` ${comment}\n` : "";
976
+ return comment ? ` ${comment}\n` : "";
977
+ }
978
+ /**
979
+ * Renders a field's `.md` doc (plus its `@generated` tag) as a bare JSDoc block, or `""` if undocumented.
980
+ *
981
+ * Reuses the same {@link buildJSDocBlock} formatter the `.md` sync uses for hand-written `Entity.ts`
982
+ * members. Used directly before a getter template (which supplies its own leading newline), so the
983
+ * JSDoc lands immediately above the getter with no intervening blank line.
984
+ */
985
+ function fieldDocBlock(fieldDocs, fieldName, entityName) {
986
+ const doc = fieldDocs[fieldName];
987
+ return doc ? buildJSDocBlock(`${doc}\n${generatedTag(entityName)}`, 0) : "";
988
+ }
989
+ /** Like {@link fieldDocBlock} but wrapped in newlines, i.e. for inline `readonly x = ...` relation decls. */
990
+ function relationDocBlock(fieldDocs, fieldName, entityName) {
991
+ const block = fieldDocBlock(fieldDocs, fieldName, entityName);
992
+ return block ? `\n${block}\n` : "";
1027
993
  }
1028
994
  function getIdType(config) {
1029
- switch (config.idType) {
1030
- case "untagged-string":
1031
- case "tagged-string":
1032
- case undefined:
1033
- return "string";
1034
- case "number":
1035
- return "number";
1036
- default:
1037
- return (0, utils_1.assertNever)(config.idType);
1038
- }
995
+ switch (config.idType) {
996
+ case "untagged-string":
997
+ case "tagged-string":
998
+ case void 0: return "string";
999
+ case "number": return "number";
1000
+ default: return assertNever(config.idType);
1001
+ }
1039
1002
  }
1003
+ //#endregion
1004
+ export { generateEntityCodegenFile, getIdType };
1005
+
1040
1006
  //# sourceMappingURL=generateEntityCodegenFile.js.map