joist-codegen 2.3.0-next.42 → 2.3.0-next.43

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