@tstdl/base 0.93.87 → 0.93.90

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 (314) hide show
  1. package/ai/genkit/helpers.d.ts +3 -1
  2. package/ai/genkit/helpers.js +3 -3
  3. package/api/server/gateway.d.ts +3 -0
  4. package/api/server/gateway.js +15 -4
  5. package/api/server/middlewares/catch-error.middleware.js +2 -4
  6. package/api/server/middlewares/cors.middleware.js +2 -3
  7. package/api/server/middlewares/csrf.middleware.d.ts +41 -0
  8. package/api/server/middlewares/csrf.middleware.js +108 -0
  9. package/api/server/middlewares/index.d.ts +1 -0
  10. package/api/server/middlewares/index.js +1 -0
  11. package/api/server/module.d.ts +8 -2
  12. package/api/server/module.js +14 -8
  13. package/api/server/tests/csrf.middleware.test.js +91 -0
  14. package/audit/drizzle/{0000_bored_stick.sql → 0000_lumpy_thunderball.sql} +3 -3
  15. package/audit/drizzle/meta/0000_snapshot.json +4 -4
  16. package/audit/drizzle/meta/_journal.json +2 -9
  17. package/audit/module.d.ts +4 -1
  18. package/audit/module.js +3 -2
  19. package/audit/schemas.d.ts +1 -1
  20. package/audit/types.d.ts +1 -1
  21. package/audit/types.js +1 -1
  22. package/authentication/client/authentication.service.d.ts +14 -1
  23. package/authentication/client/authentication.service.js +82 -23
  24. package/authentication/client/http-client.middleware.d.ts +6 -0
  25. package/authentication/client/http-client.middleware.js +36 -0
  26. package/authentication/client/module.js +8 -2
  27. package/authentication/models/service-account.model.d.ts +2 -2
  28. package/authentication/models/service-account.model.js +10 -5
  29. package/authentication/models/subject.model.d.ts +20 -5
  30. package/authentication/models/subject.model.js +34 -29
  31. package/authentication/models/system-account.model.d.ts +3 -2
  32. package/authentication/models/system-account.model.js +11 -5
  33. package/authentication/models/user.model.d.ts +2 -11
  34. package/authentication/models/user.model.js +5 -16
  35. package/authentication/server/authentication-api-request-token.provider.d.ts +0 -2
  36. package/authentication/server/authentication-api-request-token.provider.js +3 -11
  37. package/authentication/server/authentication.api-controller.d.ts +1 -2
  38. package/authentication/server/authentication.api-controller.js +8 -9
  39. package/authentication/server/authentication.audit.d.ts +3 -2
  40. package/authentication/server/authentication.service.d.ts +27 -1
  41. package/authentication/server/authentication.service.js +67 -18
  42. package/authentication/server/drizzle/{0000_normal_paper_doll.sql → 0000_soft_tag.sql} +25 -32
  43. package/authentication/server/drizzle/meta/0000_snapshot.json +180 -205
  44. package/authentication/server/drizzle/meta/_journal.json +2 -2
  45. package/authentication/server/helper.js +9 -2
  46. package/authentication/server/module.d.ts +4 -1
  47. package/authentication/server/module.js +9 -5
  48. package/authentication/server/schemas.d.ts +2 -1
  49. package/authentication/server/schemas.js +2 -2
  50. package/authentication/server/subject.service.d.ts +17 -11
  51. package/authentication/server/subject.service.js +86 -84
  52. package/authentication/tests/authentication-ancillary.service.test.d.ts +1 -0
  53. package/authentication/tests/authentication-ancillary.service.test.js +13 -0
  54. package/authentication/tests/authentication-secret-requirements.validator.test.d.ts +1 -0
  55. package/authentication/tests/authentication-secret-requirements.validator.test.js +29 -0
  56. package/authentication/tests/authentication.api-controller.test.d.ts +1 -0
  57. package/authentication/tests/authentication.api-controller.test.js +88 -0
  58. package/authentication/tests/authentication.api-request-token.provider.test.d.ts +1 -0
  59. package/authentication/tests/authentication.api-request-token.provider.test.js +48 -0
  60. package/authentication/tests/authentication.client-middleware.test.d.ts +1 -0
  61. package/authentication/tests/authentication.client-middleware.test.js +23 -0
  62. package/authentication/tests/authentication.client-service.test.d.ts +1 -0
  63. package/authentication/tests/authentication.client-service.test.js +70 -0
  64. package/authentication/tests/authentication.service.test.d.ts +1 -0
  65. package/authentication/tests/authentication.service.test.js +186 -0
  66. package/authentication/tests/authentication.test-ancillary-service.d.ts +9 -0
  67. package/authentication/tests/authentication.test-ancillary-service.js +27 -0
  68. package/authentication/tests/helper.test.d.ts +1 -0
  69. package/authentication/tests/helper.test.js +107 -0
  70. package/authentication/tests/secret-requirements.error.test.d.ts +1 -0
  71. package/authentication/tests/secret-requirements.error.test.js +14 -0
  72. package/authentication/tests/subject.service.test.d.ts +1 -0
  73. package/authentication/tests/subject.service.test.js +140 -0
  74. package/circuit-breaker/postgres/drizzle/meta/0000_snapshot.json +1 -1
  75. package/circuit-breaker/postgres/drizzle/meta/_journal.json +2 -2
  76. package/circuit-breaker/postgres/module.d.ts +7 -1
  77. package/circuit-breaker/postgres/module.js +8 -6
  78. package/circuit-breaker/tests/circuit-breaker.test.js +2 -22
  79. package/document-management/api/document-management.api.js +2 -6
  80. package/document-management/server/services/document-validation.service.js +6 -5
  81. package/document-management/server/services/document-workflow.service.js +5 -5
  82. package/document-management/service-models/document-folders.view-model.d.ts +5 -2
  83. package/document-management/service-models/document-folders.view-model.js +42 -9
  84. package/document-management/service-models/enriched/enriched-document-management-data.view.js +1 -1
  85. package/examples/document-management/main.js +4 -4
  86. package/http/client/adapters/undici.adapter.d.ts +7 -5
  87. package/http/client/adapters/undici.adapter.js +13 -10
  88. package/http/client/module.d.ts +3 -1
  89. package/http/client/module.js +8 -9
  90. package/http/server/http-server.d.ts +2 -0
  91. package/http/server/node/module.d.ts +6 -2
  92. package/http/server/node/module.js +6 -4
  93. package/http/server/node/node-http-server.d.ts +2 -0
  94. package/http/server/node/node-http-server.js +7 -0
  95. package/http/types.d.ts +1 -1
  96. package/key-value-store/postgres/module.d.ts +7 -1
  97. package/key-value-store/postgres/module.js +7 -3
  98. package/lock/postgres/lock.js +0 -1
  99. package/lock/postgres/module.d.ts +7 -1
  100. package/lock/postgres/module.js +9 -5
  101. package/logger/formatter.d.ts +2 -0
  102. package/logger/formatters/json.js +2 -2
  103. package/logger/formatters/pretty-print.js +8 -10
  104. package/logger/logger.d.ts +1 -1
  105. package/logger/logger.js +15 -12
  106. package/message-bus/local/module.d.ts +5 -2
  107. package/message-bus/local/module.js +5 -4
  108. package/module/module.d.ts +2 -1
  109. package/module/module.js +3 -0
  110. package/module/modules/web-server.module.d.ts +11 -6
  111. package/module/modules/web-server.module.js +15 -10
  112. package/orm/decorators.d.ts +24 -1
  113. package/orm/decorators.js +40 -4
  114. package/orm/query/base.d.ts +17 -17
  115. package/orm/query/base.js +1 -1
  116. package/orm/repository.types.d.ts +45 -1
  117. package/orm/schemas/tsvector.js +1 -1
  118. package/orm/server/drizzle/schema-converter.d.ts +3 -1
  119. package/orm/server/drizzle/schema-converter.js +120 -14
  120. package/orm/server/index.d.ts +1 -0
  121. package/orm/server/index.js +1 -0
  122. package/orm/server/module.d.ts +4 -2
  123. package/orm/server/module.js +6 -5
  124. package/orm/server/query-converter.d.ts +6 -3
  125. package/orm/server/query-converter.js +32 -20
  126. package/orm/server/repository-config.d.ts +8 -0
  127. package/orm/server/repository-config.js +8 -0
  128. package/orm/server/repository.d.ts +117 -43
  129. package/orm/server/repository.js +757 -253
  130. package/orm/server/transaction.d.ts +4 -2
  131. package/orm/server/transaction.js +14 -5
  132. package/orm/server/transactional.d.ts +6 -2
  133. package/orm/server/transactional.js +39 -9
  134. package/orm/server/types.d.ts +2 -0
  135. package/orm/sqls/case-when.d.ts +3 -3
  136. package/orm/sqls/case-when.js +2 -2
  137. package/orm/sqls/sqls.d.ts +31 -5
  138. package/orm/sqls/sqls.js +69 -6
  139. package/orm/tests/data-types.test.d.ts +1 -0
  140. package/orm/tests/data-types.test.js +39 -0
  141. package/orm/tests/decorators.test.d.ts +1 -0
  142. package/orm/tests/decorators.test.js +77 -0
  143. package/orm/tests/encryption.test.d.ts +1 -0
  144. package/orm/tests/encryption.test.js +34 -0
  145. package/orm/tests/query-complex.test.d.ts +1 -0
  146. package/orm/tests/query-complex.test.js +203 -0
  147. package/orm/tests/query-converter-complex.test.d.ts +1 -0
  148. package/orm/tests/query-converter-complex.test.js +126 -0
  149. package/orm/tests/query-converter.test.d.ts +1 -0
  150. package/orm/tests/query-converter.test.js +123 -0
  151. package/orm/tests/repository-advanced.test.d.ts +1 -0
  152. package/orm/tests/repository-advanced.test.js +232 -0
  153. package/orm/tests/repository-attributes.test.d.ts +1 -0
  154. package/orm/tests/repository-attributes.test.js +99 -0
  155. package/orm/tests/repository-comprehensive.test.d.ts +1 -0
  156. package/orm/tests/repository-comprehensive.test.js +187 -0
  157. package/orm/tests/repository-coverage.test.d.ts +1 -0
  158. package/orm/tests/repository-coverage.test.js +303 -0
  159. package/orm/tests/repository-cti-complex.test.d.ts +1 -0
  160. package/orm/tests/repository-cti-complex.test.js +170 -0
  161. package/orm/tests/repository-cti-embedded.test.d.ts +1 -0
  162. package/orm/tests/repository-cti-embedded.test.js +188 -0
  163. package/orm/tests/repository-cti-extensive.test.d.ts +1 -0
  164. package/orm/tests/repository-cti-extensive.test.js +308 -0
  165. package/orm/tests/repository-cti-mapping.test.d.ts +1 -0
  166. package/orm/tests/repository-cti-mapping.test.js +121 -0
  167. package/orm/tests/repository-cti-search.test.d.ts +1 -0
  168. package/orm/tests/repository-cti-search.test.js +152 -0
  169. package/orm/tests/repository-cti-soft-delete.test.d.ts +1 -0
  170. package/orm/tests/repository-cti-soft-delete.test.js +115 -0
  171. package/orm/tests/repository-cti-transactions.test.d.ts +1 -0
  172. package/orm/tests/repository-cti-transactions.test.js +126 -0
  173. package/orm/tests/repository-cti-upsert-many.test.d.ts +1 -0
  174. package/orm/tests/repository-cti-upsert-many.test.js +127 -0
  175. package/orm/tests/repository-cti.test.d.ts +1 -0
  176. package/orm/tests/repository-cti.test.js +456 -0
  177. package/orm/tests/repository-edge-cases.test.d.ts +1 -0
  178. package/orm/tests/repository-edge-cases.test.js +216 -0
  179. package/orm/tests/repository-expiration.test.d.ts +1 -0
  180. package/orm/tests/repository-expiration.test.js +153 -0
  181. package/orm/tests/repository-extra-coverage.test.d.ts +1 -0
  182. package/orm/tests/repository-extra-coverage.test.js +546 -0
  183. package/orm/tests/repository-mapping.test.d.ts +1 -0
  184. package/orm/tests/repository-mapping.test.js +71 -0
  185. package/orm/tests/repository-regression.test.d.ts +1 -0
  186. package/orm/tests/repository-regression.test.js +330 -0
  187. package/orm/tests/repository-search-coverage.test.d.ts +1 -0
  188. package/orm/tests/repository-search-coverage.test.js +129 -0
  189. package/orm/tests/repository-search.test.d.ts +1 -0
  190. package/orm/tests/repository-search.test.js +116 -0
  191. package/orm/tests/repository-soft-delete.test.d.ts +1 -0
  192. package/orm/tests/repository-soft-delete.test.js +143 -0
  193. package/orm/tests/repository-transactions-nested.test.d.ts +1 -0
  194. package/orm/tests/repository-transactions-nested.test.js +202 -0
  195. package/orm/tests/repository-types.test.d.ts +1 -0
  196. package/orm/tests/repository-types.test.js +218 -0
  197. package/orm/tests/schema-converter.test.d.ts +1 -0
  198. package/orm/tests/schema-converter.test.js +81 -0
  199. package/orm/tests/schema-generation.test.d.ts +1 -0
  200. package/orm/tests/schema-generation.test.js +127 -0
  201. package/orm/tests/sql-helpers.test.d.ts +1 -0
  202. package/orm/tests/sql-helpers.test.js +67 -0
  203. package/orm/tests/transaction-safety.test.d.ts +1 -0
  204. package/orm/tests/transaction-safety.test.js +81 -0
  205. package/orm/tests/transactional.test.d.ts +1 -0
  206. package/orm/tests/transactional.test.js +224 -0
  207. package/orm/tests/utils.test.d.ts +1 -0
  208. package/orm/tests/utils.test.js +70 -0
  209. package/orm/utils.d.ts +7 -0
  210. package/orm/utils.js +26 -6
  211. package/package.json +12 -7
  212. package/pool/pool.js +1 -1
  213. package/rate-limit/index.d.ts +2 -0
  214. package/rate-limit/index.js +2 -0
  215. package/rate-limit/postgres/drizzle/0000_watery_rage.sql +7 -0
  216. package/{queue → rate-limit}/postgres/drizzle/meta/0000_snapshot.json +14 -39
  217. package/rate-limit/postgres/drizzle/meta/_journal.json +13 -0
  218. package/{queue → rate-limit}/postgres/drizzle.config.js +1 -1
  219. package/rate-limit/postgres/index.d.ts +4 -0
  220. package/rate-limit/postgres/index.js +4 -0
  221. package/rate-limit/postgres/module.d.ts +12 -0
  222. package/rate-limit/postgres/module.js +28 -0
  223. package/rate-limit/postgres/postgres-rate-limiter.d.ts +9 -0
  224. package/rate-limit/postgres/postgres-rate-limiter.js +56 -0
  225. package/rate-limit/postgres/rate-limit.model.d.ts +8 -0
  226. package/rate-limit/postgres/rate-limit.model.js +35 -0
  227. package/rate-limit/postgres/rate-limiter.provider.d.ts +6 -0
  228. package/rate-limit/postgres/rate-limiter.provider.js +21 -0
  229. package/rate-limit/postgres/schemas.d.ts +3 -0
  230. package/rate-limit/postgres/schemas.js +4 -0
  231. package/rate-limit/provider.d.ts +9 -0
  232. package/rate-limit/provider.js +2 -0
  233. package/rate-limit/rate-limiter.d.ts +35 -0
  234. package/rate-limit/rate-limiter.js +3 -0
  235. package/rate-limit/tests/postgres-rate-limiter.test.d.ts +1 -0
  236. package/rate-limit/tests/postgres-rate-limiter.test.js +92 -0
  237. package/signals/implementation/configure.d.ts +3 -0
  238. package/signals/implementation/configure.js +3 -0
  239. package/sse/data-stream-source.d.ts +1 -1
  240. package/sse/data-stream-source.js +6 -6
  241. package/task-queue/enqueue-batch.d.ts +17 -0
  242. package/task-queue/enqueue-batch.js +24 -0
  243. package/{queue → task-queue}/index.d.ts +1 -1
  244. package/{queue → task-queue}/index.js +1 -1
  245. package/task-queue/postgres/drizzle/0000_thin_black_panther.sql +74 -0
  246. package/task-queue/postgres/drizzle/meta/0000_snapshot.json +592 -0
  247. package/task-queue/postgres/drizzle/meta/_journal.json +13 -0
  248. package/task-queue/postgres/drizzle.config.d.ts +2 -0
  249. package/task-queue/postgres/drizzle.config.js +11 -0
  250. package/task-queue/postgres/index.d.ts +4 -0
  251. package/task-queue/postgres/index.js +4 -0
  252. package/task-queue/postgres/module.d.ts +12 -0
  253. package/task-queue/postgres/module.js +28 -0
  254. package/task-queue/postgres/schemas.d.ts +16 -0
  255. package/task-queue/postgres/schemas.js +8 -0
  256. package/task-queue/postgres/task-queue.d.ts +83 -0
  257. package/task-queue/postgres/task-queue.js +1054 -0
  258. package/task-queue/postgres/task-queue.provider.d.ts +7 -0
  259. package/{queue/postgres/queue.provider.js → task-queue/postgres/task-queue.provider.js} +8 -8
  260. package/task-queue/postgres/task.model.d.ts +39 -0
  261. package/task-queue/postgres/task.model.js +178 -0
  262. package/{queue → task-queue}/provider.d.ts +3 -3
  263. package/task-queue/provider.js +2 -0
  264. package/{queue → task-queue}/task-context.d.ts +7 -7
  265. package/{queue → task-queue}/task-context.js +8 -8
  266. package/{queue/queue.d.ts → task-queue/task-queue.d.ts} +128 -59
  267. package/task-queue/task-queue.js +200 -0
  268. package/task-queue/tests/complex.test.d.ts +1 -0
  269. package/task-queue/tests/complex.test.js +299 -0
  270. package/task-queue/tests/dependencies.test.d.ts +1 -0
  271. package/task-queue/tests/dependencies.test.js +174 -0
  272. package/task-queue/tests/queue.test.d.ts +1 -0
  273. package/task-queue/tests/queue.test.js +334 -0
  274. package/task-queue/tests/worker.test.d.ts +1 -0
  275. package/task-queue/tests/worker.test.js +163 -0
  276. package/test1.js +1 -1
  277. package/test4.js +2 -2
  278. package/unit-test/index.d.ts +1 -0
  279. package/unit-test/index.js +1 -0
  280. package/unit-test/integration-setup.d.ts +55 -0
  281. package/unit-test/integration-setup.js +182 -0
  282. package/utils/patterns.d.ts +3 -0
  283. package/utils/patterns.js +6 -1
  284. package/audit/drizzle/0001_previous_network.sql +0 -2
  285. package/audit/drizzle/meta/0001_snapshot.json +0 -195
  286. package/queue/enqueue-batch.d.ts +0 -17
  287. package/queue/enqueue-batch.js +0 -18
  288. package/queue/postgres/drizzle/0000_zippy_moondragon.sql +0 -11
  289. package/queue/postgres/drizzle/0001_certain_wild_pack.sql +0 -2
  290. package/queue/postgres/drizzle/0002_dear_meggan.sql +0 -2
  291. package/queue/postgres/drizzle/0003_tricky_venom.sql +0 -30
  292. package/queue/postgres/drizzle/meta/0001_snapshot.json +0 -103
  293. package/queue/postgres/drizzle/meta/0002_snapshot.json +0 -90
  294. package/queue/postgres/drizzle/meta/0003_snapshot.json +0 -288
  295. package/queue/postgres/drizzle/meta/_journal.json +0 -34
  296. package/queue/postgres/index.d.ts +0 -4
  297. package/queue/postgres/index.js +0 -4
  298. package/queue/postgres/module.d.ts +0 -9
  299. package/queue/postgres/module.js +0 -29
  300. package/queue/postgres/queue.d.ts +0 -60
  301. package/queue/postgres/queue.js +0 -681
  302. package/queue/postgres/queue.provider.d.ts +0 -7
  303. package/queue/postgres/schemas.d.ts +0 -14
  304. package/queue/postgres/schemas.js +0 -6
  305. package/queue/postgres/task.model.d.ts +0 -24
  306. package/queue/postgres/task.model.js +0 -115
  307. package/queue/provider.js +0 -2
  308. package/queue/queue.js +0 -131
  309. package/queue/tests/queue.test.js +0 -623
  310. package/test3.d.ts +0 -1
  311. package/test3.js +0 -47
  312. /package/{queue/tests/queue.test.d.ts → api/server/tests/csrf.middleware.test.d.ts} +0 -0
  313. /package/circuit-breaker/postgres/drizzle/{0000_hard_shocker.sql → 0000_cooing_korath.sql} +0 -0
  314. /package/{queue → rate-limit}/postgres/drizzle.config.d.ts +0 -0
@@ -0,0 +1,203 @@
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 { Injector, runInInjectionContext } from '../../injector/index.js';
13
+ import { Integer, StringProperty } from '../../schema/index.js';
14
+ import { Table } from '../decorators.js';
15
+ import { Entity } from '../entity.js';
16
+ import { configureOrm, Database } from '../server/index.js';
17
+ import { injectRepository } from '../server/repository.js';
18
+ describe('ORM Query Complex (Integration)', () => {
19
+ let injector;
20
+ let db;
21
+ const schema = 'test_orm_query_complex';
22
+ let QueryEntity = class QueryEntity extends Entity {
23
+ tag;
24
+ score;
25
+ status;
26
+ };
27
+ __decorate([
28
+ StringProperty(),
29
+ __metadata("design:type", String)
30
+ ], QueryEntity.prototype, "tag", void 0);
31
+ __decorate([
32
+ Integer(),
33
+ __metadata("design:type", Number)
34
+ ], QueryEntity.prototype, "score", void 0);
35
+ __decorate([
36
+ StringProperty(),
37
+ __metadata("design:type", String)
38
+ ], QueryEntity.prototype, "status", void 0);
39
+ QueryEntity = __decorate([
40
+ Table('query_entities', { schema })
41
+ ], QueryEntity);
42
+ beforeAll(async () => {
43
+ injector = new Injector('Test');
44
+ configureOrm({
45
+ repositoryConfig: { schema },
46
+ connection: {
47
+ host: '127.0.0.1', port: 5432, user: 'tstdl', password: 'wf7rq6glrk5jykne', database: 'tstdl',
48
+ },
49
+ });
50
+ db = injector.resolve(Database);
51
+ await db.execute(sql `CREATE SCHEMA IF NOT EXISTS ${sql.identifier(schema)}`);
52
+ await db.execute(sql `DROP TABLE IF EXISTS ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
53
+ await db.execute(sql `
54
+ CREATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} (
55
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
56
+ tag TEXT NOT NULL,
57
+ score INTEGER NOT NULL,
58
+ status TEXT NOT NULL,
59
+ revision INTEGER NOT NULL,
60
+ revision_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
61
+ create_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
62
+ delete_timestamp TIMESTAMP WITH TIME ZONE,
63
+ attributes JSONB NOT NULL DEFAULT '{}'
64
+ )
65
+ `);
66
+ });
67
+ test('should support nested AND/OR logic', async () => {
68
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
69
+ await runInInjectionContext(injector, async () => {
70
+ const repo = injectRepository(QueryEntity);
71
+ await repo.insertMany([
72
+ Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }),
73
+ Object.assign(new QueryEntity(), { tag: 'A', score: 20, status: 'inactive' }),
74
+ Object.assign(new QueryEntity(), { tag: 'B', score: 10, status: 'active' }),
75
+ Object.assign(new QueryEntity(), { tag: 'B', score: 20, status: 'inactive' }),
76
+ ]);
77
+ // (Tag A AND Active) OR (Tag B AND Inactive)
78
+ const results = await repo.loadManyByQuery({
79
+ $or: [
80
+ { $and: [{ tag: 'A' }, { status: 'active' }] },
81
+ { $and: [{ tag: 'B' }, { status: 'inactive' }] },
82
+ ],
83
+ });
84
+ expect(results).toHaveLength(2);
85
+ expect(results.some((r) => r.tag === 'A' && r.status === 'active')).toBe(true);
86
+ expect(results.some((r) => r.tag === 'B' && r.status === 'inactive')).toBe(true);
87
+ });
88
+ });
89
+ test('should support implicit AND', async () => {
90
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
91
+ await runInInjectionContext(injector, async () => {
92
+ const repo = injectRepository(QueryEntity);
93
+ await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
94
+ const results = await repo.loadManyByQuery({
95
+ tag: 'A',
96
+ score: 10,
97
+ status: 'active',
98
+ });
99
+ expect(results).toHaveLength(1);
100
+ });
101
+ });
102
+ test('should support NOT operator', async () => {
103
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
104
+ await runInInjectionContext(injector, async () => {
105
+ const repo = injectRepository(QueryEntity);
106
+ await repo.insertMany([
107
+ Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }),
108
+ Object.assign(new QueryEntity(), { tag: 'B', score: 20, status: 'inactive' }),
109
+ ]);
110
+ const results = await repo.loadManyByQuery({
111
+ tag: { $not: { $eq: 'A' } },
112
+ });
113
+ expect(results).toHaveLength(1);
114
+ expect(results[0].tag).toBe('B');
115
+ });
116
+ });
117
+ test('should support IN operator with empty array (should match nothing)', async () => {
118
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
119
+ await runInInjectionContext(injector, async () => {
120
+ const repo = injectRepository(QueryEntity);
121
+ await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
122
+ const results = await repo.loadManyByQuery({
123
+ tag: { $in: [] },
124
+ });
125
+ expect(results).toHaveLength(0);
126
+ });
127
+ });
128
+ test('should support NOT IN operator with empty array (should match everything)', async () => {
129
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
130
+ await runInInjectionContext(injector, async () => {
131
+ const repo = injectRepository(QueryEntity);
132
+ await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
133
+ const results = await repo.loadManyByQuery({
134
+ tag: { $nin: [] },
135
+ });
136
+ expect(results).toHaveLength(1);
137
+ });
138
+ });
139
+ test('should support REGEX operator', async () => {
140
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
141
+ await runInInjectionContext(injector, async () => {
142
+ const repo = injectRepository(QueryEntity);
143
+ await repo.insertMany([
144
+ Object.assign(new QueryEntity(), { tag: 'apple', score: 10, status: '' }),
145
+ Object.assign(new QueryEntity(), { tag: 'banana', score: 10, status: '' }),
146
+ Object.assign(new QueryEntity(), { tag: 'apricot', score: 10, status: '' }),
147
+ ]);
148
+ const results = await repo.loadManyByQuery({
149
+ tag: { $regex: '^ap' },
150
+ });
151
+ expect(results).toHaveLength(2); // apple, apricot
152
+ });
153
+ });
154
+ test('should support complex combination of logic and comparison', async () => {
155
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
156
+ await runInInjectionContext(injector, async () => {
157
+ const repo = injectRepository(QueryEntity);
158
+ await repo.insertMany([
159
+ Object.assign(new QueryEntity(), { tag: 'A', score: 5, status: 'ok' }),
160
+ Object.assign(new QueryEntity(), { tag: 'A', score: 15, status: 'ok' }),
161
+ Object.assign(new QueryEntity(), { tag: 'A', score: 25, status: 'fail' }),
162
+ Object.assign(new QueryEntity(), { tag: 'B', score: 5, status: 'ok' }),
163
+ ]);
164
+ // Tag A AND (Score > 10 AND Score < 20) AND Status != fail
165
+ const results = await repo.loadManyByQuery({
166
+ tag: 'A',
167
+ $and: [{ score: { $gt: 10 } }, { score: { $lt: 20 } }],
168
+ status: { $neq: 'fail' },
169
+ });
170
+ expect(results).toHaveLength(1);
171
+ expect(results[0].score).toBe(15);
172
+ });
173
+ });
174
+ test('should support NULL check', async () => {
175
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
176
+ await runInInjectionContext(injector, async () => {
177
+ const repo = injectRepository(QueryEntity);
178
+ // Manually insert null status (violates NOT NULL usually, but let's assume nullable if we could change schema,
179
+ // but Entity defines it as string. We can query for null even if no rows can be null (result 0) OR if we use a nullable column).
180
+ // 'attributes' is JSONB and can be queried.
181
+ // But query-converter maps properties.
182
+ // Let's use a non-existent value for $eq which is different from null.
183
+ // But checking $eq: null generates IS NULL.
184
+ // Since our columns are NOT NULL, it should return empty.
185
+ await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
186
+ const results = await repo.loadManyByQuery({
187
+ status: { $eq: null },
188
+ });
189
+ expect(results).toHaveLength(0);
190
+ });
191
+ });
192
+ test('should support NOT NULL check', async () => {
193
+ await db.execute(sql `TRUNCATE TABLE ${sql.identifier(schema)}.${sql.identifier('query_entities')} CASCADE`);
194
+ await runInInjectionContext(injector, async () => {
195
+ const repo = injectRepository(QueryEntity);
196
+ await repo.insert(Object.assign(new QueryEntity(), { tag: 'A', score: 10, status: 'active' }));
197
+ const results = await repo.loadManyByQuery({
198
+ status: { $neq: null },
199
+ });
200
+ expect(results).toHaveLength(1);
201
+ });
202
+ });
203
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,126 @@
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 { describe, expect, test } from 'vitest';
11
+ import { sql } from 'drizzle-orm';
12
+ import { PgDialect } from 'drizzle-orm/pg-core';
13
+ import { StringProperty, Integer } from '../../schema/index.js';
14
+ import { Entity } from '../entity.js';
15
+ import { Column, Table } from '../decorators.js';
16
+ import { getDrizzleTableFromType, getColumnDefinitionsMap } from '../server/drizzle/schema-converter.js';
17
+ import { convertQuery } from '../server/query-converter.js';
18
+ describe('ORM Query Converter Complex', () => {
19
+ const dialect = new PgDialect();
20
+ let ComplexItem = class ComplexItem extends Entity {
21
+ name;
22
+ description;
23
+ value;
24
+ };
25
+ __decorate([
26
+ StringProperty(),
27
+ __metadata("design:type", String)
28
+ ], ComplexItem.prototype, "name", void 0);
29
+ __decorate([
30
+ StringProperty(),
31
+ __metadata("design:type", String)
32
+ ], ComplexItem.prototype, "description", void 0);
33
+ __decorate([
34
+ Integer(),
35
+ __metadata("design:type", Number)
36
+ ], ComplexItem.prototype, "value", void 0);
37
+ ComplexItem = __decorate([
38
+ Table('complex_items', { schema: 'test' })
39
+ ], ComplexItem);
40
+ const table = getDrizzleTableFromType(ComplexItem);
41
+ const colMap = getColumnDefinitionsMap(table);
42
+ test('should handle $tsvector with explicit weights', () => {
43
+ const q = {
44
+ $tsvector: {
45
+ fields: [['name', 'A'], ['description', 'B']],
46
+ query: 'search term',
47
+ language: 'english',
48
+ parser: 'websearch',
49
+ },
50
+ };
51
+ const condition = convertQuery(q, table, colMap);
52
+ const sqlStr = dialect.sqlToQuery(condition).sql;
53
+ expect(sqlStr).toContain('setweight(to_tsvector($1, "test"."complex_items"."name"), \'A\')');
54
+ expect(sqlStr).toContain('setweight(to_tsvector($2, "test"."complex_items"."description"), \'B\')');
55
+ expect(sqlStr).toContain('websearch_to_tsquery($3, $4)');
56
+ });
57
+ test('should handle ParadeDB $parade match with tokenizer', () => {
58
+ const q = {
59
+ name: {
60
+ $parade: {
61
+ match: {
62
+ value: 'test',
63
+ tokenizer: { type: 'ngram', min_gram: 3, max_gram: 3 },
64
+ },
65
+ },
66
+ },
67
+ };
68
+ const condition = convertQuery(q, table, colMap);
69
+ const sqlStr = dialect.sqlToQuery(condition).sql;
70
+ // Tokenizer is supported via JSON object syntax
71
+ expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'match\', jsonb_build_object(\'value\', $1, \'tokenizer\', jsonb_build_object(\'type\', $2, \'min_gram\', $3, \'max_gram\', $4)))::pdb.query');
72
+ });
73
+ test('should handle ParadeDB $parade range', () => {
74
+ const q = {
75
+ value: {
76
+ $parade: {
77
+ range: {
78
+ lowerBound: { included: 10 },
79
+ upperBound: { excluded: 20 },
80
+ },
81
+ },
82
+ },
83
+ };
84
+ const condition = convertQuery(q, table, colMap);
85
+ const sqlStr = dialect.sqlToQuery(condition).sql;
86
+ // This should fall back to convertParadeComparisonQuery with recursive jsonb build
87
+ expect(sqlStr).toContain('"test"."complex_items"."value" @@@ jsonb_build_object(\'range\', jsonb_build_object(\'lower_bound\', jsonb_build_object(\'included\', $1), \'upper_bound\', jsonb_build_object(\'excluded\', $2)))::pdb.query');
88
+ });
89
+ test('should handle ParadeDB $parade phrasePrefix', () => {
90
+ const q = {
91
+ name: {
92
+ $parade: {
93
+ phrasePrefix: { phrases: ['hello', 'wor'], maxExpansions: 10 },
94
+ },
95
+ },
96
+ };
97
+ const condition = convertQuery(q, table, colMap);
98
+ const sqlStr = dialect.sqlToQuery(condition).sql;
99
+ expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'phrase_prefix\', jsonb_build_object(\'phrases\', jsonb_build_array($1, $2), \'max_expansions\', $3))::pdb.query');
100
+ });
101
+ test('should handle ParadeDB $parade regexPhrase', () => {
102
+ const q = {
103
+ name: {
104
+ $parade: {
105
+ regexPhrase: { regexes: ['he.*', 'wo.*'], slop: 1 },
106
+ },
107
+ },
108
+ };
109
+ const condition = convertQuery(q, table, colMap);
110
+ const sqlStr = dialect.sqlToQuery(condition).sql;
111
+ expect(sqlStr).toContain('"test"."complex_items"."name" @@@ jsonb_build_object(\'regex_phrase\', jsonb_build_object(\'regexes\', jsonb_build_array($1, $2), \'slop\', $3))::pdb.query');
112
+ });
113
+ test('should handle ParadeDB top-level moreLikeThis', () => {
114
+ const q = {
115
+ $parade: {
116
+ moreLikeThis: {
117
+ keyValue: '123',
118
+ fields: ['name', 'description'],
119
+ },
120
+ },
121
+ };
122
+ const condition = convertQuery(q, table, colMap);
123
+ const sqlStr = dialect.sqlToQuery(condition).sql;
124
+ expect(sqlStr).toContain('"test"."complex_items"."id" @@@ jsonb_build_object(\'more_like_this\', jsonb_build_object(\'key_value\', $1, \'fields\', ARRAY[$2, $3]))::pdb.query');
125
+ });
126
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,123 @@
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 { describe, expect, test } from 'vitest';
11
+ import { eq, sql } from 'drizzle-orm';
12
+ import { getTableConfig, PgDialect } from 'drizzle-orm/pg-core';
13
+ import { StringProperty } from '../../schema/index.js';
14
+ import { Entity } from '../entity.js';
15
+ import { Column, Inheritance, ChildEntity, Table } from '../decorators.js';
16
+ import { getDrizzleTableFromType, getColumnDefinitionsMap } from '../server/drizzle/schema-converter.js';
17
+ import { convertQuery } from '../server/query-converter.js';
18
+ describe('ORM Query Converter (CTI)', () => {
19
+ test('should resolve columns to correct table in joined query', () => {
20
+ let BaseUser = class BaseUser extends Entity {
21
+ type;
22
+ name;
23
+ };
24
+ __decorate([
25
+ StringProperty(),
26
+ Column({ name: 'type' }),
27
+ __metadata("design:type", String)
28
+ ], BaseUser.prototype, "type", void 0);
29
+ __decorate([
30
+ StringProperty(),
31
+ Column({ name: 'name' }),
32
+ __metadata("design:type", String)
33
+ ], BaseUser.prototype, "name", void 0);
34
+ BaseUser = __decorate([
35
+ Table('users', { schema: 'test' }),
36
+ Inheritance({ strategy: 'joined', discriminatorColumn: 'type' })
37
+ ], BaseUser);
38
+ let Admin = class Admin extends BaseUser {
39
+ role;
40
+ };
41
+ __decorate([
42
+ StringProperty(),
43
+ Column({ name: 'role' }),
44
+ __metadata("design:type", String)
45
+ ], Admin.prototype, "role", void 0);
46
+ Admin = __decorate([
47
+ Table('admins', { schema: 'test' }),
48
+ ChildEntity('admin')
49
+ ], Admin);
50
+ const parentTable = getDrizzleTableFromType(BaseUser);
51
+ const childTable = getDrizzleTableFromType(Admin);
52
+ const columnDefinitionsMap = getColumnDefinitionsMap(childTable);
53
+ const dialect = new PgDialect();
54
+ // Query on child property
55
+ const query1 = { role: 'super' };
56
+ const sql1 = convertQuery(query1, childTable, columnDefinitionsMap);
57
+ const sqlString1 = dialect.sqlToQuery(sql1).sql;
58
+ expect(sqlString1).toContain('"admins"."role" = $1');
59
+ // Query on parent property
60
+ const query2 = { name: 'admin' };
61
+ const sql2 = convertQuery(query2, childTable, columnDefinitionsMap);
62
+ const sqlString2 = dialect.sqlToQuery(sql2).sql;
63
+ expect(sqlString2).toContain('"users"."name" = $1');
64
+ expect(sqlString2).not.toContain('"admins"."name"');
65
+ });
66
+ test('should handle $regex with flags', () => {
67
+ let Item = class Item extends Entity {
68
+ name;
69
+ };
70
+ __decorate([
71
+ StringProperty(),
72
+ __metadata("design:type", String)
73
+ ], Item.prototype, "name", void 0);
74
+ Item = __decorate([
75
+ Table('items', { schema: 'test' })
76
+ ], Item);
77
+ const table = getDrizzleTableFromType(Item);
78
+ const colMap = getColumnDefinitionsMap(table);
79
+ const dialect = new PgDialect();
80
+ const q = convertQuery({ name: { $regex: { pattern: '^test', flags: 'i' } } }, table, colMap);
81
+ const sqlStr = dialect.sqlToQuery(q).sql;
82
+ expect(sqlStr).toContain('"items"."name" ~* $1');
83
+ });
84
+ test('should handle $nin (not in)', () => {
85
+ let Item = class Item extends Entity {
86
+ name;
87
+ };
88
+ __decorate([
89
+ StringProperty(),
90
+ __metadata("design:type", String)
91
+ ], Item.prototype, "name", void 0);
92
+ Item = __decorate([
93
+ Table('items', { schema: 'test' })
94
+ ], Item);
95
+ const table = getDrizzleTableFromType(Item);
96
+ const colMap = getColumnDefinitionsMap(table);
97
+ const dialect = new PgDialect();
98
+ const q = convertQuery({ name: { $nin: ['a', 'b'] } }, table, colMap);
99
+ const sqlStr = dialect.sqlToQuery(q).sql;
100
+ expect(sqlStr.toLowerCase()).toContain('"items"."name" not in ($1, $2)');
101
+ });
102
+ test('should handle logical $nor', () => {
103
+ let Item = class Item extends Entity {
104
+ name;
105
+ };
106
+ __decorate([
107
+ StringProperty(),
108
+ __metadata("design:type", String)
109
+ ], Item.prototype, "name", void 0);
110
+ Item = __decorate([
111
+ Table('items', { schema: 'test' })
112
+ ], Item);
113
+ const table = getDrizzleTableFromType(Item);
114
+ const colMap = getColumnDefinitionsMap(table);
115
+ const dialect = new PgDialect();
116
+ const q = convertQuery({ $nor: [{ name: 'a' }, { name: 'b' }] }, table, colMap);
117
+ const sqlStr = dialect.sqlToQuery(q).sql.toLowerCase();
118
+ expect(sqlStr).toContain('not');
119
+ expect(sqlStr).toContain('"items"."name" = $1');
120
+ expect(sqlStr).toContain('"items"."name" = $2');
121
+ expect(sqlStr).toContain('or');
122
+ });
123
+ });
@@ -0,0 +1 @@
1
+ export {};