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,1609 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * CreateIndexSqlArgs type.
5
+ * @typedef {object} CreateIndexSqlArgs
6
+ * @property {Array<string | import("./../table-data/table-column.js").default>} columns - Columns to include in the index.
7
+ * @property {boolean} [ifNotExists] - Skip creation if the index already exists.
8
+ * @property {string} [name] - Explicit index name to use.
9
+ * @property {boolean} [unique] - Whether the index should enforce uniqueness.
10
+ * @property {string} tableName - Name of the table to add the index to.
11
+ */
12
+ /**
13
+ * DropTableSqlArgsType type.
14
+ * @typedef {object} DropTableSqlArgsType
15
+ * @property {boolean} [cascade] - Whether dependent objects should be dropped too.
16
+ * @property {boolean} [ifExists] - Skip dropping if the table does not exist.
17
+ */
18
+ /**
19
+ * DeleteSqlArgsType type.
20
+ * @typedef {object} DeleteSqlArgsType
21
+ * @property {string} tableName - Table name to delete from.
22
+ * @property {{[key: string]: ?}} conditions - Conditions used to build the delete WHERE clause.
23
+ */
24
+ /**
25
+ * InsertSqlArgsType type.
26
+ * @typedef {object} InsertSqlArgsType
27
+ * @property {string[]} [columns] - Column names for `rows` inserts.
28
+ * @property {{[key: string]: ?}} [data] - Column/value pairs for a single-row insert.
29
+ * @property {boolean} [multiple] - Whether this insert should be treated as multi-row.
30
+ * @property {string[]} [returnLastInsertedColumnNames] - Column names to return after insert.
31
+ * @property {Array<Array<?>>} [rows] - Row values for a multi-row insert.
32
+ * @property {string} tableName - Table name to insert into.
33
+ */
34
+ /**
35
+ * QueryRowType type.
36
+ * @typedef {Record<string, ?>} QueryRowType
37
+ * @typedef {Array<QueryRowType>} QueryResultType
38
+ */
39
+ /**
40
+ * RetryableDatabaseErrorResult type.
41
+ * @typedef {object} RetryableDatabaseErrorResult
42
+ * @property {boolean} retry - Whether the error should be retried.
43
+ * @property {boolean} reconnect - Whether to reconnect before retrying.
44
+ * @property {number} [maxTries] - Override the max retry attempts.
45
+ * @property {number} [waitMs] - Wait time before retrying in milliseconds.
46
+ */
47
+ /**
48
+ * QueryOptions type.
49
+ * @typedef {object} QueryOptions
50
+ * @property {string} [logName] - Query log subject.
51
+ * @property {boolean} [logQuery] - Whether to log the query.
52
+ * @property {boolean} [processListComment] - Whether to add process-list comments to the query.
53
+ * @property {string} [sourceStack] - Stack captured at the caller boundary.
54
+ */
55
+
56
+ /**
57
+ * ActiveQueryDebugSnapshot type.
58
+ * @typedef {object} ActiveQueryDebugSnapshot
59
+ * @property {string[]} annotations - Database annotations active when the query started.
60
+ * @property {string} logName - Query log name.
61
+ * @property {number} startedAtUnixMs - Query start timestamp.
62
+ * @property {number} runningMs - Query runtime in milliseconds.
63
+ * @property {string} sqlPreview - Truncated SQL preview.
64
+ */
65
+
66
+ /**
67
+ * DatabaseConnectionDebugSnapshot type.
68
+ * @typedef {object} DatabaseConnectionDebugSnapshot
69
+ * @property {ActiveQueryDebugSnapshot | null} activeQuery - Currently running query, if any.
70
+ * @property {number | undefined} checkedOutAtUnixMs - Checkout start timestamp for active checkouts.
71
+ * @property {number | undefined} checkoutAgeMs - Active checkout age in milliseconds.
72
+ * @property {string | undefined} checkoutName - Human-readable checkout name.
73
+ * @property {string} driverClass - Driver class name.
74
+ * @property {number | undefined} idSeq - Pool checkout ID sequence.
75
+ * @property {number} openTransactions - Number of open transaction frames.
76
+ * @property {number} schemaCacheEntries - Number of cached schema metadata entries.
77
+ */
78
+
79
+ /**
80
+ * ActiveQueryState type.
81
+ * @typedef {object} ActiveQueryState
82
+ * @property {string[]} annotations - Database annotations active when the query started.
83
+ * @property {string} logName - Query log name.
84
+ * @property {number} startedAtUnixMs - Query start timestamp.
85
+ * @property {string} sqlPreview - Truncated SQL preview.
86
+ */
87
+
88
+ /**
89
+ * UpdateSqlArgsType type.
90
+ * @typedef {object}UpdateSqlArgsType
91
+ * @property {object} conditions - Conditions used to build the update WHERE clause.
92
+ * @property {object} data - Column/value pairs to update.
93
+ * @property {string} tableName - Table name to update.
94
+ */
95
+ /**
96
+ * UpsertSqlArgsType type.
97
+ * @typedef {object}UpsertSqlArgsType
98
+ * @property {string[]} conflictColumns - Columns that define a conflict.
99
+ * @property {object} data - Column/value pairs to insert.
100
+ * @property {string} tableName - Table name to upsert into.
101
+ * @property {string[]} updateColumns - Columns to update on conflict.
102
+ */
103
+
104
+ import BacktraceCleaner from "../../utils/backtrace-cleaner.js"
105
+ import { getDatabaseAnnotations } from "../annotations.js"
106
+ import Logger from "../../logger.js"
107
+ import Query from "../query/index.js"
108
+ import Handler from "../handler.js"
109
+ import Mutex from "epic-locks/build/mutex.js"
110
+ import strftime from "strftime"
111
+ import UUID from "pure-uuid"
112
+ import TableData from "../table-data/index.js"
113
+ import TableColumn from "../table-data/table-column.js"
114
+ import TableForeignKey from "../table-data/table-foreign-key.js"
115
+ import wait from "awaitery/build/wait.js"
116
+
117
+ /**
118
+ * Runs now ms.
119
+ * @returns {number} - Current high-resolution-ish timestamp in milliseconds.
120
+ */
121
+ function nowMs() {
122
+ if (globalThis.performance && typeof globalThis.performance.now == "function") {
123
+ return globalThis.performance.now()
124
+ }
125
+
126
+ return Date.now()
127
+ }
128
+
129
+ /**
130
+ * Runs format elapsed ms.
131
+ * @param {number} elapsedMs - Elapsed milliseconds.
132
+ * @returns {string} - Formatted elapsed milliseconds.
133
+ */
134
+ function formatElapsedMs(elapsedMs) {
135
+ return `${Math.max(elapsedMs, 0).toFixed(1)}ms`
136
+ }
137
+
138
+ export default class VelociousDatabaseDriversBase {
139
+ /**
140
+ * Id seq.
141
+ @type {number | undefined} */
142
+ idSeq = undefined
143
+ /**
144
+ * Narrows the runtime value to the documented type.
145
+ @type {Array<Array<() => void | Promise<void>>>} */
146
+ _afterCommitCallbackFrames
147
+ /**
148
+ * Narrows the runtime value to the documented type.
149
+ @type {Map<string, Promise<?>>} */
150
+ _schemaCache
151
+ /**
152
+ * Narrows the runtime value to the documented type.
153
+ @type {(() => void) | undefined} */
154
+ _schemaCacheInvalidator
155
+ /**
156
+ * Narrows the runtime value to the documented type.
157
+ @type {string | undefined} */
158
+ _connectionCheckoutName
159
+ /**
160
+ * Active query.
161
+ @type {ActiveQueryState | null} */
162
+ _activeQuery = null
163
+
164
+ /**
165
+ * Runs constructor.
166
+ * @param {import("../../configuration-types.js").DatabaseConfigurationType} config - Configuration object.
167
+ * @param {import("../../configuration.js").default} configuration - Configuration instance.
168
+ */
169
+ constructor(config, configuration) {
170
+ this._args = config
171
+ this.configuration = configuration
172
+ this.mutex = new Mutex() // Can be used to lock this instance for exclusive use
173
+ this.logger = new Logger(this)
174
+ this._afterCommitCallbackFrames = []
175
+ this._transactionsCount = 0
176
+ this._transactionsActionsMutex = new Mutex()
177
+ this._schemaCache = new Map()
178
+ }
179
+
180
+ /**
181
+ * Runs add foreign key.
182
+ * @param {string} tableName - Table name.
183
+ * @param {string} columnName - Column name.
184
+ * @param {string} referencedTableName - Referenced table name.
185
+ * @param {string} referencedColumnName - Referenced column name.
186
+ * @param {object} args - Options object.
187
+ * @returns {Promise<void>} - Resolves when complete.
188
+ */
189
+ async addForeignKey(tableName, columnName, referencedTableName, referencedColumnName, args) {
190
+ this._assertNotReadOnly()
191
+ const tableForeignKeyArgs = Object.assign(
192
+ {
193
+ columnName,
194
+ tableName,
195
+ referencedColumnName,
196
+ referencedTableName
197
+ },
198
+ args
199
+ )
200
+ const tableForeignKey = new TableForeignKey(tableForeignKeyArgs)
201
+ const tableData = new TableData(tableName)
202
+
203
+ tableData.addForeignKey(tableForeignKey)
204
+
205
+ const alterTableSQLs = await this.alterTableSQLs(tableData)
206
+
207
+ for (const alterTableSQL of alterTableSQLs) {
208
+ await this.query(alterTableSQL)
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Runs alter table sqls.
214
+ * @abstract
215
+ * @param {import("../table-data/index.js").default} _tableData - Table data.
216
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
217
+ */
218
+ alterTableSQLs(_tableData) {
219
+ throw new Error("alterTableSQLs not implemented")
220
+ }
221
+
222
+ /**
223
+ * Runs connect.
224
+ * @abstract
225
+ * @returns {Promise<void>} - Resolves when complete.
226
+ */
227
+ connect() {
228
+ throw new Error("'connect' not implemented")
229
+ }
230
+
231
+ /**
232
+ * Optional close hook for database drivers.
233
+ * @returns {Promise<void>} - Resolves when complete.
234
+ */
235
+ async close() {
236
+ // No-op by default
237
+ }
238
+
239
+ /**
240
+ * Runs set connection checkout name.
241
+ * @param {string | undefined} name - Human-readable name for this active checkout.
242
+ * @returns {Promise<void>} - Resolves when complete.
243
+ */
244
+ async setConnectionCheckoutName(name) {
245
+ this._connectionCheckoutName = name
246
+ this._connectionCheckedOutAtUnixMs = Date.now()
247
+ }
248
+
249
+ /**
250
+ * Runs clear connection checkout name.
251
+ * @returns {Promise<void>} - Resolves when complete.
252
+ */
253
+ async clearConnectionCheckoutName() {
254
+ this._connectionCheckoutName = undefined
255
+ this._connectionCheckedOutAtUnixMs = undefined
256
+ }
257
+
258
+ /**
259
+ * Runs reconnect.
260
+ * @returns {Promise<void>} - Resolves when complete.
261
+ */
262
+ async reconnect() {
263
+ this.clearSchemaCache()
264
+ await this.close()
265
+ await this.connect()
266
+ }
267
+
268
+ /**
269
+ * Runs create database sql.
270
+ * @abstract
271
+ * @param {string} databaseName - Database name.
272
+ * @param {object} [args] - Options object.
273
+ * @param {boolean} [args.ifNotExists] - Whether if not exists.
274
+ * @param {string} [args.databaseCharset] - Database-default character set (driver-specific; mysql/mariadb).
275
+ * @param {string} [args.databaseCollation] - Database-default collation (driver-specific; mysql/mariadb).
276
+ * @returns {string[]} - SQL statements.
277
+ */
278
+ createDatabaseSql(databaseName, args) { throw new Error("'createDatabaseSql' not implemented") } // eslint-disable-line no-unused-vars
279
+
280
+ /**
281
+ * Runs drop database sql.
282
+ * @abstract
283
+ * @param {string} databaseName - Database name.
284
+ * @param {object} [args] - Options object.
285
+ * @param {boolean} [args.ifExists] - Whether if exists.
286
+ * @returns {string[]} - SQL statements.
287
+ */
288
+ dropDatabaseSql(databaseName, args) { throw new Error("'dropDatabaseSql' not implemented") } // eslint-disable-line no-unused-vars
289
+
290
+ /**
291
+ * Runs create index sqls.
292
+ * @abstract
293
+ * @param {CreateIndexSqlArgs} indexData - Index data.
294
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
295
+ */
296
+ async createIndexSQLs(indexData) { // eslint-disable-line no-unused-vars
297
+ throw new Error("'createIndexSQLs' not implemented")
298
+ }
299
+
300
+ /**
301
+ * Runs create table.
302
+ * @param {import("../table-data/index.js").default} tableData - Table data.
303
+ * @returns {Promise<void>} - Resolves when complete.
304
+ */
305
+ async createTable(tableData) {
306
+ this._assertNotReadOnly()
307
+ const sqls = await this.createTableSql(tableData)
308
+
309
+ for (const sql of sqls) {
310
+ await this.query(sql)
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Runs create table sql.
316
+ * @abstract
317
+ * @param {import("../table-data/index.js").default} tableData - Table data.
318
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
319
+ */
320
+ async createTableSql(tableData) { // eslint-disable-line no-unused-vars
321
+ throw new Error("'createTableSql' not implemented")
322
+ }
323
+
324
+ /**
325
+ * Runs delete.
326
+ * @param {DeleteSqlArgsType} args - Options object.
327
+ * @returns {Promise<void>} - Resolves when complete.
328
+ */
329
+ async delete(args) {
330
+ this._assertNotReadOnly()
331
+ const sql = this.deleteSql(args)
332
+
333
+ await this.query(sql)
334
+ }
335
+
336
+ /**
337
+ * Runs delete sql.
338
+ * @abstract
339
+ * @param {DeleteSqlArgsType} args - Options object.
340
+ * @returns {string} - SQL string.
341
+ */
342
+ deleteSql(args) { // eslint-disable-line no-unused-vars
343
+ throw new Error(`'deleteSql' not implemented`)
344
+ }
345
+
346
+ /**
347
+ * Runs drop table.
348
+ * @param {string} tableName - Table name.
349
+ * @param {DropTableSqlArgsType} [args] - Options object.
350
+ * @returns {Promise<void>} - Resolves when complete.
351
+ */
352
+ async dropTable(tableName, args) {
353
+ this._assertNotReadOnly()
354
+ const sqls = await this.dropTableSQLs(tableName, args)
355
+
356
+ for (const sql of sqls) {
357
+ await this.query(sql)
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Runs drop table sqls.
363
+ * @abstract
364
+ * @param {string} tableName - Table name.
365
+ * @param {DropTableSqlArgsType} [args] - Options object.
366
+ * @returns {Promise<string[]>} - Resolves with SQL statements.
367
+ */
368
+ async dropTableSQLs(tableName, args) { // eslint-disable-line no-unused-vars
369
+ throw new Error("dropTableSQLs not implemented")
370
+ }
371
+
372
+ /**
373
+ * Runs escape.
374
+ * @abstract
375
+ * @param {?} value - Value to use.
376
+ * @returns {?} - The escape.
377
+ */
378
+ escape(value) { // eslint-disable-line no-unused-vars
379
+ throw new Error("'escape' not implemented")
380
+ }
381
+
382
+ /**
383
+ * Runs get args.
384
+ * @returns {import("../../configuration-types.js").DatabaseConfigurationType} - The args.
385
+ */
386
+ getArgs() {
387
+ return this._args
388
+ }
389
+
390
+ /**
391
+ * Runs get configuration.
392
+ * @returns {import("../../configuration.js").default} - The configuration.
393
+ */
394
+ getConfiguration() {
395
+ if (!this.configuration) throw new Error("No configuration set")
396
+
397
+ return this.configuration
398
+ }
399
+
400
+ /**
401
+ * Runs get id seq.
402
+ * @returns {number | undefined} - The id seq.
403
+ */
404
+ getIdSeq() {
405
+ return this.idSeq
406
+ }
407
+
408
+ /**
409
+ * Clears cached schema metadata for this driver instance.
410
+ * @returns {void} - No return value.
411
+ */
412
+ clearSchemaCache() {
413
+ if (this._schemaCacheInvalidator) {
414
+ this._schemaCacheInvalidator()
415
+ return
416
+ }
417
+
418
+ this._clearLocalSchemaCache()
419
+ }
420
+
421
+ /**
422
+ * Clears only the metadata cached on this driver instance.
423
+ * @returns {void} - No return value.
424
+ */
425
+ _clearLocalSchemaCache() {
426
+ this._schemaCache.clear()
427
+ }
428
+
429
+ /**
430
+ * Runs set schema cache invalidator.
431
+ * @param {() => void} invalidator - Callback used to clear schema caches that share this driver pool.
432
+ * @returns {void} - No return value.
433
+ */
434
+ setSchemaCacheInvalidator(invalidator) {
435
+ this._schemaCacheInvalidator = invalidator
436
+ }
437
+
438
+ /**
439
+ * Runs schema cache enabled.
440
+ * @returns {boolean} - Whether schema metadata caching is enabled.
441
+ */
442
+ _schemaCacheEnabled() {
443
+ return this.getArgs().schemaCache !== false
444
+ }
445
+
446
+ /**
447
+ * Runs cached schema metadata.
448
+ * @template T
449
+ * @param {string} cacheKey - Schema cache key.
450
+ * @param {() => Promise<T>} callback - Cache miss callback.
451
+ * @returns {Promise<T>} - Resolves with the cached metadata.
452
+ */
453
+ async _cachedSchemaMetadata(cacheKey, callback) {
454
+ if (!this._schemaCacheEnabled()) return await callback()
455
+
456
+ const existingPromise = this._schemaCache.get(cacheKey)
457
+
458
+ if (existingPromise) {
459
+ return /** Narrows the runtime value to the documented type. @type {T} */ (this._schemaCacheReturnValue(await existingPromise))
460
+ }
461
+
462
+ const promise = (async () => await callback())()
463
+
464
+ this._schemaCache.set(cacheKey, promise)
465
+
466
+ try {
467
+ return /** Narrows the runtime value to the documented type. @type {T} */ (this._schemaCacheReturnValue(await promise))
468
+ } catch (error) {
469
+ if (this._schemaCache.get(cacheKey) === promise) {
470
+ this._schemaCache.delete(cacheKey)
471
+ }
472
+
473
+ throw error
474
+ }
475
+ }
476
+
477
+ /**
478
+ * Runs cached table schema metadata.
479
+ * @template T
480
+ * @param {string} tableName - Table name.
481
+ * @param {string} metadataName - Metadata name.
482
+ * @param {() => Promise<T>} callback - Cache miss callback.
483
+ * @returns {Promise<T>} - Resolves with the cached table metadata.
484
+ */
485
+ async _cachedTableSchemaMetadata(tableName, metadataName, callback) {
486
+ return await this._cachedSchemaMetadata(`table:${tableName}:${metadataName}`, callback)
487
+ }
488
+
489
+ /**
490
+ * Runs schema cache return value.
491
+ * @param {?} value - Cached value.
492
+ * @returns {?} - Value returned to callers.
493
+ */
494
+ _schemaCacheReturnValue(value) {
495
+ if (Array.isArray(value)) return value.slice()
496
+
497
+ return value
498
+ }
499
+
500
+ /**
501
+ * Runs get tables.
502
+ * @abstract
503
+ * @returns {Promise<Array<import("./base-table.js").default>>} - Resolves with the tables.
504
+ */
505
+ getTables() {
506
+ throw new Error(`${this.constructor.name}#getTables not implemented`)
507
+ }
508
+
509
+ /**
510
+ * Runs structure sql.
511
+ * @returns {Promise<string | null>} - Resolves with SQL string.
512
+ */
513
+ async structureSql() {
514
+ return null
515
+ }
516
+
517
+ /**
518
+ * Runs get table by name.
519
+ * @param {string} name - Name.
520
+ * @param {object} [args] - Options object.
521
+ * @param {boolean} args.throwError - Whether throw error.
522
+ * @returns {Promise<import("./base-table.js").default | undefined>} - Resolves with the table by name.
523
+ */
524
+ async getTableByName(name, args) {
525
+ const tables = await this.getTables()
526
+ const tableNames = []
527
+ let table
528
+
529
+ for (const candidate of tables) {
530
+ const candidateName = candidate.getName()
531
+
532
+ if (candidateName == name) {
533
+ table = candidate
534
+ break
535
+ }
536
+
537
+ tableNames.push(candidateName)
538
+ }
539
+
540
+ if (!table && args?.throwError !== false) {
541
+ throw new Error(this._missingTableErrorMessage(name, tableNames))
542
+ }
543
+
544
+ return table
545
+ }
546
+
547
+ /**
548
+ * Runs missing table error message.
549
+ * @param {string} name - Table name.
550
+ * @param {string[]} tableNames - Available table names.
551
+ * @returns {string} - Error message.
552
+ */
553
+ _missingTableErrorMessage(name, tableNames) {
554
+ const environment = this.getConfiguration().getEnvironment()
555
+ const args = this.getArgs()
556
+ const databaseName = args?.database || args?.name || args?.useDatabase || "unknown"
557
+
558
+ return `Couldn't find a table by that name "${name}" in: ${tableNames.join(", ")} (environment: ${environment}, database: ${databaseName})`
559
+ }
560
+
561
+ /**
562
+ * Runs get table by name or fail.
563
+ * @param {string} name - Name.
564
+ * @returns {Promise<import("./base-table.js").default>} - Resolves with the table by name or fail.
565
+ */
566
+ async getTableByNameOrFail(name) {
567
+ return /** Narrows the runtime value to the documented type. @type {import("./base-table.js").default} */ (await this.getTableByName(name, {throwError: true}))
568
+ }
569
+
570
+ /**
571
+ * Runs get type.
572
+ * @abstract
573
+ * @returns {string} - The type.
574
+ */
575
+ getType() {
576
+ throw new Error("'type' not implemented")
577
+ }
578
+
579
+ /**
580
+ * Runs insert.
581
+ * @param {InsertSqlArgsType} args - Options object.
582
+ * @returns {Promise<void>} - Resolves when complete.
583
+ */
584
+ async insert(args) {
585
+ this._assertNotReadOnly()
586
+ const sql = this.insertSql(args)
587
+
588
+ await this.query(sql)
589
+ }
590
+
591
+ /**
592
+ * Runs insert multiple.
593
+ * @param {string} tableName - Table name.
594
+ * @param {Array<string>} columns - Column names.
595
+ * @param {Array<Array<?>>} rows - Rows to insert.
596
+ * @returns {Promise<void>} - Resolves when complete.
597
+ */
598
+ async insertMultiple(tableName, columns, rows) {
599
+ this._assertNotReadOnly()
600
+
601
+ const sql = this.insertSql({columns, tableName, rows})
602
+
603
+ await this.query(sql)
604
+ }
605
+
606
+ /**
607
+ * Runs insert sql.
608
+ * @abstract
609
+ * @param {InsertSqlArgsType} args - Options object.
610
+ * @returns {string} - SQL string.
611
+ */
612
+ insertSql(args) { // eslint-disable-line no-unused-vars
613
+ throw new Error("'insertSql' not implemented")
614
+ }
615
+
616
+ /**
617
+ * Runs upsert.
618
+ * @param {UpsertSqlArgsType} args - Options object.
619
+ * @returns {Promise<void>} - Resolves when complete.
620
+ */
621
+ async upsert(args) {
622
+ this._assertNotReadOnly()
623
+ const sql = this.upsertSql(args)
624
+
625
+ await this.query(sql)
626
+ }
627
+
628
+ /**
629
+ * Runs last insert id.
630
+ * @abstract
631
+ * @returns {Promise<number>} - Resolves with the last insert id.
632
+ */
633
+ lastInsertID() {
634
+ throw new Error(`${this.constructor.name}#lastInsertID not implemented`)
635
+ }
636
+
637
+ /**
638
+ * Runs convert value.
639
+ * @param {?} value - Value to use.
640
+ * @returns {?} - The convert value.
641
+ */
642
+ _convertValue(value) {
643
+ if (typeof value === "boolean") {
644
+ return value ? 1 : 0
645
+ }
646
+
647
+ if (value instanceof Date) {
648
+ return strftime("%F %T.%L", value)
649
+ }
650
+
651
+ // JSON-encode plain objects/arrays so they land in JSON/text columns as valid
652
+ // JSON. Without this, drivers like mysql's escape() turn an object into
653
+ // `key` = value assignment pairs (its `SET ?` form), producing invalid SQL in
654
+ // a value position. Only PLAIN objects and arrays are encoded — class
655
+ // instances (e.g. model records, which are circular via _changes) and Buffers
656
+ // pass through untouched, since JSON.stringify on a record throws on its
657
+ // circular structure and a record is never a valid column value to serialize.
658
+ if (this._isJsonEncodableValue(value)) {
659
+ return JSON.stringify(value)
660
+ }
661
+
662
+ return value
663
+ }
664
+
665
+ /**
666
+ * Whether a value is a plain object or array that should be JSON-encoded for a
667
+ * JSON/text column. Excludes Buffers and class instances (e.g. model records).
668
+ * @param {?} value - Value to test.
669
+ * @returns {boolean} - Whether to JSON-encode the value.
670
+ */
671
+ _isJsonEncodableValue(value) {
672
+ if (value === null || typeof value !== "object") return false
673
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return false
674
+ if (Array.isArray(value)) return true
675
+
676
+ const prototype = Object.getPrototypeOf(value)
677
+
678
+ return prototype === Object.prototype || prototype === null
679
+ }
680
+
681
+ /**
682
+ * Runs options.
683
+ * @abstract
684
+ * @returns {import("../query-parser/options.js").default} - The options options.
685
+ */
686
+ options() {
687
+ throw new Error("'options' not implemented.")
688
+ }
689
+
690
+ /**
691
+ * Runs quote.
692
+ * @param {?} value - Value to use.
693
+ * @returns {number | string} - The quote.
694
+ */
695
+ quote(value) {
696
+ if (typeof value == "number") return value
697
+
698
+ const escapedValue = this.escape(value)
699
+ const result = `"${escapedValue}"`
700
+
701
+ return result
702
+ }
703
+
704
+ /**
705
+ * Runs quote column.
706
+ * @param {string} columnName - Column name.
707
+ * @returns {string} - The quote column.
708
+ */
709
+ quoteColumn(columnName) {
710
+ return this.options().quoteColumnName(columnName)
711
+ }
712
+
713
+ /**
714
+ * Runs quote index.
715
+ * @param {string} columnName - Column name.
716
+ * @returns {string} - The quote index.
717
+ */
718
+ quoteIndex(columnName) {
719
+ return this.options().quoteIndexName(columnName)
720
+ }
721
+
722
+ /**
723
+ * Runs quote table.
724
+ * @param {string} tableName - Table name.
725
+ * @returns {string} - The quote table.
726
+ */
727
+ quoteTable(tableName) {
728
+ return this.options().quoteTableName(tableName)
729
+ }
730
+
731
+ /**
732
+ * Runs new query.
733
+ * @returns {Query} - The new query.
734
+ */
735
+ newQuery() {
736
+ const handler = new Handler()
737
+
738
+ return new Query({
739
+ driver: this,
740
+ handler
741
+ })
742
+ }
743
+
744
+ /**
745
+ * Runs select.
746
+ * @param {string} tableName - Table name.
747
+ * @returns {Promise<QueryResultType>} - Resolves with the select.
748
+ */
749
+ async select(tableName) {
750
+ const query = this.newQuery()
751
+
752
+ const sql = query
753
+ .from(tableName)
754
+ .toSql()
755
+
756
+ return await this.query(sql)
757
+ }
758
+
759
+ /**
760
+ * Runs set id seq.
761
+ * @param {number | undefined} newIdSeq - New id seq.
762
+ * @returns {void} - No return value.
763
+ */
764
+ setIdSeq(newIdSeq) {
765
+ this.idSeq = newIdSeq
766
+ }
767
+
768
+ /**
769
+ * Runs should set auto increment when primary key.
770
+ * @abstract
771
+ * @returns {boolean} - Whether set auto increment when primary key.
772
+ */
773
+ shouldSetAutoIncrementWhenPrimaryKey() {
774
+ throw new Error(`'shouldSetAutoIncrementWhenPrimaryKey' not implemented`)
775
+ }
776
+
777
+ /**
778
+ * Runs supports default primary key uuid.
779
+ * @returns {boolean} - Whether supports default primary key uuid.
780
+ */
781
+ supportsDefaultPrimaryKeyUUID() { return false }
782
+
783
+ /**
784
+ * Runs supports insert into returning.
785
+ * @abstract
786
+ * @returns {boolean} - Whether supports insert into returning.
787
+ */
788
+ supportsInsertIntoReturning() { return false }
789
+
790
+ /**
791
+ * Runs table exists.
792
+ * @param {string} tableName - Table name.
793
+ * @returns {Promise<boolean>} - Resolves with Whether table exists.
794
+ */
795
+ async tableExists(tableName) {
796
+ const tables = await this.getTables()
797
+ const table = tables.find((table) => table.getName() == tableName)
798
+
799
+ if (table) return true
800
+
801
+ return false
802
+ }
803
+
804
+ /**
805
+ * Runs transaction.
806
+ * @param {() => Promise<void>} callback - Callback function.
807
+ * @returns {Promise<?>} - Resolves with the transaction.
808
+ */
809
+ async transaction(callback) {
810
+ const savePointName = this.generateSavePointName()
811
+ /**
812
+ * Callback frame.
813
+ @type {Array<() => void | Promise<void>>} */
814
+ const callbackFrame = []
815
+ let transactionStarted = false
816
+ let savePointStarted = false
817
+
818
+ this._afterCommitCallbackFrames.push(callbackFrame)
819
+
820
+ if (this._transactionsCount == 0) {
821
+ this.logger.debug("Start transaction")
822
+ await this.startTransaction()
823
+ transactionStarted = true
824
+ } else {
825
+ this.logger.debug("Start savepoint", savePointName)
826
+ await this.startSavePoint(savePointName)
827
+ savePointStarted = true
828
+ }
829
+
830
+ let result
831
+
832
+ try {
833
+ result = await callback()
834
+
835
+ if (savePointStarted) {
836
+ this.logger.debug("Release savepoint", savePointName)
837
+ await this.releaseSavePoint(savePointName)
838
+ }
839
+
840
+ if (transactionStarted) {
841
+ this.logger.debug("Commit transaction")
842
+ await this.commitTransaction()
843
+ }
844
+
845
+ await this._commitAfterCommitCallbackFrame()
846
+ } catch (error) {
847
+ if (error instanceof Error) {
848
+ this.logger.debug("Transaction error", error.message)
849
+ } else {
850
+ this.logger.debug("Transaction error", error)
851
+ }
852
+
853
+ let transactionRolledBack = false
854
+
855
+ if (savePointStarted) {
856
+ this.logger.debug("Rollback savepoint", savePointName)
857
+ try {
858
+ await this.rollbackSavePoint(savePointName)
859
+ } catch (savePointError) {
860
+ const message = savePointError instanceof Error ? savePointError.message : `${savePointError}`
861
+
862
+ // MySQL sometimes drops savepoints unexpectedly; fall back to rolling back the full transaction
863
+ if (message.includes("SAVEPOINT") || message.includes("ER_SP_DOES_NOT_EXIST")) {
864
+ this.logger.debug("Savepoint rollback failed; rolling back entire transaction instead")
865
+ await this.rollbackTransaction()
866
+ transactionRolledBack = true
867
+ } else {
868
+ throw savePointError
869
+ }
870
+ }
871
+ }
872
+
873
+ if (transactionStarted && !transactionRolledBack) {
874
+ this.logger.debug("Rollback transaction")
875
+ await this.rollbackTransaction()
876
+ }
877
+
878
+ this._afterCommitCallbackFrames.pop()
879
+
880
+ throw error
881
+ }
882
+
883
+ return result
884
+ }
885
+
886
+ /**
887
+ * Runs a callback after the surrounding transaction commits.
888
+ * If no transaction is active, the callback runs immediately.
889
+ * @param {() => void | Promise<void>} callback - Callback.
890
+ * @returns {Promise<void>} - Resolves when the callback has been registered or run.
891
+ */
892
+ async afterCommit(callback) {
893
+ const currentFrame = this._afterCommitCallbackFrames[this._afterCommitCallbackFrames.length - 1]
894
+
895
+ if (!currentFrame) {
896
+ await callback()
897
+ return
898
+ }
899
+
900
+ currentFrame.push(callback)
901
+ }
902
+
903
+ /**
904
+ * Runs start transaction.
905
+ * @returns {Promise<void>} - Resolves when complete.
906
+ */
907
+ async startTransaction() {
908
+ await this._transactionsActionsMutex.sync(async () => {
909
+ await this._startTransactionAction()
910
+ this._transactionsCount++
911
+ })
912
+ }
913
+
914
+ /**
915
+ * Runs start transaction action.
916
+ * @returns {Promise<void>} - Resolves when complete.
917
+ */
918
+ async _startTransactionAction() {
919
+ await this.query("BEGIN TRANSACTION")
920
+ }
921
+
922
+ /**
923
+ * Runs commit transaction.
924
+ * @returns {Promise<void>} - Resolves when complete.
925
+ */
926
+ async commitTransaction() {
927
+ await this._transactionsActionsMutex.sync(async () => {
928
+ await this._commitTransactionAction()
929
+ this._transactionsCount--
930
+ })
931
+ }
932
+
933
+ /**
934
+ * Runs commit transaction action.
935
+ * @returns {Promise<void>} - Resolves when complete.
936
+ */
937
+ async _commitTransactionAction() {
938
+ await this.query("COMMIT")
939
+ }
940
+
941
+ /**
942
+ * Merges committed callbacks into the parent transaction frame or runs them when the outermost commit completes.
943
+ * @returns {Promise<void>} - Resolves when complete.
944
+ */
945
+ async _commitAfterCommitCallbackFrame() {
946
+ const committedCallbacks = this._afterCommitCallbackFrames.pop()
947
+
948
+ if (!committedCallbacks || committedCallbacks.length === 0) return
949
+
950
+ const parentFrame = this._afterCommitCallbackFrames[this._afterCommitCallbackFrames.length - 1]
951
+
952
+ if (parentFrame) {
953
+ parentFrame.push(...committedCallbacks)
954
+ return
955
+ }
956
+
957
+ for (const callback of committedCallbacks) {
958
+ await callback()
959
+ }
960
+ }
961
+
962
+ /**
963
+ * Runs query.
964
+ * @param {string} sql - SQL string.
965
+ * @param {QueryOptions} [options] - Query options.
966
+ * @returns {Promise<QueryResultType>} - Resolves with the query.
967
+ */
968
+ async query(sql, options = {}) {
969
+ this._assertWritableQuery(sql)
970
+
971
+ let tries = 0
972
+ const maxTries = 5
973
+ const requestTiming = this.configuration.getCurrentRequestTiming()
974
+ const logQuery = options.logQuery ?? this._queryLoggingEnabled()
975
+ const sourceStack = logQuery ? (options.sourceStack || Error().stack) : undefined
976
+ const querySql = this._querySqlWithProcessListComment(sql, options)
977
+
978
+ while (tries < maxTries) {
979
+ tries++
980
+
981
+ try {
982
+ return await this._queryActualWithLogging({originalSql: sql, querySql}, {...options, logQuery, sourceStack}, requestTiming, tries)
983
+ } catch (error) {
984
+ if (!(error instanceof Error)) throw error
985
+
986
+ const retryInfo = this.retryableDatabaseError(error)
987
+
988
+ if (tries < maxTries && retryInfo.retry) {
989
+ if (retryInfo.reconnect) {
990
+ if (this._transactionsCount > 0) {
991
+ throw new Error(`Cannot reconnect while a transaction is active (${this._transactionsCount}). Original error: ${error.message}`, {cause: error})
992
+ }
993
+
994
+ await this.reconnect()
995
+ }
996
+
997
+ const waitMs = typeof retryInfo.waitMs === "number" && Number.isFinite(retryInfo.waitMs) ? retryInfo.waitMs : 100
998
+
999
+ if (waitMs > 0) await wait(waitMs)
1000
+ this.logger.warn(`Retrying query because failed with: ${error.stack}`)
1001
+ // Retry
1002
+ } else {
1003
+ throw error
1004
+ }
1005
+ }
1006
+ }
1007
+
1008
+ throw new Error("'query' unexpected came here")
1009
+ }
1010
+
1011
+ /**
1012
+ * Runs query actual with logging.
1013
+ * @param {object} args - Options object.
1014
+ * @param {string} args.originalSql - Original SQL string before process-list comments.
1015
+ * @param {string} args.querySql - SQL string sent to the database.
1016
+ * @param {QueryOptions} options - Query options.
1017
+ * @param {import("../../http-server/client/request-timing.js").default | undefined} requestTiming - Request timing.
1018
+ * @param {number} tries - Query attempt count.
1019
+ * @returns {Promise<QueryResultType>} - Resolves with the query.
1020
+ */
1021
+ async _queryActualWithLogging({originalSql, querySql}, options, requestTiming, tries) {
1022
+ const startedAtMs = nowMs()
1023
+ const previousActiveQuery = this._activeQuery
1024
+ this._activeQuery = {
1025
+ annotations: getDatabaseAnnotations(),
1026
+ logName: options.logName || "SQL",
1027
+ sqlPreview: this._debugSqlPreview(originalSql),
1028
+ startedAtUnixMs: Date.now()
1029
+ }
1030
+ let result
1031
+
1032
+ try {
1033
+ if (requestTiming && tries === 1) {
1034
+ result = await requestTiming.measureDbQuery(async () => await this._queryActual(querySql))
1035
+ } else if (requestTiming) {
1036
+ result = await requestTiming.measure("db", async () => await this._queryActual(querySql))
1037
+ } else {
1038
+ result = await this._queryActual(querySql)
1039
+ }
1040
+ } finally {
1041
+ this._activeQuery = previousActiveQuery
1042
+ }
1043
+
1044
+ const elapsedMs = nowMs() - startedAtMs
1045
+
1046
+ if (options.logQuery !== false) {
1047
+ await this._logQuery({
1048
+ elapsedMs,
1049
+ logName: options.logName || "SQL",
1050
+ sourceStack: options.sourceStack,
1051
+ sql: originalSql
1052
+ })
1053
+ }
1054
+
1055
+ if (this._schemaCacheInvalidatingSql(originalSql)) {
1056
+ this.clearSchemaCache()
1057
+ }
1058
+
1059
+ return result
1060
+ }
1061
+
1062
+ /**
1063
+ * Runs get debug snapshot.
1064
+ * @returns {DatabaseConnectionDebugSnapshot} - Diagnostic snapshot for this connection.
1065
+ */
1066
+ getDebugSnapshot() {
1067
+ const now = Date.now()
1068
+ const activeQuery = this._activeQuery
1069
+
1070
+ return {
1071
+ activeQuery: activeQuery ? {...activeQuery, runningMs: Math.max(0, now - activeQuery.startedAtUnixMs)} : null,
1072
+ checkoutAgeMs: this._connectionCheckedOutAtUnixMs ? Math.max(0, now - this._connectionCheckedOutAtUnixMs) : undefined,
1073
+ checkedOutAtUnixMs: this._connectionCheckedOutAtUnixMs,
1074
+ checkoutName: this._connectionCheckoutName,
1075
+ driverClass: this.constructor.name,
1076
+ idSeq: this.idSeq,
1077
+ openTransactions: this._transactionsCount,
1078
+ schemaCacheEntries: this._schemaCache.size
1079
+ }
1080
+ }
1081
+
1082
+ /**
1083
+ * Runs debug sql preview.
1084
+ * @param {string} sql - SQL to preview.
1085
+ * @returns {string} - Normalized truncated SQL preview for diagnostics.
1086
+ */
1087
+ _debugSqlPreview(sql) {
1088
+ return sql
1089
+ .replace(/\s+/g, " ")
1090
+ .trim()
1091
+ .slice(0, 500)
1092
+ }
1093
+
1094
+ /**
1095
+ * Runs query sql with process list comment.
1096
+ * @param {string} sql - SQL string.
1097
+ * @param {QueryOptions} options - Query options.
1098
+ * @returns {string} - SQL string with a leading process-list comment when annotations exist.
1099
+ */
1100
+ _querySqlWithProcessListComment(sql, options) {
1101
+ if (options.processListComment === false) return sql
1102
+
1103
+ const parts = []
1104
+
1105
+ if (this._connectionCheckoutName) {
1106
+ parts.push(`checkout="${this._processListCommentValue(this._connectionCheckoutName)}"`)
1107
+ }
1108
+
1109
+ const annotations = getDatabaseAnnotations()
1110
+
1111
+ if (annotations.length > 0) {
1112
+ parts.push(`annotations="${this._processListCommentValue(annotations.join(" > "))}"`)
1113
+ }
1114
+
1115
+ if (parts.length === 0) return sql
1116
+
1117
+ return `/* velocious ${parts.join(" ")} */ ${sql}`
1118
+ }
1119
+
1120
+ /**
1121
+ * Runs process list comment value.
1122
+ * @param {string} value - Raw process-list comment value.
1123
+ * @returns {string} - Sanitized process-list comment value.
1124
+ */
1125
+ _processListCommentValue(value) {
1126
+ let sanitized = ""
1127
+
1128
+ for (const character of value) {
1129
+ const codePoint = character.codePointAt(0)
1130
+
1131
+ sanitized += codePoint !== undefined && (codePoint < 32 || codePoint === 127) ? " " : character
1132
+ }
1133
+
1134
+ return sanitized
1135
+ .replace(/\*\//g, "* /")
1136
+ .replace(/\s+/g, " ")
1137
+ .trim()
1138
+ .slice(0, 200)
1139
+ .replace(/"/g, "'")
1140
+ }
1141
+
1142
+ /**
1143
+ * Runs schema cache invalidating sql.
1144
+ * @param {string} sql - SQL string.
1145
+ * @returns {boolean} - Whether the SQL should invalidate schema metadata.
1146
+ */
1147
+ _schemaCacheInvalidatingSql(sql) {
1148
+ const normalized = sql
1149
+ .trim()
1150
+ .replace(/^\ufeff/, "")
1151
+ .replace(/\/\*[\s\S]*?\*\//g, " ")
1152
+ .replace(/--[^\n]*(\n|$)/g, " ")
1153
+ .replace(/\s+/g, " ")
1154
+ .toLowerCase()
1155
+
1156
+ if (!normalized) return false
1157
+ if (/^(create|alter|drop|rename)\b/.test(normalized)) return true
1158
+ if (/^comment\s+on\b/.test(normalized)) return true
1159
+ if (/^exec(?:ute)?\s+sp_rename\b/.test(normalized)) return true
1160
+ if (/^if\b[\s\S]*\bbegin\s+(create|alter|drop|rename)\b/.test(normalized)) return true
1161
+
1162
+ return false
1163
+ }
1164
+
1165
+ /**
1166
+ * Runs query logging enabled.
1167
+ * @returns {boolean} - Whether query logging is enabled for this driver.
1168
+ */
1169
+ _queryLoggingEnabled() {
1170
+ if (typeof this.configuration?.getQueryLoggingEnabled !== "function") return true
1171
+ if (!this.configuration.getQueryLoggingEnabled()) return false
1172
+
1173
+ const logger = new Logger("SQL", {configuration: this.configuration})
1174
+
1175
+ return logger.isLevelEnabled("info")
1176
+ }
1177
+
1178
+ /**
1179
+ * Runs log query.
1180
+ * @param {object} args - Options object.
1181
+ * @param {number} args.elapsedMs - Elapsed milliseconds.
1182
+ * @param {string} args.logName - Query log subject.
1183
+ * @param {string | undefined} args.sourceStack - Source stack.
1184
+ * @param {string} args.sql - SQL string.
1185
+ * @returns {Promise<void>} - Resolves when complete.
1186
+ */
1187
+ async _logQuery({elapsedMs, logName, sourceStack, sql}) {
1188
+ const logger = new Logger(logName, {configuration: this.configuration})
1189
+ const sourceLine = this._querySourceLine(sourceStack)
1190
+ const message = sourceLine
1191
+ ? `(${formatElapsedMs(elapsedMs)}) ${sql}\n ↳ ${sourceLine}`
1192
+ : `(${formatElapsedMs(elapsedMs)}) ${sql}`
1193
+
1194
+ await logger.info(message)
1195
+ }
1196
+
1197
+ /**
1198
+ * Runs query source line.
1199
+ * @param {string | undefined} sourceStack - Source stack.
1200
+ * @returns {string | undefined} - Source line when an application frame is available.
1201
+ */
1202
+ _querySourceLine(sourceStack) {
1203
+ if (!sourceStack) return undefined
1204
+
1205
+ const applicationDirectory = typeof this.configuration?.getDirectoryIfAvailable === "function"
1206
+ ? this.configuration.getDirectoryIfAvailable()
1207
+ : this.configuration?.getDirectory?.()
1208
+
1209
+ if (!applicationDirectory) return undefined
1210
+
1211
+ const error = new Error("Query source")
1212
+
1213
+ error.stack = sourceStack
1214
+
1215
+ return BacktraceCleaner.getApplicationSourceLine(error, {
1216
+ applicationDirectory,
1217
+ frameworkSourceDirectory: this.configuration.getEnvironmentHandler().getFrameworkSourceDirectory()
1218
+ })
1219
+ }
1220
+
1221
+ /**
1222
+ * Runs query actual.
1223
+ * @abstract
1224
+ * @param {string} sql - SQL string.
1225
+ * @returns {Promise<QueryResultType>} - Resolves with the query actual.
1226
+ */
1227
+ _queryActual(sql) { // eslint-disable-line no-unused-vars
1228
+ throw new Error(`queryActual not implemented`)
1229
+ }
1230
+
1231
+ /**
1232
+ * Runs query to sql.
1233
+ * @abstract
1234
+ * @param {Query} _query - Query instance.
1235
+ * @returns {string} - SQL string.
1236
+ */
1237
+ queryToSql(_query) { throw new Error("queryToSql not implemented") }
1238
+
1239
+ /**
1240
+ * Runs retryable database error.
1241
+ * @param {Error} _error - Error instance.
1242
+ * @returns {RetryableDatabaseErrorResult} - Retry info.
1243
+ */
1244
+ retryableDatabaseError(_error) {
1245
+ return {retry: false, reconnect: false}
1246
+ }
1247
+
1248
+ /**
1249
+ * Runs assert writable query.
1250
+ * @param {string} sql - SQL string.
1251
+ * @returns {void} - No return value.
1252
+ */
1253
+ _assertWritableQuery(sql) {
1254
+ if (!this.isReadOnly()) return
1255
+ if (!this._sqlLooksLikeWrite(sql)) return
1256
+
1257
+ throw new Error("Database is read-only")
1258
+ }
1259
+
1260
+ /**
1261
+ * Runs assert not read only.
1262
+ * @returns {void} - No return value.
1263
+ */
1264
+ _assertNotReadOnly() {
1265
+ if (this.isReadOnly()) {
1266
+ throw new Error("Database is read-only")
1267
+ }
1268
+ }
1269
+
1270
+ /**
1271
+ * Runs sql looks like write.
1272
+ * @param {string} sql - SQL string.
1273
+ * @returns {boolean} - SQL representation.
1274
+ */
1275
+ _sqlLooksLikeWrite(sql) {
1276
+ const normalized = sql.trim().toLowerCase()
1277
+
1278
+ if (!normalized) return false
1279
+
1280
+ if (
1281
+ normalized.startsWith("select") ||
1282
+ normalized.startsWith("show") ||
1283
+ normalized.startsWith("pragma") ||
1284
+ normalized.startsWith("explain") ||
1285
+ normalized.startsWith("describe")
1286
+ ) {
1287
+ return false
1288
+ }
1289
+
1290
+ if (normalized.startsWith("with")) {
1291
+ const withMatch = normalized.match(/^\s*with[\s\S]+?\)\s*(select|insert|update|delete|merge|replace)\b/)
1292
+
1293
+ if (withMatch) {
1294
+ return withMatch[1] !== "select"
1295
+ }
1296
+
1297
+ return false
1298
+ }
1299
+
1300
+ const keywordMatch = normalized.match(/^\s*(\w+)/)
1301
+ const keyword = keywordMatch ? keywordMatch[1] : ""
1302
+
1303
+ return [
1304
+ "insert",
1305
+ "update",
1306
+ "delete",
1307
+ "create",
1308
+ "alter",
1309
+ "drop",
1310
+ "truncate",
1311
+ "merge",
1312
+ "replace"
1313
+ ].includes(keyword)
1314
+ }
1315
+
1316
+ /**
1317
+ * Runs is read only.
1318
+ * @returns {boolean} - Whether read only.
1319
+ */
1320
+ isReadOnly() {
1321
+ return Boolean(this.getArgs().readOnly)
1322
+ }
1323
+
1324
+ /**
1325
+ * Runs rollback transaction.
1326
+ * @returns {Promise<void>} - Resolves when complete.
1327
+ */
1328
+ async rollbackTransaction() {
1329
+ await this._transactionsActionsMutex.sync(async () => {
1330
+ try {
1331
+ await this._rollbackTransactionAction()
1332
+ } finally {
1333
+ this._transactionsCount--
1334
+
1335
+ // A rolled-back transaction may have reverted DDL (e.g. a CREATE TABLE
1336
+ // run lazily inside the transaction), so any cached schema metadata is
1337
+ // now stale and must be invalidated. Without this, a later tableExists()
1338
+ // check can report a table that the rollback already removed, so callers
1339
+ // skip recreating it and then fail with "no such table".
1340
+ this.clearSchemaCache()
1341
+ }
1342
+ })
1343
+ }
1344
+
1345
+ /**
1346
+ * Runs rollback transaction action.
1347
+ * @returns {Promise<void>} - Resolves when complete.
1348
+ */
1349
+ async _rollbackTransactionAction() {
1350
+ await this.query("ROLLBACK")
1351
+ }
1352
+
1353
+ /**
1354
+ * Runs generate save point name.
1355
+ * @returns {string} - The generate save point name.
1356
+ */
1357
+ generateSavePointName() {
1358
+ return `sp${new UUID(4).format().replaceAll("-", "")}`
1359
+ }
1360
+
1361
+ /**
1362
+ * Runs start save point.
1363
+ * @param {string} savePointName - Save point name.
1364
+ * @returns {Promise<void>} - Resolves when complete.
1365
+ */
1366
+ async startSavePoint(savePointName) {
1367
+ await this._transactionsActionsMutex.sync(async () => {
1368
+ await this._startSavePointAction(savePointName)
1369
+ })
1370
+ }
1371
+
1372
+ /**
1373
+ * Runs start save point action.
1374
+ * @param {string} savePointName - Save point name.
1375
+ * @returns {Promise<void>} - Resolves when complete.
1376
+ */
1377
+ async _startSavePointAction(savePointName) {
1378
+ await this.query(`SAVEPOINT ${savePointName}`)
1379
+ }
1380
+
1381
+ /**
1382
+ * Runs rename column.
1383
+ * @param {string} tableName - Table name.
1384
+ * @param {string} oldColumnName - Previous column name.
1385
+ * @param {string} newColumnName - New column name.
1386
+ * @returns {Promise<void>} - Resolves when complete.
1387
+ */
1388
+ async renameColumn(tableName, oldColumnName, newColumnName) {
1389
+ this._assertNotReadOnly()
1390
+ const tableColumn = new TableColumn(oldColumnName)
1391
+
1392
+ tableColumn.setNewName(newColumnName)
1393
+
1394
+ const tableData = new TableData(tableName)
1395
+
1396
+ tableData.addColumn(tableColumn)
1397
+
1398
+ const alterTableSQLs = await this.alterTableSQLs(tableData)
1399
+
1400
+ for (const alterTableSQL of alterTableSQLs) {
1401
+ await this.query(alterTableSQL)
1402
+ }
1403
+ }
1404
+
1405
+ /**
1406
+ * Runs release save point.
1407
+ * @param {string} savePointName - Save point name.
1408
+ * @returns {Promise<void>} - Resolves when complete.
1409
+ */
1410
+ async releaseSavePoint(savePointName) {
1411
+ await this._transactionsActionsMutex.sync(async () => {
1412
+ await this._releaseSavePointAction(savePointName)
1413
+ })
1414
+ }
1415
+
1416
+ /**
1417
+ * Runs release save point action.
1418
+ * @param {string} savePointName - Save point name.
1419
+ * @returns {Promise<void>} - Resolves when complete.
1420
+ */
1421
+ async _releaseSavePointAction(savePointName) {
1422
+ try {
1423
+ await this.query(`RELEASE SAVEPOINT ${savePointName}`)
1424
+ } catch (error) {
1425
+ const message = error instanceof Error ? error.message : `${error}`
1426
+
1427
+ // Savepoint may already be gone if the database rolled back automatically
1428
+ if (message.toLowerCase().includes("savepoint") && message.toLowerCase().includes("does not exist")) {
1429
+ this.logger.debug(`Release savepoint ignored because it no longer exists: ${savePointName}`)
1430
+ return
1431
+ }
1432
+
1433
+ throw error
1434
+ }
1435
+ }
1436
+
1437
+ /**
1438
+ * Runs rollback save point.
1439
+ * @param {string} savePointName - Save point name.
1440
+ * @returns {Promise<void>} - Resolves when complete.
1441
+ */
1442
+ async rollbackSavePoint(savePointName) {
1443
+ await this._transactionsActionsMutex.sync(async () => {
1444
+ await this._rollbackSavePointAction(savePointName)
1445
+ })
1446
+ }
1447
+
1448
+ /**
1449
+ * Runs rollback save point action.
1450
+ * @param {string} savePointName - Save point name.
1451
+ * @returns {Promise<void>} - Resolves when complete.
1452
+ */
1453
+ async _rollbackSavePointAction(savePointName) {
1454
+ await this.query(`ROLLBACK TO SAVEPOINT ${savePointName}`)
1455
+ }
1456
+
1457
+ /**
1458
+ * Runs truncate all tables.
1459
+ * @returns {Promise<void>} - Resolves when complete.
1460
+ */
1461
+ async truncateAllTables() {
1462
+ this._assertNotReadOnly()
1463
+ await this.withDisabledForeignKeys(async () => {
1464
+ let tries = 0
1465
+
1466
+ while(tries <= 5) {
1467
+ tries++
1468
+
1469
+ const tables = await this.getTables()
1470
+ const truncateErrors = []
1471
+
1472
+ for (const table of tables) {
1473
+ if (table.getName() != "schema_migrations") {
1474
+ try {
1475
+ await table.truncate({cascade: true})
1476
+ } catch (error) {
1477
+ console.error(error)
1478
+ truncateErrors.push(error)
1479
+ }
1480
+ }
1481
+ }
1482
+
1483
+ if (truncateErrors.length == 0) {
1484
+ break
1485
+ } else if (tries <= 5) {
1486
+ // A truncate failed — the schema cache may still list a table that was
1487
+ // dropped out from under us (e.g. a db:rollback test that left the
1488
+ // shared DB rolled back). Clear it so the next pass re-reads the live
1489
+ // table list and no longer tries to truncate a table that is gone.
1490
+ this.clearSchemaCache()
1491
+ } else {
1492
+ throw truncateErrors[0]
1493
+ }
1494
+ }
1495
+ })
1496
+ }
1497
+
1498
+ /**
1499
+ * Runs update.
1500
+ * @param {UpdateSqlArgsType} args - Options object.
1501
+ * @returns {Promise<void>} - Resolves when complete.
1502
+ */
1503
+ async update(args) {
1504
+ this._assertNotReadOnly()
1505
+ const sql = this.updateSql(args)
1506
+
1507
+ await this.query(sql)
1508
+ }
1509
+
1510
+ /**
1511
+ * Runs update sql.
1512
+ * @abstract
1513
+ * @param {UpdateSqlArgsType} args - Options object.
1514
+ * @returns {string} - SQL string.
1515
+ */
1516
+ updateSql(args) { // eslint-disable-line no-unused-vars
1517
+ throw new Error("'disableForeignKeys' not implemented")
1518
+ }
1519
+
1520
+ /**
1521
+ * Runs upsert sql.
1522
+ * @abstract
1523
+ * @param {UpsertSqlArgsType} args - Options object.
1524
+ * @returns {string} - SQL string.
1525
+ */
1526
+ upsertSql(args) { // eslint-disable-line no-unused-vars
1527
+ throw new Error("'upsertSql' not implemented")
1528
+ }
1529
+
1530
+ /**
1531
+ * Runs disable foreign keys.
1532
+ * @abstract
1533
+ * @returns {Promise<void>} - Resolves when complete.
1534
+ */
1535
+ disableForeignKeys() {
1536
+ throw new Error("'disableForeignKeys' not implemented")
1537
+ }
1538
+
1539
+ /**
1540
+ * Runs enable foreign keys.
1541
+ * @abstract
1542
+ * @returns {Promise<void>} - Resolves when complete.
1543
+ */
1544
+ enableForeignKeys() {
1545
+ throw new Error("'enableForeignKeys' not implemented")
1546
+ }
1547
+
1548
+ /**
1549
+ * Runs with disabled foreign keys.
1550
+ * @param {function() : void} callback - Callback function.
1551
+ * @returns {Promise<?>} - Resolves with the with disabled foreign keys.
1552
+ */
1553
+ async withDisabledForeignKeys(callback) {
1554
+ await this.disableForeignKeys()
1555
+
1556
+ try {
1557
+ return await callback()
1558
+ } finally {
1559
+ await this.enableForeignKeys()
1560
+ }
1561
+ }
1562
+
1563
+ /**
1564
+ * Blocks until a named advisory lock is acquired on this connection.
1565
+ * Advisory locks are connection-scoped and do not interact with row or
1566
+ * table locks; they are purely cooperative between callers that use the
1567
+ * same name and let you serialize functionality without blocking readers
1568
+ * or writers that do not participate in the same lock.
1569
+ * @abstract
1570
+ * @param {string} name - Lock name.
1571
+ * @param {{timeoutMs?: number | null}} [_args] - Optional timeout in milliseconds; `null` or undefined blocks forever.
1572
+ * @returns {Promise<boolean>} - Resolves to true when the lock has been acquired, false if the timeout elapsed.
1573
+ */
1574
+ acquireAdvisoryLock(name, _args = {}) {
1575
+ throw new Error(`'acquireAdvisoryLock' not implemented for ${this.constructor.name}`)
1576
+ }
1577
+
1578
+ /**
1579
+ * Attempts to acquire a named advisory lock without blocking.
1580
+ * @abstract
1581
+ * @param {string} name - Lock name.
1582
+ * @returns {Promise<boolean>} - Resolves to true if the lock was acquired, false if it was already held.
1583
+ */
1584
+ tryAcquireAdvisoryLock(name) { // eslint-disable-line no-unused-vars
1585
+ throw new Error(`'tryAcquireAdvisoryLock' not implemented for ${this.constructor.name}`)
1586
+ }
1587
+
1588
+ /**
1589
+ * Releases a named advisory lock previously acquired on this connection.
1590
+ * @abstract
1591
+ * @param {string} name - Lock name.
1592
+ * @returns {Promise<boolean>} - Resolves to true if the lock was held by this session and has now been released.
1593
+ */
1594
+ releaseAdvisoryLock(name) { // eslint-disable-line no-unused-vars
1595
+ throw new Error(`'releaseAdvisoryLock' not implemented for ${this.constructor.name}`)
1596
+ }
1597
+
1598
+ /**
1599
+ * Checks whether a named advisory lock is currently held by any session.
1600
+ * Intended as an introspection helper; callers who need to act on the
1601
+ * result should prefer `tryAcquireAdvisoryLock` to avoid a TOCTOU race.
1602
+ * @abstract
1603
+ * @param {string} name - Lock name.
1604
+ * @returns {Promise<boolean>} - Resolves to true if the lock is held by ? session.
1605
+ */
1606
+ isAdvisoryLockHeld(name) { // eslint-disable-line no-unused-vars
1607
+ throw new Error(`'isAdvisoryLockHeld' not implemented for ${this.constructor.name}`)
1608
+ }
1609
+ }