@tstdl/base 0.93.181 → 0.93.183

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 (353) hide show
  1. package/api/server/api-request-token.provider.js +1 -1
  2. package/api/server/gateway.js +8 -3
  3. package/authentication/authentication.api.d.ts +13 -40
  4. package/authentication/authentication.api.js +5 -14
  5. package/authentication/client/authentication.service.d.ts +6 -14
  6. package/authentication/client/authentication.service.js +22 -4
  7. package/authentication/client/module.d.ts +1 -1
  8. package/authentication/client/module.js +4 -4
  9. package/authentication/models/index.d.ts +1 -0
  10. package/authentication/models/index.js +1 -0
  11. package/authentication/models/totp-results.model.d.ts +11 -0
  12. package/authentication/models/totp-results.model.js +37 -0
  13. package/authentication/server/authentication.api-controller.d.ts +3 -3
  14. package/authentication/server/authentication.api-controller.js +31 -4
  15. package/authentication/server/authentication.service.d.ts +5 -14
  16. package/authentication/server/authentication.service.js +6 -4
  17. package/core.d.ts +0 -5
  18. package/core.js +0 -8
  19. package/document-management/api/document-management.api.d.ts +2 -2
  20. package/document-management/service-models/document.service-model.d.ts +1 -1
  21. package/examples/config.d.ts +25 -0
  22. package/examples/config.js +26 -0
  23. package/notification/server/module.d.ts +1 -1
  24. package/notification/server/module.js +1 -1
  25. package/package.json +5 -5
  26. package/signals/api.d.ts +5 -1
  27. package/signals/api.js +3 -1
  28. package/signals/implementation/api.d.ts +13 -5
  29. package/signals/implementation/api.js +7 -1
  30. package/signals/implementation/asserts.d.ts +2 -2
  31. package/signals/implementation/asserts.js +3 -3
  32. package/signals/implementation/computed.d.ts +7 -34
  33. package/signals/implementation/computed.js +14 -83
  34. package/signals/implementation/configure.js +6 -2
  35. package/signals/implementation/effect.d.ts +65 -46
  36. package/signals/implementation/effect.js +97 -62
  37. package/signals/implementation/index.d.ts +2 -4
  38. package/signals/implementation/index.js +2 -4
  39. package/signals/implementation/linked_signal.d.ts +36 -0
  40. package/signals/implementation/linked_signal.js +34 -0
  41. package/signals/implementation/primitive/computed.d.ts +55 -0
  42. package/signals/implementation/primitive/computed.js +107 -0
  43. package/signals/implementation/primitive/effect.d.ts +26 -0
  44. package/signals/implementation/primitive/effect.js +31 -0
  45. package/signals/implementation/{equality.d.ts → primitive/equality.d.ts} +1 -1
  46. package/signals/implementation/{equality.js → primitive/equality.js} +1 -1
  47. package/signals/implementation/primitive/errors.d.ts +10 -0
  48. package/signals/implementation/{errors.js → primitive/errors.js} +3 -4
  49. package/signals/implementation/primitive/formatter.d.ts +19 -0
  50. package/signals/implementation/primitive/formatter.js +136 -0
  51. package/signals/implementation/{graph.d.ts → primitive/graph.d.ts} +68 -36
  52. package/signals/implementation/primitive/graph.js +386 -0
  53. package/signals/implementation/primitive/linked_signal.d.ts +46 -0
  54. package/signals/implementation/primitive/linked_signal.js +110 -0
  55. package/signals/implementation/primitive/signal.d.ts +31 -0
  56. package/signals/implementation/primitive/signal.js +80 -0
  57. package/signals/implementation/primitive/untracked.d.ts +12 -0
  58. package/signals/implementation/primitive/untracked.js +23 -0
  59. package/signals/implementation/{watch.d.ts → primitive/watch.d.ts} +1 -2
  60. package/signals/implementation/{watch.js → primitive/watch.js} +22 -16
  61. package/signals/implementation/resource/api.d.ts +275 -0
  62. package/signals/implementation/resource/api.js +26 -0
  63. package/signals/implementation/resource/debounce.d.ts +13 -0
  64. package/signals/implementation/resource/debounce.js +113 -0
  65. package/signals/implementation/resource/from_snapshots.d.ts +16 -0
  66. package/signals/implementation/resource/from_snapshots.js +44 -0
  67. package/signals/implementation/resource/index.d.ts +11 -0
  68. package/signals/implementation/resource/index.js +11 -0
  69. package/signals/implementation/resource/resource.d.ts +110 -0
  70. package/signals/implementation/resource/resource.js +402 -0
  71. package/signals/implementation/root_effect_scheduler.d.ts +50 -0
  72. package/signals/implementation/root_effect_scheduler.js +66 -0
  73. package/signals/implementation/signal.d.ts +42 -18
  74. package/signals/implementation/signal.js +29 -49
  75. package/signals/implementation/to-observable.d.ts +12 -5
  76. package/signals/implementation/to-observable.js +12 -2
  77. package/signals/implementation/to-signal.d.ts +9 -18
  78. package/signals/implementation/to-signal.js +46 -13
  79. package/signals/implementation/untracked.d.ts +1 -1
  80. package/signals/implementation/untracked.js +3 -11
  81. package/signals/operators/debounce.d.ts +8 -0
  82. package/signals/operators/debounce.js +19 -0
  83. package/signals/operators/derive-async.js +43 -15
  84. package/signals/operators/index.d.ts +2 -0
  85. package/signals/operators/index.js +2 -0
  86. package/signals/operators/throttle.d.ts +8 -0
  87. package/signals/operators/throttle.js +31 -0
  88. package/ai/genkit/tests/multi-region.test.d.ts +0 -2
  89. package/ai/genkit/tests/multi-region.test.js +0 -179
  90. package/ai/genkit/tests/token-limit-fallback.test.d.ts +0 -2
  91. package/ai/genkit/tests/token-limit-fallback.test.js +0 -209
  92. package/ai/prompts/tests/prompt-builder.test.d.ts +0 -1
  93. package/ai/prompts/tests/prompt-builder.test.js +0 -22
  94. package/ai/tests/instructions-formatter.test.d.ts +0 -1
  95. package/ai/tests/instructions-formatter.test.js +0 -116
  96. package/ai/tests/steering.test.d.ts +0 -1
  97. package/ai/tests/steering.test.js +0 -37
  98. package/api/client/tests/api-client.test.d.ts +0 -1
  99. package/api/client/tests/api-client.test.js +0 -194
  100. package/api/server/tests/csrf.middleware.test.d.ts +0 -1
  101. package/api/server/tests/csrf.middleware.test.js +0 -91
  102. package/authentication/tests/authentication-password-requirements.validator.test.d.ts +0 -1
  103. package/authentication/tests/authentication-password-requirements.validator.test.js +0 -29
  104. package/authentication/tests/authentication.api-controller.test.d.ts +0 -1
  105. package/authentication/tests/authentication.api-controller.test.js +0 -156
  106. package/authentication/tests/authentication.api-request-token.provider.test.d.ts +0 -1
  107. package/authentication/tests/authentication.api-request-token.provider.test.js +0 -48
  108. package/authentication/tests/authentication.client-error-handling.test.d.ts +0 -1
  109. package/authentication/tests/authentication.client-error-handling.test.js +0 -123
  110. package/authentication/tests/authentication.client-middleware.test.d.ts +0 -1
  111. package/authentication/tests/authentication.client-middleware.test.js +0 -118
  112. package/authentication/tests/authentication.client-service-methods.test.d.ts +0 -1
  113. package/authentication/tests/authentication.client-service-methods.test.js +0 -177
  114. package/authentication/tests/authentication.client-service-refresh.test.d.ts +0 -1
  115. package/authentication/tests/authentication.client-service-refresh.test.js +0 -153
  116. package/authentication/tests/authentication.client-service.test.d.ts +0 -1
  117. package/authentication/tests/authentication.client-service.test.js +0 -76
  118. package/authentication/tests/authentication.refresh-busy-loop.test.d.ts +0 -1
  119. package/authentication/tests/authentication.refresh-busy-loop.test.js +0 -84
  120. package/authentication/tests/authentication.service.test.d.ts +0 -1
  121. package/authentication/tests/authentication.service.test.js +0 -167
  122. package/authentication/tests/authentication.test-ancillary-service.d.ts +0 -9
  123. package/authentication/tests/authentication.test-ancillary-service.js +0 -27
  124. package/authentication/tests/brute-force-protection.test.d.ts +0 -1
  125. package/authentication/tests/brute-force-protection.test.js +0 -211
  126. package/authentication/tests/helper.test.d.ts +0 -1
  127. package/authentication/tests/helper.test.js +0 -122
  128. package/authentication/tests/password-requirements.error.test.d.ts +0 -1
  129. package/authentication/tests/password-requirements.error.test.js +0 -14
  130. package/authentication/tests/remember.api.test.d.ts +0 -1
  131. package/authentication/tests/remember.api.test.js +0 -117
  132. package/authentication/tests/remember.service.test.d.ts +0 -1
  133. package/authentication/tests/remember.service.test.js +0 -83
  134. package/authentication/tests/subject.service.test.d.ts +0 -1
  135. package/authentication/tests/subject.service.test.js +0 -140
  136. package/authentication/tests/suspended-subject.test.d.ts +0 -1
  137. package/authentication/tests/suspended-subject.test.js +0 -120
  138. package/authentication/tests/totp.enrollment.test.d.ts +0 -1
  139. package/authentication/tests/totp.enrollment.test.js +0 -123
  140. package/authentication/tests/totp.login.test.d.ts +0 -1
  141. package/authentication/tests/totp.login.test.js +0 -213
  142. package/authentication/tests/totp.recovery-codes.test.d.ts +0 -1
  143. package/authentication/tests/totp.recovery-codes.test.js +0 -97
  144. package/authentication/tests/totp.status.test.d.ts +0 -1
  145. package/authentication/tests/totp.status.test.js +0 -72
  146. package/cancellation/tests/coverage.test.d.ts +0 -1
  147. package/cancellation/tests/coverage.test.js +0 -49
  148. package/cancellation/tests/leak.test.d.ts +0 -1
  149. package/cancellation/tests/leak.test.js +0 -35
  150. package/cancellation/tests/token.test.d.ts +0 -1
  151. package/cancellation/tests/token.test.js +0 -136
  152. package/circuit-breaker/tests/circuit-breaker.test.d.ts +0 -1
  153. package/circuit-breaker/tests/circuit-breaker.test.js +0 -116
  154. package/cryptography/tests/cryptography.test.d.ts +0 -1
  155. package/cryptography/tests/cryptography.test.js +0 -175
  156. package/cryptography/tests/jwt.test.d.ts +0 -1
  157. package/cryptography/tests/jwt.test.js +0 -54
  158. package/cryptography/tests/modern.test.d.ts +0 -1
  159. package/cryptography/tests/modern.test.js +0 -105
  160. package/cryptography/tests/module.test.d.ts +0 -1
  161. package/cryptography/tests/module.test.js +0 -100
  162. package/cryptography/tests/totp.test.d.ts +0 -1
  163. package/cryptography/tests/totp.test.js +0 -108
  164. package/document-management/tests/ai-config-hierarchy.test.d.ts +0 -1
  165. package/document-management/tests/ai-config-hierarchy.test.js +0 -59
  166. package/document-management/tests/ai-config-integration.test.d.ts +0 -1
  167. package/document-management/tests/ai-config-integration.test.js +0 -125
  168. package/document-management/tests/ai-config-merge.test.d.ts +0 -1
  169. package/document-management/tests/ai-config-merge.test.js +0 -46
  170. package/document-management/tests/document-management-ai-overrides.test.d.ts +0 -1
  171. package/document-management/tests/document-management-ai-overrides.test.js +0 -63
  172. package/document-management/tests/document-management-core.test.d.ts +0 -1
  173. package/document-management/tests/document-management-core.test.js +0 -157
  174. package/document-management/tests/document-management.api.test.d.ts +0 -1
  175. package/document-management/tests/document-management.api.test.js +0 -101
  176. package/document-management/tests/document-statistics.service.test.d.ts +0 -1
  177. package/document-management/tests/document-statistics.service.test.js +0 -498
  178. package/document-management/tests/document-validation-ai-overrides.test.d.ts +0 -1
  179. package/document-management/tests/document-validation-ai-overrides.test.js +0 -87
  180. package/document-management/tests/document.service.test.d.ts +0 -1
  181. package/document-management/tests/document.service.test.js +0 -143
  182. package/document-management/tests/enum-helpers.test.d.ts +0 -1
  183. package/document-management/tests/enum-helpers.test.js +0 -452
  184. package/document-management/tests/helper.d.ts +0 -24
  185. package/document-management/tests/helper.js +0 -39
  186. package/errors/tests/format.test.d.ts +0 -1
  187. package/errors/tests/format.test.js +0 -84
  188. package/http/tests/server-timing.test.d.ts +0 -1
  189. package/http/tests/server-timing.test.js +0 -42
  190. package/injector/tests/advanced.test.d.ts +0 -1
  191. package/injector/tests/advanced.test.js +0 -116
  192. package/injector/tests/async-init.test.d.ts +0 -1
  193. package/injector/tests/async-init.test.js +0 -77
  194. package/injector/tests/basic.test.d.ts +0 -1
  195. package/injector/tests/basic.test.js +0 -114
  196. package/injector/tests/hierarchical.test.d.ts +0 -1
  197. package/injector/tests/hierarchical.test.js +0 -59
  198. package/injector/tests/leak.test.d.ts +0 -1
  199. package/injector/tests/leak.test.js +0 -45
  200. package/injector/tests/lifecycles.test.d.ts +0 -1
  201. package/injector/tests/lifecycles.test.js +0 -109
  202. package/logger/tests/pretty-print.test.d.ts +0 -1
  203. package/logger/tests/pretty-print.test.js +0 -60
  204. package/notification/tests/notification-api.test.d.ts +0 -1
  205. package/notification/tests/notification-api.test.js +0 -124
  206. package/notification/tests/notification-client.test.d.ts +0 -1
  207. package/notification/tests/notification-client.test.js +0 -101
  208. package/notification/tests/notification-flow.test.d.ts +0 -1
  209. package/notification/tests/notification-flow.test.js +0 -296
  210. package/notification/tests/notification-sse.service.test.d.ts +0 -1
  211. package/notification/tests/notification-sse.service.test.js +0 -43
  212. package/notification/tests/notification-type.service.test.d.ts +0 -1
  213. package/notification/tests/notification-type.service.test.js +0 -41
  214. package/object-storage/s3/tests/s3.object-storage.integration.test.d.ts +0 -1
  215. package/object-storage/s3/tests/s3.object-storage.integration.test.js +0 -303
  216. package/orm/tests/build-jsonb.test.d.ts +0 -1
  217. package/orm/tests/build-jsonb.test.js +0 -39
  218. package/orm/tests/data-types.test.d.ts +0 -1
  219. package/orm/tests/data-types.test.js +0 -39
  220. package/orm/tests/database-extension.test.d.ts +0 -1
  221. package/orm/tests/database-extension.test.js +0 -63
  222. package/orm/tests/database-migration.test.d.ts +0 -1
  223. package/orm/tests/database-migration.test.js +0 -83
  224. package/orm/tests/decorators.test.d.ts +0 -1
  225. package/orm/tests/decorators.test.js +0 -77
  226. package/orm/tests/encryption.test.d.ts +0 -1
  227. package/orm/tests/encryption.test.js +0 -31
  228. package/orm/tests/query-complex.test.d.ts +0 -1
  229. package/orm/tests/query-complex.test.js +0 -172
  230. package/orm/tests/query-converter-complex.test.d.ts +0 -1
  231. package/orm/tests/query-converter-complex.test.js +0 -131
  232. package/orm/tests/query-converter.test.d.ts +0 -1
  233. package/orm/tests/query-converter.test.js +0 -123
  234. package/orm/tests/repository-advanced.test.d.ts +0 -1
  235. package/orm/tests/repository-advanced.test.js +0 -189
  236. package/orm/tests/repository-attributes.test.d.ts +0 -1
  237. package/orm/tests/repository-attributes.test.js +0 -83
  238. package/orm/tests/repository-compound-primary-key.test.d.ts +0 -2
  239. package/orm/tests/repository-compound-primary-key.test.js +0 -226
  240. package/orm/tests/repository-comprehensive.test.d.ts +0 -1
  241. package/orm/tests/repository-comprehensive.test.js +0 -162
  242. package/orm/tests/repository-coverage.test.d.ts +0 -2
  243. package/orm/tests/repository-coverage.test.js +0 -242
  244. package/orm/tests/repository-cti-complex.test.d.ts +0 -1
  245. package/orm/tests/repository-cti-complex.test.js +0 -151
  246. package/orm/tests/repository-cti-embedded.test.d.ts +0 -1
  247. package/orm/tests/repository-cti-embedded.test.js +0 -178
  248. package/orm/tests/repository-cti-extensive.test.d.ts +0 -2
  249. package/orm/tests/repository-cti-extensive.test.js +0 -279
  250. package/orm/tests/repository-cti-mapping.test.d.ts +0 -2
  251. package/orm/tests/repository-cti-mapping.test.js +0 -108
  252. package/orm/tests/repository-cti-search.test.d.ts +0 -1
  253. package/orm/tests/repository-cti-search.test.js +0 -141
  254. package/orm/tests/repository-cti-soft-delete.test.d.ts +0 -2
  255. package/orm/tests/repository-cti-soft-delete.test.js +0 -103
  256. package/orm/tests/repository-cti-transactions.test.d.ts +0 -1
  257. package/orm/tests/repository-cti-transactions.test.js +0 -112
  258. package/orm/tests/repository-cti-upsert-many.test.d.ts +0 -2
  259. package/orm/tests/repository-cti-upsert-many.test.js +0 -115
  260. package/orm/tests/repository-cti.test.d.ts +0 -2
  261. package/orm/tests/repository-cti.test.js +0 -390
  262. package/orm/tests/repository-edge-cases.test.d.ts +0 -1
  263. package/orm/tests/repository-edge-cases.test.js +0 -178
  264. package/orm/tests/repository-expiration.test.d.ts +0 -2
  265. package/orm/tests/repository-expiration.test.js +0 -140
  266. package/orm/tests/repository-extra-coverage.test.d.ts +0 -2
  267. package/orm/tests/repository-extra-coverage.test.js +0 -402
  268. package/orm/tests/repository-mapping.test.d.ts +0 -2
  269. package/orm/tests/repository-mapping.test.js +0 -65
  270. package/orm/tests/repository-regression.test.d.ts +0 -1
  271. package/orm/tests/repository-regression.test.js +0 -288
  272. package/orm/tests/repository-search-coverage.test.d.ts +0 -1
  273. package/orm/tests/repository-search-coverage.test.js +0 -107
  274. package/orm/tests/repository-search.test.d.ts +0 -1
  275. package/orm/tests/repository-search.test.js +0 -105
  276. package/orm/tests/repository-soft-delete.test.d.ts +0 -1
  277. package/orm/tests/repository-soft-delete.test.js +0 -118
  278. package/orm/tests/repository-transactions-nested.test.d.ts +0 -1
  279. package/orm/tests/repository-transactions-nested.test.js +0 -178
  280. package/orm/tests/repository-types.test.d.ts +0 -1
  281. package/orm/tests/repository-types.test.js +0 -184
  282. package/orm/tests/repository-undelete.test.d.ts +0 -2
  283. package/orm/tests/repository-undelete.test.js +0 -201
  284. package/orm/tests/schema-converter.test.d.ts +0 -1
  285. package/orm/tests/schema-converter.test.js +0 -82
  286. package/orm/tests/schema-generation.test.d.ts +0 -2
  287. package/orm/tests/schema-generation.test.js +0 -174
  288. package/orm/tests/sql-helpers.test.d.ts +0 -1
  289. package/orm/tests/sql-helpers.test.js +0 -67
  290. package/orm/tests/transaction-safety.test.d.ts +0 -1
  291. package/orm/tests/transaction-safety.test.js +0 -81
  292. package/orm/tests/transactional.test.d.ts +0 -1
  293. package/orm/tests/transactional.test.js +0 -215
  294. package/orm/tests/utils.test.d.ts +0 -1
  295. package/orm/tests/utils.test.js +0 -70
  296. package/pdf/tests/utils.test.d.ts +0 -1
  297. package/pdf/tests/utils.test.js +0 -187
  298. package/process/tests/spawn.test.d.ts +0 -1
  299. package/process/tests/spawn.test.js +0 -182
  300. package/rate-limit/tests/postgres-rate-limiter.test.d.ts +0 -1
  301. package/rate-limit/tests/postgres-rate-limiter.test.js +0 -84
  302. package/renderer/tests/renderer.test.d.ts +0 -1
  303. package/renderer/tests/renderer.test.js +0 -88
  304. package/rpc/tests/rpc.integration.test.d.ts +0 -1
  305. package/rpc/tests/rpc.integration.test.js +0 -615
  306. package/signals/implementation/errors.d.ts +0 -2
  307. package/signals/implementation/graph.js +0 -312
  308. package/signals/implementation/writable-signal.d.ts +0 -48
  309. package/signals/implementation/writable-signal.js +0 -32
  310. package/task-queue/tests/coverage-branch.test.d.ts +0 -1
  311. package/task-queue/tests/coverage-branch.test.js +0 -395
  312. package/task-queue/tests/coverage-enhancement.test.d.ts +0 -1
  313. package/task-queue/tests/coverage-enhancement.test.js +0 -150
  314. package/task-queue/tests/dag.test.d.ts +0 -1
  315. package/task-queue/tests/dag.test.js +0 -188
  316. package/task-queue/tests/dependencies.test.d.ts +0 -1
  317. package/task-queue/tests/dependencies.test.js +0 -296
  318. package/task-queue/tests/enqueue-batch.test.d.ts +0 -1
  319. package/task-queue/tests/enqueue-batch.test.js +0 -125
  320. package/task-queue/tests/enqueue-item.test.d.ts +0 -1
  321. package/task-queue/tests/enqueue-item.test.js +0 -12
  322. package/task-queue/tests/fan-out-spawning.test.d.ts +0 -1
  323. package/task-queue/tests/fan-out-spawning.test.js +0 -94
  324. package/task-queue/tests/idempotent-replacement.test.d.ts +0 -1
  325. package/task-queue/tests/idempotent-replacement.test.js +0 -114
  326. package/task-queue/tests/missing-idempotent-tasks.test.d.ts +0 -1
  327. package/task-queue/tests/missing-idempotent-tasks.test.js +0 -39
  328. package/task-queue/tests/optimization-edge-cases.test.d.ts +0 -1
  329. package/task-queue/tests/optimization-edge-cases.test.js +0 -124
  330. package/task-queue/tests/queue-generic.test.d.ts +0 -1
  331. package/task-queue/tests/queue-generic.test.js +0 -8
  332. package/task-queue/tests/queue.test.d.ts +0 -1
  333. package/task-queue/tests/queue.test.js +0 -756
  334. package/task-queue/tests/shutdown.test.d.ts +0 -1
  335. package/task-queue/tests/shutdown.test.js +0 -41
  336. package/task-queue/tests/task-context.test.d.ts +0 -1
  337. package/task-queue/tests/task-context.test.js +0 -7
  338. package/task-queue/tests/task-union.test.d.ts +0 -1
  339. package/task-queue/tests/task-union.test.js +0 -18
  340. package/task-queue/tests/transactions.test.d.ts +0 -1
  341. package/task-queue/tests/transactions.test.js +0 -47
  342. package/task-queue/tests/typing.test.d.ts +0 -1
  343. package/task-queue/tests/typing.test.js +0 -9
  344. package/task-queue/tests/worker.test.d.ts +0 -1
  345. package/task-queue/tests/worker.test.js +0 -258
  346. package/task-queue/tests/zombie-parent.test.d.ts +0 -1
  347. package/task-queue/tests/zombie-parent.test.js +0 -45
  348. package/task-queue/tests/zombie-recovery.test.d.ts +0 -1
  349. package/task-queue/tests/zombie-recovery.test.js +0 -51
  350. package/utils/tests/backoff.test.d.ts +0 -1
  351. package/utils/tests/backoff.test.js +0 -41
  352. package/utils/tests/retry-with-backoff.test.d.ts +0 -1
  353. package/utils/tests/retry-with-backoff.test.js +0 -49
@@ -1,112 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { sql } from 'drizzle-orm';
11
- import { beforeAll, describe, expect, test } from 'vitest';
12
- import { Singleton } from '../../injector/decorators.js';
13
- import { StringProperty } from '../../schema/index.js';
14
- import { setupIntegrationTest } from '../../testing/index.js';
15
- import { ChildEntity, Column, Inheritance, Table } from '../decorators.js';
16
- import { Entity } from '../entity.js';
17
- import { getRepository } from '../server/repository.js';
18
- import { Transactional } from '../server/transactional.js';
19
- describe('ORM Repository CTI Transactions (Integration)', () => {
20
- let injector;
21
- let db;
22
- let service;
23
- const schema = 'test_orm_cti_transactions';
24
- let Parent = class Parent extends Entity {
25
- type;
26
- name;
27
- };
28
- __decorate([
29
- StringProperty(),
30
- Column({ name: 'type' }),
31
- __metadata("design:type", String)
32
- ], Parent.prototype, "type", void 0);
33
- __decorate([
34
- StringProperty(),
35
- __metadata("design:type", String)
36
- ], Parent.prototype, "name", void 0);
37
- Parent = __decorate([
38
- Table('parents', { schema }),
39
- Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
40
- ], Parent);
41
- let Child = class Child extends Parent {
42
- childData;
43
- };
44
- __decorate([
45
- StringProperty(),
46
- __metadata("design:type", String)
47
- ], Child.prototype, "childData", void 0);
48
- Child = __decorate([
49
- Table('children', { schema }),
50
- ChildEntity('child')
51
- ], Child);
52
- let TestService = class TestService extends Transactional {
53
- #childRepo = getRepository(Child);
54
- async createTwo(name1, name2, failSecond) {
55
- await this.transaction(async (tx) => {
56
- const repo = injector.resolve(this.#childRepo).withTransaction(tx);
57
- await repo.insert(Object.assign(new Child(), { name: name1, childData: 'data1' }));
58
- if (failSecond) {
59
- throw new Error('Planned failure');
60
- }
61
- await repo.insert(Object.assign(new Child(), { name: name2, childData: 'data2' }));
62
- });
63
- }
64
- };
65
- TestService = __decorate([
66
- Singleton()
67
- ], TestService);
68
- beforeAll(async () => {
69
- ({ injector, database: db } = await setupIntegrationTest({
70
- orm: { schema },
71
- }));
72
- service = injector.resolve(TestService);
73
- await db.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
74
- await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('children')} CASCADE`);
75
- await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('parents')} CASCADE`);
76
- await db.execute(sql `
77
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('parents')} (
78
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
79
- type TEXT NOT NULL,
80
- name TEXT NOT NULL,
81
- revision INTEGER NOT NULL,
82
- revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
83
- create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
84
- delete_timestamp TIMESTAMP WITH TIME ZONE,
85
- attributes JSONB NOT NULL DEFAULT '{}',
86
- UNIQUE (id, type)
87
- )
88
- `);
89
- await db.execute(sql `
90
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('children')} (
91
- id UUID PRIMARY KEY,
92
- type TEXT NOT NULL CHECK (type = 'child'),
93
- child_data TEXT NOT NULL,
94
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('parents')} (id, type) ON DELETE CASCADE
95
- )
96
- `);
97
- });
98
- test('should rollback inheritance inserts across multiple tables on service error', async () => {
99
- await expect(service.createTwo('ShouldRollback', 'Fails', true)).rejects.toThrow('Planned failure');
100
- const { rows: parentRows } = await db.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('parents')}`);
101
- const { rows: childRows } = await db.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('children')}`);
102
- expect(parentRows).toHaveLength(0);
103
- expect(childRows).toHaveLength(0);
104
- });
105
- test('should commit inheritance inserts across multiple tables on success', async () => {
106
- await service.createTwo('C1', 'C2', false);
107
- const { rows: parentRows } = await db.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('parents')}`);
108
- const { rows: childRows } = await db.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('children')}`);
109
- expect(parentRows).toHaveLength(2);
110
- expect(childRows).toHaveLength(2);
111
- });
112
- });
@@ -1,2 +0,0 @@
1
- /** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
2
- export {};
@@ -1,115 +0,0 @@
1
- /** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- import { sql } from 'drizzle-orm';
12
- import { beforeAll, describe, expect, test } from 'vitest';
13
- import { StringProperty } from '../../schema/index.js';
14
- import { setupIntegrationTest } from '../../testing/index.js';
15
- import { ChildEntity, Column, Inheritance, Table } from '../decorators.js';
16
- import { Entity } from '../entity.js';
17
- import { getRepository } from '../server/index.js';
18
- describe('ORM Repository CTI UpsertMany (Integration)', () => {
19
- let injector;
20
- let db;
21
- let itemRepo;
22
- let bookRepo;
23
- const schema = 'test_orm_cti_upsert_many';
24
- let Item = class Item extends Entity {
25
- type;
26
- title;
27
- };
28
- __decorate([
29
- StringProperty(),
30
- Column({ name: 'type' }),
31
- __metadata("design:type", String)
32
- ], Item.prototype, "type", void 0);
33
- __decorate([
34
- StringProperty(),
35
- __metadata("design:type", String)
36
- ], Item.prototype, "title", void 0);
37
- Item = __decorate([
38
- Table('items', { schema }),
39
- Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
40
- ], Item);
41
- let Book = class Book extends Item {
42
- author;
43
- };
44
- __decorate([
45
- StringProperty(),
46
- __metadata("design:type", String)
47
- ], Book.prototype, "author", void 0);
48
- Book = __decorate([
49
- Table('books', { schema }),
50
- ChildEntity('book')
51
- ], Book);
52
- beforeAll(async () => {
53
- ({ injector, database: db } = await setupIntegrationTest({
54
- orm: { schema },
55
- }));
56
- itemRepo = injector.resolve(getRepository(Item));
57
- bookRepo = injector.resolve(getRepository(Book));
58
- await db.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
59
- await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('books')} CASCADE`);
60
- await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('items')} CASCADE`);
61
- await db.execute(sql `
62
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('items')} (
63
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
64
- type TEXT NOT NULL,
65
- title TEXT NOT NULL,
66
- revision INTEGER NOT NULL,
67
- revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
68
- create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
69
- delete_timestamp TIMESTAMP WITH TIME ZONE,
70
- attributes JSONB NOT NULL DEFAULT '{}',
71
- UNIQUE (id, type)
72
- )
73
- `);
74
- await db.execute(sql `
75
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('books')} (
76
- id UUID PRIMARY KEY,
77
- type TEXT NOT NULL CHECK (type = 'book'),
78
- author TEXT NOT NULL,
79
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('items')} (id, type) ON DELETE CASCADE
80
- )
81
- `);
82
- });
83
- test('should upsertMany child entities (insert and update mixed)', async () => {
84
- // 1. Insert initial books
85
- const book1 = Object.assign(new Book(), { title: 'Book 1', author: 'Author 1' });
86
- const book2 = Object.assign(new Book(), { title: 'Book 2', author: 'Author 2' });
87
- const [inserted1, inserted2] = await bookRepo.insertMany([book1, book2]);
88
- // 2. Prepare upsert payload: update book1, new book3
89
- const update1 = Object.assign(new Book(), { id: inserted1.id, title: 'Book 1 Updated', author: 'Author 1 Updated' });
90
- const book3 = Object.assign(new Book(), { title: 'Book 3', author: 'Author 3' });
91
- const results = await bookRepo.upsertMany('id', [update1, book3]);
92
- expect(results).toHaveLength(2);
93
- const updated1 = results.find((b) => b.id === inserted1.id);
94
- const inserted3 = results.find((b) => b.title === 'Book 3');
95
- expect(updated1).toBeDefined();
96
- expect(updated1.title).toBe('Book 1 Updated');
97
- expect(updated1.author).toBe('Author 1 Updated');
98
- expect(inserted3).toBeDefined();
99
- expect(inserted3.id).toBeDefined();
100
- expect(inserted3.author).toBe('Author 3');
101
- // Verify book2 is untouched
102
- const loaded2 = await bookRepo.load(inserted2.id);
103
- expect(loaded2.title).toBe('Book 2');
104
- });
105
- test('should polymorphic tryLoadByQuery', async () => {
106
- await bookRepo.insert(Object.assign(new Book(), { title: 'Unique Book', author: 'Unique Author' }));
107
- // Load via Item repo using a book-specific property (should fail if not joined, but here we query by title)
108
- // Querying by book-specific property requires casting query or using raw sql if repository type doesn't have it.
109
- // But we can query by base property 'title'.
110
- const loaded = await itemRepo.tryLoadByQuery({ title: 'Unique Book' }, { includeSubclasses: true });
111
- expect(loaded).toBeDefined();
112
- expect(loaded).toBeInstanceOf(Book);
113
- expect(loaded.author).toBe('Unique Author');
114
- });
115
- });
@@ -1,2 +0,0 @@
1
- /** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
2
- export {};
@@ -1,390 +0,0 @@
1
- /** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- import { sql } from 'drizzle-orm';
12
- import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
13
- import { StringProperty } from '../../schema/index.js';
14
- import { dropTables, setupIntegrationTest, truncateTables } from '../../testing/index.js';
15
- import { ChildEntity, Column, Inheritance, Table } from '../decorators.js';
16
- import { Entity } from '../entity.js';
17
- import { getRepository } from '../server/index.js';
18
- describe('ORM Repository CTI (Integration)', () => {
19
- let injector;
20
- let database;
21
- let adminRepository;
22
- let guestRepository;
23
- let userRepository;
24
- let managerRepository;
25
- const schema = 'test_orm_cti';
26
- let BaseUser = class BaseUser extends Entity {
27
- type;
28
- name;
29
- };
30
- __decorate([
31
- StringProperty(),
32
- Column({ name: 'type' }),
33
- __metadata("design:type", String)
34
- ], BaseUser.prototype, "type", void 0);
35
- __decorate([
36
- StringProperty(),
37
- Column({ name: 'name' }),
38
- __metadata("design:type", String)
39
- ], BaseUser.prototype, "name", void 0);
40
- BaseUser = __decorate([
41
- Table('users', { schema }),
42
- Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
43
- ], BaseUser);
44
- let Admin = class Admin extends BaseUser {
45
- role;
46
- };
47
- __decorate([
48
- StringProperty(),
49
- Column({ name: 'role' }),
50
- __metadata("design:type", String)
51
- ], Admin.prototype, "role", void 0);
52
- Admin = __decorate([
53
- Table('admins', { schema }),
54
- ChildEntity('admin')
55
- ], Admin);
56
- let Guest = class Guest extends BaseUser {
57
- permissions;
58
- };
59
- __decorate([
60
- StringProperty(),
61
- Column({ name: 'permissions' }),
62
- __metadata("design:type", String)
63
- ], Guest.prototype, "permissions", void 0);
64
- Guest = __decorate([
65
- Table('guests', { schema }),
66
- ChildEntity('guest')
67
- ], Guest);
68
- let Staff = class Staff extends BaseUser {
69
- employeeId;
70
- };
71
- __decorate([
72
- StringProperty(),
73
- Column({ name: 'employee_id' }),
74
- __metadata("design:type", String)
75
- ], Staff.prototype, "employeeId", void 0);
76
- Staff = __decorate([
77
- Table('staff', { schema }),
78
- Inheritance({ strategy: 'joined' }),
79
- ChildEntity('staff')
80
- ], Staff);
81
- let Manager = class Manager extends Staff {
82
- department;
83
- };
84
- __decorate([
85
- StringProperty(),
86
- Column({ name: 'department' }),
87
- __metadata("design:type", String)
88
- ], Manager.prototype, "department", void 0);
89
- Manager = __decorate([
90
- Table('managers', { schema }),
91
- ChildEntity('manager')
92
- ], Manager);
93
- beforeAll(async () => {
94
- ({ injector, database } = await setupIntegrationTest({ orm: { schema } }));
95
- adminRepository = injector.resolve(getRepository(Admin));
96
- guestRepository = injector.resolve(getRepository(Guest));
97
- userRepository = injector.resolve(getRepository(BaseUser));
98
- managerRepository = injector.resolve(getRepository(Manager));
99
- await database.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
100
- await dropTables(database, schema, ['managers', 'staff', 'guests', 'admins', 'users']);
101
- await database.execute(sql `
102
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('users')} (
103
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
104
- type TEXT NOT NULL,
105
- name TEXT NOT NULL,
106
- revision INTEGER NOT NULL,
107
- revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
108
- create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
109
- delete_timestamp TIMESTAMP WITH TIME ZONE,
110
- attributes JSONB NOT NULL DEFAULT '{}',
111
- UNIQUE (id, type)
112
- )
113
- `);
114
- await database.execute(sql `
115
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('admins')} (
116
- id UUID PRIMARY KEY,
117
- type TEXT NOT NULL CHECK (type = 'admin'),
118
- role TEXT NOT NULL,
119
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('users')} (id, type) ON DELETE CASCADE
120
- )
121
- `);
122
- await database.execute(sql `
123
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('guests')} (
124
- id UUID PRIMARY KEY,
125
- type TEXT NOT NULL CHECK (type = 'guest'),
126
- permissions TEXT NOT NULL,
127
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('users')} (id, type) ON DELETE CASCADE
128
- )
129
- `);
130
- await database.execute(sql `
131
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('staff')} (
132
- id UUID PRIMARY KEY,
133
- type TEXT NOT NULL,
134
- employee_id TEXT NOT NULL,
135
- UNIQUE (id, type),
136
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('users')} (id, type) ON DELETE CASCADE
137
- )
138
- `);
139
- await database.execute(sql `
140
- CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('managers')} (
141
- id UUID PRIMARY KEY,
142
- type TEXT NOT NULL CHECK (type = 'manager'),
143
- department TEXT NOT NULL,
144
- FOREIGN KEY (id, type) REFERENCES ${sql.identifier(schema)}.${sql.identifier('staff')} (id, type) ON DELETE CASCADE
145
- )
146
- `);
147
- });
148
- beforeEach(async () => {
149
- await truncateTables(database, schema, ['users']);
150
- });
151
- test('should insert into both parent and child tables', async () => {
152
- const newAdmin = new Admin();
153
- newAdmin.name = 'Alice';
154
- newAdmin.role = 'SuperAdmin';
155
- const inserted = await adminRepository.insert(newAdmin);
156
- expect(inserted).toBeInstanceOf(Admin);
157
- expect(inserted.id).toBeDefined();
158
- expect(inserted.name).toBe('Alice');
159
- expect(inserted.role).toBe('SuperAdmin');
160
- expect(inserted.type).toBe('admin');
161
- expect(inserted.metadata.revision).toBe(1);
162
- // Verify DB state
163
- const { rows: [userRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
164
- expect(userRow).toBeDefined();
165
- expect(userRow['type']).toBe('admin');
166
- expect(userRow['name']).toBe('Alice');
167
- expect(userRow['revision']).toBe(1);
168
- const { rows: [adminRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('admins')} WHERE id = ${inserted.id}`);
169
- expect(adminRow).toBeDefined();
170
- expect(adminRow['type']).toBe('admin');
171
- expect(adminRow['role']).toBe('SuperAdmin');
172
- });
173
- test('should insert many into both parent and child tables', async () => {
174
- const admins = [
175
- Object.assign(new Admin(), { name: 'Bob', role: 'Admin' }),
176
- Object.assign(new Admin(), { name: 'Charlie', role: 'Moderator' }),
177
- ];
178
- const insertedAdmins = await adminRepository.insertMany(admins);
179
- expect(insertedAdmins).toHaveLength(2);
180
- expect(insertedAdmins[0].name).toBe('Bob');
181
- expect(insertedAdmins[1].name).toBe('Charlie');
182
- expect(insertedAdmins[0].type).toBe('admin');
183
- expect(insertedAdmins[1].type).toBe('admin');
184
- for (const inserted of insertedAdmins) {
185
- const { rows: [userRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
186
- expect(userRow['name']).toBe(inserted.name);
187
- const { rows: [adminRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('admins')} WHERE id = ${inserted.id}`);
188
- expect(adminRow['role']).toBe(inserted.role);
189
- }
190
- });
191
- test('should update both parent and child tables', async () => {
192
- const newAdmin = Object.assign(new Admin(), { name: 'Alice', role: 'SuperAdmin' });
193
- const inserted = await adminRepository.insert(newAdmin);
194
- const update = { name: 'Alice Updated', role: 'MegaAdmin' };
195
- const updated = await adminRepository.update(inserted.id, update);
196
- expect(updated.name).toBe('Alice Updated');
197
- expect(updated.role).toBe('MegaAdmin');
198
- expect(updated.metadata.revision).toBe(2);
199
- // Verify DB state
200
- const { rows: [userRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
201
- expect(userRow['name']).toBe('Alice Updated');
202
- expect(userRow['revision']).toBe(2);
203
- const { rows: [adminRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('admins')} WHERE id = ${inserted.id}`);
204
- expect(adminRow['role']).toBe('MegaAdmin');
205
- });
206
- test('should soft delete from parent table', async () => {
207
- const newAdmin = Object.assign(new Admin(), { name: 'Alice', role: 'SuperAdmin' });
208
- const inserted = await adminRepository.insert(newAdmin);
209
- await adminRepository.delete(inserted.id);
210
- // Verify DB state
211
- const { rows: [userRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
212
- expect(userRow['delete_timestamp']).not.toBeNull();
213
- // Child table should still have the row (soft delete only affects parent)
214
- const { rows: [adminRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('admins')} WHERE id = ${inserted.id}`);
215
- expect(adminRow).toBeDefined();
216
- });
217
- test('should hard delete from both tables via cascade', async () => {
218
- const newAdmin = Object.assign(new Admin(), { name: 'Alice', role: 'SuperAdmin' });
219
- const inserted = await adminRepository.insert(newAdmin);
220
- await adminRepository.hardDelete(inserted.id);
221
- // Verify DB state
222
- const { rows: userRows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
223
- expect(userRows).toHaveLength(0);
224
- const { rows: adminRows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('admins')} WHERE id = ${inserted.id}`);
225
- expect(adminRows).toHaveLength(0);
226
- });
227
- test('should load entities polymorphically from parent repository', async () => {
228
- await adminRepository.insert(Object.assign(new Admin(), { name: 'Admin1', role: 'Super' }));
229
- await guestRepository.insert(Object.assign(new Guest(), { name: 'Guest1', permissions: 'Read' }));
230
- // Load without subclasses (default)
231
- const users = await userRepository.loadAll();
232
- expect(users).toHaveLength(2);
233
- expect(users[0]).toBeInstanceOf(BaseUser);
234
- expect(users[1]).toBeInstanceOf(BaseUser);
235
- expect(users[0].role).toBeUndefined();
236
- // Load with subclasses
237
- const polymorphicUsers = await userRepository.loadAll({ includeSubclasses: true });
238
- expect(polymorphicUsers).toHaveLength(2);
239
- const admin = polymorphicUsers.find((u) => u instanceof Admin);
240
- const guest = polymorphicUsers.find((u) => u instanceof Guest);
241
- expect(admin).toBeDefined();
242
- expect(admin).toBeInstanceOf(Admin);
243
- expect(admin.name).toBe('Admin1');
244
- expect(admin.role).toBe('Super');
245
- expect(guest).toBeDefined();
246
- expect(guest).toBeInstanceOf(Guest);
247
- expect(guest.name).toBe('Guest1');
248
- expect(guest).toBeInstanceOf(Guest);
249
- expect(guest.name).toBe('Guest1');
250
- expect(guest.permissions).toBe('Read');
251
- });
252
- test('should load polymorphic subset from parent repository', async () => {
253
- await adminRepository.insert(Object.assign(new Admin(), { name: 'Admin1', role: 'Super' }));
254
- await guestRepository.insert(Object.assign(new Guest(), { name: 'Guest1', permissions: 'Read' }));
255
- // Load ONLY Admins polymorphically
256
- const onlyAdmins = await userRepository.loadManyByQuery({}, { includeSubclasses: [Admin] });
257
- expect(onlyAdmins).toHaveLength(2); // Still returns all users from base table
258
- const admin = onlyAdmins.find((u) => u instanceof Admin);
259
- const guestAsBase = onlyAdmins.find((u) => u.name === 'Guest1');
260
- expect(admin).toBeInstanceOf(Admin);
261
- expect(admin.role).toBe('Super');
262
- expect(guestAsBase).not.toBeInstanceOf(Guest);
263
- expect(guestAsBase).toBeInstanceOf(BaseUser);
264
- });
265
- test('should count and check existence for child entities', async () => {
266
- await adminRepository.insert(Object.assign(new Admin(), { name: 'Admin1', role: 'Super' }));
267
- await adminRepository.insert(Object.assign(new Admin(), { name: 'Admin2', role: 'Normal' }));
268
- await guestRepository.insert(Object.assign(new Guest(), { name: 'Guest1', permissions: 'Read' }));
269
- expect(await adminRepository.count()).toBe(2);
270
- expect(await guestRepository.count()).toBe(1);
271
- const admins = await adminRepository.loadAll();
272
- expect(await adminRepository.has(admins[0].id)).toBe(true);
273
- expect(await adminRepository.hasByQuery({ name: 'Admin2' })).toBe(true);
274
- expect(await adminRepository.hasByQuery({ name: 'Guest1' })).toBe(false); // Different table
275
- });
276
- test('should query child entities by parent fields', async () => {
277
- await adminRepository.insert(Object.assign(new Admin(), { name: 'TargetAdmin', role: 'Super' }));
278
- await adminRepository.insert(Object.assign(new Admin(), { name: 'OtherAdmin', role: 'Normal' }));
279
- const results = await adminRepository.loadManyByQuery({ name: 'TargetAdmin' });
280
- expect(results).toHaveLength(1);
281
- expect(results[0].name).toBe('TargetAdmin');
282
- expect(results[0].role).toBe('Super');
283
- });
284
- test('should perform partial updates on parent or child fields', async () => {
285
- const inserted = await adminRepository.insert(Object.assign(new Admin(), { name: 'Alice', role: 'Super' }));
286
- // Update only parent field
287
- await adminRepository.update(inserted.id, { name: 'Alice Renamed' });
288
- let updated = await adminRepository.load(inserted.id);
289
- expect(updated.name).toBe('Alice Renamed');
290
- expect(updated.role).toBe('Super');
291
- // Update only child field
292
- await adminRepository.update(inserted.id, { role: 'Demoted' });
293
- updated = await adminRepository.load(inserted.id);
294
- expect(updated.name).toBe('Alice Renamed');
295
- expect(updated.role).toBe('Demoted');
296
- });
297
- test('should fail when violating discriminator check constraint', async () => {
298
- // Attempt manual insert with mismatched type
299
- const query = database.execute(sql `
300
- INSERT INTO ${sql.identifier(schema)}.${sql.identifier('admins')} (id, type, role)
301
- VALUES (gen_random_uuid(), 'guest', 'Invalid')
302
- `);
303
- await expect(query).rejects.toThrow();
304
- });
305
- test('should fail when violating composite foreign key', async () => {
306
- // Insert user with type 'guest'
307
- const userId = '00000000-0000-0000-0000-000000000001';
308
- await database.execute(sql `
309
- INSERT INTO ${sql.identifier(schema)}.${sql.identifier('users')} (id, type, name, revision, revision_timestamp, create_timestamp)
310
- VALUES (${userId}, 'guest', 'Guest User', 1, now(), now())
311
- `);
312
- // Attempt to insert admin pointing to that user (mismatched type 'admin' vs 'guest')
313
- const query = database.execute(sql `
314
- INSERT INTO ${sql.identifier(schema)}.${sql.identifier('admins')} (id, type, role)
315
- VALUES (${userId}, 'admin', 'Admin Role')
316
- `);
317
- await expect(query).rejects.toThrow();
318
- });
319
- test('should support nested inheritance', async () => {
320
- const manager = new Manager();
321
- manager.name = 'Big Boss';
322
- manager.employeeId = 'EMP001';
323
- manager.department = 'Executive';
324
- const inserted = await managerRepository.insert(manager);
325
- expect(inserted.name).toBe('Big Boss');
326
- expect(inserted.employeeId).toBe('EMP001');
327
- expect(inserted.department).toBe('Executive');
328
- expect(inserted.type).toBe('manager');
329
- // Verify DB state - all 3 tables should have rows
330
- const { rows: [userRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
331
- expect(userRow['name']).toBe('Big Boss');
332
- const { rows: [staffRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('staff')} WHERE id = ${inserted.id}`);
333
- expect(staffRow['employee_id']).toBe('EMP001');
334
- const { rows: [managerRow] } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('managers')} WHERE id = ${inserted.id}`);
335
- expect(managerRow['department']).toBe('Executive');
336
- });
337
- test('should rollback parent insert if child insert fails', async () => {
338
- // Attempt to insert an admin with a missing role (should fail because of NOT NULL)
339
- const invalidAdmin = new Admin();
340
- invalidAdmin.name = 'Broken Admin';
341
- // role is missing
342
- await expect(adminRepository.insert(invalidAdmin)).rejects.toThrow();
343
- // Verify that NO row was created in the users table
344
- const { rows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')}`);
345
- expect(rows).toHaveLength(0);
346
- });
347
- test('should count and check existence polymorphically', async () => {
348
- await adminRepository.insert(Object.assign(new Admin(), { name: 'A1', role: 'R1' }));
349
- await guestRepository.insert(Object.assign(new Guest(), { name: 'G1', permissions: 'P1' }));
350
- expect(await userRepository.count()).toBe(2);
351
- expect(await userRepository.hasByQuery({ name: 'A1' })).toBe(true);
352
- expect(await userRepository.hasByQuery({ name: 'G1' })).toBe(true);
353
- });
354
- test('should load many by IDs polymorphically', async () => {
355
- const a1 = await adminRepository.insert(Object.assign(new Admin(), { name: 'A1', role: 'R1' }));
356
- const g1 = await guestRepository.insert(Object.assign(new Guest(), { name: 'G1', permissions: 'P1' }));
357
- const results = await userRepository.loadMany([a1.id, g1.id], { includeSubclasses: true });
358
- expect(results).toHaveLength(2);
359
- expect(results.find((u) => u.id === a1.id)).toBeInstanceOf(Admin);
360
- expect(results.find((u) => u.id === g1.id)).toBeInstanceOf(Guest);
361
- });
362
- test('should update many child entities', async () => {
363
- const a1 = await adminRepository.insert(Object.assign(new Admin(), { name: 'A1', role: 'Old' }));
364
- const a2 = await adminRepository.insert(Object.assign(new Admin(), { name: 'A2', role: 'Old' }));
365
- await adminRepository.updateMany([a1.id, a2.id], { role: 'New' });
366
- const results = await adminRepository.loadMany([a1.id, a2.id]);
367
- expect(results[0].role).toBe('New');
368
- expect(results[1].role).toBe('New');
369
- });
370
- test('should update nested inheritance fields', async () => {
371
- const manager = Object.assign(new Manager(), { name: 'Boss', employeeId: 'E1', department: 'D1' });
372
- const inserted = await managerRepository.insert(manager);
373
- await managerRepository.update(inserted.id, { name: 'New Boss', employeeId: 'E2', department: 'D2' });
374
- const updated = await managerRepository.load(inserted.id);
375
- expect(updated.name).toBe('New Boss');
376
- expect(updated.employeeId).toBe('E2');
377
- expect(updated.department).toBe('D2');
378
- });
379
- test('should delete from nested inheritance tables', async () => {
380
- const manager = Object.assign(new Manager(), { name: 'Boss', employeeId: 'E1', department: 'D1' });
381
- const inserted = await managerRepository.insert(manager);
382
- await managerRepository.hardDelete(inserted.id);
383
- const { rows: userRows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('users')} WHERE id = ${inserted.id}`);
384
- const { rows: staffRows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('staff')} WHERE id = ${inserted.id}`);
385
- const { rows: managerRows } = await database.execute(sql `SELECT * FROM ${sql.identifier(schema)}.${sql.identifier('managers')} WHERE id = ${inserted.id}`);
386
- expect(userRows).toHaveLength(0);
387
- expect(staffRows).toHaveLength(0);
388
- expect(managerRows).toHaveLength(0);
389
- });
390
- });
@@ -1 +0,0 @@
1
- export {};