alepha 0.20.1 → 0.20.3

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 (393) hide show
  1. package/README.md +0 -1
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui.css +1 -1
  4. package/dist/api/audits/index.browser.js +49 -0
  5. package/dist/api/audits/index.browser.js.map +1 -1
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +49 -0
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.d.ts.map +1 -1
  10. package/dist/api/files/index.js +2 -1
  11. package/dist/api/files/index.js.map +1 -1
  12. package/dist/api/jobs/index.browser.js +64 -148
  13. package/dist/api/jobs/index.browser.js.map +1 -1
  14. package/dist/api/jobs/index.d.ts +339 -600
  15. package/dist/api/jobs/index.d.ts.map +1 -1
  16. package/dist/api/jobs/index.js +605 -1012
  17. package/dist/api/jobs/index.js.map +1 -1
  18. package/dist/api/keys/index.js.map +1 -1
  19. package/dist/api/notifications/index.d.ts +79 -27
  20. package/dist/api/notifications/index.d.ts.map +1 -1
  21. package/dist/api/notifications/index.js +90 -23
  22. package/dist/api/notifications/index.js.map +1 -1
  23. package/dist/api/organizations/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.browser.js +37 -0
  25. package/dist/api/parameters/index.browser.js.map +1 -1
  26. package/dist/api/parameters/index.d.ts +4 -65
  27. package/dist/api/parameters/index.d.ts.map +1 -1
  28. package/dist/api/parameters/index.js +37 -0
  29. package/dist/api/parameters/index.js.map +1 -1
  30. package/dist/api/payments/index.d.ts +2 -1
  31. package/dist/api/payments/index.d.ts.map +1 -1
  32. package/dist/api/payments/index.js +4 -2
  33. package/dist/api/payments/index.js.map +1 -1
  34. package/dist/api/users/index.d.ts +225 -5199
  35. package/dist/api/users/index.d.ts.map +1 -1
  36. package/dist/api/users/index.js +15 -11
  37. package/dist/api/users/index.js.map +1 -1
  38. package/dist/api/verifications/index.d.ts.map +1 -1
  39. package/dist/api/verifications/index.js +4 -2
  40. package/dist/api/verifications/index.js.map +1 -1
  41. package/dist/bucket/index.js +5 -1
  42. package/dist/bucket/index.js.map +1 -1
  43. package/dist/bucket/index.workerd.js +5 -1
  44. package/dist/bucket/index.workerd.js.map +1 -1
  45. package/dist/cache/core/index.js.map +1 -1
  46. package/dist/cache/core/index.workerd.js.map +1 -1
  47. package/dist/captcha/index.js.map +1 -1
  48. package/dist/cli/core/index.d.ts +225 -11681
  49. package/dist/cli/core/index.d.ts.map +1 -1
  50. package/dist/cli/core/index.js +732 -257
  51. package/dist/cli/core/index.js.map +1 -1
  52. package/dist/cli/devtools/index.js +7 -1
  53. package/dist/cli/devtools/index.js.map +1 -1
  54. package/dist/cli/platform/index.d.ts +65 -63
  55. package/dist/cli/platform/index.d.ts.map +1 -1
  56. package/dist/cli/platform/index.js +140 -27
  57. package/dist/cli/platform/index.js.map +1 -1
  58. package/dist/cli/vendor/index.js +15 -0
  59. package/dist/cli/vendor/index.js.map +1 -1
  60. package/dist/command/index.d.ts +1 -1
  61. package/dist/command/index.js +1 -1
  62. package/dist/command/index.js.map +1 -1
  63. package/dist/core/index.browser.js +6 -0
  64. package/dist/core/index.browser.js.map +1 -1
  65. package/dist/core/index.d.ts +8 -8
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +6 -0
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/index.native.js +6 -0
  70. package/dist/core/index.native.js.map +1 -1
  71. package/dist/core/index.workerd.js +6 -0
  72. package/dist/core/index.workerd.js.map +1 -1
  73. package/dist/crypto/index.js.map +1 -1
  74. package/dist/datetime/index.js.map +1 -1
  75. package/dist/email/core/index.js.map +1 -1
  76. package/dist/email/smtp/index.js +2 -10522
  77. package/dist/email/smtp/index.js.map +1 -1
  78. package/dist/fake/index.d.ts +4 -8085
  79. package/dist/fake/index.d.ts.map +1 -1
  80. package/dist/fake/index.js +3 -33554
  81. package/dist/fake/index.js.map +1 -1
  82. package/dist/lock/core/index.js.map +1 -1
  83. package/dist/lock/redis/index.js.map +1 -1
  84. package/dist/logger/index.js +32 -1
  85. package/dist/logger/index.js.map +1 -1
  86. package/dist/mcp/index.js +5 -1
  87. package/dist/mcp/index.js.map +1 -1
  88. package/dist/orm/core/index.browser.js +1 -361
  89. package/dist/orm/core/index.browser.js.map +1 -1
  90. package/dist/orm/core/index.bun.js +14 -406
  91. package/dist/orm/core/index.bun.js.map +1 -1
  92. package/dist/orm/core/index.d.ts +96 -5117
  93. package/dist/orm/core/index.d.ts.map +1 -1
  94. package/dist/orm/core/index.js +23 -419
  95. package/dist/orm/core/index.js.map +1 -1
  96. package/dist/orm/postgres/index.bun.js +17 -20
  97. package/dist/orm/postgres/index.bun.js.map +1 -1
  98. package/dist/orm/postgres/index.d.ts +2 -613
  99. package/dist/orm/postgres/index.d.ts.map +1 -1
  100. package/dist/orm/postgres/index.js +17 -20
  101. package/dist/orm/postgres/index.js.map +1 -1
  102. package/dist/react/core/index.js.map +1 -1
  103. package/dist/react/form/index.d.ts +60 -1
  104. package/dist/react/form/index.d.ts.map +1 -1
  105. package/dist/react/form/index.js +86 -1
  106. package/dist/react/form/index.js.map +1 -1
  107. package/dist/react/head/index.browser.js +16 -1
  108. package/dist/react/head/index.browser.js.map +1 -1
  109. package/dist/react/head/index.d.ts +6 -0
  110. package/dist/react/head/index.d.ts.map +1 -1
  111. package/dist/react/head/index.js +16 -1
  112. package/dist/react/head/index.js.map +1 -1
  113. package/dist/react/i18n/index.js.map +1 -1
  114. package/dist/react/intro/index.js +22 -17
  115. package/dist/react/intro/index.js.map +1 -1
  116. package/dist/react/router/index.browser.js +78 -12
  117. package/dist/react/router/index.browser.js.map +1 -1
  118. package/dist/react/router/index.d.ts +57 -13
  119. package/dist/react/router/index.d.ts.map +1 -1
  120. package/dist/react/router/index.js +102 -14
  121. package/dist/react/router/index.js.map +1 -1
  122. package/dist/react/testing/index.d.ts +1 -411
  123. package/dist/react/testing/index.d.ts.map +1 -1
  124. package/dist/react/testing/index.js +13 -12293
  125. package/dist/react/testing/index.js.map +1 -1
  126. package/dist/react/ui/index.d.ts +124 -0
  127. package/dist/react/ui/index.d.ts.map +1 -0
  128. package/dist/react/ui/index.js +209 -0
  129. package/dist/react/ui/index.js.map +1 -0
  130. package/dist/react/websocket/index.js.map +1 -1
  131. package/dist/redis/index.js.map +1 -1
  132. package/dist/router/index.d.ts +13 -13
  133. package/dist/router/index.d.ts.map +1 -1
  134. package/dist/router/index.js +45 -32
  135. package/dist/router/index.js.map +1 -1
  136. package/dist/scheduler/index.d.ts +1 -83
  137. package/dist/scheduler/index.d.ts.map +1 -1
  138. package/dist/scheduler/index.js +2 -391
  139. package/dist/scheduler/index.js.map +1 -1
  140. package/dist/scheduler/index.workerd.js +2 -391
  141. package/dist/scheduler/index.workerd.js.map +1 -1
  142. package/dist/security/index.browser.js.map +1 -1
  143. package/dist/security/index.d.ts +2 -325
  144. package/dist/security/index.d.ts.map +1 -1
  145. package/dist/security/index.js +3 -1362
  146. package/dist/security/index.js.map +1 -1
  147. package/dist/server/auth/index.d.ts +1 -1054
  148. package/dist/server/auth/index.d.ts.map +1 -1
  149. package/dist/server/auth/index.js +16 -1224
  150. package/dist/server/auth/index.js.map +1 -1
  151. package/dist/server/cookies/index.js.map +1 -1
  152. package/dist/server/core/index.browser.js.map +1 -1
  153. package/dist/server/core/index.d.ts +1 -4
  154. package/dist/server/core/index.d.ts.map +1 -1
  155. package/dist/server/core/index.js +19 -4
  156. package/dist/server/core/index.js.map +1 -1
  157. package/dist/server/links/index.browser.js.map +1 -1
  158. package/dist/server/links/index.js.map +1 -1
  159. package/dist/server/metrics/index.d.ts +1 -514
  160. package/dist/server/metrics/index.d.ts.map +1 -1
  161. package/dist/server/metrics/index.js +4 -4356
  162. package/dist/server/metrics/index.js.map +1 -1
  163. package/dist/server/rate-limit/index.js.map +1 -1
  164. package/dist/server/static/index.js.map +1 -1
  165. package/dist/server/swagger/index.js +1 -1
  166. package/dist/server/swagger/index.js.map +1 -1
  167. package/dist/sms/index.js.map +1 -1
  168. package/dist/system/index.browser.js.map +1 -1
  169. package/dist/system/index.d.ts.map +1 -1
  170. package/dist/system/index.js +1 -0
  171. package/dist/system/index.js.map +1 -1
  172. package/dist/system/index.workerd.js.map +1 -1
  173. package/dist/topic/core/index.js +1 -1
  174. package/dist/topic/core/index.js.map +1 -1
  175. package/dist/websocket/index.browser.js +21 -0
  176. package/dist/websocket/index.browser.js.map +1 -1
  177. package/dist/websocket/index.js +21 -0
  178. package/dist/websocket/index.js.map +1 -1
  179. package/package.json +23 -37
  180. package/src/api/files/__tests__/FileController.spec.ts +1 -1
  181. package/src/api/files/jobs/FileJobs.ts +2 -1
  182. package/src/api/jobs/__tests__/$job.spec.ts +320 -2867
  183. package/src/api/jobs/controllers/AdminJobController.ts +29 -138
  184. package/src/api/jobs/entities/jobExecutionEntity.ts +27 -19
  185. package/src/api/jobs/index.browser.ts +5 -7
  186. package/src/api/jobs/index.ts +23 -51
  187. package/src/api/jobs/primitives/$job.ts +66 -58
  188. package/src/api/jobs/providers/JobProvider.ts +561 -566
  189. package/src/api/jobs/providers/JobQueueProvider.ts +18 -19
  190. package/src/api/jobs/schemas/jobConfigAtom.ts +20 -23
  191. package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +3 -27
  192. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +5 -7
  193. package/src/api/jobs/schemas/jobRegistrationSchema.ts +7 -4
  194. package/src/api/jobs/schemas/triggerJobSchema.ts +0 -1
  195. package/src/api/jobs/services/JobService.ts +90 -483
  196. package/src/api/notifications/controllers/AdminNotificationController.ts +19 -12
  197. package/src/api/notifications/index.ts +7 -4
  198. package/src/api/notifications/jobs/NotificationJobs.ts +83 -12
  199. package/src/api/payments/services/PaymentService.ts +4 -2
  200. package/src/api/users/__tests__/UserJobs.spec.ts +10 -49
  201. package/src/api/users/audits/UserAudits.ts +3 -1
  202. package/src/api/users/buckets/UserBuckets.ts +2 -1
  203. package/src/api/users/index.ts +1 -4
  204. package/src/api/users/jobs/UserJobs.ts +5 -4
  205. package/src/api/users/schemas/userQuerySchema.ts +0 -1
  206. package/src/api/users/services/UserService.ts +1 -5
  207. package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
  208. package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
  209. package/src/api/verifications/jobs/VerificationJobs.ts +2 -1
  210. package/src/api/verifications/services/VerificationService.ts +1 -0
  211. package/src/cli/core/__tests__/init.spec.ts +209 -1
  212. package/src/cli/core/commands/init.ts +9 -9
  213. package/src/cli/core/services/PackageManagerUtils.ts +22 -12
  214. package/src/cli/core/services/ProjectScaffolder.ts +300 -70
  215. package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
  216. package/src/cli/core/tasks/BuildServerTask.ts +8 -0
  217. package/src/cli/core/templates/agentMd.ts +2 -8
  218. package/src/cli/core/templates/apiIndexTs.ts +22 -14
  219. package/src/cli/core/templates/componentsJsonTs.ts +39 -0
  220. package/src/cli/core/templates/mainCss.ts +2 -36
  221. package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
  222. package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
  223. package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
  224. package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
  225. package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
  226. package/src/cli/core/templates/vitestConfigTs.ts +17 -0
  227. package/src/cli/core/templates/webAppRouterTs.ts +102 -82
  228. package/src/cli/core/templates/webIndexTs.ts +23 -1
  229. package/src/cli/platform/__tests__/CloudflareAdapter.spec.ts +22 -71
  230. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
  231. package/src/cli/platform/adapters/CloudflareAdapter.ts +12 -11
  232. package/src/cli/platform/atoms/platformOptions.ts +9 -0
  233. package/src/cli/platform/schemas/cloudflare.ts +3 -2
  234. package/src/cli/platform/services/CloudflareApi.ts +164 -25
  235. package/src/cli/platform/services/WranglerApi.ts +0 -17
  236. package/src/command/providers/CliProvider.ts +1 -1
  237. package/src/core/Alepha.ts +9 -0
  238. package/src/core/interfaces/Service.ts +3 -1
  239. package/src/core/providers/TypeProvider.ts +1 -1
  240. package/src/logger/services/Logger.ts +1 -1
  241. package/src/mcp/__tests__/$resource.spec.ts +1 -1
  242. package/src/mcp/__tests__/$tool.spec.ts +1 -1
  243. package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
  244. package/src/orm/__tests__/$repository-tests.ts +1 -0
  245. package/src/orm/__tests__/orm-next-tests.ts +2 -67
  246. package/src/orm/__tests__/orm-next.spec.ts +0 -21
  247. package/src/orm/core/index.shared.ts +0 -2
  248. package/src/orm/core/index.ts +1 -2
  249. package/src/orm/core/primitives/$repository.ts +3 -6
  250. package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
  251. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
  252. package/src/orm/core/services/ModelBuilder.ts +1 -13
  253. package/src/orm/core/services/Repository.ts +1 -42
  254. package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
  255. package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
  256. package/src/react/form/index.ts +2 -0
  257. package/src/react/form/services/parseField.ts +163 -0
  258. package/src/react/form/services/prettyName.ts +19 -0
  259. package/src/react/head/providers/BrowserHeadProvider.ts +31 -10
  260. package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
  261. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
  262. package/src/react/router/primitives/$page.ts +35 -12
  263. package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
  264. package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
  265. package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
  266. package/src/react/router/providers/ReactServerProvider.ts +1 -0
  267. package/src/react/ui/atoms/uiAtom.ts +28 -0
  268. package/src/react/ui/components/ColorScheme.tsx +36 -0
  269. package/src/react/ui/hooks/useColorMode.ts +49 -0
  270. package/src/react/ui/hooks/useSidebarState.ts +26 -0
  271. package/src/react/ui/hooks/useTheme.ts +22 -0
  272. package/src/react/ui/index.ts +35 -0
  273. package/src/react/ui/services/UiPersistence.ts +41 -0
  274. package/src/router/TemplatedPathParser.ts +50 -51
  275. package/src/router/__tests__/RouterProvider.spec.ts +62 -0
  276. package/src/router/__tests__/TemplatedPathParser.spec.ts +18 -0
  277. package/src/router/providers/RouterProvider.ts +10 -5
  278. package/src/scheduler/providers/CronProvider.ts +1 -1
  279. package/src/security/primitives/$basicAuth.ts +1 -1
  280. package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
  281. package/src/server/core/interfaces/ServerRequest.ts +1 -0
  282. package/src/server/core/providers/ServerProvider.ts +1 -1
  283. package/src/server/core/providers/ServerRouterProvider.ts +2 -2
  284. package/src/server/core/services/HttpClient.ts +1 -1
  285. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  286. package/src/system/providers/NodeShellProvider.ts +1 -0
  287. package/src/topic/core/providers/TopicProvider.ts +1 -1
  288. package/dist/api/invitations/index.d.ts +0 -790
  289. package/dist/api/invitations/index.d.ts.map +0 -1
  290. package/dist/api/invitations/index.js +0 -662
  291. package/dist/api/invitations/index.js.map +0 -1
  292. package/dist/api/issues/index.d.ts +0 -810
  293. package/dist/api/issues/index.d.ts.map +0 -1
  294. package/dist/api/issues/index.js +0 -444
  295. package/dist/api/issues/index.js.map +0 -1
  296. package/dist/api/subscriptions/index.d.ts +0 -1692
  297. package/dist/api/subscriptions/index.d.ts.map +0 -1
  298. package/dist/api/subscriptions/index.js +0 -1867
  299. package/dist/api/subscriptions/index.js.map +0 -1
  300. package/dist/api/workflows/index.browser.js +0 -246
  301. package/dist/api/workflows/index.browser.js.map +0 -1
  302. package/dist/api/workflows/index.d.ts +0 -1618
  303. package/dist/api/workflows/index.d.ts.map +0 -1
  304. package/dist/api/workflows/index.js +0 -1495
  305. package/dist/api/workflows/index.js.map +0 -1
  306. package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
  307. package/src/api/invitations/__tests__/InvitationService.spec.ts +0 -439
  308. package/src/api/invitations/controllers/AdminInvitationController.ts +0 -86
  309. package/src/api/invitations/controllers/InvitationController.ts +0 -84
  310. package/src/api/invitations/entities/invitations.ts +0 -33
  311. package/src/api/invitations/index.ts +0 -58
  312. package/src/api/invitations/jobs/InvitationJobs.ts +0 -37
  313. package/src/api/invitations/providers/InvitationProvider.ts +0 -45
  314. package/src/api/invitations/schemas/createInvitationSchema.ts +0 -12
  315. package/src/api/invitations/schemas/invitationConfigAtom.ts +0 -20
  316. package/src/api/invitations/schemas/invitationQuerySchema.ts +0 -15
  317. package/src/api/invitations/schemas/invitationResourceSchema.ts +0 -6
  318. package/src/api/invitations/schemas/invitationWithResourceInfoSchema.ts +0 -22
  319. package/src/api/invitations/schemas/myInvitationsQuerySchema.ts +0 -10
  320. package/src/api/invitations/services/InvitationService.ts +0 -556
  321. package/src/api/issues/__tests__/IssueService.spec.ts +0 -263
  322. package/src/api/issues/controllers/AdminIssueController.ts +0 -149
  323. package/src/api/issues/controllers/IssueController.ts +0 -44
  324. package/src/api/issues/entities/issues.ts +0 -49
  325. package/src/api/issues/index.ts +0 -50
  326. package/src/api/issues/schemas/createIssueSchema.ts +0 -13
  327. package/src/api/issues/schemas/issueConfigAtom.ts +0 -13
  328. package/src/api/issues/schemas/issueQuerySchema.ts +0 -18
  329. package/src/api/issues/schemas/issueResourceSchema.ts +0 -6
  330. package/src/api/issues/schemas/myIssueQuerySchema.ts +0 -10
  331. package/src/api/issues/schemas/updateIssueSchema.ts +0 -13
  332. package/src/api/issues/services/IssueService.ts +0 -264
  333. package/src/api/jobs/__tests__/$job-middleware.spec.ts +0 -126
  334. package/src/api/jobs/__tests__/JobService.spec.ts +0 -31
  335. package/src/api/jobs/entities/jobExecutionLogEntity.ts +0 -13
  336. package/src/api/jobs/schemas/jobActivitySchema.ts +0 -15
  337. package/src/api/jobs/schemas/jobCronInfoSchema.ts +0 -22
  338. package/src/api/jobs/schemas/jobExecutionDetailResourceSchema.ts +0 -20
  339. package/src/api/jobs/schemas/jobFailureSchema.ts +0 -9
  340. package/src/api/jobs/schemas/jobQueueDepthSchema.ts +0 -14
  341. package/src/api/jobs/schemas/jobStatsSchema.ts +0 -14
  342. package/src/api/jobs/services/JobService-tests.ts +0 -157
  343. package/src/api/subscriptions/__tests__/BillingService.spec.ts +0 -218
  344. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +0 -278
  345. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +0 -212
  346. package/src/api/subscriptions/controllers/SubscriptionController.ts +0 -189
  347. package/src/api/subscriptions/entities/subscriptionEvents.ts +0 -54
  348. package/src/api/subscriptions/entities/subscriptions.ts +0 -68
  349. package/src/api/subscriptions/index.ts +0 -133
  350. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +0 -382
  351. package/src/api/subscriptions/middleware/$requireLimit.ts +0 -50
  352. package/src/api/subscriptions/middleware/$requirePlan.ts +0 -49
  353. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +0 -110
  354. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +0 -8
  355. package/src/api/subscriptions/schemas/changePlanSchema.ts +0 -9
  356. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +0 -11
  357. package/src/api/subscriptions/schemas/entitlementsSchema.ts +0 -21
  358. package/src/api/subscriptions/schemas/mrrSchema.ts +0 -13
  359. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +0 -71
  360. package/src/api/subscriptions/schemas/planResourceSchema.ts +0 -25
  361. package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +0 -8
  362. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +0 -19
  363. package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +0 -6
  364. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +0 -32
  365. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +0 -23
  366. package/src/api/subscriptions/services/BillingService.ts +0 -437
  367. package/src/api/subscriptions/services/SubscriptionConfig.ts +0 -56
  368. package/src/api/subscriptions/services/SubscriptionService.ts +0 -867
  369. package/src/api/subscriptions/services/UsageService.ts +0 -118
  370. package/src/api/workflows/__tests__/$workflow.spec.ts +0 -616
  371. package/src/api/workflows/controllers/AdminWorkflowController.ts +0 -191
  372. package/src/api/workflows/entities/workflowExecutions.ts +0 -74
  373. package/src/api/workflows/entities/workflowStepExecutions.ts +0 -74
  374. package/src/api/workflows/entities/workflowStepLogs.ts +0 -13
  375. package/src/api/workflows/index.browser.ts +0 -22
  376. package/src/api/workflows/index.ts +0 -115
  377. package/src/api/workflows/jobs/WorkflowJobs.ts +0 -77
  378. package/src/api/workflows/primitives/$workflow.ts +0 -202
  379. package/src/api/workflows/providers/WorkflowProvider.ts +0 -1284
  380. package/src/api/workflows/schemas/workflowActivitySchema.ts +0 -15
  381. package/src/api/workflows/schemas/workflowConfigAtom.ts +0 -51
  382. package/src/api/workflows/schemas/workflowExecutionDetailSchema.ts +0 -18
  383. package/src/api/workflows/schemas/workflowExecutionQuerySchema.ts +0 -26
  384. package/src/api/workflows/schemas/workflowExecutionResourceSchema.ts +0 -30
  385. package/src/api/workflows/schemas/workflowRegistrationSchema.ts +0 -26
  386. package/src/api/workflows/schemas/workflowStatsSchema.ts +0 -16
  387. package/src/api/workflows/schemas/workflowStepExecutionResourceSchema.ts +0 -15
  388. package/src/api/workflows/services/WorkflowService.ts +0 -382
  389. package/src/cli/core/templates/apiAppSecurityTs.ts +0 -43
  390. package/src/cli/core/templates/webAdminDashboardTsx.ts +0 -17
  391. package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
  392. package/src/orm/core/helpers/parseQueryString.ts +0 -502
  393. package/src/orm/core/primitives/$view.ts +0 -88
@@ -1,196 +0,0 @@
1
- import { describe, test } from "vitest";
2
- import { buildQueryString, parseQueryString } from "../index.ts";
3
-
4
- describe("parseQueryString with wildcard patterns", () => {
5
- test("should parse wildcard patterns with = operator", ({ expect }) => {
6
- // Test startsWith pattern
7
- const result1 = parseQueryString("name=John*");
8
- expect(result1).toEqual({ name: { startsWith: "John" } });
9
-
10
- // Test endsWith pattern
11
- const result2 = parseQueryString("name=*Smith");
12
- expect(result2).toEqual({ name: { endsWith: "Smith" } });
13
-
14
- // Test contains pattern
15
- const result3 = parseQueryString("name=*oh*");
16
- expect(result3).toEqual({ name: { contains: "oh" } });
17
-
18
- // Test literal asterisk in the middle (not at beginning or end)
19
- const result4 = parseQueryString("name=Jo*hn");
20
- expect(result4).toEqual({ name: { eq: "Jo*hn" } });
21
-
22
- // Test literal equals (no wildcards)
23
- const result5 = parseQueryString("name=John");
24
- expect(result5).toEqual({ name: { eq: "John" } });
25
- });
26
-
27
- test("should handle wildcard patterns in complex queries", ({ expect }) => {
28
- // Multiple conditions with wildcards
29
- const result1 = parseQueryString("name=*John&email=*@example.com");
30
- expect(result1).toEqual({
31
- and: [
32
- { name: { endsWith: "John" } },
33
- { email: { endsWith: "@example.com" } },
34
- ],
35
- });
36
-
37
- // OR conditions with wildcards
38
- const result2 = parseQueryString("name=John*|name=*Smith");
39
- expect(result2).toEqual({
40
- or: [{ name: { startsWith: "John" } }, { name: { endsWith: "Smith" } }],
41
- });
42
-
43
- // Nested conditions with wildcards
44
- const result3 = parseQueryString("(name=*John*|email=admin*)&age>18");
45
- expect(result3).toEqual({
46
- and: [
47
- {
48
- or: [
49
- { name: { contains: "John" } },
50
- { email: { startsWith: "admin" } },
51
- ],
52
- },
53
- { age: { gt: 18 } },
54
- ],
55
- });
56
- });
57
-
58
- test("should handle wildcard patterns in quoted strings", ({ expect }) => {
59
- // Quoted string with wildcards should be treated as wildcards
60
- const result1 = parseQueryString('name="*John*"');
61
- expect(result1).toEqual({ name: { contains: "John" } });
62
-
63
- // Quoted string with asterisk in middle
64
- const result2 = parseQueryString('name="Jo*hn"');
65
- expect(result2).toEqual({ name: { eq: "Jo*hn" } });
66
-
67
- // Single quotes
68
- const result3 = parseQueryString("name='*Smith'");
69
- expect(result3).toEqual({ name: { endsWith: "Smith" } });
70
- });
71
-
72
- test("should handle wildcard patterns with special characters", ({
73
- expect,
74
- }) => {
75
- // Wildcard with spaces
76
- const result1 = parseQueryString("name=*John Smith*");
77
- expect(result1).toEqual({ name: { contains: "John Smith" } });
78
-
79
- // Wildcard with special characters
80
- const result2 = parseQueryString("email=*@example.com");
81
- expect(result2).toEqual({ email: { endsWith: "@example.com" } });
82
-
83
- // Wildcard with numbers
84
- const result3 = parseQueryString("code=ABC*123");
85
- expect(result3).toEqual({ code: { eq: "ABC*123" } }); // Asterisk in middle is literal
86
- });
87
-
88
- test("should handle wildcard patterns in arrays", ({ expect }) => {
89
- // Array values don't support wildcards (treated as literal)
90
- const result = parseQueryString("status=[active*,*pending,*idle*]");
91
- expect(result).toEqual({
92
- status: { inArray: ["active*", "*pending", "*idle*"] },
93
- });
94
- });
95
-
96
- test("should handle wildcard patterns with != operator", ({ expect }) => {
97
- // != operator doesn't support wildcards, treats as literal
98
- const result1 = parseQueryString("name!=*John");
99
- expect(result1).toEqual({ name: { ne: "*John" } });
100
-
101
- const result2 = parseQueryString("name!=John*");
102
- expect(result2).toEqual({ name: { ne: "John*" } });
103
- });
104
-
105
- test("should handle empty wildcard patterns", ({ expect }) => {
106
- // Just asterisks - a single asterisk at the end means "starts with nothing" = everything
107
- const result1 = parseQueryString("name=*");
108
- expect(result1).toEqual({ name: { contains: "" } }); // Since * alone has both start and end asterisk
109
-
110
- const result2 = parseQueryString("name=**");
111
- expect(result2).toEqual({ name: { contains: "" } });
112
-
113
- const result3 = parseQueryString("name=***");
114
- expect(result3).toEqual({ name: { contains: "*" } });
115
- });
116
-
117
- test("should handle JSONB nested queries with wildcards", ({ expect }) => {
118
- const result = parseQueryString("profile.city=*Paris*&profile.name=John*");
119
- expect(result).toEqual({
120
- and: [
121
- { profile: { city: { contains: "Paris" } } },
122
- { profile: { name: { startsWith: "John" } } },
123
- ],
124
- });
125
- });
126
-
127
- test("should not apply wildcards to non-string operators", ({ expect }) => {
128
- // Numeric comparison operators don't use wildcards
129
- const result1 = parseQueryString("age>18");
130
- expect(result1).toEqual({ age: { gt: 18 } });
131
-
132
- // NULL checks don't use wildcards
133
- const result2 = parseQueryString("name=null");
134
- expect(result2).toEqual({ name: { isNull: true } });
135
-
136
- const result3 = parseQueryString("name!=null");
137
- expect(result3).toEqual({ name: { isNotNull: true } });
138
- });
139
- });
140
-
141
- describe("buildQueryString with wildcard patterns", () => {
142
- test("should build query strings from wildcard conditions", ({ expect }) => {
143
- // startsWith
144
- const query1 = buildQueryString({ name: { startsWith: "John" } });
145
- expect(query1).toBe("name=John*");
146
-
147
- // endsWith
148
- const query2 = buildQueryString({ name: { endsWith: "Smith" } });
149
- expect(query2).toBe("name=*Smith");
150
-
151
- // contains
152
- const query3 = buildQueryString({ name: { contains: "oh" } });
153
- expect(query3).toBe("name=*oh*");
154
- });
155
-
156
- test("should build complex query strings with wildcards", ({ expect }) => {
157
- const query = buildQueryString({
158
- and: [
159
- { name: { startsWith: "John" } },
160
- { email: { endsWith: "@example.com" } },
161
- { bio: { contains: "developer" } },
162
- ],
163
- });
164
- expect(query).toBe("name=John*&email=*@example.com&bio=*developer*");
165
- });
166
-
167
- test("should handle OR conditions with wildcards", ({ expect }) => {
168
- const query = buildQueryString({
169
- or: [
170
- { name: { startsWith: "Admin" } },
171
- { role: { contains: "manager" } },
172
- ],
173
- });
174
- expect(query).toBe("(name=Admin*|role=*manager*)");
175
- });
176
-
177
- test("round-trip conversion should preserve wildcard semantics", ({
178
- expect,
179
- }) => {
180
- const testCases = [
181
- "name=John*",
182
- "name=*Smith",
183
- "name=*John*",
184
- "email=admin*&role=*manager*",
185
- "(name=*John*|name=*Jane*)&active=true",
186
- "profile.city=*Paris*",
187
- ];
188
-
189
- for (const original of testCases) {
190
- const parsed = parseQueryString(original);
191
- const rebuilt = buildQueryString(parsed);
192
- const reparsed = parseQueryString(rebuilt);
193
- expect(reparsed).toEqual(parsed);
194
- }
195
- });
196
- });
@@ -1,502 +0,0 @@
1
- import { AlephaError, type TObject } from "alepha";
2
- import type { PgQueryWhere } from "../interfaces/PgQueryWhere.ts";
3
-
4
- /**
5
- * Parse a string query into a PgQueryWhere object.
6
- *
7
- * Supported syntax:
8
- * - Simple equality: "name=John"
9
- * - Wildcard patterns: "name=John*" (startsWith), "name=*John" (endsWith), "name=*John*" (contains)
10
- * - Operators: "age>18", "age>=18", "age<65", "age<=65", "status!=active"
11
- * - NULL checks: "deletedAt=null", "email!=null"
12
- * - IN arrays: "status=[pending,active]"
13
- * - AND conditions: "name=John&age>18"
14
- * - OR conditions: "name=John|email=john@example.com"
15
- * - Nested AND/OR: "(name=John|name=Jane)&age>18"
16
- * - JSONB nested: "profile.city=Paris"
17
- *
18
- * @example
19
- * ```ts
20
- * // Simple equality
21
- * parseQueryString("name=John")
22
- * // => { name: { eq: "John" } }
23
- *
24
- * // Wildcard patterns
25
- * parseQueryString("name=John*") // startsWith
26
- * // => { name: { startsWith: "John" } }
27
- * parseQueryString("name=*Smith") // endsWith
28
- * // => { name: { endsWith: "Smith" } }
29
- * parseQueryString("name=*oh*") // contains
30
- * // => { name: { contains: "oh" } }
31
- *
32
- * // Multiple conditions
33
- * parseQueryString("name=John&age>18")
34
- * // => { and: [{ name: { eq: "John" } }, { age: { gt: 18 } }] }
35
- *
36
- * // OR conditions
37
- * parseQueryString("status=active|status=pending")
38
- * // => { or: [{ status: { eq: "active" } }, { status: { eq: "pending" } }] }
39
- *
40
- * // Complex nested
41
- * parseQueryString("(name=John|name=Jane)&age>18&status!=archived")
42
- * // => { and: [
43
- * // { or: [{ name: { eq: "John" } }, { name: { eq: "Jane" } }] },
44
- * // { age: { gt: 18 } },
45
- * // { status: { ne: "archived" } }
46
- * // ] }
47
- *
48
- * // JSONB nested query
49
- * parseQueryString("profile.city=Paris&profile.age>25")
50
- * // => { profile: { city: { eq: "Paris" }, age: { gt: 25 } } }
51
- * ```
52
- */
53
- export function parseQueryString<T extends TObject>(
54
- query: string,
55
- ): PgQueryWhere<T> {
56
- if (!query || query.trim() === "") {
57
- return {};
58
- }
59
-
60
- const parser = new QueryStringParser(query);
61
- return parser.parse() as PgQueryWhere<T>;
62
- }
63
-
64
- // ---------------------------------------------------------------------------------------------------------------------
65
-
66
- class QueryStringParser {
67
- protected pos = 0;
68
- protected readonly query: string;
69
-
70
- constructor(query: string) {
71
- this.query = query.trim();
72
- }
73
-
74
- parse(): PgQueryWhere<any> {
75
- return this.parseExpression();
76
- }
77
-
78
- protected parseExpression(): PgQueryWhere<any> {
79
- return this.parseOr();
80
- }
81
-
82
- protected parseOr(): any {
83
- const left = this.parseAnd();
84
-
85
- // Check for OR operator (|)
86
- if (this.peek() === "|") {
87
- const conditions = [left];
88
-
89
- while (this.peek() === "|") {
90
- this.consume("|");
91
- conditions.push(this.parseAnd());
92
- }
93
-
94
- return { or: conditions };
95
- }
96
-
97
- return left;
98
- }
99
-
100
- protected parseAnd(): any {
101
- const left = this.parsePrimary();
102
-
103
- // Check for AND operator (&)
104
- if (this.peek() === "&") {
105
- const conditions = [left];
106
-
107
- while (this.peek() === "&") {
108
- this.consume("&");
109
- conditions.push(this.parsePrimary());
110
- }
111
-
112
- return { and: conditions };
113
- }
114
-
115
- return left;
116
- }
117
-
118
- protected parsePrimary(): any {
119
- this.skipWhitespace();
120
-
121
- // Handle parentheses
122
- if (this.peek() === "(") {
123
- this.consume("(");
124
- const expr = this.parseExpression();
125
- this.consume(")");
126
- return expr;
127
- }
128
-
129
- // Parse field condition
130
- return this.parseCondition();
131
- }
132
-
133
- protected parseCondition(): any {
134
- const field = this.parseFieldPath();
135
- this.skipWhitespace();
136
-
137
- // Get operator
138
- const operator = this.parseOperator();
139
- this.skipWhitespace();
140
-
141
- // Get value
142
- const value = this.parseValue();
143
-
144
- if (value === "") {
145
- throw new AlephaError(`Expected value for field '${field.join(".")}'`);
146
- }
147
-
148
- // Build the condition object
149
- return this.buildCondition(field, operator, value);
150
- }
151
-
152
- protected parseFieldPath(): string[] {
153
- const path: string[] = [];
154
- let current = "";
155
-
156
- while (this.pos < this.query.length) {
157
- const ch = this.query[this.pos];
158
-
159
- if (ch === "." && current) {
160
- path.push(current);
161
- current = "";
162
- this.pos++;
163
- continue;
164
- }
165
-
166
- if (ch === "=" || ch === "!" || ch === ">" || ch === "<" || ch === " ") {
167
- break;
168
- }
169
-
170
- current += ch;
171
- this.pos++;
172
- }
173
-
174
- if (current) {
175
- path.push(current);
176
- }
177
-
178
- return path;
179
- }
180
-
181
- protected parseOperator(): string {
182
- this.skipWhitespace();
183
-
184
- const remaining = this.query.slice(this.pos);
185
-
186
- // Two-character operators
187
- if (remaining.startsWith(">=")) {
188
- this.pos += 2;
189
- return ">=";
190
- }
191
- if (remaining.startsWith("<=")) {
192
- this.pos += 2;
193
- return "<=";
194
- }
195
- if (remaining.startsWith("!=")) {
196
- this.pos += 2;
197
- return "!=";
198
- }
199
-
200
- // Single-character operators
201
- const ch = this.query[this.pos];
202
- if (ch === "=" || ch === ">" || ch === "<") {
203
- this.pos++;
204
- return ch;
205
- }
206
-
207
- throw new AlephaError(`Expected operator at position ${this.pos}`);
208
- }
209
-
210
- protected parseValue(): any {
211
- this.skipWhitespace();
212
-
213
- // Handle null
214
- if (this.query.slice(this.pos, this.pos + 4).toLowerCase() === "null") {
215
- this.pos += 4;
216
- return null;
217
- }
218
-
219
- // Handle arrays [value1,value2,...]
220
- if (this.query[this.pos] === "[") {
221
- return this.parseArray();
222
- }
223
-
224
- // Handle quoted strings
225
- if (this.query[this.pos] === '"' || this.query[this.pos] === "'") {
226
- return this.parseQuotedString();
227
- }
228
-
229
- // Parse unquoted value (until &, |, or ))
230
- let value = "";
231
- while (this.pos < this.query.length) {
232
- const ch = this.query[this.pos];
233
- if (ch === "&" || ch === "|" || ch === ")") {
234
- break;
235
- }
236
- value += ch;
237
- this.pos++;
238
- }
239
-
240
- return this.coerceValue(value.trim());
241
- }
242
-
243
- protected parseArray(): any[] {
244
- this.consume("[");
245
- const values: any[] = [];
246
-
247
- while (this.pos < this.query.length && this.query[this.pos] !== "]") {
248
- this.skipWhitespace();
249
-
250
- // Handle quoted values
251
- if (this.query[this.pos] === '"' || this.query[this.pos] === "'") {
252
- values.push(this.parseQuotedString());
253
- } else {
254
- // Parse until comma or ]
255
- let value = "";
256
- while (
257
- this.pos < this.query.length &&
258
- this.query[this.pos] !== "," &&
259
- this.query[this.pos] !== "]"
260
- ) {
261
- value += this.query[this.pos];
262
- this.pos++;
263
- }
264
- values.push(this.coerceValue(value.trim()));
265
- }
266
-
267
- this.skipWhitespace();
268
- if (this.query[this.pos] === ",") {
269
- this.pos++;
270
- }
271
- }
272
-
273
- this.consume("]");
274
- return values;
275
- }
276
-
277
- protected parseQuotedString(): string {
278
- const quote = this.query[this.pos];
279
- this.pos++; // Skip opening quote
280
-
281
- let value = "";
282
- let escaped = false;
283
-
284
- while (this.pos < this.query.length) {
285
- const ch = this.query[this.pos];
286
-
287
- if (escaped) {
288
- value += ch;
289
- escaped = false;
290
- this.pos++;
291
- continue;
292
- }
293
-
294
- if (ch === "\\") {
295
- escaped = true;
296
- this.pos++;
297
- continue;
298
- }
299
-
300
- if (ch === quote) {
301
- this.pos++; // Skip closing quote
302
- break;
303
- }
304
-
305
- value += ch;
306
- this.pos++;
307
- }
308
-
309
- return value;
310
- }
311
-
312
- protected coerceValue(value: string): any {
313
- // Try to parse as number
314
- if (/^-?\d+$/.test(value)) {
315
- return parseInt(value, 10);
316
- }
317
-
318
- if (/^-?\d+\.\d+$/.test(value)) {
319
- return parseFloat(value);
320
- }
321
-
322
- // Try to parse as boolean
323
- if (value.toLowerCase() === "true") {
324
- return true;
325
- }
326
- if (value.toLowerCase() === "false") {
327
- return false;
328
- }
329
-
330
- return value;
331
- }
332
-
333
- protected buildCondition(path: string[], operator: string, value: any): any {
334
- // Map operator to filter operator
335
- let filterOp: any;
336
-
337
- if (operator === "=") {
338
- if (value === null) {
339
- filterOp = { isNull: true };
340
- } else if (Array.isArray(value)) {
341
- // Arrays should be treated as inArray regardless of content
342
- filterOp = { inArray: value };
343
- } else if (typeof value === "string" && value.includes("*")) {
344
- // Handle wildcard patterns
345
- const startsWithAsterisk = value.startsWith("*");
346
- const endsWithAsterisk = value.endsWith("*");
347
- const cleanValue = value.replace(/^\*|\*$/g, ""); // Remove leading/trailing asterisks
348
-
349
- if (startsWithAsterisk && endsWithAsterisk) {
350
- // *text* -> contains
351
- filterOp = { contains: cleanValue };
352
- } else if (startsWithAsterisk) {
353
- // *text -> endsWith
354
- filterOp = { endsWith: cleanValue };
355
- } else if (endsWithAsterisk) {
356
- // text* -> startsWith
357
- filterOp = { startsWith: cleanValue };
358
- } else {
359
- // Has asterisk in the middle, treat as literal
360
- filterOp = { eq: value };
361
- }
362
- } else {
363
- filterOp = { eq: value };
364
- }
365
- } else if (operator === "!=") {
366
- if (value === null) {
367
- filterOp = { isNotNull: true };
368
- } else {
369
- filterOp = { ne: value };
370
- }
371
- } else if (operator === ">") {
372
- filterOp = { gt: value };
373
- } else if (operator === ">=") {
374
- filterOp = { gte: value };
375
- } else if (operator === "<") {
376
- filterOp = { lt: value };
377
- } else if (operator === "<=") {
378
- filterOp = { lte: value };
379
- } else {
380
- throw new AlephaError(`Unsupported operator: ${operator}`);
381
- }
382
-
383
- // Build nested object for path
384
- if (path.length === 1) {
385
- return { [path[0]]: filterOp };
386
- }
387
-
388
- // Handle nested paths (JSONB)
389
- let result: any = filterOp;
390
- for (let i = path.length - 1; i >= 0; i--) {
391
- result = { [path[i]]: result };
392
- }
393
-
394
- return result;
395
- }
396
-
397
- protected peek(): string {
398
- this.skipWhitespace();
399
- return this.query[this.pos] || "";
400
- }
401
-
402
- protected consume(expected: string): void {
403
- this.skipWhitespace();
404
- if (this.query[this.pos] !== expected) {
405
- throw new AlephaError(
406
- `Expected '${expected}' at position ${this.pos}, got '${this.query[this.pos]}'`,
407
- );
408
- }
409
- this.pos++;
410
- }
411
-
412
- protected skipWhitespace(): void {
413
- while (this.pos < this.query.length && /\s/.test(this.query[this.pos])) {
414
- this.pos++;
415
- }
416
- }
417
- }
418
-
419
- // ---------------------------------------------------------------------------------------------------------------------
420
-
421
- /**
422
- * Helper function to build query strings programmatically
423
- *
424
- * @example
425
- * ```ts
426
- * buildQueryString({
427
- * and: [
428
- * { name: "eq:John" },
429
- * { age: "gt:18" }
430
- * ]
431
- * })
432
- * // => "name=John&age>18"
433
- * ```
434
- */
435
- export function buildQueryString(where: any): string {
436
- if (!where || typeof where !== "object") {
437
- return "";
438
- }
439
-
440
- // Handle logical operators
441
- if ("and" in where && Array.isArray(where.and)) {
442
- return where.and.map((w: any) => buildQueryString(w)).join("&");
443
- }
444
-
445
- if ("or" in where && Array.isArray(where.or)) {
446
- const parts = where.or.map((w: any) => buildQueryString(w));
447
- return parts.length > 1 ? `(${parts.join("|")})` : parts[0];
448
- }
449
-
450
- if ("not" in where) {
451
- // Not operator is harder to represent in string form
452
- // For now, we'll skip it or you could add a syntax like "!field=value"
453
- return "";
454
- }
455
-
456
- // Handle field conditions
457
- const parts: string[] = [];
458
-
459
- for (const [field, condition] of Object.entries(where)) {
460
- if (typeof condition !== "object" || condition === null) {
461
- parts.push(`${field}=${condition}`);
462
- continue;
463
- }
464
-
465
- if ("eq" in condition) {
466
- parts.push(`${field}=${condition.eq}`);
467
- } else if ("ne" in condition) {
468
- parts.push(`${field}!=${condition.ne}`);
469
- } else if ("gt" in condition) {
470
- parts.push(`${field}>${condition.gt}`);
471
- } else if ("gte" in condition) {
472
- parts.push(`${field}>=${condition.gte}`);
473
- } else if ("lt" in condition) {
474
- parts.push(`${field}<${condition.lt}`);
475
- } else if ("lte" in condition) {
476
- parts.push(`${field}<=${condition.lte}`);
477
- } else if ("contains" in condition) {
478
- parts.push(`${field}=*${condition.contains}*`);
479
- } else if ("startsWith" in condition) {
480
- parts.push(`${field}=${condition.startsWith}*`);
481
- } else if ("endsWith" in condition) {
482
- parts.push(`${field}=*${condition.endsWith}`);
483
- } else if ("isNull" in condition && condition.isNull) {
484
- parts.push(`${field}=null`);
485
- } else if ("isNotNull" in condition && condition.isNotNull) {
486
- parts.push(`${field}!=null`);
487
- } else if ("inArray" in condition && Array.isArray(condition.inArray)) {
488
- const values = condition.inArray.map((v: any) =>
489
- typeof v === "string" ? `"${v}"` : v,
490
- );
491
- parts.push(`${field}=[${values.join(",")}]`);
492
- } else {
493
- // Nested object (JSONB)
494
- const nested = buildQueryString(condition);
495
- if (nested) {
496
- parts.push(`${field}.${nested}`);
497
- }
498
- }
499
- }
500
-
501
- return parts.join("&");
502
- }