equipped 5.2.8 → 5.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (779) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +362 -34
  3. package/dist/cjs/cache/adapters/in-memory/index.cjs +824 -0
  4. package/dist/cjs/cache/adapters/in-memory/index.cjs.map +1 -0
  5. package/dist/cjs/cache/adapters/in-memory/index.min.cjs +4 -0
  6. package/dist/cjs/cache/adapters/in-memory/index.min.cjs.map +1 -0
  7. package/dist/cjs/cache/adapters/redis/index.cjs +844 -0
  8. package/dist/cjs/cache/adapters/redis/index.cjs.map +1 -0
  9. package/dist/cjs/cache/adapters/redis/index.min.cjs +4 -0
  10. package/dist/cjs/cache/adapters/redis/index.min.cjs.map +1 -0
  11. package/dist/cjs/cache/index.cjs +602 -4
  12. package/dist/cjs/cache/index.cjs.map +1 -1
  13. package/dist/cjs/cache/index.min.cjs +3 -1
  14. package/dist/cjs/cache/index.min.cjs.map +1 -1
  15. package/dist/cjs/dbs/adapters/mongodb/index.cjs +1314 -0
  16. package/dist/cjs/dbs/adapters/mongodb/index.cjs.map +1 -0
  17. package/dist/cjs/dbs/adapters/mongodb/index.min.cjs +4 -0
  18. package/dist/cjs/dbs/adapters/mongodb/index.min.cjs.map +1 -0
  19. package/dist/cjs/dbs/index.cjs +965 -6
  20. package/dist/cjs/dbs/index.cjs.map +1 -1
  21. package/dist/cjs/dbs/index.min.cjs +3 -1
  22. package/dist/cjs/dbs/index.min.cjs.map +1 -1
  23. package/dist/cjs/errors/index.cjs +127 -8
  24. package/dist/cjs/errors/index.cjs.map +1 -1
  25. package/dist/cjs/errors/index.min.cjs +1 -1
  26. package/dist/cjs/errors/index.min.cjs.map +1 -1
  27. package/dist/cjs/events/adapters/kafka/index.cjs +845 -0
  28. package/dist/cjs/events/adapters/kafka/index.cjs.map +1 -0
  29. package/dist/cjs/events/adapters/kafka/index.min.cjs +4 -0
  30. package/dist/cjs/events/adapters/kafka/index.min.cjs.map +1 -0
  31. package/dist/cjs/events/adapters/rabbitmq/index.cjs +836 -0
  32. package/dist/cjs/events/adapters/rabbitmq/index.cjs.map +1 -0
  33. package/dist/cjs/events/adapters/rabbitmq/index.min.cjs +4 -0
  34. package/dist/cjs/events/adapters/rabbitmq/index.min.cjs.map +1 -0
  35. package/dist/cjs/events/index.cjs +33 -4
  36. package/dist/cjs/events/index.cjs.map +1 -1
  37. package/dist/cjs/events/index.min.cjs +1 -1
  38. package/dist/cjs/events/index.min.cjs.map +1 -1
  39. package/dist/cjs/index.cjs +588 -1
  40. package/dist/cjs/index.cjs.map +1 -1
  41. package/dist/cjs/index.min.cjs +3 -1
  42. package/dist/cjs/index.min.cjs.map +1 -1
  43. package/dist/cjs/instance/index.cjs +514 -64
  44. package/dist/cjs/instance/index.cjs.map +1 -1
  45. package/dist/cjs/instance/index.min.cjs +3 -3
  46. package/dist/cjs/instance/index.min.cjs.map +1 -1
  47. package/dist/cjs/jobs/adapters/redis/index.cjs +979 -0
  48. package/dist/cjs/jobs/adapters/redis/index.cjs.map +1 -0
  49. package/dist/cjs/jobs/adapters/redis/index.min.cjs +4 -0
  50. package/dist/cjs/jobs/adapters/redis/index.min.cjs.map +1 -0
  51. package/dist/cjs/jobs/index.cjs +55 -2
  52. package/dist/cjs/jobs/index.cjs.map +1 -1
  53. package/dist/cjs/jobs/index.min.cjs +1 -1
  54. package/dist/cjs/jobs/index.min.cjs.map +1 -1
  55. package/dist/cjs/orm/adapters/in-memory/index.cjs +2551 -0
  56. package/dist/cjs/orm/adapters/in-memory/index.cjs.map +1 -0
  57. package/dist/cjs/orm/adapters/in-memory/index.min.cjs +4 -0
  58. package/dist/cjs/orm/adapters/in-memory/index.min.cjs.map +1 -0
  59. package/dist/cjs/orm/adapters/json/index.cjs +3518 -0
  60. package/dist/cjs/orm/adapters/json/index.cjs.map +1 -0
  61. package/dist/cjs/orm/adapters/json/index.min.cjs +4 -0
  62. package/dist/cjs/orm/adapters/json/index.min.cjs.map +1 -0
  63. package/dist/cjs/orm/adapters/mongodb/index.cjs +3299 -0
  64. package/dist/cjs/orm/adapters/mongodb/index.cjs.map +1 -0
  65. package/dist/cjs/orm/adapters/mongodb/index.min.cjs +4 -0
  66. package/dist/cjs/orm/adapters/mongodb/index.min.cjs.map +1 -0
  67. package/dist/cjs/orm/adapters/postgresql/index.cjs +4114 -0
  68. package/dist/cjs/orm/adapters/postgresql/index.cjs.map +1 -0
  69. package/dist/cjs/orm/adapters/postgresql/index.min.cjs +49 -0
  70. package/dist/cjs/orm/adapters/postgresql/index.min.cjs.map +1 -0
  71. package/dist/cjs/orm/index.cjs +9216 -0
  72. package/dist/cjs/orm/index.cjs.map +1 -0
  73. package/dist/cjs/orm/index.min.cjs +4 -0
  74. package/dist/cjs/orm/index.min.cjs.map +1 -0
  75. package/dist/cjs/server/adapters/express/index.cjs +1705 -0
  76. package/dist/cjs/server/adapters/express/index.cjs.map +1 -0
  77. package/dist/cjs/server/adapters/express/index.min.cjs +32 -0
  78. package/dist/cjs/server/adapters/express/index.min.cjs.map +1 -0
  79. package/dist/cjs/server/adapters/fastify/index.cjs +1709 -0
  80. package/dist/cjs/server/adapters/fastify/index.cjs.map +1 -0
  81. package/dist/cjs/server/adapters/fastify/index.min.cjs +32 -0
  82. package/dist/cjs/server/adapters/fastify/index.min.cjs.map +1 -0
  83. package/dist/cjs/server/index.cjs +1600 -9
  84. package/dist/cjs/server/index.cjs.map +1 -1
  85. package/dist/cjs/server/index.min.cjs +31 -1
  86. package/dist/cjs/server/index.min.cjs.map +1 -1
  87. package/dist/cjs/types/index.cjs +18 -1
  88. package/dist/cjs/types/index.cjs.map +1 -1
  89. package/dist/cjs/types/index.min.cjs +1 -1
  90. package/dist/cjs/types/index.min.cjs.map +1 -1
  91. package/dist/cjs/utilities/index.cjs +862 -7
  92. package/dist/cjs/utilities/index.cjs.map +1 -1
  93. package/dist/cjs/utilities/index.min.cjs +3 -1
  94. package/dist/cjs/utilities/index.min.cjs.map +1 -1
  95. package/dist/cjs/validations/index.cjs +679 -10
  96. package/dist/cjs/validations/index.cjs.map +1 -1
  97. package/dist/cjs/validations/index.min.cjs +3 -1
  98. package/dist/cjs/validations/index.min.cjs.map +1 -1
  99. package/dist/esm/cache/adapters/in-memory/index.min.mjs +2 -0
  100. package/dist/esm/cache/adapters/in-memory/index.min.mjs.map +1 -0
  101. package/dist/esm/cache/adapters/in-memory/index.mjs +93 -0
  102. package/dist/esm/cache/adapters/in-memory/index.mjs.map +1 -0
  103. package/dist/esm/cache/adapters/redis/index.min.mjs +2 -0
  104. package/dist/esm/cache/adapters/redis/index.mjs +13 -0
  105. package/dist/esm/cache/index.min.mjs +1 -1
  106. package/dist/esm/cache/index.min.mjs.map +1 -1
  107. package/dist/esm/cache/index.mjs +9 -4
  108. package/dist/esm/cache/index.mjs.map +1 -1
  109. package/dist/esm/chunk-2TCFNKRZ.mjs +1824 -0
  110. package/dist/esm/chunk-2TCFNKRZ.mjs.map +1 -0
  111. package/dist/esm/chunk-6DW4GW3R.min.mjs +2 -0
  112. package/dist/esm/chunk-6DW4GW3R.min.mjs.map +1 -0
  113. package/dist/esm/chunk-6SB5M4XH.mjs +795 -0
  114. package/dist/esm/chunk-6SB5M4XH.mjs.map +1 -0
  115. package/dist/esm/chunk-AQY7QVYI.min.mjs +2 -0
  116. package/dist/esm/chunk-AUKXL4EA.min.mjs +2 -0
  117. package/dist/esm/chunk-AUKXL4EA.min.mjs.map +1 -0
  118. package/dist/esm/chunk-BJNIUCPT.min.mjs +2 -0
  119. package/dist/esm/chunk-BJNIUCPT.min.mjs.map +1 -0
  120. package/dist/esm/chunk-DKPZJIIR.mjs +29 -0
  121. package/dist/esm/chunk-DKPZJIIR.mjs.map +1 -0
  122. package/dist/esm/chunk-DSUJ5FUL.min.mjs +2 -0
  123. package/dist/esm/chunk-DSUJ5FUL.min.mjs.map +1 -0
  124. package/dist/esm/chunk-ECBJ3NT3.min.mjs +2 -0
  125. package/dist/esm/chunk-ECBJ3NT3.min.mjs.map +1 -0
  126. package/dist/{types/events/types/kafka.js → esm/chunk-I4BB436E.mjs} +60 -37
  127. package/dist/esm/chunk-I4BB436E.mjs.map +1 -0
  128. package/dist/esm/chunk-IEBC3OWN.mjs +22 -0
  129. package/dist/esm/chunk-IEBC3OWN.mjs.map +1 -0
  130. package/dist/esm/chunk-J5LGTIGS.mjs +10 -0
  131. package/dist/esm/chunk-KW3PBDFD.mjs +53 -0
  132. package/dist/esm/chunk-KW3PBDFD.mjs.map +1 -0
  133. package/dist/esm/chunk-LTDVZJYJ.min.mjs +32 -0
  134. package/dist/esm/chunk-LTDVZJYJ.min.mjs.map +1 -0
  135. package/dist/esm/chunk-MYGAF2AC.min.mjs +2 -0
  136. package/dist/esm/chunk-MYGAF2AC.min.mjs.map +1 -0
  137. package/dist/esm/chunk-OXI6IKAM.min.mjs +2 -0
  138. package/dist/esm/chunk-OXI6IKAM.min.mjs.map +1 -0
  139. package/dist/esm/chunk-RIRBNBTC.mjs +113 -0
  140. package/dist/esm/chunk-RIRBNBTC.mjs.map +1 -0
  141. package/dist/esm/chunk-TWKHVLLT.mjs +1280 -0
  142. package/dist/esm/chunk-TWKHVLLT.mjs.map +1 -0
  143. package/dist/esm/chunk-VCCS7CAI.mjs +8 -0
  144. package/dist/esm/chunk-VCCS7CAI.mjs.map +1 -0
  145. package/dist/esm/chunk-WHIWTP2Z.min.mjs +2 -0
  146. package/dist/esm/chunk-WHIWTP2Z.min.mjs.map +1 -0
  147. package/dist/esm/chunk-YTHRK2PO.mjs +126 -0
  148. package/dist/esm/chunk-YTHRK2PO.mjs.map +1 -0
  149. package/dist/esm/chunk-YTM6ZURZ.min.mjs +2 -0
  150. package/dist/esm/chunk-YTM6ZURZ.min.mjs.map +1 -0
  151. package/dist/esm/dbs/adapters/mongodb/index.min.mjs +2 -0
  152. package/dist/esm/dbs/adapters/mongodb/index.min.mjs.map +1 -0
  153. package/dist/esm/dbs/adapters/mongodb/index.mjs +419 -0
  154. package/dist/esm/dbs/adapters/mongodb/index.mjs.map +1 -0
  155. package/dist/esm/dbs/index.min.mjs +1 -1
  156. package/dist/esm/dbs/index.min.mjs.map +1 -1
  157. package/dist/esm/dbs/index.mjs +22 -6
  158. package/dist/esm/dbs/index.mjs.map +1 -1
  159. package/dist/esm/errors/index.min.mjs +1 -1
  160. package/dist/esm/errors/index.min.mjs.map +1 -1
  161. package/dist/esm/errors/index.mjs +22 -8
  162. package/dist/esm/errors/index.mjs.map +1 -1
  163. package/dist/esm/events/adapters/kafka/index.min.mjs +2 -0
  164. package/dist/esm/events/adapters/kafka/index.min.mjs.map +1 -0
  165. package/dist/esm/events/adapters/kafka/index.mjs +12 -0
  166. package/dist/esm/events/adapters/kafka/index.mjs.map +1 -0
  167. package/dist/esm/events/adapters/rabbitmq/index.min.mjs +2 -0
  168. package/dist/esm/events/adapters/rabbitmq/index.min.mjs.map +1 -0
  169. package/dist/esm/events/adapters/rabbitmq/index.mjs +92 -0
  170. package/dist/esm/events/adapters/rabbitmq/index.mjs.map +1 -0
  171. package/dist/esm/events/index.min.mjs +1 -1
  172. package/dist/esm/events/index.min.mjs.map +1 -1
  173. package/dist/esm/events/index.mjs +7 -4
  174. package/dist/esm/events/index.mjs.map +1 -1
  175. package/dist/esm/index.min.mjs +1 -1
  176. package/dist/esm/index.min.mjs.map +1 -1
  177. package/dist/esm/index.mjs +8 -1
  178. package/dist/esm/index.mjs.map +1 -1
  179. package/dist/esm/instance/index.min.mjs +1 -3
  180. package/dist/esm/instance/index.min.mjs.map +1 -1
  181. package/dist/esm/instance/index.mjs +4 -132
  182. package/dist/esm/instance/index.mjs.map +1 -1
  183. package/dist/esm/introspection-GP3G26B6.min.mjs +2 -0
  184. package/dist/esm/introspection-GP3G26B6.min.mjs.map +1 -0
  185. package/dist/esm/introspection-Y7EXSYPD.mjs +10 -0
  186. package/dist/esm/introspection-Y7EXSYPD.mjs.map +1 -0
  187. package/dist/esm/jobs/adapters/redis/index.min.mjs +2 -0
  188. package/dist/esm/jobs/adapters/redis/index.min.mjs.map +1 -0
  189. package/dist/esm/jobs/{types/redis.mjs → adapters/redis/index.mjs} +71 -56
  190. package/dist/esm/jobs/adapters/redis/index.mjs.map +1 -0
  191. package/dist/esm/jobs/index.min.mjs +1 -1
  192. package/dist/esm/jobs/index.min.mjs.map +1 -1
  193. package/dist/esm/jobs/index.mjs +9 -2
  194. package/dist/esm/jobs/index.mjs.map +1 -1
  195. package/dist/esm/orm/adapters/in-memory/index.min.mjs +2 -0
  196. package/dist/esm/orm/adapters/in-memory/index.min.mjs.map +1 -0
  197. package/dist/esm/orm/adapters/in-memory/index.mjs +11 -0
  198. package/dist/esm/orm/adapters/in-memory/index.mjs.map +1 -0
  199. package/dist/esm/orm/adapters/json/index.min.mjs +2 -0
  200. package/dist/esm/orm/adapters/json/index.min.mjs.map +1 -0
  201. package/dist/esm/orm/adapters/json/index.mjs +980 -0
  202. package/dist/esm/orm/adapters/json/index.mjs.map +1 -0
  203. package/dist/esm/orm/adapters/mongodb/index.min.mjs +2 -0
  204. package/dist/esm/orm/adapters/mongodb/index.min.mjs.map +1 -0
  205. package/dist/esm/orm/adapters/mongodb/index.mjs +1539 -0
  206. package/dist/esm/orm/adapters/mongodb/index.mjs.map +1 -0
  207. package/dist/esm/orm/adapters/postgresql/index.min.mjs +47 -0
  208. package/dist/esm/orm/adapters/postgresql/index.min.mjs.map +1 -0
  209. package/dist/esm/orm/adapters/postgresql/index.mjs +2070 -0
  210. package/dist/esm/orm/adapters/postgresql/index.mjs.map +1 -0
  211. package/dist/esm/orm/index.min.mjs +2 -0
  212. package/dist/esm/orm/index.min.mjs.map +1 -0
  213. package/dist/esm/orm/index.mjs +7326 -0
  214. package/dist/esm/orm/index.mjs.map +1 -0
  215. package/dist/esm/server/adapters/express/index.min.mjs +2 -0
  216. package/dist/esm/server/adapters/express/index.min.mjs.map +1 -0
  217. package/dist/esm/server/adapters/express/index.mjs +126 -0
  218. package/dist/esm/server/adapters/express/index.mjs.map +1 -0
  219. package/dist/esm/server/adapters/fastify/index.min.mjs +2 -0
  220. package/dist/esm/server/adapters/fastify/index.min.mjs.map +1 -0
  221. package/dist/{types/server/impls/fastify.js → esm/server/adapters/fastify/index.mjs} +56 -45
  222. package/dist/esm/server/adapters/fastify/index.mjs.map +1 -0
  223. package/dist/esm/server/index.min.mjs +1 -1
  224. package/dist/esm/server/index.min.mjs.map +1 -1
  225. package/dist/esm/server/index.mjs +38 -9
  226. package/dist/esm/server/index.mjs.map +1 -1
  227. package/dist/esm/types/index.min.mjs +0 -1
  228. package/dist/esm/types/index.min.mjs.map +1 -1
  229. package/dist/esm/types/index.mjs +0 -1
  230. package/dist/esm/types/index.mjs.map +1 -1
  231. package/dist/esm/utilities/index.min.mjs +1 -1
  232. package/dist/esm/utilities/index.min.mjs.map +1 -1
  233. package/dist/esm/utilities/index.mjs +22 -9
  234. package/dist/esm/utilities/index.mjs.map +1 -1
  235. package/dist/esm/validations/index.min.mjs +1 -1
  236. package/dist/esm/validations/index.min.mjs.map +1 -1
  237. package/dist/esm/validations/index.mjs +8 -18
  238. package/dist/esm/validations/index.mjs.map +1 -1
  239. package/dist/types/adapter-Coap9ISX.d.ts +1435 -0
  240. package/dist/types/{fastify-DLPUK3vD.d.ts → base-3PpBAx1K.d.ts} +58 -143
  241. package/dist/types/cache/adapters/in-memory/index.d.ts +21 -0
  242. package/dist/types/cache/adapters/in-memory/index.js +92 -0
  243. package/dist/types/cache/adapters/redis/index.d.ts +73 -0
  244. package/dist/types/cache/adapters/redis/index.js +12 -0
  245. package/dist/types/cache/index.d.ts +2 -42
  246. package/dist/types/cache/index.js +9 -4
  247. package/dist/types/chunk-32DMHN3G.js +1823 -0
  248. package/dist/types/chunk-4LRJJSGG.js +112 -0
  249. package/dist/types/chunk-A2MRYMCA.js +1279 -0
  250. package/dist/types/chunk-H6JBLKX5.js +794 -0
  251. package/dist/{esm/events/types/kafka.mjs → types/chunk-IAHTILKJ.js} +59 -38
  252. package/dist/types/chunk-JZ2JTENY.js +125 -0
  253. package/dist/types/chunk-KZKFYO4V.js +7 -0
  254. package/dist/types/chunk-LN3A6R4Y.js +28 -0
  255. package/dist/types/chunk-LWUMIHL4.js +21 -0
  256. package/dist/types/chunk-MLKGABMK.js +9 -0
  257. package/dist/types/chunk-XOU2A2Y6.js +52 -0
  258. package/dist/types/{core-BrkNSwvc.d.ts → core-tNlIMH9Y.d.ts} +48 -38
  259. package/dist/types/dbs/adapters/mongodb/index.d.ts +43 -0
  260. package/dist/types/dbs/adapters/mongodb/index.js +418 -0
  261. package/dist/types/dbs/index.d.ts +14 -12
  262. package/dist/types/dbs/index.js +22 -6
  263. package/dist/types/equippedError-Cmo60Kn-.d.ts +8 -0
  264. package/dist/types/errors/index.d.ts +3 -3
  265. package/dist/types/errors/index.js +22 -8
  266. package/dist/types/events/adapters/kafka/index.d.ts +83 -0
  267. package/dist/types/events/adapters/kafka/index.js +11 -0
  268. package/dist/types/events/adapters/rabbitmq/index.d.ts +41 -0
  269. package/dist/types/events/adapters/rabbitmq/index.js +91 -0
  270. package/dist/types/events/index.d.ts +11 -11
  271. package/dist/types/events/index.js +7 -4
  272. package/dist/types/index.d.ts +2 -25
  273. package/dist/types/index.js +8 -1
  274. package/dist/types/instance/index.d.ts +12 -179
  275. package/dist/types/instance/index.js +4 -132
  276. package/dist/types/introspection-ZQCAW254.js +9 -0
  277. package/dist/types/jobs/adapters/redis/index.d.ts +93 -0
  278. package/dist/types/jobs/{types/redis.js → adapters/redis/index.js} +70 -55
  279. package/dist/types/jobs/index.d.ts +19 -35
  280. package/dist/types/jobs/index.js +9 -2
  281. package/dist/types/orm/adapters/in-memory/index.d.ts +92 -0
  282. package/dist/types/orm/adapters/in-memory/index.js +10 -0
  283. package/dist/types/orm/adapters/json/index.d.ts +72 -0
  284. package/dist/types/orm/adapters/json/index.js +979 -0
  285. package/dist/types/orm/adapters/mongodb/index.d.ts +74 -0
  286. package/dist/types/orm/adapters/mongodb/index.js +1538 -0
  287. package/dist/types/orm/adapters/postgresql/index.d.ts +112 -0
  288. package/dist/types/orm/adapters/postgresql/index.js +2069 -0
  289. package/dist/types/orm/index.d.ts +160 -0
  290. package/dist/types/orm/index.js +7325 -0
  291. package/dist/types/{requestError-C2PNWUrt.d.ts → requestError-DdaL8hc3.d.ts} +2 -8
  292. package/dist/types/server/adapters/express/index.d.ts +194 -0
  293. package/dist/types/server/adapters/express/index.js +125 -0
  294. package/dist/types/server/adapters/fastify/index.d.ts +219 -0
  295. package/dist/{esm/server/impls/fastify.mjs → types/server/adapters/fastify/index.js} +55 -46
  296. package/dist/types/server/index.d.ts +10 -11
  297. package/dist/types/server/index.js +38 -9
  298. package/dist/types/types/index.js +0 -1
  299. package/dist/types/utilities/index.d.ts +22 -9
  300. package/dist/types/utilities/index.js +22 -9
  301. package/dist/types/{validationError-Bw8OYv5s.d.ts → validationError-oigtHqBi.d.ts} +1 -1
  302. package/dist/types/validations/index.d.ts +3 -2
  303. package/dist/types/validations/index.js +8 -18
  304. package/package.json +154 -15
  305. package/dist/cjs/audit/events.cjs +0 -101
  306. package/dist/cjs/audit/events.cjs.map +0 -1
  307. package/dist/cjs/audit/events.min.cjs +0 -2
  308. package/dist/cjs/audit/events.min.cjs.map +0 -1
  309. package/dist/cjs/audit/index.cjs +0 -2
  310. package/dist/cjs/audit/index.cjs.map +0 -1
  311. package/dist/cjs/audit/index.min.cjs +0 -2
  312. package/dist/cjs/audit/index.min.cjs.map +0 -1
  313. package/dist/cjs/cache/base.cjs +0 -6
  314. package/dist/cjs/cache/base.cjs.map +0 -1
  315. package/dist/cjs/cache/base.min.cjs +0 -2
  316. package/dist/cjs/cache/base.min.cjs.map +0 -1
  317. package/dist/cjs/cache/pipes.cjs +0 -16
  318. package/dist/cjs/cache/pipes.cjs.map +0 -1
  319. package/dist/cjs/cache/pipes.min.cjs +0 -2
  320. package/dist/cjs/cache/pipes.min.cjs.map +0 -1
  321. package/dist/cjs/cache/types/in-memory.cjs +0 -47
  322. package/dist/cjs/cache/types/in-memory.cjs.map +0 -1
  323. package/dist/cjs/cache/types/in-memory.min.cjs +0 -2
  324. package/dist/cjs/cache/types/in-memory.min.cjs.map +0 -1
  325. package/dist/cjs/cache/types/redis.cjs +0 -55
  326. package/dist/cjs/cache/types/redis.cjs.map +0 -1
  327. package/dist/cjs/cache/types/redis.min.cjs +0 -2
  328. package/dist/cjs/cache/types/redis.min.cjs.map +0 -1
  329. package/dist/cjs/dbs/base/changes.cjs +0 -36
  330. package/dist/cjs/dbs/base/changes.cjs.map +0 -1
  331. package/dist/cjs/dbs/base/changes.min.cjs +0 -2
  332. package/dist/cjs/dbs/base/changes.min.cjs.map +0 -1
  333. package/dist/cjs/dbs/base/core.cjs +0 -1
  334. package/dist/cjs/dbs/base/core.cjs.map +0 -1
  335. package/dist/cjs/dbs/base/core.min.cjs +0 -1
  336. package/dist/cjs/dbs/base/core.min.cjs.map +0 -1
  337. package/dist/cjs/dbs/base/db.cjs +0 -14
  338. package/dist/cjs/dbs/base/db.cjs.map +0 -1
  339. package/dist/cjs/dbs/base/db.min.cjs +0 -2
  340. package/dist/cjs/dbs/base/db.min.cjs.map +0 -1
  341. package/dist/cjs/dbs/base/types.cjs +0 -2
  342. package/dist/cjs/dbs/base/types.cjs.map +0 -1
  343. package/dist/cjs/dbs/base/types.min.cjs +0 -2
  344. package/dist/cjs/dbs/base/types.min.cjs.map +0 -1
  345. package/dist/cjs/dbs/mongo/changes.cjs +0 -81
  346. package/dist/cjs/dbs/mongo/changes.cjs.map +0 -1
  347. package/dist/cjs/dbs/mongo/changes.min.cjs +0 -2
  348. package/dist/cjs/dbs/mongo/changes.min.cjs.map +0 -1
  349. package/dist/cjs/dbs/mongo/db.cjs +0 -225
  350. package/dist/cjs/dbs/mongo/db.cjs.map +0 -1
  351. package/dist/cjs/dbs/mongo/db.min.cjs +0 -2
  352. package/dist/cjs/dbs/mongo/db.min.cjs.map +0 -1
  353. package/dist/cjs/dbs/mongo/query.cjs +0 -66
  354. package/dist/cjs/dbs/mongo/query.cjs.map +0 -1
  355. package/dist/cjs/dbs/mongo/query.min.cjs +0 -2
  356. package/dist/cjs/dbs/mongo/query.min.cjs.map +0 -1
  357. package/dist/cjs/dbs/pipes.cjs +0 -104
  358. package/dist/cjs/dbs/pipes.cjs.map +0 -1
  359. package/dist/cjs/dbs/pipes.min.cjs +0 -2
  360. package/dist/cjs/dbs/pipes.min.cjs.map +0 -1
  361. package/dist/cjs/errors/equippedError.cjs +0 -12
  362. package/dist/cjs/errors/equippedError.cjs.map +0 -1
  363. package/dist/cjs/errors/equippedError.min.cjs +0 -2
  364. package/dist/cjs/errors/equippedError.min.cjs.map +0 -1
  365. package/dist/cjs/errors/requestError.cjs +0 -12
  366. package/dist/cjs/errors/requestError.cjs.map +0 -1
  367. package/dist/cjs/errors/requestError.min.cjs +0 -2
  368. package/dist/cjs/errors/requestError.min.cjs.map +0 -1
  369. package/dist/cjs/errors/types/badRequestError.cjs +0 -12
  370. package/dist/cjs/errors/types/badRequestError.cjs.map +0 -1
  371. package/dist/cjs/errors/types/badRequestError.min.cjs +0 -2
  372. package/dist/cjs/errors/types/badRequestError.min.cjs.map +0 -1
  373. package/dist/cjs/errors/types/notAuthenticatedError.cjs +0 -12
  374. package/dist/cjs/errors/types/notAuthenticatedError.cjs.map +0 -1
  375. package/dist/cjs/errors/types/notAuthenticatedError.min.cjs +0 -2
  376. package/dist/cjs/errors/types/notAuthenticatedError.min.cjs.map +0 -1
  377. package/dist/cjs/errors/types/notAuthorizedError.cjs +0 -12
  378. package/dist/cjs/errors/types/notAuthorizedError.cjs.map +0 -1
  379. package/dist/cjs/errors/types/notAuthorizedError.min.cjs +0 -2
  380. package/dist/cjs/errors/types/notAuthorizedError.min.cjs.map +0 -1
  381. package/dist/cjs/errors/types/notFoundError.cjs +0 -12
  382. package/dist/cjs/errors/types/notFoundError.cjs.map +0 -1
  383. package/dist/cjs/errors/types/notFoundError.min.cjs +0 -2
  384. package/dist/cjs/errors/types/notFoundError.min.cjs.map +0 -1
  385. package/dist/cjs/errors/types/tokenExpired.cjs +0 -12
  386. package/dist/cjs/errors/types/tokenExpired.cjs.map +0 -1
  387. package/dist/cjs/errors/types/tokenExpired.min.cjs +0 -2
  388. package/dist/cjs/errors/types/tokenExpired.min.cjs.map +0 -1
  389. package/dist/cjs/errors/types/validationError.cjs +0 -16
  390. package/dist/cjs/errors/types/validationError.cjs.map +0 -1
  391. package/dist/cjs/errors/types/validationError.min.cjs +0 -2
  392. package/dist/cjs/errors/types/validationError.min.cjs.map +0 -1
  393. package/dist/cjs/events/base.cjs +0 -6
  394. package/dist/cjs/events/base.cjs.map +0 -1
  395. package/dist/cjs/events/base.min.cjs +0 -2
  396. package/dist/cjs/events/base.min.cjs.map +0 -1
  397. package/dist/cjs/events/pipes.cjs +0 -28
  398. package/dist/cjs/events/pipes.cjs.map +0 -1
  399. package/dist/cjs/events/pipes.min.cjs +0 -2
  400. package/dist/cjs/events/pipes.min.cjs.map +0 -1
  401. package/dist/cjs/events/types/kafka.cjs +0 -80
  402. package/dist/cjs/events/types/kafka.cjs.map +0 -1
  403. package/dist/cjs/events/types/kafka.min.cjs +0 -2
  404. package/dist/cjs/events/types/kafka.min.cjs.map +0 -1
  405. package/dist/cjs/events/types/rabbitmq.cjs +0 -54
  406. package/dist/cjs/events/types/rabbitmq.cjs.map +0 -1
  407. package/dist/cjs/events/types/rabbitmq.min.cjs +0 -2
  408. package/dist/cjs/events/types/rabbitmq.min.cjs.map +0 -1
  409. package/dist/cjs/instance/hooks.cjs +0 -26
  410. package/dist/cjs/instance/hooks.cjs.map +0 -1
  411. package/dist/cjs/instance/hooks.min.cjs +0 -2
  412. package/dist/cjs/instance/hooks.min.cjs.map +0 -1
  413. package/dist/cjs/instance/settings.cjs +0 -57
  414. package/dist/cjs/instance/settings.cjs.map +0 -1
  415. package/dist/cjs/instance/settings.min.cjs +0 -2
  416. package/dist/cjs/instance/settings.min.cjs.map +0 -1
  417. package/dist/cjs/jobs/pipes.cjs +0 -13
  418. package/dist/cjs/jobs/pipes.cjs.map +0 -1
  419. package/dist/cjs/jobs/pipes.min.cjs +0 -2
  420. package/dist/cjs/jobs/pipes.min.cjs.map +0 -1
  421. package/dist/cjs/jobs/types/redis.cjs +0 -106
  422. package/dist/cjs/jobs/types/redis.cjs.map +0 -1
  423. package/dist/cjs/jobs/types/redis.min.cjs +0 -2
  424. package/dist/cjs/jobs/types/redis.min.cjs.map +0 -1
  425. package/dist/cjs/server/impls/base.cjs +0 -211
  426. package/dist/cjs/server/impls/base.cjs.map +0 -1
  427. package/dist/cjs/server/impls/base.min.cjs +0 -2
  428. package/dist/cjs/server/impls/base.min.cjs.map +0 -1
  429. package/dist/cjs/server/impls/express.cjs +0 -111
  430. package/dist/cjs/server/impls/express.cjs.map +0 -1
  431. package/dist/cjs/server/impls/express.min.cjs +0 -2
  432. package/dist/cjs/server/impls/express.min.cjs.map +0 -1
  433. package/dist/cjs/server/impls/fastify.cjs +0 -121
  434. package/dist/cjs/server/impls/fastify.cjs.map +0 -1
  435. package/dist/cjs/server/impls/fastify.min.cjs +0 -2
  436. package/dist/cjs/server/impls/fastify.min.cjs.map +0 -1
  437. package/dist/cjs/server/middlewares/index.cjs +0 -2
  438. package/dist/cjs/server/middlewares/index.cjs.map +0 -1
  439. package/dist/cjs/server/middlewares/index.min.cjs +0 -2
  440. package/dist/cjs/server/middlewares/index.min.cjs.map +0 -1
  441. package/dist/cjs/server/middlewares/requireAuthUser.cjs +0 -22
  442. package/dist/cjs/server/middlewares/requireAuthUser.cjs.map +0 -1
  443. package/dist/cjs/server/middlewares/requireAuthUser.min.cjs +0 -2
  444. package/dist/cjs/server/middlewares/requireAuthUser.min.cjs.map +0 -1
  445. package/dist/cjs/server/openapi.cjs +0 -191
  446. package/dist/cjs/server/openapi.cjs.map +0 -1
  447. package/dist/cjs/server/openapi.min.cjs +0 -30
  448. package/dist/cjs/server/openapi.min.cjs.map +0 -1
  449. package/dist/cjs/server/pipes.cjs +0 -67
  450. package/dist/cjs/server/pipes.cjs.map +0 -1
  451. package/dist/cjs/server/pipes.min.cjs +0 -2
  452. package/dist/cjs/server/pipes.min.cjs.map +0 -1
  453. package/dist/cjs/server/requests-auth-methods/apiKeys.cjs +0 -21
  454. package/dist/cjs/server/requests-auth-methods/apiKeys.cjs.map +0 -1
  455. package/dist/cjs/server/requests-auth-methods/apiKeys.min.cjs +0 -2
  456. package/dist/cjs/server/requests-auth-methods/apiKeys.min.cjs.map +0 -1
  457. package/dist/cjs/server/requests-auth-methods/base.cjs +0 -20
  458. package/dist/cjs/server/requests-auth-methods/base.cjs.map +0 -1
  459. package/dist/cjs/server/requests-auth-methods/base.min.cjs +0 -2
  460. package/dist/cjs/server/requests-auth-methods/base.min.cjs.map +0 -1
  461. package/dist/cjs/server/requests-auth-methods/index.cjs +0 -4
  462. package/dist/cjs/server/requests-auth-methods/index.cjs.map +0 -1
  463. package/dist/cjs/server/requests-auth-methods/index.min.cjs +0 -2
  464. package/dist/cjs/server/requests-auth-methods/index.min.cjs.map +0 -1
  465. package/dist/cjs/server/requests-auth-methods/jwt.cjs +0 -78
  466. package/dist/cjs/server/requests-auth-methods/jwt.cjs.map +0 -1
  467. package/dist/cjs/server/requests-auth-methods/jwt.min.cjs +0 -2
  468. package/dist/cjs/server/requests-auth-methods/jwt.min.cjs.map +0 -1
  469. package/dist/cjs/server/requests.cjs +0 -80
  470. package/dist/cjs/server/requests.cjs.map +0 -1
  471. package/dist/cjs/server/requests.min.cjs +0 -2
  472. package/dist/cjs/server/requests.min.cjs.map +0 -1
  473. package/dist/cjs/server/routes.cjs +0 -74
  474. package/dist/cjs/server/routes.cjs.map +0 -1
  475. package/dist/cjs/server/routes.min.cjs +0 -2
  476. package/dist/cjs/server/routes.min.cjs.map +0 -1
  477. package/dist/cjs/server/sockets.cjs +0 -126
  478. package/dist/cjs/server/sockets.cjs.map +0 -1
  479. package/dist/cjs/server/sockets.min.cjs +0 -2
  480. package/dist/cjs/server/sockets.min.cjs.map +0 -1
  481. package/dist/cjs/server/types.cjs +0 -34
  482. package/dist/cjs/server/types.cjs.map +0 -1
  483. package/dist/cjs/server/types.min.cjs +0 -2
  484. package/dist/cjs/server/types.min.cjs.map +0 -1
  485. package/dist/cjs/types/overrides.cjs +0 -1
  486. package/dist/cjs/types/overrides.cjs.map +0 -1
  487. package/dist/cjs/types/overrides.min.cjs +0 -1
  488. package/dist/cjs/types/overrides.min.cjs.map +0 -1
  489. package/dist/cjs/utilities/authProviders.cjs +0 -53
  490. package/dist/cjs/utilities/authProviders.cjs.map +0 -1
  491. package/dist/cjs/utilities/authProviders.min.cjs +0 -2
  492. package/dist/cjs/utilities/authProviders.min.cjs.map +0 -1
  493. package/dist/cjs/utilities/hash.cjs +0 -17
  494. package/dist/cjs/utilities/hash.cjs.map +0 -1
  495. package/dist/cjs/utilities/hash.min.cjs +0 -2
  496. package/dist/cjs/utilities/hash.min.cjs.map +0 -1
  497. package/dist/cjs/utilities/json.cjs +0 -16
  498. package/dist/cjs/utilities/json.cjs.map +0 -1
  499. package/dist/cjs/utilities/json.min.cjs +0 -2
  500. package/dist/cjs/utilities/json.min.cjs.map +0 -1
  501. package/dist/cjs/utilities/media.cjs +0 -13
  502. package/dist/cjs/utilities/media.cjs.map +0 -1
  503. package/dist/cjs/utilities/media.min.cjs +0 -2
  504. package/dist/cjs/utilities/media.min.cjs.map +0 -1
  505. package/dist/cjs/utilities/random.cjs +0 -12
  506. package/dist/cjs/utilities/random.cjs.map +0 -1
  507. package/dist/cjs/utilities/random.min.cjs +0 -2
  508. package/dist/cjs/utilities/random.min.cjs.map +0 -1
  509. package/dist/cjs/utilities/retry.cjs +0 -14
  510. package/dist/cjs/utilities/retry.cjs.map +0 -1
  511. package/dist/cjs/utilities/retry.min.cjs +0 -2
  512. package/dist/cjs/utilities/retry.min.cjs.map +0 -1
  513. package/dist/cjs/validations/valleyed.cjs +0 -43
  514. package/dist/cjs/validations/valleyed.cjs.map +0 -1
  515. package/dist/cjs/validations/valleyed.min.cjs +0 -2
  516. package/dist/cjs/validations/valleyed.min.cjs.map +0 -1
  517. package/dist/esm/audit/events.min.mjs +0 -2
  518. package/dist/esm/audit/events.min.mjs.map +0 -1
  519. package/dist/esm/audit/events.mjs +0 -101
  520. package/dist/esm/audit/events.mjs.map +0 -1
  521. package/dist/esm/audit/index.min.mjs +0 -2
  522. package/dist/esm/audit/index.min.mjs.map +0 -1
  523. package/dist/esm/audit/index.mjs +0 -2
  524. package/dist/esm/audit/index.mjs.map +0 -1
  525. package/dist/esm/cache/base.min.mjs +0 -2
  526. package/dist/esm/cache/base.min.mjs.map +0 -1
  527. package/dist/esm/cache/base.mjs +0 -6
  528. package/dist/esm/cache/base.mjs.map +0 -1
  529. package/dist/esm/cache/pipes.min.mjs +0 -2
  530. package/dist/esm/cache/pipes.min.mjs.map +0 -1
  531. package/dist/esm/cache/pipes.mjs +0 -16
  532. package/dist/esm/cache/pipes.mjs.map +0 -1
  533. package/dist/esm/cache/types/in-memory.min.mjs +0 -2
  534. package/dist/esm/cache/types/in-memory.min.mjs.map +0 -1
  535. package/dist/esm/cache/types/in-memory.mjs +0 -47
  536. package/dist/esm/cache/types/in-memory.mjs.map +0 -1
  537. package/dist/esm/cache/types/redis.min.mjs +0 -2
  538. package/dist/esm/cache/types/redis.min.mjs.map +0 -1
  539. package/dist/esm/cache/types/redis.mjs +0 -55
  540. package/dist/esm/cache/types/redis.mjs.map +0 -1
  541. package/dist/esm/dbs/base/changes.min.mjs +0 -2
  542. package/dist/esm/dbs/base/changes.min.mjs.map +0 -1
  543. package/dist/esm/dbs/base/changes.mjs +0 -36
  544. package/dist/esm/dbs/base/changes.mjs.map +0 -1
  545. package/dist/esm/dbs/base/core.min.mjs +0 -1
  546. package/dist/esm/dbs/base/core.mjs +0 -1
  547. package/dist/esm/dbs/base/db.min.mjs +0 -2
  548. package/dist/esm/dbs/base/db.min.mjs.map +0 -1
  549. package/dist/esm/dbs/base/db.mjs +0 -14
  550. package/dist/esm/dbs/base/db.mjs.map +0 -1
  551. package/dist/esm/dbs/base/types.min.mjs +0 -2
  552. package/dist/esm/dbs/base/types.min.mjs.map +0 -1
  553. package/dist/esm/dbs/base/types.mjs +0 -2
  554. package/dist/esm/dbs/base/types.mjs.map +0 -1
  555. package/dist/esm/dbs/mongo/changes.min.mjs +0 -2
  556. package/dist/esm/dbs/mongo/changes.min.mjs.map +0 -1
  557. package/dist/esm/dbs/mongo/changes.mjs +0 -81
  558. package/dist/esm/dbs/mongo/changes.mjs.map +0 -1
  559. package/dist/esm/dbs/mongo/db.min.mjs +0 -2
  560. package/dist/esm/dbs/mongo/db.min.mjs.map +0 -1
  561. package/dist/esm/dbs/mongo/db.mjs +0 -225
  562. package/dist/esm/dbs/mongo/db.mjs.map +0 -1
  563. package/dist/esm/dbs/mongo/query.min.mjs +0 -2
  564. package/dist/esm/dbs/mongo/query.min.mjs.map +0 -1
  565. package/dist/esm/dbs/mongo/query.mjs +0 -66
  566. package/dist/esm/dbs/mongo/query.mjs.map +0 -1
  567. package/dist/esm/dbs/pipes.min.mjs +0 -2
  568. package/dist/esm/dbs/pipes.min.mjs.map +0 -1
  569. package/dist/esm/dbs/pipes.mjs +0 -104
  570. package/dist/esm/dbs/pipes.mjs.map +0 -1
  571. package/dist/esm/errors/equippedError.min.mjs +0 -2
  572. package/dist/esm/errors/equippedError.min.mjs.map +0 -1
  573. package/dist/esm/errors/equippedError.mjs +0 -12
  574. package/dist/esm/errors/equippedError.mjs.map +0 -1
  575. package/dist/esm/errors/requestError.min.mjs +0 -2
  576. package/dist/esm/errors/requestError.min.mjs.map +0 -1
  577. package/dist/esm/errors/requestError.mjs +0 -12
  578. package/dist/esm/errors/requestError.mjs.map +0 -1
  579. package/dist/esm/errors/types/badRequestError.min.mjs +0 -2
  580. package/dist/esm/errors/types/badRequestError.min.mjs.map +0 -1
  581. package/dist/esm/errors/types/badRequestError.mjs +0 -12
  582. package/dist/esm/errors/types/badRequestError.mjs.map +0 -1
  583. package/dist/esm/errors/types/notAuthenticatedError.min.mjs +0 -2
  584. package/dist/esm/errors/types/notAuthenticatedError.min.mjs.map +0 -1
  585. package/dist/esm/errors/types/notAuthenticatedError.mjs +0 -12
  586. package/dist/esm/errors/types/notAuthenticatedError.mjs.map +0 -1
  587. package/dist/esm/errors/types/notAuthorizedError.min.mjs +0 -2
  588. package/dist/esm/errors/types/notAuthorizedError.min.mjs.map +0 -1
  589. package/dist/esm/errors/types/notAuthorizedError.mjs +0 -12
  590. package/dist/esm/errors/types/notAuthorizedError.mjs.map +0 -1
  591. package/dist/esm/errors/types/notFoundError.min.mjs +0 -2
  592. package/dist/esm/errors/types/notFoundError.min.mjs.map +0 -1
  593. package/dist/esm/errors/types/notFoundError.mjs +0 -12
  594. package/dist/esm/errors/types/notFoundError.mjs.map +0 -1
  595. package/dist/esm/errors/types/tokenExpired.min.mjs +0 -2
  596. package/dist/esm/errors/types/tokenExpired.min.mjs.map +0 -1
  597. package/dist/esm/errors/types/tokenExpired.mjs +0 -12
  598. package/dist/esm/errors/types/tokenExpired.mjs.map +0 -1
  599. package/dist/esm/errors/types/validationError.min.mjs +0 -2
  600. package/dist/esm/errors/types/validationError.min.mjs.map +0 -1
  601. package/dist/esm/errors/types/validationError.mjs +0 -16
  602. package/dist/esm/errors/types/validationError.mjs.map +0 -1
  603. package/dist/esm/events/base.min.mjs +0 -2
  604. package/dist/esm/events/base.min.mjs.map +0 -1
  605. package/dist/esm/events/base.mjs +0 -6
  606. package/dist/esm/events/base.mjs.map +0 -1
  607. package/dist/esm/events/pipes.min.mjs +0 -2
  608. package/dist/esm/events/pipes.min.mjs.map +0 -1
  609. package/dist/esm/events/pipes.mjs +0 -28
  610. package/dist/esm/events/pipes.mjs.map +0 -1
  611. package/dist/esm/events/types/kafka.min.mjs +0 -2
  612. package/dist/esm/events/types/kafka.min.mjs.map +0 -1
  613. package/dist/esm/events/types/kafka.mjs.map +0 -1
  614. package/dist/esm/events/types/rabbitmq.min.mjs +0 -2
  615. package/dist/esm/events/types/rabbitmq.min.mjs.map +0 -1
  616. package/dist/esm/events/types/rabbitmq.mjs +0 -54
  617. package/dist/esm/events/types/rabbitmq.mjs.map +0 -1
  618. package/dist/esm/instance/hooks.min.mjs +0 -2
  619. package/dist/esm/instance/hooks.min.mjs.map +0 -1
  620. package/dist/esm/instance/hooks.mjs +0 -26
  621. package/dist/esm/instance/hooks.mjs.map +0 -1
  622. package/dist/esm/instance/settings.min.mjs +0 -2
  623. package/dist/esm/instance/settings.min.mjs.map +0 -1
  624. package/dist/esm/instance/settings.mjs +0 -57
  625. package/dist/esm/instance/settings.mjs.map +0 -1
  626. package/dist/esm/jobs/pipes.min.mjs +0 -2
  627. package/dist/esm/jobs/pipes.min.mjs.map +0 -1
  628. package/dist/esm/jobs/pipes.mjs +0 -13
  629. package/dist/esm/jobs/pipes.mjs.map +0 -1
  630. package/dist/esm/jobs/types/redis.min.mjs +0 -2
  631. package/dist/esm/jobs/types/redis.min.mjs.map +0 -1
  632. package/dist/esm/jobs/types/redis.mjs.map +0 -1
  633. package/dist/esm/server/impls/base.min.mjs +0 -2
  634. package/dist/esm/server/impls/base.min.mjs.map +0 -1
  635. package/dist/esm/server/impls/base.mjs +0 -211
  636. package/dist/esm/server/impls/base.mjs.map +0 -1
  637. package/dist/esm/server/impls/express.min.mjs +0 -2
  638. package/dist/esm/server/impls/express.min.mjs.map +0 -1
  639. package/dist/esm/server/impls/express.mjs +0 -111
  640. package/dist/esm/server/impls/express.mjs.map +0 -1
  641. package/dist/esm/server/impls/fastify.min.mjs +0 -2
  642. package/dist/esm/server/impls/fastify.min.mjs.map +0 -1
  643. package/dist/esm/server/impls/fastify.mjs.map +0 -1
  644. package/dist/esm/server/middlewares/index.min.mjs +0 -2
  645. package/dist/esm/server/middlewares/index.min.mjs.map +0 -1
  646. package/dist/esm/server/middlewares/index.mjs +0 -2
  647. package/dist/esm/server/middlewares/index.mjs.map +0 -1
  648. package/dist/esm/server/middlewares/requireAuthUser.min.mjs +0 -2
  649. package/dist/esm/server/middlewares/requireAuthUser.min.mjs.map +0 -1
  650. package/dist/esm/server/middlewares/requireAuthUser.mjs +0 -22
  651. package/dist/esm/server/middlewares/requireAuthUser.mjs.map +0 -1
  652. package/dist/esm/server/openapi.min.mjs +0 -30
  653. package/dist/esm/server/openapi.min.mjs.map +0 -1
  654. package/dist/esm/server/openapi.mjs +0 -191
  655. package/dist/esm/server/openapi.mjs.map +0 -1
  656. package/dist/esm/server/pipes.min.mjs +0 -2
  657. package/dist/esm/server/pipes.min.mjs.map +0 -1
  658. package/dist/esm/server/pipes.mjs +0 -67
  659. package/dist/esm/server/pipes.mjs.map +0 -1
  660. package/dist/esm/server/requests-auth-methods/apiKeys.min.mjs +0 -2
  661. package/dist/esm/server/requests-auth-methods/apiKeys.min.mjs.map +0 -1
  662. package/dist/esm/server/requests-auth-methods/apiKeys.mjs +0 -21
  663. package/dist/esm/server/requests-auth-methods/apiKeys.mjs.map +0 -1
  664. package/dist/esm/server/requests-auth-methods/base.min.mjs +0 -2
  665. package/dist/esm/server/requests-auth-methods/base.min.mjs.map +0 -1
  666. package/dist/esm/server/requests-auth-methods/base.mjs +0 -20
  667. package/dist/esm/server/requests-auth-methods/base.mjs.map +0 -1
  668. package/dist/esm/server/requests-auth-methods/index.min.mjs +0 -2
  669. package/dist/esm/server/requests-auth-methods/index.min.mjs.map +0 -1
  670. package/dist/esm/server/requests-auth-methods/index.mjs +0 -4
  671. package/dist/esm/server/requests-auth-methods/index.mjs.map +0 -1
  672. package/dist/esm/server/requests-auth-methods/jwt.min.mjs +0 -2
  673. package/dist/esm/server/requests-auth-methods/jwt.min.mjs.map +0 -1
  674. package/dist/esm/server/requests-auth-methods/jwt.mjs +0 -78
  675. package/dist/esm/server/requests-auth-methods/jwt.mjs.map +0 -1
  676. package/dist/esm/server/requests.min.mjs +0 -2
  677. package/dist/esm/server/requests.min.mjs.map +0 -1
  678. package/dist/esm/server/requests.mjs +0 -80
  679. package/dist/esm/server/requests.mjs.map +0 -1
  680. package/dist/esm/server/routes.min.mjs +0 -2
  681. package/dist/esm/server/routes.min.mjs.map +0 -1
  682. package/dist/esm/server/routes.mjs +0 -74
  683. package/dist/esm/server/routes.mjs.map +0 -1
  684. package/dist/esm/server/sockets.min.mjs +0 -2
  685. package/dist/esm/server/sockets.min.mjs.map +0 -1
  686. package/dist/esm/server/sockets.mjs +0 -126
  687. package/dist/esm/server/sockets.mjs.map +0 -1
  688. package/dist/esm/server/types.min.mjs +0 -2
  689. package/dist/esm/server/types.min.mjs.map +0 -1
  690. package/dist/esm/server/types.mjs +0 -34
  691. package/dist/esm/server/types.mjs.map +0 -1
  692. package/dist/esm/types/overrides.min.mjs +0 -1
  693. package/dist/esm/types/overrides.mjs +0 -1
  694. package/dist/esm/utilities/authProviders.min.mjs +0 -2
  695. package/dist/esm/utilities/authProviders.min.mjs.map +0 -1
  696. package/dist/esm/utilities/authProviders.mjs +0 -53
  697. package/dist/esm/utilities/authProviders.mjs.map +0 -1
  698. package/dist/esm/utilities/hash.min.mjs +0 -2
  699. package/dist/esm/utilities/hash.min.mjs.map +0 -1
  700. package/dist/esm/utilities/hash.mjs +0 -17
  701. package/dist/esm/utilities/hash.mjs.map +0 -1
  702. package/dist/esm/utilities/json.min.mjs +0 -2
  703. package/dist/esm/utilities/json.min.mjs.map +0 -1
  704. package/dist/esm/utilities/json.mjs +0 -16
  705. package/dist/esm/utilities/json.mjs.map +0 -1
  706. package/dist/esm/utilities/media.min.mjs +0 -2
  707. package/dist/esm/utilities/media.min.mjs.map +0 -1
  708. package/dist/esm/utilities/media.mjs +0 -13
  709. package/dist/esm/utilities/media.mjs.map +0 -1
  710. package/dist/esm/utilities/random.min.mjs +0 -2
  711. package/dist/esm/utilities/random.min.mjs.map +0 -1
  712. package/dist/esm/utilities/random.mjs +0 -12
  713. package/dist/esm/utilities/random.mjs.map +0 -1
  714. package/dist/esm/utilities/retry.min.mjs +0 -2
  715. package/dist/esm/utilities/retry.min.mjs.map +0 -1
  716. package/dist/esm/utilities/retry.mjs +0 -14
  717. package/dist/esm/utilities/retry.mjs.map +0 -1
  718. package/dist/esm/validations/valleyed.min.mjs +0 -2
  719. package/dist/esm/validations/valleyed.min.mjs.map +0 -1
  720. package/dist/esm/validations/valleyed.mjs +0 -43
  721. package/dist/esm/validations/valleyed.mjs.map +0 -1
  722. package/dist/types/audit/events.js +0 -100
  723. package/dist/types/audit/index.d.ts +0 -44
  724. package/dist/types/audit/index.js +0 -1
  725. package/dist/types/cache/base.js +0 -5
  726. package/dist/types/cache/pipes.js +0 -15
  727. package/dist/types/cache/types/in-memory.js +0 -46
  728. package/dist/types/cache/types/redis.js +0 -54
  729. package/dist/types/db-C8YY1yTO.d.ts +0 -14
  730. package/dist/types/db-Dj1SGto0.d.ts +0 -24
  731. package/dist/types/dbs/base/changes.js +0 -35
  732. package/dist/types/dbs/base/core.js +0 -0
  733. package/dist/types/dbs/base/db.js +0 -13
  734. package/dist/types/dbs/base/types.js +0 -1
  735. package/dist/types/dbs/mongo/changes.js +0 -80
  736. package/dist/types/dbs/mongo/db.js +0 -224
  737. package/dist/types/dbs/mongo/query.js +0 -65
  738. package/dist/types/dbs/pipes.js +0 -103
  739. package/dist/types/errors/equippedError.js +0 -11
  740. package/dist/types/errors/requestError.js +0 -11
  741. package/dist/types/errors/types/badRequestError.js +0 -11
  742. package/dist/types/errors/types/notAuthenticatedError.js +0 -11
  743. package/dist/types/errors/types/notAuthorizedError.js +0 -11
  744. package/dist/types/errors/types/notFoundError.js +0 -11
  745. package/dist/types/errors/types/tokenExpired.js +0 -11
  746. package/dist/types/errors/types/validationError.js +0 -15
  747. package/dist/types/events/base.js +0 -5
  748. package/dist/types/events/pipes.js +0 -27
  749. package/dist/types/events/types/rabbitmq.js +0 -53
  750. package/dist/types/instance/hooks.js +0 -25
  751. package/dist/types/instance/settings.js +0 -56
  752. package/dist/types/jobs/pipes.js +0 -12
  753. package/dist/types/kafka-Cf-TUJgv.d.ts +0 -54
  754. package/dist/types/server/impls/base.js +0 -210
  755. package/dist/types/server/impls/express.js +0 -110
  756. package/dist/types/server/middlewares/index.js +0 -1
  757. package/dist/types/server/middlewares/requireAuthUser.js +0 -21
  758. package/dist/types/server/openapi.js +0 -190
  759. package/dist/types/server/pipes.js +0 -66
  760. package/dist/types/server/requests-auth-methods/apiKeys.js +0 -20
  761. package/dist/types/server/requests-auth-methods/base.js +0 -19
  762. package/dist/types/server/requests-auth-methods/index.js +0 -3
  763. package/dist/types/server/requests-auth-methods/jwt.js +0 -77
  764. package/dist/types/server/requests.js +0 -79
  765. package/dist/types/server/routes.js +0 -73
  766. package/dist/types/server/sockets.js +0 -125
  767. package/dist/types/server/types.js +0 -33
  768. package/dist/types/types/overrides.js +0 -0
  769. package/dist/types/utilities/authProviders.js +0 -52
  770. package/dist/types/utilities/hash.js +0 -16
  771. package/dist/types/utilities/json.js +0 -15
  772. package/dist/types/utilities/media.js +0 -12
  773. package/dist/types/utilities/random.js +0 -11
  774. package/dist/types/utilities/retry.js +0 -13
  775. package/dist/types/validations/valleyed.js +0 -42
  776. /package/dist/esm/{dbs/base/core.min.mjs.map → cache/adapters/redis/index.min.mjs.map} +0 -0
  777. /package/dist/esm/{dbs/base/core.mjs.map → cache/adapters/redis/index.mjs.map} +0 -0
  778. /package/dist/esm/{types/overrides.min.mjs.map → chunk-AQY7QVYI.min.mjs.map} +0 -0
  779. /package/dist/esm/{types/overrides.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
@@ -0,0 +1,4114 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/errors/equippedError.ts
34
+ var EquippedError;
35
+ var init_equippedError = __esm({
36
+ "src/errors/equippedError.ts"() {
37
+ "use strict";
38
+ EquippedError = class extends Error {
39
+ constructor(message, context, cause) {
40
+ super(message, { cause });
41
+ this.message = message;
42
+ this.context = context;
43
+ this.cause = cause;
44
+ }
45
+ };
46
+ }
47
+ });
48
+
49
+ // src/errors/requestError.ts
50
+ var init_requestError = __esm({
51
+ "src/errors/requestError.ts"() {
52
+ "use strict";
53
+ }
54
+ });
55
+
56
+ // src/instance/hooks.ts
57
+ function registerHook(hooks, record) {
58
+ for (const dep of record.after) {
59
+ if (!hooks.some((h) => h.class === dep)) {
60
+ const depName = dep.name || "unknown";
61
+ const ownerName = record.class?.name || "anonymous";
62
+ throw new Error(`Missing dependency: ${ownerName} declares after: [${depName}], but ${depName} is not registered`);
63
+ }
64
+ }
65
+ if (record.class) {
66
+ const tentative = [...hooks, record];
67
+ detectCycle(tentative);
68
+ }
69
+ hooks.push(record);
70
+ }
71
+ function detectCycle(hooks) {
72
+ const classToAfter = /* @__PURE__ */ new Map();
73
+ for (const h of hooks) {
74
+ if (!h.class) continue;
75
+ const existing = classToAfter.get(h.class);
76
+ if (existing) {
77
+ for (const dep of h.after) {
78
+ if (!existing.includes(dep)) existing.push(dep);
79
+ }
80
+ } else {
81
+ classToAfter.set(h.class, [...h.after]);
82
+ }
83
+ }
84
+ const visited = /* @__PURE__ */ new Set();
85
+ const stack = /* @__PURE__ */ new Set();
86
+ function visit(cls, path) {
87
+ if (stack.has(cls)) {
88
+ const cycleStart = path.indexOf(cls);
89
+ const cycle = [...path.slice(cycleStart), cls];
90
+ const names = cycle.map((c) => c.name || "unknown");
91
+ throw new Error(`Cycle detected: ${names.join(" \u2192 ")}`);
92
+ }
93
+ if (visited.has(cls)) return;
94
+ stack.add(cls);
95
+ path.push(cls);
96
+ for (const dep of classToAfter.get(cls) ?? []) {
97
+ visit(dep, path);
98
+ }
99
+ path.pop();
100
+ stack.delete(cls);
101
+ visited.add(cls);
102
+ }
103
+ for (const cls of classToAfter.keys()) {
104
+ visit(cls, []);
105
+ }
106
+ }
107
+ function resolveHookDAG(hooks, invert = false) {
108
+ if (hooks.length === 0) return [];
109
+ const classToHooks = /* @__PURE__ */ new Map();
110
+ const anonymous = [];
111
+ for (const h of hooks) {
112
+ if (h.class) {
113
+ const list = classToHooks.get(h.class);
114
+ if (list) list.push(h);
115
+ else classToHooks.set(h.class, [h]);
116
+ } else {
117
+ anonymous.push(h);
118
+ }
119
+ }
120
+ const classes = [...classToHooks.keys()];
121
+ const inDegree = /* @__PURE__ */ new Map();
122
+ const graph = /* @__PURE__ */ new Map();
123
+ for (const cls of classes) {
124
+ inDegree.set(cls, 0);
125
+ graph.set(cls, []);
126
+ }
127
+ for (const h of hooks) {
128
+ if (!h.class) continue;
129
+ for (const dep of h.after) {
130
+ const [from, to] = invert ? [h.class, dep] : [dep, h.class];
131
+ const edges = graph.get(from);
132
+ if (!edges.includes(to)) {
133
+ edges.push(to);
134
+ inDegree.set(to, inDegree.get(to) + 1);
135
+ }
136
+ }
137
+ }
138
+ const layers = [];
139
+ let queue = classes.filter((c) => inDegree.get(c) === 0);
140
+ while (queue.length > 0) {
141
+ const layer = [];
142
+ const next = [];
143
+ for (const cls of queue) {
144
+ layer.push(...classToHooks.get(cls) ?? []);
145
+ }
146
+ layers.push(layer);
147
+ for (const cls of queue) {
148
+ for (const neighbor of graph.get(cls) ?? []) {
149
+ const d = inDegree.get(neighbor) - 1;
150
+ inDegree.set(neighbor, d);
151
+ if (d === 0) next.push(neighbor);
152
+ }
153
+ }
154
+ queue = next;
155
+ }
156
+ if (anonymous.length > 0) {
157
+ const anonWithDeps = anonymous.filter((h) => h.after.length > 0);
158
+ const anonWithoutDeps = anonymous.filter((h) => h.after.length === 0);
159
+ if (anonWithDeps.length > 0) {
160
+ let maxLayer = -1;
161
+ for (const h of anonWithDeps) {
162
+ for (const dep of h.after) {
163
+ const depLayer = layers.findIndex((l) => l.some((r) => r.class === dep));
164
+ if (depLayer > maxLayer) maxLayer = depLayer;
165
+ }
166
+ }
167
+ const insertAt = maxLayer + 1;
168
+ if (insertAt < layers.length) {
169
+ layers[insertAt].push(...anonWithDeps);
170
+ } else {
171
+ layers.push(anonWithDeps);
172
+ }
173
+ }
174
+ if (anonWithoutDeps.length > 0) {
175
+ if (layers.length > 0) {
176
+ layers[layers.length - 1].push(...anonWithoutDeps);
177
+ } else {
178
+ layers.push(anonWithoutDeps);
179
+ }
180
+ }
181
+ }
182
+ return layers;
183
+ }
184
+ async function runHooks(hooks, onError = (error) => {
185
+ throw error;
186
+ }, invert = false) {
187
+ const layers = resolveHookDAG(hooks, invert);
188
+ for (const layer of layers)
189
+ await Promise.all(
190
+ layer.map(async (h) => {
191
+ try {
192
+ if (typeof h.cb === "function") return await h.cb();
193
+ return await h.cb;
194
+ } catch (error) {
195
+ return onError(error instanceof Error ? error : new Error(`${error}`));
196
+ }
197
+ })
198
+ );
199
+ }
200
+ var init_hooks = __esm({
201
+ "src/instance/hooks.ts"() {
202
+ "use strict";
203
+ if (void 0) {
204
+ const { describe, test, expect } = void 0;
205
+ class A {
206
+ }
207
+ class B {
208
+ }
209
+ class C {
210
+ }
211
+ class D {
212
+ }
213
+ const noop = () => {
214
+ };
215
+ describe("registerHook", () => {
216
+ test("registers a hook with no dependencies", () => {
217
+ const hooks = [];
218
+ registerHook(hooks, { cb: noop, class: A, after: [] });
219
+ expect(hooks).toHaveLength(1);
220
+ });
221
+ test("throws on missing dependency", () => {
222
+ const hooks = [];
223
+ expect(() => registerHook(hooks, { cb: noop, class: B, after: [A] })).toThrow(/Missing dependency.*B.*A/);
224
+ });
225
+ test("throws on cycle: A\u2192B\u2192A", () => {
226
+ const hooks = [];
227
+ registerHook(hooks, { cb: noop, class: A, after: [] });
228
+ registerHook(hooks, { cb: noop, class: B, after: [A] });
229
+ expect(() => registerHook(hooks, { cb: noop, class: A, after: [B] })).toThrow(/Cycle detected/);
230
+ });
231
+ test("throws on transitive cycle: A\u2192B\u2192C\u2192A", () => {
232
+ const hooks = [];
233
+ registerHook(hooks, { cb: noop, class: A, after: [] });
234
+ registerHook(hooks, { cb: noop, class: B, after: [A] });
235
+ registerHook(hooks, { cb: noop, class: C, after: [B] });
236
+ expect(() => registerHook(hooks, { cb: noop, class: A, after: [C] })).toThrow(/Cycle detected/);
237
+ });
238
+ test("allows anonymous hooks with dependencies", () => {
239
+ const hooks = [];
240
+ registerHook(hooks, { cb: noop, class: A, after: [] });
241
+ registerHook(hooks, { cb: noop, after: [A] });
242
+ expect(hooks).toHaveLength(2);
243
+ });
244
+ test("anonymous hook throws on missing dependency", () => {
245
+ const hooks = [];
246
+ expect(() => registerHook(hooks, { cb: noop, after: [A] })).toThrow(/Missing dependency.*anonymous.*A/);
247
+ });
248
+ });
249
+ describe("resolveHookDAG", () => {
250
+ test("linear chain: A \u2192 B \u2192 C", () => {
251
+ const hooks = [
252
+ { cb: noop, class: A, after: [] },
253
+ { cb: noop, class: B, after: [A] },
254
+ { cb: noop, class: C, after: [B] }
255
+ ];
256
+ const layers = resolveHookDAG(hooks);
257
+ expect(layers).toHaveLength(3);
258
+ expect(layers[0].every((h) => h.class === A)).toBe(true);
259
+ expect(layers[1].every((h) => h.class === B)).toBe(true);
260
+ expect(layers[2].every((h) => h.class === C)).toBe(true);
261
+ });
262
+ test("fan-out: A \u2192 B, A \u2192 C (B and C are parallel)", () => {
263
+ const hooks = [
264
+ { cb: noop, class: A, after: [] },
265
+ { cb: noop, class: B, after: [A] },
266
+ { cb: noop, class: C, after: [A] }
267
+ ];
268
+ const layers = resolveHookDAG(hooks);
269
+ expect(layers).toHaveLength(2);
270
+ expect(layers[0].every((h) => h.class === A)).toBe(true);
271
+ const secondClasses = layers[1].map((h) => h.class);
272
+ expect(secondClasses).toContain(B);
273
+ expect(secondClasses).toContain(C);
274
+ });
275
+ test("fan-in: B \u2192 D, C \u2192 D", () => {
276
+ const hooks = [
277
+ { cb: noop, class: B, after: [] },
278
+ { cb: noop, class: C, after: [] },
279
+ { cb: noop, class: D, after: [B, C] }
280
+ ];
281
+ const layers = resolveHookDAG(hooks);
282
+ expect(layers).toHaveLength(2);
283
+ const firstClasses = layers[0].map((h) => h.class);
284
+ expect(firstClasses).toContain(B);
285
+ expect(firstClasses).toContain(C);
286
+ expect(layers[1].every((h) => h.class === D)).toBe(true);
287
+ });
288
+ test("diamond: A \u2192 B, A \u2192 C, B \u2192 D, C \u2192 D", () => {
289
+ const hooks = [
290
+ { cb: noop, class: A, after: [] },
291
+ { cb: noop, class: B, after: [A] },
292
+ { cb: noop, class: C, after: [A] },
293
+ { cb: noop, class: D, after: [B, C] }
294
+ ];
295
+ const layers = resolveHookDAG(hooks);
296
+ expect(layers).toHaveLength(3);
297
+ expect(layers[0][0].class).toBe(A);
298
+ const midClasses = layers[1].map((h) => h.class);
299
+ expect(midClasses).toContain(B);
300
+ expect(midClasses).toContain(C);
301
+ expect(layers[2][0].class).toBe(D);
302
+ });
303
+ test("close-event inversion reverses the graph", () => {
304
+ const hooks = [
305
+ { cb: noop, class: A, after: [] },
306
+ { cb: noop, class: B, after: [A] },
307
+ { cb: noop, class: C, after: [B] }
308
+ ];
309
+ const layers = resolveHookDAG(hooks, true);
310
+ expect(layers).toHaveLength(3);
311
+ expect(layers[0].every((h) => h.class === C)).toBe(true);
312
+ expect(layers[1].every((h) => h.class === B)).toBe(true);
313
+ expect(layers[2].every((h) => h.class === A)).toBe(true);
314
+ });
315
+ test("close inversion: fan-out becomes fan-in", () => {
316
+ const hooks = [
317
+ { cb: noop, class: A, after: [] },
318
+ { cb: noop, class: B, after: [A] },
319
+ { cb: noop, class: C, after: [A] }
320
+ ];
321
+ const layers = resolveHookDAG(hooks, true);
322
+ expect(layers).toHaveLength(2);
323
+ const firstClasses = layers[0].map((h) => h.class);
324
+ expect(firstClasses).toContain(B);
325
+ expect(firstClasses).toContain(C);
326
+ expect(layers[1].every((h) => h.class === A)).toBe(true);
327
+ });
328
+ test("multiple hooks per class are all in the same layer", () => {
329
+ const cb1 = () => {
330
+ };
331
+ const cb2 = () => {
332
+ };
333
+ const hooks = [
334
+ { cb: cb1, class: A, after: [] },
335
+ { cb: cb2, class: A, after: [] },
336
+ { cb: noop, class: B, after: [A] }
337
+ ];
338
+ const layers = resolveHookDAG(hooks);
339
+ expect(layers).toHaveLength(2);
340
+ expect(layers[0]).toHaveLength(2);
341
+ expect(layers[0].every((h) => h.class === A)).toBe(true);
342
+ });
343
+ test("anonymous hooks without deps run at deepest level", () => {
344
+ const hooks = [
345
+ { cb: noop, class: A, after: [] },
346
+ { cb: noop, class: B, after: [A] },
347
+ { cb: noop, after: [] }
348
+ ];
349
+ const layers = resolveHookDAG(hooks);
350
+ expect(layers).toHaveLength(2);
351
+ const lastLayer = layers[layers.length - 1];
352
+ expect(lastLayer.some((h) => h.class === void 0)).toBe(true);
353
+ });
354
+ test("anonymous hooks with deps run after their dependencies", () => {
355
+ const hooks = [
356
+ { cb: noop, class: A, after: [] },
357
+ { cb: noop, class: B, after: [A] },
358
+ { cb: noop, class: C, after: [B] },
359
+ { cb: noop, after: [A] }
360
+ ];
361
+ const layers = resolveHookDAG(hooks);
362
+ const anonLayer = layers.findIndex((l) => l.some((h) => h.class === void 0));
363
+ const aLayer = layers.findIndex((l) => l.some((h) => h.class === A));
364
+ expect(anonLayer).toBeGreaterThan(aLayer);
365
+ });
366
+ test("empty hooks returns empty layers", () => {
367
+ expect(resolveHookDAG([])).toEqual([]);
368
+ });
369
+ });
370
+ describe("runHooks", () => {
371
+ test("same-depth siblings observably overlap", async () => {
372
+ const log = [];
373
+ const hooks = [
374
+ {
375
+ cb: async () => {
376
+ log.push("B-start");
377
+ await new Promise((r) => setTimeout(r, 20));
378
+ log.push("B-end");
379
+ },
380
+ class: B,
381
+ after: []
382
+ },
383
+ {
384
+ cb: async () => {
385
+ log.push("C-start");
386
+ await new Promise((r) => setTimeout(r, 20));
387
+ log.push("C-end");
388
+ },
389
+ class: C,
390
+ after: []
391
+ }
392
+ ];
393
+ await runHooks(hooks);
394
+ expect(log[0]).toBe("B-start");
395
+ expect(log[1]).toBe("C-start");
396
+ });
397
+ test("different depths run sequentially", async () => {
398
+ const log = [];
399
+ const hooks = [
400
+ {
401
+ cb: async () => {
402
+ log.push("A");
403
+ },
404
+ class: A,
405
+ after: []
406
+ },
407
+ {
408
+ cb: async () => {
409
+ log.push("B");
410
+ },
411
+ class: B,
412
+ after: [A]
413
+ }
414
+ ];
415
+ await runHooks(hooks);
416
+ expect(log).toEqual(["A", "B"]);
417
+ });
418
+ test("close inversion runs hooks in reverse dependency order", async () => {
419
+ const log = [];
420
+ const hooks = [
421
+ { cb: async () => log.push("A"), class: A, after: [] },
422
+ { cb: async () => log.push("B"), class: B, after: [A] },
423
+ { cb: async () => log.push("C"), class: C, after: [B] }
424
+ ];
425
+ await runHooks(hooks, void 0, true);
426
+ expect(log).toEqual(["C", "B", "A"]);
427
+ });
428
+ test("errors are routed to onError handler", async () => {
429
+ const errors = [];
430
+ const hooks = [
431
+ {
432
+ cb: () => {
433
+ throw new Error("boom");
434
+ },
435
+ class: A,
436
+ after: []
437
+ }
438
+ ];
439
+ await runHooks(hooks, (e) => {
440
+ errors.push(e);
441
+ });
442
+ expect(errors).toHaveLength(1);
443
+ expect(errors[0].message).toBe("boom");
444
+ });
445
+ test("raw promise callbacks are awaited", async () => {
446
+ const log = [];
447
+ const hooks = [
448
+ {
449
+ cb: Promise.resolve().then(() => log.push("resolved")),
450
+ class: A,
451
+ after: []
452
+ }
453
+ ];
454
+ await runHooks(hooks);
455
+ expect(log).toContain("resolved");
456
+ });
457
+ });
458
+ }
459
+ }
460
+ });
461
+
462
+ // src/instance/settings.ts
463
+ var import_valleyed, instanceSettingsPipe;
464
+ var init_settings = __esm({
465
+ "src/instance/settings.ts"() {
466
+ "use strict";
467
+ import_valleyed = require("valleyed");
468
+ instanceSettingsPipe = () => import_valleyed.v.object({
469
+ app: import_valleyed.v.object({
470
+ name: import_valleyed.v.string()
471
+ }),
472
+ log: import_valleyed.v.defaults(
473
+ import_valleyed.v.object({
474
+ level: import_valleyed.v.defaults(import_valleyed.v.in(["fatal", "error", "warn", "info", "debug", "trace", "silent"]), "info")
475
+ }),
476
+ {}
477
+ ),
478
+ utils: import_valleyed.v.defaults(
479
+ import_valleyed.v.object({
480
+ hashSaltRounds: import_valleyed.v.defaults(import_valleyed.v.number(), 10),
481
+ paginationDefaultLimit: import_valleyed.v.defaults(import_valleyed.v.number(), 100),
482
+ maxFileUploadSizeInMb: import_valleyed.v.defaults(import_valleyed.v.number(), 500)
483
+ }),
484
+ {}
485
+ )
486
+ });
487
+ }
488
+ });
489
+
490
+ // src/instance/index.ts
491
+ var import_pino, import_ulid, import_valleyed2, Instance;
492
+ var init_instance = __esm({
493
+ "src/instance/index.ts"() {
494
+ "use strict";
495
+ import_pino = __toESM(require("pino"), 1);
496
+ import_ulid = require("ulid");
497
+ import_valleyed2 = require("valleyed");
498
+ init_errors();
499
+ init_hooks();
500
+ init_settings();
501
+ Instance = class _Instance {
502
+ static #id;
503
+ static #instance;
504
+ static #hooks = {};
505
+ settings;
506
+ log;
507
+ constructor(settings) {
508
+ _Instance.#instance = this;
509
+ this.settings = Object.freeze(settings);
510
+ this.log = (0, import_pino.default)({
511
+ level: this.settings.log.level,
512
+ serializers: {
513
+ err: import_pino.default.stdSerializers.err,
514
+ error: import_pino.default.stdSerializers.err,
515
+ req: import_pino.default.stdSerializers.req,
516
+ res: import_pino.default.stdSerializers.res
517
+ },
518
+ mixin: () => ({
519
+ instanceId: _Instance.#id
520
+ })
521
+ });
522
+ _Instance.#registerOnExitHandler();
523
+ }
524
+ alias(id) {
525
+ if (_Instance.#id !== void 0) return _Instance.crash(new EquippedError("Instance already has an alias", {}));
526
+ _Instance.#id = id;
527
+ }
528
+ get id() {
529
+ if (_Instance.#id === void 0) return _Instance.crash(new EquippedError("Instance doesnt have an alias yet", {}));
530
+ return _Instance.#id;
531
+ }
532
+ getScopedName(name, key = ".") {
533
+ return [this.settings.app.name, name].join(key);
534
+ }
535
+ async start() {
536
+ try {
537
+ await runHooks(_Instance.#hooks["setup"] ?? []);
538
+ await runHooks(_Instance.#hooks["start"] ?? []);
539
+ } catch (error) {
540
+ _Instance.crash(new EquippedError(`Error starting instance`, {}, error));
541
+ }
542
+ }
543
+ static envs(envsPipe) {
544
+ const envValidity = import_valleyed2.v.validate(envsPipe, process.env);
545
+ if (!envValidity.valid) {
546
+ _Instance.crash(
547
+ new EquippedError(`Environment variables are not valid
548
+ ${envValidity.error.toString()}`, {
549
+ messages: envValidity.error.messages
550
+ })
551
+ );
552
+ }
553
+ return envValidity.value;
554
+ }
555
+ static create(settings) {
556
+ if (_Instance.#instance) return _Instance.crash(new EquippedError("Instance has been initialized already", {}));
557
+ const settingsValidity = import_valleyed2.v.validate(instanceSettingsPipe(), settings);
558
+ if (!settingsValidity.valid) {
559
+ _Instance.crash(
560
+ new EquippedError(`Settings are not valid
561
+ ${settingsValidity.error.toString()}`, {
562
+ messages: settingsValidity.error.messages
563
+ })
564
+ );
565
+ }
566
+ return new _Instance(settingsValidity.value);
567
+ }
568
+ static get() {
569
+ if (!_Instance.#instance)
570
+ return _Instance.crash(
571
+ new EquippedError("Has not been initialized. Make sure an instance has been created before you get an instance", {})
572
+ );
573
+ return _Instance.#instance;
574
+ }
575
+ static maybeGet() {
576
+ return _Instance.#instance;
577
+ }
578
+ static on(event, cb, options) {
579
+ _Instance.#hooks[event] ??= [];
580
+ const record = { cb, class: options?.class, after: options?.after ?? [] };
581
+ registerHook(_Instance.#hooks[event], record);
582
+ }
583
+ static #registerOnExitHandler() {
584
+ const signals = {
585
+ SIGHUP: 1,
586
+ SIGINT: 2,
587
+ SIGTERM: 15
588
+ };
589
+ Object.entries(signals).forEach(([signal, code]) => {
590
+ process.on(signal, async () => {
591
+ await runHooks(_Instance.#hooks["close"] ?? [], () => {
592
+ }, true);
593
+ process.exit(128 + code);
594
+ });
595
+ });
596
+ }
597
+ static resolveBeforeCrash(cb) {
598
+ const value = cb();
599
+ _Instance.on("close", async () => await value);
600
+ return value;
601
+ }
602
+ static crash(error) {
603
+ console.error(error);
604
+ process.exit(1);
605
+ }
606
+ static createId(opts) {
607
+ return `${opts?.prefix ?? ""}${(0, import_ulid.ulid)(opts?.time?.getTime())}`;
608
+ }
609
+ };
610
+ }
611
+ });
612
+
613
+ // src/utilities/authProviders.ts
614
+ var import_axios, import_jsonwebtoken, import_jwks_rsa;
615
+ var init_authProviders = __esm({
616
+ "src/utilities/authProviders.ts"() {
617
+ "use strict";
618
+ import_axios = __toESM(require("axios"), 1);
619
+ import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
620
+ import_jwks_rsa = __toESM(require("jwks-rsa"), 1);
621
+ }
622
+ });
623
+
624
+ // src/utilities/configurable.ts
625
+ function configurable(pipeFn, base) {
626
+ const pipe = pipeFn();
627
+ import_valleyed3.v.compile(pipe);
628
+ class Configurable extends base {
629
+ constructor(config, ...baseArgs) {
630
+ super(...baseArgs);
631
+ this.config = config;
632
+ }
633
+ static create(input, ...args) {
634
+ const r = import_valleyed3.v.validate(pipe, input);
635
+ if (!r.valid) throw r.error;
636
+ return new this(r.value, ...args);
637
+ }
638
+ }
639
+ return Configurable;
640
+ }
641
+ var import_valleyed3;
642
+ var init_configurable = __esm({
643
+ "src/utilities/configurable.ts"() {
644
+ "use strict";
645
+ import_valleyed3 = require("valleyed");
646
+ if (void 0) {
647
+ const { describe, test, expect, expectTypeOf } = void 0;
648
+ const { v: v6 } = null;
649
+ const testPipe = () => v6.object({
650
+ host: v6.string(),
651
+ port: v6.number()
652
+ });
653
+ class TestBase {
654
+ baseValue;
655
+ constructor() {
656
+ this.baseValue = "base";
657
+ }
658
+ }
659
+ class TestBaseWithArgs {
660
+ label;
661
+ constructor(label) {
662
+ this.label = label;
663
+ }
664
+ }
665
+ describe("configurable", () => {
666
+ test("validation runs in static create before constructor body executes", () => {
667
+ let constructorRan = false;
668
+ const Wrapped = configurable(testPipe, TestBase);
669
+ class MyClass extends Wrapped {
670
+ constructor(config) {
671
+ super(config);
672
+ constructorRan = true;
673
+ }
674
+ }
675
+ expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
676
+ expect(constructorRan).toBe(false);
677
+ MyClass.create({ host: "localhost", port: 3e3 });
678
+ expect(constructorRan).toBe(true);
679
+ });
680
+ test("constructor receives validated value", () => {
681
+ const Wrapped = configurable(testPipe, TestBase);
682
+ let receivedConfig;
683
+ class MyClass extends Wrapped {
684
+ constructor(config) {
685
+ super(config);
686
+ receivedConfig = this.config;
687
+ }
688
+ }
689
+ MyClass.create({ host: "localhost", port: 3e3 });
690
+ expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
691
+ });
692
+ test("external new is a compile error", () => {
693
+ const Wrapped = configurable(testPipe, TestBase);
694
+ class MyClass extends Wrapped {
695
+ constructor(config) {
696
+ super(config);
697
+ }
698
+ }
699
+ void (() => new MyClass({ host: "localhost", port: 3e3 }));
700
+ });
701
+ test("static Config resolves to PipeOutput<P> at the type level", () => {
702
+ const Wrapped = configurable(testPipe, TestBase);
703
+ class MyClass extends Wrapped {
704
+ constructor(config) {
705
+ super(config);
706
+ }
707
+ }
708
+ expectTypeOf().toEqualTypeOf();
709
+ expect(MyClass.create).toBeTypeOf("function");
710
+ });
711
+ test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
712
+ const Wrapped = configurable(testPipe, TestBase);
713
+ class MyClass extends Wrapped {
714
+ extra;
715
+ constructor(config, extra) {
716
+ super(config);
717
+ this.extra = extra;
718
+ }
719
+ }
720
+ const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
721
+ expect(instance.extra).toBe(42);
722
+ expectTypeOf(instance).toHaveProperty("extra");
723
+ expectTypeOf(instance.extra).toEqualTypeOf();
724
+ void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
725
+ });
726
+ test("base-args forwarding works for non-zero-arg bases", () => {
727
+ const Wrapped = configurable(testPipe, TestBaseWithArgs);
728
+ class MyClass extends Wrapped {
729
+ constructor(config, label) {
730
+ super(config, label);
731
+ }
732
+ }
733
+ const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
734
+ expect(instance.label).toBe("test-label");
735
+ });
736
+ test("config is accessible as protected readonly on instances", () => {
737
+ const Wrapped = configurable(testPipe, TestBase);
738
+ class MyClass extends Wrapped {
739
+ constructor(config) {
740
+ super(config);
741
+ }
742
+ getHost() {
743
+ return this.config.host;
744
+ }
745
+ }
746
+ const instance = MyClass.create({ host: "localhost", port: 3e3 });
747
+ expect(instance.getHost()).toBe("localhost");
748
+ });
749
+ test("accepts an abstract base class", () => {
750
+ class AbstractBase {
751
+ }
752
+ const Wrapped = configurable(testPipe, AbstractBase);
753
+ class Concrete extends Wrapped {
754
+ constructor(config) {
755
+ super(config);
756
+ }
757
+ greet() {
758
+ return `hello from ${this.config.host}`;
759
+ }
760
+ }
761
+ const instance = Concrete.create({ host: "localhost", port: 3e3 });
762
+ expect(instance.greet()).toBe("hello from localhost");
763
+ expectTypeOf(instance).toHaveProperty("config");
764
+ });
765
+ });
766
+ }
767
+ }
768
+ });
769
+
770
+ // src/utilities/hash.ts
771
+ var bcrypt;
772
+ var init_hash = __esm({
773
+ "src/utilities/hash.ts"() {
774
+ "use strict";
775
+ bcrypt = __toESM(require("bcryptjs"), 1);
776
+ }
777
+ });
778
+
779
+ // src/utilities/json.ts
780
+ var init_json = __esm({
781
+ "src/utilities/json.ts"() {
782
+ "use strict";
783
+ }
784
+ });
785
+
786
+ // src/utilities/media.ts
787
+ var import_music_metadata;
788
+ var init_media = __esm({
789
+ "src/utilities/media.ts"() {
790
+ "use strict";
791
+ import_music_metadata = require("music-metadata");
792
+ }
793
+ });
794
+
795
+ // src/utilities/random.ts
796
+ var init_random = __esm({
797
+ "src/utilities/random.ts"() {
798
+ "use strict";
799
+ }
800
+ });
801
+
802
+ // src/utilities/retry.ts
803
+ var init_retry = __esm({
804
+ "src/utilities/retry.ts"() {
805
+ "use strict";
806
+ }
807
+ });
808
+
809
+ // src/utilities/index.ts
810
+ var init_utilities = __esm({
811
+ "src/utilities/index.ts"() {
812
+ "use strict";
813
+ init_authProviders();
814
+ init_configurable();
815
+ init_hash();
816
+ init_json();
817
+ init_media();
818
+ init_random();
819
+ init_retry();
820
+ }
821
+ });
822
+
823
+ // src/errors/types/badRequestError.ts
824
+ var init_badRequestError = __esm({
825
+ "src/errors/types/badRequestError.ts"() {
826
+ "use strict";
827
+ }
828
+ });
829
+
830
+ // src/errors/types/notAuthenticatedError.ts
831
+ var init_notAuthenticatedError = __esm({
832
+ "src/errors/types/notAuthenticatedError.ts"() {
833
+ "use strict";
834
+ }
835
+ });
836
+
837
+ // src/errors/types/notAuthorizedError.ts
838
+ var init_notAuthorizedError = __esm({
839
+ "src/errors/types/notAuthorizedError.ts"() {
840
+ "use strict";
841
+ }
842
+ });
843
+
844
+ // src/errors/types/notFoundError.ts
845
+ var init_notFoundError = __esm({
846
+ "src/errors/types/notFoundError.ts"() {
847
+ "use strict";
848
+ }
849
+ });
850
+
851
+ // src/errors/types/tokenExpired.ts
852
+ var init_tokenExpired = __esm({
853
+ "src/errors/types/tokenExpired.ts"() {
854
+ "use strict";
855
+ }
856
+ });
857
+
858
+ // src/errors/types/validationError.ts
859
+ var init_validationError = __esm({
860
+ "src/errors/types/validationError.ts"() {
861
+ "use strict";
862
+ }
863
+ });
864
+
865
+ // src/errors/index.ts
866
+ var init_errors = __esm({
867
+ "src/errors/index.ts"() {
868
+ "use strict";
869
+ init_equippedError();
870
+ init_requestError();
871
+ init_badRequestError();
872
+ init_notAuthenticatedError();
873
+ init_notAuthorizedError();
874
+ init_notFoundError();
875
+ init_tokenExpired();
876
+ init_validationError();
877
+ }
878
+ });
879
+
880
+ // src/orm/errors/introspection.ts
881
+ var introspection_exports = {};
882
+ __export(introspection_exports, {
883
+ OrmIntrospectionError: () => OrmIntrospectionError
884
+ });
885
+ var OrmIntrospectionError;
886
+ var init_introspection = __esm({
887
+ "src/orm/errors/introspection.ts"() {
888
+ "use strict";
889
+ init_errors();
890
+ OrmIntrospectionError = class extends EquippedError {
891
+ adapter;
892
+ table;
893
+ constructor(opts) {
894
+ super(`Introspection failed for table '${opts.table}' on adapter '${opts.adapter}'`, { adapter: opts.adapter, table: opts.table }, opts.cause);
895
+ this.adapter = opts.adapter;
896
+ this.table = opts.table;
897
+ }
898
+ };
899
+ if (void 0) {
900
+ const { describe, test, expect } = void 0;
901
+ const { EquippedError: EquippedError2 } = null;
902
+ describe("OrmIntrospectionError", () => {
903
+ test("stores adapter, table, and cause on the instance", () => {
904
+ const cause = new Error("unknown column type");
905
+ const err = new OrmIntrospectionError({ adapter: "postgres", table: "users", cause });
906
+ expect(err.adapter).toBe("postgres");
907
+ expect(err.table).toBe("users");
908
+ expect(err.cause).toBe(cause);
909
+ });
910
+ test("message includes adapter and table", () => {
911
+ const err = new OrmIntrospectionError({ adapter: "pg", table: "posts", cause: "bad type" });
912
+ expect(err.message).toBe("Introspection failed for table 'posts' on adapter 'pg'");
913
+ });
914
+ test("instanceof EquippedError is true", () => {
915
+ const err = new OrmIntrospectionError({ adapter: "x", table: "y", cause: null });
916
+ expect(err).toBeInstanceOf(OrmIntrospectionError);
917
+ expect(err).toBeInstanceOf(EquippedError2);
918
+ });
919
+ test("context carries adapter and table", () => {
920
+ const err = new OrmIntrospectionError({ adapter: "mem", table: "items", cause: "fail" });
921
+ expect(err.context.adapter).toBe("mem");
922
+ expect(err.context.table).toBe("items");
923
+ });
924
+ test("discriminates from sibling error classes", async () => {
925
+ const { OrmMigrationError } = await null;
926
+ const { OrmValidationError: OrmValidationError2 } = await null;
927
+ const err = new OrmIntrospectionError({ adapter: "x", table: "y", cause: null });
928
+ expect(err).not.toBeInstanceOf(OrmMigrationError);
929
+ expect(err).not.toBeInstanceOf(OrmValidationError2);
930
+ });
931
+ });
932
+ }
933
+ }
934
+ });
935
+
936
+ // src/orm/adapters/postgresql/index.ts
937
+ var postgresql_exports = {};
938
+ __export(postgresql_exports, {
939
+ PostgresAdapter: () => PostgresAdapter
940
+ });
941
+ module.exports = __toCommonJS(postgresql_exports);
942
+ var import_node_async_hooks = require("async_hooks");
943
+ var import_pg = require("pg");
944
+ var import_pg_cursor = __toESM(require("pg-cursor"), 1);
945
+ var import_valleyed5 = require("valleyed");
946
+
947
+ // src/orm/filter.ts
948
+ init_errors();
949
+
950
+ // src/orm/fields.ts
951
+ var import_valleyed4 = require("valleyed");
952
+ var Field = class {
953
+ name;
954
+ path;
955
+ constructor(name, path) {
956
+ this.name = name;
957
+ this.path = path ?? [name];
958
+ }
959
+ };
960
+ function toFieldName(field) {
961
+ if (field instanceof Field) return field.path.join(".");
962
+ return field;
963
+ }
964
+ if (void 0) {
965
+ const { describe, test, expect } = void 0;
966
+ describe("Fields", () => {
967
+ describe("Field", () => {
968
+ test("stores name and defaults path to [name]", () => {
969
+ const f = new Field("email");
970
+ expect(f.name).toBe("email");
971
+ expect(f.path).toEqual(["email"]);
972
+ });
973
+ test("stores provided custom path", () => {
974
+ const f = new Field("profile", ["profile", "displayName"]);
975
+ expect(f.name).toBe("profile");
976
+ expect(f.path).toEqual(["profile", "displayName"]);
977
+ });
978
+ });
979
+ describe("toFieldName()", () => {
980
+ test("returns string input unchanged", () => {
981
+ expect(toFieldName("createdAt")).toBe("createdAt");
982
+ });
983
+ test("converts Field path into dot notation", () => {
984
+ const f = new Field("profile", ["profile", "displayName"]);
985
+ expect(toFieldName(f)).toBe("profile.displayName");
986
+ });
987
+ });
988
+ describe("SchemaField", () => {
989
+ test("extends Field and stores pipe", () => {
990
+ const mockPipe = v4.string();
991
+ const f = new SchemaField("email", mockPipe);
992
+ expect(f).toBeInstanceOf(Field);
993
+ expect(f.name).toBe("email");
994
+ expect(f.path).toEqual(["email"]);
995
+ expect(f.pipe).toBe(mockPipe);
996
+ });
997
+ test("stores lifecycle hooks when provided", () => {
998
+ const mockPipe = v4.number();
999
+ const f = new SchemaField("updatedAt", mockPipe, {
1000
+ onCreate: () => 1e3,
1001
+ onUpdate: () => 2e3
1002
+ });
1003
+ expect(f.onCreate?.()).toBe(1e3);
1004
+ expect(f.onUpdate?.()).toBe(2e3);
1005
+ });
1006
+ test("keeps lifecycle hooks undefined when omitted", () => {
1007
+ const mockPipe = v4.string();
1008
+ const f = new SchemaField("name", mockPipe);
1009
+ expect(f.onCreate).toBeUndefined();
1010
+ expect(f.onUpdate).toBeUndefined();
1011
+ });
1012
+ });
1013
+ });
1014
+ }
1015
+
1016
+ // src/orm/filter.ts
1017
+ var Filter = class {
1018
+ constructor(field, op, value) {
1019
+ this.op = op;
1020
+ this.value = value;
1021
+ this.field = toFieldName(field);
1022
+ }
1023
+ field;
1024
+ };
1025
+ var FilterGroup = class _FilterGroup {
1026
+ constructor(op = "and", children) {
1027
+ this.op = op;
1028
+ this.children = children ?? [];
1029
+ }
1030
+ children;
1031
+ #withChild(child) {
1032
+ return new _FilterGroup(this.op, [...this.children, child]);
1033
+ }
1034
+ eq(field, value) {
1035
+ return this.#withChild(new Filter(field, "eq", value));
1036
+ }
1037
+ ne(field, value) {
1038
+ return this.#withChild(new Filter(field, "ne", value));
1039
+ }
1040
+ gt(field, value) {
1041
+ return this.#withChild(new Filter(field, "gt", value));
1042
+ }
1043
+ gte(field, value) {
1044
+ return this.#withChild(new Filter(field, "gte", value));
1045
+ }
1046
+ lt(field, value) {
1047
+ return this.#withChild(new Filter(field, "lt", value));
1048
+ }
1049
+ lte(field, value) {
1050
+ return this.#withChild(new Filter(field, "lte", value));
1051
+ }
1052
+ in(field, value) {
1053
+ return this.#withChild(new Filter(field, "in", value));
1054
+ }
1055
+ notIn(field, value) {
1056
+ return this.#withChild(new Filter(field, "notIn", value));
1057
+ }
1058
+ like(field, value) {
1059
+ return this.#withChild(new Filter(field, "like", value));
1060
+ }
1061
+ exists(field) {
1062
+ return this.#withChild(new Filter(field, "exists", true));
1063
+ }
1064
+ notExists(field) {
1065
+ return this.#withChild(new Filter(field, "notExists", true));
1066
+ }
1067
+ contains(field, value) {
1068
+ return this.#withChild(new Filter(field, "contains", value));
1069
+ }
1070
+ notContains(field, value) {
1071
+ return this.#withChild(new Filter(field, "notContains", value));
1072
+ }
1073
+ and(facFns) {
1074
+ if (facFns.length === 0) throw new EquippedError("and() requires at least one filter factory", { op: "and" });
1075
+ const group = new _FilterGroup("and", facFns.map((fn) => fn(_FilterGroup.create())));
1076
+ return this.#withChild(group);
1077
+ }
1078
+ or(facFns) {
1079
+ if (facFns.length === 0) throw new EquippedError("or() requires at least one filter factory", { op: "or" });
1080
+ const group = new _FilterGroup("or", facFns.map((fn) => fn(_FilterGroup.create())));
1081
+ return this.#withChild(group);
1082
+ }
1083
+ clone() {
1084
+ return new _FilterGroup(
1085
+ this.op,
1086
+ this.children.map((c) => {
1087
+ if (c instanceof Filter) return new Filter(c.field, c.op, structuredClone(c.value));
1088
+ return c.clone();
1089
+ })
1090
+ );
1091
+ }
1092
+ static create() {
1093
+ return new _FilterGroup();
1094
+ }
1095
+ };
1096
+ if (void 0) {
1097
+ const { describe, test, expect } = void 0;
1098
+ const { v: v6 } = null;
1099
+ const { Schema } = null;
1100
+ const UserSchema = Schema.from("users").pk("id", v6.string(), () => "u1").field("email", v6.string()).field("age", v6.number()).field("name", v6.string()).field("tags", v6.array(v6.string())).build();
1101
+ describe("FilterGroup", () => {
1102
+ describe("filter-op methods", () => {
1103
+ test("eq adds a filter clause with op eq", () => {
1104
+ const g = FilterGroup.create().eq(UserSchema.fields.age, 25);
1105
+ expect(g.children).toHaveLength(1);
1106
+ const f = g.children[0];
1107
+ expect(f.field).toBe("age");
1108
+ expect(f.op).toBe("eq");
1109
+ expect(f.value).toBe(25);
1110
+ });
1111
+ test("ne adds a filter clause with op ne", () => {
1112
+ const g = FilterGroup.create().ne("name", "Bob");
1113
+ const f = g.children[0];
1114
+ expect(f.op).toBe("ne");
1115
+ expect(f.value).toBe("Bob");
1116
+ });
1117
+ test("gt/gte/lt/lte produce correct ops", () => {
1118
+ const g = FilterGroup.create().gt(UserSchema.fields.age, 10).gte(UserSchema.fields.age, 20).lt(UserSchema.fields.age, 30).lte(UserSchema.fields.age, 40);
1119
+ expect(g.children.map((c) => c.op)).toEqual(["gt", "gte", "lt", "lte"]);
1120
+ });
1121
+ test("in adds a filter clause with array value", () => {
1122
+ const g = FilterGroup.create().in(UserSchema.fields.age, [1, 2, 3]);
1123
+ const f = g.children[0];
1124
+ expect(f.op).toBe("in");
1125
+ expect(f.value).toEqual([1, 2, 3]);
1126
+ });
1127
+ test("notIn adds a filter clause with op notIn", () => {
1128
+ const g = FilterGroup.create().notIn(UserSchema.fields.age, [4, 5]);
1129
+ const f = g.children[0];
1130
+ expect(f.op).toBe("notIn");
1131
+ expect(f.value).toEqual([4, 5]);
1132
+ });
1133
+ test("like adds a filter clause with op like", () => {
1134
+ const g = FilterGroup.create().like(UserSchema.fields.email, "alice");
1135
+ const f = g.children[0];
1136
+ expect(f.op).toBe("like");
1137
+ expect(f.value).toBe("alice");
1138
+ });
1139
+ test("exists adds a filter clause with op exists", () => {
1140
+ const g = FilterGroup.create().exists(UserSchema.fields.name);
1141
+ const f = g.children[0];
1142
+ expect(f.op).toBe("exists");
1143
+ });
1144
+ test("notExists is its own op, not a boolean form of exists", () => {
1145
+ const g = FilterGroup.create().notExists(UserSchema.fields.name);
1146
+ const f = g.children[0];
1147
+ expect(f.op).toBe("notExists");
1148
+ expect(f.op).not.toBe("exists");
1149
+ });
1150
+ test("contains/notContains produce correct ops", () => {
1151
+ const g = FilterGroup.create().contains("tags", ["a"]).notContains("tags", ["b"]);
1152
+ expect(g.children[0].op).toBe("contains");
1153
+ expect(g.children[1].op).toBe("notContains");
1154
+ });
1155
+ test("all 13 filter ops produce matching Filter.op values (name-parity)", () => {
1156
+ const g = FilterGroup.create().eq("f", 1).ne("f", 1).gt("f", 1).gte("f", 1).lt("f", 1).lte("f", 1).in("f", [1]).notIn("f", [1]).like("f", "x").exists("f").notExists("f").contains("f", [1]).notContains("f", [1]);
1157
+ const ops = g.children.map((c) => c.op);
1158
+ expect(ops).toEqual([
1159
+ "eq",
1160
+ "ne",
1161
+ "gt",
1162
+ "gte",
1163
+ "lt",
1164
+ "lte",
1165
+ "in",
1166
+ "notIn",
1167
+ "like",
1168
+ "exists",
1169
+ "notExists",
1170
+ "contains",
1171
+ "notContains"
1172
+ ]);
1173
+ });
1174
+ });
1175
+ describe("raw-string field overload", () => {
1176
+ test("accepts raw string field name", () => {
1177
+ const g = FilterGroup.create().eq("age", 18);
1178
+ const f = g.children[0];
1179
+ expect(f.field).toBe("age");
1180
+ });
1181
+ test("accepts typed Field ref and extracts field name", () => {
1182
+ const g = FilterGroup.create().eq(UserSchema.fields.age, 18);
1183
+ const f = g.children[0];
1184
+ expect(f.field).toBe("age");
1185
+ });
1186
+ });
1187
+ describe("structural combinators", () => {
1188
+ test("and() creates a nested and-group", () => {
1189
+ const g = FilterGroup.create().and([
1190
+ (q) => q.eq("age", 10),
1191
+ (q) => q.eq("name", "Alice")
1192
+ ]);
1193
+ expect(g.children).toHaveLength(1);
1194
+ const nested = g.children[0];
1195
+ expect(nested.op).toBe("and");
1196
+ expect(nested.children).toHaveLength(2);
1197
+ });
1198
+ test("or() creates a nested or-group", () => {
1199
+ const g = FilterGroup.create().or([
1200
+ (q) => q.eq("name", "Alice"),
1201
+ (q) => q.eq("name", "Bob")
1202
+ ]);
1203
+ const nested = g.children[0];
1204
+ expect(nested.op).toBe("or");
1205
+ });
1206
+ });
1207
+ describe("empty-combinator rejection", () => {
1208
+ test("and([]) throws at builder time", () => {
1209
+ expect(() => FilterGroup.create().and([])).toThrow();
1210
+ });
1211
+ test("or([]) throws at builder time", () => {
1212
+ expect(() => FilterGroup.create().or([])).toThrow();
1213
+ });
1214
+ test("thrown error has stack pointing at offending call", () => {
1215
+ try {
1216
+ FilterGroup.create().and([]);
1217
+ expect.unreachable();
1218
+ } catch (e) {
1219
+ expect(e.stack).toContain("filter.ts");
1220
+ }
1221
+ });
1222
+ });
1223
+ describe("clone()", () => {
1224
+ test("deep-clones the tree", () => {
1225
+ const original = FilterGroup.create().eq("name", "Alice").and([(q) => q.gt("age", 20)]);
1226
+ const cloned = original.clone();
1227
+ expect(cloned.children).toHaveLength(2);
1228
+ expect(cloned).not.toBe(original);
1229
+ expect(cloned.children[0]).not.toBe(original.children[0]);
1230
+ });
1231
+ test("structuredClone of values \u2014 mutations on clone do not leak", () => {
1232
+ const arr = [1, 2, 3];
1233
+ const original = FilterGroup.create().in("ids", arr);
1234
+ const cloned = original.clone();
1235
+ const clonedValue = cloned.children[0].value;
1236
+ clonedValue.push(4);
1237
+ expect(original.children[0].value).toEqual([1, 2, 3]);
1238
+ expect(clonedValue).toEqual([1, 2, 3, 4]);
1239
+ });
1240
+ });
1241
+ });
1242
+ describe("clone-on-step: fan-out independence", () => {
1243
+ test(".eq() returns a new FilterGroup, not the same instance", () => {
1244
+ const base = FilterGroup.create();
1245
+ const a = base.eq("name", "Alice");
1246
+ expect(a).not.toBe(base);
1247
+ });
1248
+ test("fan-out from shared base does not pollute either branch", () => {
1249
+ const base = FilterGroup.create().eq("name", "Alice");
1250
+ const branchA = base.gt("age", 20);
1251
+ const branchB = base.lt("age", 40);
1252
+ expect(branchA.children).toHaveLength(2);
1253
+ expect(branchB.children).toHaveLength(2);
1254
+ expect(base.children).toHaveLength(1);
1255
+ expect(branchA.children[1].op).toBe("gt");
1256
+ expect(branchB.children[1].op).toBe("lt");
1257
+ });
1258
+ test(".and() returns a new FilterGroup", () => {
1259
+ const base = FilterGroup.create().eq("name", "Alice");
1260
+ const withAnd = base.and([(q) => q.gt("age", 20)]);
1261
+ expect(withAnd).not.toBe(base);
1262
+ expect(base.children).toHaveLength(1);
1263
+ expect(withAnd.children).toHaveLength(2);
1264
+ });
1265
+ test(".or() returns a new FilterGroup", () => {
1266
+ const base = FilterGroup.create().eq("name", "Alice");
1267
+ const withOr = base.or([(q) => q.gt("age", 20)]);
1268
+ expect(withOr).not.toBe(base);
1269
+ expect(base.children).toHaveLength(1);
1270
+ expect(withOr.children).toHaveLength(2);
1271
+ });
1272
+ });
1273
+ describe("assertNormalisedFilter", () => {
1274
+ test("passes for valid filter referencing known fields", () => {
1275
+ const g = FilterGroup.create().eq(UserSchema.fields.age, 25);
1276
+ expect(() => assertNormalisedFilter(UserSchema, g)).not.toThrow();
1277
+ });
1278
+ test("passes for raw string field that exists on schema", () => {
1279
+ const g = FilterGroup.create().eq("email", "test@test.com");
1280
+ expect(() => assertNormalisedFilter(UserSchema, g)).not.toThrow();
1281
+ });
1282
+ test("rejects unknown field name with OrmValidationError", () => {
1283
+ const g = FilterGroup.create().eq("unknownField", 42);
1284
+ expect(() => assertNormalisedFilter(UserSchema, g)).toThrow(OrmValidationError);
1285
+ });
1286
+ test("rejected error has kind validation", () => {
1287
+ const g = FilterGroup.create().eq("badField", 42);
1288
+ try {
1289
+ assertNormalisedFilter(UserSchema, g);
1290
+ expect.unreachable();
1291
+ } catch (e) {
1292
+ expect(e).toBeInstanceOf(OrmValidationError);
1293
+ expect(e.kind).toBe("validation");
1294
+ expect(e.failures).toHaveLength(1);
1295
+ expect(e.failures[0].field).toBe("badField");
1296
+ }
1297
+ });
1298
+ test("preserves logical field names verbatim for Field refs", () => {
1299
+ const g = FilterGroup.create().eq(UserSchema.fields.email, "a@b.com");
1300
+ const f = g.children[0];
1301
+ expect(f.field).toBe("email");
1302
+ assertNormalisedFilter(UserSchema, g);
1303
+ });
1304
+ test("preserves logical field names verbatim for raw-string overloads", () => {
1305
+ const g = FilterGroup.create().eq("age", 18);
1306
+ const f = g.children[0];
1307
+ expect(f.field).toBe("age");
1308
+ assertNormalisedFilter(UserSchema, g);
1309
+ });
1310
+ test("walks nested groups to detect unknown fields", () => {
1311
+ const g = FilterGroup.create().and([
1312
+ (q) => q.eq("name", "Alice"),
1313
+ (q) => q.or([(inner) => inner.eq("nonexistent", "val")])
1314
+ ]);
1315
+ expect(() => assertNormalisedFilter(UserSchema, g)).toThrow(OrmValidationError);
1316
+ });
1317
+ });
1318
+ describe("assertNormalisedAggregate", () => {
1319
+ const adapter = { aggregateOps: ["count"] };
1320
+ test("passes for valid count aggregate", () => {
1321
+ const spec = { aggregates: [{ fn: "count", alias: "total" }], groupBy: [] };
1322
+ expect(() => assertNormalisedAggregate(UserSchema, adapter, spec)).not.toThrow();
1323
+ });
1324
+ test("rejects empty aggregator list", () => {
1325
+ const spec = { aggregates: [], groupBy: [] };
1326
+ expect(() => assertNormalisedAggregate(UserSchema, adapter, spec)).toThrow(OrmValidationError);
1327
+ try {
1328
+ assertNormalisedAggregate(UserSchema, adapter, spec);
1329
+ expect.unreachable();
1330
+ } catch (e) {
1331
+ expect(e.kind).toBe("aggregate");
1332
+ }
1333
+ });
1334
+ test("rejects undeclared aggregate op", () => {
1335
+ const spec = { aggregates: [{ fn: "sum", alias: "total", field: "age" }], groupBy: [] };
1336
+ expect(() => assertNormalisedAggregate(UserSchema, adapter, spec)).toThrow(OrmValidationError);
1337
+ try {
1338
+ assertNormalisedAggregate(UserSchema, adapter, spec);
1339
+ expect.unreachable();
1340
+ } catch (e) {
1341
+ const err = e;
1342
+ expect(err.kind).toBe("aggregate");
1343
+ expect(err.failures[0].alias).toBe("total");
1344
+ expect(err.failures[0].cause).toContain("Undeclared");
1345
+ }
1346
+ });
1347
+ test("rejects duplicate aliases", () => {
1348
+ const spec = {
1349
+ aggregates: [
1350
+ { fn: "count", alias: "total" },
1351
+ { fn: "count", alias: "total" }
1352
+ ],
1353
+ groupBy: []
1354
+ };
1355
+ expect(() => assertNormalisedAggregate(UserSchema, adapter, spec)).toThrow(OrmValidationError);
1356
+ try {
1357
+ assertNormalisedAggregate(UserSchema, adapter, spec);
1358
+ expect.unreachable();
1359
+ } catch (e) {
1360
+ const err = e;
1361
+ expect(err.failures.some((f) => f.alias === "total")).toBe(true);
1362
+ }
1363
+ });
1364
+ test("validates where filter against schema", () => {
1365
+ const spec = {
1366
+ aggregates: [{ fn: "count", alias: "total" }],
1367
+ groupBy: [],
1368
+ where: FilterGroup.create().eq("unknownField", 42)
1369
+ };
1370
+ expect(() => assertNormalisedAggregate(UserSchema, adapter, spec)).toThrow(OrmValidationError);
1371
+ });
1372
+ test("collects multiple failures", () => {
1373
+ const spec = {
1374
+ aggregates: [
1375
+ { fn: "sum", alias: "x", field: "age" },
1376
+ { fn: "avg", alias: "x", field: "age" }
1377
+ ],
1378
+ groupBy: []
1379
+ };
1380
+ try {
1381
+ assertNormalisedAggregate(UserSchema, adapter, spec);
1382
+ expect.unreachable();
1383
+ } catch (e) {
1384
+ const err = e;
1385
+ expect(err.failures.length).toBeGreaterThanOrEqual(2);
1386
+ }
1387
+ });
1388
+ test("rejects unknown groupBy field", () => {
1389
+ const allOps = { aggregateOps: ["count", "sum"] };
1390
+ const spec = {
1391
+ aggregates: [{ fn: "count", alias: "total" }],
1392
+ groupBy: ["nonexistent"]
1393
+ };
1394
+ try {
1395
+ assertNormalisedAggregate(UserSchema, allOps, spec);
1396
+ expect.unreachable();
1397
+ } catch (e) {
1398
+ const err = e;
1399
+ expect(err.kind).toBe("aggregate");
1400
+ expect(err.failures[0].cause).toContain("groupBy");
1401
+ expect(err.failures[0].field).toBe("nonexistent");
1402
+ }
1403
+ });
1404
+ test("rejects alias colliding with groupBy field name", () => {
1405
+ const allOps = { aggregateOps: ["count"] };
1406
+ const spec = {
1407
+ aggregates: [{ fn: "count", alias: "name" }],
1408
+ groupBy: ["name"]
1409
+ };
1410
+ try {
1411
+ assertNormalisedAggregate(UserSchema, allOps, spec);
1412
+ expect.unreachable();
1413
+ } catch (e) {
1414
+ const err = e;
1415
+ expect(err.kind).toBe("aggregate");
1416
+ expect(err.failures.some((f) => String(f.cause).includes("collides"))).toBe(true);
1417
+ }
1418
+ });
1419
+ test("rejects unknown having field", () => {
1420
+ const allOps = { aggregateOps: ["count"] };
1421
+ const spec = {
1422
+ aggregates: [{ fn: "count", alias: "total" }],
1423
+ groupBy: ["name"],
1424
+ having: FilterGroup.create().gt("nonexistent", 0)
1425
+ };
1426
+ try {
1427
+ assertNormalisedAggregate(UserSchema, allOps, spec);
1428
+ expect.unreachable();
1429
+ } catch (e) {
1430
+ const err = e;
1431
+ expect(err.kind).toBe("aggregate");
1432
+ expect(err.failures[0].cause).toContain("having");
1433
+ }
1434
+ });
1435
+ test("having accepts alias and groupBy field names", () => {
1436
+ const allOps = { aggregateOps: ["count"] };
1437
+ const spec = {
1438
+ aggregates: [{ fn: "count", alias: "total" }],
1439
+ groupBy: ["name"],
1440
+ having: FilterGroup.create().gt("total", 0).eq("name", "Alice")
1441
+ };
1442
+ expect(() => assertNormalisedAggregate(UserSchema, allOps, spec)).not.toThrow();
1443
+ });
1444
+ test("passes valid groupBy with known schema fields", () => {
1445
+ const allOps = { aggregateOps: ["count"] };
1446
+ const spec = {
1447
+ aggregates: [{ fn: "count", alias: "total" }],
1448
+ groupBy: ["name", "age"]
1449
+ };
1450
+ expect(() => assertNormalisedAggregate(UserSchema, allOps, spec)).not.toThrow();
1451
+ });
1452
+ });
1453
+ }
1454
+
1455
+ // src/orm/errors/validation.ts
1456
+ init_errors();
1457
+ var OrmValidationError = class extends EquippedError {
1458
+ constructor(kind, schema, operation, failures) {
1459
+ super(`ORM validation error (${kind}) on ${schema}.${operation}`, {
1460
+ kind,
1461
+ schema,
1462
+ operation,
1463
+ failures
1464
+ });
1465
+ this.kind = kind;
1466
+ this.schema = schema;
1467
+ this.operation = operation;
1468
+ this.failures = failures;
1469
+ }
1470
+ };
1471
+ if (void 0) {
1472
+ const { describe, test, expect } = void 0;
1473
+ const { EquippedError: EquippedError2 } = null;
1474
+ describe("OrmValidationError", () => {
1475
+ test("constructs with aggregate kind", () => {
1476
+ const err = new OrmValidationError("aggregate", "orders", "aggregate", []);
1477
+ expect(err.kind).toBe("aggregate");
1478
+ expect(err.operation).toBe("aggregate");
1479
+ expect(err.message).toBe("ORM validation error (aggregate) on orders.aggregate");
1480
+ expect(err).toBeInstanceOf(OrmValidationError);
1481
+ expect(err).toBeInstanceOf(EquippedError2);
1482
+ });
1483
+ test("failure carries alias through to context", () => {
1484
+ const failures = [
1485
+ { alias: "total_price", cause: "alias collision" }
1486
+ ];
1487
+ const err = new OrmValidationError("aggregate", "orders", "aggregate", failures);
1488
+ expect(err.failures[0].alias).toBe("total_price");
1489
+ expect(err.context.failures[0].alias).toBe("total_price");
1490
+ });
1491
+ test("failure without alias still works", () => {
1492
+ const failures = [
1493
+ { field: "amount", cause: "invalid field" }
1494
+ ];
1495
+ const err = new OrmValidationError("validation", "orders", "createOne", failures);
1496
+ expect(err.failures[0].alias).toBeUndefined();
1497
+ expect(err.failures[0].field).toBe("amount");
1498
+ });
1499
+ test.each([
1500
+ "validation",
1501
+ "conflicting-ops",
1502
+ "empty-group",
1503
+ "undeclared-op",
1504
+ "upsert-filter-incompatible",
1505
+ "query-shape",
1506
+ "changes"
1507
+ ])("kind %s still works", (kind) => {
1508
+ const err = new OrmValidationError(kind, "users", "createOne", []);
1509
+ expect(err.kind).toBe(kind);
1510
+ });
1511
+ });
1512
+ }
1513
+
1514
+ // src/orm/updates.ts
1515
+ var SetOp = class {
1516
+ constructor(values) {
1517
+ this.values = values;
1518
+ }
1519
+ kind = "set";
1520
+ };
1521
+ var IncOp = class {
1522
+ constructor(field, value) {
1523
+ this.field = field;
1524
+ this.value = value;
1525
+ }
1526
+ kind = "inc";
1527
+ };
1528
+ var MulOp = class {
1529
+ constructor(field, value) {
1530
+ this.field = field;
1531
+ this.value = value;
1532
+ }
1533
+ kind = "mul";
1534
+ };
1535
+ var MinOp = class {
1536
+ constructor(field, value) {
1537
+ this.field = field;
1538
+ this.value = value;
1539
+ }
1540
+ kind = "min";
1541
+ };
1542
+ var MaxOp = class {
1543
+ constructor(field, value) {
1544
+ this.field = field;
1545
+ this.value = value;
1546
+ }
1547
+ kind = "max";
1548
+ };
1549
+ var UnsetOp = class {
1550
+ constructor(field) {
1551
+ this.field = field;
1552
+ }
1553
+ kind = "unset";
1554
+ };
1555
+ var PushOp = class {
1556
+ constructor(field, value) {
1557
+ this.field = field;
1558
+ this.value = value;
1559
+ }
1560
+ kind = "push";
1561
+ };
1562
+ var PullOp = class {
1563
+ constructor(field, value) {
1564
+ this.field = field;
1565
+ this.value = value;
1566
+ }
1567
+ kind = "pull";
1568
+ };
1569
+ var PatchOp = class {
1570
+ constructor(field, value) {
1571
+ this.field = field;
1572
+ this.value = value;
1573
+ }
1574
+ kind = "patch";
1575
+ };
1576
+ function flattenOps(ops) {
1577
+ const data = {};
1578
+ for (const op of ops) {
1579
+ if (op instanceof SetOp) Object.assign(data, op.values);
1580
+ else data[op.field] = op;
1581
+ }
1582
+ return data;
1583
+ }
1584
+ if (void 0) {
1585
+ const { describe, test, expect, expectTypeOf } = void 0;
1586
+ const { v: v6 } = null;
1587
+ const { Schema } = null;
1588
+ const TestSchema = Schema.from("test").pk("id", v6.string(), () => "x").field("name", v6.string()).field("age", v6.number()).field("score", v6.optional(v6.number())).field("tags", v6.array(v6.string())).field("meta", v6.object({ a: v6.number() })).field("createdAt", v6.number(), { onCreate: () => 1e3 }).field("updatedAt", v6.number(), { onCreate: () => 1e3, onUpdate: () => 2e3 }).build();
1589
+ describe("op classes", () => {
1590
+ test('SetOp has kind "set" and stores values', () => {
1591
+ const op = new SetOp({ name: "Alice" });
1592
+ expect(op.kind).toBe("set");
1593
+ expect(op.values).toEqual({ name: "Alice" });
1594
+ });
1595
+ test('IncOp has kind "inc" and stores field + value', () => {
1596
+ const op = new IncOp("age", 5);
1597
+ expect(op.kind).toBe("inc");
1598
+ expect(op.field).toBe("age");
1599
+ expect(op.value).toBe(5);
1600
+ });
1601
+ test('MulOp has kind "mul" and stores field + value', () => {
1602
+ const op = new MulOp("score", 3);
1603
+ expect(op.kind).toBe("mul");
1604
+ expect(op.field).toBe("score");
1605
+ expect(op.value).toBe(3);
1606
+ });
1607
+ test('MinOp has kind "min"', () => {
1608
+ expect(new MinOp("age", 10).kind).toBe("min");
1609
+ });
1610
+ test('MaxOp has kind "max"', () => {
1611
+ expect(new MaxOp("age", 99).kind).toBe("max");
1612
+ });
1613
+ test('UnsetOp has kind "unset"', () => {
1614
+ expect(new UnsetOp("score").kind).toBe("unset");
1615
+ });
1616
+ test('PushOp has kind "push"', () => {
1617
+ expect(new PushOp("tags", "x").kind).toBe("push");
1618
+ });
1619
+ test('PullOp has kind "pull"', () => {
1620
+ expect(new PullOp("tags", "x").kind).toBe("pull");
1621
+ });
1622
+ test('PatchOp has kind "patch"', () => {
1623
+ expect(new PatchOp("meta", { a: 9 }).kind).toBe("patch");
1624
+ });
1625
+ });
1626
+ describe("isUpdateOp", () => {
1627
+ test("returns true for every op class", () => {
1628
+ expect(isUpdateOp(new SetOp({}))).toBe(true);
1629
+ expect(isUpdateOp(new IncOp("f", 1))).toBe(true);
1630
+ expect(isUpdateOp(new MulOp("f", 2))).toBe(true);
1631
+ expect(isUpdateOp(new MinOp("f", 0))).toBe(true);
1632
+ expect(isUpdateOp(new MaxOp("f", 10))).toBe(true);
1633
+ expect(isUpdateOp(new UnsetOp("f"))).toBe(true);
1634
+ expect(isUpdateOp(new PushOp("f", "v"))).toBe(true);
1635
+ expect(isUpdateOp(new PullOp("f", "v"))).toBe(true);
1636
+ expect(isUpdateOp(new PatchOp("f", {}))).toBe(true);
1637
+ });
1638
+ test("returns false for non-op values", () => {
1639
+ expect(isUpdateOp("string")).toBe(false);
1640
+ expect(isUpdateOp(42)).toBe(false);
1641
+ expect(isUpdateOp(null)).toBe(false);
1642
+ expect(isUpdateOp({})).toBe(false);
1643
+ });
1644
+ });
1645
+ describe("op helper functions", () => {
1646
+ test("set() creates SetOp with values", () => {
1647
+ const op = set({ name: "Alice", age: 30 });
1648
+ expect(op).toBeInstanceOf(SetOp);
1649
+ expect(op.kind).toBe("set");
1650
+ expect(op.values).toEqual({ name: "Alice", age: 30 });
1651
+ });
1652
+ test("inc() creates IncOp from field ref", () => {
1653
+ const op = inc(TestSchema.fields.age, 5);
1654
+ expect(op).toBeInstanceOf(IncOp);
1655
+ expect(op.field).toBe("age");
1656
+ expect(op.value).toBe(5);
1657
+ });
1658
+ test("mul() creates MulOp from field ref", () => {
1659
+ const op = mul(TestSchema.fields.age, 3);
1660
+ expect(op).toBeInstanceOf(MulOp);
1661
+ expect(op.field).toBe("age");
1662
+ expect(op.value).toBe(3);
1663
+ });
1664
+ test("min() creates MinOp from field ref", () => {
1665
+ const op = min(TestSchema.fields.age, 10);
1666
+ expect(op).toBeInstanceOf(MinOp);
1667
+ expect(op.field).toBe("age");
1668
+ });
1669
+ test("max() creates MaxOp from field ref", () => {
1670
+ const op = max(TestSchema.fields.age, 99);
1671
+ expect(op).toBeInstanceOf(MaxOp);
1672
+ expect(op.field).toBe("age");
1673
+ });
1674
+ test("unset() creates UnsetOp from field ref", () => {
1675
+ const op = unset(TestSchema.fields.score);
1676
+ expect(op).toBeInstanceOf(UnsetOp);
1677
+ expect(op.field).toBe("score");
1678
+ });
1679
+ test("push() creates PushOp from field ref", () => {
1680
+ const op = push(TestSchema.fields.tags, "new-tag");
1681
+ expect(op).toBeInstanceOf(PushOp);
1682
+ expect(op.field).toBe("tags");
1683
+ expect(op.value).toBe("new-tag");
1684
+ });
1685
+ test("pull() creates PullOp from field ref", () => {
1686
+ const op = pull(TestSchema.fields.tags, "old-tag");
1687
+ expect(op).toBeInstanceOf(PullOp);
1688
+ expect(op.field).toBe("tags");
1689
+ });
1690
+ test("patch() creates PatchOp from field ref", () => {
1691
+ const op = patch(TestSchema.fields.meta, { a: 9 });
1692
+ expect(op).toBeInstanceOf(PatchOp);
1693
+ expect(op.field).toBe("meta");
1694
+ expect(op.value).toEqual({ a: 9 });
1695
+ });
1696
+ });
1697
+ describe("opTouchedFields", () => {
1698
+ test("SetOp returns all keys from values", () => {
1699
+ expect(opTouchedFields(new SetOp({ name: "A", age: 1 }))).toEqual(["name", "age"]);
1700
+ });
1701
+ test("IncOp returns the field", () => {
1702
+ expect(opTouchedFields(new IncOp("age", 1))).toEqual(["age"]);
1703
+ });
1704
+ test("UnsetOp returns the field", () => {
1705
+ expect(opTouchedFields(new UnsetOp("score"))).toEqual(["score"]);
1706
+ });
1707
+ });
1708
+ describe("type-level: field-category helpers", () => {
1709
+ test("NumericFieldOf only matches numeric fields (excludes optional numeric)", () => {
1710
+ expectTypeOf().toEqualTypeOf();
1711
+ });
1712
+ test("ComparableFieldOf matches numeric and string fields (excludes optional)", () => {
1713
+ expectTypeOf().toEqualTypeOf();
1714
+ });
1715
+ test("OptionalFieldOf only matches optional fields", () => {
1716
+ expectTypeOf().toEqualTypeOf();
1717
+ });
1718
+ test("ArrayFieldOf only matches array fields", () => {
1719
+ expectTypeOf().toEqualTypeOf();
1720
+ });
1721
+ test("ObjectFieldOf only matches object fields (not arrays)", () => {
1722
+ expectTypeOf().toEqualTypeOf();
1723
+ });
1724
+ });
1725
+ describe("type-level: inc on a string field is a TS error", () => {
1726
+ test("inc rejects non-numeric fields", () => {
1727
+ inc(TestSchema.fields.name, 1);
1728
+ });
1729
+ });
1730
+ describe("type-level: push on a non-array field is a TS error", () => {
1731
+ test("push rejects non-array fields", () => {
1732
+ push(TestSchema.fields.name, "val");
1733
+ });
1734
+ });
1735
+ describe("type-level: per-op gating via UpdateOp<S, A>", () => {
1736
+ test("undeclared ops resolve to never", async () => {
1737
+ const { OrmAdapter: OrmAdapter2 } = await null;
1738
+ class LimitedAdapter extends OrmAdapter2 {
1739
+ schemaConfigPipe = v6.object({});
1740
+ supportedFieldTypes = ["string", "number"];
1741
+ updateOps = ["set", "inc"];
1742
+ }
1743
+ expectTypeOf().toEqualTypeOf();
1744
+ });
1745
+ test("adapter with no updateOps resolves all variants to never", async () => {
1746
+ const { OrmAdapter: OrmAdapter2 } = await null;
1747
+ class NoOpsAdapter extends OrmAdapter2 {
1748
+ schemaConfigPipe = v6.object({});
1749
+ supportedFieldTypes = ["string"];
1750
+ updateOps = [];
1751
+ }
1752
+ expectTypeOf().toBeNever();
1753
+ });
1754
+ test("adapter with all updateOps includes all variants", async () => {
1755
+ const { OrmAdapter: OrmAdapter2 } = await null;
1756
+ class FullAdapter extends OrmAdapter2 {
1757
+ schemaConfigPipe = v6.object({});
1758
+ supportedFieldTypes = ["string", "number"];
1759
+ updateOps = ["set", "inc", "mul", "min", "max", "unset", "push", "pull", "patch"];
1760
+ }
1761
+ expectTypeOf().toEqualTypeOf();
1762
+ });
1763
+ });
1764
+ }
1765
+
1766
+ // src/orm/adapters/postgresql/query.ts
1767
+ function mapField(field, primaryKey) {
1768
+ if (field === "id" && primaryKey !== "id") return primaryKey;
1769
+ return field;
1770
+ }
1771
+ function compileOps(f, field, nextParam) {
1772
+ switch (f.op) {
1773
+ case "eq":
1774
+ return f.value === null ? `${field} IS NULL` : `${field} = ${nextParam(f.value)}`;
1775
+ case "ne":
1776
+ return f.value === null ? `${field} IS NOT NULL` : `${field} != ${nextParam(f.value)}`;
1777
+ case "gt":
1778
+ return `${field} > ${nextParam(f.value)}`;
1779
+ case "gte":
1780
+ return `${field} >= ${nextParam(f.value)}`;
1781
+ case "lt":
1782
+ return `${field} < ${nextParam(f.value)}`;
1783
+ case "lte":
1784
+ return `${field} <= ${nextParam(f.value)}`;
1785
+ case "in":
1786
+ return `${field} = ANY(${nextParam(f.value)})`;
1787
+ case "notIn":
1788
+ return `NOT (${field} = ANY(${nextParam(f.value)}))`;
1789
+ case "like":
1790
+ return `${field} ILIKE ${nextParam(`%${f.value}%`)}`;
1791
+ case "exists":
1792
+ return `${field} IS NOT NULL`;
1793
+ case "notExists":
1794
+ return `${field} IS NULL`;
1795
+ case "contains":
1796
+ return `${field} @> ${nextParam(JSON.stringify(f.value))}::jsonb`;
1797
+ case "notContains":
1798
+ return `NOT (${field} @> ${nextParam(JSON.stringify(f.value))}::jsonb)`;
1799
+ default:
1800
+ return `${field} = ${nextParam(f.value)}`;
1801
+ }
1802
+ }
1803
+ function compileFilter(f, primaryKey, nextParam) {
1804
+ return compileOps(f, `"${mapField(f.field, primaryKey)}"`, nextParam);
1805
+ }
1806
+ function compileChildren(group, compileLeaf) {
1807
+ return group.children.map((c) => compileChild(c, compileLeaf)).filter((c) => c !== null);
1808
+ }
1809
+ function compileGroup(group, compileLeaf) {
1810
+ const parts = compileChildren(group, compileLeaf);
1811
+ if (parts.length === 0) return null;
1812
+ if (parts.length === 1) return parts[0];
1813
+ return `(${parts.join(group.op === "or" ? " OR " : " AND ")})`;
1814
+ }
1815
+ function compileChild(child, compileLeaf) {
1816
+ if (child instanceof Filter) return compileLeaf(child);
1817
+ if (child instanceof FilterGroup) return compileGroup(child, compileLeaf);
1818
+ return null;
1819
+ }
1820
+ function compilePgFilter(group, primaryKey, startIndex = 1) {
1821
+ const params = [];
1822
+ let paramIndex = startIndex;
1823
+ function nextParam(value) {
1824
+ params.push(value);
1825
+ return `$${paramIndex++}`;
1826
+ }
1827
+ const leaf = (f) => compileFilter(f, primaryKey, nextParam);
1828
+ const whereParts = compileChildren(group, leaf);
1829
+ const whereClause = whereParts.length > 0 ? `WHERE ${whereParts.join(" AND ")}` : "";
1830
+ return { whereClause, params, nextParamIndex: paramIndex };
1831
+ }
1832
+ function buildSetParts(data, startIndex) {
1833
+ const params = [];
1834
+ let paramIndex = startIndex;
1835
+ const setParts = Object.entries(data).map(([key, value]) => {
1836
+ const col = `"${key}"`;
1837
+ if (value instanceof IncOp) {
1838
+ params.push(value.value);
1839
+ return `${col} = ${col} + $${paramIndex++}`;
1840
+ }
1841
+ if (value instanceof MulOp) {
1842
+ params.push(value.value);
1843
+ return `${col} = ${col} * $${paramIndex++}`;
1844
+ }
1845
+ if (value instanceof MinOp) {
1846
+ params.push(value.value);
1847
+ return `${col} = LEAST(${col}, $${paramIndex++})`;
1848
+ }
1849
+ if (value instanceof MaxOp) {
1850
+ params.push(value.value);
1851
+ return `${col} = GREATEST(${col}, $${paramIndex++})`;
1852
+ }
1853
+ if (value instanceof UnsetOp) {
1854
+ return `${col} = NULL`;
1855
+ }
1856
+ if (value instanceof PushOp) {
1857
+ params.push(JSON.stringify(value.value));
1858
+ return `${col} = ${col} || jsonb_build_array($${paramIndex++}::jsonb)`;
1859
+ }
1860
+ if (value instanceof PullOp) {
1861
+ params.push(JSON.stringify(value.value));
1862
+ return `${col} = (SELECT COALESCE(jsonb_agg(e), '[]'::jsonb) FROM jsonb_array_elements(${col}) e WHERE e <> $${paramIndex++}::jsonb)`;
1863
+ }
1864
+ if (value instanceof PatchOp) {
1865
+ params.push(JSON.stringify(value.value));
1866
+ return `${col} = ${col} || $${paramIndex++}::jsonb`;
1867
+ }
1868
+ params.push(value);
1869
+ return `${col} = $${paramIndex++}`;
1870
+ });
1871
+ return { setParts, params, nextParamIndex: paramIndex };
1872
+ }
1873
+ function buildSelectQuery(group, options, tableName, primaryKey) {
1874
+ const { whereClause, params, nextParamIndex } = compilePgFilter(group, primaryKey);
1875
+ let i = nextParamIndex;
1876
+ const orderParts = (options?.orderBy ?? []).map((o) => `"${mapField(o.field, primaryKey)}" ${o.direction.toUpperCase()}`);
1877
+ const orderClause = orderParts.length > 0 ? `ORDER BY ${orderParts.join(", ")}` : "";
1878
+ let limitClause = "";
1879
+ if (options?.limit != null) {
1880
+ params.push(options.limit);
1881
+ limitClause = `LIMIT $${i++}`;
1882
+ }
1883
+ let offsetClause = "";
1884
+ if (options?.offset != null) {
1885
+ params.push(options.offset);
1886
+ offsetClause = `OFFSET $${i++}`;
1887
+ }
1888
+ const selectClause = options?.select?.length ? options.select.map((f) => `"${mapField(f, primaryKey)}"`).join(", ") : "*";
1889
+ const sql = `SELECT ${selectClause} FROM "${tableName}" ${whereClause} ${orderClause} ${limitClause} ${offsetClause}`.trim().replace(/\s+/g, " ");
1890
+ return { sql, params };
1891
+ }
1892
+ function buildCountQuery(group, tableName, primaryKey) {
1893
+ const { whereClause, params } = compilePgFilter(group, primaryKey);
1894
+ const sql = `SELECT COUNT(*) as count FROM "${tableName}" ${whereClause}`.trim().replace(/\s+/g, " ");
1895
+ return { sql, params };
1896
+ }
1897
+ function buildCreateQuery(tableName, data) {
1898
+ const keys = Object.keys(data);
1899
+ const params = Object.values(data);
1900
+ const placeholders = keys.map((_, i) => `$${i + 1}`);
1901
+ const columns = keys.map((k) => `"${k}"`).join(", ");
1902
+ const sql = `INSERT INTO "${tableName}" (${columns}) VALUES (${placeholders.join(", ")}) RETURNING *`;
1903
+ return { sql, params };
1904
+ }
1905
+ function buildUpdateQuery(group, tableName, primaryKey, data) {
1906
+ const { setParts, params: setParams, nextParamIndex } = buildSetParts(data, 1);
1907
+ const { whereClause, params: whereParams } = compilePgFilter(group, primaryKey, nextParamIndex);
1908
+ const params = [...setParams, ...whereParams];
1909
+ const sql = `UPDATE "${tableName}" SET ${setParts.join(", ")} ${whereClause} RETURNING *`.trim().replace(/\s+/g, " ");
1910
+ return { sql, params };
1911
+ }
1912
+ function buildPkUpdateQuery(tableName, primaryKey, pk, data) {
1913
+ const { setParts, params: setParams, nextParamIndex } = buildSetParts(data, 1);
1914
+ setParams.push(pk);
1915
+ const sql = `UPDATE "${tableName}" SET ${setParts.join(", ")} WHERE "${primaryKey}" = $${nextParamIndex} RETURNING *`.replace(
1916
+ /\s+/g,
1917
+ " "
1918
+ );
1919
+ return { sql, params: setParams };
1920
+ }
1921
+ function buildDeleteQuery(group, tableName, primaryKey) {
1922
+ const { whereClause, params } = compilePgFilter(group, primaryKey);
1923
+ const sql = `DELETE FROM "${tableName}" ${whereClause} RETURNING *`.trim().replace(/\s+/g, " ");
1924
+ return { sql, params };
1925
+ }
1926
+ function buildUpsertQuery(tableName, conflictColumn, primaryKey, create, data) {
1927
+ const columns = Object.keys(create);
1928
+ const createParams = Object.values(create);
1929
+ const placeholders = columns.map((_, i) => `$${i + 1}`);
1930
+ const pgConflictCol = mapField(conflictColumn, primaryKey);
1931
+ let setClause;
1932
+ const allParams = [...createParams];
1933
+ if (Object.keys(data).length > 0) {
1934
+ const { setParts, params: setParams } = buildSetParts(data, columns.length + 1);
1935
+ setClause = setParts.join(", ");
1936
+ allParams.push(...setParams);
1937
+ } else {
1938
+ setClause = `"${pgConflictCol}" = EXCLUDED."${pgConflictCol}"`;
1939
+ }
1940
+ const sql = `INSERT INTO "${tableName}" (${columns.map((c) => `"${c}"`).join(", ")}) VALUES (${placeholders.join(", ")}) ON CONFLICT ("${pgConflictCol}") DO UPDATE SET ${setClause} RETURNING *`.replace(
1941
+ /\s+/g,
1942
+ " "
1943
+ );
1944
+ return { sql, params: allParams };
1945
+ }
1946
+ function extractUpsertConflictColumn(filter, schemaName) {
1947
+ if (filter.children.length === 1 && filter.children[0] instanceof Filter && filter.children[0].op === "eq") {
1948
+ return filter.children[0].field;
1949
+ }
1950
+ let description;
1951
+ if (filter.children.length === 0) {
1952
+ description = "empty filter";
1953
+ } else if (filter.children.length === 1) {
1954
+ const child = filter.children[0];
1955
+ const opDesc = child instanceof Filter ? child.op : "group";
1956
+ description = `single non-eq filter (op: ${opDesc})`;
1957
+ } else {
1958
+ description = `${filter.children.length} filter clauses`;
1959
+ }
1960
+ throw new OrmValidationError("upsert-filter-incompatible", schemaName, "upsertOne", [
1961
+ {
1962
+ cause: `PostgreSQL upsert requires a single eq filter on a UNIQUE-indexed column; received ${description}`
1963
+ }
1964
+ ]);
1965
+ }
1966
+ function aggFnToSql(fn, field, primaryKey) {
1967
+ if (fn === "count") return "COUNT(*)";
1968
+ const col = `"${mapField(field, primaryKey)}"`;
1969
+ switch (fn) {
1970
+ case "countDistinct":
1971
+ return `COUNT(DISTINCT ${col})`;
1972
+ case "sum":
1973
+ return `SUM(${col})`;
1974
+ case "avg":
1975
+ return `AVG(${col})`;
1976
+ case "min":
1977
+ return `MIN(${col})`;
1978
+ case "max":
1979
+ return `MAX(${col})`;
1980
+ }
1981
+ }
1982
+ function resolveHavingField(field, primaryKey, aliasToExpr, groupBySet) {
1983
+ if (aliasToExpr.has(field)) return aliasToExpr.get(field);
1984
+ if (groupBySet.has(field)) return `"${mapField(field, primaryKey)}"`;
1985
+ return `"${field}"`;
1986
+ }
1987
+ function buildAggregateQuery(spec, tableName, primaryKey) {
1988
+ const params = [];
1989
+ let paramIndex = 1;
1990
+ function nextParam(value) {
1991
+ params.push(value);
1992
+ return `$${paramIndex++}`;
1993
+ }
1994
+ const selectParts = [];
1995
+ const aliasToExpr = /* @__PURE__ */ new Map();
1996
+ for (const agg of spec.aggregates) {
1997
+ const expr = aggFnToSql(agg.fn, agg.field, primaryKey);
1998
+ aliasToExpr.set(agg.alias, expr);
1999
+ selectParts.push(`${expr} AS "${agg.alias}"`);
2000
+ }
2001
+ const groupByFields = [];
2002
+ for (const f of spec.groupBy) {
2003
+ const col = `"${mapField(f, primaryKey)}"`;
2004
+ groupByFields.push(col);
2005
+ selectParts.push(`${col} AS "${f}"`);
2006
+ }
2007
+ let whereClause = "";
2008
+ if (spec.where) {
2009
+ const whereLeaf = (f) => compileFilter(f, primaryKey, nextParam);
2010
+ const whereParts = compileChildren(spec.where, whereLeaf);
2011
+ if (whereParts.length > 0) whereClause = `WHERE ${whereParts.join(" AND ")}`;
2012
+ }
2013
+ const groupByClause = groupByFields.length > 0 ? `GROUP BY ${groupByFields.join(", ")}` : "";
2014
+ let havingClause = "";
2015
+ if (spec.having) {
2016
+ const groupBySet = new Set(spec.groupBy);
2017
+ const havingLeaf = (f) => compileOps(f, resolveHavingField(f.field, primaryKey, aliasToExpr, groupBySet), nextParam);
2018
+ const havingParts = compileChildren(spec.having, havingLeaf);
2019
+ if (havingParts.length > 0) havingClause = `HAVING ${havingParts.join(" AND ")}`;
2020
+ }
2021
+ const sql = `SELECT ${selectParts.join(", ")} FROM "${tableName}" ${whereClause} ${groupByClause} ${havingClause}`.trim().replace(/\s+/g, " ");
2022
+ return { sql, params };
2023
+ }
2024
+ if (void 0) {
2025
+ const { describe, test, expect } = void 0;
2026
+ const { FilterGroup: FilterGroup2 } = null;
2027
+ const { OrderBy } = null;
2028
+ const { IncOp: IncOp2, MulOp: MulOp2, MinOp: MinOp2, MaxOp: MaxOp2, UnsetOp: UnsetOp2, PushOp: PushOp2, PullOp: PullOp2, PatchOp: PatchOp2, SetOp: SetOp2, flattenOps: flattenOps2 } = null;
2029
+ const { OrmValidationError: OrmValidationError2 } = null;
2030
+ describe("compilePgFilter", () => {
2031
+ test("empty filter group compiles to empty WHERE clause", () => {
2032
+ const group = FilterGroup2.create();
2033
+ const { sql } = buildSelectQuery(group, void 0, "users", "id");
2034
+ expect(sql).toBe('SELECT * FROM "users"');
2035
+ });
2036
+ test("single eq filter compiles to WHERE field = $1", () => {
2037
+ const group = FilterGroup2.create().eq("name", "Alice");
2038
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2039
+ expect(sql).toBe('SELECT * FROM "users" WHERE "name" = $1');
2040
+ expect(params).toEqual(["Alice"]);
2041
+ });
2042
+ test("eq with null compiles to IS NULL", () => {
2043
+ const group = FilterGroup2.create().eq("name", null);
2044
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2045
+ expect(sql).toBe('SELECT * FROM "users" WHERE "name" IS NULL');
2046
+ expect(params).toEqual([]);
2047
+ });
2048
+ test("ne compiles to != (or IS NOT NULL for null)", () => {
2049
+ const group = FilterGroup2.create().ne("age", 5);
2050
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2051
+ expect(sql).toBe('SELECT * FROM "users" WHERE "age" != $1');
2052
+ expect(params).toEqual([5]);
2053
+ const nullGroup = FilterGroup2.create().ne("age", null);
2054
+ const { sql: nullSql } = buildSelectQuery(nullGroup, void 0, "users", "id");
2055
+ expect(nullSql).toBe('SELECT * FROM "users" WHERE "age" IS NOT NULL');
2056
+ });
2057
+ test("gt, gte, lt, lte compile to >, >=, <, <=", () => {
2058
+ expect(buildSelectQuery(FilterGroup2.create().gt("age", 10), void 0, "t", "id").sql).toContain('"age" > $1');
2059
+ expect(buildSelectQuery(FilterGroup2.create().gte("age", 20), void 0, "t", "id").sql).toContain('"age" >= $1');
2060
+ expect(buildSelectQuery(FilterGroup2.create().lt("age", 30), void 0, "t", "id").sql).toContain('"age" < $1');
2061
+ expect(buildSelectQuery(FilterGroup2.create().lte("age", 40), void 0, "t", "id").sql).toContain('"age" <= $1');
2062
+ });
2063
+ test("in compiles to = ANY($N)", () => {
2064
+ const group = FilterGroup2.create().in("status", ["a", "b"]);
2065
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2066
+ expect(sql).toContain('"status" = ANY($1)');
2067
+ expect(params).toEqual([["a", "b"]]);
2068
+ });
2069
+ test("notIn compiles to NOT (field = ANY($N)) \u2014 canonical name notIn", () => {
2070
+ const group = FilterGroup2.create().notIn("status", ["x", "y"]);
2071
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2072
+ expect(sql).toContain('NOT ("status" = ANY($1))');
2073
+ expect(params).toEqual([["x", "y"]]);
2074
+ });
2075
+ test("like compiles to ILIKE with % wrapping", () => {
2076
+ const group = FilterGroup2.create().like("name", "ali");
2077
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2078
+ expect(sql).toContain('"name" ILIKE $1');
2079
+ expect(params).toEqual(["%ali%"]);
2080
+ });
2081
+ test("exists compiles to IS NOT NULL (own op, not boolean form)", () => {
2082
+ const group = FilterGroup2.create().exists("val");
2083
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2084
+ expect(sql).toContain('"val" IS NOT NULL');
2085
+ expect(params).toEqual([]);
2086
+ });
2087
+ test("notExists is its own op \u2014 compiles to IS NULL", () => {
2088
+ const group = FilterGroup2.create().notExists("val");
2089
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2090
+ expect(sql).toContain('"val" IS NULL');
2091
+ expect(params).toEqual([]);
2092
+ });
2093
+ test("contains compiles to @> jsonb", () => {
2094
+ const group = FilterGroup2.create().contains("tags", ["a", "b"]);
2095
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2096
+ expect(sql).toContain('"tags" @> $1::jsonb');
2097
+ expect(params).toEqual([JSON.stringify(["a", "b"])]);
2098
+ });
2099
+ test("notContains compiles to NOT (@> jsonb)", () => {
2100
+ const group = FilterGroup2.create().notContains("tags", ["x"]);
2101
+ const { sql, params } = buildSelectQuery(group, void 0, "users", "id");
2102
+ expect(sql).toContain('NOT ("tags" @> $1::jsonb)');
2103
+ expect(params).toEqual([JSON.stringify(["x"])]);
2104
+ });
2105
+ test("multiple clauses produce AND-joined WHERE", () => {
2106
+ const group = FilterGroup2.create().eq("a", 1).gt("b", 2);
2107
+ const { sql } = buildSelectQuery(group, void 0, "t", "id");
2108
+ expect(sql).toContain('WHERE "a" = $1 AND "b" > $2');
2109
+ });
2110
+ test("nested and/or groups compile correctly", () => {
2111
+ const group = FilterGroup2.create().and([
2112
+ (q) => q.eq("a", 1),
2113
+ (q) => q.or([(g) => g.eq("b", 2), (g) => g.eq("c", 3)])
2114
+ ]);
2115
+ const { sql, params } = buildSelectQuery(group, void 0, "t", "id");
2116
+ expect(sql).toContain('("a" = $1 AND ("b" = $2 OR "c" = $3))');
2117
+ expect(params).toEqual([1, 2, 3]);
2118
+ });
2119
+ test("maps id field to primaryKey when primaryKey differs", () => {
2120
+ const group = FilterGroup2.create().eq("id", "abc");
2121
+ const { sql } = buildSelectQuery(group, void 0, "users", "user_id");
2122
+ expect(sql).toContain('"user_id" = $1');
2123
+ });
2124
+ });
2125
+ describe("buildSelectQuery", () => {
2126
+ test("options: sort, limit, offset, select", () => {
2127
+ const group = FilterGroup2.create().eq("active", true);
2128
+ const options = {
2129
+ orderBy: [new OrderBy("name", "asc"), new OrderBy("age", "desc")],
2130
+ limit: 10,
2131
+ offset: 5,
2132
+ select: ["name", "age"]
2133
+ };
2134
+ const { sql, params } = buildSelectQuery(group, options, "users", "id");
2135
+ expect(sql).toContain('SELECT "name", "age"');
2136
+ expect(sql).toContain('ORDER BY "name" ASC, "age" DESC');
2137
+ expect(sql).toContain("LIMIT $2");
2138
+ expect(sql).toContain("OFFSET $3");
2139
+ expect(params).toEqual([true, 10, 5]);
2140
+ });
2141
+ test("undefined options returns basic SELECT *", () => {
2142
+ const group = FilterGroup2.create().eq("x", 1);
2143
+ const { sql } = buildSelectQuery(group, void 0, "users", "id");
2144
+ expect(sql).toBe('SELECT * FROM "users" WHERE "x" = $1');
2145
+ });
2146
+ });
2147
+ describe("buildCreateQuery", () => {
2148
+ test("produces INSERT with RETURNING *", () => {
2149
+ const { sql, params } = buildCreateQuery("users", { name: "Alice", age: 30 });
2150
+ expect(sql).toBe('INSERT INTO "users" ("name", "age") VALUES ($1, $2) RETURNING *');
2151
+ expect(params).toEqual(["Alice", 30]);
2152
+ });
2153
+ });
2154
+ describe("buildUpdateQuery", () => {
2155
+ test("plain values produce SET col = $N", () => {
2156
+ const group = FilterGroup2.create().eq("id", "u1");
2157
+ const { sql, params } = buildUpdateQuery(group, "users", "id", { name: "Bob", age: 25 });
2158
+ expect(sql).toBe('UPDATE "users" SET "name" = $1, "age" = $2 WHERE "id" = $3 RETURNING *');
2159
+ expect(params).toEqual(["Bob", 25, "u1"]);
2160
+ });
2161
+ test("IncOp produces col = col + $N", () => {
2162
+ const group = FilterGroup2.create().eq("id", "u1");
2163
+ const { sql, params } = buildUpdateQuery(group, "users", "id", { count: new IncOp2("count", 5) });
2164
+ expect(sql).toContain('"count" = "count" + $1');
2165
+ expect(params[0]).toBe(5);
2166
+ });
2167
+ test("MulOp produces col = col * $N", () => {
2168
+ const group = FilterGroup2.create().eq("id", "u1");
2169
+ const { sql } = buildUpdateQuery(group, "users", "id", { score: new MulOp2("score", 2) });
2170
+ expect(sql).toContain('"score" = "score" * $1');
2171
+ });
2172
+ test("MinOp/MaxOp produce LEAST/GREATEST", () => {
2173
+ const group = FilterGroup2.create().eq("id", "u1");
2174
+ const { sql } = buildUpdateQuery(group, "users", "id", {
2175
+ lo: new MinOp2("lo", 1),
2176
+ hi: new MaxOp2("hi", 99)
2177
+ });
2178
+ expect(sql).toContain('LEAST("lo", $1)');
2179
+ expect(sql).toContain('GREATEST("hi", $2)');
2180
+ });
2181
+ test("UnsetOp produces col = NULL", () => {
2182
+ const group = FilterGroup2.create().eq("id", "u1");
2183
+ const { sql } = buildUpdateQuery(group, "users", "id", { old: new UnsetOp2("old") });
2184
+ expect(sql).toContain('"old" = NULL');
2185
+ });
2186
+ test("PushOp produces jsonb array append", () => {
2187
+ const group = FilterGroup2.create().eq("id", "u1");
2188
+ const { sql } = buildUpdateQuery(group, "users", "id", { tags: new PushOp2("tags", "new") });
2189
+ expect(sql).toContain("jsonb_build_array($1::jsonb)");
2190
+ });
2191
+ test("PullOp produces jsonb array removal", () => {
2192
+ const group = FilterGroup2.create().eq("id", "u1");
2193
+ const { sql } = buildUpdateQuery(group, "users", "id", { tags: new PullOp2("tags", "old") });
2194
+ expect(sql).toContain("jsonb_array_elements");
2195
+ });
2196
+ test("PatchOp produces jsonb merge", () => {
2197
+ const group = FilterGroup2.create().eq("id", "u1");
2198
+ const { sql } = buildUpdateQuery(group, "users", "id", { meta: new PatchOp2("meta", { a: 1 }) });
2199
+ expect(sql).toContain("|| $1::jsonb");
2200
+ });
2201
+ });
2202
+ describe("buildPkUpdateQuery", () => {
2203
+ test("builds UPDATE with PK WHERE clause", () => {
2204
+ const { sql, params } = buildPkUpdateQuery("users", "id", "u1", { name: "Bob" });
2205
+ expect(sql).toBe('UPDATE "users" SET "name" = $1 WHERE "id" = $2 RETURNING *');
2206
+ expect(params).toEqual(["Bob", "u1"]);
2207
+ });
2208
+ test("handles ops in PK update", () => {
2209
+ const { sql, params } = buildPkUpdateQuery("users", "id", "u1", { count: new IncOp2("count", 3) });
2210
+ expect(sql).toContain('"count" = "count" + $1');
2211
+ expect(sql).toContain('WHERE "id" = $2');
2212
+ expect(params).toEqual([3, "u1"]);
2213
+ });
2214
+ });
2215
+ describe("buildDeleteQuery", () => {
2216
+ test("produces DELETE with RETURNING *", () => {
2217
+ const group = FilterGroup2.create().eq("id", "u1");
2218
+ const { sql, params } = buildDeleteQuery(group, "users", "id");
2219
+ expect(sql).toBe('DELETE FROM "users" WHERE "id" = $1 RETURNING *');
2220
+ expect(params).toEqual(["u1"]);
2221
+ });
2222
+ });
2223
+ describe("buildUpsertQuery", () => {
2224
+ test("produces INSERT ON CONFLICT with SET parts from data", () => {
2225
+ const data = flattenOps2([new SetOp2({ name: "Updated" })]);
2226
+ const { sql, params } = buildUpsertQuery("users", "email", "id", { id: "u1", email: "a@b.com", name: "Alice" }, data);
2227
+ expect(sql).toContain('INSERT INTO "users"');
2228
+ expect(sql).toContain('ON CONFLICT ("email") DO UPDATE SET');
2229
+ expect(sql).toContain('"name" = $4');
2230
+ expect(sql).toContain("RETURNING *");
2231
+ expect(params).toEqual(["u1", "a@b.com", "Alice", "Updated"]);
2232
+ });
2233
+ test("empty data produces no-op SET on conflict column", () => {
2234
+ const { sql, params } = buildUpsertQuery("users", "email", "id", { id: "u1", email: "a@b.com" }, {});
2235
+ expect(sql).toContain('ON CONFLICT ("email") DO UPDATE SET "email" = EXCLUDED."email"');
2236
+ expect(params).toEqual(["u1", "a@b.com"]);
2237
+ });
2238
+ test("maps conflict column via mapField when primaryKey differs", () => {
2239
+ const { sql } = buildUpsertQuery("users", "id", "user_id", { user_id: "u1", name: "A" }, {});
2240
+ expect(sql).toContain('ON CONFLICT ("user_id")');
2241
+ });
2242
+ test("handles ops in upsert SET clause", () => {
2243
+ const data = flattenOps2([new IncOp2("views", 1)]);
2244
+ const { sql, params } = buildUpsertQuery("posts", "slug", "id", { id: "p1", slug: "hello", views: 0 }, data);
2245
+ expect(sql).toContain('"views" = "views" + $4');
2246
+ expect(params).toEqual(["p1", "hello", 0, 1]);
2247
+ });
2248
+ });
2249
+ describe("extractUpsertConflictColumn", () => {
2250
+ test("extracts field from single eq filter", () => {
2251
+ const filter = FilterGroup2.create().eq("email", "a@b.com");
2252
+ expect(extractUpsertConflictColumn(filter, "users")).toBe("email");
2253
+ });
2254
+ test("throws upsert-filter-incompatible on empty filter", () => {
2255
+ const filter = FilterGroup2.create();
2256
+ expect(() => extractUpsertConflictColumn(filter, "users")).toThrow(OrmValidationError2);
2257
+ try {
2258
+ extractUpsertConflictColumn(filter, "users");
2259
+ } catch (e) {
2260
+ const err = e;
2261
+ expect(err.kind).toBe("upsert-filter-incompatible");
2262
+ expect(err.schema).toBe("users");
2263
+ expect(err.operation).toBe("upsertOne");
2264
+ expect(err.failures[0].cause).toContain("empty filter");
2265
+ }
2266
+ });
2267
+ test("throws upsert-filter-incompatible on multiple filters", () => {
2268
+ const filter = FilterGroup2.create().eq("a", 1).eq("b", 2);
2269
+ expect(() => extractUpsertConflictColumn(filter, "users")).toThrow(OrmValidationError2);
2270
+ try {
2271
+ extractUpsertConflictColumn(filter, "users");
2272
+ } catch (e) {
2273
+ const err = e;
2274
+ expect(err.kind).toBe("upsert-filter-incompatible");
2275
+ expect(err.failures[0].cause).toContain("2 filter clauses");
2276
+ }
2277
+ });
2278
+ test("throws upsert-filter-incompatible on non-eq filter", () => {
2279
+ const filter = FilterGroup2.create().gt("age", 10);
2280
+ expect(() => extractUpsertConflictColumn(filter, "users")).toThrow(OrmValidationError2);
2281
+ try {
2282
+ extractUpsertConflictColumn(filter, "users");
2283
+ } catch (e) {
2284
+ const err = e;
2285
+ expect(err.kind).toBe("upsert-filter-incompatible");
2286
+ expect(err.failures[0].cause).toContain("non-eq filter");
2287
+ }
2288
+ });
2289
+ test("throws with clear message naming received filter shape", () => {
2290
+ const filter = FilterGroup2.create().in("status", ["a", "b"]);
2291
+ try {
2292
+ extractUpsertConflictColumn(filter, "test");
2293
+ expect.unreachable();
2294
+ } catch (e) {
2295
+ const err = e;
2296
+ expect(err.kind).toBe("upsert-filter-incompatible");
2297
+ expect(err.failures[0].cause).toContain("single eq filter");
2298
+ expect(err.failures[0].cause).toContain("UNIQUE-indexed column");
2299
+ }
2300
+ });
2301
+ });
2302
+ describe("buildAggregateQuery", () => {
2303
+ test("bare count produces SELECT COUNT(*) AS alias", () => {
2304
+ const { sql, params } = buildAggregateQuery(
2305
+ { aggregates: [{ fn: "count", alias: "total" }], groupBy: [] },
2306
+ "orders",
2307
+ "id"
2308
+ );
2309
+ expect(sql).toBe('SELECT COUNT(*) AS "total" FROM "orders"');
2310
+ expect(params).toEqual([]);
2311
+ });
2312
+ test("multi-aggregator produces all functions", () => {
2313
+ const { sql, params } = buildAggregateQuery(
2314
+ {
2315
+ aggregates: [
2316
+ { fn: "count", alias: "cnt" },
2317
+ { fn: "sum", field: "amount", alias: "revenue" },
2318
+ { fn: "avg", field: "amount", alias: "avgAmt" },
2319
+ { fn: "min", field: "amount", alias: "lo" },
2320
+ { fn: "max", field: "amount", alias: "hi" }
2321
+ ],
2322
+ groupBy: []
2323
+ },
2324
+ "orders",
2325
+ "id"
2326
+ );
2327
+ expect(sql).toBe(
2328
+ 'SELECT COUNT(*) AS "cnt", SUM("amount") AS "revenue", AVG("amount") AS "avgAmt", MIN("amount") AS "lo", MAX("amount") AS "hi" FROM "orders"'
2329
+ );
2330
+ expect(params).toEqual([]);
2331
+ });
2332
+ test("countDistinct produces COUNT(DISTINCT col)", () => {
2333
+ const { sql } = buildAggregateQuery(
2334
+ { aggregates: [{ fn: "countDistinct", field: "category", alias: "unique" }], groupBy: [] },
2335
+ "items",
2336
+ "id"
2337
+ );
2338
+ expect(sql).toBe('SELECT COUNT(DISTINCT "category") AS "unique" FROM "items"');
2339
+ });
2340
+ test("single-column groupBy produces GROUP BY clause", () => {
2341
+ const { sql } = buildAggregateQuery(
2342
+ {
2343
+ aggregates: [{ fn: "count", alias: "cnt" }],
2344
+ groupBy: ["region"]
2345
+ },
2346
+ "orders",
2347
+ "id"
2348
+ );
2349
+ expect(sql).toBe('SELECT COUNT(*) AS "cnt", "region" AS "region" FROM "orders" GROUP BY "region"');
2350
+ });
2351
+ test("multi-column groupBy produces all GROUP BY columns", () => {
2352
+ const { sql } = buildAggregateQuery(
2353
+ {
2354
+ aggregates: [{ fn: "count", alias: "cnt" }],
2355
+ groupBy: ["region", "product"]
2356
+ },
2357
+ "orders",
2358
+ "id"
2359
+ );
2360
+ expect(sql).toBe(
2361
+ 'SELECT COUNT(*) AS "cnt", "region" AS "region", "product" AS "product" FROM "orders" GROUP BY "region", "product"'
2362
+ );
2363
+ });
2364
+ test("where-only produces WHERE clause with params", () => {
2365
+ const where = FilterGroup2.create().eq("status", "active");
2366
+ const { sql, params } = buildAggregateQuery(
2367
+ { aggregates: [{ fn: "count", alias: "total" }], groupBy: [], where },
2368
+ "orders",
2369
+ "id"
2370
+ );
2371
+ expect(sql).toBe('SELECT COUNT(*) AS "total" FROM "orders" WHERE "status" = $1');
2372
+ expect(params).toEqual(["active"]);
2373
+ });
2374
+ test("having-only filters on aggregate alias via repeated expression", () => {
2375
+ const having = FilterGroup2.create().gt("total", 10);
2376
+ const { sql, params } = buildAggregateQuery(
2377
+ {
2378
+ aggregates: [{ fn: "count", alias: "total" }],
2379
+ groupBy: ["region"],
2380
+ having
2381
+ },
2382
+ "orders",
2383
+ "id"
2384
+ );
2385
+ expect(sql).toBe(
2386
+ 'SELECT COUNT(*) AS "total", "region" AS "region" FROM "orders" GROUP BY "region" HAVING COUNT(*) > $1'
2387
+ );
2388
+ expect(params).toEqual([10]);
2389
+ });
2390
+ test("where + having both produce correct param ordering", () => {
2391
+ const where = FilterGroup2.create().eq("status", "active");
2392
+ const having = FilterGroup2.create().gte("revenue", 1e3);
2393
+ const { sql, params } = buildAggregateQuery(
2394
+ {
2395
+ aggregates: [{ fn: "sum", field: "amount", alias: "revenue" }],
2396
+ groupBy: ["region"],
2397
+ where,
2398
+ having
2399
+ },
2400
+ "orders",
2401
+ "id"
2402
+ );
2403
+ expect(sql).toBe(
2404
+ 'SELECT SUM("amount") AS "revenue", "region" AS "region" FROM "orders" WHERE "status" = $1 GROUP BY "region" HAVING SUM("amount") >= $2'
2405
+ );
2406
+ expect(params).toEqual(["active", 1e3]);
2407
+ });
2408
+ test("having on groupBy field uses column name directly", () => {
2409
+ const having = FilterGroup2.create().eq("region", "US");
2410
+ const { sql, params } = buildAggregateQuery(
2411
+ {
2412
+ aggregates: [{ fn: "count", alias: "cnt" }],
2413
+ groupBy: ["region"],
2414
+ having
2415
+ },
2416
+ "orders",
2417
+ "id"
2418
+ );
2419
+ expect(sql).toBe(
2420
+ 'SELECT COUNT(*) AS "cnt", "region" AS "region" FROM "orders" GROUP BY "region" HAVING "region" = $1'
2421
+ );
2422
+ expect(params).toEqual(["US"]);
2423
+ });
2424
+ test("field-name mapping: id maps to primaryKey when primaryKey differs", () => {
2425
+ const { sql } = buildAggregateQuery(
2426
+ {
2427
+ aggregates: [{ fn: "countDistinct", field: "id", alias: "uniqueIds" }],
2428
+ groupBy: []
2429
+ },
2430
+ "users",
2431
+ "user_id"
2432
+ );
2433
+ expect(sql).toBe('SELECT COUNT(DISTINCT "user_id") AS "uniqueIds" FROM "users"');
2434
+ });
2435
+ test("groupBy with id field maps to primaryKey", () => {
2436
+ const { sql } = buildAggregateQuery(
2437
+ {
2438
+ aggregates: [{ fn: "count", alias: "cnt" }],
2439
+ groupBy: ["id"]
2440
+ },
2441
+ "users",
2442
+ "user_id"
2443
+ );
2444
+ expect(sql).toContain('GROUP BY "user_id"');
2445
+ expect(sql).toContain('"user_id" AS "id"');
2446
+ });
2447
+ test("complex having with AND/OR groups", () => {
2448
+ const having = FilterGroup2.create().and([
2449
+ (q) => q.gt("cnt", 5),
2450
+ (q) => q.or([(g) => g.eq("region", "US"), (g) => g.eq("region", "EU")])
2451
+ ]);
2452
+ const { sql, params } = buildAggregateQuery(
2453
+ {
2454
+ aggregates: [{ fn: "count", alias: "cnt" }],
2455
+ groupBy: ["region"],
2456
+ having
2457
+ },
2458
+ "orders",
2459
+ "id"
2460
+ );
2461
+ expect(sql).toContain('HAVING (COUNT(*) > $1 AND ("region" = $2 OR "region" = $3))');
2462
+ expect(params).toEqual([5, "US", "EU"]);
2463
+ });
2464
+ });
2465
+ }
2466
+
2467
+ // src/orm/adapters/postgresql/index.ts
2468
+ init_errors();
2469
+ init_utilities();
2470
+
2471
+ // src/orm/orm-adapter.ts
2472
+ init_errors();
2473
+ init_instance();
2474
+ var OrmAdapter = class {
2475
+ queryableOps = [];
2476
+ updateOps = [];
2477
+ aggregateOps = [];
2478
+ supportedFieldTypes = [];
2479
+ onFatalError(err) {
2480
+ const wrapped = err instanceof EquippedError ? err : new EquippedError("OrmAdapter fatal error", {}, err);
2481
+ Instance.crash(wrapped);
2482
+ }
2483
+ constructor() {
2484
+ const self = this;
2485
+ if (typeof self.connect === "function") {
2486
+ Instance.on("start", () => self.connect(), { class: this.constructor });
2487
+ }
2488
+ if (typeof self.disconnect === "function") {
2489
+ Instance.on("close", () => self.disconnect(), { class: this.constructor });
2490
+ }
2491
+ }
2492
+ use(schema, config) {
2493
+ const self = this;
2494
+ const emptyIterator = async function* () {
2495
+ };
2496
+ const use = {
2497
+ findMany: (filter, opts) => self.findMany?.(schema, config, filter, opts) ?? Promise.resolve([]),
2498
+ iterateMany: (filter, opts) => self.iterateMany?.(schema, config, filter, opts) ?? emptyIterator(),
2499
+ findOne: async (filter) => {
2500
+ const rows = await use.findMany(filter, { limit: 1 });
2501
+ return rows[0] ?? null;
2502
+ },
2503
+ count: (filter) => self.count?.(schema, config, filter) ?? Promise.reject(new Error("count not implemented")),
2504
+ createOne: async (d) => {
2505
+ const rows = await use.createMany([d]);
2506
+ return rows[0];
2507
+ },
2508
+ createMany: (d) => self.createMany?.(schema, config, d) ?? Promise.resolve([]),
2509
+ updateMany: (filter, d) => self.updateMany?.(schema, config, filter, d) ?? Promise.resolve([]),
2510
+ updateOne: async (filter, d) => {
2511
+ const match = await use.findOne(filter);
2512
+ if (!match) return null;
2513
+ const pk = schema.pkField.name;
2514
+ const pkFilter = FilterGroup.create().eq(pk, match[pk]);
2515
+ const rows = await use.updateMany(pkFilter, d);
2516
+ return rows[0] ?? null;
2517
+ },
2518
+ upsertOne: (filter, create, ops) => self.upsertOne?.(schema, config, filter, create, ops) ?? Promise.reject(new Error("upsertOne not implemented")),
2519
+ deleteOne: async (filter) => {
2520
+ const row = await use.findOne(filter);
2521
+ if (!row) return null;
2522
+ const pk = schema.pkField.name;
2523
+ if (self.deleteByPk) {
2524
+ await self.deleteByPk(schema, config, row[pk]);
2525
+ } else if (self.deleteMany) {
2526
+ const pkFilter = FilterGroup.create().eq(pk, row[pk]);
2527
+ await self.deleteMany(schema, config, pkFilter);
2528
+ }
2529
+ return row;
2530
+ },
2531
+ deleteMany: (filter) => self.deleteMany?.(schema, config, filter) ?? Promise.resolve([]),
2532
+ raw: (...args) => self.raw?.(schema, config, ...args) ?? Promise.reject(new Error("raw not implemented")),
2533
+ aggregate: (spec) => self.aggregate?.(schema, config, spec) ?? Promise.reject(new Error("aggregate not implemented")),
2534
+ aggregateOps: self.aggregateOps ?? []
2535
+ };
2536
+ return use;
2537
+ }
2538
+ };
2539
+ if (void 0) {
2540
+ const { describe, test, expect, vi } = void 0;
2541
+ const { v: v6 } = null;
2542
+ describe("OrmAdapter", () => {
2543
+ test("subclass with connect/disconnect auto-registers Instance hooks", async () => {
2544
+ const { Instance: Inst } = await null;
2545
+ const onSpy = vi.spyOn(Inst, "on").mockImplementation(() => {
2546
+ });
2547
+ class TestAdapter extends OrmAdapter {
2548
+ schemaConfigPipe = v6.object({ table: v6.string() });
2549
+ supportedFieldTypes = ["string"];
2550
+ async connect() {
2551
+ }
2552
+ async disconnect() {
2553
+ }
2554
+ }
2555
+ new TestAdapter();
2556
+ expect(onSpy).toHaveBeenCalledWith("start", expect.any(Function), expect.objectContaining({ class: TestAdapter }));
2557
+ expect(onSpy).toHaveBeenCalledWith("close", expect.any(Function), expect.objectContaining({ class: TestAdapter }));
2558
+ onSpy.mockRestore();
2559
+ });
2560
+ test("subclass without connect/disconnect does not register hooks", async () => {
2561
+ const { Instance: Inst } = await null;
2562
+ const onSpy = vi.spyOn(Inst, "on").mockImplementation(() => {
2563
+ });
2564
+ class MinimalAdapter extends OrmAdapter {
2565
+ schemaConfigPipe = v6.object({ table: v6.string() });
2566
+ }
2567
+ new MinimalAdapter();
2568
+ expect(onSpy).not.toHaveBeenCalled();
2569
+ onSpy.mockRestore();
2570
+ });
2571
+ test("capability declarations default to empty arrays", async () => {
2572
+ const { Instance: Inst } = await null;
2573
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2574
+ });
2575
+ class DefaultAdapter extends OrmAdapter {
2576
+ schemaConfigPipe = v6.object({ table: v6.string() });
2577
+ }
2578
+ const adapter = new DefaultAdapter();
2579
+ expect(adapter.queryableOps).toEqual([]);
2580
+ expect(adapter.updateOps).toEqual([]);
2581
+ expect(adapter.aggregateOps).toEqual([]);
2582
+ expect(adapter.supportedFieldTypes).toEqual([]);
2583
+ vi.restoreAllMocks();
2584
+ });
2585
+ test("onFatalError wraps non-EquippedError and calls Instance.crash", async () => {
2586
+ const { Instance: Inst } = await null;
2587
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2588
+ });
2589
+ const crashSpy = vi.spyOn(Inst, "crash").mockImplementation((() => {
2590
+ throw new Error("crash");
2591
+ }));
2592
+ class FatalAdapter extends OrmAdapter {
2593
+ schemaConfigPipe = v6.object({ table: v6.string() });
2594
+ triggerFatal() {
2595
+ this.onFatalError(new Error("something broke"));
2596
+ }
2597
+ }
2598
+ const adapter = new FatalAdapter();
2599
+ expect(() => adapter.triggerFatal()).toThrow("crash");
2600
+ expect(crashSpy).toHaveBeenCalled();
2601
+ vi.restoreAllMocks();
2602
+ });
2603
+ test("onFatalError passes through EquippedError directly", async () => {
2604
+ const { Instance: Inst } = await null;
2605
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2606
+ });
2607
+ let crashedWith;
2608
+ vi.spyOn(Inst, "crash").mockImplementation(((err) => {
2609
+ crashedWith = err;
2610
+ throw err;
2611
+ }));
2612
+ class FatalAdapter extends OrmAdapter {
2613
+ schemaConfigPipe = v6.object({ table: v6.string() });
2614
+ triggerFatal() {
2615
+ this.onFatalError(new EquippedError("equipped error", { detail: "test" }));
2616
+ }
2617
+ }
2618
+ const adapter = new FatalAdapter();
2619
+ expect(() => adapter.triggerFatal()).toThrow();
2620
+ expect(crashedWith).toBeInstanceOf(EquippedError);
2621
+ expect(crashedWith.message).toBe("equipped error");
2622
+ vi.restoreAllMocks();
2623
+ });
2624
+ test("use() creates OrmUse bridge that delegates to flat methods", async () => {
2625
+ const { Instance: Inst } = await null;
2626
+ const { Schema } = await null;
2627
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2628
+ });
2629
+ class BridgeAdapter extends OrmAdapter {
2630
+ schemaConfigPipe = v6.object({ table: v6.string() });
2631
+ supportedFieldTypes = ["string"];
2632
+ queryableOps = ["eq"];
2633
+ async findMany(_s, _c, _f, _o) {
2634
+ return [{ id: "found" }];
2635
+ }
2636
+ async count(_s, _c, _f) {
2637
+ return 1;
2638
+ }
2639
+ async *iterateMany(_s, _c, _f, _o) {
2640
+ yield { id: "iterated" };
2641
+ }
2642
+ async createMany(_s, _c, data) {
2643
+ return data;
2644
+ }
2645
+ }
2646
+ const TestSchema = Schema.from("bridge_test").pk("id", v6.string(), () => "x").build();
2647
+ const adapter = new BridgeAdapter();
2648
+ const ormUse = adapter.use(TestSchema, { table: "bridge_test" });
2649
+ const rows = await ormUse.findMany(FilterGroup.create());
2650
+ expect(rows).toEqual([{ id: "found" }]);
2651
+ await expect(ormUse.count(FilterGroup.create())).resolves.toBe(1);
2652
+ const iterated = [];
2653
+ for await (const row of ormUse.iterateMany(FilterGroup.create())) iterated.push(row);
2654
+ expect(iterated).toEqual([{ id: "iterated" }]);
2655
+ const created = await ormUse.createOne({ id: "new" });
2656
+ expect(created).toEqual({ id: "new" });
2657
+ vi.restoreAllMocks();
2658
+ });
2659
+ test("use() bridge delegates updateMany to flat method", async () => {
2660
+ const { Instance: Inst } = await null;
2661
+ const { Schema } = await null;
2662
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2663
+ });
2664
+ class UpdateAdapter extends OrmAdapter {
2665
+ schemaConfigPipe = v6.object({ table: v6.string() });
2666
+ supportedFieldTypes = ["string", "number"];
2667
+ updateOps = ["set"];
2668
+ async findMany(_s, _c, _f) {
2669
+ return [{ id: "u1", name: "old" }];
2670
+ }
2671
+ async updateMany(_s, _c, _f, data) {
2672
+ return [{ id: "u1", ...data }];
2673
+ }
2674
+ }
2675
+ const TestSchema = Schema.from("upd_test").pk("id", v6.string(), () => "x").field("name", v6.string()).build();
2676
+ const adapter = new UpdateAdapter();
2677
+ const ormUse = adapter.use(TestSchema, { table: "upd_test" });
2678
+ const updated = await ormUse.updateOne(FilterGroup.create().eq("id", "u1"), { name: "new" });
2679
+ expect(updated).not.toBeNull();
2680
+ expect(updated.name).toBe("new");
2681
+ vi.restoreAllMocks();
2682
+ });
2683
+ test("use().iterateMany does not fall back to findMany when adapter omits iterateMany", async () => {
2684
+ const { Instance: Inst } = await null;
2685
+ const { Schema } = await null;
2686
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2687
+ });
2688
+ let findManyCalls = 0;
2689
+ class FindOnlyAdapter extends OrmAdapter {
2690
+ schemaConfigPipe = v6.object({ table: v6.string() });
2691
+ supportedFieldTypes = ["string"];
2692
+ async findMany() {
2693
+ findManyCalls += 1;
2694
+ return [{ id: "found" }];
2695
+ }
2696
+ }
2697
+ const TestSchema = Schema.from("iter_no_fallback").pk("id", v6.string(), () => "x").build();
2698
+ const adapter = new FindOnlyAdapter();
2699
+ const rows = [];
2700
+ for await (const row of adapter.use(TestSchema, { table: "iter_no_fallback" }).iterateMany(FilterGroup.create())) rows.push(row);
2701
+ expect(rows).toEqual([]);
2702
+ expect(findManyCalls).toBe(0);
2703
+ vi.restoreAllMocks();
2704
+ });
2705
+ test("use() bridge delegates deleteByPk via deleteOne", async () => {
2706
+ const { Instance: Inst } = await null;
2707
+ const { Schema } = await null;
2708
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2709
+ });
2710
+ let deletedPk = null;
2711
+ class DeleteAdapter extends OrmAdapter {
2712
+ schemaConfigPipe = v6.object({ table: v6.string() });
2713
+ supportedFieldTypes = ["string"];
2714
+ async findMany(_s, _c, _f) {
2715
+ return [{ id: "d1" }];
2716
+ }
2717
+ async deleteByPk(_s, _c, pk) {
2718
+ deletedPk = pk;
2719
+ return { id: String(pk) };
2720
+ }
2721
+ }
2722
+ const TestSchema = Schema.from("del_test").pk("id", v6.string(), () => "x").build();
2723
+ const adapter = new DeleteAdapter();
2724
+ const ormUse = adapter.use(TestSchema, { table: "del_test" });
2725
+ const deleted = await ormUse.deleteOne(FilterGroup.create().eq("id", "d1"));
2726
+ expect(deleted).toEqual({ id: "d1" });
2727
+ expect(deletedPk).toBe("d1");
2728
+ vi.restoreAllMocks();
2729
+ });
2730
+ test("use() bridge delegates session to flat method", async () => {
2731
+ const { Instance: Inst } = await null;
2732
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2733
+ });
2734
+ let sessionRan = false;
2735
+ class SessionAdapter extends OrmAdapter {
2736
+ schemaConfigPipe = v6.object({ table: v6.string() });
2737
+ async session(fn) {
2738
+ sessionRan = true;
2739
+ return fn();
2740
+ }
2741
+ }
2742
+ const adapter = new SessionAdapter();
2743
+ const result = await adapter.session(async () => 42);
2744
+ expect(result).toBe(42);
2745
+ expect(sessionRan).toBe(true);
2746
+ vi.restoreAllMocks();
2747
+ });
2748
+ test("type-level: subclass method override enforces canonical signature", async () => {
2749
+ const { Instance: Inst } = await null;
2750
+ vi.spyOn(Inst, "on").mockImplementation(() => {
2751
+ });
2752
+ class CorrectAdapter extends OrmAdapter {
2753
+ schemaConfigPipe = v6.object({ table: v6.string() });
2754
+ async findByPk(_s, _c, _pk) {
2755
+ return null;
2756
+ }
2757
+ async createMany(_s, _c, _d) {
2758
+ return [];
2759
+ }
2760
+ async raw(_s, _c, ..._args) {
2761
+ return null;
2762
+ }
2763
+ }
2764
+ const adapter = new CorrectAdapter();
2765
+ expect(adapter.findByPk).toBeTypeOf("function");
2766
+ expect(adapter.createMany).toBeTypeOf("function");
2767
+ expect(adapter.raw).toBeTypeOf("function");
2768
+ vi.restoreAllMocks();
2769
+ });
2770
+ });
2771
+ }
2772
+
2773
+ // src/orm/adapters/postgresql/index.ts
2774
+ var postgresqlConnectionPipe = () => import_valleyed5.v.object({
2775
+ host: import_valleyed5.v.string(),
2776
+ port: import_valleyed5.v.number(),
2777
+ username: import_valleyed5.v.string(),
2778
+ password: import_valleyed5.v.string(),
2779
+ database: import_valleyed5.v.string(),
2780
+ ssl: import_valleyed5.v.defaults(import_valleyed5.v.boolean(), false)
2781
+ });
2782
+ var TRACKER_TABLE = "equipped_migrations";
2783
+ var ADVISORY_LOCK_KEY = 3735928559;
2784
+ var DEFAULT_CURSOR_BATCH_SIZE = 1e3;
2785
+ var FIELD_TYPE_TO_PG = {
2786
+ string: "text",
2787
+ number: "double precision",
2788
+ boolean: "boolean",
2789
+ date: "timestamptz",
2790
+ null: "text",
2791
+ object: "jsonb",
2792
+ array: "jsonb"
2793
+ };
2794
+ var PG_TO_FIELD_TYPE = {
2795
+ text: "string",
2796
+ "character varying": "string",
2797
+ varchar: "string",
2798
+ char: "string",
2799
+ character: "string",
2800
+ "double precision": "number",
2801
+ real: "number",
2802
+ integer: "number",
2803
+ smallint: "number",
2804
+ numeric: "number",
2805
+ decimal: "number",
2806
+ boolean: "boolean",
2807
+ "timestamp with time zone": "date",
2808
+ "timestamp without time zone": "date",
2809
+ timestamptz: "date",
2810
+ timestamp: "date",
2811
+ date: "date",
2812
+ jsonb: "object",
2813
+ json: "object"
2814
+ };
2815
+ var PostgresAdapter = class extends configurable(postgresqlConnectionPipe, OrmAdapter) {
2816
+ schemaConfigPipe = import_valleyed5.v.object({
2817
+ schema: import_valleyed5.v.optional(import_valleyed5.v.string()),
2818
+ table: import_valleyed5.v.string()
2819
+ });
2820
+ supportedFieldTypes = ["string", "number", "boolean", "null", "object", "array", "date"];
2821
+ queryableOps = [
2822
+ "eq",
2823
+ "ne",
2824
+ "gt",
2825
+ "gte",
2826
+ "lt",
2827
+ "lte",
2828
+ "in",
2829
+ "notIn",
2830
+ "like",
2831
+ "exists",
2832
+ "notExists",
2833
+ "contains",
2834
+ "notContains"
2835
+ ];
2836
+ updateOps = ["set", "inc", "mul", "min", "max", "unset", "push", "pull", "patch"];
2837
+ aggregateOps = ["count", "countDistinct", "sum", "avg", "min", "max"];
2838
+ pool;
2839
+ #sessionStore = new import_node_async_hooks.AsyncLocalStorage();
2840
+ constructor(config) {
2841
+ super(config);
2842
+ this.pool = new import_pg.Pool({
2843
+ host: config.host,
2844
+ port: config.port,
2845
+ user: config.username,
2846
+ password: config.password,
2847
+ database: config.database,
2848
+ ssl: config.ssl ? { rejectUnauthorized: false } : false
2849
+ });
2850
+ }
2851
+ #getClient() {
2852
+ return this.#sessionStore.getStore() ?? this.pool;
2853
+ }
2854
+ #resolveTableName(config) {
2855
+ return config.schema && config.schema !== "public" ? `${config.schema}.${config.table}` : config.table;
2856
+ }
2857
+ async connect() {
2858
+ }
2859
+ async disconnect() {
2860
+ try {
2861
+ await this.pool.end();
2862
+ } catch (error) {
2863
+ throw new EquippedError("Failed to disconnect PostgreSQL pool", { adapter: "postgresql" }, error);
2864
+ }
2865
+ }
2866
+ async findByPk(schema, config, pk) {
2867
+ const c = config;
2868
+ try {
2869
+ const tableName = this.#resolveTableName(c);
2870
+ const pkName = schema.pkField.name;
2871
+ const result = await this.#getClient().query(`SELECT * FROM "${tableName}" WHERE "${pkName}" = $1`, [pk]);
2872
+ return result.rows[0] ?? null;
2873
+ } catch (error) {
2874
+ throw new EquippedError("PostgreSQL findByPk failed", { adapter: "postgresql", operation: "findByPk", table: c.table }, error);
2875
+ }
2876
+ }
2877
+ async createMany(_schema, config, data) {
2878
+ const c = config;
2879
+ try {
2880
+ const tableName = this.#resolveTableName(c);
2881
+ const client = this.#getClient();
2882
+ const results = [];
2883
+ for (const doc of data) {
2884
+ const { sql, params } = buildCreateQuery(tableName, doc);
2885
+ const result = await client.query(sql, params);
2886
+ results.push(result.rows[0]);
2887
+ }
2888
+ return results;
2889
+ } catch (error) {
2890
+ throw new EquippedError(
2891
+ "PostgreSQL createMany failed",
2892
+ { adapter: "postgresql", operation: "createMany", table: c.table },
2893
+ error
2894
+ );
2895
+ }
2896
+ }
2897
+ async updateByPk(schema, config, pk, ops) {
2898
+ const c = config;
2899
+ try {
2900
+ const tableName = this.#resolveTableName(c);
2901
+ const pkName = schema.pkField.name;
2902
+ const data = flattenOps(ops);
2903
+ if (Object.keys(data).length === 0) {
2904
+ const result2 = await this.#getClient().query(`SELECT * FROM "${tableName}" WHERE "${pkName}" = $1`, [pk]);
2905
+ return result2.rows[0] ?? null;
2906
+ }
2907
+ const { sql, params } = buildPkUpdateQuery(tableName, pkName, pk, data);
2908
+ const result = await this.#getClient().query(sql, params);
2909
+ return result.rows[0] ?? null;
2910
+ } catch (error) {
2911
+ throw new EquippedError(
2912
+ "PostgreSQL updateByPk failed",
2913
+ { adapter: "postgresql", operation: "updateByPk", table: c.table },
2914
+ error
2915
+ );
2916
+ }
2917
+ }
2918
+ async deleteByPk(schema, config, pk) {
2919
+ const c = config;
2920
+ try {
2921
+ const tableName = this.#resolveTableName(c);
2922
+ const pkName = schema.pkField.name;
2923
+ const result = await this.#getClient().query(`DELETE FROM "${tableName}" WHERE "${pkName}" = $1 RETURNING *`, [pk]);
2924
+ return result.rows[0] ?? null;
2925
+ } catch (error) {
2926
+ throw new EquippedError(
2927
+ "PostgreSQL deleteByPk failed",
2928
+ { adapter: "postgresql", operation: "deleteByPk", table: c.table },
2929
+ error
2930
+ );
2931
+ }
2932
+ }
2933
+ async raw(_schema, config, command, params = []) {
2934
+ const c = config;
2935
+ try {
2936
+ const result = await this.#getClient().query(command, params);
2937
+ return result;
2938
+ } catch (error) {
2939
+ if (error instanceof EquippedError) throw error;
2940
+ throw new EquippedError("PostgreSQL raw failed", { adapter: "postgresql", operation: "raw", table: c.table }, error);
2941
+ }
2942
+ }
2943
+ async findMany(schema, config, filter, options) {
2944
+ const c = config;
2945
+ try {
2946
+ const tableName = this.#resolveTableName(c);
2947
+ const { sql, params } = buildSelectQuery(filter, options, tableName, schema.pkField.name);
2948
+ const result = await this.#getClient().query(sql, params);
2949
+ return result.rows;
2950
+ } catch (error) {
2951
+ throw new EquippedError("PostgreSQL findMany failed", { adapter: "postgresql", operation: "findMany", table: c.table }, error);
2952
+ }
2953
+ }
2954
+ async count(schema, config, filter) {
2955
+ const c = config;
2956
+ try {
2957
+ const tableName = this.#resolveTableName(c);
2958
+ const { sql, params } = buildCountQuery(filter, tableName, schema.pkField.name);
2959
+ const result = await this.#getClient().query(sql, params);
2960
+ return Number(result.rows[0]?.count ?? 0);
2961
+ } catch (error) {
2962
+ throw new EquippedError("PostgreSQL count failed", { adapter: "postgresql", operation: "count", table: c.table }, error);
2963
+ }
2964
+ }
2965
+ async *iterateMany(schema, config, filter, options) {
2966
+ const c = config;
2967
+ let client;
2968
+ let releaseClient = false;
2969
+ let cursor;
2970
+ try {
2971
+ const tableName = this.#resolveTableName(c);
2972
+ const { sql, params } = buildSelectQuery(filter, options, tableName, schema.pkField.name);
2973
+ const sessionClient = this.#sessionStore.getStore();
2974
+ if (sessionClient) {
2975
+ client = sessionClient;
2976
+ } else {
2977
+ client = await this.pool.connect();
2978
+ releaseClient = true;
2979
+ }
2980
+ cursor = client.query(new import_pg_cursor.default(sql, params));
2981
+ const batchSize = options?.batchSize ?? DEFAULT_CURSOR_BATCH_SIZE;
2982
+ while (true) {
2983
+ const rows = await cursor.read(batchSize);
2984
+ if (rows.length === 0) break;
2985
+ for (const row of rows) yield row;
2986
+ }
2987
+ } catch (error) {
2988
+ throw new EquippedError("PostgreSQL iterateMany failed", { adapter: "postgresql", operation: "iterateMany", table: c.table }, error);
2989
+ } finally {
2990
+ try {
2991
+ await cursor?.close();
2992
+ } finally {
2993
+ if (releaseClient) client?.release();
2994
+ }
2995
+ }
2996
+ }
2997
+ async updateMany(schema, config, filter, data) {
2998
+ const c = config;
2999
+ try {
3000
+ const tableName = this.#resolveTableName(c);
3001
+ const { sql, params } = buildUpdateQuery(filter, tableName, schema.pkField.name, data);
3002
+ const result = await this.#getClient().query(sql, params);
3003
+ return result.rows;
3004
+ } catch (error) {
3005
+ throw new EquippedError(
3006
+ "PostgreSQL updateMany failed",
3007
+ { adapter: "postgresql", operation: "updateMany", table: c.table },
3008
+ error
3009
+ );
3010
+ }
3011
+ }
3012
+ async deleteMany(schema, config, filter) {
3013
+ const c = config;
3014
+ try {
3015
+ const tableName = this.#resolveTableName(c);
3016
+ const { sql, params } = buildDeleteQuery(filter, tableName, schema.pkField.name);
3017
+ const result = await this.#getClient().query(sql, params);
3018
+ return result.rows;
3019
+ } catch (error) {
3020
+ throw new EquippedError(
3021
+ "PostgreSQL deleteMany failed",
3022
+ { adapter: "postgresql", operation: "deleteMany", table: c.table },
3023
+ error
3024
+ );
3025
+ }
3026
+ }
3027
+ async upsertOne(schema, config, filter, create, ops) {
3028
+ const c = config;
3029
+ try {
3030
+ const tableName = this.#resolveTableName(c);
3031
+ const conflictColumn = extractUpsertConflictColumn(filter, schema.name);
3032
+ const data = ops.length > 0 ? flattenOps(ops) : {};
3033
+ const { sql, params } = buildUpsertQuery(tableName, conflictColumn, schema.pkField.name, create, data);
3034
+ const result = await this.#getClient().query(sql, params);
3035
+ return result.rows[0];
3036
+ } catch (error) {
3037
+ if (error instanceof EquippedError) throw error;
3038
+ throw new EquippedError("PostgreSQL upsertOne failed", { adapter: "postgresql", operation: "upsertOne", table: c.table }, error);
3039
+ }
3040
+ }
3041
+ async aggregate(schema, config, spec) {
3042
+ const c = config;
3043
+ try {
3044
+ const tableName = this.#resolveTableName(c);
3045
+ const { sql, params } = buildAggregateQuery(spec, tableName, schema.pkField.name);
3046
+ const result = await this.#getClient().query(sql, params);
3047
+ return result.rows.map((row) => {
3048
+ const mapped = {};
3049
+ for (const agg of spec.aggregates) {
3050
+ const val = row[agg.alias];
3051
+ if (agg.fn === "min" || agg.fn === "max") {
3052
+ mapped[agg.alias] = val;
3053
+ } else {
3054
+ mapped[agg.alias] = typeof val === "string" ? Number(val) : Number(val ?? 0);
3055
+ }
3056
+ }
3057
+ for (const field of spec.groupBy) {
3058
+ mapped[field] = row[field];
3059
+ }
3060
+ return mapped;
3061
+ });
3062
+ } catch (error) {
3063
+ if (error instanceof EquippedError) throw error;
3064
+ throw new EquippedError("PostgreSQL aggregate failed", { adapter: "postgresql", operation: "aggregate", table: c.table }, error);
3065
+ }
3066
+ }
3067
+ async loadMigrations() {
3068
+ const client = this.#getClient();
3069
+ await client.query(`
3070
+ CREATE TABLE IF NOT EXISTS "${TRACKER_TABLE}" (
3071
+ id text PRIMARY KEY,
3072
+ applied_at bigint NOT NULL
3073
+ )
3074
+ `);
3075
+ const result = await client.query(`SELECT id, applied_at FROM "${TRACKER_TABLE}"`);
3076
+ return result.rows.map((row) => ({ id: row.id, appliedAt: Number(row.applied_at) }));
3077
+ }
3078
+ async recordMigration(id, appliedAt) {
3079
+ const client = this.#getClient();
3080
+ await client.query(`INSERT INTO "${TRACKER_TABLE}" (id, applied_at) VALUES ($1, $2)`, [id, appliedAt]);
3081
+ }
3082
+ async acquireMigrationLock(fn) {
3083
+ const client = this.#getClient();
3084
+ await client.query(`SELECT pg_advisory_lock($1)`, [ADVISORY_LOCK_KEY]);
3085
+ try {
3086
+ return await fn();
3087
+ } finally {
3088
+ await client.query(`SELECT pg_advisory_unlock($1)`, [ADVISORY_LOCK_KEY]);
3089
+ }
3090
+ }
3091
+ async applyCreateTable(change) {
3092
+ const pkType = FIELD_TYPE_TO_PG[change.pk.type] ?? "text";
3093
+ const cols = [`"${change.pk.name}" ${pkType} PRIMARY KEY`];
3094
+ for (const f of change.fields) {
3095
+ cols.push(this.#renderColumnDef(f));
3096
+ }
3097
+ await this.#getClient().query(`CREATE TABLE "${change.name}" (${cols.join(", ")})`);
3098
+ }
3099
+ async applyDropTable(change) {
3100
+ await this.#getClient().query(`DROP TABLE "${change.name}"`);
3101
+ }
3102
+ async applyAddField(change) {
3103
+ const colDef = this.#renderColumnDef(change.field);
3104
+ await this.#getClient().query(`ALTER TABLE "${change.table}" ADD COLUMN ${colDef}`);
3105
+ }
3106
+ async applyDropField(change) {
3107
+ await this.#getClient().query(`ALTER TABLE "${change.table}" DROP COLUMN "${change.name}"`);
3108
+ }
3109
+ async applyModifyField(change) {
3110
+ const client = this.#getClient();
3111
+ const table = `"${change.table}"`;
3112
+ const col = `"${change.name}"`;
3113
+ const newType = FIELD_TYPE_TO_PG[change.to.type] ?? "text";
3114
+ await client.query(`ALTER TABLE ${table} ALTER COLUMN ${col} TYPE ${newType} USING ${col}::${newType}`);
3115
+ if (change.to.nullable) {
3116
+ await client.query(`ALTER TABLE ${table} ALTER COLUMN ${col} DROP NOT NULL`);
3117
+ } else {
3118
+ await client.query(`ALTER TABLE ${table} ALTER COLUMN ${col} SET NOT NULL`);
3119
+ }
3120
+ if (change.to.default !== void 0) {
3121
+ await client.query(`ALTER TABLE ${table} ALTER COLUMN ${col} SET DEFAULT ${this.#renderDefault(change.to.default)}`);
3122
+ } else {
3123
+ await client.query(`ALTER TABLE ${table} ALTER COLUMN ${col} DROP DEFAULT`);
3124
+ }
3125
+ if (change.to.name !== change.name) {
3126
+ await client.query(`ALTER TABLE ${table} RENAME COLUMN ${col} TO "${change.to.name}"`);
3127
+ }
3128
+ }
3129
+ async applyRenameTable(change) {
3130
+ await this.#getClient().query(`ALTER TABLE "${change.from}" RENAME TO "${change.to}"`);
3131
+ }
3132
+ async applyRenameField(change) {
3133
+ await this.#getClient().query(`ALTER TABLE "${change.table}" RENAME COLUMN "${change.from}" TO "${change.to}"`);
3134
+ }
3135
+ async applyAddIndex(change) {
3136
+ const name = change.name ?? this.#deriveIndexName(change.table, change.on, change.unique);
3137
+ const unique = change.unique ? "UNIQUE " : "";
3138
+ const cols = change.on.map((c) => `"${c}"`).join(", ");
3139
+ await this.#getClient().query(`CREATE ${unique}INDEX "${name}" ON "${change.table}" (${cols})`);
3140
+ }
3141
+ async applyDropIndex(change) {
3142
+ await this.#getClient().query(`DROP INDEX "${change.name}"`);
3143
+ }
3144
+ async applyAddForeignKey(change) {
3145
+ const name = change.name ?? `fk_${change.table}_${change.on}`;
3146
+ let sql = `ALTER TABLE "${change.table}" ADD CONSTRAINT "${name}" FOREIGN KEY ("${change.on}") REFERENCES "${change.references.table}" ("${change.references.column}")`;
3147
+ if (change.onDelete) sql += ` ON DELETE ${this.#renderFkAction(change.onDelete)}`;
3148
+ if (change.onUpdate) sql += ` ON UPDATE ${this.#renderFkAction(change.onUpdate)}`;
3149
+ await this.#getClient().query(sql);
3150
+ }
3151
+ async applyDropForeignKey(change) {
3152
+ await this.#getClient().query(`ALTER TABLE "${change.table}" DROP CONSTRAINT "${change.name}"`);
3153
+ }
3154
+ async introspect() {
3155
+ const { OrmIntrospectionError: OrmIntrospectionError2 } = await Promise.resolve().then(() => (init_introspection(), introspection_exports));
3156
+ const client = this.#getClient();
3157
+ const tablesResult = await client.query(`
3158
+ SELECT table_name FROM information_schema.tables
3159
+ WHERE table_schema = 'public' AND table_type = 'BASE TABLE' AND table_name != $1
3160
+ `, [TRACKER_TABLE]);
3161
+ const schemas = [];
3162
+ for (const tableRow of tablesResult.rows) {
3163
+ const tableName = tableRow.table_name;
3164
+ const colsResult = await client.query(`
3165
+ SELECT column_name, data_type, is_nullable, column_default
3166
+ FROM information_schema.columns
3167
+ WHERE table_schema = 'public' AND table_name = $1
3168
+ ORDER BY ordinal_position
3169
+ `, [tableName]);
3170
+ const pkResult = await client.query(`
3171
+ SELECT kcu.column_name
3172
+ FROM information_schema.table_constraints tc
3173
+ JOIN information_schema.key_column_usage kcu
3174
+ ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
3175
+ WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'PRIMARY KEY'
3176
+ `, [tableName]);
3177
+ const pkColName = pkResult.rows[0]?.column_name;
3178
+ const uniqueResult = await client.query(`
3179
+ SELECT kcu.column_name
3180
+ FROM information_schema.table_constraints tc
3181
+ JOIN information_schema.key_column_usage kcu
3182
+ ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
3183
+ WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'UNIQUE'
3184
+ `, [tableName]);
3185
+ const uniqueCols = new Set(uniqueResult.rows.map((r) => r.column_name));
3186
+ let pk;
3187
+ const fields = [];
3188
+ for (const col of colsResult.rows) {
3189
+ const pgType = col.data_type.toLowerCase();
3190
+ const fieldType = PG_TO_FIELD_TYPE[pgType];
3191
+ if (!fieldType) {
3192
+ throw new OrmIntrospectionError2({ adapter: "postgresql", table: tableName, cause: `Unsupported column type '${pgType}' on column '${col.column_name}'` });
3193
+ }
3194
+ if (col.column_name === pkColName) {
3195
+ pk = { name: col.column_name, type: fieldType };
3196
+ continue;
3197
+ }
3198
+ const nullable = col.is_nullable === "YES";
3199
+ const raw = col.column_default;
3200
+ const def = this.#parseDefault(raw);
3201
+ fields.push({
3202
+ name: col.column_name,
3203
+ type: fieldType,
3204
+ nullable,
3205
+ ...def !== void 0 ? { default: def } : {},
3206
+ ...uniqueCols.has(col.column_name) ? { unique: true } : {}
3207
+ });
3208
+ }
3209
+ const idxResult = await client.query(`
3210
+ SELECT indexname, indexdef
3211
+ FROM pg_indexes
3212
+ WHERE schemaname = 'public' AND tablename = $1
3213
+ `, [tableName]);
3214
+ const indexes = [];
3215
+ for (const idx of idxResult.rows) {
3216
+ const idxName = idx.indexname;
3217
+ const idxDef = idx.indexdef;
3218
+ if (idxDef.includes("PRIMARY KEY") || idxName.endsWith("_pkey")) continue;
3219
+ const unique = idxDef.toUpperCase().includes("UNIQUE");
3220
+ const colMatch = idxDef.match(/\(([^)]+)\)/);
3221
+ const cols = colMatch ? colMatch[1].split(",").map((c) => c.trim().replace(/"/g, "")) : [];
3222
+ indexes.push({ name: idxName, on: cols, unique });
3223
+ }
3224
+ const fkResult = await client.query(`
3225
+ SELECT
3226
+ tc.constraint_name,
3227
+ kcu.column_name,
3228
+ ccu.table_name AS foreign_table_name,
3229
+ ccu.column_name AS foreign_column_name,
3230
+ rc.delete_rule,
3231
+ rc.update_rule
3232
+ FROM information_schema.table_constraints tc
3233
+ JOIN information_schema.key_column_usage kcu
3234
+ ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
3235
+ JOIN information_schema.constraint_column_usage ccu
3236
+ ON tc.constraint_name = ccu.constraint_name AND tc.table_schema = ccu.table_schema
3237
+ JOIN information_schema.referential_constraints rc
3238
+ ON tc.constraint_name = rc.constraint_name AND tc.table_schema = rc.constraint_schema
3239
+ WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'FOREIGN KEY'
3240
+ `, [tableName]);
3241
+ const foreignKeys = [];
3242
+ for (const fk of fkResult.rows) {
3243
+ foreignKeys.push({
3244
+ name: fk.constraint_name,
3245
+ on: fk.column_name,
3246
+ references: { table: fk.foreign_table_name, column: fk.foreign_column_name },
3247
+ ...fk.delete_rule && fk.delete_rule !== "NO ACTION" ? { onDelete: this.#parseFkAction(fk.delete_rule) } : {},
3248
+ ...fk.update_rule && fk.update_rule !== "NO ACTION" ? { onUpdate: this.#parseFkAction(fk.update_rule) } : {}
3249
+ });
3250
+ }
3251
+ schemas.push({ name: tableName, pk, fields, indexes, foreignKeys });
3252
+ }
3253
+ return schemas;
3254
+ }
3255
+ #renderColumnDef(f) {
3256
+ const pgType = FIELD_TYPE_TO_PG[f.type] ?? "text";
3257
+ let def = `"${f.name}" ${pgType}`;
3258
+ if (!f.nullable) def += " NOT NULL";
3259
+ if (f.default !== void 0) def += ` DEFAULT ${this.#renderDefault(f.default)}`;
3260
+ if (f.unique) def += " UNIQUE";
3261
+ return def;
3262
+ }
3263
+ #renderDefault(val) {
3264
+ if (val === null) return "NULL";
3265
+ if (typeof val === "string") return `'${val.replace(/'/g, "''")}'`;
3266
+ if (typeof val === "boolean") return val ? "TRUE" : "FALSE";
3267
+ return String(val);
3268
+ }
3269
+ #deriveIndexName(table, cols, unique) {
3270
+ const base = `idx_${table}_${cols.join("_")}`;
3271
+ return unique ? `${base}_unique` : base;
3272
+ }
3273
+ #renderFkAction(action) {
3274
+ const map = { cascade: "CASCADE", restrict: "RESTRICT", setnull: "SET NULL", noaction: "NO ACTION" };
3275
+ return map[action.toLowerCase()] ?? "NO ACTION";
3276
+ }
3277
+ #parseFkAction(rule) {
3278
+ const map = { CASCADE: "cascade", RESTRICT: "restrict", "SET NULL": "setNull" };
3279
+ return map[rule.toUpperCase()] ?? "noAction";
3280
+ }
3281
+ #parseDefault(raw) {
3282
+ if (raw === null || raw === void 0) return void 0;
3283
+ if (raw === "NULL" || raw === "NULL::text") return null;
3284
+ if (raw === "true" || raw === "TRUE") return true;
3285
+ if (raw === "false" || raw === "FALSE") return false;
3286
+ const numMatch = raw.match(/^(-?\d+(?:\.\d+)?)$/);
3287
+ if (numMatch) return Number(numMatch[1]);
3288
+ const strMatch = raw.match(/^'(.*)'(?:::.*)?$/);
3289
+ if (strMatch) return strMatch[1].replace(/''/g, "'");
3290
+ return void 0;
3291
+ }
3292
+ async session(fn) {
3293
+ if (this.#sessionStore.getStore()) return fn();
3294
+ let client;
3295
+ try {
3296
+ client = await this.pool.connect();
3297
+ await client.query("BEGIN");
3298
+ const result = await this.#sessionStore.run(client, fn);
3299
+ await client.query("COMMIT");
3300
+ return result;
3301
+ } catch (error) {
3302
+ if (client) {
3303
+ try {
3304
+ await client.query("ROLLBACK");
3305
+ } catch {
3306
+ }
3307
+ }
3308
+ if (error instanceof EquippedError) throw error;
3309
+ throw new EquippedError("PostgreSQL session failed", { adapter: "postgresql", operation: "session" }, error);
3310
+ } finally {
3311
+ client?.release();
3312
+ }
3313
+ }
3314
+ };
3315
+ if (void 0) {
3316
+ const { describe, test, expect, expectTypeOf, vi, beforeEach, afterEach } = void 0;
3317
+ const testConnectionConfig = {
3318
+ host: "localhost",
3319
+ port: 5432,
3320
+ username: "test",
3321
+ password: "test",
3322
+ database: "testdb",
3323
+ ssl: false
3324
+ };
3325
+ describe("PostgresAdapter: class-via-configurable shape", () => {
3326
+ let onSpy;
3327
+ beforeEach(async () => {
3328
+ const { Instance: Instance2 } = await null;
3329
+ onSpy = vi.spyOn(Instance2, "on").mockImplementation(() => {
3330
+ });
3331
+ });
3332
+ afterEach(() => {
3333
+ onSpy.mockRestore();
3334
+ });
3335
+ test("PostgresAdapter.create returns instance with correct capability declarations", () => {
3336
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3337
+ expect(adapter.supportedFieldTypes).toEqual(["string", "number", "boolean", "null", "object", "array", "date"]);
3338
+ expect(adapter.queryableOps).toEqual([
3339
+ "eq",
3340
+ "ne",
3341
+ "gt",
3342
+ "gte",
3343
+ "lt",
3344
+ "lte",
3345
+ "in",
3346
+ "notIn",
3347
+ "like",
3348
+ "exists",
3349
+ "notExists",
3350
+ "contains",
3351
+ "notContains"
3352
+ ]);
3353
+ expect(adapter.updateOps).toEqual(["set", "inc", "mul", "min", "max", "unset", "push", "pull", "patch"]);
3354
+ });
3355
+ test("PostgresAdapter.create validates connection config", () => {
3356
+ expect(() => PostgresAdapter.create({ host: 123, port: "bad" })).toThrow();
3357
+ });
3358
+ test("pool is exposed as a readonly instance field", () => {
3359
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3360
+ expect(adapter.pool).toBeInstanceOf(import_pg.Pool);
3361
+ });
3362
+ test("schemaConfigPipe is declared as readonly with table-name shape", () => {
3363
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3364
+ expect(adapter.schemaConfigPipe).toBeDefined();
3365
+ });
3366
+ test("auto-wires Instance hooks for connect and disconnect", () => {
3367
+ PostgresAdapter.create(testConnectionConfig);
3368
+ expect(onSpy).toHaveBeenCalledWith("start", expect.any(Function), expect.objectContaining({ class: PostgresAdapter }));
3369
+ expect(onSpy).toHaveBeenCalledWith("close", expect.any(Function), expect.objectContaining({ class: PostgresAdapter }));
3370
+ });
3371
+ test("adapter.use returns OrmUse-shaped object", async () => {
3372
+ const { Schema } = await null;
3373
+ const schema = Schema.from("test").pk("id", import_valleyed5.v.string(), () => "x").build();
3374
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3375
+ const use = adapter.use(schema, { table: "test" });
3376
+ expect(use.findMany).toBeTypeOf("function");
3377
+ expect(use.iterateMany).toBeTypeOf("function");
3378
+ expect(use.findOne).toBeTypeOf("function");
3379
+ expect(use.count).toBeTypeOf("function");
3380
+ expect(use.createOne).toBeTypeOf("function");
3381
+ expect(use.createMany).toBeTypeOf("function");
3382
+ expect(use.updateMany).toBeTypeOf("function");
3383
+ expect(use.updateOne).toBeTypeOf("function");
3384
+ expect(use.upsertOne).toBeTypeOf("function");
3385
+ expect(use.deleteOne).toBeTypeOf("function");
3386
+ expect(use.deleteMany).toBeTypeOf("function");
3387
+ expect(use.raw).toBeTypeOf("function");
3388
+ });
3389
+ test("type-level: capability declarations use as const", () => {
3390
+ const _adapter = PostgresAdapter.create(testConnectionConfig);
3391
+ expectTypeOf().toEqualTypeOf();
3392
+ expectTypeOf().toEqualTypeOf();
3393
+ expectTypeOf().toEqualTypeOf();
3394
+ });
3395
+ test("type-level: Repo.from with PostgresAdapter enables all builder methods", async () => {
3396
+ const { Repo } = await null;
3397
+ const { Schema } = await null;
3398
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3399
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
3400
+ const _TestSchema = Schema.from("test").pk("id", import_valleyed5.v.string(), () => "x").build();
3401
+ const _one = repo.on(_TestSchema).one();
3402
+ const _all = repo.on(_TestSchema).all();
3403
+ const _ref = repo.on(_TestSchema);
3404
+ expectTypeOf(_one.create).toBeFunction();
3405
+ expectTypeOf(_one.find).toBeFunction();
3406
+ expectTypeOf(_one.update).toBeFunction();
3407
+ expectTypeOf(_one.delete).toBeFunction();
3408
+ expectTypeOf(_one.upsert).toBeFunction();
3409
+ expectTypeOf(_all.create).toBeFunction();
3410
+ expectTypeOf(_all.find).toBeFunction();
3411
+ expectTypeOf(_all.count).toBeFunction();
3412
+ expectTypeOf(_all.update).toBeFunction();
3413
+ expectTypeOf(_all.delete).toBeFunction();
3414
+ expectTypeOf(_ref.raw).toBeFunction();
3415
+ expectTypeOf(repo.session).toBeFunction();
3416
+ });
3417
+ test("type-level: raw arg-tuple infers (command: string, params?: unknown[]) from PostgresAdapter", async () => {
3418
+ const { Repo } = await null;
3419
+ const { Schema } = await null;
3420
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3421
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
3422
+ const _TestSchema = Schema.from("test").pk("id", import_valleyed5.v.string(), () => "x").build();
3423
+ const _ref = repo.on(_TestSchema);
3424
+ expectTypeOf(_ref.raw).parameters.toEqualTypeOf();
3425
+ });
3426
+ test("type-level: per-call <T> override narrows PostgresAdapter raw return type", async () => {
3427
+ const { Repo } = await null;
3428
+ const { Schema } = await null;
3429
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3430
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
3431
+ const _TestSchema = Schema.from("test").pk("id", import_valleyed5.v.string(), () => "x").build();
3432
+ const _ref = repo.on(_TestSchema);
3433
+ expectTypeOf(_ref.raw).returns.toEqualTypeOf();
3434
+ });
3435
+ test("count forwards COUNT query to pool.query and returns a number", async () => {
3436
+ const { Schema } = await null;
3437
+ const { FilterGroup: FilterGroup2 } = await null;
3438
+ const schema = Schema.from("pg_count").pk("id", import_valleyed5.v.string(), () => "x").field("name", import_valleyed5.v.string()).build();
3439
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3440
+ let capturedSql;
3441
+ let capturedParams;
3442
+ adapter.pool.query = async (sql, params) => {
3443
+ capturedSql = sql;
3444
+ capturedParams = params;
3445
+ return { rows: [{ count: "4" }] };
3446
+ };
3447
+ const result = await adapter.count(schema, { table: "users" }, FilterGroup2.create().eq("name", "Alice"));
3448
+ expect(capturedSql).toBe('SELECT COUNT(*) as count FROM "users" WHERE "name" = $1');
3449
+ expect(capturedParams).toEqual(["Alice"]);
3450
+ expect(result).toBe(4);
3451
+ });
3452
+ test("raw forwards (command, params) to pool.query at runtime", async () => {
3453
+ const { Schema } = await null;
3454
+ const schema = Schema.from("pg_raw").pk("id", import_valleyed5.v.string(), () => "x").build();
3455
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3456
+ let capturedCommand;
3457
+ let capturedParams;
3458
+ const mockResult = { rows: [{ id: "1" }], rowCount: 1 };
3459
+ adapter.pool.query = async (cmd, params) => {
3460
+ capturedCommand = cmd;
3461
+ capturedParams = params;
3462
+ return mockResult;
3463
+ };
3464
+ const result = await adapter.use(schema, { table: "users" }).raw("SELECT * FROM users WHERE id = $1", ["abc"]);
3465
+ expect(capturedCommand).toBe("SELECT * FROM users WHERE id = $1");
3466
+ expect(capturedParams).toEqual(["abc"]);
3467
+ expect(result).toBe(mockResult);
3468
+ });
3469
+ test("raw defaults params to [] when omitted", async () => {
3470
+ const { Schema } = await null;
3471
+ const schema = Schema.from("pg_raw2").pk("id", import_valleyed5.v.string(), () => "x").build();
3472
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3473
+ let capturedParams;
3474
+ adapter.pool.query = async (_cmd, params) => {
3475
+ capturedParams = params;
3476
+ return { rows: [] };
3477
+ };
3478
+ await adapter.use(schema, { table: "users" }).raw("SELECT 1");
3479
+ expect(capturedParams).toEqual([]);
3480
+ });
3481
+ test("iterateMany opens a dedicated cursor client, reads in batchSize chunks, and releases on completion", async () => {
3482
+ const { Schema } = await null;
3483
+ const { FilterGroup: FilterGroup2 } = await null;
3484
+ const { OrderBy } = await null;
3485
+ const schema = Schema.from("pg_iter").pk("id", import_valleyed5.v.string(), () => "x").field("age", import_valleyed5.v.number()).build();
3486
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3487
+ let capturedCursor;
3488
+ const release = vi.fn();
3489
+ const cursor = {
3490
+ read: vi.fn().mockResolvedValueOnce([{ id: "u3", age: 40 }]).mockResolvedValueOnce([{ id: "u1", age: 30 }]).mockResolvedValueOnce([]),
3491
+ close: vi.fn().mockResolvedValue(void 0)
3492
+ };
3493
+ const client = {
3494
+ query: vi.fn((query) => {
3495
+ capturedCursor = query;
3496
+ return cursor;
3497
+ }),
3498
+ release
3499
+ };
3500
+ adapter.pool.connect = vi.fn(async () => client);
3501
+ const rows = [];
3502
+ for await (const row of adapter.use(schema, { table: "people" }).iterateMany(FilterGroup2.create().gt("age", 19), {
3503
+ orderBy: [new OrderBy("age", "desc")],
3504
+ offset: 1,
3505
+ limit: 2,
3506
+ batchSize: 1
3507
+ })) {
3508
+ rows.push(row);
3509
+ }
3510
+ expect(adapter.pool.connect).toHaveBeenCalledTimes(1);
3511
+ expect(capturedCursor).toBeInstanceOf(import_pg_cursor.default);
3512
+ const capturedCursorConfig = capturedCursor;
3513
+ expect(capturedCursorConfig.text).toBe('SELECT * FROM "people" WHERE "age" > $1 ORDER BY "age" DESC LIMIT $2 OFFSET $3');
3514
+ expect(capturedCursorConfig.values).toEqual(["19", "2", "1"]);
3515
+ expect(cursor.read).toHaveBeenNthCalledWith(1, 1);
3516
+ expect(cursor.read).toHaveBeenNthCalledWith(2, 1);
3517
+ expect(cursor.read).toHaveBeenNthCalledWith(3, 1);
3518
+ expect(cursor.close).toHaveBeenCalledTimes(1);
3519
+ expect(release).toHaveBeenCalledTimes(1);
3520
+ expect(rows).toEqual([{ id: "u3", age: 40 }, { id: "u1", age: 30 }]);
3521
+ });
3522
+ test("iterateMany closes cursor and releases dedicated client on early break", async () => {
3523
+ const { Schema } = await null;
3524
+ const { FilterGroup: FilterGroup2 } = await null;
3525
+ const schema = Schema.from("pg_iter_break").pk("id", import_valleyed5.v.string(), () => "x").build();
3526
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3527
+ const release = vi.fn();
3528
+ const cursor = {
3529
+ read: vi.fn().mockResolvedValueOnce([{ id: "u1" }, { id: "u2" }]),
3530
+ close: vi.fn().mockResolvedValue(void 0)
3531
+ };
3532
+ adapter.pool.connect = vi.fn(async () => ({
3533
+ query: vi.fn(() => cursor),
3534
+ release
3535
+ }));
3536
+ const rows = [];
3537
+ for await (const row of adapter.use(schema, { table: "people" }).iterateMany(FilterGroup2.create())) {
3538
+ rows.push(row);
3539
+ break;
3540
+ }
3541
+ expect(rows).toEqual([{ id: "u1" }]);
3542
+ expect(cursor.close).toHaveBeenCalledTimes(1);
3543
+ expect(release).toHaveBeenCalledTimes(1);
3544
+ });
3545
+ test("iterateMany closes cursor and releases dedicated client when the consumer throws", async () => {
3546
+ const { Schema } = await null;
3547
+ const { FilterGroup: FilterGroup2 } = await null;
3548
+ const schema = Schema.from("pg_iter_throw").pk("id", import_valleyed5.v.string(), () => "x").build();
3549
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3550
+ const release = vi.fn();
3551
+ const cursor = {
3552
+ read: vi.fn().mockResolvedValueOnce([{ id: "u1" }]),
3553
+ close: vi.fn().mockResolvedValue(void 0)
3554
+ };
3555
+ adapter.pool.connect = vi.fn(async () => ({
3556
+ query: vi.fn(() => cursor),
3557
+ release
3558
+ }));
3559
+ const consumerError = new Error("consumer failed");
3560
+ await expect(async () => {
3561
+ for await (const _row of adapter.use(schema, { table: "people" }).iterateMany(FilterGroup2.create())) {
3562
+ throw consumerError;
3563
+ }
3564
+ }).rejects.toThrow(consumerError);
3565
+ expect(cursor.close).toHaveBeenCalledTimes(1);
3566
+ expect(release).toHaveBeenCalledTimes(1);
3567
+ });
3568
+ test("iterateMany inside a session uses the active client and leaves release ownership to session", async () => {
3569
+ const { Schema } = await null;
3570
+ const { FilterGroup: FilterGroup2 } = await null;
3571
+ const schema = Schema.from("pg_iter_session").pk("id", import_valleyed5.v.string(), () => "x").build();
3572
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3573
+ const events = [];
3574
+ const release = vi.fn(() => events.push("release"));
3575
+ const cursor = {
3576
+ read: vi.fn().mockResolvedValueOnce([{ id: "u1" }]).mockResolvedValueOnce([]),
3577
+ close: vi.fn(async () => events.push("cursor.close"))
3578
+ };
3579
+ const client = {
3580
+ query: vi.fn((query) => {
3581
+ if (typeof query === "string") {
3582
+ events.push(query);
3583
+ return { rows: [] };
3584
+ }
3585
+ events.push("cursor.open");
3586
+ return cursor;
3587
+ }),
3588
+ release
3589
+ };
3590
+ adapter.pool.connect = vi.fn(async () => client);
3591
+ const rows = [];
3592
+ await adapter.session(async () => {
3593
+ for await (const row of adapter.use(schema, { table: "people" }).iterateMany(FilterGroup2.create(), { batchSize: 1 })) {
3594
+ rows.push(row);
3595
+ }
3596
+ events.push("session.body.done");
3597
+ });
3598
+ expect(adapter.pool.connect).toHaveBeenCalledTimes(1);
3599
+ expect(rows).toEqual([{ id: "u1" }]);
3600
+ expect(events).toEqual(["BEGIN", "cursor.open", "cursor.close", "session.body.done", "COMMIT", "release"]);
3601
+ expect(release).toHaveBeenCalledTimes(1);
3602
+ });
3603
+ test("session method is exposed on the adapter", () => {
3604
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3605
+ expect(adapter.session).toBeDefined();
3606
+ expect(adapter.session).toBeTypeOf("function");
3607
+ });
3608
+ test("declares aggregateOps with all six canonical ops", () => {
3609
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3610
+ expect(adapter.aggregateOps).toEqual(["count", "countDistinct", "sum", "avg", "min", "max"]);
3611
+ });
3612
+ test("type-level: aggregateOps is a readonly tuple of all six ops", () => {
3613
+ const _adapter = PostgresAdapter.create(testConnectionConfig);
3614
+ expectTypeOf().toEqualTypeOf();
3615
+ });
3616
+ test("aggregate method forwards spec to pool.query and returns mapped rows", async () => {
3617
+ const { Schema } = await null;
3618
+ const schema = Schema.from("pg_agg").pk("id", import_valleyed5.v.string(), () => "x").field("amount", import_valleyed5.v.number()).field("region", import_valleyed5.v.string()).build();
3619
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3620
+ let capturedSql;
3621
+ let capturedParams;
3622
+ adapter.pool.query = async (sql, params) => {
3623
+ capturedSql = sql;
3624
+ capturedParams = params;
3625
+ return { rows: [{ total: "5" }] };
3626
+ };
3627
+ const result = await adapter.aggregate(schema, { table: "orders" }, {
3628
+ aggregates: [{ fn: "count", alias: "total" }],
3629
+ groupBy: []
3630
+ });
3631
+ expect(capturedSql).toBe('SELECT COUNT(*) AS "total" FROM "orders"');
3632
+ expect(capturedParams).toEqual([]);
3633
+ expect(result).toEqual([{ total: 5 }]);
3634
+ });
3635
+ test("aggregate converts PG bigint/numeric strings to numbers for count/sum/avg", async () => {
3636
+ const { Schema } = await null;
3637
+ const schema = Schema.from("pg_agg_types").pk("id", import_valleyed5.v.string(), () => "x").field("amount", import_valleyed5.v.number()).build();
3638
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3639
+ adapter.pool.query = async () => ({
3640
+ rows: [{ cnt: "10", revenue: "250.50", avgAmt: "25.05" }]
3641
+ });
3642
+ const result = await adapter.aggregate(schema, { table: "orders" }, {
3643
+ aggregates: [
3644
+ { fn: "count", alias: "cnt" },
3645
+ { fn: "sum", field: "amount", alias: "revenue" },
3646
+ { fn: "avg", field: "amount", alias: "avgAmt" }
3647
+ ],
3648
+ groupBy: []
3649
+ });
3650
+ expect(result[0].cnt).toBe(10);
3651
+ expect(result[0].revenue).toBe(250.5);
3652
+ expect(result[0].avgAmt).toBe(25.05);
3653
+ });
3654
+ test("aggregate preserves original type for min/max", async () => {
3655
+ const { Schema } = await null;
3656
+ const schema = Schema.from("pg_agg_minmax").pk("id", import_valleyed5.v.string(), () => "x").field("name", import_valleyed5.v.string()).build();
3657
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3658
+ adapter.pool.query = async () => ({
3659
+ rows: [{ lowest: "Alice", highest: "Zara" }]
3660
+ });
3661
+ const result = await adapter.aggregate(schema, { table: "users" }, {
3662
+ aggregates: [
3663
+ { fn: "min", field: "name", alias: "lowest" },
3664
+ { fn: "max", field: "name", alias: "highest" }
3665
+ ],
3666
+ groupBy: []
3667
+ });
3668
+ expect(result[0].lowest).toBe("Alice");
3669
+ expect(result[0].highest).toBe("Zara");
3670
+ });
3671
+ test("aggregate includes groupBy fields in result rows", async () => {
3672
+ const { Schema } = await null;
3673
+ const schema = Schema.from("pg_agg_group").pk("id", import_valleyed5.v.string(), () => "x").field("region", import_valleyed5.v.string()).build();
3674
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3675
+ adapter.pool.query = async () => ({
3676
+ rows: [
3677
+ { cnt: "3", region: "US" },
3678
+ { cnt: "2", region: "EU" }
3679
+ ]
3680
+ });
3681
+ const result = await adapter.aggregate(schema, { table: "orders" }, {
3682
+ aggregates: [{ fn: "count", alias: "cnt" }],
3683
+ groupBy: ["region"]
3684
+ });
3685
+ expect(result).toEqual([
3686
+ { cnt: 3, region: "US" },
3687
+ { cnt: 2, region: "EU" }
3688
+ ]);
3689
+ });
3690
+ test("type-level: Repo.from with PostgresAdapter enables aggregate method", async () => {
3691
+ const { Repo } = await null;
3692
+ const { Schema } = await null;
3693
+ const adapter = PostgresAdapter.create(testConnectionConfig);
3694
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
3695
+ const _TestSchema = Schema.from("test").pk("id", import_valleyed5.v.string(), () => "x").build();
3696
+ const _ref = repo.on(_TestSchema);
3697
+ expectTypeOf(_ref.aggregate).toBeFunction();
3698
+ });
3699
+ });
3700
+ describe("PostgresAdapter: migration methods", () => {
3701
+ let onSpy;
3702
+ let adapter;
3703
+ let queries;
3704
+ beforeEach(async () => {
3705
+ const { Instance: Instance2 } = await null;
3706
+ onSpy = vi.spyOn(Instance2, "on").mockImplementation(() => {
3707
+ });
3708
+ adapter = PostgresAdapter.create(testConnectionConfig);
3709
+ queries = [];
3710
+ adapter.pool.query = async (sql, params) => {
3711
+ queries.push({ sql, params });
3712
+ return { rows: [] };
3713
+ };
3714
+ });
3715
+ afterEach(() => {
3716
+ onSpy.mockRestore();
3717
+ });
3718
+ test("loadMigrations creates tracker table then selects rows", async () => {
3719
+ ;
3720
+ adapter.pool.query = async (sql, params) => {
3721
+ queries.push({ sql, params });
3722
+ if (sql.includes("SELECT id")) {
3723
+ return { rows: [{ id: "0001", applied_at: "1700000000000" }] };
3724
+ }
3725
+ return { rows: [] };
3726
+ };
3727
+ const result = await adapter.loadMigrations();
3728
+ expect(queries).toHaveLength(2);
3729
+ expect(queries[0].sql).toContain("CREATE TABLE IF NOT EXISTS");
3730
+ expect(queries[0].sql).toContain("equipped_migrations");
3731
+ expect(queries[1].sql).toContain("SELECT id, applied_at");
3732
+ expect(result).toEqual([{ id: "0001", appliedAt: 17e11 }]);
3733
+ });
3734
+ test("recordMigration inserts into tracker table", async () => {
3735
+ await adapter.recordMigration("0001-init", 17e11);
3736
+ expect(queries).toHaveLength(1);
3737
+ expect(queries[0].sql).toContain("INSERT INTO");
3738
+ expect(queries[0].sql).toContain("equipped_migrations");
3739
+ expect(queries[0].params).toEqual(["0001-init", 17e11]);
3740
+ });
3741
+ test("acquireMigrationLock wraps fn with pg_advisory_lock/unlock", async () => {
3742
+ const result = await adapter.acquireMigrationLock(async () => {
3743
+ queries.push({ sql: "USER_FN" });
3744
+ return 42;
3745
+ });
3746
+ expect(result).toBe(42);
3747
+ expect(queries[0].sql).toContain("pg_advisory_lock");
3748
+ expect(queries[1].sql).toBe("USER_FN");
3749
+ expect(queries[2].sql).toContain("pg_advisory_unlock");
3750
+ });
3751
+ test("acquireMigrationLock unlocks even on error", async () => {
3752
+ await expect(adapter.acquireMigrationLock(async () => {
3753
+ throw new Error("boom");
3754
+ })).rejects.toThrow("boom");
3755
+ expect(queries[0].sql).toContain("pg_advisory_lock");
3756
+ expect(queries[1].sql).toContain("pg_advisory_unlock");
3757
+ });
3758
+ test("applyCreateTable generates correct DDL", async () => {
3759
+ await adapter.applyCreateTable({
3760
+ kind: "createTable",
3761
+ name: "users",
3762
+ pk: { name: "id", type: "string" },
3763
+ fields: [
3764
+ { name: "email", type: "string", unique: true },
3765
+ { name: "age", type: "number", nullable: true },
3766
+ { name: "active", type: "boolean", default: true }
3767
+ ]
3768
+ });
3769
+ expect(queries).toHaveLength(1);
3770
+ const sql = queries[0].sql;
3771
+ expect(sql).toContain('CREATE TABLE "users"');
3772
+ expect(sql).toContain('"id" text PRIMARY KEY');
3773
+ expect(sql).toContain('"email" text NOT NULL UNIQUE');
3774
+ expect(sql).toContain('"age" double precision');
3775
+ expect(sql).not.toContain('"age" double precision NOT NULL');
3776
+ expect(sql).toContain('"active" boolean NOT NULL DEFAULT TRUE');
3777
+ });
3778
+ test("applyDropTable generates DROP TABLE", async () => {
3779
+ await adapter.applyDropTable({ kind: "dropTable", name: "users" });
3780
+ expect(queries[0].sql).toBe('DROP TABLE "users"');
3781
+ });
3782
+ test("applyAddField generates ALTER TABLE ADD COLUMN", async () => {
3783
+ await adapter.applyAddField({
3784
+ kind: "addField",
3785
+ table: "users",
3786
+ field: { name: "bio", type: "string", nullable: true, default: "none" }
3787
+ });
3788
+ expect(queries[0].sql).toContain('ALTER TABLE "users" ADD COLUMN');
3789
+ expect(queries[0].sql).toContain('"bio" text');
3790
+ expect(queries[0].sql).not.toContain("NOT NULL");
3791
+ expect(queries[0].sql).toContain("DEFAULT 'none'");
3792
+ });
3793
+ test("applyDropField generates ALTER TABLE DROP COLUMN", async () => {
3794
+ await adapter.applyDropField({ kind: "dropField", table: "users", name: "bio" });
3795
+ expect(queries[0].sql).toBe('ALTER TABLE "users" DROP COLUMN "bio"');
3796
+ });
3797
+ test("applyModifyField generates ALTER COLUMN statements for type, nullable, default", async () => {
3798
+ await adapter.applyModifyField({
3799
+ kind: "modifyField",
3800
+ table: "users",
3801
+ name: "age",
3802
+ to: { name: "age", type: "string", nullable: true, default: null }
3803
+ });
3804
+ expect(queries[0].sql).toContain('ALTER COLUMN "age" TYPE text');
3805
+ expect(queries[1].sql).toContain("DROP NOT NULL");
3806
+ expect(queries[2].sql).toContain("SET DEFAULT NULL");
3807
+ });
3808
+ test("applyModifyField renames column when to.name differs", async () => {
3809
+ await adapter.applyModifyField({
3810
+ kind: "modifyField",
3811
+ table: "users",
3812
+ name: "age",
3813
+ to: { name: "years", type: "number" }
3814
+ });
3815
+ const renameSql = queries.find((q) => q.sql.includes("RENAME COLUMN"));
3816
+ expect(renameSql).toBeDefined();
3817
+ expect(renameSql.sql).toContain('RENAME COLUMN "age" TO "years"');
3818
+ });
3819
+ test("applyRenameTable generates ALTER TABLE RENAME", async () => {
3820
+ await adapter.applyRenameTable({ kind: "renameTable", from: "users", to: "accounts" });
3821
+ expect(queries[0].sql).toBe('ALTER TABLE "users" RENAME TO "accounts"');
3822
+ });
3823
+ test("applyRenameField generates ALTER TABLE RENAME COLUMN", async () => {
3824
+ await adapter.applyRenameField({ kind: "renameField", table: "users", from: "name", to: "fullName" });
3825
+ expect(queries[0].sql).toBe('ALTER TABLE "users" RENAME COLUMN "name" TO "fullName"');
3826
+ });
3827
+ test("applyAddIndex generates CREATE INDEX with auto-derived name", async () => {
3828
+ await adapter.applyAddIndex({ kind: "addIndex", table: "users", on: ["email"] });
3829
+ expect(queries[0].sql).toBe('CREATE INDEX "idx_users_email" ON "users" ("email")');
3830
+ });
3831
+ test("applyAddIndex generates CREATE UNIQUE INDEX with explicit name", async () => {
3832
+ await adapter.applyAddIndex({ kind: "addIndex", table: "users", on: ["email"], unique: true, name: "my_idx" });
3833
+ expect(queries[0].sql).toBe('CREATE UNIQUE INDEX "my_idx" ON "users" ("email")');
3834
+ });
3835
+ test("applyAddIndex auto-derives unique suffix when unique and no name", async () => {
3836
+ await adapter.applyAddIndex({ kind: "addIndex", table: "posts", on: ["author", "title"], unique: true });
3837
+ expect(queries[0].sql).toBe('CREATE UNIQUE INDEX "idx_posts_author_title_unique" ON "posts" ("author", "title")');
3838
+ });
3839
+ test("applyDropIndex generates DROP INDEX", async () => {
3840
+ await adapter.applyDropIndex({ kind: "dropIndex", name: "idx_users_email" });
3841
+ expect(queries[0].sql).toBe('DROP INDEX "idx_users_email"');
3842
+ });
3843
+ test("applyAddForeignKey generates ALTER TABLE ADD CONSTRAINT with auto-derived name", async () => {
3844
+ await adapter.applyAddForeignKey({
3845
+ kind: "addForeignKey",
3846
+ table: "posts",
3847
+ on: "authorId",
3848
+ references: { table: "users", column: "id" },
3849
+ onDelete: "cascade",
3850
+ onUpdate: "setNull"
3851
+ });
3852
+ const sql = queries[0].sql;
3853
+ expect(sql).toContain('ALTER TABLE "posts" ADD CONSTRAINT "fk_posts_authorId"');
3854
+ expect(sql).toContain('FOREIGN KEY ("authorId") REFERENCES "users" ("id")');
3855
+ expect(sql).toContain("ON DELETE CASCADE");
3856
+ expect(sql).toContain("ON UPDATE SET NULL");
3857
+ });
3858
+ test("applyAddForeignKey uses explicit name when provided", async () => {
3859
+ await adapter.applyAddForeignKey({
3860
+ kind: "addForeignKey",
3861
+ table: "posts",
3862
+ on: "authorId",
3863
+ references: { table: "users", column: "id" },
3864
+ name: "custom_fk"
3865
+ });
3866
+ expect(queries[0].sql).toContain('ADD CONSTRAINT "custom_fk"');
3867
+ });
3868
+ test("applyDropForeignKey generates ALTER TABLE DROP CONSTRAINT", async () => {
3869
+ await adapter.applyDropForeignKey({ kind: "dropForeignKey", table: "posts", name: "fk_posts_authorId" });
3870
+ expect(queries[0].sql).toBe('ALTER TABLE "posts" DROP CONSTRAINT "fk_posts_authorId"');
3871
+ });
3872
+ test("introspect queries information_schema and builds DiscoveredSchema[]", async () => {
3873
+ ;
3874
+ adapter.pool.query = async (sql, params) => {
3875
+ queries.push({ sql, params });
3876
+ if (sql.includes("information_schema.tables")) {
3877
+ return { rows: [{ table_name: "users" }] };
3878
+ }
3879
+ if (sql.includes("information_schema.columns")) {
3880
+ return {
3881
+ rows: [
3882
+ { column_name: "id", data_type: "text", is_nullable: "NO", column_default: null },
3883
+ { column_name: "email", data_type: "character varying", is_nullable: "NO", column_default: null },
3884
+ { column_name: "age", data_type: "integer", is_nullable: "YES", column_default: "25" }
3885
+ ]
3886
+ };
3887
+ }
3888
+ if (sql.includes("PRIMARY KEY")) {
3889
+ return { rows: [{ column_name: "id" }] };
3890
+ }
3891
+ if (sql.includes("constraint_type = 'UNIQUE'")) {
3892
+ return { rows: [{ column_name: "email" }] };
3893
+ }
3894
+ if (sql.includes("pg_indexes")) {
3895
+ return { rows: [{ indexname: "users_email_idx", indexdef: "CREATE UNIQUE INDEX users_email_idx ON public.users USING btree (email)" }] };
3896
+ }
3897
+ if (sql.includes("constraint_type = 'FOREIGN KEY'")) {
3898
+ return { rows: [] };
3899
+ }
3900
+ return { rows: [] };
3901
+ };
3902
+ const schemas = await adapter.introspect();
3903
+ expect(schemas).toHaveLength(1);
3904
+ const s = schemas[0];
3905
+ expect(s.name).toBe("users");
3906
+ expect(s.pk).toEqual({ name: "id", type: "string" });
3907
+ expect(s.fields).toEqual([
3908
+ { name: "email", type: "string", nullable: false, unique: true },
3909
+ { name: "age", type: "number", nullable: true, default: 25 }
3910
+ ]);
3911
+ expect(s.indexes).toEqual([{ name: "users_email_idx", on: ["email"], unique: true }]);
3912
+ expect(s.foreignKeys).toEqual([]);
3913
+ });
3914
+ test("introspect throws OrmIntrospectionError on unsupported PG type", async () => {
3915
+ const { OrmIntrospectionError: OrmIntrospectionError2 } = await null;
3916
+ adapter.pool.query = async (sql) => {
3917
+ if (sql.includes("information_schema.tables")) {
3918
+ return { rows: [{ table_name: "files" }] };
3919
+ }
3920
+ if (sql.includes("information_schema.columns")) {
3921
+ return {
3922
+ rows: [
3923
+ { column_name: "id", data_type: "text", is_nullable: "NO", column_default: null },
3924
+ { column_name: "data", data_type: "bytea", is_nullable: "YES", column_default: null }
3925
+ ]
3926
+ };
3927
+ }
3928
+ if (sql.includes("PRIMARY KEY")) {
3929
+ return { rows: [{ column_name: "id" }] };
3930
+ }
3931
+ if (sql.includes("constraint_type = 'UNIQUE'")) {
3932
+ return { rows: [] };
3933
+ }
3934
+ return { rows: [] };
3935
+ };
3936
+ await expect(adapter.introspect()).rejects.toThrow(OrmIntrospectionError2);
3937
+ try {
3938
+ await adapter.introspect();
3939
+ } catch (err) {
3940
+ expect(err.adapter).toBe("postgresql");
3941
+ expect(err.table).toBe("files");
3942
+ expect(err.cause).toContain("bytea");
3943
+ }
3944
+ });
3945
+ test("introspect parses foreign keys with cascade actions", async () => {
3946
+ ;
3947
+ adapter.pool.query = async (sql) => {
3948
+ if (sql.includes("information_schema.tables")) {
3949
+ return { rows: [{ table_name: "posts" }] };
3950
+ }
3951
+ if (sql.includes("information_schema.columns")) {
3952
+ return {
3953
+ rows: [
3954
+ { column_name: "id", data_type: "text", is_nullable: "NO", column_default: null },
3955
+ { column_name: "author_id", data_type: "text", is_nullable: "NO", column_default: null }
3956
+ ]
3957
+ };
3958
+ }
3959
+ if (sql.includes("PRIMARY KEY")) {
3960
+ return { rows: [{ column_name: "id" }] };
3961
+ }
3962
+ if (sql.includes("constraint_type = 'UNIQUE'")) {
3963
+ return { rows: [] };
3964
+ }
3965
+ if (sql.includes("pg_indexes")) {
3966
+ return { rows: [] };
3967
+ }
3968
+ if (sql.includes("constraint_type = 'FOREIGN KEY'")) {
3969
+ return {
3970
+ rows: [{
3971
+ constraint_name: "fk_posts_author_id",
3972
+ column_name: "author_id",
3973
+ foreign_table_name: "users",
3974
+ foreign_column_name: "id",
3975
+ delete_rule: "CASCADE",
3976
+ update_rule: "SET NULL"
3977
+ }]
3978
+ };
3979
+ }
3980
+ return { rows: [] };
3981
+ };
3982
+ const schemas = await adapter.introspect();
3983
+ expect(schemas[0].foreignKeys).toEqual([{
3984
+ name: "fk_posts_author_id",
3985
+ on: "author_id",
3986
+ references: { table: "users", column: "id" },
3987
+ onDelete: "cascade",
3988
+ onUpdate: "setNull"
3989
+ }]);
3990
+ });
3991
+ test("introspect excludes tracker table from results", async () => {
3992
+ ;
3993
+ adapter.pool.query = async (sql, params) => {
3994
+ if (sql.includes("information_schema.tables")) {
3995
+ expect(params).toContain("equipped_migrations");
3996
+ return { rows: [] };
3997
+ }
3998
+ return { rows: [] };
3999
+ };
4000
+ const schemas = await adapter.introspect();
4001
+ expect(schemas).toEqual([]);
4002
+ });
4003
+ test("type-level: PostgresAdapter declares all migration methods", () => {
4004
+ expectTypeOf(adapter.loadMigrations).toBeFunction();
4005
+ expectTypeOf(adapter.recordMigration).toBeFunction();
4006
+ expectTypeOf(adapter.acquireMigrationLock).toBeFunction();
4007
+ expectTypeOf(adapter.applyCreateTable).toBeFunction();
4008
+ expectTypeOf(adapter.applyDropTable).toBeFunction();
4009
+ expectTypeOf(adapter.applyAddField).toBeFunction();
4010
+ expectTypeOf(adapter.applyDropField).toBeFunction();
4011
+ expectTypeOf(adapter.applyModifyField).toBeFunction();
4012
+ expectTypeOf(adapter.applyRenameTable).toBeFunction();
4013
+ expectTypeOf(adapter.applyRenameField).toBeFunction();
4014
+ expectTypeOf(adapter.applyAddIndex).toBeFunction();
4015
+ expectTypeOf(adapter.applyDropIndex).toBeFunction();
4016
+ expectTypeOf(adapter.applyAddForeignKey).toBeFunction();
4017
+ expectTypeOf(adapter.applyDropForeignKey).toBeFunction();
4018
+ expectTypeOf(adapter.introspect).toBeFunction();
4019
+ });
4020
+ test("type-level: Migrator.from rejects withoutLock for PostgresAdapter", async () => {
4021
+ const { Repo } = await null;
4022
+ const { Migrator } = await null;
4023
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
4024
+ const step = Migrator.from(repo, adapter).migrations([]);
4025
+ expectTypeOf(step).toHaveProperty("build");
4026
+ expectTypeOf(step).not.toHaveProperty("withoutLock");
4027
+ });
4028
+ test("applyCreateTable maps all field types to correct PG types", async () => {
4029
+ await adapter.applyCreateTable({
4030
+ kind: "createTable",
4031
+ name: "all_types",
4032
+ pk: { name: "id", type: "string" },
4033
+ fields: [
4034
+ { name: "f_num", type: "number" },
4035
+ { name: "f_bool", type: "boolean" },
4036
+ { name: "f_date", type: "date" },
4037
+ { name: "f_null", type: "null" },
4038
+ { name: "f_obj", type: "object" },
4039
+ { name: "f_arr", type: "array" }
4040
+ ]
4041
+ });
4042
+ const sql = queries[0].sql;
4043
+ expect(sql).toContain('"f_num" double precision NOT NULL');
4044
+ expect(sql).toContain('"f_bool" boolean NOT NULL');
4045
+ expect(sql).toContain('"f_date" timestamptz NOT NULL');
4046
+ expect(sql).toContain('"f_null" text NOT NULL');
4047
+ expect(sql).toContain('"f_obj" jsonb NOT NULL');
4048
+ expect(sql).toContain('"f_arr" jsonb NOT NULL');
4049
+ });
4050
+ test("applyModifyField sets NOT NULL when nullable is falsy", async () => {
4051
+ await adapter.applyModifyField({
4052
+ kind: "modifyField",
4053
+ table: "users",
4054
+ name: "email",
4055
+ to: { name: "email", type: "string" }
4056
+ });
4057
+ expect(queries[1].sql).toContain("SET NOT NULL");
4058
+ });
4059
+ test("applyModifyField drops default when to.default is undefined", async () => {
4060
+ await adapter.applyModifyField({
4061
+ kind: "modifyField",
4062
+ table: "users",
4063
+ name: "age",
4064
+ to: { name: "age", type: "number" }
4065
+ });
4066
+ expect(queries[2].sql).toContain("DROP DEFAULT");
4067
+ });
4068
+ test("applyAddField with string default escapes single quotes", async () => {
4069
+ await adapter.applyAddField({
4070
+ kind: "addField",
4071
+ table: "users",
4072
+ field: { name: "bio", type: "string", default: "it's" }
4073
+ });
4074
+ expect(queries[0].sql).toContain("DEFAULT 'it''s'");
4075
+ });
4076
+ test("end-to-end: Migrator.from(repo, adapter) wires up correctly", async () => {
4077
+ const { Repo } = await null;
4078
+ const { Migrator } = await null;
4079
+ const { Schema } = await null;
4080
+ Schema.from("users").pk("id", import_valleyed5.v.string(), () => "x").field("email", import_valleyed5.v.string()).build();
4081
+ const repo = Repo.from(adapter).resolve(() => ({ table: "test" })).build();
4082
+ let loadCalls = 0;
4083
+ const mockClient = {
4084
+ query: async (sql, _params) => {
4085
+ if (sql.includes("pg_advisory_lock") || sql.includes("pg_advisory_unlock")) return { rows: [] };
4086
+ if (sql.includes("CREATE TABLE IF NOT EXISTS")) return { rows: [] };
4087
+ if (sql.includes("SELECT id, applied_at")) {
4088
+ loadCalls++;
4089
+ return { rows: [] };
4090
+ }
4091
+ if (sql.includes("INSERT INTO")) return { rows: [] };
4092
+ if (sql.includes("CREATE TABLE")) return { rows: [] };
4093
+ if (sql === "BEGIN" || sql === "COMMIT" || sql === "ROLLBACK") return { rows: [] };
4094
+ return { rows: [] };
4095
+ },
4096
+ release: () => {
4097
+ }
4098
+ };
4099
+ adapter.pool.query = mockClient.query;
4100
+ adapter.pool.connect = async () => mockClient;
4101
+ const migrator = Migrator.from(repo, adapter).migrations([
4102
+ { id: "0001", changes: [{ kind: "createTable", name: "users", pk: { name: "id", type: "string" }, fields: [{ name: "email", type: "string" }] }] }
4103
+ ]).build();
4104
+ const result = await migrator.up();
4105
+ expect(result.ran).toEqual(["0001"]);
4106
+ expect(loadCalls).toBe(1);
4107
+ });
4108
+ });
4109
+ }
4110
+ // Annotate the CommonJS export names for ESM import in node:
4111
+ 0 && (module.exports = {
4112
+ PostgresAdapter
4113
+ });
4114
+ //# sourceMappingURL=index.cjs.map