velocious 1.0.431 → 1.0.433

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 (794) hide show
  1. package/build/application.js +229 -0
  2. package/build/authorization/ability.js +329 -0
  3. package/build/authorization/base-resource.js +143 -0
  4. package/build/background-jobs/client.js +50 -0
  5. package/build/background-jobs/cron-expression.js +277 -0
  6. package/build/background-jobs/forked-runner-child.js +86 -0
  7. package/build/background-jobs/job-record.js +13 -0
  8. package/build/background-jobs/job-registry.js +92 -0
  9. package/build/background-jobs/job-runner.js +107 -0
  10. package/build/background-jobs/job.js +77 -0
  11. package/build/background-jobs/json-socket.js +78 -0
  12. package/build/background-jobs/main.js +926 -0
  13. package/build/background-jobs/normalize-error.js +26 -0
  14. package/build/background-jobs/scheduler.js +274 -0
  15. package/build/background-jobs/socket-request.js +68 -0
  16. package/build/background-jobs/status-reporter.js +101 -0
  17. package/build/background-jobs/store.js +994 -0
  18. package/build/background-jobs/types.js +70 -0
  19. package/build/background-jobs/web/authorization.js +89 -0
  20. package/build/background-jobs/web/controller.js +280 -0
  21. package/build/background-jobs/web/index.js +57 -0
  22. package/build/background-jobs/web/path-matcher.js +74 -0
  23. package/build/background-jobs/web/registry.js +49 -0
  24. package/build/background-jobs/worker.js +683 -0
  25. package/build/beacon/client.js +330 -0
  26. package/build/beacon/in-process-broker.js +71 -0
  27. package/build/beacon/in-process-client.js +139 -0
  28. package/build/beacon/server.js +148 -0
  29. package/build/beacon/types.js +55 -0
  30. package/build/cli/base-command.js +67 -0
  31. package/build/cli/browser-cli.js +45 -0
  32. package/build/cli/commands/background-jobs-main.js +7 -0
  33. package/build/cli/commands/background-jobs-runner.js +7 -0
  34. package/build/cli/commands/background-jobs-worker.js +7 -0
  35. package/build/cli/commands/beacon.js +7 -0
  36. package/build/cli/commands/console.js +12 -0
  37. package/build/cli/commands/db/base-command.js +82 -0
  38. package/build/cli/commands/db/create.js +64 -0
  39. package/build/cli/commands/db/drop.js +75 -0
  40. package/build/cli/commands/db/migrate.js +17 -0
  41. package/build/cli/commands/db/reset.js +22 -0
  42. package/build/cli/commands/db/rollback.js +15 -0
  43. package/build/cli/commands/db/schema/dump.js +12 -0
  44. package/build/cli/commands/db/schema/load.js +12 -0
  45. package/build/cli/commands/db/seed.js +12 -0
  46. package/build/cli/commands/db/tenants/check.js +38 -0
  47. package/build/cli/commands/db/tenants/create.js +33 -0
  48. package/build/cli/commands/db/tenants/migrate.js +49 -0
  49. package/build/cli/commands/destroy/migration.js +7 -0
  50. package/build/cli/commands/generate/base-models.js +7 -0
  51. package/build/cli/commands/generate/frontend-models.js +12 -0
  52. package/build/cli/commands/generate/migration.js +7 -0
  53. package/build/cli/commands/generate/model.js +7 -0
  54. package/build/cli/commands/init.js +11 -0
  55. package/build/cli/commands/routes.js +7 -0
  56. package/build/cli/commands/run-script.js +12 -0
  57. package/build/cli/commands/runner.js +12 -0
  58. package/build/cli/commands/server.js +7 -0
  59. package/build/cli/commands/test.js +9 -0
  60. package/build/cli/index.js +152 -0
  61. package/build/cli/tenant-database-command-helper.js +198 -0
  62. package/build/cli/use-browser-cli.js +30 -0
  63. package/build/configuration-resolver.js +65 -0
  64. package/build/configuration-types.js +429 -0
  65. package/build/configuration.js +2590 -0
  66. package/build/controller.js +421 -0
  67. package/build/current-configuration.js +31 -0
  68. package/build/current.js +80 -0
  69. package/build/database/annotations-async-hooks.js +47 -0
  70. package/build/database/annotations.js +40 -0
  71. package/build/database/drivers/base-column.js +182 -0
  72. package/build/database/drivers/base-columns-index.js +81 -0
  73. package/build/database/drivers/base-foreign-key.js +104 -0
  74. package/build/database/drivers/base-table.js +156 -0
  75. package/build/database/drivers/base.js +1609 -0
  76. package/build/database/drivers/mssql/column.js +74 -0
  77. package/build/database/drivers/mssql/columns-index.js +6 -0
  78. package/build/database/drivers/mssql/connect-connection.js +16 -0
  79. package/build/database/drivers/mssql/foreign-key.js +12 -0
  80. package/build/database/drivers/mssql/index.js +590 -0
  81. package/build/database/drivers/mssql/options.js +79 -0
  82. package/build/database/drivers/mssql/query-parser.js +6 -0
  83. package/build/database/drivers/mssql/sql/alter-table.js +4 -0
  84. package/build/database/drivers/mssql/sql/create-database.js +36 -0
  85. package/build/database/drivers/mssql/sql/create-index.js +4 -0
  86. package/build/database/drivers/mssql/sql/create-table.js +4 -0
  87. package/build/database/drivers/mssql/sql/delete.js +19 -0
  88. package/build/database/drivers/mssql/sql/drop-database.js +36 -0
  89. package/build/database/drivers/mssql/sql/drop-table.js +4 -0
  90. package/build/database/drivers/mssql/sql/insert.js +4 -0
  91. package/build/database/drivers/mssql/sql/update.js +31 -0
  92. package/build/database/drivers/mssql/sql/upsert.js +23 -0
  93. package/build/database/drivers/mssql/structure-sql.js +120 -0
  94. package/build/database/drivers/mssql/table.js +145 -0
  95. package/build/database/drivers/mysql/column.js +112 -0
  96. package/build/database/drivers/mysql/columns-index.js +22 -0
  97. package/build/database/drivers/mysql/foreign-key.js +12 -0
  98. package/build/database/drivers/mysql/index.js +473 -0
  99. package/build/database/drivers/mysql/options.js +34 -0
  100. package/build/database/drivers/mysql/query-parser.js +6 -0
  101. package/build/database/drivers/mysql/query.js +37 -0
  102. package/build/database/drivers/mysql/sql/alter-table.js +6 -0
  103. package/build/database/drivers/mysql/sql/create-database.js +39 -0
  104. package/build/database/drivers/mysql/sql/create-index.js +6 -0
  105. package/build/database/drivers/mysql/sql/create-table.js +6 -0
  106. package/build/database/drivers/mysql/sql/delete.js +21 -0
  107. package/build/database/drivers/mysql/sql/drop-database.js +6 -0
  108. package/build/database/drivers/mysql/sql/drop-table.js +6 -0
  109. package/build/database/drivers/mysql/sql/insert.js +6 -0
  110. package/build/database/drivers/mysql/sql/update.js +33 -0
  111. package/build/database/drivers/mysql/sql/upsert.js +13 -0
  112. package/build/database/drivers/mysql/structure-sql.js +93 -0
  113. package/build/database/drivers/mysql/table.js +121 -0
  114. package/build/database/drivers/pgsql/column.js +90 -0
  115. package/build/database/drivers/pgsql/columns-index.js +6 -0
  116. package/build/database/drivers/pgsql/foreign-key.js +12 -0
  117. package/build/database/drivers/pgsql/index.js +441 -0
  118. package/build/database/drivers/pgsql/options.js +32 -0
  119. package/build/database/drivers/pgsql/query-parser.js +6 -0
  120. package/build/database/drivers/pgsql/sql/alter-table.js +6 -0
  121. package/build/database/drivers/pgsql/sql/create-database.js +38 -0
  122. package/build/database/drivers/pgsql/sql/create-index.js +6 -0
  123. package/build/database/drivers/pgsql/sql/create-table.js +6 -0
  124. package/build/database/drivers/pgsql/sql/delete.js +21 -0
  125. package/build/database/drivers/pgsql/sql/drop-database.js +6 -0
  126. package/build/database/drivers/pgsql/sql/drop-table.js +6 -0
  127. package/build/database/drivers/pgsql/sql/insert.js +6 -0
  128. package/build/database/drivers/pgsql/sql/update.js +33 -0
  129. package/build/database/drivers/pgsql/sql/upsert.js +14 -0
  130. package/build/database/drivers/pgsql/structure-sql.js +126 -0
  131. package/build/database/drivers/pgsql/table.js +135 -0
  132. package/build/database/drivers/sqlite/base.js +509 -0
  133. package/build/database/drivers/sqlite/column.js +75 -0
  134. package/build/database/drivers/sqlite/columns-index.js +30 -0
  135. package/build/database/drivers/sqlite/connection-sql-js.js +46 -0
  136. package/build/database/drivers/sqlite/foreign-key.js +24 -0
  137. package/build/database/drivers/sqlite/index.js +394 -0
  138. package/build/database/drivers/sqlite/index.native.js +72 -0
  139. package/build/database/drivers/sqlite/index.web.js +99 -0
  140. package/build/database/drivers/sqlite/options.js +32 -0
  141. package/build/database/drivers/sqlite/query-parser.js +6 -0
  142. package/build/database/drivers/sqlite/query.js +35 -0
  143. package/build/database/drivers/sqlite/query.native.js +35 -0
  144. package/build/database/drivers/sqlite/query.web.js +49 -0
  145. package/build/database/drivers/sqlite/sql/alter-table.js +187 -0
  146. package/build/database/drivers/sqlite/sql/create-index.js +6 -0
  147. package/build/database/drivers/sqlite/sql/create-table.js +6 -0
  148. package/build/database/drivers/sqlite/sql/delete.js +26 -0
  149. package/build/database/drivers/sqlite/sql/drop-table.js +6 -0
  150. package/build/database/drivers/sqlite/sql/insert.js +6 -0
  151. package/build/database/drivers/sqlite/sql/update.js +33 -0
  152. package/build/database/drivers/sqlite/sql/upsert.js +14 -0
  153. package/build/database/drivers/sqlite/structure-sql.js +56 -0
  154. package/build/database/drivers/sqlite/table-rebuilder.js +96 -0
  155. package/build/database/drivers/sqlite/table.js +131 -0
  156. package/build/database/drivers/structure-sql/utils.js +35 -0
  157. package/build/database/handler.js +13 -0
  158. package/build/database/initializer-from-require-context.js +101 -0
  159. package/build/database/migration/index.js +438 -0
  160. package/build/database/migrator/files-finder.js +55 -0
  161. package/build/database/migrator/types.js +31 -0
  162. package/build/database/migrator.js +557 -0
  163. package/build/database/pool/async-tracked-multi-connection.js +1164 -0
  164. package/build/database/pool/base-methods-forward.js +52 -0
  165. package/build/database/pool/base.js +380 -0
  166. package/build/database/pool/single-multi-use.js +118 -0
  167. package/build/database/query/alter-table-base.js +104 -0
  168. package/build/database/query/base.js +49 -0
  169. package/build/database/query/create-database-base.js +42 -0
  170. package/build/database/query/create-index-base.js +117 -0
  171. package/build/database/query/create-table-base.js +205 -0
  172. package/build/database/query/delete-base.js +19 -0
  173. package/build/database/query/drop-database-base.js +38 -0
  174. package/build/database/query/drop-table-base.js +58 -0
  175. package/build/database/query/from-base.js +36 -0
  176. package/build/database/query/from-plain.js +16 -0
  177. package/build/database/query/from-table.js +18 -0
  178. package/build/database/query/index.js +533 -0
  179. package/build/database/query/insert-base.js +172 -0
  180. package/build/database/query/join-base.js +43 -0
  181. package/build/database/query/join-object.js +167 -0
  182. package/build/database/query/join-plain.js +18 -0
  183. package/build/database/query/join-tracker.js +93 -0
  184. package/build/database/query/model-class-query.js +1577 -0
  185. package/build/database/query/order-base.js +33 -0
  186. package/build/database/query/order-column.js +77 -0
  187. package/build/database/query/order-plain.js +28 -0
  188. package/build/database/query/preloader/belongs-to.js +267 -0
  189. package/build/database/query/preloader/ensure-model-class-initialized.js +18 -0
  190. package/build/database/query/preloader/has-many.js +316 -0
  191. package/build/database/query/preloader/has-one.js +123 -0
  192. package/build/database/query/preloader/selection.js +152 -0
  193. package/build/database/query/preloader.js +201 -0
  194. package/build/database/query/query-data.js +305 -0
  195. package/build/database/query/select-base.js +30 -0
  196. package/build/database/query/select-plain.js +18 -0
  197. package/build/database/query/select-table-and-column.js +28 -0
  198. package/build/database/query/update-base.js +41 -0
  199. package/build/database/query/upsert-base.js +103 -0
  200. package/build/database/query/where-base.js +38 -0
  201. package/build/database/query/where-combinator.js +31 -0
  202. package/build/database/query/where-hash.js +77 -0
  203. package/build/database/query/where-model-class-hash.js +505 -0
  204. package/build/database/query/where-not.js +23 -0
  205. package/build/database/query/where-plain.js +20 -0
  206. package/build/database/query/with-count.js +219 -0
  207. package/build/database/query-parser/base-query-parser.js +40 -0
  208. package/build/database/query-parser/from-parser.js +49 -0
  209. package/build/database/query-parser/group-parser.js +55 -0
  210. package/build/database/query-parser/joins-parser.js +37 -0
  211. package/build/database/query-parser/limit-parser.js +77 -0
  212. package/build/database/query-parser/options.js +94 -0
  213. package/build/database/query-parser/order-parser.js +45 -0
  214. package/build/database/query-parser/select-parser.js +67 -0
  215. package/build/database/query-parser/where-parser.js +46 -0
  216. package/build/database/record/acts-as-list.js +374 -0
  217. package/build/database/record/attachments/download.js +49 -0
  218. package/build/database/record/attachments/handle.js +188 -0
  219. package/build/database/record/attachments/normalize-input.js +213 -0
  220. package/build/database/record/attachments/storage-drivers/filesystem.js +114 -0
  221. package/build/database/record/attachments/storage-drivers/native.js +146 -0
  222. package/build/database/record/attachments/storage-drivers/s3.js +245 -0
  223. package/build/database/record/attachments/store.js +591 -0
  224. package/build/database/record/index.js +4119 -0
  225. package/build/database/record/instance-relationships/base.js +289 -0
  226. package/build/database/record/instance-relationships/belongs-to.js +84 -0
  227. package/build/database/record/instance-relationships/has-many.js +284 -0
  228. package/build/database/record/instance-relationships/has-one.js +117 -0
  229. package/build/database/record/record-not-found-error.js +3 -0
  230. package/build/database/record/relationships/base.js +195 -0
  231. package/build/database/record/relationships/belongs-to.js +57 -0
  232. package/build/database/record/relationships/has-many.js +46 -0
  233. package/build/database/record/relationships/has-one.js +46 -0
  234. package/build/database/record/state-machine.js +278 -0
  235. package/build/database/record/user-module.js +43 -0
  236. package/build/database/record/validators/base.js +27 -0
  237. package/build/database/record/validators/format.js +50 -0
  238. package/build/database/record/validators/presence.js +24 -0
  239. package/build/database/record/validators/uniqueness.js +124 -0
  240. package/build/database/table-data/index.js +241 -0
  241. package/build/database/table-data/table-column.js +416 -0
  242. package/build/database/table-data/table-foreign-key.js +69 -0
  243. package/build/database/table-data/table-index.js +46 -0
  244. package/build/database/table-data/table-reference.js +13 -0
  245. package/build/database/use-database.js +48 -0
  246. package/build/environment-handlers/base.js +561 -0
  247. package/build/environment-handlers/browser.js +338 -0
  248. package/build/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
  249. package/build/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
  250. package/build/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
  251. package/build/environment-handlers/node/cli/commands/beacon.js +21 -0
  252. package/build/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
  253. package/build/environment-handlers/node/cli/commands/console.js +149 -0
  254. package/build/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
  255. package/build/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
  256. package/build/environment-handlers/node/cli/commands/db/seed.js +79 -0
  257. package/build/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
  258. package/build/environment-handlers/node/cli/commands/generate/base-models.js +396 -0
  259. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
  260. package/build/environment-handlers/node/cli/commands/generate/migration.js +45 -0
  261. package/build/environment-handlers/node/cli/commands/generate/model.js +45 -0
  262. package/build/environment-handlers/node/cli/commands/init.js +68 -0
  263. package/build/environment-handlers/node/cli/commands/routes.js +63 -0
  264. package/build/environment-handlers/node/cli/commands/run-script.js +85 -0
  265. package/build/environment-handlers/node/cli/commands/runner.js +84 -0
  266. package/build/environment-handlers/node/cli/commands/server.js +151 -0
  267. package/build/environment-handlers/node/cli/commands/test.js +118 -0
  268. package/build/environment-handlers/node.js +887 -0
  269. package/build/error-logger.js +30 -0
  270. package/build/frontend-model-controller.js +3491 -0
  271. package/build/frontend-model-resource/base-resource.js +939 -0
  272. package/build/frontend-models/base.js +4004 -0
  273. package/build/frontend-models/clear-pending-debounced-callback.js +16 -0
  274. package/build/frontend-models/event-hook-models.js +49 -0
  275. package/build/frontend-models/model-registry.js +28 -0
  276. package/build/frontend-models/outgoing-event-buffer.js +51 -0
  277. package/build/frontend-models/preloader.js +169 -0
  278. package/build/frontend-models/query.js +2245 -0
  279. package/build/frontend-models/resource-config-validation.js +56 -0
  280. package/build/frontend-models/resource-definition.js +399 -0
  281. package/build/frontend-models/transport-serialization.js +369 -0
  282. package/build/frontend-models/use-created-event.js +21 -0
  283. package/build/frontend-models/use-destroyed-event.js +148 -0
  284. package/build/frontend-models/use-model-class-event.js +164 -0
  285. package/build/frontend-models/use-updated-event.js +152 -0
  286. package/build/frontend-models/websocket-channel.js +494 -0
  287. package/build/frontend-models/websocket-publishers.js +224 -0
  288. package/build/http-client/header.js +17 -0
  289. package/build/http-client/index.js +139 -0
  290. package/build/http-client/request.js +94 -0
  291. package/build/http-client/response.js +151 -0
  292. package/build/http-client/websocket-client.js +27 -0
  293. package/build/http-server/client/index.js +507 -0
  294. package/build/http-server/client/params-to-object.js +152 -0
  295. package/build/http-server/client/request-buffer/form-data-part.js +139 -0
  296. package/build/http-server/client/request-buffer/header.js +19 -0
  297. package/build/http-server/client/request-buffer/index.js +535 -0
  298. package/build/http-server/client/request-parser.js +195 -0
  299. package/build/http-server/client/request-runner.js +321 -0
  300. package/build/http-server/client/request-timing.js +171 -0
  301. package/build/http-server/client/request.js +114 -0
  302. package/build/http-server/client/response.js +251 -0
  303. package/build/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
  304. package/build/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
  305. package/build/http-server/client/uploaded-file/uploaded-file.js +36 -0
  306. package/build/http-server/client/websocket-request.js +147 -0
  307. package/build/http-server/client/websocket-session.js +1755 -0
  308. package/build/http-server/cookie.js +245 -0
  309. package/build/http-server/development-reloader.js +240 -0
  310. package/build/http-server/index.js +561 -0
  311. package/build/http-server/remote-address.js +77 -0
  312. package/build/http-server/server-client.js +222 -0
  313. package/build/http-server/server-lock.js +178 -0
  314. package/build/http-server/websocket-channel-subscribers.js +110 -0
  315. package/build/http-server/websocket-channel.js +137 -0
  316. package/build/http-server/websocket-connection.js +118 -0
  317. package/build/http-server/websocket-event-log-store.js +433 -0
  318. package/build/http-server/websocket-events-host.js +170 -0
  319. package/build/http-server/websocket-events.js +50 -0
  320. package/build/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
  321. package/build/http-server/worker-handler/in-process.js +155 -0
  322. package/build/http-server/worker-handler/index.js +370 -0
  323. package/build/http-server/worker-handler/worker-script.js +6 -0
  324. package/build/http-server/worker-handler/worker-thread.js +286 -0
  325. package/build/initializer.js +39 -0
  326. package/build/jobs/mail-delivery.js +22 -0
  327. package/build/logger/base-logger.js +34 -0
  328. package/build/logger/console-logger.js +28 -0
  329. package/build/logger/file-logger.js +36 -0
  330. package/build/logger/outputs/array-output.js +50 -0
  331. package/build/logger/outputs/console-output.js +32 -0
  332. package/build/logger/outputs/file-output.js +55 -0
  333. package/build/logger/outputs/stdout-output.js +64 -0
  334. package/build/logger.js +507 -0
  335. package/build/mailer/backends/smtp.js +197 -0
  336. package/build/mailer/base.js +337 -0
  337. package/build/mailer/delivery.js +70 -0
  338. package/build/mailer/index.js +24 -0
  339. package/build/mailer.js +15 -0
  340. package/build/plugins/sqljs-wasm-route-controller.js +70 -0
  341. package/build/plugins/sqljs-wasm-route.js +71 -0
  342. package/build/record-payload-values.js +83 -0
  343. package/build/routes/app-routes.js +17 -0
  344. package/build/routes/base-route.js +133 -0
  345. package/build/routes/basic-route.js +109 -0
  346. package/build/routes/built-in/debug/controller.js +12 -0
  347. package/build/routes/built-in/errors/controller.js +7 -0
  348. package/build/routes/get-route.js +75 -0
  349. package/build/routes/hooks/frontend-model-command-route-hook.js +100 -0
  350. package/build/routes/index.js +50 -0
  351. package/build/routes/namespace-route.js +51 -0
  352. package/build/routes/plugin-routes.js +141 -0
  353. package/build/routes/post-route.js +74 -0
  354. package/build/routes/resolver.js +535 -0
  355. package/build/routes/resource-route.js +154 -0
  356. package/build/routes/root-route.js +11 -0
  357. package/build/src/application.js +187 -214
  358. package/build/src/authorization/ability.js +250 -297
  359. package/build/src/authorization/base-resource.js +120 -136
  360. package/build/src/background-jobs/client.js +43 -47
  361. package/build/src/background-jobs/cron-expression.js +127 -166
  362. package/build/src/background-jobs/forked-runner-child.js +37 -47
  363. package/build/src/background-jobs/job-record.js +8 -10
  364. package/build/src/background-jobs/job-registry.js +72 -84
  365. package/build/src/background-jobs/job-runner.js +74 -81
  366. package/build/src/background-jobs/job.js +62 -72
  367. package/build/src/background-jobs/json-socket.js +65 -70
  368. package/build/src/background-jobs/main.js +841 -900
  369. package/build/src/background-jobs/normalize-error.js +12 -11
  370. package/build/src/background-jobs/scheduler.js +205 -247
  371. package/build/src/background-jobs/socket-request.js +60 -65
  372. package/build/src/background-jobs/status-reporter.js +86 -96
  373. package/build/src/background-jobs/store.js +862 -980
  374. package/build/src/background-jobs/types.js +2 -3
  375. package/build/src/background-jobs/web/authorization.js +38 -50
  376. package/build/src/background-jobs/web/controller.js +232 -268
  377. package/build/src/background-jobs/web/index.js +36 -40
  378. package/build/src/background-jobs/web/path-matcher.js +45 -48
  379. package/build/src/background-jobs/web/registry.js +9 -14
  380. package/build/src/background-jobs/worker.js +585 -639
  381. package/build/src/beacon/client.js +264 -293
  382. package/build/src/beacon/in-process-broker.js +20 -25
  383. package/build/src/beacon/in-process-client.js +104 -116
  384. package/build/src/beacon/server.js +110 -126
  385. package/build/src/beacon/types.js +2 -8
  386. package/build/src/cli/base-command.js +49 -57
  387. package/build/src/cli/browser-cli.js +37 -42
  388. package/build/src/cli/commands/background-jobs-main.js +5 -5
  389. package/build/src/cli/commands/background-jobs-runner.js +5 -5
  390. package/build/src/cli/commands/background-jobs-worker.js +5 -5
  391. package/build/src/cli/commands/beacon.js +5 -5
  392. package/build/src/cli/commands/console.js +10 -10
  393. package/build/src/cli/commands/db/base-command.js +71 -76
  394. package/build/src/cli/commands/db/create.js +53 -61
  395. package/build/src/cli/commands/db/drop.js +62 -71
  396. package/build/src/cli/commands/db/migrate.js +13 -15
  397. package/build/src/cli/commands/db/reset.js +16 -19
  398. package/build/src/cli/commands/db/rollback.js +12 -13
  399. package/build/src/cli/commands/db/schema/dump.js +9 -9
  400. package/build/src/cli/commands/db/schema/load.js +9 -9
  401. package/build/src/cli/commands/db/seed.js +9 -9
  402. package/build/src/cli/commands/db/tenants/check.js +32 -35
  403. package/build/src/cli/commands/db/tenants/create.js +26 -29
  404. package/build/src/cli/commands/db/tenants/migrate.js +40 -44
  405. package/build/src/cli/commands/destroy/migration.js +5 -5
  406. package/build/src/cli/commands/generate/base-models.js +5 -5
  407. package/build/src/cli/commands/generate/frontend-models.js +9 -9
  408. package/build/src/cli/commands/generate/migration.js +5 -5
  409. package/build/src/cli/commands/generate/model.js +5 -5
  410. package/build/src/cli/commands/init.js +7 -9
  411. package/build/src/cli/commands/routes.js +6 -6
  412. package/build/src/cli/commands/run-script.js +9 -9
  413. package/build/src/cli/commands/runner.js +9 -9
  414. package/build/src/cli/commands/server.js +6 -6
  415. package/build/src/cli/commands/test.js +6 -7
  416. package/build/src/cli/index.js +127 -141
  417. package/build/src/cli/tenant-database-command-helper.js +154 -185
  418. package/build/src/cli/use-browser-cli.js +15 -20
  419. package/build/src/configuration-resolver.js +47 -54
  420. package/build/src/configuration-types.d.ts +5 -3
  421. package/build/src/configuration-types.d.ts.map +1 -1
  422. package/build/src/configuration-types.js +3 -54
  423. package/build/src/configuration.js +2240 -2547
  424. package/build/src/controller.js +363 -407
  425. package/build/src/current-configuration.js +9 -12
  426. package/build/src/current.js +70 -75
  427. package/build/src/database/annotations-async-hooks.js +16 -22
  428. package/build/src/database/annotations.js +12 -18
  429. package/build/src/database/drivers/base-column.js +155 -179
  430. package/build/src/database/drivers/base-columns-index.js +69 -78
  431. package/build/src/database/drivers/base-foreign-key.js +89 -101
  432. package/build/src/database/drivers/base-table.js +124 -149
  433. package/build/src/database/drivers/base.js +1306 -1489
  434. package/build/src/database/drivers/mssql/column.js +39 -50
  435. package/build/src/database/drivers/mssql/columns-index.js +2 -3
  436. package/build/src/database/drivers/mssql/connect-connection.js +11 -9
  437. package/build/src/database/drivers/mssql/foreign-key.js +8 -9
  438. package/build/src/database/drivers/mssql/index.js +507 -587
  439. package/build/src/database/drivers/mssql/options.js +68 -75
  440. package/build/src/database/drivers/mssql/query-parser.js +2 -3
  441. package/build/src/database/drivers/mssql/sql/alter-table.js +2 -2
  442. package/build/src/database/drivers/mssql/sql/create-database.js +24 -31
  443. package/build/src/database/drivers/mssql/sql/create-index.js +2 -2
  444. package/build/src/database/drivers/mssql/sql/create-table.js +2 -2
  445. package/build/src/database/drivers/mssql/sql/delete.js +14 -16
  446. package/build/src/database/drivers/mssql/sql/drop-database.js +24 -31
  447. package/build/src/database/drivers/mssql/sql/drop-table.js +2 -2
  448. package/build/src/database/drivers/mssql/sql/insert.js +2 -2
  449. package/build/src/database/drivers/mssql/sql/update.js +24 -28
  450. package/build/src/database/drivers/mssql/sql/upsert.js +18 -20
  451. package/build/src/database/drivers/mssql/structure-sql.js +102 -114
  452. package/build/src/database/drivers/mssql/table.js +81 -96
  453. package/build/src/database/drivers/mysql/column.js +75 -92
  454. package/build/src/database/drivers/mysql/columns-index.js +16 -19
  455. package/build/src/database/drivers/mysql/foreign-key.js +8 -9
  456. package/build/src/database/drivers/mysql/index.js +396 -457
  457. package/build/src/database/drivers/mysql/options.js +26 -30
  458. package/build/src/database/drivers/mysql/query-parser.js +2 -3
  459. package/build/src/database/drivers/mysql/query.js +26 -29
  460. package/build/src/database/drivers/mysql/sql/alter-table.js +2 -3
  461. package/build/src/database/drivers/mysql/sql/create-database.js +23 -28
  462. package/build/src/database/drivers/mysql/sql/create-index.js +2 -3
  463. package/build/src/database/drivers/mysql/sql/create-table.js +2 -3
  464. package/build/src/database/drivers/mysql/sql/delete.js +14 -17
  465. package/build/src/database/drivers/mysql/sql/drop-database.js +2 -3
  466. package/build/src/database/drivers/mysql/sql/drop-table.js +2 -3
  467. package/build/src/database/drivers/mysql/sql/insert.js +2 -3
  468. package/build/src/database/drivers/mysql/sql/update.js +24 -29
  469. package/build/src/database/drivers/mysql/sql/upsert.js +8 -10
  470. package/build/src/database/drivers/mysql/structure-sql.js +79 -88
  471. package/build/src/database/drivers/mysql/table.js +83 -98
  472. package/build/src/database/drivers/pgsql/column.js +56 -72
  473. package/build/src/database/drivers/pgsql/columns-index.js +2 -3
  474. package/build/src/database/drivers/pgsql/foreign-key.js +8 -9
  475. package/build/src/database/drivers/pgsql/index.js +377 -438
  476. package/build/src/database/drivers/pgsql/options.js +25 -28
  477. package/build/src/database/drivers/pgsql/query-parser.js +2 -3
  478. package/build/src/database/drivers/pgsql/sql/alter-table.js +2 -3
  479. package/build/src/database/drivers/pgsql/sql/create-database.js +19 -23
  480. package/build/src/database/drivers/pgsql/sql/create-index.js +2 -3
  481. package/build/src/database/drivers/pgsql/sql/create-table.js +2 -3
  482. package/build/src/database/drivers/pgsql/sql/delete.js +14 -17
  483. package/build/src/database/drivers/pgsql/sql/drop-database.js +2 -3
  484. package/build/src/database/drivers/pgsql/sql/drop-table.js +2 -3
  485. package/build/src/database/drivers/pgsql/sql/insert.js +2 -3
  486. package/build/src/database/drivers/pgsql/sql/update.js +24 -29
  487. package/build/src/database/drivers/pgsql/sql/upsert.js +9 -11
  488. package/build/src/database/drivers/pgsql/structure-sql.js +108 -120
  489. package/build/src/database/drivers/pgsql/table.js +60 -77
  490. package/build/src/database/drivers/sqlite/base.js +405 -478
  491. package/build/src/database/drivers/sqlite/column.js +54 -69
  492. package/build/src/database/drivers/sqlite/columns-index.js +22 -27
  493. package/build/src/database/drivers/sqlite/connection-sql-js.js +35 -42
  494. package/build/src/database/drivers/sqlite/foreign-key.js +18 -21
  495. package/build/src/database/drivers/sqlite/index.js +330 -373
  496. package/build/src/database/drivers/sqlite/index.native.js +55 -64
  497. package/build/src/database/drivers/sqlite/index.web.js +69 -87
  498. package/build/src/database/drivers/sqlite/options.js +25 -28
  499. package/build/src/database/drivers/sqlite/query-parser.js +2 -3
  500. package/build/src/database/drivers/sqlite/query.js +21 -24
  501. package/build/src/database/drivers/sqlite/query.native.js +20 -25
  502. package/build/src/database/drivers/sqlite/query.web.js +30 -37
  503. package/build/src/database/drivers/sqlite/sql/alter-table.js +159 -179
  504. package/build/src/database/drivers/sqlite/sql/create-index.js +2 -3
  505. package/build/src/database/drivers/sqlite/sql/create-table.js +2 -3
  506. package/build/src/database/drivers/sqlite/sql/delete.js +17 -22
  507. package/build/src/database/drivers/sqlite/sql/drop-table.js +2 -3
  508. package/build/src/database/drivers/sqlite/sql/insert.js +2 -3
  509. package/build/src/database/drivers/sqlite/sql/update.js +24 -29
  510. package/build/src/database/drivers/sqlite/sql/upsert.js +9 -11
  511. package/build/src/database/drivers/sqlite/structure-sql.js +49 -52
  512. package/build/src/database/drivers/sqlite/table-rebuilder.js +62 -75
  513. package/build/src/database/drivers/sqlite/table.js +102 -125
  514. package/build/src/database/drivers/structure-sql/utils.js +14 -17
  515. package/build/src/database/handler.js +9 -10
  516. package/build/src/database/initializer-from-require-context.js +76 -87
  517. package/build/src/database/migration/index.js +332 -395
  518. package/build/src/database/migrator/files-finder.js +40 -50
  519. package/build/src/database/migrator/types.js +2 -30
  520. package/build/src/database/migrator.js +454 -526
  521. package/build/src/database/pool/async-tracked-multi-connection.js +997 -1147
  522. package/build/src/database/pool/base-methods-forward.js +40 -43
  523. package/build/src/database/pool/base.js +298 -343
  524. package/build/src/database/pool/single-multi-use.js +93 -110
  525. package/build/src/database/query/alter-table-base.js +84 -99
  526. package/build/src/database/query/base.js +39 -46
  527. package/build/src/database/query/create-database-base.js +25 -30
  528. package/build/src/database/query/create-index-base.js +75 -94
  529. package/build/src/database/query/create-table-base.js +151 -193
  530. package/build/src/database/query/delete-base.js +14 -16
  531. package/build/src/database/query/drop-database-base.js +23 -28
  532. package/build/src/database/query/drop-table-base.js +42 -53
  533. package/build/src/database/query/from-base.js +30 -33
  534. package/build/src/database/query/from-plain.js +11 -13
  535. package/build/src/database/query/from-table.js +13 -15
  536. package/build/src/database/query/index.js +410 -472
  537. package/build/src/database/query/insert-base.js +143 -164
  538. package/build/src/database/query/join-base.js +35 -40
  539. package/build/src/database/query/join-object.js +128 -153
  540. package/build/src/database/query/join-plain.js +13 -15
  541. package/build/src/database/query/join-tracker.js +76 -90
  542. package/build/src/database/query/model-class-query.js +1134 -1370
  543. package/build/src/database/query/order-base.js +27 -30
  544. package/build/src/database/query/order-column.js +44 -53
  545. package/build/src/database/query/order-plain.js +20 -24
  546. package/build/src/database/query/preloader/belongs-to.js +210 -258
  547. package/build/src/database/query/preloader/ensure-model-class-initialized.js +8 -9
  548. package/build/src/database/query/preloader/has-many.js +240 -301
  549. package/build/src/database/query/preloader/has-one.js +91 -117
  550. package/build/src/database/query/preloader/selection.js +117 -129
  551. package/build/src/database/query/preloader.js +160 -185
  552. package/build/src/database/query/query-data.js +157 -201
  553. package/build/src/database/query/select-base.js +25 -27
  554. package/build/src/database/query/select-plain.js +13 -15
  555. package/build/src/database/query/select-table-and-column.js +21 -25
  556. package/build/src/database/query/update-base.js +35 -38
  557. package/build/src/database/query/upsert-base.js +93 -100
  558. package/build/src/database/query/where-base.js +32 -35
  559. package/build/src/database/query/where-combinator.js +25 -28
  560. package/build/src/database/query/where-hash.js +61 -68
  561. package/build/src/database/query/where-model-class-hash.js +414 -469
  562. package/build/src/database/query/where-not.js +18 -20
  563. package/build/src/database/query/where-plain.js +15 -17
  564. package/build/src/database/query/with-count.js +125 -159
  565. package/build/src/database/query-parser/base-query-parser.js +32 -37
  566. package/build/src/database/query-parser/from-parser.js +36 -45
  567. package/build/src/database/query-parser/group-parser.js +42 -50
  568. package/build/src/database/query-parser/joins-parser.js +28 -33
  569. package/build/src/database/query-parser/limit-parser.js +67 -70
  570. package/build/src/database/query-parser/options.js +75 -82
  571. package/build/src/database/query-parser/order-parser.js +36 -40
  572. package/build/src/database/query-parser/select-parser.js +49 -60
  573. package/build/src/database/query-parser/where-parser.js +36 -41
  574. package/build/src/database/record/acts-as-list.js +235 -273
  575. package/build/src/database/record/attachments/download.js +44 -45
  576. package/build/src/database/record/attachments/handle.js +141 -161
  577. package/build/src/database/record/attachments/normalize-input.js +128 -138
  578. package/build/src/database/record/attachments/storage-drivers/filesystem.js +77 -91
  579. package/build/src/database/record/attachments/storage-drivers/native.js +112 -121
  580. package/build/src/database/record/attachments/storage-drivers/s3.js +177 -208
  581. package/build/src/database/record/attachments/store.js +467 -539
  582. package/build/src/database/record/index.d.ts +109 -25
  583. package/build/src/database/record/index.d.ts.map +1 -1
  584. package/build/src/database/record/index.js +3502 -3898
  585. package/build/src/database/record/instance-relationships/base.js +234 -268
  586. package/build/src/database/record/instance-relationships/belongs-to.js +58 -73
  587. package/build/src/database/record/instance-relationships/has-many.js +225 -264
  588. package/build/src/database/record/instance-relationships/has-one.js +85 -105
  589. package/build/src/database/record/record-not-found-error.js +3 -2
  590. package/build/src/database/record/relationships/base.js +144 -166
  591. package/build/src/database/record/relationships/belongs-to.js +44 -51
  592. package/build/src/database/record/relationships/has-many.js +32 -40
  593. package/build/src/database/record/relationships/has-one.js +32 -40
  594. package/build/src/database/record/state-machine.js +156 -208
  595. package/build/src/database/record/user-module.js +32 -38
  596. package/build/src/database/record/validators/base.js +22 -24
  597. package/build/src/database/record/validators/format.js +36 -46
  598. package/build/src/database/record/validators/presence.js +18 -20
  599. package/build/src/database/record/validators/uniqueness.js +99 -117
  600. package/build/src/database/table-data/index.js +199 -231
  601. package/build/src/database/table-data/table-column.js +338 -382
  602. package/build/src/database/table-data/table-foreign-key.js +57 -66
  603. package/build/src/database/table-data/table-index.js +29 -36
  604. package/build/src/database/table-data/table-reference.js +10 -10
  605. package/build/src/database/use-database.js +32 -40
  606. package/build/src/environment-handlers/base.js +484 -544
  607. package/build/src/environment-handlers/browser.js +241 -294
  608. package/build/src/environment-handlers/node/cli/commands/background-jobs-main.js +16 -19
  609. package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +18 -21
  610. package/build/src/environment-handlers/node/cli/commands/background-jobs-worker.js +22 -29
  611. package/build/src/environment-handlers/node/cli/commands/beacon.js +16 -19
  612. package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +14 -15
  613. package/build/src/environment-handlers/node/cli/commands/console.js +99 -120
  614. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +34 -39
  615. package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +57 -63
  616. package/build/src/environment-handlers/node/cli/commands/db/seed.js +51 -63
  617. package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +32 -40
  618. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +4 -2
  619. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  620. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +326 -358
  621. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +10 -10
  622. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  623. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +729 -844
  624. package/build/src/environment-handlers/node/cli/commands/generate/migration.js +34 -38
  625. package/build/src/environment-handlers/node/cli/commands/generate/model.js +34 -38
  626. package/build/src/environment-handlers/node/cli/commands/init.js +56 -61
  627. package/build/src/environment-handlers/node/cli/commands/routes.js +51 -59
  628. package/build/src/environment-handlers/node/cli/commands/run-script.js +54 -68
  629. package/build/src/environment-handlers/node/cli/commands/runner.js +56 -74
  630. package/build/src/environment-handlers/node/cli/commands/server.js +93 -106
  631. package/build/src/environment-handlers/node/cli/commands/test.js +97 -113
  632. package/build/src/environment-handlers/node.js +753 -874
  633. package/build/src/error-logger.js +22 -21
  634. package/build/src/frontend-model-controller.js +2791 -3291
  635. package/build/src/frontend-model-resource/base-resource.d.ts +8 -3
  636. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  637. package/build/src/frontend-model-resource/base-resource.js +770 -865
  638. package/build/src/frontend-models/base.js +3136 -3593
  639. package/build/src/frontend-models/clear-pending-debounced-callback.js +7 -8
  640. package/build/src/frontend-models/event-hook-models.js +16 -21
  641. package/build/src/frontend-models/model-registry.js +9 -11
  642. package/build/src/frontend-models/outgoing-event-buffer.js +10 -17
  643. package/build/src/frontend-models/preloader.js +131 -149
  644. package/build/src/frontend-models/query.js +1557 -1855
  645. package/build/src/frontend-models/resource-config-validation.js +27 -37
  646. package/build/src/frontend-models/resource-definition.d.ts +6 -7
  647. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  648. package/build/src/frontend-models/resource-definition.js +237 -291
  649. package/build/src/frontend-models/transport-serialization.js +203 -266
  650. package/build/src/frontend-models/use-created-event.js +5 -7
  651. package/build/src/frontend-models/use-destroyed-event.js +80 -93
  652. package/build/src/frontend-models/use-model-class-event.js +79 -91
  653. package/build/src/frontend-models/use-updated-event.js +84 -97
  654. package/build/src/frontend-models/websocket-channel.js +381 -441
  655. package/build/src/frontend-models/websocket-publishers.js +142 -175
  656. package/build/src/http-client/header.js +13 -14
  657. package/build/src/http-client/index.js +116 -132
  658. package/build/src/http-client/request.js +71 -87
  659. package/build/src/http-client/response.js +122 -140
  660. package/build/src/http-client/websocket-client.js +15 -17
  661. package/build/src/http-server/client/index.js +409 -465
  662. package/build/src/http-server/client/params-to-object.js +124 -135
  663. package/build/src/http-server/client/request-buffer/form-data-part.js +111 -132
  664. package/build/src/http-server/client/request-buffer/header.js +15 -16
  665. package/build/src/http-server/client/request-buffer/index.js +446 -506
  666. package/build/src/http-server/client/request-parser.js +163 -186
  667. package/build/src/http-server/client/request-runner.js +226 -259
  668. package/build/src/http-server/client/request-timing.js +132 -151
  669. package/build/src/http-server/client/request.js +96 -108
  670. package/build/src/http-server/client/response.js +213 -235
  671. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +25 -29
  672. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +25 -29
  673. package/build/src/http-server/client/uploaded-file/uploaded-file.js +33 -33
  674. package/build/src/http-server/client/websocket-request.js +114 -137
  675. package/build/src/http-server/client/websocket-session.js +1452 -1657
  676. package/build/src/http-server/cookie.js +216 -236
  677. package/build/src/http-server/development-reloader.js +190 -221
  678. package/build/src/http-server/index.js +451 -525
  679. package/build/src/http-server/remote-address.js +38 -50
  680. package/build/src/http-server/server-client.js +181 -208
  681. package/build/src/http-server/server-lock.js +153 -167
  682. package/build/src/http-server/websocket-channel-subscribers.js +81 -93
  683. package/build/src/http-server/websocket-channel.js +104 -117
  684. package/build/src/http-server/websocket-connection.js +96 -104
  685. package/build/src/http-server/websocket-event-log-store.js +350 -404
  686. package/build/src/http-server/websocket-events-host.js +145 -164
  687. package/build/src/http-server/websocket-events.js +47 -47
  688. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +13 -14
  689. package/build/src/http-server/worker-handler/in-process.js +123 -141
  690. package/build/src/http-server/worker-handler/index.js +313 -349
  691. package/build/src/http-server/worker-handler/worker-script.js +4 -5
  692. package/build/src/http-server/worker-handler/worker-thread.js +240 -269
  693. package/build/src/initializer.js +31 -36
  694. package/build/src/jobs/mail-delivery.js +13 -15
  695. package/build/src/logger/base-logger.js +24 -26
  696. package/build/src/logger/console-logger.js +21 -23
  697. package/build/src/logger/file-logger.js +29 -31
  698. package/build/src/logger/outputs/array-output.js +37 -42
  699. package/build/src/logger/outputs/console-output.js +20 -24
  700. package/build/src/logger/outputs/file-output.js +43 -48
  701. package/build/src/logger/outputs/stdout-output.js +39 -48
  702. package/build/src/logger.js +338 -394
  703. package/build/src/mailer/backends/smtp.js +134 -163
  704. package/build/src/mailer/base.js +211 -251
  705. package/build/src/mailer/delivery.js +56 -64
  706. package/build/src/mailer/index.js +4 -22
  707. package/build/src/mailer.js +4 -13
  708. package/build/src/plugins/sqljs-wasm-route-controller.js +42 -52
  709. package/build/src/plugins/sqljs-wasm-route.js +28 -38
  710. package/build/src/record-payload-values.js +25 -28
  711. package/build/src/routes/app-routes.js +12 -14
  712. package/build/src/routes/base-route.js +112 -130
  713. package/build/src/routes/basic-route.js +83 -102
  714. package/build/src/routes/built-in/debug/controller.js +10 -10
  715. package/build/src/routes/built-in/errors/controller.js +5 -5
  716. package/build/src/routes/get-route.js +50 -63
  717. package/build/src/routes/hooks/frontend-model-command-route-hook.js +66 -80
  718. package/build/src/routes/index.js +36 -43
  719. package/build/src/routes/namespace-route.js +38 -47
  720. package/build/src/routes/plugin-routes.js +107 -124
  721. package/build/src/routes/post-route.js +51 -62
  722. package/build/src/routes/resolver.js +422 -494
  723. package/build/src/routes/resource-route.js +124 -143
  724. package/build/src/routes/root-route.js +7 -8
  725. package/build/src/testing/base-expect.js +13 -14
  726. package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +329 -405
  727. package/build/src/testing/browser-test-app.js +23 -29
  728. package/build/src/testing/expect-to-change.js +41 -50
  729. package/build/src/testing/expect-utils.js +139 -184
  730. package/build/src/testing/expect.js +638 -731
  731. package/build/src/testing/request-client.js +70 -85
  732. package/build/src/testing/test-files-finder.js +285 -339
  733. package/build/src/testing/test-filter-parser.js +124 -155
  734. package/build/src/testing/test-runner.js +883 -1020
  735. package/build/src/testing/test-suite-splitter.js +114 -142
  736. package/build/src/testing/test.js +216 -256
  737. package/build/src/utils/backtrace-cleaner-node.js +62 -69
  738. package/build/src/utils/backtrace-cleaner.js +188 -216
  739. package/build/src/utils/ensure-error.js +7 -7
  740. package/build/src/utils/event-emitter.js +4 -6
  741. package/build/src/utils/file-exists.js +9 -10
  742. package/build/src/utils/format-value.js +67 -76
  743. package/build/src/utils/model-scope.js +27 -31
  744. package/build/src/utils/nest-callbacks.js +10 -13
  745. package/build/src/utils/plain-object.js +5 -6
  746. package/build/src/utils/ransack.js +448 -563
  747. package/build/src/utils/rest-args-error.js +5 -6
  748. package/build/src/utils/singularize-model-name.js +9 -11
  749. package/build/src/utils/split-sql-statements.js +68 -79
  750. package/build/src/utils/to-import-specifier.js +24 -30
  751. package/build/src/utils/with-tracked-stack-async-hooks.js +60 -74
  752. package/build/src/utils/with-tracked-stack.js +14 -18
  753. package/build/src/velocious-error.js +27 -30
  754. package/build/templates/configuration.js +61 -0
  755. package/build/templates/generate-migration.js +11 -0
  756. package/build/templates/generate-model.js +6 -0
  757. package/build/templates/routes.js +11 -0
  758. package/build/testing/base-expect.js +17 -0
  759. package/build/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
  760. package/build/testing/browser-test-app.js +32 -0
  761. package/build/testing/expect-to-change.js +55 -0
  762. package/build/testing/expect-utils.js +269 -0
  763. package/build/testing/expect.js +763 -0
  764. package/build/testing/request-client.js +90 -0
  765. package/build/testing/test-files-finder.js +364 -0
  766. package/build/testing/test-filter-parser.js +198 -0
  767. package/build/testing/test-runner.js +1168 -0
  768. package/build/testing/test-suite-splitter.js +177 -0
  769. package/build/testing/test.js +370 -0
  770. package/build/utils/backtrace-cleaner-node.js +87 -0
  771. package/build/utils/backtrace-cleaner.js +266 -0
  772. package/build/utils/ensure-error.js +15 -0
  773. package/build/utils/event-emitter.js +8 -0
  774. package/build/utils/file-exists.js +18 -0
  775. package/build/utils/format-value.js +101 -0
  776. package/build/utils/model-scope.js +56 -0
  777. package/build/utils/nest-callbacks.js +22 -0
  778. package/build/utils/plain-object.js +14 -0
  779. package/build/utils/ransack.js +859 -0
  780. package/build/utils/rest-args-error.js +14 -0
  781. package/build/utils/singularize-model-name.js +18 -0
  782. package/build/utils/split-sql-statements.js +88 -0
  783. package/build/utils/to-import-specifier.js +53 -0
  784. package/build/utils/with-tracked-stack-async-hooks.js +103 -0
  785. package/build/utils/with-tracked-stack.js +38 -0
  786. package/build/velocious-error.js +34 -0
  787. package/package.json +3 -3
  788. package/src/configuration-types.js +1 -1
  789. package/src/database/record/index.js +174 -25
  790. package/src/environment-handlers/node/cli/commands/generate/base-models.js +50 -21
  791. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +5 -5
  792. package/src/frontend-model-resource/base-resource.js +6 -2
  793. package/src/frontend-models/resource-definition.js +3 -3
  794. package/src/frontend-models/websocket-publishers.js +6 -6
@@ -0,0 +1,1577 @@
1
+ // @ts-check
2
+
3
+ import {incorporate} from "incorporator"
4
+ import * as inflection from "inflection"
5
+ import {isPlainObject} from "is-plain-object"
6
+ import Logger from "../../logger.js"
7
+ import Preloader from "./preloader.js"
8
+ import {normalizeQueryDataSpec, runQueryData} from "./query-data.js"
9
+ import {normalizeWithCount, runWithCount} from "./with-count.js"
10
+ import DatabaseQuery from "./index.js"
11
+ import JoinObject from "./join-object.js"
12
+ import JoinPlain from "./join-plain.js"
13
+ import JoinTracker from "./join-tracker.js"
14
+ import RecordNotFoundError from "../record/record-not-found-error.js"
15
+ import {normalizeRansackGroup, parseRansackSort} from "../../utils/ransack.js"
16
+ import {isModelScopeDescriptor} from "../../utils/model-scope.js"
17
+ import WhereCombinator from "./where-combinator.js"
18
+ import WhereModelClassHash from "./where-model-class-hash.js"
19
+ import WhereNot from "./where-not.js"
20
+ import JoinsParser from "../query-parser/joins-parser.js"
21
+ import WhereParser from "../query-parser/where-parser.js"
22
+
23
+ /**
24
+ * Runs unquote sql identifier.
25
+ * @param {string} value - Potentially quoted SQL identifier.
26
+ * @returns {string} - Unquoted identifier.
27
+ */
28
+ function unquoteSqlIdentifier(value) {
29
+ const trimmed = value.trim()
30
+
31
+ if (trimmed.length >= 2 && ((trimmed.startsWith("`") && trimmed.endsWith("`")) || (trimmed.startsWith("\"") && trimmed.endsWith("\"")))) {
32
+ return trimmed.slice(1, -1)
33
+ }
34
+
35
+ if (trimmed.length >= 2 && trimmed.startsWith("[") && trimmed.endsWith("]")) {
36
+ return trimmed.slice(1, -1)
37
+ }
38
+
39
+ return trimmed
40
+ }
41
+
42
+ /**
43
+ * Runs parse from plain table reference.
44
+ * @param {string} fromPlain - FROM clause source.
45
+ * @returns {string | null} - Parsed table reference or null when unsupported.
46
+ */
47
+ function parseFromPlainTableReference(fromPlain) {
48
+ const trimmed = fromPlain.trim()
49
+
50
+ if (trimmed.length < 1) return null
51
+
52
+ const aliasMatch = trimmed.match(/(?:^|\s)(?:AS\s+)?([`"]?[a-zA-Z_][a-zA-Z0-9_]*[`"]?|\[[a-zA-Z_][a-zA-Z0-9_]*\])\s*$/i)
53
+
54
+ if (!aliasMatch || !aliasMatch[1]) return null
55
+
56
+ return unquoteSqlIdentifier(aliasMatch[1])
57
+ }
58
+
59
+ /**
60
+ * Runs normalize scope path.
61
+ * @param {string | string[]} path - Scope path input.
62
+ * @returns {string[]} - Normalized path.
63
+ */
64
+ function normalizeScopePath(path) {
65
+ if (typeof path === "string") {
66
+ if (path.length < 1) throw new Error("Scope path strings must be non-empty")
67
+
68
+ return [path]
69
+ }
70
+
71
+ if (!Array.isArray(path)) {
72
+ throw new Error(`Invalid scope path type: ${typeof path}`)
73
+ }
74
+
75
+ for (const entry of path) {
76
+ if (typeof entry !== "string" || entry.length < 1) {
77
+ throw new Error("Scope path entries must be non-empty strings")
78
+ }
79
+ }
80
+
81
+ return [...path]
82
+ }
83
+
84
+ /**
85
+ * Deep-copies a preload select map (keyed by model name with attribute arrays)
86
+ * so a cloned query's selections can be mutated without affecting the original.
87
+ * @param {Record<string, string[]>} map - Preload select map to copy.
88
+ * @returns {Record<string, string[]>} - A copy with independent arrays.
89
+ */
90
+ function clonePreloadSelectMap(map) {
91
+ /**
92
+ * Result.
93
+ @type {Record<string, string[]>} */
94
+ const result = {}
95
+
96
+ for (const [modelName, attributes] of Object.entries(map)) {
97
+ result[modelName] = [...attributes]
98
+ }
99
+
100
+ return result
101
+ }
102
+
103
+ /**
104
+ * Runs normalize preload record.
105
+ * @param {import("./index.js").NestedPreloadRecord | string | Array<string | import("./index.js").NestedPreloadRecord>} preload - Preload data in shorthand or nested form.
106
+ * @returns {import("./index.js").NestedPreloadRecord} - Normalized preload record.
107
+ */
108
+ function normalizePreloadRecord(preload) {
109
+ if (!preload) return {}
110
+
111
+ if (typeof preload == "string") {
112
+ return {[preload]: true}
113
+ }
114
+
115
+ if (Array.isArray(preload)) {
116
+ /**
117
+ * Result.
118
+ @type {import("./index.js").NestedPreloadRecord} */
119
+ const result = {}
120
+
121
+ for (const entry of preload) {
122
+ if (typeof entry == "string") {
123
+ result[entry] = true
124
+ continue
125
+ }
126
+
127
+ if (isPlainObject(entry)) {
128
+ incorporate(result, normalizePreloadRecord(entry))
129
+ continue
130
+ }
131
+
132
+ throw new Error(`Invalid preload entry type: ${typeof entry}`)
133
+ }
134
+
135
+ return result
136
+ }
137
+
138
+ if (!isPlainObject(preload)) {
139
+ throw new Error(`Invalid preload type: ${typeof preload}`)
140
+ }
141
+
142
+ /**
143
+ * Result.
144
+ @type {import("./index.js").NestedPreloadRecord} */
145
+ const result = {}
146
+
147
+ for (const [key, value] of Object.entries(preload)) {
148
+ if (value === true || value === false) {
149
+ result[key] = value
150
+ continue
151
+ }
152
+
153
+ if (typeof value == "string" || Array.isArray(value) || isPlainObject(value)) {
154
+ result[key] = normalizePreloadRecord(value)
155
+ continue
156
+ }
157
+
158
+ throw new Error(`Invalid preload value for ${key}: ${typeof value}`)
159
+ }
160
+
161
+ return result
162
+ }
163
+
164
+ /**
165
+ * Defines this typedef.
166
+ * @template {typeof import("../record/index.js").default} [MC=typeof import("../record/index.js").default]
167
+ */
168
+ /**
169
+ * Defines this typedef.
170
+ * @template {typeof import("../record/index.js").default} [MC=typeof import("../record/index.js").default]
171
+ * @typedef {import("./index.js").QueryArgsType & {modelClass: MC, joinBasePath?: string[], joinTracker?: import("./join-tracker.js").default, forceQualifyBaseTable?: boolean, withCount?: import("./with-count.js").WithCountEntry[], queryData?: import("./query-data.js").QueryDataEntry[]}} ModelClassQueryArgsType
172
+ */
173
+
174
+ /**
175
+ * A generic query over some model type.
176
+ * @template {typeof import("../record/index.js").default} [MC=typeof import("../record/index.js").default]
177
+ */
178
+ export default class VelociousDatabaseQueryModelClassQuery extends DatabaseQuery {
179
+ /**
180
+ * Runs constructor.
181
+ * @param {ModelClassQueryArgsType<MC>} args - Query constructor arguments.
182
+ */
183
+ constructor(args) {
184
+ const {modelClass} = args
185
+
186
+ if (!modelClass) throw new Error(`No modelClass given in ${Object.keys(args).join(", ")}`)
187
+
188
+ super(args)
189
+ this.logger = new Logger(this)
190
+
191
+ /**
192
+ * Narrows the runtime value to the documented type.
193
+ @type {MC} */
194
+ this.modelClass = modelClass
195
+
196
+ /**
197
+ * Narrows the runtime value to the documented type.
198
+ @type {string[]} */
199
+ this._joinBasePath = args.joinBasePath || []
200
+ this._joinTracker = args.joinTracker || new JoinTracker({modelClass: this.modelClass})
201
+ this._forceQualifyBaseTable = Boolean(args.forceQualifyBaseTable)
202
+
203
+ /**
204
+ * Narrows the runtime value to the documented type.
205
+ @type {import("./with-count.js").WithCountEntry[]} */
206
+ this._withCount = args.withCount ? [...args.withCount] : []
207
+
208
+ /**
209
+ * Narrows the runtime value to the documented type.
210
+ @type {import("./query-data.js").QueryDataEntry[]} */
211
+ this._queryData = args.queryData ? [...args.queryData] : []
212
+ }
213
+
214
+ /**
215
+ * Runs clone.
216
+ * @returns {this} - The clone.
217
+ */
218
+ clone() {
219
+ const newQuery = /**
220
+ * Narrows the runtime value to the documented type.
221
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (new VelociousDatabaseQueryModelClassQuery({
222
+ driver: this._driverFn,
223
+ froms: [...this._froms],
224
+ handler: this.handler.clone(),
225
+ groups: [...this._groups],
226
+ joins: [...this._joins],
227
+ limit: this._limit,
228
+ modelClass: this.modelClass,
229
+ offset: this._offset,
230
+ orders: [...this._orders],
231
+ page: this._page,
232
+ perPage: this._perPage,
233
+ preload: {...this._preload},
234
+ preloadSelects: clonePreloadSelectMap(this._preloadSelects),
235
+ preloadSelectsExtra: clonePreloadSelectMap(this._preloadSelectsExtra),
236
+ distinct: this._distinct,
237
+ selects: [...this._selects],
238
+ wheres: [...this._wheres],
239
+ joinBasePath: [...this._joinBasePath],
240
+ joinTracker: this._joinTracker.clone(),
241
+ forceQualifyBaseTable: this._forceQualifyBaseTable,
242
+ withCount: [...this._withCount],
243
+ queryData: [...this._queryData]
244
+ }))
245
+
246
+ // @ts-expect-error
247
+ return newQuery
248
+ }
249
+
250
+ /**
251
+ * Tell the query to attach one or more association counts onto every
252
+ * loaded record. The counts land as regular attributes on each record;
253
+ * read them with `model.readAttribute("<name>Count")`.
254
+ * @param {import("./with-count.js").WithCountSpec} spec - Count spec in shorthand or nested form.
255
+ * @returns {this} - This query, for chaining.
256
+ */
257
+ withCount(spec) {
258
+ for (const entry of normalizeWithCount(spec)) {
259
+ this._withCount.push(entry)
260
+ }
261
+
262
+ return this
263
+ }
264
+
265
+ /**
266
+ * Attach one or more consumer-defined, per-row computed values onto
267
+ * every loaded root record. Leaf strings in the spec are names of
268
+ * functions previously registered via `Model.queryData(name, fn)`.
269
+ * Nested object keys are relationship names traced from the root to
270
+ * the model that declares the fn. Every resulting SELECT alias is
271
+ * attached to the **root** record (not to the intermediate joined
272
+ * rows); read values with `record.queryData(aliasName)`.
273
+ *
274
+ * See also `src/database/query/query-data.js`.
275
+ * @param {import("./query-data.js").QueryDataSpec} spec - Spec in shorthand or nested form.
276
+ * @returns {this} - This query, for chaining.
277
+ */
278
+ queryData(spec) {
279
+ for (const entry of normalizeQueryDataSpec(spec)) {
280
+ this._queryData.push(entry)
281
+ }
282
+
283
+ return this
284
+ }
285
+
286
+ /**
287
+ * Return the table reference (alias or table name) registered for the
288
+ * given relationship chain, relative to the query's current join base
289
+ * path. Convenience wrapper around `getTableReferenceForJoin` for use
290
+ * inside `queryData` callbacks where the writer's intent reads more
291
+ * naturally as "give me the table name for 'tasks'".
292
+ * @param {...string} path - Relationship path segments.
293
+ * @returns {string} - Unquoted table reference.
294
+ */
295
+ tableNameFor(...path) {
296
+ return this.getTableReferenceForJoin(...path)
297
+ }
298
+
299
+ /**
300
+ * Runs count.
301
+ * @returns {Promise<number>} - Resolves with the count.
302
+ */
303
+ async count() {
304
+ if (this._limit !== null || this._offset !== null) {
305
+ return await this.paginatedCount()
306
+ }
307
+
308
+ // Generate count SQL
309
+ const primaryKey = `${this.driver.quoteTable(this.getModelClass().tableName())}.${this.driver.quoteColumn(this.getModelClass().primaryKey())}`
310
+ const distinctPrefix = this._distinct ? "DISTINCT " : ""
311
+ let sql = `COUNT(${distinctPrefix}${primaryKey})`
312
+
313
+ if (this.driver.getType() == "pgsql") sql += "::int"
314
+
315
+ sql += " AS count"
316
+
317
+
318
+ // Clone query and execute count
319
+ const countQuery = this.clone()
320
+
321
+ countQuery._distinct = false
322
+ countQuery._selects = []
323
+ countQuery.select(sql)
324
+
325
+ const results = /**
326
+ * Narrows the runtime value to the documented type.
327
+ @type {{count: number}[]} */ (await countQuery._executeQuery({
328
+ logName: countQuery.queryLogName("Count")
329
+ }))
330
+
331
+ // The query isn't grouped and a single result has been given
332
+ if (results.length == 1) {
333
+ return results[0].count
334
+ }
335
+
336
+ // The query may be grouped and a lot of different counts a given
337
+ let countResult = 0
338
+
339
+ for (const result of results) {
340
+ if (!("count" in result)) {
341
+ throw new Error("Invalid count result")
342
+ }
343
+
344
+ countResult += result.count
345
+ }
346
+
347
+ return countResult
348
+ }
349
+
350
+ /**
351
+ * Runs paginated count.
352
+ * @returns {Promise<number>} - Resolves with the count after pagination is applied.
353
+ */
354
+ async paginatedCount() {
355
+ const countQuery = this.clone()
356
+ const countSql = this.driver.getType() == "pgsql" ? "COUNT(*)::int" : "COUNT(*)"
357
+ const sql = [
358
+ `SELECT ${countSql} AS ${this.driver.quoteColumn("count")}`,
359
+ `FROM (${countQuery.toSql()}) AS ${this.driver.quoteTable("paginated_count_rows")}`
360
+ ].join(" ")
361
+ const results = /**
362
+ * Narrows the runtime value to the documented type.
363
+ @type {{count: number}[]} */ (await this.driver.query(
364
+ sql,
365
+ {logName: this.queryLogName("Count")}
366
+ ))
367
+
368
+ if (results.length != 1 || !("count" in results[0])) {
369
+ throw new Error("Invalid count result")
370
+ }
371
+
372
+ return results[0].count
373
+ }
374
+
375
+ /**
376
+ * Runs select.
377
+ * @param {import("./index.js").SelectArgumentType} select - Select.
378
+ * @returns {this} - The select.
379
+ */
380
+ select(select) {
381
+ if (Array.isArray(select)) {
382
+ for (const selectEntry of select) {
383
+ this.select(selectEntry)
384
+ }
385
+
386
+ return this
387
+ }
388
+
389
+ if (typeof select === "string") {
390
+ const trimmedSelect = select.trim()
391
+
392
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmedSelect)) {
393
+ const modelClass = this.getModelClass()
394
+ const attributeMap = modelClass.getAttributeNameToColumnNameMap()
395
+ const columnName = attributeMap[trimmedSelect] || trimmedSelect
396
+ const tableReference = this.rootTableReference()
397
+ const qualifiedColumn = `${this.driver.quoteTable(tableReference)}.${this.driver.quoteColumn(columnName)}`
398
+
399
+ return super.select(qualifiedColumn)
400
+ }
401
+ }
402
+
403
+ // Object form keyed by target model name, e.g. `.select({Account: ["id"]})`.
404
+ // These limit the attributes loaded for preloaded relationship targets
405
+ // rather than the root query's SELECT clause.
406
+ if (isPlainObject(select)) {
407
+ this._mergePreloadSelect(this._preloadSelects, select)
408
+
409
+ return this
410
+ }
411
+
412
+ return super.select(select)
413
+ }
414
+
415
+ /**
416
+ * Loads the default columns plus the given extra selects for preloaded
417
+ * relationship targets, keyed by target model name, e.g.
418
+ * `.selectsExtra({Account: ["(SELECT count(*) FROM projects) AS projects_count"]})`.
419
+ * Unlike `select({...})`, which narrows to only the listed columns, this keeps
420
+ * the default `SELECT *` columns and adds the extras on top.
421
+ * @param {Record<string, string | string[]>} select - Extra selects keyed by target model name.
422
+ * @returns {this} - This query, for chaining.
423
+ */
424
+ selectsExtra(select) {
425
+ this._mergePreloadSelect(this._preloadSelectsExtra, select)
426
+
427
+ return this
428
+ }
429
+
430
+ /**
431
+ * Merges an object-form preload select (keyed by target model name) into the
432
+ * given target map, de-duplicating attribute/expression entries.
433
+ * @param {Record<string, string[]>} target - Map to merge into.
434
+ * @param {Record<string, string | string[]>} select - Object-form select.
435
+ * @returns {void} - No return value.
436
+ */
437
+ _mergePreloadSelect(target, select) {
438
+ for (const [modelName, attributes] of Object.entries(select)) {
439
+ const normalizedAttributes = Array.isArray(attributes) ? attributes : [attributes]
440
+
441
+ if (!target[modelName]) target[modelName] = []
442
+
443
+ for (const attribute of normalizedAttributes) {
444
+ if (!target[modelName].includes(attribute)) target[modelName].push(attribute)
445
+ }
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Runs root table reference.
451
+ * @returns {string} - Root table reference for query select qualification.
452
+ */
453
+ rootTableReference() {
454
+ const froms = this.getFroms()
455
+ const lastFrom = froms[froms.length - 1]
456
+
457
+ if (lastFrom && typeof /**
458
+ * Narrows the runtime value to the documented type.
459
+ @type {?} */ (lastFrom).tableName === "string") {
460
+ return /** Narrows the runtime value to the documented type. @type {?} */ (lastFrom).tableName
461
+ }
462
+
463
+ if (lastFrom && typeof /**
464
+ * Narrows the runtime value to the documented type.
465
+ @type {?} */ (lastFrom).plain === "string") {
466
+ const parsedReference = parseFromPlainTableReference(/**
467
+ * Narrows the runtime value to the documented type.
468
+ @type {?} */ (lastFrom).plain)
469
+
470
+ if (parsedReference) return parsedReference
471
+ }
472
+
473
+ return this.getTableReferenceForJoin()
474
+ }
475
+
476
+ /**
477
+ * Runs get model class.
478
+ * @returns {MC} - The model class.
479
+ */
480
+ getModelClass() {
481
+ if (!this.modelClass) throw new Error("modelClass not set")
482
+
483
+ return this.modelClass
484
+ }
485
+
486
+ /**
487
+ * Runs get join base path.
488
+ * @returns {string[]} - The join base path.
489
+ */
490
+ getJoinBasePath() {
491
+ return this._joinBasePath
492
+ }
493
+
494
+ /**
495
+ * Runs get join tracker.
496
+ * @returns {import("./join-tracker.js").default} - The join tracker.
497
+ */
498
+ getJoinTracker() {
499
+ return this._joinTracker
500
+ }
501
+
502
+ /**
503
+ * Runs get force qualify base table.
504
+ * @returns {boolean} - Whether to qualify base table.
505
+ */
506
+ getForceQualifyBaseTable() {
507
+ return this._forceQualifyBaseTable
508
+ }
509
+
510
+ /**
511
+ * Runs set join base path.
512
+ * @param {string[]} joinBasePath - Join base path.
513
+ * @returns {this} - The query with updated base path.
514
+ */
515
+ setJoinBasePath(joinBasePath) {
516
+ this._joinBasePath = joinBasePath
517
+ return this
518
+ }
519
+
520
+ /**
521
+ * Runs with join path.
522
+ * @param {string[]} joinBasePath - Join base path.
523
+ * @returns {VelociousDatabaseQueryModelClassQuery<MC>} - The scoped query.
524
+ */
525
+ withJoinPath(joinBasePath) {
526
+ const scopedQuery = /**
527
+ * Narrows the runtime value to the documented type.
528
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (this.clone())
529
+
530
+ scopedQuery._joinBasePath = joinBasePath
531
+ scopedQuery._joinTracker = this._joinTracker
532
+
533
+ return scopedQuery
534
+ }
535
+
536
+ /**
537
+ * Runs resolve table name for join path.
538
+ * @param {string[]} path - Join path.
539
+ * @returns {string} - Table name for path.
540
+ */
541
+ _resolveTableNameForJoinPath(path) {
542
+ return this._resolveModelClassForJoinPath(path).tableName()
543
+ }
544
+
545
+ /**
546
+ * Runs resolve model class for join path.
547
+ * @param {string[]} path - Join path.
548
+ * @returns {typeof import("../record/index.js").default} - Target model class.
549
+ */
550
+ _resolveModelClassForJoinPath(path) {
551
+ let modelClass = this._joinTracker.getRootModelClass()
552
+
553
+ for (const relationshipName of path) {
554
+ const relationship = modelClass.getRelationshipByName(relationshipName)
555
+ const targetModelClass = relationship.getTargetModelClass()
556
+
557
+ if (!targetModelClass) {
558
+ throw new Error(`No target model class for ${modelClass.name}#${relationshipName}`)
559
+ }
560
+
561
+ modelClass = targetModelClass
562
+ }
563
+
564
+ return modelClass
565
+ }
566
+
567
+ /**
568
+ * Runs register join path.
569
+ * @param {string[]} path - Join path.
570
+ * @returns {{tableName: string, alias: string | undefined}} - The entry.
571
+ */
572
+ _registerJoinPath(path) {
573
+ const tableName = this._resolveTableNameForJoinPath(path)
574
+
575
+ return this._joinTracker.registerPath(path, tableName)
576
+ }
577
+
578
+ /**
579
+ * Runs get join table reference.
580
+ * @param {string[]} path - Join path.
581
+ * @returns {string} - Unquoted table reference (alias or table name).
582
+ */
583
+ getJoinTableReference(path) {
584
+ const entry = this._joinTracker.getEntry(path) || this._registerJoinPath(path)
585
+
586
+ return entry.alias || entry.tableName
587
+ }
588
+
589
+ /**
590
+ * Runs get table reference for join.
591
+ * @param {...string} path - Join path segments.
592
+ * @returns {string} - Unquoted table reference (alias or table name).
593
+ */
594
+ getTableReferenceForJoin(...path) {
595
+ const fullPath = this._joinBasePath.concat(path)
596
+
597
+ return this.getJoinTableReference(fullPath)
598
+ }
599
+
600
+ /**
601
+ * Runs get table for join.
602
+ * @param {...string} path - Join path segments.
603
+ * @returns {string} - Quoted table name for join path.
604
+ */
605
+ getTableForJoin(...path) {
606
+ return this.driver.quoteTable(this.getTableReferenceForJoin(...path))
607
+ }
608
+
609
+ /**
610
+ * Runs scope.
611
+ * @param {import("../../utils/model-scope.js").ModelScopeDescriptor | string | string[]} pathOrScopeDescriptor - Scope descriptor or join path.
612
+ * @param {import("../../utils/model-scope.js").ModelScopeDescriptor} [maybeScopeDescriptor] - Scope descriptor when path is given.
613
+ * @returns {this} - Scoped query.
614
+ */
615
+ scope(pathOrScopeDescriptor, maybeScopeDescriptor) {
616
+ if (isModelScopeDescriptor(pathOrScopeDescriptor) && !maybeScopeDescriptor) {
617
+ return this._applyRootScope(pathOrScopeDescriptor)
618
+ }
619
+
620
+ if (!maybeScopeDescriptor) {
621
+ throw new Error("scope(path, descriptor) requires a scope descriptor")
622
+ }
623
+
624
+ return this._applyJoinPathScope({
625
+ joinPath: normalizeScopePath(/**
626
+ * Narrows the runtime value to the documented type.
627
+ @type {string | string[]} */ (pathOrScopeDescriptor)),
628
+ scopeDescriptor: maybeScopeDescriptor
629
+ })
630
+ }
631
+
632
+ /**
633
+ * Runs apply root scope.
634
+ * @param {import("../../utils/model-scope.js").ModelScopeDescriptor} scopeDescriptor - Scope descriptor.
635
+ * @returns {this} - Scoped query.
636
+ */
637
+ _applyRootScope(scopeDescriptor) {
638
+ if (!isModelScopeDescriptor(scopeDescriptor)) {
639
+ throw new Error("scope() expects a descriptor returned by defineScope(...).scope(...)")
640
+ }
641
+
642
+ if (scopeDescriptor.modelClass !== this.getModelClass()) {
643
+ throw new Error(`Cannot apply ${scopeDescriptor.modelClass.name} scope to ${this.getModelClass().name} query`)
644
+ }
645
+
646
+ const scopedQuery = /**
647
+ * Narrows the runtime value to the documented type.
648
+ @type {this | void} */ (scopeDescriptor.callback({
649
+ driver: this.driver,
650
+ modelClass: this.getModelClass(),
651
+ query: this,
652
+ table: this.rootTableReference()
653
+ }, ...scopeDescriptor.scopeArgs))
654
+
655
+ return scopedQuery || this
656
+ }
657
+
658
+ /**
659
+ * Runs apply join path scope.
660
+ * @param {object} args - Join-path scope options.
661
+ * @param {string[]} args.joinPath - Join path relative to the current query.
662
+ * @param {import("../../utils/model-scope.js").ModelScopeDescriptor} args.scopeDescriptor - Scope descriptor.
663
+ * @returns {this} - Scoped query.
664
+ */
665
+ _applyJoinPathScope({joinPath, scopeDescriptor}) {
666
+ if (!isModelScopeDescriptor(scopeDescriptor)) {
667
+ throw new Error("scope() expects a descriptor returned by defineScope(...).scope(...)")
668
+ }
669
+
670
+ const fullJoinPath = this.getJoinBasePath().concat(joinPath)
671
+ const targetModelClass = this._resolveModelClassForJoinPath(fullJoinPath)
672
+
673
+ if (scopeDescriptor.modelClass !== targetModelClass) {
674
+ throw new Error(`Cannot apply ${scopeDescriptor.modelClass.name} scope to join path ${fullJoinPath.join(".")} (${targetModelClass.name})`)
675
+ }
676
+
677
+ const scopedQuery = this.buildJoinScopeQuery(targetModelClass, fullJoinPath)
678
+ const originalJoinCount = scopedQuery._joins.length
679
+ const originalWhereCount = scopedQuery._wheres.length
680
+ const appliedQuery = /**
681
+ * Narrows the runtime value to the documented type.
682
+ @type {typeof scopedQuery | void} */ (scopeDescriptor.callback({
683
+ driver: scopedQuery.driver,
684
+ modelClass: targetModelClass,
685
+ path: [...fullJoinPath],
686
+ query: scopedQuery,
687
+ table: scopedQuery.getTableReferenceForJoin()
688
+ }, ...scopeDescriptor.scopeArgs)) || scopedQuery
689
+
690
+ if (appliedQuery.getFroms().length !== scopedQuery.getFroms().length ||
691
+ appliedQuery.getGroups().length !== scopedQuery.getGroups().length ||
692
+ appliedQuery.getSelects().length !== scopedQuery.getSelects().length ||
693
+ appliedQuery._orders.length !== scopedQuery._orders.length ||
694
+ appliedQuery._limit !== scopedQuery._limit ||
695
+ appliedQuery._offset !== scopedQuery._offset ||
696
+ appliedQuery._page !== scopedQuery._page ||
697
+ appliedQuery._perPage !== scopedQuery._perPage ||
698
+ appliedQuery._distinct !== scopedQuery._distinct ||
699
+ Object.keys(appliedQuery._preload).length !== Object.keys(scopedQuery._preload).length) {
700
+ throw new Error("Joined-path scopes may only add where(...) and joins(...) clauses")
701
+ }
702
+
703
+ if (appliedQuery._joins.length > originalJoinCount) {
704
+ for (const join of appliedQuery._joins.slice(originalJoinCount)) {
705
+ if (join instanceof JoinObject) {
706
+ this._joins.push(new JoinObject(join.object, fullJoinPath))
707
+ } else if (join instanceof JoinPlain) {
708
+ this._joins.push(join)
709
+ } else {
710
+ this._joins.push(join)
711
+ }
712
+ }
713
+ }
714
+
715
+ if (appliedQuery._wheres.length > originalWhereCount) {
716
+ this._wheres.push(...appliedQuery._wheres.slice(originalWhereCount))
717
+ }
718
+
719
+ return this
720
+ }
721
+
722
+ /**
723
+ * Runs build join scope query.
724
+ * @param {typeof import("../record/index.js").default} targetModelClass - Target model class.
725
+ * @param {string[]} joinPath - Join path.
726
+ * @returns {VelociousDatabaseQueryModelClassQuery<MC>} - The scoped join query.
727
+ */
728
+ buildJoinScopeQuery(targetModelClass, joinPath) {
729
+ const scopedQuery = /**
730
+ * Narrows the runtime value to the documented type.
731
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (targetModelClass._newQuery())
732
+
733
+ scopedQuery._joinTracker = this._joinTracker
734
+ scopedQuery._joinBasePath = joinPath
735
+ scopedQuery._forceQualifyBaseTable = true
736
+
737
+ return scopedQuery
738
+ }
739
+
740
+ /**
741
+ * Runs destroy all.
742
+ * @returns {Promise<void>} - Resolves when complete.
743
+ */
744
+ async destroyAll() {
745
+ const records = await this.toArray()
746
+
747
+ for (const record of records) {
748
+ await record.destroy()
749
+ }
750
+ }
751
+
752
+ /**
753
+ * Executes a bulk UPDATE on all rows matching the query's WHERE
754
+ * clause. Bypasses model lifecycle callbacks — use this for
755
+ * efficient batch updates where per-row hooks aren't needed.
756
+ * @param {Record<string, ?>} data - camelCase attribute names → values.
757
+ * @returns {Promise<void>} - Resolves when the update completes.
758
+ */
759
+ async updateAll(data) {
760
+ const driver = this.driver
761
+ const tableName = this.getModelClass().tableName()
762
+ const entries = Object.entries(data)
763
+
764
+ if (entries.length === 0) return
765
+
766
+ const setCols = entries.map(([key, value]) => {
767
+ const columnName = inflection.underscore(key)
768
+ const quoted = value === null ? "NULL" : driver.quote(value)
769
+
770
+ return `${driver.quoteColumn(columnName)} = ${quoted}`
771
+ }).join(", ")
772
+
773
+ const joinsSql = new JoinsParser({pretty: false, query: this}).toSql()
774
+ const whereSql = new WhereParser({pretty: false, query: this}).toSql()
775
+ let sql
776
+
777
+ if (joinsSql.length > 0) {
778
+ // Use a subquery for cross-driver compatibility (SQLite
779
+ // doesn't support UPDATE ... JOIN).
780
+ const pk = driver.quoteColumn(this.getModelClass().primaryKey())
781
+ const qt = driver.quoteTable(tableName)
782
+
783
+ sql = `UPDATE ${qt} SET ${setCols} WHERE ${pk} IN (SELECT ${qt}.${pk} FROM ${qt}${joinsSql}${whereSql})`
784
+ } else {
785
+ sql = `UPDATE ${driver.quoteTable(tableName)} SET ${setCols}${whereSql}`
786
+ }
787
+
788
+ await driver.query(sql, {logName: this.queryLogName("Update All")})
789
+ }
790
+
791
+ /**
792
+ * Runs find.
793
+ * @param {number|string} recordId - Record id.
794
+ * @returns {Promise<InstanceType<MC>>} - Resolves with the find.
795
+ */
796
+ async find(recordId) {
797
+ /**
798
+ * Conditions.
799
+ @type {{[key: string]: number | string}} */
800
+ const conditions = {}
801
+
802
+ conditions[this.getModelClass().primaryKey()] = recordId
803
+
804
+ const newQuery = /**
805
+ * Narrows the runtime value to the documented type.
806
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (this.clone())
807
+
808
+ newQuery.where(conditions)
809
+
810
+ const record = (await newQuery.first())
811
+
812
+ if (!record) {
813
+ throw new RecordNotFoundError(`Couldn't find ${this.getModelClass().name} with '${this.getModelClass().primaryKey()}'=${recordId}`)
814
+ }
815
+
816
+ return record
817
+ }
818
+
819
+ /**
820
+ * Runs find by.
821
+ * @param {{[key: string]: string | number}} conditions - Conditions hash keyed by attribute name.
822
+ * @returns {Promise<InstanceType<MC> | null>} - Resolves with the by.
823
+ */
824
+ async findBy(conditions) {
825
+ const newQuery = /**
826
+ * Narrows the runtime value to the documented type.
827
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (this.clone())
828
+
829
+ newQuery.where(conditions)
830
+
831
+ return await newQuery.first()
832
+ }
833
+
834
+ /**
835
+ * Runs find or create by.
836
+ * @param {{[key: string]: string | number}} conditions - Conditions hash keyed by attribute name.
837
+ * @param {function(InstanceType<MC>) : void} [callback] - Callback function.
838
+ * @returns {Promise<InstanceType<MC>>} - Resolves with the or create by.
839
+ */
840
+ async findOrCreateBy(conditions, callback) {
841
+ const record = await this.findOrInitializeBy(conditions, callback)
842
+
843
+ if (record.isNewRecord()) {
844
+ await record.save()
845
+ }
846
+
847
+ return record
848
+ }
849
+
850
+ /**
851
+ * Runs find by or fail.
852
+ * @param {{[key: string]: string | number}} conditions - Conditions hash keyed by attribute name.
853
+ * @returns {Promise<InstanceType<MC>>} - Resolves with the by or fail.
854
+ */
855
+ async findByOrFail(conditions) {
856
+ const record = await this.findBy(conditions)
857
+
858
+ if (!record) {
859
+ throw new Error("Record not found")
860
+ }
861
+
862
+ return record
863
+ }
864
+
865
+ /**
866
+ * Runs find or initialize by.
867
+ * @param {Record<string, ?>} conditions - Conditions.
868
+ * @param {function(InstanceType<MC>) : void} [callback] - Callback function.
869
+ * @returns {Promise<InstanceType<MC>>} - Resolves with the or initialize by.
870
+ */
871
+ async findOrInitializeBy(conditions, callback) {
872
+ const record = await this.findBy(conditions)
873
+
874
+ if (record) return record
875
+
876
+ const ModelClass = this.getModelClass()
877
+ const newRecord = /**
878
+ * Narrows the runtime value to the documented type.
879
+ @type {InstanceType<MC>} */ (new ModelClass(conditions))
880
+
881
+ if (callback) {
882
+ callback(newRecord)
883
+ }
884
+
885
+ return newRecord
886
+ }
887
+
888
+ /**
889
+ * Runs first.
890
+ * @returns {Promise<InstanceType<MC> | null>} - Resolves with the first.
891
+ */
892
+ async first() {
893
+ const newQuery = this.clone().limit(1).reorder(`${this.driver.quoteTable(this.getModelClass().tableName())}.${this.driver.quoteColumn(this.getModelClass().orderableColumn())}`)
894
+ const results = await newQuery.toArray()
895
+
896
+ return results[0] || null
897
+ }
898
+
899
+ /**
900
+ * Runs last.
901
+ * @returns {Promise<InstanceType<MC> | null>} - Resolves with the last.
902
+ */
903
+ async last() {
904
+ const primaryKey = this.getModelClass().primaryKey()
905
+ const tableName = this.getModelClass().tableName()
906
+ const results = await this.clone().reorder(`${this.driver.quoteTable(tableName)}.${this.driver.quoteColumn(primaryKey)} DESC`).limit(1).toArray()
907
+
908
+ return results[0] || null
909
+ }
910
+
911
+ /**
912
+ * Runs preload.
913
+ * @param {import("./index.js").NestedPreloadRecord | string | Array<string | import("./index.js").NestedPreloadRecord>} data - Data payload.
914
+ * @returns {this} - The preload.
915
+ */
916
+ preload(data) {
917
+ const normalizedPreload = normalizePreloadRecord(data)
918
+ incorporate(this._preload, normalizedPreload)
919
+ return this
920
+ }
921
+
922
+ /**
923
+ * Loads query results into model instances.
924
+ * @returns {Promise<Array<InstanceType<MC>>>} - Resolves with the array.
925
+ */
926
+ async load() {
927
+ const models = []
928
+ const results = await this.results()
929
+
930
+ for (const result of results) {
931
+ const ModelClass = this.getModelClass()
932
+ const model = /**
933
+ * Narrows the runtime value to the documented type.
934
+ @type {InstanceType<MC>} */ (new ModelClass())
935
+
936
+ model.loadExistingRecord(result)
937
+ models.push(model)
938
+ }
939
+
940
+ // Share a single cohort reference across every sibling record so that
941
+ // auto-preload can batch lazy relationship access later.
942
+ for (const model of models) {
943
+ model._loadCohort = models
944
+ }
945
+
946
+ if (Object.keys(this._preload).length > 0 && models.length > 0) {
947
+ const preloader = new Preloader({
948
+ modelClass: this.modelClass,
949
+ models,
950
+ preload: this._preload,
951
+ preloadSelects: this._preloadSelects,
952
+ preloadSelectsExtra: this._preloadSelectsExtra
953
+ })
954
+
955
+ await preloader.run()
956
+ }
957
+
958
+ if (this._withCount.length > 0 && models.length > 0) {
959
+ await runWithCount({
960
+ entries: this._withCount,
961
+ modelClass: this.modelClass,
962
+ models
963
+ })
964
+ }
965
+
966
+ if (this._queryData.length > 0 && models.length > 0) {
967
+ await runQueryData({
968
+ entries: this._queryData,
969
+ rootModelClass: this.modelClass,
970
+ rootModels: models
971
+ })
972
+ }
973
+
974
+ return models
975
+ }
976
+
977
+ /**
978
+ * Converts query results to array of model instances
979
+ * @returns {Promise<Array<InstanceType<MC>>>} - Resolves with the array.
980
+ */
981
+ async toArray() {
982
+ return await this.load()
983
+ }
984
+
985
+ /**
986
+ * Plucks one or more columns directly from the database without instantiating models.
987
+ * @param {...string|string[]} columns - Column names.
988
+ * @returns {Promise<Array<?>>} - Resolves with the pluck.
989
+ */
990
+ async pluck(...columns) {
991
+ const flatColumns = columns.flat()
992
+
993
+ if (flatColumns.length === 0) throw new Error("No columns given to pluck")
994
+
995
+ const modelClass = this.getModelClass()
996
+ const tableName = modelClass.tableName()
997
+ const attributeMap = modelClass.getAttributeNameToColumnNameMap()
998
+ const columnNames = flatColumns.map((column) => attributeMap[column] || column)
999
+
1000
+ const query = /**
1001
+ * Narrows the runtime value to the documented type.
1002
+ @type {VelociousDatabaseQueryModelClassQuery<MC>} */ (this.clone())
1003
+
1004
+ query._preload = {}
1005
+ query._selects = []
1006
+
1007
+ columnNames.forEach((columnName) => {
1008
+ const selectSql = `${this.driver.quoteTable(tableName)}.${this.driver.quoteColumn(columnName)}`
1009
+
1010
+ query.select(selectSql)
1011
+ })
1012
+
1013
+ const rows = await query._executeQuery({logName: query.queryLogName("Pluck")})
1014
+
1015
+ if (columnNames.length === 1) {
1016
+ const [columnName] = columnNames
1017
+ return rows.map((row) => /**
1018
+ * Narrows the runtime value to the documented type.
1019
+ @type {Record<string, ?>} */ (row)[columnName])
1020
+ }
1021
+
1022
+ return rows.map((row) => {
1023
+ const rowHash = /**
1024
+ * Narrows the runtime value to the documented type.
1025
+ @type {Record<string, ?>} */ (row)
1026
+
1027
+ return columnNames.map((columnName) => rowHash[columnName])
1028
+ })
1029
+ }
1030
+
1031
+ /**
1032
+ * Runs where.
1033
+ * @param {import("./index.js").WhereArgumentType} where - Where.
1034
+ * @returns {this} This query instance
1035
+ */
1036
+ where(where) {
1037
+ if (typeof where == "string") {
1038
+ return super.where(where)
1039
+ }
1040
+
1041
+ if (isPlainObject(where)) {
1042
+ const {resolvedHash, fallbackHash} = splitWhereHash({hash: where, modelClass: this.getModelClass()})
1043
+ const joinObject = buildJoinObjectFromWhereHash({hash: where, modelClass: this.getModelClass()})
1044
+
1045
+ if (Object.keys(joinObject).length > 0) {
1046
+ this.joins(joinObject)
1047
+ }
1048
+
1049
+ if (Object.keys(resolvedHash).length > 0) {
1050
+ const qualifyBaseTable = this.getForceQualifyBaseTable() || Object.keys(joinObject).length > 0
1051
+ this._wheres.push(new WhereModelClassHash({
1052
+ hash: resolvedHash,
1053
+ modelClass: this.getModelClass(),
1054
+ qualifyBaseTable,
1055
+ query: this
1056
+ }))
1057
+ }
1058
+
1059
+ if (Object.keys(fallbackHash).length > 0) {
1060
+ super.where(fallbackHash)
1061
+ }
1062
+
1063
+ return this
1064
+ }
1065
+
1066
+ throw new Error(`Invalid type of where: ${typeof where} (${where.constructor.name})`)
1067
+ }
1068
+
1069
+ /**
1070
+ * Runs ransack.
1071
+ * @param {Record<string, ?>} params - Ransack-style params hash. Supports `s` key for sorting (e.g., `{s: "name asc"}`).
1072
+ * @returns {this} - Query with Ransack filters and sort applied.
1073
+ */
1074
+ ransack(params) {
1075
+ const {s, ...filterParams} = params
1076
+ const group = normalizeRansackGroup(this.getModelClass(), filterParams)
1077
+
1078
+ applyRansackGroup({group, query: this})
1079
+
1080
+ if (typeof s === "string" && s.trim().length > 0) {
1081
+ const sorts = parseRansackSort(this.getModelClass(), s)
1082
+
1083
+ for (const sortDef of sorts) {
1084
+ this.order({column: sortDef.attribute, direction: sortDef.direction})
1085
+ }
1086
+ }
1087
+
1088
+ return this
1089
+ }
1090
+
1091
+ /**
1092
+ * Runs where not.
1093
+ * @param {import("./index.js").WhereArgumentType} where - Where.
1094
+ * @returns {this} This query instance
1095
+ */
1096
+ whereNot(where) {
1097
+ if (typeof where == "string") {
1098
+ return super.whereNot(where)
1099
+ }
1100
+
1101
+ if (isPlainObject(where)) {
1102
+ const {resolvedHash, fallbackHash} = splitWhereHash({hash: where, modelClass: this.getModelClass()})
1103
+ const joinObject = buildJoinObjectFromWhereHash({hash: where, modelClass: this.getModelClass()})
1104
+
1105
+ if (Object.keys(joinObject).length > 0) {
1106
+ this.joins(joinObject)
1107
+ }
1108
+
1109
+ if (Object.keys(resolvedHash).length > 0) {
1110
+ const qualifyBaseTable = this.getForceQualifyBaseTable() || Object.keys(joinObject).length > 0
1111
+ this._wheres.push(new WhereNot(new WhereModelClassHash({
1112
+ hash: resolvedHash,
1113
+ modelClass: this.getModelClass(),
1114
+ qualifyBaseTable,
1115
+ query: this
1116
+ })))
1117
+ }
1118
+
1119
+ if (Object.keys(fallbackHash).length > 0) {
1120
+ super.whereNot(fallbackHash)
1121
+ }
1122
+
1123
+ return this
1124
+ }
1125
+
1126
+ throw new Error(`Invalid type of where: ${typeof where} (${where.constructor.name})`)
1127
+ }
1128
+
1129
+ /**
1130
+ * Runs query log name.
1131
+ * @param {string} operation - Query operation.
1132
+ * @returns {string} - Query log name.
1133
+ */
1134
+ queryLogName(operation) {
1135
+ return `${this.getModelClass().name} ${operation}`
1136
+ }
1137
+ }
1138
+
1139
+ /**
1140
+ * Runs apply ransack group.
1141
+ * @param {object} args - Options.
1142
+ * @param {import("../../utils/ransack.js").RansackGroup} args.group - Normalized Ransack group.
1143
+ * @param {import("./model-class-query.js").default<?>} args.query - Query instance.
1144
+ * @returns {void}
1145
+ */
1146
+ function applyRansackGroup({group, query}) {
1147
+ const where = buildRansackGroupWhere({group, query})
1148
+
1149
+ if (where) {
1150
+ query._wheres.push(where)
1151
+ }
1152
+ }
1153
+
1154
+ /**
1155
+ * Runs build ransack group where.
1156
+ * @param {object} args - Options.
1157
+ * @param {import("../../utils/ransack.js").RansackGroup} args.group - Normalized Ransack group.
1158
+ * @param {import("./model-class-query.js").default<?>} args.query - Query instance.
1159
+ * @returns {import("./where-base.js").default | null} - Combined where clause.
1160
+ */
1161
+ function buildRansackGroupWhere({group, query}) {
1162
+ /**
1163
+ * Wheres.
1164
+ @type {import("./where-base.js").default[]} */
1165
+ const wheres = []
1166
+
1167
+ for (const condition of group.conditions) {
1168
+ const where = buildRansackConditionWhere({condition, query})
1169
+
1170
+ if (where) wheres.push(where)
1171
+ }
1172
+
1173
+ for (const grouping of group.groupings) {
1174
+ const where = buildRansackGroupWhere({group: grouping, query})
1175
+
1176
+ if (where) wheres.push(where)
1177
+ }
1178
+
1179
+ if (wheres.length < 1) return null
1180
+ if (wheres.length === 1) return wheres[0]
1181
+
1182
+ return new WhereCombinator({
1183
+ combinator: group.combinator,
1184
+ query,
1185
+ wheres
1186
+ })
1187
+ }
1188
+
1189
+ /**
1190
+ * Runs build ransack condition where.
1191
+ * @param {object} args - Options.
1192
+ * @param {import("../../utils/ransack.js").RansackCondition} args.condition - Normalized Ransack condition.
1193
+ * @param {import("./model-class-query.js").default<?>} args.query - Query instance.
1194
+ * @returns {import("./where-base.js").default | null} - Condition where clause.
1195
+ */
1196
+ function buildRansackConditionWhere({condition, query}) {
1197
+ /**
1198
+ * Wheres.
1199
+ @type {import("./where-base.js").default[]} */
1200
+ const wheres = []
1201
+
1202
+ for (const attribute of condition.attributes) {
1203
+ wheres.push(buildRansackAttributeWhere({attribute, condition, query}))
1204
+ }
1205
+
1206
+ if (wheres.length < 1) return null
1207
+ if (wheres.length === 1) return wheres[0]
1208
+
1209
+ return new WhereCombinator({
1210
+ combinator: condition.combinator,
1211
+ query,
1212
+ wheres
1213
+ })
1214
+ }
1215
+
1216
+ /**
1217
+ * Runs build ransack attribute where.
1218
+ * @param {object} args - Options.
1219
+ * @param {import("../../utils/ransack.js").RansackAttribute} args.attribute - Normalized Ransack attribute.
1220
+ * @param {import("../../utils/ransack.js").RansackCondition} args.condition - Normalized Ransack condition.
1221
+ * @param {import("./model-class-query.js").default<?>} args.query - Query instance.
1222
+ * @returns {import("./where-base.js").default} - Attribute where clause.
1223
+ */
1224
+ function buildRansackAttributeWhere({attribute, condition, query}) {
1225
+ const hash = buildRansackAttributeHash({attribute, condition})
1226
+ const joinObject = buildJoinObjectFromWhereHash({hash, modelClass: query.getModelClass()})
1227
+
1228
+ if (Object.keys(joinObject).length > 0) {
1229
+ query.joins(joinObject)
1230
+ }
1231
+
1232
+ const where = new WhereModelClassHash({
1233
+ hash,
1234
+ modelClass: query.getModelClass(),
1235
+ qualifyBaseTable: true,
1236
+ query
1237
+ })
1238
+
1239
+ if (condition.predicate === "not_eq" || condition.predicate === "not_in") {
1240
+ return new WhereNot(where)
1241
+ }
1242
+
1243
+ if (condition.predicate === "null" && !condition.value) {
1244
+ return new WhereNot(where)
1245
+ }
1246
+
1247
+ return where
1248
+ }
1249
+
1250
+ /**
1251
+ * Runs build ransack attribute hash.
1252
+ * @param {object} args - Options.
1253
+ * @param {import("../../utils/ransack.js").RansackAttribute} args.attribute - Normalized Ransack attribute.
1254
+ * @param {import("../../utils/ransack.js").RansackCondition} args.condition - Normalized Ransack condition.
1255
+ * @returns {Record<string, ?>} - Nested hash suitable for query where nodes.
1256
+ */
1257
+ function buildRansackAttributeHash({attribute, condition}) {
1258
+ if (condition.predicate === "eq" || condition.predicate === "in" || condition.predicate === "not_eq" || condition.predicate === "not_in") {
1259
+ return buildNestedRansackHash({attribute, value: condition.value})
1260
+ }
1261
+
1262
+ if (condition.predicate === "null") {
1263
+ return buildNestedRansackHash({attribute, value: null})
1264
+ }
1265
+
1266
+ return buildNestedRansackTupleHash({
1267
+ attribute,
1268
+ operator: ransackTupleOperator(condition.predicate),
1269
+ value: ransackTupleValue(condition)
1270
+ })
1271
+ }
1272
+
1273
+ /**
1274
+ * Runs build nested ransack hash.
1275
+ * @param {object} args - Options.
1276
+ * @param {import("../../utils/ransack.js").RansackAttribute} args.attribute - Normalized Ransack attribute.
1277
+ * @param {?} args.value - Final value.
1278
+ * @returns {Record<string, ?>} - Nested hash suitable for query where nodes.
1279
+ */
1280
+ function buildNestedRansackHash({attribute, value}) {
1281
+ /**
1282
+ * Hash.
1283
+ @type {Record<string, ?>} */
1284
+ let hash = {[attribute.attributeName]: value}
1285
+
1286
+ for (let index = attribute.path.length - 1; index >= 0; index -= 1) {
1287
+ hash = {[attribute.path[index]]: hash}
1288
+ }
1289
+
1290
+ return hash
1291
+ }
1292
+
1293
+ /**
1294
+ * Runs build nested ransack tuple hash.
1295
+ * @param {object} args - Options.
1296
+ * @param {import("../../utils/ransack.js").RansackAttribute} args.attribute - Normalized Ransack attribute.
1297
+ * @param {"gt" | "gteq" | "lt" | "lteq" | "like"} args.operator - Tuple operator.
1298
+ * @param {?} args.value - Final value.
1299
+ * @returns {Record<string, ?>} - Nested tuple hash suitable for query.where.
1300
+ */
1301
+ function buildNestedRansackTupleHash({attribute, operator, value}) {
1302
+ /**
1303
+ * Hash.
1304
+ @type {Record<string, ?>} */
1305
+ let hash = {
1306
+ [attribute.attributeName]: [[attribute.attributeName, operator, value]]
1307
+ }
1308
+
1309
+ for (let index = attribute.path.length - 1; index >= 0; index -= 1) {
1310
+ hash = {[attribute.path[index]]: hash}
1311
+ }
1312
+
1313
+ return hash
1314
+ }
1315
+
1316
+ /**
1317
+ * Runs ransack tuple operator.
1318
+ * @param {import("../../utils/ransack.js").RansackPredicate} predicate - Ransack predicate.
1319
+ * @returns {"gt" | "gteq" | "lt" | "lteq" | "like"} - Query tuple operator.
1320
+ */
1321
+ function ransackTupleOperator(predicate) {
1322
+ if (predicate === "gt" || predicate === "gteq" || predicate === "lt" || predicate === "lteq") {
1323
+ return predicate
1324
+ }
1325
+
1326
+ return "like"
1327
+ }
1328
+
1329
+ /**
1330
+ * Runs ransack tuple value.
1331
+ * @param {import("../../utils/ransack.js").RansackCondition} condition - Ransack condition.
1332
+ * @returns {?} - Query tuple value.
1333
+ */
1334
+ function ransackTupleValue(condition) {
1335
+ if (condition.predicate === "cont") return `%${condition.value}%`
1336
+ if (condition.predicate === "start") return `${condition.value}%`
1337
+ if (condition.predicate === "end") return `%${condition.value}`
1338
+
1339
+ return condition.value
1340
+ }
1341
+
1342
+ /**
1343
+ * Runs get relationship by name.
1344
+ * @param {typeof import("../record/index.js").default} modelClass - Model class.
1345
+ * @param {string} relationshipName - Relationship name.
1346
+ * @returns {import("../record/relationships/base.js").default | undefined} - The relationship.
1347
+ */
1348
+ function getRelationshipByName(modelClass, relationshipName) {
1349
+ return modelClass.getRelationshipsMap()[relationshipName]
1350
+ }
1351
+
1352
+ /**
1353
+ * Runs resolve column name.
1354
+ * @param {typeof import("../record/index.js").default} modelClass - Model class.
1355
+ * @param {string} key - Attribute or column name.
1356
+ * @returns {string | undefined} - The resolved column name.
1357
+ */
1358
+ function resolveColumnName(modelClass, key) {
1359
+ const attributeMap = modelClass.getAttributeNameToColumnNameMap()
1360
+
1361
+ if (attributeMap[key]) return attributeMap[key]
1362
+
1363
+ const columnMap = modelClass.getColumnNameToAttributeNameMap()
1364
+ const underscored = inflection.underscore(key)
1365
+
1366
+ return columnMap[key] || columnMap[underscored] || undefined
1367
+ }
1368
+
1369
+ /**
1370
+ * Runs split where hash.
1371
+ * @param {object} args - Options.
1372
+ * @param {Record<string, ?>} args.hash - Where hash.
1373
+ * @param {typeof import("../record/index.js").default} args.modelClass - Model class.
1374
+ * @returns {{resolvedHash: Record<string, ?>, fallbackHash: Record<string, ?>}} - Split hashes.
1375
+ */
1376
+ function splitWhereHash({hash, modelClass}) {
1377
+ /**
1378
+ * Resolved hash.
1379
+ @type {Record<string, ?>} */
1380
+ const resolvedHash = {}
1381
+ /**
1382
+ * Fallback hash.
1383
+ @type {Record<string, ?>} */
1384
+ const fallbackHash = {}
1385
+
1386
+ for (const key in hash) {
1387
+ const value = hash[key]
1388
+ const isNested = isPlainObject(value)
1389
+ const relationship = getRelationshipByName(modelClass, key)
1390
+
1391
+ if (isNested) {
1392
+ if (relationship) {
1393
+ const targetModelClass = relationship.getTargetModelClass()
1394
+ if (!targetModelClass) {
1395
+ fallbackHash[key] = value
1396
+ continue
1397
+ }
1398
+ const nestedResult = splitWhereHash({hash: value, modelClass: targetModelClass})
1399
+ const nestedResolvedKeys = Object.keys(nestedResult.resolvedHash)
1400
+ const nestedFallbackKeys = Object.keys(nestedResult.fallbackHash)
1401
+
1402
+ if (nestedResolvedKeys.length > 0) {
1403
+ resolvedHash[key] = nestedResult.resolvedHash
1404
+ }
1405
+
1406
+ if (nestedFallbackKeys.length > 0) {
1407
+ const tableName = targetModelClass.tableName()
1408
+
1409
+ if (!fallbackHash[tableName]) fallbackHash[tableName] = {}
1410
+ Object.assign(fallbackHash[tableName], nestedResult.fallbackHash)
1411
+ }
1412
+ } else {
1413
+ fallbackHash[key] = value
1414
+ }
1415
+ } else if (relationship && hasRelationshipWhereOperatorTuples(value)) {
1416
+ resolvedHash[key] = normalizeRelationshipWhereOperatorTuples(value)
1417
+ } else {
1418
+ const columnName = resolveColumnName(modelClass, key)
1419
+
1420
+ if (columnName) {
1421
+ resolvedHash[columnName] = value
1422
+ } else {
1423
+ fallbackHash[key] = value
1424
+ }
1425
+ }
1426
+ }
1427
+
1428
+ return {resolvedHash, fallbackHash}
1429
+ }
1430
+
1431
+ /**
1432
+ * Runs build join object from where hash.
1433
+ * @param {object} args - Options.
1434
+ * @param {Record<string, ?>} args.hash - Where hash.
1435
+ * @param {typeof import("../record/index.js").default} args.modelClass - Model class.
1436
+ * @returns {Record<string, ?>} - Join object.
1437
+ */
1438
+ function buildJoinObjectFromWhereHash({hash, modelClass}) {
1439
+ /**
1440
+ * Join object.
1441
+ @type {Record<string, ?>} */
1442
+ const joinObject = {}
1443
+
1444
+ for (const key in hash) {
1445
+ const value = hash[key]
1446
+ const relationship = getRelationshipByName(modelClass, key)
1447
+
1448
+ if (!relationship) continue
1449
+
1450
+ if (isPlainObject(value)) {
1451
+ const targetModelClass = relationship.getTargetModelClass()
1452
+ if (!targetModelClass) continue
1453
+ const nestedJoinObject = buildJoinObjectFromWhereHash({hash: value, modelClass: targetModelClass})
1454
+
1455
+ joinObject[key] = Object.keys(nestedJoinObject).length > 0 ? nestedJoinObject : true
1456
+ continue
1457
+ }
1458
+
1459
+ if (hasRelationshipWhereOperatorTuples(value)) {
1460
+ joinObject[key] = true
1461
+ }
1462
+ }
1463
+
1464
+ return joinObject
1465
+ }
1466
+
1467
+ const relationshipWhereOperators = new Set(["eq", "notEq", "gt", "gteq", "lt", "lteq", "like", ">", ">=", "<", "<="])
1468
+
1469
+ /**
1470
+ * Runs normalize relationship where operator.
1471
+ * @param {string} operator - Raw relationship where operator.
1472
+ * @returns {"eq" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | "like"} - Normalized operator.
1473
+ */
1474
+ function normalizeRelationshipWhereOperator(operator) {
1475
+ const operatorAliases = {
1476
+ "<": "lt",
1477
+ "<=": "lteq",
1478
+ ">": "gt",
1479
+ ">=": "gteq"
1480
+ }
1481
+
1482
+ return /** Narrows the runtime value to the documented type. @type {"eq" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | "like"} */ (
1483
+ operatorAliases[/**
1484
+ * Narrows the runtime value to the documented type.
1485
+ @type {"<" | "<=" | ">" | ">="} */ (operator)] || operator
1486
+ )
1487
+ }
1488
+
1489
+ /**
1490
+ * Runs is relationship where operator tuple.
1491
+ * @param {?} tupleValue - Candidate tuple.
1492
+ * @returns {boolean} - Whether this is a relationship where tuple.
1493
+ */
1494
+ function isRelationshipWhereOperatorTuple(tupleValue) {
1495
+ if (!Array.isArray(tupleValue) || tupleValue.length < 3) {
1496
+ return false
1497
+ }
1498
+
1499
+ return typeof tupleValue[0] === "string" &&
1500
+ typeof tupleValue[1] === "string" &&
1501
+ relationshipWhereOperators.has(tupleValue[1])
1502
+ }
1503
+
1504
+ /**
1505
+ * Runs normalize relationship where operator tuples.
1506
+ * @param {?} value - Candidate value.
1507
+ * @returns {Array<[string, "eq" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | "like", unknown]>} - Normalized tuples.
1508
+ */
1509
+ function normalizeRelationshipWhereOperatorTuples(value) {
1510
+ if (!Array.isArray(value)) {
1511
+ throw new Error(`Invalid relationship where tuple container type: ${typeof value}`)
1512
+ }
1513
+
1514
+ /**
1515
+ * Normalized.
1516
+ @type {Array<[string, "eq" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | "like", unknown]>} */
1517
+ const normalized = []
1518
+ /**
1519
+ * Add condition.
1520
+ * @param {?} conditionValue - Candidate nested condition.
1521
+ */
1522
+ const addCondition = (conditionValue) => {
1523
+ if (isRelationshipWhereOperatorTuple(conditionValue)) {
1524
+ const tuple = /**
1525
+ * Narrows the runtime value to the documented type.
1526
+ @type {[string, "eq" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | "like" | ">" | ">=" | "<" | "<=", unknown, ...Array<unknown>]} */ (conditionValue)
1527
+ const normalizedOperator = normalizeRelationshipWhereOperator(tuple[1])
1528
+
1529
+ normalized.push([
1530
+ tuple[0],
1531
+ normalizedOperator,
1532
+ tuple[2]
1533
+ ])
1534
+
1535
+ if (tuple.length > 3) {
1536
+ for (let index = 3; index < tuple.length; index += 1) {
1537
+ addCondition(tuple[index])
1538
+ }
1539
+ }
1540
+
1541
+ return
1542
+ }
1543
+
1544
+ if (!Array.isArray(conditionValue)) {
1545
+ throw new Error("Relationship where conditions must be tuples")
1546
+ }
1547
+
1548
+ /**
1549
+ * Narrows the runtime value to the documented type.
1550
+ @type {Array<?>} */ (conditionValue).forEach((nestedConditionValue) => {
1551
+ addCondition(nestedConditionValue)
1552
+ })
1553
+ }
1554
+
1555
+ addCondition(value)
1556
+
1557
+ if (normalized.length < 1) {
1558
+ throw new Error("Relationship where tuple container cannot be empty")
1559
+ }
1560
+
1561
+ return normalized
1562
+ }
1563
+
1564
+ /**
1565
+ * Runs has relationship where operator tuples.
1566
+ * @param {?} value - Candidate relationship where value.
1567
+ * @returns {boolean} - Whether value can be normalized to relationship tuples.
1568
+ */
1569
+ function hasRelationshipWhereOperatorTuples(value) {
1570
+ try {
1571
+ normalizeRelationshipWhereOperatorTuples(value)
1572
+
1573
+ return true
1574
+ } catch {
1575
+ return false
1576
+ }
1577
+ }