@baasix/baasix 0.1.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 (666) hide show
  1. package/LICENSE.MD +85 -0
  2. package/README.md +526 -0
  3. package/assets/banner.jpg +0 -0
  4. package/assets/banner_small.jpg +0 -0
  5. package/assets/logo_icon.svg +20 -0
  6. package/assets/logo_icon_rounded.svg +20 -0
  7. package/dist/LICENSE.MD +85 -0
  8. package/dist/README.md +526 -0
  9. package/dist/app/404/index.html +1 -0
  10. package/dist/app/404.html +1 -0
  11. package/dist/app/_next/static/chunks/041e1f03-56ae8a902a7f2fe6.js +24 -0
  12. package/dist/app/_next/static/chunks/1117-05479929a8da73e3.js +1 -0
  13. package/dist/app/_next/static/chunks/1299.77cc7b7b76b75cba.js +1 -0
  14. package/dist/app/_next/static/chunks/1303-35a96e9c9cdeab9d.js +1 -0
  15. package/dist/app/_next/static/chunks/1509-56ac00cdaaecdf53.js +1 -0
  16. package/dist/app/_next/static/chunks/1668-e3eabd0f6753c780.js +1 -0
  17. package/dist/app/_next/static/chunks/1783-d9fb550fd324300c.js +1 -0
  18. package/dist/app/_next/static/chunks/2117-29b5fa47421595ad.js +2 -0
  19. package/dist/app/_next/static/chunks/2344.35b46d2179a765b5.js +1 -0
  20. package/dist/app/_next/static/chunks/257.990da16794a31292.js +1 -0
  21. package/dist/app/_next/static/chunks/2676-73b0ee7c80073a84.js +1 -0
  22. package/dist/app/_next/static/chunks/3563-b8842744384391fe.js +1 -0
  23. package/dist/app/_next/static/chunks/363642f4-933b579ed3c85f60.js +1 -0
  24. package/dist/app/_next/static/chunks/3817-e20c8f0a0810fc95.js +1 -0
  25. package/dist/app/_next/static/chunks/3834.84944e390d902509.js +2 -0
  26. package/dist/app/_next/static/chunks/4043-3a30c8a75896f241.js +1 -0
  27. package/dist/app/_next/static/chunks/4225-14090c7c0cd9dec6.js +1 -0
  28. package/dist/app/_next/static/chunks/4438-c9a12ca15b6e9160.js +1 -0
  29. package/dist/app/_next/static/chunks/4458-679fd0c6884f456a.js +1 -0
  30. package/dist/app/_next/static/chunks/4475-8bdfbd536fba8c48.js +1 -0
  31. package/dist/app/_next/static/chunks/4883-8a924721bb21b3b0.js +1 -0
  32. package/dist/app/_next/static/chunks/489-683ab07188f9df2b.js +1 -0
  33. package/dist/app/_next/static/chunks/4952-1b97320cf61f3f21.js +1 -0
  34. package/dist/app/_next/static/chunks/5094-8d53e403235d4ca6.js +1 -0
  35. package/dist/app/_next/static/chunks/5101-3a146e0625747ad1.js +1 -0
  36. package/dist/app/_next/static/chunks/54a60aa6-d9747982e0a81f58.js +79 -0
  37. package/dist/app/_next/static/chunks/5650-f096291df402bfc2.js +1 -0
  38. package/dist/app/_next/static/chunks/600-539045311240f579.js +1 -0
  39. package/dist/app/_next/static/chunks/6170-803b82e19d3ade6d.js +89 -0
  40. package/dist/app/_next/static/chunks/6241-30d7169d1010e5a4.js +1 -0
  41. package/dist/app/_next/static/chunks/6530-a91e10cffa4200c4.js +1 -0
  42. package/dist/app/_next/static/chunks/6547-4bbbdb5c399aef1e.js +1 -0
  43. package/dist/app/_next/static/chunks/6712-781937c53a2c49da.js +1 -0
  44. package/dist/app/_next/static/chunks/6fcbdc68-90be1a5480b8d353.js +1 -0
  45. package/dist/app/_next/static/chunks/70e0d97a-aeaf0cdc26ba1a58.js +1 -0
  46. package/dist/app/_next/static/chunks/7214-5154a89d08d24dde.js +1 -0
  47. package/dist/app/_next/static/chunks/7324-b53229c59a640880.js +10 -0
  48. package/dist/app/_next/static/chunks/7636-66424f0b51d350e9.js +1 -0
  49. package/dist/app/_next/static/chunks/7874-39a3f2541165a675.js +1 -0
  50. package/dist/app/_next/static/chunks/7982-9da12b83f11e3f5f.js +1 -0
  51. package/dist/app/_next/static/chunks/8213a2eb-da25a3b3c5521b2b.js +1 -0
  52. package/dist/app/_next/static/chunks/8473-6598318371eca31b.js +1 -0
  53. package/dist/app/_next/static/chunks/8640fa6b-72e43370f68e5587.js +1 -0
  54. package/dist/app/_next/static/chunks/9090-3ef676f29c95f1c7.js +1 -0
  55. package/dist/app/_next/static/chunks/9124-a02f9e209e6e3cce.js +1 -0
  56. package/dist/app/_next/static/chunks/926-156f32067d111d6b.js +1 -0
  57. package/dist/app/_next/static/chunks/9487-b17481605e513b83.js +1 -0
  58. package/dist/app/_next/static/chunks/9599-a7e572bb88c3392b.js +1 -0
  59. package/dist/app/_next/static/chunks/9881-419697138376e755.js +1 -0
  60. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/all-activity/page-8917930b4d663405.js +1 -0
  61. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/email-log/page-b27a6ee32782d7df.js +1 -0
  62. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/notifications/page-b7eda523ede2702c.js +1 -0
  63. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/page-1cfa62d1caedaed0.js +1 -0
  64. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/sessions/page-3e21e20db90aeff7.js +1 -0
  65. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-executions/page-27bcc26b747fb29b.js +1 -0
  66. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-logs/page-9f9e9e952aef436e.js +1 -0
  67. package/dist/app/_next/static/chunks/app/(authenticated)/change-password/page-8d61aa499eabb127.js +1 -0
  68. package/dist/app/_next/static/chunks/app/(authenticated)/dashboard/page-1ceeac9e72997a8a.js +1 -0
  69. package/dist/app/_next/static/chunks/app/(authenticated)/data-browser/page-8cda2b57759dd670.js +1 -0
  70. package/dist/app/_next/static/chunks/app/(authenticated)/file-manager/page-8c6f1b1da66ad7e4.js +1 -0
  71. package/dist/app/_next/static/chunks/app/(authenticated)/layout-f70d225b2759c998.js +1 -0
  72. package/dist/app/_next/static/chunks/app/(authenticated)/settings/migrations/page-aacec8f7cfb40ab2.js +1 -0
  73. package/dist/app/_next/static/chunks/app/(authenticated)/settings/permissions/page-828110cfcde429c6.js +1 -0
  74. package/dist/app/_next/static/chunks/app/(authenticated)/settings/project/page-420e794bb76bd204.js +1 -0
  75. package/dist/app/_next/static/chunks/app/(authenticated)/settings/roles/page-9001d02b28f70708.js +1 -0
  76. package/dist/app/_next/static/chunks/app/(authenticated)/settings/schema/page-899574f35091dd58.js +1 -0
  77. package/dist/app/_next/static/chunks/app/(authenticated)/settings/tasks/page-ad7ab3e27c83f44f.js +1 -0
  78. package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/edit/page-bd83414cb8c4cb04.js +1 -0
  79. package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/page-3181447f8772b1d3.js +1 -0
  80. package/dist/app/_next/static/chunks/app/(authenticated)/settings/tenants/page-ef9bfbacef5a1d73.js +1 -0
  81. package/dist/app/_next/static/chunks/app/(authenticated)/users/invites/page-480306b7b2bbac7e.js +1 -0
  82. package/dist/app/_next/static/chunks/app/(authenticated)/users/list/page-74da51254c2606b3.js +1 -0
  83. package/dist/app/_next/static/chunks/app/(authenticated)/users/page-e99c6f0b915001b2.js +1 -0
  84. package/dist/app/_next/static/chunks/app/(authenticated)/users/preferences/page-1a935630ce8f2b12.js +1 -0
  85. package/dist/app/_next/static/chunks/app/(authenticated)/users/user-roles/page-901dfb8ea1f39ca8.js +1 -0
  86. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/detail/page-9a6b839aea688ca4.js +1 -0
  87. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/edit/page-11774efbc2fecae2.js +1 -0
  88. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/execution/page-8ec1aea90412c03d.js +1 -0
  89. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/page-88bc5b36ccb0a1f7.js +1 -0
  90. package/dist/app/_next/static/chunks/app/(public)/forgot-password/page-ed263fd46ef81c20.js +1 -0
  91. package/dist/app/_next/static/chunks/app/(public)/layout-f538977545844af8.js +1 -0
  92. package/dist/app/_next/static/chunks/app/(public)/login/page-c0a10b137f346096.js +1 -0
  93. package/dist/app/_next/static/chunks/app/(public)/register/page-4cb7644893efd9b3.js +1 -0
  94. package/dist/app/_next/static/chunks/app/_not-found/page-653f8815b78256cc.js +1 -0
  95. package/dist/app/_next/static/chunks/app/layout-591ca7a3e16528a1.js +1 -0
  96. package/dist/app/_next/static/chunks/app/page-dd19d124b5fa2577.js +1 -0
  97. package/dist/app/_next/static/chunks/c37d3baf.c2ff165f5b02c692.js +1 -0
  98. package/dist/app/_next/static/chunks/d0deef33.0379166a4ec23470.js +1 -0
  99. package/dist/app/_next/static/chunks/fd9d1056-54169f07cd680d6c.js +1 -0
  100. package/dist/app/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
  101. package/dist/app/_next/static/chunks/main-324e91f5a430cddf.js +1 -0
  102. package/dist/app/_next/static/chunks/main-app-55bcae20c77aaf0e.js +1 -0
  103. package/dist/app/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
  104. package/dist/app/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
  105. package/dist/app/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  106. package/dist/app/_next/static/chunks/webpack-2c306566f7ee1b63.js +1 -0
  107. package/dist/app/_next/static/css/6c4002bae4e236b2.css +3 -0
  108. package/dist/app/_next/static/css/a275cc2b185e04f8.css +1 -0
  109. package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_buildManifest.js +1 -0
  110. package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_ssgManifest.js +1 -0
  111. package/dist/app/activity-log/all-activity/index.html +1 -0
  112. package/dist/app/activity-log/all-activity/index.txt +14 -0
  113. package/dist/app/activity-log/email-log/index.html +1 -0
  114. package/dist/app/activity-log/email-log/index.txt +14 -0
  115. package/dist/app/activity-log/index.html +1 -0
  116. package/dist/app/activity-log/index.txt +14 -0
  117. package/dist/app/activity-log/notifications/index.html +1 -0
  118. package/dist/app/activity-log/notifications/index.txt +14 -0
  119. package/dist/app/activity-log/sessions/index.html +1 -0
  120. package/dist/app/activity-log/sessions/index.txt +14 -0
  121. package/dist/app/activity-log/workflow-executions/index.html +1 -0
  122. package/dist/app/activity-log/workflow-executions/index.txt +14 -0
  123. package/dist/app/activity-log/workflow-logs/index.html +1 -0
  124. package/dist/app/activity-log/workflow-logs/index.txt +14 -0
  125. package/dist/app/change-password/index.html +1 -0
  126. package/dist/app/change-password/index.txt +14 -0
  127. package/dist/app/dashboard/index.html +1 -0
  128. package/dist/app/dashboard/index.txt +14 -0
  129. package/dist/app/data-browser/index.html +1 -0
  130. package/dist/app/data-browser/index.txt +14 -0
  131. package/dist/app/file-manager/index.html +1 -0
  132. package/dist/app/file-manager/index.txt +14 -0
  133. package/dist/app/forgot-password/index.html +1 -0
  134. package/dist/app/forgot-password/index.txt +13 -0
  135. package/dist/app/index.html +1 -0
  136. package/dist/app/index.txt +9 -0
  137. package/dist/app/login/index.html +1 -0
  138. package/dist/app/login/index.txt +13 -0
  139. package/dist/app/logo-dark.png +0 -0
  140. package/dist/app/logo-icon.svg +81 -0
  141. package/dist/app/logo-light.png +0 -0
  142. package/dist/app/register/index.html +1 -0
  143. package/dist/app/register/index.txt +13 -0
  144. package/dist/app/settings/migrations/index.html +1 -0
  145. package/dist/app/settings/migrations/index.txt +14 -0
  146. package/dist/app/settings/permissions/index.html +1 -0
  147. package/dist/app/settings/permissions/index.txt +14 -0
  148. package/dist/app/settings/project/index.html +1 -0
  149. package/dist/app/settings/project/index.txt +14 -0
  150. package/dist/app/settings/roles/index.html +1 -0
  151. package/dist/app/settings/roles/index.txt +14 -0
  152. package/dist/app/settings/schema/index.html +1 -0
  153. package/dist/app/settings/schema/index.txt +14 -0
  154. package/dist/app/settings/tasks/index.html +1 -0
  155. package/dist/app/settings/tasks/index.txt +14 -0
  156. package/dist/app/settings/templates/edit/index.html +1 -0
  157. package/dist/app/settings/templates/edit/index.txt +14 -0
  158. package/dist/app/settings/templates/index.html +1 -0
  159. package/dist/app/settings/templates/index.txt +14 -0
  160. package/dist/app/settings/tenants/index.html +1 -0
  161. package/dist/app/settings/tenants/index.txt +14 -0
  162. package/dist/app/users/index.html +1 -0
  163. package/dist/app/users/index.txt +14 -0
  164. package/dist/app/users/invites/index.html +1 -0
  165. package/dist/app/users/invites/index.txt +14 -0
  166. package/dist/app/users/list/index.html +1 -0
  167. package/dist/app/users/list/index.txt +14 -0
  168. package/dist/app/users/preferences/index.html +1 -0
  169. package/dist/app/users/preferences/index.txt +14 -0
  170. package/dist/app/users/user-roles/index.html +1 -0
  171. package/dist/app/users/user-roles/index.txt +14 -0
  172. package/dist/app/workflows/detail/index.html +1 -0
  173. package/dist/app/workflows/detail/index.txt +14 -0
  174. package/dist/app/workflows/edit/index.html +1 -0
  175. package/dist/app/workflows/edit/index.txt +14 -0
  176. package/dist/app/workflows/execution/index.html +1 -0
  177. package/dist/app/workflows/execution/index.txt +14 -0
  178. package/dist/app/workflows/index.html +1 -0
  179. package/dist/app/workflows/index.txt +14 -0
  180. package/dist/app.d.ts +36 -0
  181. package/dist/app.d.ts.map +1 -0
  182. package/dist/app.js +546 -0
  183. package/dist/app.js.map +1 -0
  184. package/dist/auth/adapters/baasix-adapter.d.ts +12 -0
  185. package/dist/auth/adapters/baasix-adapter.d.ts.map +1 -0
  186. package/dist/auth/adapters/baasix-adapter.js +318 -0
  187. package/dist/auth/adapters/baasix-adapter.js.map +1 -0
  188. package/dist/auth/adapters/index.d.ts +6 -0
  189. package/dist/auth/adapters/index.d.ts.map +1 -0
  190. package/dist/auth/adapters/index.js +5 -0
  191. package/dist/auth/adapters/index.js.map +1 -0
  192. package/dist/auth/core.d.ts +73 -0
  193. package/dist/auth/core.d.ts.map +1 -0
  194. package/dist/auth/core.js +528 -0
  195. package/dist/auth/core.js.map +1 -0
  196. package/dist/auth/index.d.ts +56 -0
  197. package/dist/auth/index.d.ts.map +1 -0
  198. package/dist/auth/index.js +58 -0
  199. package/dist/auth/index.js.map +1 -0
  200. package/dist/auth/oauth2/index.d.ts +5 -0
  201. package/dist/auth/oauth2/index.d.ts.map +1 -0
  202. package/dist/auth/oauth2/index.js +5 -0
  203. package/dist/auth/oauth2/index.js.map +1 -0
  204. package/dist/auth/oauth2/utils.d.ts +90 -0
  205. package/dist/auth/oauth2/utils.d.ts.map +1 -0
  206. package/dist/auth/oauth2/utils.js +167 -0
  207. package/dist/auth/oauth2/utils.js.map +1 -0
  208. package/dist/auth/providers/apple.d.ts +28 -0
  209. package/dist/auth/providers/apple.d.ts.map +1 -0
  210. package/dist/auth/providers/apple.js +192 -0
  211. package/dist/auth/providers/apple.js.map +1 -0
  212. package/dist/auth/providers/credential.d.ts +87 -0
  213. package/dist/auth/providers/credential.d.ts.map +1 -0
  214. package/dist/auth/providers/credential.js +162 -0
  215. package/dist/auth/providers/credential.js.map +1 -0
  216. package/dist/auth/providers/facebook.d.ts +26 -0
  217. package/dist/auth/providers/facebook.d.ts.map +1 -0
  218. package/dist/auth/providers/facebook.js +112 -0
  219. package/dist/auth/providers/facebook.js.map +1 -0
  220. package/dist/auth/providers/github.d.ts +29 -0
  221. package/dist/auth/providers/github.d.ts.map +1 -0
  222. package/dist/auth/providers/github.js +144 -0
  223. package/dist/auth/providers/github.js.map +1 -0
  224. package/dist/auth/providers/google.d.ts +32 -0
  225. package/dist/auth/providers/google.d.ts.map +1 -0
  226. package/dist/auth/providers/google.js +145 -0
  227. package/dist/auth/providers/google.js.map +1 -0
  228. package/dist/auth/providers/index.d.ts +22 -0
  229. package/dist/auth/providers/index.d.ts.map +1 -0
  230. package/dist/auth/providers/index.js +17 -0
  231. package/dist/auth/providers/index.js.map +1 -0
  232. package/dist/auth/routes.d.ts +63 -0
  233. package/dist/auth/routes.d.ts.map +1 -0
  234. package/dist/auth/routes.js +827 -0
  235. package/dist/auth/routes.js.map +1 -0
  236. package/dist/auth/services/index.d.ts +10 -0
  237. package/dist/auth/services/index.d.ts.map +1 -0
  238. package/dist/auth/services/index.js +7 -0
  239. package/dist/auth/services/index.js.map +1 -0
  240. package/dist/auth/services/session.d.ts +81 -0
  241. package/dist/auth/services/session.d.ts.map +1 -0
  242. package/dist/auth/services/session.js +186 -0
  243. package/dist/auth/services/session.js.map +1 -0
  244. package/dist/auth/services/token.d.ts +41 -0
  245. package/dist/auth/services/token.d.ts.map +1 -0
  246. package/dist/auth/services/token.js +44 -0
  247. package/dist/auth/services/token.js.map +1 -0
  248. package/dist/auth/services/verification.d.ts +77 -0
  249. package/dist/auth/services/verification.d.ts.map +1 -0
  250. package/dist/auth/services/verification.js +143 -0
  251. package/dist/auth/services/verification.js.map +1 -0
  252. package/dist/auth/types.d.ts +318 -0
  253. package/dist/auth/types.d.ts.map +1 -0
  254. package/dist/auth/types.js +6 -0
  255. package/dist/auth/types.js.map +1 -0
  256. package/dist/customTypes/arrays.d.ts +200 -0
  257. package/dist/customTypes/arrays.d.ts.map +1 -0
  258. package/dist/customTypes/arrays.js +309 -0
  259. package/dist/customTypes/arrays.js.map +1 -0
  260. package/dist/customTypes/index.d.ts +8 -0
  261. package/dist/customTypes/index.d.ts.map +1 -0
  262. package/dist/customTypes/index.js +11 -0
  263. package/dist/customTypes/index.js.map +1 -0
  264. package/dist/customTypes/postgis.d.ts +146 -0
  265. package/dist/customTypes/postgis.d.ts.map +1 -0
  266. package/dist/customTypes/postgis.js +315 -0
  267. package/dist/customTypes/postgis.js.map +1 -0
  268. package/dist/customTypes/ranges.d.ts +128 -0
  269. package/dist/customTypes/ranges.d.ts.map +1 -0
  270. package/dist/customTypes/ranges.js +257 -0
  271. package/dist/customTypes/ranges.js.map +1 -0
  272. package/dist/index.d.ts +37 -0
  273. package/dist/index.d.ts.map +1 -0
  274. package/dist/index.js +42 -0
  275. package/dist/index.js.map +1 -0
  276. package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts +29 -0
  277. package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts.map +1 -0
  278. package/dist/migrations/0.1.0-alpha.0_initial_setup.js +72 -0
  279. package/dist/migrations/0.1.0-alpha.0_initial_setup.js.map +1 -0
  280. package/dist/migrations/_example_migration.d.ts +31 -0
  281. package/dist/migrations/_example_migration.d.ts.map +1 -0
  282. package/dist/migrations/_example_migration.js +75 -0
  283. package/dist/migrations/_example_migration.js.map +1 -0
  284. package/dist/plugins/definePlugin.d.ts +49 -0
  285. package/dist/plugins/definePlugin.d.ts.map +1 -0
  286. package/dist/plugins/definePlugin.js +131 -0
  287. package/dist/plugins/definePlugin.js.map +1 -0
  288. package/dist/plugins/softDelete.d.ts +179 -0
  289. package/dist/plugins/softDelete.d.ts.map +1 -0
  290. package/dist/plugins/softDelete.js +235 -0
  291. package/dist/plugins/softDelete.js.map +1 -0
  292. package/dist/routes/auth.route.d.ts +14 -0
  293. package/dist/routes/auth.route.d.ts.map +1 -0
  294. package/dist/routes/auth.route.js +421 -0
  295. package/dist/routes/auth.route.js.map +1 -0
  296. package/dist/routes/file.route.d.ts +7 -0
  297. package/dist/routes/file.route.d.ts.map +1 -0
  298. package/dist/routes/file.route.js +274 -0
  299. package/dist/routes/file.route.js.map +1 -0
  300. package/dist/routes/items.route.d.ts +7 -0
  301. package/dist/routes/items.route.d.ts.map +1 -0
  302. package/dist/routes/items.route.js +369 -0
  303. package/dist/routes/items.route.js.map +1 -0
  304. package/dist/routes/migration.route.d.ts +7 -0
  305. package/dist/routes/migration.route.d.ts.map +1 -0
  306. package/dist/routes/migration.route.js +225 -0
  307. package/dist/routes/migration.route.js.map +1 -0
  308. package/dist/routes/notification.route.d.ts +7 -0
  309. package/dist/routes/notification.route.d.ts.map +1 -0
  310. package/dist/routes/notification.route.js +124 -0
  311. package/dist/routes/notification.route.js.map +1 -0
  312. package/dist/routes/openapi.route.d.ts +7 -0
  313. package/dist/routes/openapi.route.d.ts.map +1 -0
  314. package/dist/routes/openapi.route.js +2169 -0
  315. package/dist/routes/openapi.route.js.map +1 -0
  316. package/dist/routes/permission.route.d.ts +7 -0
  317. package/dist/routes/permission.route.d.ts.map +1 -0
  318. package/dist/routes/permission.route.js +158 -0
  319. package/dist/routes/permission.route.js.map +1 -0
  320. package/dist/routes/realtime.route.d.ts +21 -0
  321. package/dist/routes/realtime.route.d.ts.map +1 -0
  322. package/dist/routes/realtime.route.js +243 -0
  323. package/dist/routes/realtime.route.js.map +1 -0
  324. package/dist/routes/reports.route.d.ts +7 -0
  325. package/dist/routes/reports.route.d.ts.map +1 -0
  326. package/dist/routes/reports.route.js +95 -0
  327. package/dist/routes/reports.route.js.map +1 -0
  328. package/dist/routes/schema.route.d.ts +7 -0
  329. package/dist/routes/schema.route.d.ts.map +1 -0
  330. package/dist/routes/schema.route.js +1780 -0
  331. package/dist/routes/schema.route.js.map +1 -0
  332. package/dist/routes/settings.route.d.ts +7 -0
  333. package/dist/routes/settings.route.d.ts.map +1 -0
  334. package/dist/routes/settings.route.js +154 -0
  335. package/dist/routes/settings.route.js.map +1 -0
  336. package/dist/routes/templates.route.d.ts +7 -0
  337. package/dist/routes/templates.route.d.ts.map +1 -0
  338. package/dist/routes/templates.route.js +91 -0
  339. package/dist/routes/templates.route.js.map +1 -0
  340. package/dist/routes/utils.route.d.ts +7 -0
  341. package/dist/routes/utils.route.d.ts.map +1 -0
  342. package/dist/routes/utils.route.js +33 -0
  343. package/dist/routes/utils.route.js.map +1 -0
  344. package/dist/routes/workflow.route.d.ts +7 -0
  345. package/dist/routes/workflow.route.d.ts.map +1 -0
  346. package/dist/routes/workflow.route.js +787 -0
  347. package/dist/routes/workflow.route.js.map +1 -0
  348. package/dist/services/AssetsService.d.ts +39 -0
  349. package/dist/services/AssetsService.d.ts.map +1 -0
  350. package/dist/services/AssetsService.js +255 -0
  351. package/dist/services/AssetsService.js.map +1 -0
  352. package/dist/services/CacheService.d.ts +169 -0
  353. package/dist/services/CacheService.d.ts.map +1 -0
  354. package/dist/services/CacheService.js +722 -0
  355. package/dist/services/CacheService.js.map +1 -0
  356. package/dist/services/FilesService.d.ts +30 -0
  357. package/dist/services/FilesService.d.ts.map +1 -0
  358. package/dist/services/FilesService.js +268 -0
  359. package/dist/services/FilesService.js.map +1 -0
  360. package/dist/services/HooksManager.d.ts +38 -0
  361. package/dist/services/HooksManager.d.ts.map +1 -0
  362. package/dist/services/HooksManager.js +165 -0
  363. package/dist/services/HooksManager.js.map +1 -0
  364. package/dist/services/ItemsService.d.ts +273 -0
  365. package/dist/services/ItemsService.d.ts.map +1 -0
  366. package/dist/services/ItemsService.js +2458 -0
  367. package/dist/services/ItemsService.js.map +1 -0
  368. package/dist/services/MailService.d.ts +76 -0
  369. package/dist/services/MailService.d.ts.map +1 -0
  370. package/dist/services/MailService.js +585 -0
  371. package/dist/services/MailService.js.map +1 -0
  372. package/dist/services/MigrationService.d.ts +243 -0
  373. package/dist/services/MigrationService.d.ts.map +1 -0
  374. package/dist/services/MigrationService.js +914 -0
  375. package/dist/services/MigrationService.js.map +1 -0
  376. package/dist/services/NotificationService.d.ts +35 -0
  377. package/dist/services/NotificationService.d.ts.map +1 -0
  378. package/dist/services/NotificationService.js +159 -0
  379. package/dist/services/NotificationService.js.map +1 -0
  380. package/dist/services/PermissionService.d.ts +128 -0
  381. package/dist/services/PermissionService.d.ts.map +1 -0
  382. package/dist/services/PermissionService.js +373 -0
  383. package/dist/services/PermissionService.js.map +1 -0
  384. package/dist/services/PluginManager.d.ts +138 -0
  385. package/dist/services/PluginManager.d.ts.map +1 -0
  386. package/dist/services/PluginManager.js +463 -0
  387. package/dist/services/PluginManager.js.map +1 -0
  388. package/dist/services/RealtimeService.d.ts +209 -0
  389. package/dist/services/RealtimeService.d.ts.map +1 -0
  390. package/dist/services/RealtimeService.js +978 -0
  391. package/dist/services/RealtimeService.js.map +1 -0
  392. package/dist/services/ReportService.d.ts +13 -0
  393. package/dist/services/ReportService.d.ts.map +1 -0
  394. package/dist/services/ReportService.js +91 -0
  395. package/dist/services/ReportService.js.map +1 -0
  396. package/dist/services/SettingsService.d.ts +60 -0
  397. package/dist/services/SettingsService.d.ts.map +1 -0
  398. package/dist/services/SettingsService.js +474 -0
  399. package/dist/services/SettingsService.js.map +1 -0
  400. package/dist/services/SocketService.d.ts +129 -0
  401. package/dist/services/SocketService.d.ts.map +1 -0
  402. package/dist/services/SocketService.js +600 -0
  403. package/dist/services/SocketService.js.map +1 -0
  404. package/dist/services/StatsService.d.ts +10 -0
  405. package/dist/services/StatsService.d.ts.map +1 -0
  406. package/dist/services/StatsService.js +40 -0
  407. package/dist/services/StatsService.js.map +1 -0
  408. package/dist/services/StorageService.d.ts +20 -0
  409. package/dist/services/StorageService.d.ts.map +1 -0
  410. package/dist/services/StorageService.js +164 -0
  411. package/dist/services/StorageService.js.map +1 -0
  412. package/dist/services/TasksService.d.ts +74 -0
  413. package/dist/services/TasksService.d.ts.map +1 -0
  414. package/dist/services/TasksService.js +404 -0
  415. package/dist/services/TasksService.js.map +1 -0
  416. package/dist/services/WorkflowService.d.ts +305 -0
  417. package/dist/services/WorkflowService.d.ts.map +1 -0
  418. package/dist/services/WorkflowService.js +1811 -0
  419. package/dist/services/WorkflowService.js.map +1 -0
  420. package/dist/templates/logo/logo.png +0 -0
  421. package/dist/templates/mails/default.liquid +23 -0
  422. package/dist/types/aggregation.d.ts +40 -0
  423. package/dist/types/aggregation.d.ts.map +1 -0
  424. package/dist/types/aggregation.js +6 -0
  425. package/dist/types/aggregation.js.map +1 -0
  426. package/dist/types/assets.d.ts +32 -0
  427. package/dist/types/assets.d.ts.map +1 -0
  428. package/dist/types/assets.js +6 -0
  429. package/dist/types/assets.js.map +1 -0
  430. package/dist/types/auth.d.ts +50 -0
  431. package/dist/types/auth.d.ts.map +1 -0
  432. package/dist/types/auth.js +6 -0
  433. package/dist/types/auth.js.map +1 -0
  434. package/dist/types/cache.d.ts +47 -0
  435. package/dist/types/cache.d.ts.map +1 -0
  436. package/dist/types/cache.js +6 -0
  437. package/dist/types/cache.js.map +1 -0
  438. package/dist/types/database.d.ts +16 -0
  439. package/dist/types/database.d.ts.map +1 -0
  440. package/dist/types/database.js +6 -0
  441. package/dist/types/database.js.map +1 -0
  442. package/dist/types/fields.d.ts +71 -0
  443. package/dist/types/fields.d.ts.map +1 -0
  444. package/dist/types/fields.js +6 -0
  445. package/dist/types/fields.js.map +1 -0
  446. package/dist/types/files.d.ts +33 -0
  447. package/dist/types/files.d.ts.map +1 -0
  448. package/dist/types/files.js +6 -0
  449. package/dist/types/files.js.map +1 -0
  450. package/dist/types/hooks.d.ts +29 -0
  451. package/dist/types/hooks.d.ts.map +1 -0
  452. package/dist/types/hooks.js +6 -0
  453. package/dist/types/hooks.js.map +1 -0
  454. package/dist/types/import-export.d.ts +62 -0
  455. package/dist/types/import-export.d.ts.map +1 -0
  456. package/dist/types/import-export.js +6 -0
  457. package/dist/types/import-export.js.map +1 -0
  458. package/dist/types/index.d.ts +31 -0
  459. package/dist/types/index.d.ts.map +1 -0
  460. package/dist/types/index.js +58 -0
  461. package/dist/types/index.js.map +1 -0
  462. package/dist/types/mail.d.ts +34 -0
  463. package/dist/types/mail.d.ts.map +1 -0
  464. package/dist/types/mail.js +6 -0
  465. package/dist/types/mail.js.map +1 -0
  466. package/dist/types/notifications.d.ts +16 -0
  467. package/dist/types/notifications.d.ts.map +1 -0
  468. package/dist/types/notifications.js +6 -0
  469. package/dist/types/notifications.js.map +1 -0
  470. package/dist/types/plugin.d.ts +351 -0
  471. package/dist/types/plugin.d.ts.map +1 -0
  472. package/dist/types/plugin.js +8 -0
  473. package/dist/types/plugin.js.map +1 -0
  474. package/dist/types/query.d.ts +71 -0
  475. package/dist/types/query.d.ts.map +1 -0
  476. package/dist/types/query.js +6 -0
  477. package/dist/types/query.js.map +1 -0
  478. package/dist/types/relations.d.ts +111 -0
  479. package/dist/types/relations.d.ts.map +1 -0
  480. package/dist/types/relations.js +6 -0
  481. package/dist/types/relations.js.map +1 -0
  482. package/dist/types/reports.d.ts +17 -0
  483. package/dist/types/reports.d.ts.map +1 -0
  484. package/dist/types/reports.js +6 -0
  485. package/dist/types/reports.js.map +1 -0
  486. package/dist/types/schema.d.ts +26 -0
  487. package/dist/types/schema.d.ts.map +1 -0
  488. package/dist/types/schema.js +6 -0
  489. package/dist/types/schema.js.map +1 -0
  490. package/dist/types/seed.d.ts +27 -0
  491. package/dist/types/seed.d.ts.map +1 -0
  492. package/dist/types/seed.js +6 -0
  493. package/dist/types/seed.js.map +1 -0
  494. package/dist/types/services.d.ts +68 -0
  495. package/dist/types/services.d.ts.map +1 -0
  496. package/dist/types/services.js +6 -0
  497. package/dist/types/services.js.map +1 -0
  498. package/dist/types/settings.d.ts +36 -0
  499. package/dist/types/settings.d.ts.map +1 -0
  500. package/dist/types/settings.js +6 -0
  501. package/dist/types/settings.js.map +1 -0
  502. package/dist/types/sockets.d.ts +26 -0
  503. package/dist/types/sockets.d.ts.map +1 -0
  504. package/dist/types/sockets.js +6 -0
  505. package/dist/types/sockets.js.map +1 -0
  506. package/dist/types/sort.d.ts +25 -0
  507. package/dist/types/sort.d.ts.map +1 -0
  508. package/dist/types/sort.js +6 -0
  509. package/dist/types/sort.js.map +1 -0
  510. package/dist/types/spatial.d.ts +19 -0
  511. package/dist/types/spatial.d.ts.map +1 -0
  512. package/dist/types/spatial.js +6 -0
  513. package/dist/types/spatial.js.map +1 -0
  514. package/dist/types/stats.d.ts +21 -0
  515. package/dist/types/stats.d.ts.map +1 -0
  516. package/dist/types/stats.js +6 -0
  517. package/dist/types/stats.js.map +1 -0
  518. package/dist/types/storage.d.ts +19 -0
  519. package/dist/types/storage.d.ts.map +1 -0
  520. package/dist/types/storage.js +6 -0
  521. package/dist/types/storage.js.map +1 -0
  522. package/dist/types/tasks.d.ts +14 -0
  523. package/dist/types/tasks.d.ts.map +1 -0
  524. package/dist/types/tasks.js +6 -0
  525. package/dist/types/tasks.js.map +1 -0
  526. package/dist/types/utils.d.ts +54 -0
  527. package/dist/types/utils.d.ts.map +1 -0
  528. package/dist/types/utils.js +6 -0
  529. package/dist/types/utils.js.map +1 -0
  530. package/dist/types/workflow.d.ts +17 -0
  531. package/dist/types/workflow.d.ts.map +1 -0
  532. package/dist/types/workflow.js +6 -0
  533. package/dist/types/workflow.js.map +1 -0
  534. package/dist/utils/aggregationUtils.d.ts +192 -0
  535. package/dist/utils/aggregationUtils.d.ts.map +1 -0
  536. package/dist/utils/aggregationUtils.js +450 -0
  537. package/dist/utils/aggregationUtils.js.map +1 -0
  538. package/dist/utils/auth.d.ts +93 -0
  539. package/dist/utils/auth.d.ts.map +1 -0
  540. package/dist/utils/auth.js +557 -0
  541. package/dist/utils/auth.js.map +1 -0
  542. package/dist/utils/cache.d.ts +64 -0
  543. package/dist/utils/cache.d.ts.map +1 -0
  544. package/dist/utils/cache.js +464 -0
  545. package/dist/utils/cache.js.map +1 -0
  546. package/dist/utils/common.d.ts +53 -0
  547. package/dist/utils/common.d.ts.map +1 -0
  548. package/dist/utils/common.js +162 -0
  549. package/dist/utils/common.js.map +1 -0
  550. package/dist/utils/db.d.ts +101 -0
  551. package/dist/utils/db.d.ts.map +1 -0
  552. package/dist/utils/db.js +413 -0
  553. package/dist/utils/db.js.map +1 -0
  554. package/dist/utils/dirname.d.ts +30 -0
  555. package/dist/utils/dirname.d.ts.map +1 -0
  556. package/dist/utils/dirname.js +95 -0
  557. package/dist/utils/dirname.js.map +1 -0
  558. package/dist/utils/dynamicVariableResolver.d.ts +17 -0
  559. package/dist/utils/dynamicVariableResolver.d.ts.map +1 -0
  560. package/dist/utils/dynamicVariableResolver.js +262 -0
  561. package/dist/utils/dynamicVariableResolver.js.map +1 -0
  562. package/dist/utils/env.d.ts +38 -0
  563. package/dist/utils/env.d.ts.map +1 -0
  564. package/dist/utils/env.js +80 -0
  565. package/dist/utils/env.js.map +1 -0
  566. package/dist/utils/errorHandler.d.ts +14 -0
  567. package/dist/utils/errorHandler.d.ts.map +1 -0
  568. package/dist/utils/errorHandler.js +79 -0
  569. package/dist/utils/errorHandler.js.map +1 -0
  570. package/dist/utils/fieldExpansion.d.ts +30 -0
  571. package/dist/utils/fieldExpansion.d.ts.map +1 -0
  572. package/dist/utils/fieldExpansion.js +145 -0
  573. package/dist/utils/fieldExpansion.js.map +1 -0
  574. package/dist/utils/fieldUtils.d.ts +179 -0
  575. package/dist/utils/fieldUtils.d.ts.map +1 -0
  576. package/dist/utils/fieldUtils.js +424 -0
  577. package/dist/utils/fieldUtils.js.map +1 -0
  578. package/dist/utils/filterOperators.d.ts +472 -0
  579. package/dist/utils/filterOperators.d.ts.map +1 -0
  580. package/dist/utils/filterOperators.js +1229 -0
  581. package/dist/utils/filterOperators.js.map +1 -0
  582. package/dist/utils/importUtils.d.ts +127 -0
  583. package/dist/utils/importUtils.d.ts.map +1 -0
  584. package/dist/utils/importUtils.js +437 -0
  585. package/dist/utils/importUtils.js.map +1 -0
  586. package/dist/utils/index.d.ts +75 -0
  587. package/dist/utils/index.d.ts.map +1 -0
  588. package/dist/utils/index.js +101 -0
  589. package/dist/utils/index.js.map +1 -0
  590. package/dist/utils/logger.d.ts +41 -0
  591. package/dist/utils/logger.d.ts.map +1 -0
  592. package/dist/utils/logger.js +217 -0
  593. package/dist/utils/logger.js.map +1 -0
  594. package/dist/utils/orderUtils.d.ts +117 -0
  595. package/dist/utils/orderUtils.d.ts.map +1 -0
  596. package/dist/utils/orderUtils.js +249 -0
  597. package/dist/utils/orderUtils.js.map +1 -0
  598. package/dist/utils/queryBuilder.d.ts +118 -0
  599. package/dist/utils/queryBuilder.d.ts.map +1 -0
  600. package/dist/utils/queryBuilder.js +489 -0
  601. package/dist/utils/queryBuilder.js.map +1 -0
  602. package/dist/utils/relationLoader.d.ts +65 -0
  603. package/dist/utils/relationLoader.d.ts.map +1 -0
  604. package/dist/utils/relationLoader.js +1081 -0
  605. package/dist/utils/relationLoader.js.map +1 -0
  606. package/dist/utils/relationPathResolver.d.ts +30 -0
  607. package/dist/utils/relationPathResolver.d.ts.map +1 -0
  608. package/dist/utils/relationPathResolver.js +173 -0
  609. package/dist/utils/relationPathResolver.js.map +1 -0
  610. package/dist/utils/relationUtils.d.ts +139 -0
  611. package/dist/utils/relationUtils.d.ts.map +1 -0
  612. package/dist/utils/relationUtils.js +711 -0
  613. package/dist/utils/relationUtils.js.map +1 -0
  614. package/dist/utils/router.d.ts +6 -0
  615. package/dist/utils/router.d.ts.map +1 -0
  616. package/dist/utils/router.js +95 -0
  617. package/dist/utils/router.js.map +1 -0
  618. package/dist/utils/schema.d.ts +88 -0
  619. package/dist/utils/schema.d.ts.map +1 -0
  620. package/dist/utils/schema.js +24 -0
  621. package/dist/utils/schema.js.map +1 -0
  622. package/dist/utils/schemaManager.d.ts +238 -0
  623. package/dist/utils/schemaManager.d.ts.map +1 -0
  624. package/dist/utils/schemaManager.js +1992 -0
  625. package/dist/utils/schemaManager.js.map +1 -0
  626. package/dist/utils/schemaValidator.d.ts +83 -0
  627. package/dist/utils/schemaValidator.d.ts.map +1 -0
  628. package/dist/utils/schemaValidator.js +491 -0
  629. package/dist/utils/schemaValidator.js.map +1 -0
  630. package/dist/utils/seed.d.ts +45 -0
  631. package/dist/utils/seed.d.ts.map +1 -0
  632. package/dist/utils/seed.js +248 -0
  633. package/dist/utils/seed.js.map +1 -0
  634. package/dist/utils/sessionCleanup.d.ts +10 -0
  635. package/dist/utils/sessionCleanup.d.ts.map +1 -0
  636. package/dist/utils/sessionCleanup.js +49 -0
  637. package/dist/utils/sessionCleanup.js.map +1 -0
  638. package/dist/utils/sortUtils.d.ts +117 -0
  639. package/dist/utils/sortUtils.d.ts.map +1 -0
  640. package/dist/utils/sortUtils.js +232 -0
  641. package/dist/utils/sortUtils.js.map +1 -0
  642. package/dist/utils/spatialUtils.d.ts +244 -0
  643. package/dist/utils/spatialUtils.d.ts.map +1 -0
  644. package/dist/utils/spatialUtils.js +359 -0
  645. package/dist/utils/spatialUtils.js.map +1 -0
  646. package/dist/utils/systemschema.d.ts +11040 -0
  647. package/dist/utils/systemschema.d.ts.map +1 -0
  648. package/dist/utils/systemschema.js +1777 -0
  649. package/dist/utils/systemschema.js.map +1 -0
  650. package/dist/utils/tenantUtils.d.ts +34 -0
  651. package/dist/utils/tenantUtils.d.ts.map +1 -0
  652. package/dist/utils/tenantUtils.js +124 -0
  653. package/dist/utils/tenantUtils.js.map +1 -0
  654. package/dist/utils/typeMapper.d.ts +25 -0
  655. package/dist/utils/typeMapper.d.ts.map +1 -0
  656. package/dist/utils/typeMapper.js +282 -0
  657. package/dist/utils/typeMapper.js.map +1 -0
  658. package/dist/utils/valueValidator.d.ts +60 -0
  659. package/dist/utils/valueValidator.d.ts.map +1 -0
  660. package/dist/utils/valueValidator.js +303 -0
  661. package/dist/utils/valueValidator.js.map +1 -0
  662. package/dist/utils/workflow.d.ts +87 -0
  663. package/dist/utils/workflow.d.ts.map +1 -0
  664. package/dist/utils/workflow.js +205 -0
  665. package/dist/utils/workflow.js.map +1 -0
  666. package/package.json +115 -0
@@ -0,0 +1,1229 @@
1
+ /**
2
+ * Filter Operators Module for Drizzle ORM
3
+ *
4
+ * This module provides a comprehensive set of filter operators that map
5
+ * Sequelize-style filter syntax to Drizzle ORM where conditions.
6
+ *
7
+ * Supports:
8
+ * - Basic comparison operators (eq, ne, gt, lt, gte, lte)
9
+ * - String pattern matching (like, ilike, startsWith, endsWith)
10
+ * - Collection operators (in, notIn)
11
+ * - Range operators (between, notBetween)
12
+ * - Null checks (isNull, isNotNull)
13
+ * - Array operators (arraycontains, arraycontained)
14
+ * - JSONB operators (jsonbContains, jsonbHasKey, jsonbPathExists, etc.)
15
+ * - Geo/spatial operators (within, contains, intersects, dwithin)
16
+ * - Column-to-column comparisons with $COL() syntax
17
+ * - Type casting with PostgreSQL :: syntax
18
+ */
19
+ import { eq, ne, gt, gte, lt, lte, isNull, isNotNull, inArray, notInArray, between, notBetween, like, ilike, notLike, notIlike, sql } from 'drizzle-orm';
20
+ /**
21
+ * Valid PostgreSQL cast types to prevent SQL injection
22
+ */
23
+ const VALID_CAST_TYPES = [
24
+ 'text', 'varchar', 'char', 'character',
25
+ 'integer', 'int', 'bigint', 'smallint',
26
+ 'decimal', 'numeric', 'real', 'double precision', 'float',
27
+ 'boolean', 'bool',
28
+ 'date', 'timestamp', 'timestamptz', 'time', 'timetz',
29
+ 'uuid', 'json', 'jsonb',
30
+ 'text[]', 'varchar[]', 'integer[]', 'bigint[]', 'uuid[]'
31
+ ];
32
+ /**
33
+ * Validate PostgreSQL cast type to prevent SQL injection
34
+ */
35
+ function validateCastType(castType) {
36
+ if (!castType)
37
+ return null;
38
+ const normalizedType = castType.toLowerCase().trim();
39
+ if (VALID_CAST_TYPES.includes(normalizedType)) {
40
+ return normalizedType;
41
+ }
42
+ // Invalid cast types are silently ignored (return null to skip casting)
43
+ console.warn(`Invalid cast type "${castType}" will be ignored. Allowed types: ${VALID_CAST_TYPES.join(', ')}`);
44
+ return null;
45
+ }
46
+ /**
47
+ * Check if a value is a column reference
48
+ * Format: $COL(columnName) or $COL(tableName.columnName)
49
+ */
50
+ export function isColumnReference(value) {
51
+ return typeof value === 'string' && value.startsWith('$COL(') && value.endsWith(')');
52
+ }
53
+ /**
54
+ * Extract column name/path from column reference
55
+ */
56
+ export function extractColumnFromReference(value) {
57
+ return value.slice(5, -1); // Remove '$COL(' and ')'
58
+ }
59
+ /**
60
+ * Parse PostgreSQL casting syntax from column reference
61
+ * Example: "columnName::text" -> { columnPath: "columnName", castType: "text" }
62
+ */
63
+ export function parseColumnCastSyntax(columnPath) {
64
+ const castMatch = columnPath.match(/^(.+)::(.+)$/);
65
+ if (castMatch) {
66
+ return {
67
+ columnPath: castMatch[1],
68
+ castType: castMatch[2]
69
+ };
70
+ }
71
+ return {
72
+ columnPath,
73
+ castType: null
74
+ };
75
+ }
76
+ /**
77
+ * Build SQL identifier for column with optional casting
78
+ */
79
+ export function buildColumnSQL(columnPath, castType) {
80
+ const validated = validateCastType(castType || undefined);
81
+ // Check if columnPath is already quoted (e.g., from resolveRelationPath)
82
+ // Format: "alias"."column" or "column"
83
+ if (columnPath.startsWith('"')) {
84
+ // Already quoted, use as-is without nesting sql templates
85
+ return validated ? sql.raw(`CAST(${columnPath} AS ${validated.toUpperCase()})`) : sql.raw(columnPath);
86
+ }
87
+ if (columnPath.includes('.')) {
88
+ const [tableName, columnName] = columnPath.split('.');
89
+ const quotedPath = `"${tableName}"."${columnName}"`;
90
+ return validated ? sql.raw(`CAST(${quotedPath} AS ${validated.toUpperCase()})`) : sql.raw(quotedPath);
91
+ }
92
+ const quotedPath = `"${columnPath}"`;
93
+ return validated ? sql.raw(`CAST(${quotedPath} AS ${validated.toUpperCase()})`) : sql.raw(quotedPath);
94
+ }
95
+ /**
96
+ * Build raw SQL string for column identifier (without wrapping in SQL object)
97
+ * Used when we need to build a completely raw SQL expression
98
+ */
99
+ function buildColumnSQLString(columnPath, castType) {
100
+ const validated = validateCastType(castType || undefined);
101
+ // Check if columnPath is already quoted (e.g., from resolveRelationPath)
102
+ // Format: "alias"."column" or "column"
103
+ let quotedPath;
104
+ if (columnPath.startsWith('"')) {
105
+ // Already quoted, use as-is
106
+ quotedPath = columnPath;
107
+ }
108
+ else if (columnPath.includes('.')) {
109
+ const [tableName, columnName] = columnPath.split('.');
110
+ quotedPath = `"${tableName}"."${columnName}"`;
111
+ }
112
+ else {
113
+ quotedPath = `"${columnPath}"`;
114
+ }
115
+ return validated ? `CAST(${quotedPath} AS ${validated.toUpperCase()})` : quotedPath;
116
+ }
117
+ /**
118
+ * Safely escape SQL string values
119
+ */
120
+ function escapeSqlValue(value) {
121
+ return String(value).replace(/'/g, "''");
122
+ }
123
+ /**
124
+ * Convert a value to a raw SQL string literal for use in filter operations
125
+ * Handles dates, strings, and numbers appropriately
126
+ */
127
+ function valueToRawSQL(value) {
128
+ console.log(`[valueToRawSQL] Input value:`, value, `Type:`, typeof value);
129
+ if (typeof value === 'string') {
130
+ // Check if it's a date-like string (YYYY-MM-DD or ISO format)
131
+ const datePattern = /^\d{4}-\d{2}-\d{2}/;
132
+ if (datePattern.test(value)) {
133
+ const dateObj = new Date(value);
134
+ if (!isNaN(dateObj.getTime())) {
135
+ const result = `'${dateObj.toISOString()}'`;
136
+ console.log(`[valueToRawSQL] Date string converted:`, result);
137
+ return result;
138
+ }
139
+ }
140
+ // Regular string - escape and quote
141
+ const result = `'${value.replace(/'/g, "''")}'`;
142
+ console.log(`[valueToRawSQL] String escaped:`, result);
143
+ return result;
144
+ }
145
+ else if (value instanceof Date) {
146
+ const result = `'${value.toISOString()}'`;
147
+ console.log(`[valueToRawSQL] Date object converted:`, result);
148
+ return result;
149
+ }
150
+ else {
151
+ // Numbers and other types - no quotes
152
+ const result = String(value);
153
+ console.log(`[valueToRawSQL] Number/other:`, result);
154
+ return result;
155
+ }
156
+ }
157
+ /**
158
+ * Normalize date values - convert datetime strings to Date objects
159
+ * Keep date-only strings (YYYY-MM-DD) as strings for Date type columns
160
+ * Convert datetime strings (YYYY-MM-DDTHH:MM:SS) to Date objects for DateTime/Timestamp columns
161
+ */
162
+ function normalizeDateValue(value) {
163
+ // If already a Date, return as-is
164
+ if (value instanceof Date) {
165
+ return value;
166
+ }
167
+ // If it's a string that looks like a datetime (has time component), convert to Date
168
+ if (typeof value === 'string') {
169
+ // Check if it's a full datetime string (has time component)
170
+ const datetimePattern = /^\d{4}-\d{2}-\d{2}[T\s]\d{2}:\d{2}/;
171
+ if (datetimePattern.test(value)) {
172
+ const parsedDate = new Date(value);
173
+ if (!isNaN(parsedDate.getTime())) {
174
+ return parsedDate;
175
+ }
176
+ }
177
+ // For date-only strings (YYYY-MM-DD), keep as string
178
+ // This is needed for Date type columns which expect strings, not Date objects
179
+ }
180
+ // Return as-is for other types (including date-only strings)
181
+ return value;
182
+ }
183
+ /**
184
+ * Format array values based on PostgreSQL element type
185
+ */
186
+ function formatArrayForPostgreSQL(value, elementType) {
187
+ const arrayValue = Array.isArray(value) ? value : [value];
188
+ switch (elementType.toLowerCase()) {
189
+ case 'integer':
190
+ case 'bigint':
191
+ return `ARRAY[${arrayValue.map(v => parseInt(String(v)) || 0).join(',')}]`;
192
+ case 'decimal':
193
+ case 'numeric':
194
+ case 'real':
195
+ case 'double precision':
196
+ return `ARRAY[${arrayValue.map(v => parseFloat(String(v)) || 0).join(',')}]`;
197
+ case 'boolean':
198
+ return `ARRAY[${arrayValue.map(v => Boolean(v)).join(',')}]`;
199
+ case 'uuid':
200
+ return `ARRAY[${arrayValue.map(v => `'${escapeSqlValue(v)}'`).join(',')}]::uuid[]`;
201
+ case 'date':
202
+ case 'dateonly':
203
+ case 'time':
204
+ return `ARRAY[${arrayValue.map(v => `'${escapeSqlValue(v)}'`).join(',')}]::${elementType}[]`;
205
+ case 'string':
206
+ case 'text':
207
+ case 'varchar':
208
+ default:
209
+ return `ARRAY[${arrayValue.map(v => `'${escapeSqlValue(v)}'`).join(',')}]::text[]`;
210
+ }
211
+ }
212
+ /**
213
+ * Operator: Equality (eq)
214
+ * Example: { age: { eq: 25 } } -> age = 25
215
+ */
216
+ export function eqOperator(ctx, value, castType) {
217
+ if (isColumnReference(value)) {
218
+ const rightCol = extractColumnFromReference(value);
219
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
220
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
221
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
222
+ return sql `${leftSQL} = ${rightSQL}`;
223
+ }
224
+ // Normalize date values (convert string dates to Date objects)
225
+ const normalizedValue = normalizeDateValue(value);
226
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
227
+ if (castType || ctx.tableName) {
228
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
229
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
230
+ const rightSQL = valueToRawSQL(normalizedValue);
231
+ return sql.raw(`${leftSQL} = ${rightSQL}`);
232
+ }
233
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
234
+ return eq(ctx.column, normalizedValue);
235
+ }
236
+ /**
237
+ * Operator: Not Equal (ne)
238
+ * Example: { status: { ne: 'inactive' } } -> status != 'inactive'
239
+ * Example: { contract_number: { ne: null } } -> contract_number IS NOT NULL
240
+ */
241
+ export function neOperator(ctx, value, castType) {
242
+ if (isColumnReference(value)) {
243
+ const rightCol = extractColumnFromReference(value);
244
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
245
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
246
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
247
+ return sql `${leftSQL} != ${rightSQL}`;
248
+ }
249
+ // Special handling for null values - must use IS NOT NULL syntax
250
+ if (value === null) {
251
+ if (castType || ctx.tableName) {
252
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
253
+ return sql `${leftSQL} IS NOT NULL`;
254
+ }
255
+ return isNotNull(ctx.column);
256
+ }
257
+ // Normalize date values (convert string dates to Date objects)
258
+ const normalizedValue = normalizeDateValue(value);
259
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
260
+ if (castType || ctx.tableName) {
261
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
262
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
263
+ const rightSQL = valueToRawSQL(normalizedValue);
264
+ return sql.raw(`${leftSQL} != ${rightSQL}`);
265
+ }
266
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
267
+ return ne(ctx.column, normalizedValue);
268
+ }
269
+ /**
270
+ * Operator: Greater Than (gt)
271
+ * Example: { age: { gt: 18 } } -> age > 18
272
+ */
273
+ export function gtOperator(ctx, value, castType) {
274
+ if (isColumnReference(value)) {
275
+ const rightCol = extractColumnFromReference(value);
276
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
277
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
278
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
279
+ return sql `${leftSQL} > ${rightSQL}`;
280
+ }
281
+ // Normalize date values (convert string dates to Date objects)
282
+ const normalizedValue = normalizeDateValue(value);
283
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
284
+ if (castType || ctx.tableName) {
285
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
286
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
287
+ const rightSQL = valueToRawSQL(normalizedValue);
288
+ return sql.raw(`${leftSQL} > ${rightSQL}`);
289
+ }
290
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
291
+ return gt(ctx.column, normalizedValue);
292
+ }
293
+ /**
294
+ * Operator: Greater Than or Equal (gte)
295
+ * Example: { age: { gte: 18 } } -> age >= 18
296
+ */
297
+ export function gteOperator(ctx, value, castType) {
298
+ if (isColumnReference(value)) {
299
+ const rightCol = extractColumnFromReference(value);
300
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
301
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
302
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
303
+ return sql `${leftSQL} >= ${rightSQL}`;
304
+ }
305
+ // Normalize date values (convert string dates to Date objects)
306
+ const normalizedValue = normalizeDateValue(value);
307
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
308
+ if (castType || ctx.tableName) {
309
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
310
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
311
+ const rightSQL = valueToRawSQL(normalizedValue);
312
+ return sql.raw(`${leftSQL} >= ${rightSQL}`);
313
+ }
314
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
315
+ return gte(ctx.column, normalizedValue);
316
+ }
317
+ /**
318
+ * Operator: Less Than (lt)
319
+ * Example: { age: { lt: 65 } } -> age < 65
320
+ */
321
+ export function ltOperator(ctx, value, castType) {
322
+ if (isColumnReference(value)) {
323
+ const rightCol = extractColumnFromReference(value);
324
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
325
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
326
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
327
+ return sql `${leftSQL} < ${rightSQL}`;
328
+ }
329
+ // Normalize date values (convert string dates to Date objects)
330
+ const normalizedValue = normalizeDateValue(value);
331
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
332
+ if (castType || ctx.tableName) {
333
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
334
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
335
+ const rightSQL = valueToRawSQL(normalizedValue);
336
+ return sql.raw(`${leftSQL} < ${rightSQL}`);
337
+ }
338
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
339
+ return lt(ctx.column, normalizedValue);
340
+ }
341
+ /**
342
+ * Operator: Less Than or Equal (lte)
343
+ * Example: { age: { lte: 65 } } -> age <= 65
344
+ */
345
+ export function lteOperator(ctx, value, castType) {
346
+ if (isColumnReference(value)) {
347
+ const rightCol = extractColumnFromReference(value);
348
+ const { columnPath, castType: rightCast } = parseColumnCastSyntax(rightCol);
349
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
350
+ const rightSQL = buildColumnSQL(columnPath, rightCast || castType);
351
+ return sql `${leftSQL} <= ${rightSQL}`;
352
+ }
353
+ // Normalize date values (convert string dates to Date objects)
354
+ const normalizedValue = normalizeDateValue(value);
355
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
356
+ if (castType || ctx.tableName) {
357
+ // Build the entire expression as raw SQL to completely bypass Drizzle's type mappers
358
+ const leftSQL = buildColumnSQLString(ctx.fieldName, castType);
359
+ const rightSQL = valueToRawSQL(normalizedValue);
360
+ return sql.raw(`${leftSQL} <= ${rightSQL}`);
361
+ }
362
+ // For Drizzle operators, keep as Date object (Drizzle's column mappers expect Date objects)
363
+ return lte(ctx.column, normalizedValue);
364
+ }
365
+ /**
366
+ * Operator: LIKE (case-sensitive pattern matching)
367
+ * Example: { name: { like: 'John' } } -> name LIKE '%John%'
368
+ */
369
+ export function likeOperator(ctx, value, castType) {
370
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
371
+ if (castType || ctx.tableName) {
372
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
373
+ return sql `${leftSQL} LIKE ${'%' + escapeSqlValue(value) + '%'}`;
374
+ }
375
+ return like(ctx.column, `%${value}%`);
376
+ }
377
+ /**
378
+ * Operator: NOT LIKE (case-sensitive pattern non-matching)
379
+ */
380
+ export function notLikeOperator(ctx, value, castType) {
381
+ if (castType || ctx.tableName) {
382
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
383
+ return sql `${leftSQL} NOT LIKE ${'%' + escapeSqlValue(value) + '%'}`;
384
+ }
385
+ return notLike(ctx.column, `%${value}%`);
386
+ }
387
+ /**
388
+ * Operator: ILIKE (case-insensitive pattern matching)
389
+ * Example: { name: { iLike: 'john' } } -> name ILIKE '%john%'
390
+ */
391
+ export function iLikeOperator(ctx, value, castType) {
392
+ if (castType || ctx.tableName) {
393
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
394
+ return sql `${leftSQL} ILIKE ${'%' + escapeSqlValue(value) + '%'}`;
395
+ }
396
+ return ilike(ctx.column, `%${value}%`);
397
+ }
398
+ /**
399
+ * Operator: NOT ILIKE (case-insensitive pattern non-matching)
400
+ */
401
+ export function notILikeOperator(ctx, value, castType) {
402
+ if (castType || ctx.tableName) {
403
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
404
+ return sql `${leftSQL} NOT ILIKE ${'%' + escapeSqlValue(value) + '%'}`;
405
+ }
406
+ return notIlike(ctx.column, `%${value}%`);
407
+ }
408
+ /**
409
+ * Operator: Starts With (case-insensitive)
410
+ * Example: { name: { startsWith: 'John' } } -> name ILIKE 'John%'
411
+ */
412
+ export function startsWithOperator(ctx, value, castType) {
413
+ if (castType) {
414
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
415
+ return sql `${leftSQL} ILIKE ${escapeSqlValue(value) + '%'}`;
416
+ }
417
+ return ilike(ctx.column, `${value}%`);
418
+ }
419
+ /**
420
+ * Operator: Starts With Case-Sensitive (startsWiths)
421
+ */
422
+ export function startsWithsOperator(ctx, value, castType) {
423
+ if (castType) {
424
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
425
+ return sql `${leftSQL} LIKE ${escapeSqlValue(value) + '%'}`;
426
+ }
427
+ return like(ctx.column, `${value}%`);
428
+ }
429
+ /**
430
+ * Operator: Ends With (case-insensitive)
431
+ * Example: { name: { endsWith: 'son' } } -> name ILIKE '%son'
432
+ */
433
+ export function endsWithOperator(ctx, value, castType) {
434
+ if (castType) {
435
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
436
+ return sql `${leftSQL} ILIKE ${'%' + escapeSqlValue(value)}`;
437
+ }
438
+ return ilike(ctx.column, `%${value}`);
439
+ }
440
+ /**
441
+ * Operator: Ends With Case-Sensitive (endsWiths)
442
+ */
443
+ export function endsWithsOperator(ctx, value, castType) {
444
+ if (castType) {
445
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
446
+ return sql `${leftSQL} LIKE ${'%' + escapeSqlValue(value)}`;
447
+ }
448
+ return like(ctx.column, `%${value}`);
449
+ }
450
+ /**
451
+ * Operator: Not Starts With (case-insensitive)
452
+ */
453
+ export function nstartsWithOperator(ctx, value, castType) {
454
+ if (castType) {
455
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
456
+ return sql `${leftSQL} NOT ILIKE ${escapeSqlValue(value) + '%'}`;
457
+ }
458
+ return notIlike(ctx.column, `${value}%`);
459
+ }
460
+ /**
461
+ * Operator: Not Starts With Case-Sensitive
462
+ */
463
+ export function nstartsWithsOperator(ctx, value, castType) {
464
+ if (castType) {
465
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
466
+ return sql `${leftSQL} NOT LIKE ${escapeSqlValue(value) + '%'}`;
467
+ }
468
+ return notLike(ctx.column, `${value}%`);
469
+ }
470
+ /**
471
+ * Operator: Not Ends With (case-insensitive)
472
+ */
473
+ export function nendsWithOperator(ctx, value, castType) {
474
+ if (castType) {
475
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
476
+ return sql `${leftSQL} NOT ILIKE ${'%' + escapeSqlValue(value)}`;
477
+ }
478
+ return notIlike(ctx.column, `%${value}`);
479
+ }
480
+ /**
481
+ * Operator: Not Ends With Case-Sensitive
482
+ */
483
+ export function nendsWithsOperator(ctx, value, castType) {
484
+ if (castType) {
485
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
486
+ return sql `${leftSQL} NOT LIKE ${'%' + escapeSqlValue(value)}`;
487
+ }
488
+ return notLike(ctx.column, `%${value}`);
489
+ }
490
+ /**
491
+ * Operator: IN (value in array)
492
+ * Example: { status: { in: ['active', 'pending'] } }
493
+ */
494
+ export function inOperator(ctx, value, castType) {
495
+ // Handle null/undefined/non-array values - return a condition that's always false
496
+ if (!Array.isArray(value) || value.length === 0) {
497
+ return sql `1 = 0`;
498
+ }
499
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
500
+ if (castType || ctx.tableName) {
501
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
502
+ // Use parameterized values instead of manual escaping
503
+ return sql `${leftSQL} IN (${sql.join(value.map(v => sql `${v}`), sql `, `)})`;
504
+ }
505
+ return inArray(ctx.column, value);
506
+ }
507
+ /**
508
+ * Operator: NOT IN (value not in array)
509
+ * Example: { status: { notIn: ['deleted', 'archived'] } }
510
+ */
511
+ export function notInOperator(ctx, value, castType) {
512
+ // Handle null/undefined/non-array values - return a condition that's always true
513
+ if (!Array.isArray(value) || value.length === 0) {
514
+ return sql `1 = 1`;
515
+ }
516
+ // Use buildColumnSQL if we have a tableName (alias) or castType to ensure proper aliasing
517
+ if (castType || ctx.tableName) {
518
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
519
+ // Use parameterized values instead of manual escaping
520
+ return sql `${leftSQL} NOT IN (${sql.join(value.map(v => sql `${v}`), sql `, `)})`;
521
+ }
522
+ return notInArray(ctx.column, value);
523
+ }
524
+ /**
525
+ * Operator: BETWEEN (value in range)
526
+ * Example: { age: { between: [18, 65] } } -> age BETWEEN 18 AND 65
527
+ */
528
+ export function betweenOperator(ctx, value, castType) {
529
+ if (!Array.isArray(value) || value.length !== 2) {
530
+ throw new Error('BETWEEN operator requires array of exactly 2 values');
531
+ }
532
+ if (castType || ctx.tableName) {
533
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
534
+ return sql `${leftSQL} BETWEEN ${value[0]} AND ${value[1]}`;
535
+ }
536
+ return between(ctx.column, value[0], value[1]);
537
+ }
538
+ /**
539
+ * Operator: NOT BETWEEN (value not in range)
540
+ */
541
+ export function notBetweenOperator(ctx, value, castType) {
542
+ if (!Array.isArray(value) || value.length !== 2) {
543
+ throw new Error('NOT BETWEEN operator requires array of exactly 2 values');
544
+ }
545
+ if (castType || ctx.tableName) {
546
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
547
+ return sql `${leftSQL} NOT BETWEEN ${value[0]} AND ${value[1]}`;
548
+ }
549
+ return notBetween(ctx.column, value[0], value[1]);
550
+ }
551
+ /**
552
+ * Operator: IS NULL
553
+ * Example: { deletedAt: { isNull: true } } -> deletedAt IS NULL
554
+ */
555
+ export function isNullOperator(ctx, value, castType) {
556
+ if (castType || ctx.tableName) {
557
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
558
+ const checkValue = value === true || value === 'true';
559
+ // Use sql keywords instead of sql.raw for NULL
560
+ return checkValue ? sql `${leftSQL} IS NULL` : sql `${leftSQL} IS NOT NULL`;
561
+ }
562
+ const checkValue = value === true || (typeof value === 'string' && value === 'true');
563
+ return checkValue ? isNull(ctx.column) : isNotNull(ctx.column);
564
+ }
565
+ /**
566
+ * Operator: IS NOT NULL
567
+ * Example: { deletedAt: { isNotNull: true } } -> deletedAt IS NOT NULL
568
+ */
569
+ export function isNotNullOperator(ctx, value, castType) {
570
+ if (castType || ctx.tableName) {
571
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
572
+ const checkValue = value === true || (typeof value === 'string' && value === 'true');
573
+ // Use sql keywords instead of sql.raw for NULL
574
+ return checkValue ? sql `${leftSQL} IS NOT NULL` : sql `${leftSQL} IS NULL`;
575
+ }
576
+ const checkValue = value === true || (typeof value === 'string' && value === 'true');
577
+ return checkValue ? isNotNull(ctx.column) : isNull(ctx.column);
578
+ }
579
+ /**
580
+ * Operator: Array Contains (@>)
581
+ * Example: { tags: { arraycontains: ['javascript', 'nodejs'] } }
582
+ * PostgreSQL: tags @> ARRAY['javascript', 'nodejs']
583
+ */
584
+ export function arrayContainsOperator(ctx, value, elementType = 'text') {
585
+ const preparedValues = Array.isArray(value) ? value : [value];
586
+ const formattedArray = formatArrayForPostgreSQL(preparedValues, elementType);
587
+ // Use buildColumnSQL for proper relation path handling (same pattern as other operators)
588
+ if (ctx.tableName) {
589
+ // For relational paths or when we have a table alias
590
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
591
+ // For string types, cast to text[]
592
+ if (['string', 'text', 'varchar'].includes(elementType)) {
593
+ return sql.raw(`${columnSQL}::text[] @> ${formattedArray}`);
594
+ }
595
+ return sql.raw(`${columnSQL} @> ${formattedArray}`);
596
+ }
597
+ // Direct field without relation
598
+ const formattedArrayDirect = formatArrayForPostgreSQL(value, elementType);
599
+ // For string types, cast to text[]
600
+ if (['string', 'text', 'varchar'].includes(elementType)) {
601
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
602
+ return sql.raw(`${columnSQL}::text[] @> ${formattedArrayDirect}`);
603
+ }
604
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
605
+ return sql.raw(`${columnSQL} @> ${formattedArrayDirect}`);
606
+ }
607
+ /**
608
+ * Operator: Array Contained By (<@)
609
+ * Example: { tags: { arraycontained: ['javascript', 'nodejs', 'typescript'] } }
610
+ * PostgreSQL: tags <@ ARRAY['javascript', 'nodejs', 'typescript']
611
+ */
612
+ export function arrayContainedOperator(ctx, value, elementType = 'text') {
613
+ const preparedValues = Array.isArray(value) ? value : [value];
614
+ const formattedArray = formatArrayForPostgreSQL(preparedValues, elementType);
615
+ // Use buildColumnSQL for proper relation path handling (same pattern as other operators)
616
+ if (ctx.tableName) {
617
+ // For relational paths or when we have a table alias
618
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
619
+ // For string types, cast to text[]
620
+ if (['string', 'text', 'varchar'].includes(elementType)) {
621
+ return sql.raw(`${columnSQL}::text[] <@ ${formattedArray}`);
622
+ }
623
+ return sql.raw(`${columnSQL} <@ ${formattedArray}`);
624
+ }
625
+ // Direct field without relation
626
+ const formattedArrayDirect = formatArrayForPostgreSQL(value, elementType);
627
+ // For string types, cast to text[]
628
+ if (['string', 'text', 'varchar'].includes(elementType)) {
629
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
630
+ return sql.raw(`${columnSQL}::text[] <@ ${formattedArrayDirect}`);
631
+ }
632
+ const columnSQL = buildColumnSQLString(ctx.fieldName);
633
+ return sql.raw(`${columnSQL} <@ ${formattedArrayDirect}`);
634
+ }
635
+ // ============================================================================
636
+ // JSONB OPERATORS
637
+ // PostgreSQL provides powerful JSONB operators for querying JSON data.
638
+ // These operators allow filtering based on JSON structure and contents.
639
+ // ============================================================================
640
+ /**
641
+ * Helper to build field reference for JSONB operations
642
+ */
643
+ function buildFieldRef(fieldName) {
644
+ if (fieldName.startsWith('"')) {
645
+ return fieldName;
646
+ }
647
+ else if (fieldName.includes('.')) {
648
+ const [table, col] = fieldName.split('.');
649
+ return `"${table}"."${col}"`;
650
+ }
651
+ else {
652
+ return `"${fieldName}"`;
653
+ }
654
+ }
655
+ /**
656
+ * Safely escape and stringify JSON value for SQL
657
+ */
658
+ function jsonToSqlString(value) {
659
+ return JSON.stringify(value).replace(/'/g, "''");
660
+ }
661
+ /**
662
+ * Operator: JSONB Contains (@>)
663
+ * Checks if the JSONB column contains the specified JSON value
664
+ * Example: { metadata: { jsonbContains: { status: "active" } } }
665
+ * PostgreSQL: metadata @> '{"status": "active"}'::jsonb
666
+ *
667
+ * This operator tests whether the left JSONB value contains the right JSONB value.
668
+ * A JSONB value contains another if it has all the keys and matching values.
669
+ */
670
+ export function jsonbContainsOperator(ctx, value) {
671
+ const fieldRef = buildFieldRef(ctx.fieldName);
672
+ const jsonValue = jsonToSqlString(value);
673
+ return sql.raw(`${fieldRef} @> '${jsonValue}'::jsonb`);
674
+ }
675
+ /**
676
+ * Operator: JSONB Contained By (<@)
677
+ * Checks if the JSONB column is contained by the specified JSON value
678
+ * Example: { metadata: { jsonbContainedBy: { status: "active", type: "user", role: "admin" } } }
679
+ * PostgreSQL: metadata <@ '{"status": "active", "type": "user", "role": "admin"}'::jsonb
680
+ *
681
+ * This operator tests whether the left JSONB value is contained by the right JSONB value.
682
+ */
683
+ export function jsonbContainedByOperator(ctx, value) {
684
+ const fieldRef = buildFieldRef(ctx.fieldName);
685
+ const jsonValue = jsonToSqlString(value);
686
+ return sql.raw(`${fieldRef} <@ '${jsonValue}'::jsonb`);
687
+ }
688
+ /**
689
+ * Operator: JSONB Has Key (?)
690
+ * Checks if the JSONB column has a specific top-level key
691
+ * Example: { metadata: { jsonbHasKey: "status" } }
692
+ * PostgreSQL: metadata ? 'status'
693
+ */
694
+ export function jsonbHasKeyOperator(ctx, value) {
695
+ const fieldRef = buildFieldRef(ctx.fieldName);
696
+ const escapedKey = String(value).replace(/'/g, "''");
697
+ return sql.raw(`${fieldRef} ? '${escapedKey}'`);
698
+ }
699
+ /**
700
+ * Operator: JSONB Has Any Keys (?|)
701
+ * Checks if the JSONB column has any of the specified keys
702
+ * Example: { metadata: { jsonbHasAnyKeys: ["status", "type", "role"] } }
703
+ * PostgreSQL: metadata ?| array['status', 'type', 'role']
704
+ */
705
+ export function jsonbHasAnyKeysOperator(ctx, value) {
706
+ const fieldRef = buildFieldRef(ctx.fieldName);
707
+ const keys = Array.isArray(value) ? value : value != null ? [value] : [];
708
+ if (keys.length === 0) {
709
+ return sql `1 = 0`;
710
+ }
711
+ const escapedKeys = keys.map(k => `'${String(k).replace(/'/g, "''")}'`).join(', ');
712
+ return sql.raw(`${fieldRef} ?| array[${escapedKeys}]`);
713
+ }
714
+ /**
715
+ * Operator: JSONB Has All Keys (?&)
716
+ * Checks if the JSONB column has all of the specified keys
717
+ * Example: { metadata: { jsonbHasAllKeys: ["status", "type"] } }
718
+ * PostgreSQL: metadata ?& array['status', 'type']
719
+ */
720
+ export function jsonbHasAllKeysOperator(ctx, value) {
721
+ const fieldRef = buildFieldRef(ctx.fieldName);
722
+ const keys = Array.isArray(value) ? value : value != null ? [value] : [];
723
+ if (keys.length === 0) {
724
+ return sql `1 = 1`;
725
+ }
726
+ const escapedKeys = keys.map(k => `'${String(k).replace(/'/g, "''")}'`).join(', ');
727
+ return sql.raw(`${fieldRef} ?& array[${escapedKeys}]`);
728
+ }
729
+ /**
730
+ * Operator: JSONB Path Exists (using @?)
731
+ * Checks if a JSON path exists and returns any items
732
+ * Example: { metadata: { jsonbPathExists: "$.user.preferences" } }
733
+ * PostgreSQL: metadata @? '$.user.preferences'
734
+ *
735
+ * This uses the JSON path language to query JSONB data.
736
+ * The path can include filters like: $.items[*] ? (@.price > 10)
737
+ */
738
+ export function jsonbPathExistsOperator(ctx, value) {
739
+ const fieldRef = buildFieldRef(ctx.fieldName);
740
+ const escapedPath = String(value).replace(/'/g, "''");
741
+ return sql.raw(`${fieldRef} @? '${escapedPath}'`);
742
+ }
743
+ /**
744
+ * Operator: JSONB Path Match (using @@)
745
+ * Checks if a JSON path predicate returns true
746
+ * Example: { metadata: { jsonbPathMatch: "$.price > 10" } }
747
+ * PostgreSQL: metadata @@ '$.price > 10'
748
+ *
749
+ * The path predicate must return a boolean value.
750
+ */
751
+ export function jsonbPathMatchOperator(ctx, value) {
752
+ const fieldRef = buildFieldRef(ctx.fieldName);
753
+ const escapedPath = String(value).replace(/'/g, "''");
754
+ return sql.raw(`${fieldRef} @@ '${escapedPath}'`);
755
+ }
756
+ /**
757
+ * Operator: JSONB Not Contains (NOT @>)
758
+ * Checks if the JSONB column does NOT contain the specified JSON value
759
+ * Example: { metadata: { jsonbNotContains: { status: "deleted" } } }
760
+ * PostgreSQL: NOT (metadata @> '{"status": "deleted"}'::jsonb)
761
+ */
762
+ export function jsonbNotContainsOperator(ctx, value) {
763
+ const fieldRef = buildFieldRef(ctx.fieldName);
764
+ const jsonValue = jsonToSqlString(value);
765
+ return sql.raw(`NOT (${fieldRef} @> '${jsonValue}'::jsonb)`);
766
+ }
767
+ /**
768
+ * Operator: JSONB Key Equals (->>, then compare)
769
+ * Access a top-level key and compare its text value
770
+ * Example: { metadata: { jsonbKeyEquals: { key: "status", value: "active" } } }
771
+ * PostgreSQL: metadata->>'status' = 'active'
772
+ *
773
+ * This is useful when you want to compare a specific key's value directly.
774
+ */
775
+ export function jsonbKeyEqualsOperator(ctx, value) {
776
+ const fieldRef = buildFieldRef(ctx.fieldName);
777
+ const escapedKey = String(value.key).replace(/'/g, "''");
778
+ if (value.value === null) {
779
+ return sql.raw(`${fieldRef}->>'${escapedKey}' IS NULL`);
780
+ }
781
+ if (typeof value.value === 'number') {
782
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric = ${value.value}`);
783
+ }
784
+ if (typeof value.value === 'boolean') {
785
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::boolean = ${value.value}`);
786
+ }
787
+ const escapedValue = String(value.value).replace(/'/g, "''");
788
+ return sql.raw(`${fieldRef}->>'${escapedKey}' = '${escapedValue}'`);
789
+ }
790
+ /**
791
+ * Operator: JSONB Key Not Equals (->>, then compare)
792
+ * Access a top-level key and compare its text value is NOT equal
793
+ * Example: { metadata: { jsonbKeyNotEquals: { key: "status", value: "deleted" } } }
794
+ * PostgreSQL: metadata->>'status' != 'deleted' OR metadata->>'status' IS NULL
795
+ */
796
+ export function jsonbKeyNotEqualsOperator(ctx, value) {
797
+ const fieldRef = buildFieldRef(ctx.fieldName);
798
+ const escapedKey = String(value.key).replace(/'/g, "''");
799
+ if (value.value === null) {
800
+ return sql.raw(`${fieldRef}->>'${escapedKey}' IS NOT NULL`);
801
+ }
802
+ if (typeof value.value === 'number') {
803
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric != ${value.value} OR ${fieldRef}->>'${escapedKey}' IS NULL`);
804
+ }
805
+ if (typeof value.value === 'boolean') {
806
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::boolean != ${value.value} OR ${fieldRef}->>'${escapedKey}' IS NULL`);
807
+ }
808
+ const escapedValue = String(value.value).replace(/'/g, "''");
809
+ return sql.raw(`${fieldRef}->>'${escapedKey}' != '${escapedValue}' OR ${fieldRef}->>'${escapedKey}' IS NULL`);
810
+ }
811
+ /**
812
+ * Operator: JSONB Key Greater Than
813
+ * Access a top-level key and compare if value is greater than
814
+ * Example: { metadata: { jsonbKeyGt: { key: "price", value: 100 } } }
815
+ * PostgreSQL: (metadata->>'price')::numeric > 100
816
+ */
817
+ export function jsonbKeyGtOperator(ctx, value) {
818
+ const fieldRef = buildFieldRef(ctx.fieldName);
819
+ const escapedKey = String(value.key).replace(/'/g, "''");
820
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric > ${value.value}`);
821
+ }
822
+ /**
823
+ * Operator: JSONB Key Greater Than or Equal
824
+ * Example: { metadata: { jsonbKeyGte: { key: "price", value: 100 } } }
825
+ */
826
+ export function jsonbKeyGteOperator(ctx, value) {
827
+ const fieldRef = buildFieldRef(ctx.fieldName);
828
+ const escapedKey = String(value.key).replace(/'/g, "''");
829
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric >= ${value.value}`);
830
+ }
831
+ /**
832
+ * Operator: JSONB Key Less Than
833
+ * Example: { metadata: { jsonbKeyLt: { key: "price", value: 100 } } }
834
+ */
835
+ export function jsonbKeyLtOperator(ctx, value) {
836
+ const fieldRef = buildFieldRef(ctx.fieldName);
837
+ const escapedKey = String(value.key).replace(/'/g, "''");
838
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric < ${value.value}`);
839
+ }
840
+ /**
841
+ * Operator: JSONB Key Less Than or Equal
842
+ * Example: { metadata: { jsonbKeyLte: { key: "price", value: 100 } } }
843
+ */
844
+ export function jsonbKeyLteOperator(ctx, value) {
845
+ const fieldRef = buildFieldRef(ctx.fieldName);
846
+ const escapedKey = String(value.key).replace(/'/g, "''");
847
+ return sql.raw(`(${fieldRef}->>'${escapedKey}')::numeric <= ${value.value}`);
848
+ }
849
+ /**
850
+ * Operator: JSONB Key In (->>, then IN)
851
+ * Access a top-level key and check if value is in a list
852
+ * Example: { metadata: { jsonbKeyIn: { key: "status", values: ["active", "pending"] } } }
853
+ * PostgreSQL: metadata->>'status' IN ('active', 'pending')
854
+ */
855
+ export function jsonbKeyInOperator(ctx, value) {
856
+ if (!value || value.key == null) {
857
+ return sql `1 = 0`;
858
+ }
859
+ const fieldRef = buildFieldRef(ctx.fieldName);
860
+ const escapedKey = String(value.key).replace(/'/g, "''");
861
+ const values = Array.isArray(value.values) ? value.values : value.values != null ? [value.values] : [];
862
+ if (values.length === 0) {
863
+ return sql `1 = 0`;
864
+ }
865
+ const escapedValues = values.map(v => `'${String(v).replace(/'/g, "''")}'`).join(', ');
866
+ return sql.raw(`${fieldRef}->>'${escapedKey}' IN (${escapedValues})`);
867
+ }
868
+ /**
869
+ * Operator: JSONB Key Not In
870
+ * Example: { metadata: { jsonbKeyNotIn: { key: "status", values: ["deleted", "archived"] } } }
871
+ */
872
+ export function jsonbKeyNotInOperator(ctx, value) {
873
+ if (!value || value.key == null) {
874
+ return sql `1 = 1`;
875
+ }
876
+ const fieldRef = buildFieldRef(ctx.fieldName);
877
+ const escapedKey = String(value.key).replace(/'/g, "''");
878
+ const values = Array.isArray(value.values) ? value.values : value.values != null ? [value.values] : [];
879
+ if (values.length === 0) {
880
+ return sql `1 = 1`;
881
+ }
882
+ const escapedValues = values.map(v => `'${String(v).replace(/'/g, "''")}'`).join(', ');
883
+ return sql.raw(`${fieldRef}->>'${escapedKey}' NOT IN (${escapedValues})`);
884
+ }
885
+ /**
886
+ * Operator: JSONB Key Like (->>, then ILIKE)
887
+ * Access a top-level key and perform pattern matching
888
+ * Example: { metadata: { jsonbKeyLike: { key: "name", pattern: "%john%" } } }
889
+ * PostgreSQL: metadata->>'name' ILIKE '%john%'
890
+ */
891
+ export function jsonbKeyLikeOperator(ctx, value) {
892
+ const fieldRef = buildFieldRef(ctx.fieldName);
893
+ const escapedKey = String(value.key).replace(/'/g, "''");
894
+ const escapedPattern = String(value.pattern).replace(/'/g, "''");
895
+ return sql.raw(`${fieldRef}->>'${escapedKey}' ILIKE '${escapedPattern}'`);
896
+ }
897
+ /**
898
+ * Operator: JSONB Key Is Null
899
+ * Check if a specific key's value is null (not if the key is missing)
900
+ * Example: { metadata: { jsonbKeyIsNull: "deletedAt" } }
901
+ * PostgreSQL: metadata->>'deletedAt' IS NULL
902
+ */
903
+ export function jsonbKeyIsNullOperator(ctx, value) {
904
+ const fieldRef = buildFieldRef(ctx.fieldName);
905
+ const escapedKey = String(value).replace(/'/g, "''");
906
+ return sql.raw(`${fieldRef}->>'${escapedKey}' IS NULL`);
907
+ }
908
+ /**
909
+ * Operator: JSONB Key Is Not Null
910
+ * Check if a specific key's value is not null
911
+ * Example: { metadata: { jsonbKeyIsNotNull: "createdAt" } }
912
+ * PostgreSQL: metadata->>'createdAt' IS NOT NULL
913
+ */
914
+ export function jsonbKeyIsNotNullOperator(ctx, value) {
915
+ const fieldRef = buildFieldRef(ctx.fieldName);
916
+ const escapedKey = String(value).replace(/'/g, "''");
917
+ return sql.raw(`${fieldRef}->>'${escapedKey}' IS NOT NULL`);
918
+ }
919
+ /**
920
+ * Operator: JSONB Array Length
921
+ * Check the length of a JSONB array at a specific path
922
+ * Example: { metadata: { jsonbArrayLength: { path: "items", op: "gte", value: 5 } } }
923
+ * PostgreSQL: jsonb_array_length(metadata->'items') >= 5
924
+ */
925
+ export function jsonbArrayLengthOperator(ctx, value) {
926
+ const fieldRef = buildFieldRef(ctx.fieldName);
927
+ const operators = {
928
+ eq: '=',
929
+ ne: '!=',
930
+ gt: '>',
931
+ gte: '>=',
932
+ lt: '<',
933
+ lte: '<='
934
+ };
935
+ const sqlOp = operators[value.op] || '=';
936
+ if (value.path) {
937
+ const escapedPath = String(value.path).replace(/'/g, "''");
938
+ return sql.raw(`jsonb_array_length(${fieldRef}->'${escapedPath}') ${sqlOp} ${value.value}`);
939
+ }
940
+ // If no path, assume the column itself is the array
941
+ return sql.raw(`jsonb_array_length(${fieldRef}) ${sqlOp} ${value.value}`);
942
+ }
943
+ /**
944
+ * Operator: JSONB Type Of
945
+ * Check the type of a JSONB value or a key's value
946
+ * Example: { metadata: { jsonbTypeOf: { path: "price", type: "number" } } }
947
+ * PostgreSQL: jsonb_typeof(metadata->'price') = 'number'
948
+ *
949
+ * Valid types: 'object', 'array', 'string', 'number', 'boolean', 'null'
950
+ */
951
+ export function jsonbTypeOfOperator(ctx, value) {
952
+ const fieldRef = buildFieldRef(ctx.fieldName);
953
+ const escapedType = String(value.type).replace(/'/g, "''");
954
+ if (value.path) {
955
+ const escapedPath = String(value.path).replace(/'/g, "''");
956
+ return sql.raw(`jsonb_typeof(${fieldRef}->'${escapedPath}') = '${escapedType}'`);
957
+ }
958
+ return sql.raw(`jsonb_typeof(${fieldRef}) = '${escapedType}'`);
959
+ }
960
+ /**
961
+ * Operator: JSONB Deep Value (using #>> for nested path)
962
+ * Access a deeply nested value and compare
963
+ * Example: { metadata: { jsonbDeepValue: { path: ["user", "preferences", "theme"], value: "dark" } } }
964
+ * PostgreSQL: metadata #>> '{user,preferences,theme}' = 'dark'
965
+ *
966
+ * The path array represents the keys to traverse.
967
+ */
968
+ export function jsonbDeepValueOperator(ctx, value) {
969
+ if (!value || value.path == null) {
970
+ return sql `1 = 0`;
971
+ }
972
+ const fieldRef = buildFieldRef(ctx.fieldName);
973
+ const pathArray = Array.isArray(value.path) ? value.path : value.path != null ? [value.path] : [];
974
+ if (pathArray.length === 0) {
975
+ return sql `1 = 0`;
976
+ }
977
+ const escapedPath = pathArray.map(p => String(p).replace(/"/g, '\\"')).join(',');
978
+ const op = value.op || 'eq';
979
+ const operators = {
980
+ eq: '=',
981
+ ne: '!=',
982
+ gt: '>',
983
+ gte: '>=',
984
+ lt: '<',
985
+ lte: '<=',
986
+ like: 'LIKE',
987
+ ilike: 'ILIKE'
988
+ };
989
+ const sqlOp = operators[op] || '=';
990
+ if (value.value === null) {
991
+ return op === 'ne'
992
+ ? sql.raw(`${fieldRef} #>> '{${escapedPath}}' IS NOT NULL`)
993
+ : sql.raw(`${fieldRef} #>> '{${escapedPath}}' IS NULL`);
994
+ }
995
+ if (typeof value.value === 'number' && !['like', 'ilike'].includes(op)) {
996
+ return sql.raw(`(${fieldRef} #>> '{${escapedPath}}')::numeric ${sqlOp} ${value.value}`);
997
+ }
998
+ const escapedValue = String(value.value).replace(/'/g, "''");
999
+ return sql.raw(`${fieldRef} #>> '{${escapedPath}}' ${sqlOp} '${escapedValue}'`);
1000
+ }
1001
+ /**
1002
+ * Operator: ST_Within (geometry within)
1003
+ * Example: { location: { within: geoJSON } }
1004
+ */
1005
+ export function withinOperator(ctx, value) {
1006
+ // Build properly quoted column reference
1007
+ let fieldRef;
1008
+ if (ctx.fieldName.startsWith('"')) {
1009
+ // Already quoted
1010
+ fieldRef = ctx.fieldName;
1011
+ }
1012
+ else if (ctx.fieldName.includes('.')) {
1013
+ const [table, col] = ctx.fieldName.split('.');
1014
+ fieldRef = `"${table}"."${col}"`;
1015
+ }
1016
+ else {
1017
+ fieldRef = `"${ctx.fieldName}"`;
1018
+ }
1019
+ return sql.raw(`ST_Within(${fieldRef}, ST_GeomFromGeoJSON('${JSON.stringify(value)}'))`);
1020
+ }
1021
+ /**
1022
+ * Operator: ST_Contains (geometry contains)
1023
+ * Example: { boundary: { containsGEO: geoJSON } }
1024
+ */
1025
+ export function containsGEOOperator(ctx, value) {
1026
+ // Build properly quoted column reference
1027
+ let fieldRef;
1028
+ if (ctx.fieldName.startsWith('"')) {
1029
+ // Already quoted
1030
+ fieldRef = ctx.fieldName;
1031
+ }
1032
+ else if (ctx.fieldName.includes('.')) {
1033
+ const [table, col] = ctx.fieldName.split('.');
1034
+ fieldRef = `"${table}"."${col}"`;
1035
+ }
1036
+ else {
1037
+ fieldRef = `"${ctx.fieldName}"`;
1038
+ }
1039
+ return sql.raw(`ST_Contains(${fieldRef}, ST_GeomFromGeoJSON('${JSON.stringify(value)}'))`);
1040
+ }
1041
+ /**
1042
+ * Operator: ST_Intersects (geometries intersect)
1043
+ * Example: { area: { intersects: geoJSON } }
1044
+ */
1045
+ export function intersectsOperator(ctx, value) {
1046
+ // Build properly quoted column reference
1047
+ let fieldRef;
1048
+ if (ctx.fieldName.startsWith('"')) {
1049
+ // Already quoted
1050
+ fieldRef = ctx.fieldName;
1051
+ }
1052
+ else if (ctx.fieldName.includes('.')) {
1053
+ const [table, col] = ctx.fieldName.split('.');
1054
+ fieldRef = `"${table}"."${col}"`;
1055
+ }
1056
+ else {
1057
+ fieldRef = `"${ctx.fieldName}"`;
1058
+ }
1059
+ // Cast column to geometry to resolve function overload ambiguity
1060
+ return sql.raw(`ST_Intersects(${fieldRef}::geometry, ST_GeomFromGeoJSON('${JSON.stringify(value)}'))`);
1061
+ }
1062
+ /**
1063
+ * Operator: NOT ST_Intersects
1064
+ */
1065
+ export function nIntersectsOperator(ctx, value) {
1066
+ // Build properly quoted column reference
1067
+ let fieldRef;
1068
+ if (ctx.fieldName.startsWith('"')) {
1069
+ // Already quoted
1070
+ fieldRef = ctx.fieldName;
1071
+ }
1072
+ else if (ctx.fieldName.includes('.')) {
1073
+ const [table, col] = ctx.fieldName.split('.');
1074
+ fieldRef = `"${table}"."${col}"`;
1075
+ }
1076
+ else {
1077
+ fieldRef = `"${ctx.fieldName}"`;
1078
+ }
1079
+ return sql.raw(`NOT ST_Intersects(${fieldRef}, ST_GeomFromGeoJSON('${JSON.stringify(value)}'))`);
1080
+ }
1081
+ /**
1082
+ * Operator: ST_DWithin (within distance)
1083
+ * Example: { location: { dwithin: { geometry: geoJSON, distance: 1000, not: false } } }
1084
+ * Uses ST_DistanceSpheroid for accurate earth-surface distance calculations in meters
1085
+ */
1086
+ export function dwithinOperator(ctx, value) {
1087
+ const { geometry, distance, not: negated } = value;
1088
+ // Build properly quoted column reference
1089
+ let fieldRef;
1090
+ if (ctx.fieldName.startsWith('"')) {
1091
+ // Already quoted
1092
+ fieldRef = ctx.fieldName;
1093
+ }
1094
+ else if (ctx.fieldName.includes('.')) {
1095
+ const [table, col] = ctx.fieldName.split('.');
1096
+ fieldRef = `"${table}"."${col}"`;
1097
+ }
1098
+ else {
1099
+ fieldRef = `"${ctx.fieldName}"`;
1100
+ }
1101
+ // Use ST_DistanceSpheroid for accurate distance calculations in meters
1102
+ // This is more reliable than ::geography casting across different PostGIS versions
1103
+ const spheroid = `SPHEROID["WGS 84",6378137,298.257223563]`;
1104
+ const condition = `ST_DistanceSpheroid(${fieldRef}, ST_SetSRID(ST_GeomFromGeoJSON('${JSON.stringify(geometry)}'), 4326), '${spheroid}') <= ${distance}`;
1105
+ return negated ? sql.raw(`NOT (${condition})`) : sql.raw(condition);
1106
+ }
1107
+ /**
1108
+ * Operator: NOT
1109
+ * Example: { status: { not: 'active' } } -> status != 'active'
1110
+ * Example: { id: { not: null } } -> id IS NOT NULL
1111
+ */
1112
+ export function notOperator(ctx, value, castType) {
1113
+ // Special handling for null values - must use IS NOT NULL syntax
1114
+ if (value === null) {
1115
+ if (castType || ctx.tableName) {
1116
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
1117
+ return sql `${leftSQL} IS NOT NULL`;
1118
+ }
1119
+ return isNotNull(ctx.column);
1120
+ }
1121
+ if (castType || ctx.tableName) {
1122
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
1123
+ return sql `NOT (${leftSQL} = ${value})`;
1124
+ }
1125
+ return ne(ctx.column, value);
1126
+ }
1127
+ /**
1128
+ * Operator: IS
1129
+ * Example: { deletedAt: { is: null } } -> deletedAt IS NULL
1130
+ */
1131
+ export function isOperator(ctx, value, castType) {
1132
+ if (castType || ctx.tableName) {
1133
+ const leftSQL = buildColumnSQL(ctx.fieldName, castType);
1134
+ // Handle NULL specially with IS NULL syntax
1135
+ if (value === null || value === 'null') {
1136
+ return sql `${leftSQL} IS NULL`;
1137
+ }
1138
+ return sql `${leftSQL} IS ${value}`;
1139
+ }
1140
+ if (value === null) {
1141
+ return isNull(ctx.column);
1142
+ }
1143
+ return eq(ctx.column, value);
1144
+ }
1145
+ /**
1146
+ * Map of operator names to their handler functions
1147
+ */
1148
+ export const OPERATOR_MAP = {
1149
+ // Comparison
1150
+ eq: eqOperator,
1151
+ ne: neOperator,
1152
+ gt: gtOperator,
1153
+ gte: gteOperator,
1154
+ lt: ltOperator,
1155
+ lte: lteOperator,
1156
+ // String pattern matching
1157
+ like: likeOperator,
1158
+ notLike: notLikeOperator,
1159
+ iLike: iLikeOperator,
1160
+ notILike: notILikeOperator,
1161
+ startsWith: startsWithOperator,
1162
+ startsWiths: startsWithsOperator,
1163
+ endsWith: endsWithOperator,
1164
+ endsWiths: endsWithsOperator,
1165
+ nstartsWith: nstartsWithOperator,
1166
+ nstartsWiths: nstartsWithsOperator,
1167
+ nendsWith: nendsWithOperator,
1168
+ nendsWiths: nendsWithsOperator,
1169
+ // Collection
1170
+ in: inOperator,
1171
+ notIn: notInOperator,
1172
+ not: notOperator,
1173
+ is: isOperator,
1174
+ // Range
1175
+ between: betweenOperator,
1176
+ notBetween: notBetweenOperator,
1177
+ // Null checks
1178
+ isNull: isNullOperator,
1179
+ isNotNull: isNotNullOperator,
1180
+ // Array operators
1181
+ arraycontains: arrayContainsOperator,
1182
+ arraycontained: arrayContainedOperator,
1183
+ // JSONB operators
1184
+ jsonbContains: jsonbContainsOperator,
1185
+ jsonbContainedBy: jsonbContainedByOperator,
1186
+ jsonbHasKey: jsonbHasKeyOperator,
1187
+ jsonbHasAnyKeys: jsonbHasAnyKeysOperator,
1188
+ jsonbHasAllKeys: jsonbHasAllKeysOperator,
1189
+ jsonbPathExists: jsonbPathExistsOperator,
1190
+ jsonbPathMatch: jsonbPathMatchOperator,
1191
+ jsonbNotContains: jsonbNotContainsOperator,
1192
+ jsonbKeyEquals: jsonbKeyEqualsOperator,
1193
+ jsonbKeyNotEquals: jsonbKeyNotEqualsOperator,
1194
+ jsonbKeyGt: jsonbKeyGtOperator,
1195
+ jsonbKeyGte: jsonbKeyGteOperator,
1196
+ jsonbKeyLt: jsonbKeyLtOperator,
1197
+ jsonbKeyLte: jsonbKeyLteOperator,
1198
+ jsonbKeyIn: jsonbKeyInOperator,
1199
+ jsonbKeyNotIn: jsonbKeyNotInOperator,
1200
+ jsonbKeyLike: jsonbKeyLikeOperator,
1201
+ jsonbKeyIsNull: jsonbKeyIsNullOperator,
1202
+ jsonbKeyIsNotNull: jsonbKeyIsNotNullOperator,
1203
+ jsonbArrayLength: jsonbArrayLengthOperator,
1204
+ jsonbTypeOf: jsonbTypeOfOperator,
1205
+ jsonbDeepValue: jsonbDeepValueOperator,
1206
+ // Geo operators
1207
+ within: withinOperator,
1208
+ containsGEO: containsGEOOperator,
1209
+ intersects: intersectsOperator,
1210
+ nIntersects: nIntersectsOperator,
1211
+ dwithin: dwithinOperator,
1212
+ };
1213
+ /**
1214
+ * Apply an operator to a column with a value
1215
+ */
1216
+ export function applyOperator(operatorName, ctx, value, castType, elementType) {
1217
+ const operator = OPERATOR_MAP[operatorName];
1218
+ if (!operator) {
1219
+ console.warn(`Unknown operator: ${operatorName}`);
1220
+ return null;
1221
+ }
1222
+ // Special handling for array operators
1223
+ if (operatorName === 'arraycontains' || operatorName === 'arraycontained') {
1224
+ return operator(ctx, value, elementType);
1225
+ }
1226
+ // @ts-ignore - Type complexity with operator overloads
1227
+ return operator(ctx, value, castType);
1228
+ }
1229
+ //# sourceMappingURL=filterOperators.js.map