velocious 1.0.85 → 1.0.87

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 (95) hide show
  1. package/bin/velocious.js +10 -1
  2. package/eslint.config.js +33 -0
  3. package/package.json +7 -2
  4. package/peak_flow.yml +6 -0
  5. package/spec/cli/commands/db/create-spec.js +4 -0
  6. package/spec/cli/commands/db/migrate-spec.js +4 -2
  7. package/spec/cli/commands/db/rollback-spec.js +179 -0
  8. package/spec/cli/commands/destroy/migration-spec.js +4 -0
  9. package/spec/cli/commands/generate/migration-spec.js +4 -0
  10. package/spec/cli/commands/init-spec.js +4 -0
  11. package/spec/dummy/index.js +7 -4
  12. package/spec/dummy/src/config/configuration.example.js +2 -0
  13. package/spec/dummy/src/config/configuration.peakflow.mariadb.js +2 -0
  14. package/spec/dummy/src/config/configuration.peakflow.mssql.js +2 -0
  15. package/spec/dummy/src/config/configuration.peakflow.pgsql.js +2 -0
  16. package/spec/dummy/src/config/configuration.peakflow.sqlite.js +2 -0
  17. package/spec/dummy/src/database/migrations/20250921121002-create-project-details.js +3 -1
  18. package/src/application.js +12 -0
  19. package/src/cli/base-command.js +9 -5
  20. package/src/cli/browser-cli.js +37 -0
  21. package/src/cli/commands/db/create.js +5 -5
  22. package/src/cli/commands/db/drop.js +4 -5
  23. package/src/cli/commands/db/migrate.js +6 -10
  24. package/src/cli/commands/db/reset.js +8 -12
  25. package/src/cli/commands/db/rollback.js +15 -0
  26. package/src/cli/commands/destroy/migration.js +2 -2
  27. package/src/cli/commands/generate/migration.js +3 -6
  28. package/src/cli/commands/generate/model.js +3 -6
  29. package/src/cli/commands/init.js +5 -8
  30. package/src/cli/commands/server.js +3 -3
  31. package/src/cli/commands/test.js +1 -1
  32. package/src/cli/index.js +15 -63
  33. package/src/cli/use-browser-cli.js +25 -0
  34. package/src/configuration-resolver.js +1 -1
  35. package/src/configuration.js +118 -9
  36. package/src/controller.js +29 -0
  37. package/src/database/drivers/base-column.js +14 -0
  38. package/src/database/drivers/base-columns-index.js +3 -0
  39. package/src/database/drivers/base-foreign-key.js +3 -0
  40. package/src/database/drivers/base-table.js +3 -0
  41. package/src/database/drivers/base.js +55 -1
  42. package/src/database/drivers/mssql/index.js +64 -1
  43. package/src/database/drivers/mysql/columns-index.js +0 -1
  44. package/src/database/drivers/sqlite/base.js +39 -0
  45. package/src/database/drivers/sqlite/connection-remote.js +1 -1
  46. package/src/database/drivers/sqlite/sql/alter-table.js +1 -1
  47. package/src/database/drivers/sqlite/sql/delete.js +15 -10
  48. package/src/database/migration/index.js +122 -1
  49. package/src/database/migrator/files-finder.js +13 -1
  50. package/src/database/migrator.js +125 -24
  51. package/src/database/pool/single-multi-use.js +1 -1
  52. package/src/database/query/alter-table-base.js +11 -0
  53. package/src/database/query/base.js +7 -0
  54. package/src/database/query/create-database-base.js +3 -0
  55. package/src/database/query/create-index-base.js +3 -1
  56. package/src/database/query/create-table-base.js +3 -0
  57. package/src/database/query/drop-table-base.js +4 -1
  58. package/src/database/query/from-base.js +7 -0
  59. package/src/database/query/index.js +96 -6
  60. package/src/database/query/insert-base.js +6 -0
  61. package/src/database/query/join-base.js +3 -0
  62. package/src/database/query/order-base.js +3 -0
  63. package/src/database/query/select-base.js +3 -0
  64. package/src/database/query/update-base.js +3 -0
  65. package/src/database/query/where-base.js +3 -0
  66. package/src/database/record/index.js +272 -19
  67. package/src/database/record/instance-relationships/base.js +66 -1
  68. package/src/database/record/relationships/base.js +41 -1
  69. package/src/database/record/validators/base.js +10 -0
  70. package/src/database/record/validators/presence.js +1 -1
  71. package/src/database/table-data/table-column.js +37 -3
  72. package/src/database/table-data/table-index.js +1 -1
  73. package/src/database/use-database.js +2 -2
  74. package/src/environment-handlers/base.js +53 -0
  75. package/src/environment-handlers/browser.js +171 -0
  76. package/src/environment-handlers/node.js +162 -0
  77. package/src/http-server/client/request-buffer/index.js +9 -9
  78. package/src/http-server/index.js +6 -0
  79. package/src/http-server/worker-handler/index.js +20 -19
  80. package/src/initializer.js +17 -1
  81. package/src/logger.js +3 -0
  82. package/src/routes/app-routes.js +6 -2
  83. package/src/routes/base-route.js +1 -1
  84. package/src/routes/get-route.js +1 -1
  85. package/src/routes/namespace-route.js +1 -1
  86. package/src/routes/post-route.js +1 -1
  87. package/src/routes/resolver.js +1 -1
  88. package/src/routes/resource-route.js +1 -1
  89. package/src/templates/configuration.js +4 -0
  90. package/src/testing/request-client.js +26 -3
  91. package/src/testing/test-files-finder.js +2 -2
  92. package/src/testing/test-runner.js +74 -28
  93. package/src/testing/test.js +62 -0
  94. package/src/utils/file-exists.js +7 -5
  95. package/src/utils/rest-args-error.js +5 -3
@@ -1,10 +1,15 @@
1
1
  import {digg} from "diggerize"
2
2
  import * as inflection from "inflection"
3
3
  import {Logger} from "../logger.js"
4
+ import restArgsError from "../utils/rest-args-error.js"
4
5
  import TableData from "./table-data/index.js"
5
6
 
6
7
  export default class VelociousDatabaseMigrator {
7
- constructor({configuration}) {
8
+ constructor({configuration, ...restArgs}) {
9
+ restArgsError(restArgs)
10
+
11
+ if (!configuration) throw new Error("configuration argument is required")
12
+
8
13
  this.configuration = configuration
9
14
  this.logger = new Logger(this)
10
15
  }
@@ -62,13 +67,21 @@ export default class VelociousDatabaseMigrator {
62
67
  requireMigration: async () => {
63
68
  const migrationImport = await importCallback(migration.fullPath)
64
69
 
65
- return migrationImport.default
70
+ if (!migrationImport) {
71
+ throw new Error(`Migration file must export migration class: ${migration.fullPath}`)
72
+ }
73
+
74
+ return migrationImport
66
75
  }
67
76
  })
68
77
  }
69
78
  })
70
79
  }
71
80
 
81
+ /**
82
+ * @param {*} requireContext
83
+ * @returns {Promise<void>}
84
+ */
72
85
  async migrateFilesFromRequireContext(requireContext) {
73
86
  const files = requireContext
74
87
  .keys()
@@ -111,6 +124,9 @@ export default class VelociousDatabaseMigrator {
111
124
  })
112
125
  }
113
126
 
127
+ /**
128
+ * @returns {Promise<void>}
129
+ */
114
130
  async loadMigrationsVersions() {
115
131
  this.migrationsVersions = {}
116
132
 
@@ -142,6 +158,9 @@ export default class VelociousDatabaseMigrator {
142
158
  }
143
159
  }
144
160
 
161
+ /**
162
+ * @returns {Promise<boolean>}
163
+ */
145
164
  async migrationsTableExist(db) {
146
165
  const schemaTable = await db.getTableByName("schema_migrations", {throwError: false})
147
166
 
@@ -150,10 +169,12 @@ export default class VelociousDatabaseMigrator {
150
169
  return true
151
170
  }
152
171
 
172
+ /**
173
+ * @returns {Promise<void>}
174
+ */
153
175
  async executeRequireContext(requireContext) {
154
176
  const migrationFiles = requireContext.keys()
155
-
156
- files = migrationFiles
177
+ const files = migrationFiles
157
178
  .map((file) => {
158
179
  const match = file.match(/^(\d{14})-(.+)\.js$/)
159
180
 
@@ -165,7 +186,7 @@ export default class VelociousDatabaseMigrator {
165
186
 
166
187
  return {
167
188
  file,
168
- fullPath: `${migrationsPath}/${file}`,
189
+ fullPath: `${migrationsPath}/${file}`, // eslint-disable-line no-undef
169
190
  date,
170
191
  migrationClassName
171
192
  }
@@ -181,6 +202,9 @@ export default class VelociousDatabaseMigrator {
181
202
  }
182
203
  }
183
204
 
205
+ /**
206
+ * @returns {Promise<void>}
207
+ */
184
208
  async reset() {
185
209
  const dbs = await this.configuration.getCurrentConnections()
186
210
 
@@ -205,7 +229,7 @@ export default class VelociousDatabaseMigrator {
205
229
  }
206
230
 
207
231
  break
208
- } catch (error) {
232
+ } catch (error) { // eslint-disable-line no-unused-vars
209
233
  if (errors.length > 0 && anyTableDropped) {
210
234
  // Retry
211
235
  } else {
@@ -217,13 +241,69 @@ export default class VelociousDatabaseMigrator {
217
241
  }
218
242
  }
219
243
 
220
- async runMigrationFile({migration, requireMigration}) {
244
+ /**
245
+ * @param {{date: number}[]} files
246
+ * @param {function(string) : void} importCallback Function to import a file
247
+ * @returns {Promise<void>}
248
+ */
249
+ async rollback(files, importCallback) {
250
+ const latestMigrationVersion = await this._latestMigrationVersion()
251
+
252
+ if (!latestMigrationVersion) {
253
+ throw new Error("No migrations have been run yet")
254
+ }
255
+
256
+ const latestMigrationVersionNumber = parseInt(latestMigrationVersion)
257
+ const migration = files.find((file) => file.date == latestMigrationVersionNumber)
258
+
259
+ if (!migration) {
260
+ throw new Error(`Migration file for version ${latestMigrationVersionNumber} not found`)
261
+ }
262
+
263
+ await this.runMigrationFile({
264
+ migration,
265
+ requireMigration: async () => await importCallback(migration.fullPath),
266
+ direction: "down"
267
+ })
268
+ }
269
+
270
+ /**
271
+ * @returns {Promise<string | null>} The latest migration version
272
+ */
273
+ async _latestMigrationVersion() {
274
+ if (!this.migrationsVersions) await this.loadMigrationsVersions()
275
+
276
+ let highestVersion
277
+
278
+ for (const dbIdentifier in this.migrationsVersions) {
279
+ for (const migrationVersion in this.migrationsVersions[dbIdentifier]) {
280
+ if (!highestVersion || migrationVersion > highestVersion) {
281
+ highestVersion = migrationVersion
282
+ }
283
+ }
284
+ }
285
+
286
+ return highestVersion
287
+ }
288
+
289
+ /**
290
+ * @param {object} args
291
+ * @param {object} args.migration
292
+ * @param {function() : void} args.requireMigration
293
+ * @param {string} args.direction
294
+ */
295
+ async runMigrationFile({migration, requireMigration, direction = "up"}) {
221
296
  if (!this.configuration) throw new Error("No configuration set")
222
297
  if (!this.configuration.isDatabasePoolInitialized()) await this.configuration.initializeDatabasePool()
223
298
  if (!this.migrationsVersions) await this.loadMigrationsVersions()
224
299
 
225
300
  const dbs = await this.configuration.getCurrentConnections()
226
301
  const migrationClass = await requireMigration()
302
+
303
+ if (!migrationClass || typeof migrationClass !== "function") {
304
+ throw new Error(`Migration ${migration.file} must export a default migration class. Type: ${typeof migrationClass}`)
305
+ }
306
+
227
307
  const migrationDatabaseIdentifiers = migrationClass.getDatabaseIdentifiers() || ["default"]
228
308
 
229
309
  for (const dbIdentifier in dbs) {
@@ -239,9 +319,18 @@ export default class VelociousDatabaseMigrator {
239
319
  continue
240
320
  }
241
321
 
242
- if (this.hasRunMigrationVersion(dbIdentifier, migration.date)) {
243
- this.logger.debug(`${dbIdentifier} has already run migration ${migration.file}`)
244
- continue
322
+ if (direction == "up") {
323
+ if (this.hasRunMigrationVersion(dbIdentifier, migration.date)) {
324
+ this.logger.debug(`${dbIdentifier} has already run migration ${migration.file}`)
325
+ continue
326
+ }
327
+ } else if (direction == "down") {
328
+ if (!this.hasRunMigrationVersion(dbIdentifier, migration.date)) {
329
+ this.logger.debug(`${dbIdentifier} hasn't run migration ${migration.file}`)
330
+ continue
331
+ }
332
+ } else {
333
+ throw new Error(`Unknown direction: ${direction}`)
245
334
  }
246
335
 
247
336
  this.logger.debug(`Running migration on ${dbIdentifier}: ${migration.file}`, {migrationDatabaseIdentifiers})
@@ -252,23 +341,35 @@ export default class VelociousDatabaseMigrator {
252
341
  configuration: this.configuration,
253
342
  db
254
343
  })
344
+ const dateString = `${digg(migration, "date")}`
345
+
346
+ if (direction == "up") {
347
+ if (migrationInstance.change) {
348
+ await migrationInstance.change()
349
+ } else if (migrationInstance.up) {
350
+ await migrationInstance.up()
351
+ } else {
352
+ throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
353
+ }
255
354
 
256
- if (migrationInstance.change) {
257
- await migrationInstance.change()
258
- } else if (migrationInstance.up) {
259
- await migrationInstance.up()
260
- } else {
261
- throw new Error(`'change' or 'up' didn't exist on migration: ${migration.file}`)
262
- }
355
+ const existingSchemaMigrations = await db.newQuery()
356
+ .from("schema_migrations")
357
+ .where({version: dateString})
358
+ .results()
263
359
 
264
- const dateString = digg(migration, "date")
265
- const existingSchemaMigrations = await db.newQuery()
266
- .from("schema_migrations")
267
- .where({version: `${dateString}`})
268
- .results()
360
+ if (existingSchemaMigrations.length == 0) {
361
+ await db.insert({tableName: "schema_migrations", data: {version: dateString}})
362
+ }
363
+ } else if (direction == "down") {
364
+ if (migrationInstance.down) {
365
+ await migrationInstance.down()
366
+ } else {
367
+ throw new Error(`'down' didn't exist on migration: ${migration.file}`)
368
+ }
269
369
 
270
- if (existingSchemaMigrations.length == 0) {
271
- await db.insert({tableName: "schema_migrations", data: {version: dateString}})
370
+ await db.delete({tableName: "schema_migrations", conditions: {version: dateString}})
371
+ } else {
372
+ throw new Error(`Unknown direction: ${direction}`)
272
373
  }
273
374
  }
274
375
  }
@@ -1,7 +1,7 @@
1
1
  import BasePool from "./base.js"
2
2
 
3
3
  export default class VelociousDatabasePoolSingleMultiUser extends BasePool {
4
- checkin(connection) {
4
+ checkin(connection) { // eslint-disable-line no-unused-vars
5
5
  // Do nothing
6
6
  }
7
7
 
@@ -4,6 +4,12 @@ import restArgsError from "../../utils/rest-args-error.js"
4
4
  import TableData from "../table-data/index.js"
5
5
 
6
6
  export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
7
+ /**
8
+ * @param {object} args
9
+ * @template Tdriver extends import("../driver/base.js").default
10
+ * @param {Tdriver} args.driver
11
+ * @param {TableData} args.tableData
12
+ */
7
13
  constructor({driver, tableData, ...restArgs}) {
8
14
  restArgsError(restArgs)
9
15
 
@@ -13,6 +19,9 @@ export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
13
19
  this.tableData = tableData
14
20
  }
15
21
 
22
+ /**
23
+ * @returns {string[]}
24
+ */
16
25
  toSqls() {
17
26
  const databaseType = this.getDriver().getType()
18
27
  const sqls = []
@@ -30,6 +39,8 @@ export default class VelociousDatabaseQueryAlterTableBase extends QueryBase {
30
39
  sql += column.getSQL({driver: this.getDriver(), forAlterTable: true})
31
40
  } else if (column.getNewName()) {
32
41
  sql += `RENAME COLUMN ${options.quoteColumnName(column.getName())} TO ${options.quoteColumnName(column.getNewName())}`
42
+ } else if (column.getDropColumn()) {
43
+ sql += `DROP COLUMN ${options.quoteColumnName}`
33
44
  } else {
34
45
  if (databaseType == "mssql" || databaseType == "pgsql") {
35
46
  sql += "ALTER COLUMN "
@@ -18,6 +18,9 @@ export default class VelociousDatabaseQueryBase {
18
18
  return this._driver
19
19
  }
20
20
 
21
+ /**
22
+ * @returns {import("../query-parser/options.js").default}
23
+ */
21
24
  getOptions() {
22
25
  return this._options
23
26
  }
@@ -26,6 +29,10 @@ export default class VelociousDatabaseQueryBase {
26
29
  return this.getDriver().getType()
27
30
  }
28
31
 
32
+ /**
33
+ * @interface
34
+ * @returns {string[]}
35
+ */
29
36
  toSql() {
30
37
  throw new Error("'toSql' wasn't implemented")
31
38
  }
@@ -7,6 +7,9 @@ export default class VelociousDatabaseQueryCreateDatabaseBase extends QueryBase
7
7
  this.ifNotExists = ifNotExists
8
8
  }
9
9
 
10
+ /**
11
+ * @returns {string[]}
12
+ */
10
13
  toSql() {
11
14
  const {databaseName} = this
12
15
  let sql = "CREATE DATABASE"
@@ -1,4 +1,3 @@
1
- import {digs} from "diggerize"
2
1
  import QueryBase from "./base.js"
3
2
 
4
3
  export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
@@ -35,6 +34,9 @@ export default class VelociousDatabaseQueryCreateIndexBase extends QueryBase {
35
34
  return indexName
36
35
  }
37
36
 
37
+ /**
38
+ * @returns {string}
39
+ */
38
40
  toSql() {
39
41
  const databaseType = this.getDriver().getType()
40
42
  const indexName = this.name || this.generateIndexName()
@@ -14,6 +14,9 @@ export default class VelociousDatabaseQueryCreateTableBase extends QueryBase {
14
14
  this.tableData = tableData
15
15
  }
16
16
 
17
+ /**
18
+ * @returns {string[]}
19
+ */
17
20
  toSql() {
18
21
  const databaseType = this.getDatabaseType()
19
22
  const driver = this.getDriver()
@@ -13,6 +13,9 @@ export default class VelociousDatabaseQueryDropTableBase extends QueryBase {
13
13
  this.tableName = tableName
14
14
  }
15
15
 
16
+ /**
17
+ * @returns {string[]}
18
+ */
16
19
  toSql() {
17
20
  const databaseType = this.getDatabaseType()
18
21
  const options = this.getOptions()
@@ -40,6 +43,6 @@ export default class VelociousDatabaseQueryDropTableBase extends QueryBase {
40
43
 
41
44
  sqls.push(sql)
42
45
 
43
- return [sql]
46
+ return sqls
44
47
  }
45
48
  }
@@ -1,8 +1,15 @@
1
1
  export default class VelociousDatabaseQueryFromBase {
2
+ /**
3
+ * @returns {import("../query-parser/options.js").default}
4
+ */
2
5
  getOptions() {
3
6
  return this.query.getOptions()
4
7
  }
5
8
 
9
+ /**
10
+ * @interface
11
+ * @returns {string[]}
12
+ */
6
13
  toSql() {
7
14
  throw new Error("'toSql' wasn't implemented")
8
15
  }
@@ -35,6 +35,9 @@ export default class VelociousDatabaseQuery {
35
35
  this._wheres = wheres
36
36
  }
37
37
 
38
+ /**
39
+ * @returns {VelociousDatabaseQuery}
40
+ */
38
41
  clone() {
39
42
  const newQuery = new VelociousDatabaseQuery({
40
43
  driver: this.driver,
@@ -56,6 +59,9 @@ export default class VelociousDatabaseQuery {
56
59
  return newQuery
57
60
  }
58
61
 
62
+ /**
63
+ * @returns {Promise<number>}
64
+ */
59
65
  async count() {
60
66
  // Generate count SQL
61
67
  let sql = `COUNT(${this.driver.quoteTable(this.modelClass.tableName())}.${this.driver.quoteColumn(this.modelClass.primaryKey())})`
@@ -94,8 +100,14 @@ export default class VelociousDatabaseQuery {
94
100
  return countResult
95
101
  }
96
102
 
103
+ /**
104
+ * @returns {import("../query-parser/options.js").default}
105
+ */
97
106
  getOptions() { return this.driver.options() }
98
107
 
108
+ /**
109
+ * @returns {Promise<void>}
110
+ */
99
111
  async destroyAll() {
100
112
  const records = await this.toArray()
101
113
 
@@ -104,6 +116,10 @@ export default class VelociousDatabaseQuery {
104
116
  }
105
117
  }
106
118
 
119
+ /**
120
+ * @param {number|string} recordId
121
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
122
+ */
107
123
  async find(recordId) {
108
124
  const conditions = {}
109
125
 
@@ -119,6 +135,10 @@ export default class VelociousDatabaseQuery {
119
135
  return record
120
136
  }
121
137
 
138
+ /**
139
+ * @param {object} conditions
140
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
141
+ */
122
142
  async findBy(conditions) {
123
143
  const newConditions = {}
124
144
 
@@ -131,6 +151,10 @@ export default class VelociousDatabaseQuery {
131
151
  return await this.clone().where(newConditions).first()
132
152
  }
133
153
 
154
+ /**
155
+ * @param {...Parameters<this["findOrInitializeBy"]>} args
156
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
157
+ */
134
158
  async findOrCreateBy(...args) {
135
159
  const record = await this.findOrInitializeBy(...args)
136
160
 
@@ -141,6 +165,10 @@ export default class VelociousDatabaseQuery {
141
165
  return record
142
166
  }
143
167
 
168
+ /**
169
+ * @param {object} conditions
170
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
171
+ */
144
172
  async findByOrFail(conditions) {
145
173
  const newConditions = {}
146
174
 
@@ -159,6 +187,11 @@ export default class VelociousDatabaseQuery {
159
187
  return model
160
188
  }
161
189
 
190
+ /**
191
+ * @param {object} conditions
192
+ * @param {function() : void} callback
193
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
194
+ */
162
195
  async findOrInitializeBy(conditions, callback) {
163
196
  const record = await this.findBy(conditions)
164
197
 
@@ -173,6 +206,9 @@ export default class VelociousDatabaseQuery {
173
206
  return newRecord
174
207
  }
175
208
 
209
+ /**
210
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
211
+ */
176
212
  async first() {
177
213
  const newQuery = this.clone().limit(1).reorder(`${this.driver.quoteTable(this.modelClass.tableName())}.${this.driver.quoteColumn(this.modelClass.orderableColumn())}`)
178
214
  const results = await newQuery.toArray()
@@ -180,6 +216,10 @@ export default class VelociousDatabaseQuery {
180
216
  return results[0]
181
217
  }
182
218
 
219
+ /**
220
+ * @param {string|FromPlain} from
221
+ * @returns {this}
222
+ */
183
223
  from(from) {
184
224
  if (typeof from == "string") from = new FromPlain({plain: from, query: this})
185
225
 
@@ -189,11 +229,19 @@ export default class VelociousDatabaseQuery {
189
229
  return this
190
230
  }
191
231
 
232
+ /**
233
+ * @param {string} group
234
+ * @returns {this}
235
+ */
192
236
  group(group) {
193
237
  this._groups.push(group)
194
238
  return this
195
239
  }
196
240
 
241
+ /**
242
+ * @param {string|JoinPlain} join
243
+ * @returns {this}
244
+ */
197
245
  joins(join) {
198
246
  if (typeof join == "string") {
199
247
  join = new JoinPlain({plain: join, query: this})
@@ -207,6 +255,9 @@ export default class VelociousDatabaseQuery {
207
255
  return this
208
256
  }
209
257
 
258
+ /**
259
+ * @returns {Promise<InstanceType<this["modelClass"]>>}
260
+ */
210
261
  async last() {
211
262
  const primaryKey = this.modelClass.primaryKey()
212
263
  const tableName = this.modelClass.tableName()
@@ -215,16 +266,28 @@ export default class VelociousDatabaseQuery {
215
266
  return results[0]
216
267
  }
217
268
 
269
+ /**
270
+ * @param {number} value
271
+ * @returns {this}
272
+ */
218
273
  limit(value) {
219
274
  this._limit = value
220
275
  return this
221
276
  }
222
277
 
278
+ /**
279
+ * @param {number} value
280
+ * @returns {this}
281
+ */
223
282
  offset(value) {
224
283
  this._offset = value
225
284
  return this
226
285
  }
227
286
 
287
+ /**
288
+ * @param {*} order
289
+ * @returns {this}
290
+ */
228
291
  order(order) {
229
292
  if (typeof order == "number" || typeof order == "string") order = new OrderPlain({plain: order, query: this})
230
293
 
@@ -234,6 +297,10 @@ export default class VelociousDatabaseQuery {
234
297
  return this
235
298
  }
236
299
 
300
+ /**
301
+ * @param {number} pageNumber
302
+ * @returns {this}
303
+ */
237
304
  page(pageNumber) {
238
305
  const perPage = this._perPage || 30
239
306
  const offset = (pageNumber - 1) * perPage
@@ -245,22 +312,37 @@ export default class VelociousDatabaseQuery {
245
312
  return this
246
313
  }
247
314
 
315
+ /**
316
+ * @param {number} perPage
317
+ * @returns {this}
318
+ */
248
319
  perPage(perPage) {
249
320
  this._perPage = perPage
250
321
  return this
251
322
  }
252
323
 
324
+ /**
325
+ * @param {string} data
326
+ * @returns {this}
327
+ */
253
328
  preload(data) {
254
329
  incorporate(this._preload, data)
255
330
  return this
256
331
  }
257
332
 
333
+ /**
334
+ * @param {string|OrderPlain} order
335
+ * @returns {this}
336
+ */
258
337
  reorder(order) {
259
338
  this._orders = []
260
339
  this.order(order)
261
340
  return this
262
341
  }
263
342
 
343
+ /**
344
+ * @returns {this}
345
+ */
264
346
  reverseOrder() {
265
347
  for (const order of this._orders) {
266
348
  order.setReverseOrder(true)
@@ -269,6 +351,10 @@ export default class VelociousDatabaseQuery {
269
351
  return this
270
352
  }
271
353
 
354
+ /**
355
+ * @param {string|SelectPlain} select
356
+ * @returns {this}
357
+ */
272
358
  select(select) {
273
359
  if (Array.isArray(select)) {
274
360
  for (const selectInArray of select) {
@@ -286,23 +372,28 @@ export default class VelociousDatabaseQuery {
286
372
  return this
287
373
  }
288
374
 
375
+ /**
376
+ * @returns {Promise<Array<object>>} Array of results from the database
377
+ */
289
378
  async _executeQuery() {
290
379
  const sql = this.toSql()
291
380
  const results = await this.driver.query(sql)
292
381
 
293
- this.logger.debug("SQL:", sql)
382
+ this.logger.debug(() => ["SQL:", sql])
294
383
 
295
384
  return results
296
385
  }
297
386
 
387
+ /**
388
+ * @returns {Promise<Array<object>>} Array of results from the database
389
+ */
298
390
  async results() {
299
391
  return await this._executeQuery()
300
392
  }
301
393
 
302
394
  /**
303
395
  * Converts query results to array of model instances
304
- *
305
- * @returns {Promise<Array>} Array of model instances
396
+ * @returns {Promise<Array<InstanceType<this["modelClass"]>>>}
306
397
  */
307
398
  async toArray() {
308
399
  const models = []
@@ -330,13 +421,12 @@ export default class VelociousDatabaseQuery {
330
421
 
331
422
  /**
332
423
  * Generates SQL string representing this query
333
- *
334
- * @returns {String} SQL string representing this query
424
+ * @returns {string} SQL string representing this query
335
425
  */
336
426
  toSql() { return this.driver.queryToSql(this) }
337
427
 
338
428
  /**
339
- * @param {Object|String} where
429
+ * @param {object|string} where
340
430
  * @returns {VelociousDatabaseQuery} This query instance
341
431
  */
342
432
  where(where) {
@@ -16,10 +16,16 @@ export default class VelociousDatabaseQueryInsertBase {
16
16
  this.tableName = tableName
17
17
  }
18
18
 
19
+ /**
20
+ * @returns {import("../query-parser/options.js").default}
21
+ */
19
22
  getOptions() {
20
23
  return this.driver.options()
21
24
  }
22
25
 
26
+ /**
27
+ * @returns {string} SQL statement
28
+ */
23
29
  toSql() {
24
30
  const {driver} = this
25
31
 
@@ -1,4 +1,7 @@
1
1
  export default class VelociousDatabaseQueryJoinBase {
2
+ /**
3
+ * @returns {import("../query-parser/options.js").default}
4
+ */
2
5
  getOptions() {
3
6
  return this.query.driver.options()
4
7
  }
@@ -1,4 +1,7 @@
1
1
  export default class VelociousDatabaseQueryOrderBase {
2
+ /**
3
+ * @returns {import("../query-parser/options.js").default}
4
+ */
2
5
  getOptions() {
3
6
  return this.query.driver.options()
4
7
  }
@@ -1,4 +1,7 @@
1
1
  export default class VelociousDatabaseQuerySelectBase {
2
+ /**
3
+ * @returns {import("../query-parser/options.js").default}
4
+ */
2
5
  getOptions() {
3
6
  return this.query.driver.options()
4
7
  }