velocious 1.0.429 → 1.0.431

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 (812) hide show
  1. package/bin/velocious.js +48 -0
  2. package/build/bin/velocious.js +39 -34
  3. package/build/index.js +1 -2
  4. package/build/src/application.js +214 -187
  5. package/build/src/authorization/ability.d.ts +24 -23
  6. package/build/src/authorization/ability.d.ts.map +1 -1
  7. package/build/src/authorization/ability.js +300 -252
  8. package/build/src/authorization/base-resource.d.ts +20 -26
  9. package/build/src/authorization/base-resource.d.ts.map +1 -1
  10. package/build/src/authorization/base-resource.js +136 -118
  11. package/build/src/background-jobs/client.js +47 -43
  12. package/build/src/background-jobs/cron-expression.js +166 -127
  13. package/build/src/background-jobs/forked-runner-child.js +47 -37
  14. package/build/src/background-jobs/job-record.js +10 -8
  15. package/build/src/background-jobs/job-registry.js +84 -72
  16. package/build/src/background-jobs/job-runner.js +81 -74
  17. package/build/src/background-jobs/job.js +72 -62
  18. package/build/src/background-jobs/json-socket.js +70 -65
  19. package/build/src/background-jobs/main.js +900 -841
  20. package/build/src/background-jobs/normalize-error.js +11 -12
  21. package/build/src/background-jobs/scheduler.js +247 -205
  22. package/build/src/background-jobs/socket-request.js +65 -60
  23. package/build/src/background-jobs/status-reporter.js +96 -86
  24. package/build/src/background-jobs/store.js +980 -862
  25. package/build/src/background-jobs/types.js +3 -2
  26. package/build/src/background-jobs/web/authorization.js +50 -38
  27. package/build/src/background-jobs/web/controller.js +268 -232
  28. package/build/src/background-jobs/web/index.js +40 -36
  29. package/build/src/background-jobs/web/path-matcher.js +48 -45
  30. package/build/src/background-jobs/web/registry.js +14 -9
  31. package/build/src/background-jobs/worker.js +639 -585
  32. package/build/src/beacon/client.js +293 -264
  33. package/build/src/beacon/in-process-broker.js +25 -20
  34. package/build/src/beacon/in-process-client.js +116 -104
  35. package/build/src/beacon/server.js +126 -110
  36. package/build/src/beacon/types.js +8 -2
  37. package/build/src/cli/base-command.js +57 -49
  38. package/build/src/cli/browser-cli.js +42 -37
  39. package/build/src/cli/commands/background-jobs-main.js +5 -5
  40. package/build/src/cli/commands/background-jobs-runner.js +5 -5
  41. package/build/src/cli/commands/background-jobs-worker.js +5 -5
  42. package/build/src/cli/commands/beacon.js +5 -5
  43. package/build/src/cli/commands/console.js +10 -10
  44. package/build/src/cli/commands/db/base-command.js +76 -71
  45. package/build/src/cli/commands/db/create.js +61 -53
  46. package/build/src/cli/commands/db/drop.js +71 -62
  47. package/build/src/cli/commands/db/migrate.js +15 -13
  48. package/build/src/cli/commands/db/reset.js +19 -16
  49. package/build/src/cli/commands/db/rollback.js +13 -12
  50. package/build/src/cli/commands/db/schema/dump.js +9 -9
  51. package/build/src/cli/commands/db/schema/load.js +9 -9
  52. package/build/src/cli/commands/db/seed.js +9 -9
  53. package/build/src/cli/commands/db/tenants/check.js +35 -32
  54. package/build/src/cli/commands/db/tenants/create.js +29 -26
  55. package/build/src/cli/commands/db/tenants/migrate.js +44 -40
  56. package/build/src/cli/commands/destroy/migration.js +5 -5
  57. package/build/src/cli/commands/generate/base-models.js +5 -5
  58. package/build/src/cli/commands/generate/frontend-models.js +9 -9
  59. package/build/src/cli/commands/generate/migration.js +5 -5
  60. package/build/src/cli/commands/generate/model.js +5 -5
  61. package/build/src/cli/commands/init.js +9 -7
  62. package/build/src/cli/commands/routes.js +6 -6
  63. package/build/src/cli/commands/run-script.js +9 -9
  64. package/build/src/cli/commands/runner.js +9 -9
  65. package/build/src/cli/commands/server.js +6 -6
  66. package/build/src/cli/commands/test.js +7 -6
  67. package/build/src/cli/index.js +141 -127
  68. package/build/src/cli/tenant-database-command-helper.js +185 -154
  69. package/build/src/cli/use-browser-cli.js +20 -15
  70. package/build/src/configuration-resolver.js +54 -47
  71. package/build/src/configuration-types.d.ts +21 -2
  72. package/build/src/configuration-types.d.ts.map +1 -1
  73. package/build/src/configuration-types.js +60 -3
  74. package/build/src/configuration.js +2547 -2240
  75. package/build/src/controller.js +407 -363
  76. package/build/src/current-configuration.js +12 -9
  77. package/build/src/current.js +75 -70
  78. package/build/src/database/annotations-async-hooks.js +22 -16
  79. package/build/src/database/annotations.js +18 -12
  80. package/build/src/database/drivers/base-column.js +179 -155
  81. package/build/src/database/drivers/base-columns-index.js +78 -69
  82. package/build/src/database/drivers/base-foreign-key.js +101 -89
  83. package/build/src/database/drivers/base-table.js +149 -124
  84. package/build/src/database/drivers/base.js +1489 -1306
  85. package/build/src/database/drivers/mssql/column.js +50 -39
  86. package/build/src/database/drivers/mssql/columns-index.js +3 -2
  87. package/build/src/database/drivers/mssql/connect-connection.js +9 -11
  88. package/build/src/database/drivers/mssql/foreign-key.js +9 -8
  89. package/build/src/database/drivers/mssql/index.js +587 -507
  90. package/build/src/database/drivers/mssql/options.js +75 -68
  91. package/build/src/database/drivers/mssql/query-parser.js +3 -2
  92. package/build/src/database/drivers/mssql/sql/alter-table.js +2 -2
  93. package/build/src/database/drivers/mssql/sql/create-database.js +31 -24
  94. package/build/src/database/drivers/mssql/sql/create-index.js +2 -2
  95. package/build/src/database/drivers/mssql/sql/create-table.js +2 -2
  96. package/build/src/database/drivers/mssql/sql/delete.js +16 -14
  97. package/build/src/database/drivers/mssql/sql/drop-database.js +31 -24
  98. package/build/src/database/drivers/mssql/sql/drop-table.js +2 -2
  99. package/build/src/database/drivers/mssql/sql/insert.js +2 -2
  100. package/build/src/database/drivers/mssql/sql/update.js +28 -24
  101. package/build/src/database/drivers/mssql/sql/upsert.js +20 -18
  102. package/build/src/database/drivers/mssql/structure-sql.js +114 -102
  103. package/build/src/database/drivers/mssql/table.js +96 -81
  104. package/build/src/database/drivers/mysql/column.js +92 -75
  105. package/build/src/database/drivers/mysql/columns-index.js +19 -16
  106. package/build/src/database/drivers/mysql/foreign-key.js +9 -8
  107. package/build/src/database/drivers/mysql/index.js +457 -396
  108. package/build/src/database/drivers/mysql/options.js +30 -26
  109. package/build/src/database/drivers/mysql/query-parser.js +3 -2
  110. package/build/src/database/drivers/mysql/query.js +29 -26
  111. package/build/src/database/drivers/mysql/sql/alter-table.js +3 -2
  112. package/build/src/database/drivers/mysql/sql/create-database.js +28 -23
  113. package/build/src/database/drivers/mysql/sql/create-index.js +3 -2
  114. package/build/src/database/drivers/mysql/sql/create-table.js +3 -2
  115. package/build/src/database/drivers/mysql/sql/delete.js +17 -14
  116. package/build/src/database/drivers/mysql/sql/drop-database.js +3 -2
  117. package/build/src/database/drivers/mysql/sql/drop-table.js +3 -2
  118. package/build/src/database/drivers/mysql/sql/insert.js +3 -2
  119. package/build/src/database/drivers/mysql/sql/update.js +29 -24
  120. package/build/src/database/drivers/mysql/sql/upsert.js +10 -8
  121. package/build/src/database/drivers/mysql/structure-sql.js +88 -79
  122. package/build/src/database/drivers/mysql/table.js +98 -83
  123. package/build/src/database/drivers/pgsql/column.js +72 -56
  124. package/build/src/database/drivers/pgsql/columns-index.js +3 -2
  125. package/build/src/database/drivers/pgsql/foreign-key.js +9 -8
  126. package/build/src/database/drivers/pgsql/index.js +438 -377
  127. package/build/src/database/drivers/pgsql/options.js +28 -25
  128. package/build/src/database/drivers/pgsql/query-parser.js +3 -2
  129. package/build/src/database/drivers/pgsql/sql/alter-table.js +3 -2
  130. package/build/src/database/drivers/pgsql/sql/create-database.js +23 -19
  131. package/build/src/database/drivers/pgsql/sql/create-index.js +3 -2
  132. package/build/src/database/drivers/pgsql/sql/create-table.js +3 -2
  133. package/build/src/database/drivers/pgsql/sql/delete.js +17 -14
  134. package/build/src/database/drivers/pgsql/sql/drop-database.js +3 -2
  135. package/build/src/database/drivers/pgsql/sql/drop-table.js +3 -2
  136. package/build/src/database/drivers/pgsql/sql/insert.js +3 -2
  137. package/build/src/database/drivers/pgsql/sql/update.js +29 -24
  138. package/build/src/database/drivers/pgsql/sql/upsert.js +11 -9
  139. package/build/src/database/drivers/pgsql/structure-sql.js +120 -108
  140. package/build/src/database/drivers/pgsql/table.js +77 -60
  141. package/build/src/database/drivers/sqlite/base.js +478 -405
  142. package/build/src/database/drivers/sqlite/column.js +69 -54
  143. package/build/src/database/drivers/sqlite/columns-index.js +27 -22
  144. package/build/src/database/drivers/sqlite/connection-sql-js.js +42 -35
  145. package/build/src/database/drivers/sqlite/foreign-key.js +21 -18
  146. package/build/src/database/drivers/sqlite/index.js +373 -330
  147. package/build/src/database/drivers/sqlite/index.native.js +64 -55
  148. package/build/src/database/drivers/sqlite/index.web.js +87 -69
  149. package/build/src/database/drivers/sqlite/options.js +28 -25
  150. package/build/src/database/drivers/sqlite/query-parser.js +3 -2
  151. package/build/src/database/drivers/sqlite/query.js +24 -21
  152. package/build/src/database/drivers/sqlite/query.native.js +25 -20
  153. package/build/src/database/drivers/sqlite/query.web.js +37 -30
  154. package/build/src/database/drivers/sqlite/sql/alter-table.js +179 -159
  155. package/build/src/database/drivers/sqlite/sql/create-index.js +3 -2
  156. package/build/src/database/drivers/sqlite/sql/create-table.js +3 -2
  157. package/build/src/database/drivers/sqlite/sql/delete.js +22 -17
  158. package/build/src/database/drivers/sqlite/sql/drop-table.js +3 -2
  159. package/build/src/database/drivers/sqlite/sql/insert.js +3 -2
  160. package/build/src/database/drivers/sqlite/sql/update.js +29 -24
  161. package/build/src/database/drivers/sqlite/sql/upsert.js +11 -9
  162. package/build/src/database/drivers/sqlite/structure-sql.js +52 -49
  163. package/build/src/database/drivers/sqlite/table-rebuilder.js +75 -62
  164. package/build/src/database/drivers/sqlite/table.js +125 -102
  165. package/build/src/database/drivers/structure-sql/utils.js +17 -14
  166. package/build/src/database/handler.js +10 -9
  167. package/build/src/database/initializer-from-require-context.js +87 -76
  168. package/build/src/database/migration/index.js +395 -332
  169. package/build/src/database/migrator/files-finder.js +50 -40
  170. package/build/src/database/migrator/types.js +30 -2
  171. package/build/src/database/migrator.js +526 -454
  172. package/build/src/database/pool/async-tracked-multi-connection.js +1147 -997
  173. package/build/src/database/pool/base-methods-forward.js +43 -40
  174. package/build/src/database/pool/base.js +343 -298
  175. package/build/src/database/pool/single-multi-use.js +110 -93
  176. package/build/src/database/query/alter-table-base.js +99 -84
  177. package/build/src/database/query/base.js +46 -39
  178. package/build/src/database/query/create-database-base.js +30 -25
  179. package/build/src/database/query/create-index-base.js +94 -75
  180. package/build/src/database/query/create-table-base.js +193 -151
  181. package/build/src/database/query/delete-base.js +16 -14
  182. package/build/src/database/query/drop-database-base.js +28 -23
  183. package/build/src/database/query/drop-table-base.js +53 -42
  184. package/build/src/database/query/from-base.js +33 -30
  185. package/build/src/database/query/from-plain.js +13 -11
  186. package/build/src/database/query/from-table.js +15 -13
  187. package/build/src/database/query/index.js +472 -410
  188. package/build/src/database/query/insert-base.js +164 -143
  189. package/build/src/database/query/join-base.js +40 -35
  190. package/build/src/database/query/join-object.js +153 -128
  191. package/build/src/database/query/join-plain.js +15 -13
  192. package/build/src/database/query/join-tracker.js +90 -76
  193. package/build/src/database/query/model-class-query.js +1370 -1134
  194. package/build/src/database/query/order-base.js +30 -27
  195. package/build/src/database/query/order-column.js +53 -44
  196. package/build/src/database/query/order-plain.js +24 -20
  197. package/build/src/database/query/preloader/belongs-to.js +258 -210
  198. package/build/src/database/query/preloader/ensure-model-class-initialized.js +9 -8
  199. package/build/src/database/query/preloader/has-many.js +301 -240
  200. package/build/src/database/query/preloader/has-one.js +117 -91
  201. package/build/src/database/query/preloader/selection.js +129 -117
  202. package/build/src/database/query/preloader.js +185 -160
  203. package/build/src/database/query/query-data.js +201 -157
  204. package/build/src/database/query/select-base.js +27 -25
  205. package/build/src/database/query/select-plain.js +15 -13
  206. package/build/src/database/query/select-table-and-column.js +25 -21
  207. package/build/src/database/query/update-base.js +38 -35
  208. package/build/src/database/query/upsert-base.js +100 -93
  209. package/build/src/database/query/where-base.js +35 -32
  210. package/build/src/database/query/where-combinator.d.ts.map +1 -1
  211. package/build/src/database/query/where-combinator.js +28 -26
  212. package/build/src/database/query/where-hash.js +68 -61
  213. package/build/src/database/query/where-model-class-hash.js +469 -414
  214. package/build/src/database/query/where-not.js +20 -18
  215. package/build/src/database/query/where-plain.js +17 -15
  216. package/build/src/database/query/with-count.js +159 -125
  217. package/build/src/database/query-parser/base-query-parser.js +37 -32
  218. package/build/src/database/query-parser/from-parser.js +45 -36
  219. package/build/src/database/query-parser/group-parser.js +50 -42
  220. package/build/src/database/query-parser/joins-parser.js +33 -28
  221. package/build/src/database/query-parser/limit-parser.js +70 -67
  222. package/build/src/database/query-parser/options.js +82 -75
  223. package/build/src/database/query-parser/order-parser.js +40 -36
  224. package/build/src/database/query-parser/select-parser.js +60 -49
  225. package/build/src/database/query-parser/where-parser.js +41 -36
  226. package/build/src/database/record/acts-as-list.d.ts.map +1 -1
  227. package/build/src/database/record/acts-as-list.js +273 -229
  228. package/build/src/database/record/attachments/download.js +45 -44
  229. package/build/src/database/record/attachments/handle.js +161 -141
  230. package/build/src/database/record/attachments/normalize-input.js +138 -128
  231. package/build/src/database/record/attachments/storage-drivers/filesystem.js +91 -77
  232. package/build/src/database/record/attachments/storage-drivers/native.js +121 -112
  233. package/build/src/database/record/attachments/storage-drivers/s3.js +208 -177
  234. package/build/src/database/record/attachments/store.d.ts +1 -1
  235. package/build/src/database/record/attachments/store.d.ts.map +1 -1
  236. package/build/src/database/record/attachments/store.js +540 -468
  237. package/build/src/database/record/index.d.ts +23 -15
  238. package/build/src/database/record/index.d.ts.map +1 -1
  239. package/build/src/database/record/index.js +3894 -3350
  240. package/build/src/database/record/instance-relationships/base.js +268 -234
  241. package/build/src/database/record/instance-relationships/belongs-to.js +73 -58
  242. package/build/src/database/record/instance-relationships/has-many.js +264 -225
  243. package/build/src/database/record/instance-relationships/has-one.js +105 -85
  244. package/build/src/database/record/record-not-found-error.js +2 -3
  245. package/build/src/database/record/relationships/base.d.ts +2 -2
  246. package/build/src/database/record/relationships/base.d.ts.map +1 -1
  247. package/build/src/database/record/relationships/base.js +167 -145
  248. package/build/src/database/record/relationships/belongs-to.js +51 -44
  249. package/build/src/database/record/relationships/has-many.js +40 -32
  250. package/build/src/database/record/relationships/has-one.js +40 -32
  251. package/build/src/database/record/state-machine.js +208 -156
  252. package/build/src/database/record/user-module.js +38 -32
  253. package/build/src/database/record/validators/base.js +24 -22
  254. package/build/src/database/record/validators/format.js +46 -36
  255. package/build/src/database/record/validators/presence.js +20 -18
  256. package/build/src/database/record/validators/uniqueness.js +117 -99
  257. package/build/src/database/table-data/index.js +231 -199
  258. package/build/src/database/table-data/table-column.js +382 -338
  259. package/build/src/database/table-data/table-foreign-key.js +66 -57
  260. package/build/src/database/table-data/table-index.js +36 -29
  261. package/build/src/database/table-data/table-reference.js +10 -10
  262. package/build/src/database/use-database.js +40 -32
  263. package/build/src/environment-handlers/base.js +544 -484
  264. package/build/src/environment-handlers/browser.js +294 -241
  265. package/build/src/environment-handlers/node/cli/commands/background-jobs-main.js +19 -16
  266. package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +21 -18
  267. package/build/src/environment-handlers/node/cli/commands/background-jobs-worker.js +29 -22
  268. package/build/src/environment-handlers/node/cli/commands/beacon.js +19 -16
  269. package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +15 -14
  270. package/build/src/environment-handlers/node/cli/commands/console.js +120 -99
  271. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +39 -34
  272. package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +63 -57
  273. package/build/src/environment-handlers/node/cli/commands/db/seed.js +63 -51
  274. package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +40 -32
  275. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  276. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +353 -298
  277. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +844 -729
  278. package/build/src/environment-handlers/node/cli/commands/generate/migration.js +38 -34
  279. package/build/src/environment-handlers/node/cli/commands/generate/model.js +38 -34
  280. package/build/src/environment-handlers/node/cli/commands/init.js +61 -56
  281. package/build/src/environment-handlers/node/cli/commands/routes.js +59 -51
  282. package/build/src/environment-handlers/node/cli/commands/run-script.js +68 -54
  283. package/build/src/environment-handlers/node/cli/commands/runner.js +74 -56
  284. package/build/src/environment-handlers/node/cli/commands/server.js +106 -93
  285. package/build/src/environment-handlers/node/cli/commands/test.js +113 -97
  286. package/build/src/environment-handlers/node.js +874 -753
  287. package/build/src/error-logger.js +21 -22
  288. package/build/src/frontend-model-controller.d.ts +6 -6
  289. package/build/src/frontend-model-controller.d.ts.map +1 -1
  290. package/build/src/frontend-model-controller.js +3288 -2788
  291. package/build/src/frontend-model-resource/base-resource.d.ts +18 -17
  292. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  293. package/build/src/frontend-model-resource/base-resource.js +869 -759
  294. package/build/src/frontend-models/base.d.ts +19 -12
  295. package/build/src/frontend-models/base.d.ts.map +1 -1
  296. package/build/src/frontend-models/base.js +3602 -3114
  297. package/build/src/frontend-models/clear-pending-debounced-callback.js +8 -7
  298. package/build/src/frontend-models/event-hook-models.js +21 -16
  299. package/build/src/frontend-models/model-registry.js +11 -9
  300. package/build/src/frontend-models/outgoing-event-buffer.js +17 -10
  301. package/build/src/frontend-models/preloader.d.ts +6 -6
  302. package/build/src/frontend-models/preloader.d.ts.map +1 -1
  303. package/build/src/frontend-models/preloader.js +149 -131
  304. package/build/src/frontend-models/query.d.ts.map +1 -1
  305. package/build/src/frontend-models/query.js +1855 -1560
  306. package/build/src/frontend-models/resource-config-validation.js +37 -27
  307. package/build/src/frontend-models/resource-definition.js +288 -234
  308. package/build/src/frontend-models/transport-serialization.js +266 -203
  309. package/build/src/frontend-models/use-created-event.js +7 -5
  310. package/build/src/frontend-models/use-destroyed-event.js +93 -80
  311. package/build/src/frontend-models/use-model-class-event.js +91 -79
  312. package/build/src/frontend-models/use-updated-event.js +97 -84
  313. package/build/src/frontend-models/websocket-channel.js +441 -381
  314. package/build/src/frontend-models/websocket-publishers.js +173 -140
  315. package/build/src/http-client/header.js +14 -13
  316. package/build/src/http-client/index.js +132 -116
  317. package/build/src/http-client/request.js +87 -71
  318. package/build/src/http-client/response.js +140 -122
  319. package/build/src/http-client/websocket-client.js +17 -15
  320. package/build/src/http-server/client/index.js +465 -409
  321. package/build/src/http-server/client/params-to-object.js +135 -124
  322. package/build/src/http-server/client/request-buffer/form-data-part.js +132 -111
  323. package/build/src/http-server/client/request-buffer/header.js +16 -15
  324. package/build/src/http-server/client/request-buffer/index.js +506 -446
  325. package/build/src/http-server/client/request-parser.js +186 -163
  326. package/build/src/http-server/client/request-runner.js +259 -226
  327. package/build/src/http-server/client/request-timing.js +151 -132
  328. package/build/src/http-server/client/request.js +108 -96
  329. package/build/src/http-server/client/response.js +235 -213
  330. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +29 -25
  331. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +29 -25
  332. package/build/src/http-server/client/uploaded-file/uploaded-file.js +33 -33
  333. package/build/src/http-server/client/websocket-request.js +137 -114
  334. package/build/src/http-server/client/websocket-session.js +1657 -1452
  335. package/build/src/http-server/cookie.js +236 -216
  336. package/build/src/http-server/development-reloader.js +221 -190
  337. package/build/src/http-server/index.js +525 -451
  338. package/build/src/http-server/remote-address.js +50 -38
  339. package/build/src/http-server/server-client.js +208 -181
  340. package/build/src/http-server/server-lock.js +167 -153
  341. package/build/src/http-server/websocket-channel-subscribers.js +93 -81
  342. package/build/src/http-server/websocket-channel.js +117 -104
  343. package/build/src/http-server/websocket-connection.js +104 -96
  344. package/build/src/http-server/websocket-event-log-store.js +404 -350
  345. package/build/src/http-server/websocket-events-host.js +164 -145
  346. package/build/src/http-server/websocket-events.js +47 -47
  347. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +14 -13
  348. package/build/src/http-server/worker-handler/in-process.js +141 -123
  349. package/build/src/http-server/worker-handler/index.js +349 -313
  350. package/build/src/http-server/worker-handler/worker-script.js +5 -4
  351. package/build/src/http-server/worker-handler/worker-thread.js +269 -240
  352. package/build/src/initializer.js +36 -31
  353. package/build/src/jobs/mail-delivery.js +15 -13
  354. package/build/src/logger/base-logger.js +26 -24
  355. package/build/src/logger/console-logger.js +23 -21
  356. package/build/src/logger/file-logger.js +31 -29
  357. package/build/src/logger/outputs/array-output.js +42 -37
  358. package/build/src/logger/outputs/console-output.js +24 -20
  359. package/build/src/logger/outputs/file-output.js +48 -43
  360. package/build/src/logger/outputs/stdout-output.js +48 -39
  361. package/build/src/logger.js +394 -338
  362. package/build/src/mailer/backends/smtp.js +163 -134
  363. package/build/src/mailer/base.js +251 -211
  364. package/build/src/mailer/delivery.js +64 -56
  365. package/build/src/mailer/index.js +22 -4
  366. package/build/src/mailer.js +13 -4
  367. package/build/src/plugins/sqljs-wasm-route-controller.js +52 -42
  368. package/build/src/plugins/sqljs-wasm-route.js +38 -28
  369. package/build/src/record-payload-values.js +28 -25
  370. package/build/src/routes/app-routes.js +14 -12
  371. package/build/src/routes/base-route.js +130 -112
  372. package/build/src/routes/basic-route.js +102 -83
  373. package/build/src/routes/built-in/debug/controller.js +10 -10
  374. package/build/src/routes/built-in/errors/controller.js +5 -5
  375. package/build/src/routes/get-route.js +63 -50
  376. package/build/src/routes/hooks/frontend-model-command-route-hook.js +80 -66
  377. package/build/src/routes/index.js +43 -36
  378. package/build/src/routes/namespace-route.js +47 -38
  379. package/build/src/routes/plugin-routes.js +124 -107
  380. package/build/src/routes/post-route.js +62 -51
  381. package/build/src/routes/resolver.js +494 -422
  382. package/build/src/routes/resource-route.js +143 -124
  383. package/build/src/routes/root-route.js +8 -7
  384. package/build/src/testing/base-expect.js +14 -13
  385. package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +405 -329
  386. package/build/src/testing/browser-test-app.js +29 -23
  387. package/build/src/testing/expect-to-change.js +50 -41
  388. package/build/src/testing/expect-utils.js +184 -139
  389. package/build/src/testing/expect.js +731 -638
  390. package/build/src/testing/request-client.js +85 -70
  391. package/build/src/testing/test-files-finder.js +339 -285
  392. package/build/src/testing/test-filter-parser.js +155 -124
  393. package/build/src/testing/test-runner.js +1020 -883
  394. package/build/src/testing/test-suite-splitter.js +142 -114
  395. package/build/src/testing/test.js +256 -216
  396. package/build/src/utils/backtrace-cleaner-node.js +69 -62
  397. package/build/src/utils/backtrace-cleaner.js +216 -188
  398. package/build/src/utils/ensure-error.js +7 -7
  399. package/build/src/utils/event-emitter.js +6 -4
  400. package/build/src/utils/file-exists.js +10 -9
  401. package/build/src/utils/format-value.js +76 -67
  402. package/build/src/utils/model-scope.js +31 -27
  403. package/build/src/utils/nest-callbacks.js +13 -10
  404. package/build/src/utils/plain-object.js +6 -5
  405. package/build/src/utils/ransack.d.ts.map +1 -1
  406. package/build/src/utils/ransack.js +563 -449
  407. package/build/src/utils/rest-args-error.js +6 -5
  408. package/build/src/utils/singularize-model-name.js +11 -9
  409. package/build/src/utils/split-sql-statements.js +79 -68
  410. package/build/src/utils/to-import-specifier.js +30 -24
  411. package/build/src/utils/with-tracked-stack-async-hooks.js +74 -60
  412. package/build/src/utils/with-tracked-stack.js +18 -14
  413. package/build/src/velocious-error.js +30 -27
  414. package/index.js +1 -0
  415. package/package.json +10 -4
  416. package/scripts/clean-build.js +8 -0
  417. package/scripts/ensure-bin-executable.js +13 -0
  418. package/scripts/run-tests.js +37 -0
  419. package/scripts/test-browser.js +486 -0
  420. package/src/application.js +229 -0
  421. package/src/authorization/ability.js +329 -0
  422. package/src/authorization/base-resource.js +143 -0
  423. package/src/background-jobs/client.js +50 -0
  424. package/src/background-jobs/cron-expression.js +277 -0
  425. package/src/background-jobs/forked-runner-child.js +86 -0
  426. package/src/background-jobs/job-record.js +13 -0
  427. package/src/background-jobs/job-registry.js +92 -0
  428. package/src/background-jobs/job-runner.js +107 -0
  429. package/src/background-jobs/job.js +77 -0
  430. package/src/background-jobs/json-socket.js +78 -0
  431. package/src/background-jobs/main.js +926 -0
  432. package/src/background-jobs/normalize-error.js +26 -0
  433. package/src/background-jobs/scheduler.js +274 -0
  434. package/src/background-jobs/socket-request.js +68 -0
  435. package/src/background-jobs/status-reporter.js +101 -0
  436. package/src/background-jobs/store.js +994 -0
  437. package/src/background-jobs/types.js +70 -0
  438. package/src/background-jobs/web/authorization.js +89 -0
  439. package/src/background-jobs/web/controller.js +280 -0
  440. package/src/background-jobs/web/index.js +57 -0
  441. package/src/background-jobs/web/path-matcher.js +74 -0
  442. package/src/background-jobs/web/registry.js +49 -0
  443. package/src/background-jobs/worker.js +683 -0
  444. package/src/beacon/client.js +330 -0
  445. package/src/beacon/in-process-broker.js +71 -0
  446. package/src/beacon/in-process-client.js +139 -0
  447. package/src/beacon/server.js +148 -0
  448. package/src/beacon/types.js +55 -0
  449. package/src/cli/base-command.js +67 -0
  450. package/src/cli/browser-cli.js +45 -0
  451. package/src/cli/commands/background-jobs-main.js +7 -0
  452. package/src/cli/commands/background-jobs-runner.js +7 -0
  453. package/src/cli/commands/background-jobs-worker.js +7 -0
  454. package/src/cli/commands/beacon.js +7 -0
  455. package/src/cli/commands/console.js +12 -0
  456. package/src/cli/commands/db/base-command.js +82 -0
  457. package/src/cli/commands/db/create.js +64 -0
  458. package/src/cli/commands/db/drop.js +75 -0
  459. package/src/cli/commands/db/migrate.js +17 -0
  460. package/src/cli/commands/db/reset.js +22 -0
  461. package/src/cli/commands/db/rollback.js +15 -0
  462. package/src/cli/commands/db/schema/dump.js +12 -0
  463. package/src/cli/commands/db/schema/load.js +12 -0
  464. package/src/cli/commands/db/seed.js +12 -0
  465. package/src/cli/commands/db/tenants/check.js +38 -0
  466. package/src/cli/commands/db/tenants/create.js +33 -0
  467. package/src/cli/commands/db/tenants/migrate.js +49 -0
  468. package/src/cli/commands/destroy/migration.js +7 -0
  469. package/src/cli/commands/generate/base-models.js +7 -0
  470. package/src/cli/commands/generate/frontend-models.js +12 -0
  471. package/src/cli/commands/generate/migration.js +7 -0
  472. package/src/cli/commands/generate/model.js +7 -0
  473. package/src/cli/commands/init.js +11 -0
  474. package/src/cli/commands/routes.js +7 -0
  475. package/src/cli/commands/run-script.js +12 -0
  476. package/src/cli/commands/runner.js +12 -0
  477. package/src/cli/commands/server.js +7 -0
  478. package/src/cli/commands/test.js +9 -0
  479. package/src/cli/index.js +152 -0
  480. package/src/cli/tenant-database-command-helper.js +198 -0
  481. package/src/cli/use-browser-cli.js +30 -0
  482. package/src/configuration-resolver.js +65 -0
  483. package/src/configuration-types.js +429 -0
  484. package/src/configuration.js +2590 -0
  485. package/src/controller.js +421 -0
  486. package/src/current-configuration.js +31 -0
  487. package/src/current.js +80 -0
  488. package/src/database/annotations-async-hooks.js +47 -0
  489. package/src/database/annotations.js +40 -0
  490. package/src/database/drivers/base-column.js +182 -0
  491. package/src/database/drivers/base-columns-index.js +81 -0
  492. package/src/database/drivers/base-foreign-key.js +104 -0
  493. package/src/database/drivers/base-table.js +156 -0
  494. package/src/database/drivers/base.js +1609 -0
  495. package/src/database/drivers/mssql/column.js +74 -0
  496. package/src/database/drivers/mssql/columns-index.js +6 -0
  497. package/src/database/drivers/mssql/connect-connection.js +16 -0
  498. package/src/database/drivers/mssql/foreign-key.js +12 -0
  499. package/src/database/drivers/mssql/index.js +590 -0
  500. package/src/database/drivers/mssql/options.js +79 -0
  501. package/src/database/drivers/mssql/query-parser.js +6 -0
  502. package/src/database/drivers/mssql/sql/alter-table.js +4 -0
  503. package/src/database/drivers/mssql/sql/create-database.js +36 -0
  504. package/src/database/drivers/mssql/sql/create-index.js +4 -0
  505. package/src/database/drivers/mssql/sql/create-table.js +4 -0
  506. package/src/database/drivers/mssql/sql/delete.js +19 -0
  507. package/src/database/drivers/mssql/sql/drop-database.js +36 -0
  508. package/src/database/drivers/mssql/sql/drop-table.js +4 -0
  509. package/src/database/drivers/mssql/sql/insert.js +4 -0
  510. package/src/database/drivers/mssql/sql/update.js +31 -0
  511. package/src/database/drivers/mssql/sql/upsert.js +23 -0
  512. package/src/database/drivers/mssql/structure-sql.js +120 -0
  513. package/src/database/drivers/mssql/table.js +145 -0
  514. package/src/database/drivers/mysql/column.js +112 -0
  515. package/src/database/drivers/mysql/columns-index.js +22 -0
  516. package/src/database/drivers/mysql/foreign-key.js +12 -0
  517. package/src/database/drivers/mysql/index.js +473 -0
  518. package/src/database/drivers/mysql/options.js +34 -0
  519. package/src/database/drivers/mysql/query-parser.js +6 -0
  520. package/src/database/drivers/mysql/query.js +37 -0
  521. package/src/database/drivers/mysql/sql/alter-table.js +6 -0
  522. package/src/database/drivers/mysql/sql/create-database.js +39 -0
  523. package/src/database/drivers/mysql/sql/create-index.js +6 -0
  524. package/src/database/drivers/mysql/sql/create-table.js +6 -0
  525. package/src/database/drivers/mysql/sql/delete.js +21 -0
  526. package/src/database/drivers/mysql/sql/drop-database.js +6 -0
  527. package/src/database/drivers/mysql/sql/drop-table.js +6 -0
  528. package/src/database/drivers/mysql/sql/insert.js +6 -0
  529. package/src/database/drivers/mysql/sql/update.js +33 -0
  530. package/src/database/drivers/mysql/sql/upsert.js +13 -0
  531. package/src/database/drivers/mysql/structure-sql.js +93 -0
  532. package/src/database/drivers/mysql/table.js +121 -0
  533. package/src/database/drivers/pgsql/column.js +90 -0
  534. package/src/database/drivers/pgsql/columns-index.js +6 -0
  535. package/src/database/drivers/pgsql/foreign-key.js +12 -0
  536. package/src/database/drivers/pgsql/index.js +441 -0
  537. package/src/database/drivers/pgsql/options.js +32 -0
  538. package/src/database/drivers/pgsql/query-parser.js +6 -0
  539. package/src/database/drivers/pgsql/sql/alter-table.js +6 -0
  540. package/src/database/drivers/pgsql/sql/create-database.js +38 -0
  541. package/src/database/drivers/pgsql/sql/create-index.js +6 -0
  542. package/src/database/drivers/pgsql/sql/create-table.js +6 -0
  543. package/src/database/drivers/pgsql/sql/delete.js +21 -0
  544. package/src/database/drivers/pgsql/sql/drop-database.js +6 -0
  545. package/src/database/drivers/pgsql/sql/drop-table.js +6 -0
  546. package/src/database/drivers/pgsql/sql/insert.js +6 -0
  547. package/src/database/drivers/pgsql/sql/update.js +33 -0
  548. package/src/database/drivers/pgsql/sql/upsert.js +14 -0
  549. package/src/database/drivers/pgsql/structure-sql.js +126 -0
  550. package/src/database/drivers/pgsql/table.js +135 -0
  551. package/src/database/drivers/sqlite/base.js +509 -0
  552. package/src/database/drivers/sqlite/column.js +75 -0
  553. package/src/database/drivers/sqlite/columns-index.js +30 -0
  554. package/src/database/drivers/sqlite/connection-sql-js.js +46 -0
  555. package/src/database/drivers/sqlite/foreign-key.js +24 -0
  556. package/src/database/drivers/sqlite/index.js +394 -0
  557. package/src/database/drivers/sqlite/index.native.js +72 -0
  558. package/src/database/drivers/sqlite/index.web.js +99 -0
  559. package/src/database/drivers/sqlite/options.js +32 -0
  560. package/src/database/drivers/sqlite/query-parser.js +6 -0
  561. package/src/database/drivers/sqlite/query.js +35 -0
  562. package/src/database/drivers/sqlite/query.native.js +35 -0
  563. package/src/database/drivers/sqlite/query.web.js +49 -0
  564. package/src/database/drivers/sqlite/sql/alter-table.js +187 -0
  565. package/src/database/drivers/sqlite/sql/create-index.js +6 -0
  566. package/src/database/drivers/sqlite/sql/create-table.js +6 -0
  567. package/src/database/drivers/sqlite/sql/delete.js +26 -0
  568. package/src/database/drivers/sqlite/sql/drop-table.js +6 -0
  569. package/src/database/drivers/sqlite/sql/insert.js +6 -0
  570. package/src/database/drivers/sqlite/sql/update.js +33 -0
  571. package/src/database/drivers/sqlite/sql/upsert.js +14 -0
  572. package/src/database/drivers/sqlite/structure-sql.js +56 -0
  573. package/src/database/drivers/sqlite/table-rebuilder.js +96 -0
  574. package/src/database/drivers/sqlite/table.js +131 -0
  575. package/src/database/drivers/structure-sql/utils.js +35 -0
  576. package/src/database/handler.js +13 -0
  577. package/src/database/initializer-from-require-context.js +101 -0
  578. package/src/database/migration/index.js +438 -0
  579. package/src/database/migrator/files-finder.js +55 -0
  580. package/src/database/migrator/types.js +31 -0
  581. package/src/database/migrator.js +557 -0
  582. package/src/database/pool/async-tracked-multi-connection.js +1164 -0
  583. package/src/database/pool/base-methods-forward.js +52 -0
  584. package/src/database/pool/base.js +380 -0
  585. package/src/database/pool/single-multi-use.js +118 -0
  586. package/src/database/query/alter-table-base.js +104 -0
  587. package/src/database/query/base.js +49 -0
  588. package/src/database/query/create-database-base.js +42 -0
  589. package/src/database/query/create-index-base.js +117 -0
  590. package/src/database/query/create-table-base.js +205 -0
  591. package/src/database/query/delete-base.js +19 -0
  592. package/src/database/query/drop-database-base.js +38 -0
  593. package/src/database/query/drop-table-base.js +58 -0
  594. package/src/database/query/from-base.js +36 -0
  595. package/src/database/query/from-plain.js +16 -0
  596. package/src/database/query/from-table.js +18 -0
  597. package/src/database/query/index.js +533 -0
  598. package/src/database/query/insert-base.js +172 -0
  599. package/src/database/query/join-base.js +43 -0
  600. package/src/database/query/join-object.js +167 -0
  601. package/src/database/query/join-plain.js +18 -0
  602. package/src/database/query/join-tracker.js +93 -0
  603. package/src/database/query/model-class-query.js +1577 -0
  604. package/src/database/query/order-base.js +33 -0
  605. package/src/database/query/order-column.js +77 -0
  606. package/src/database/query/order-plain.js +28 -0
  607. package/src/database/query/preloader/belongs-to.js +267 -0
  608. package/src/database/query/preloader/ensure-model-class-initialized.js +18 -0
  609. package/src/database/query/preloader/has-many.js +316 -0
  610. package/src/database/query/preloader/has-one.js +123 -0
  611. package/src/database/query/preloader/selection.js +152 -0
  612. package/src/database/query/preloader.js +201 -0
  613. package/src/database/query/query-data.js +305 -0
  614. package/src/database/query/select-base.js +30 -0
  615. package/src/database/query/select-plain.js +18 -0
  616. package/src/database/query/select-table-and-column.js +28 -0
  617. package/src/database/query/update-base.js +41 -0
  618. package/src/database/query/upsert-base.js +103 -0
  619. package/src/database/query/where-base.js +38 -0
  620. package/src/database/query/where-combinator.js +31 -0
  621. package/src/database/query/where-hash.js +77 -0
  622. package/src/database/query/where-model-class-hash.js +505 -0
  623. package/src/database/query/where-not.js +23 -0
  624. package/src/database/query/where-plain.js +20 -0
  625. package/src/database/query/with-count.js +219 -0
  626. package/src/database/query-parser/base-query-parser.js +40 -0
  627. package/src/database/query-parser/from-parser.js +49 -0
  628. package/src/database/query-parser/group-parser.js +55 -0
  629. package/src/database/query-parser/joins-parser.js +37 -0
  630. package/src/database/query-parser/limit-parser.js +77 -0
  631. package/src/database/query-parser/options.js +94 -0
  632. package/src/database/query-parser/order-parser.js +45 -0
  633. package/src/database/query-parser/select-parser.js +67 -0
  634. package/src/database/query-parser/where-parser.js +46 -0
  635. package/src/database/record/acts-as-list.js +374 -0
  636. package/src/database/record/attachments/download.js +49 -0
  637. package/src/database/record/attachments/handle.js +188 -0
  638. package/src/database/record/attachments/normalize-input.js +213 -0
  639. package/src/database/record/attachments/storage-drivers/filesystem.js +114 -0
  640. package/src/database/record/attachments/storage-drivers/native.js +146 -0
  641. package/src/database/record/attachments/storage-drivers/s3.js +245 -0
  642. package/src/database/record/attachments/store.js +591 -0
  643. package/src/database/record/index.js +3970 -0
  644. package/src/database/record/instance-relationships/base.js +289 -0
  645. package/src/database/record/instance-relationships/belongs-to.js +84 -0
  646. package/src/database/record/instance-relationships/has-many.js +284 -0
  647. package/src/database/record/instance-relationships/has-one.js +117 -0
  648. package/src/database/record/record-not-found-error.js +3 -0
  649. package/src/database/record/relationships/base.js +195 -0
  650. package/src/database/record/relationships/belongs-to.js +57 -0
  651. package/src/database/record/relationships/has-many.js +46 -0
  652. package/src/database/record/relationships/has-one.js +46 -0
  653. package/src/database/record/state-machine.js +278 -0
  654. package/src/database/record/user-module.js +43 -0
  655. package/src/database/record/validators/base.js +27 -0
  656. package/src/database/record/validators/format.js +50 -0
  657. package/src/database/record/validators/presence.js +24 -0
  658. package/src/database/record/validators/uniqueness.js +124 -0
  659. package/src/database/table-data/index.js +241 -0
  660. package/src/database/table-data/table-column.js +416 -0
  661. package/src/database/table-data/table-foreign-key.js +69 -0
  662. package/src/database/table-data/table-index.js +46 -0
  663. package/src/database/table-data/table-reference.js +13 -0
  664. package/src/database/use-database.js +48 -0
  665. package/src/environment-handlers/base.js +561 -0
  666. package/src/environment-handlers/browser.js +338 -0
  667. package/src/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
  668. package/src/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
  669. package/src/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
  670. package/src/environment-handlers/node/cli/commands/beacon.js +21 -0
  671. package/src/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
  672. package/src/environment-handlers/node/cli/commands/console.js +149 -0
  673. package/src/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
  674. package/src/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
  675. package/src/environment-handlers/node/cli/commands/db/seed.js +79 -0
  676. package/src/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
  677. package/src/environment-handlers/node/cli/commands/generate/base-models.js +367 -0
  678. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
  679. package/src/environment-handlers/node/cli/commands/generate/migration.js +45 -0
  680. package/src/environment-handlers/node/cli/commands/generate/model.js +45 -0
  681. package/src/environment-handlers/node/cli/commands/init.js +68 -0
  682. package/src/environment-handlers/node/cli/commands/routes.js +63 -0
  683. package/src/environment-handlers/node/cli/commands/run-script.js +85 -0
  684. package/src/environment-handlers/node/cli/commands/runner.js +84 -0
  685. package/src/environment-handlers/node/cli/commands/server.js +151 -0
  686. package/src/environment-handlers/node/cli/commands/test.js +118 -0
  687. package/src/environment-handlers/node.js +887 -0
  688. package/src/error-logger.js +30 -0
  689. package/src/frontend-model-controller.js +3491 -0
  690. package/src/frontend-model-resource/base-resource.js +935 -0
  691. package/src/frontend-models/base.js +4004 -0
  692. package/src/frontend-models/clear-pending-debounced-callback.js +16 -0
  693. package/src/frontend-models/event-hook-models.js +49 -0
  694. package/src/frontend-models/model-registry.js +28 -0
  695. package/src/frontend-models/outgoing-event-buffer.js +51 -0
  696. package/src/frontend-models/preloader.js +169 -0
  697. package/src/frontend-models/query.js +2245 -0
  698. package/src/frontend-models/resource-config-validation.js +56 -0
  699. package/src/frontend-models/resource-definition.js +399 -0
  700. package/src/frontend-models/transport-serialization.js +369 -0
  701. package/src/frontend-models/use-created-event.js +21 -0
  702. package/src/frontend-models/use-destroyed-event.js +148 -0
  703. package/src/frontend-models/use-model-class-event.js +164 -0
  704. package/src/frontend-models/use-updated-event.js +152 -0
  705. package/src/frontend-models/websocket-channel.js +494 -0
  706. package/src/frontend-models/websocket-publishers.js +224 -0
  707. package/src/http-client/header.js +17 -0
  708. package/src/http-client/index.js +139 -0
  709. package/src/http-client/request.js +94 -0
  710. package/src/http-client/response.js +151 -0
  711. package/src/http-client/websocket-client.js +27 -0
  712. package/src/http-server/client/index.js +507 -0
  713. package/src/http-server/client/params-to-object.js +152 -0
  714. package/src/http-server/client/request-buffer/form-data-part.js +139 -0
  715. package/src/http-server/client/request-buffer/header.js +19 -0
  716. package/src/http-server/client/request-buffer/index.js +535 -0
  717. package/src/http-server/client/request-parser.js +195 -0
  718. package/src/http-server/client/request-runner.js +321 -0
  719. package/src/http-server/client/request-timing.js +171 -0
  720. package/src/http-server/client/request.js +114 -0
  721. package/src/http-server/client/response.js +251 -0
  722. package/src/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
  723. package/src/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
  724. package/src/http-server/client/uploaded-file/uploaded-file.js +36 -0
  725. package/src/http-server/client/websocket-request.js +147 -0
  726. package/src/http-server/client/websocket-session.js +1755 -0
  727. package/src/http-server/cookie.js +245 -0
  728. package/src/http-server/development-reloader.js +240 -0
  729. package/src/http-server/index.js +561 -0
  730. package/src/http-server/remote-address.js +77 -0
  731. package/src/http-server/server-client.js +222 -0
  732. package/src/http-server/server-lock.js +178 -0
  733. package/src/http-server/websocket-channel-subscribers.js +110 -0
  734. package/src/http-server/websocket-channel.js +137 -0
  735. package/src/http-server/websocket-connection.js +118 -0
  736. package/src/http-server/websocket-event-log-store.js +433 -0
  737. package/src/http-server/websocket-events-host.js +170 -0
  738. package/src/http-server/websocket-events.js +50 -0
  739. package/src/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
  740. package/src/http-server/worker-handler/in-process.js +155 -0
  741. package/src/http-server/worker-handler/index.js +370 -0
  742. package/src/http-server/worker-handler/worker-script.js +6 -0
  743. package/src/http-server/worker-handler/worker-thread.js +286 -0
  744. package/src/initializer.js +39 -0
  745. package/src/jobs/.gitkeep +1 -0
  746. package/src/jobs/mail-delivery.js +22 -0
  747. package/src/logger/base-logger.js +34 -0
  748. package/src/logger/console-logger.js +28 -0
  749. package/src/logger/file-logger.js +36 -0
  750. package/src/logger/outputs/array-output.js +50 -0
  751. package/src/logger/outputs/console-output.js +32 -0
  752. package/src/logger/outputs/file-output.js +55 -0
  753. package/src/logger/outputs/stdout-output.js +64 -0
  754. package/src/logger.js +507 -0
  755. package/src/mailer/backends/smtp.js +197 -0
  756. package/src/mailer/base.js +337 -0
  757. package/src/mailer/delivery.js +70 -0
  758. package/src/mailer/index.js +24 -0
  759. package/src/mailer.js +15 -0
  760. package/src/plugins/sqljs-wasm-route-controller.js +70 -0
  761. package/src/plugins/sqljs-wasm-route.js +71 -0
  762. package/src/record-payload-values.js +83 -0
  763. package/src/routes/app-routes.js +17 -0
  764. package/src/routes/base-route.js +133 -0
  765. package/src/routes/basic-route.js +109 -0
  766. package/src/routes/built-in/debug/controller.js +12 -0
  767. package/src/routes/built-in/errors/controller.js +7 -0
  768. package/src/routes/built-in/errors/not-found.ejs +1 -0
  769. package/src/routes/get-route.js +75 -0
  770. package/src/routes/hooks/frontend-model-command-route-hook.js +100 -0
  771. package/src/routes/index.js +50 -0
  772. package/src/routes/namespace-route.js +51 -0
  773. package/src/routes/plugin-routes.js +141 -0
  774. package/src/routes/post-route.js +74 -0
  775. package/src/routes/resolver.js +535 -0
  776. package/src/routes/resource-route.js +154 -0
  777. package/src/routes/root-route.js +11 -0
  778. package/src/templates/configuration.js +61 -0
  779. package/src/templates/generate-migration.js +11 -0
  780. package/src/templates/generate-model.js +6 -0
  781. package/src/templates/routes.js +11 -0
  782. package/src/testing/base-expect.js +17 -0
  783. package/src/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
  784. package/src/testing/browser-test-app.js +32 -0
  785. package/src/testing/expect-to-change.js +55 -0
  786. package/src/testing/expect-utils.js +269 -0
  787. package/src/testing/expect.js +763 -0
  788. package/src/testing/request-client.js +90 -0
  789. package/src/testing/test-files-finder.js +364 -0
  790. package/src/testing/test-filter-parser.js +198 -0
  791. package/src/testing/test-runner.js +1168 -0
  792. package/src/testing/test-suite-splitter.js +177 -0
  793. package/src/testing/test.js +370 -0
  794. package/src/types/external-modules.d.ts +57 -0
  795. package/src/utils/backtrace-cleaner-node.js +87 -0
  796. package/src/utils/backtrace-cleaner.js +266 -0
  797. package/src/utils/ensure-error.js +15 -0
  798. package/src/utils/event-emitter.js +8 -0
  799. package/src/utils/file-exists.js +18 -0
  800. package/src/utils/format-value.js +101 -0
  801. package/src/utils/model-scope.js +56 -0
  802. package/src/utils/nest-callbacks.js +22 -0
  803. package/src/utils/plain-object.js +14 -0
  804. package/src/utils/ransack.js +859 -0
  805. package/src/utils/rest-args-error.js +14 -0
  806. package/src/utils/singularize-model-name.js +18 -0
  807. package/src/utils/split-sql-statements.js +88 -0
  808. package/src/utils/to-import-specifier.js +53 -0
  809. package/src/utils/with-tracked-stack-async-hooks.js +103 -0
  810. package/src/utils/with-tracked-stack.js +38 -0
  811. package/src/velocious-error.js +34 -0
  812. package/tsconfig.json +16 -0
@@ -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
+ }