velocious 1.0.104 → 1.0.105

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 (85) hide show
  1. package/package.json +1 -1
  2. package/spec/dummy/dummy-directory.js +2 -0
  3. package/spec/dummy/index.js +5 -1
  4. package/src/application.js +1 -0
  5. package/src/configuration-types.js +6 -0
  6. package/src/controller.js +44 -24
  7. package/src/database/drivers/base-foreign-key.js +1 -1
  8. package/src/database/drivers/base.js +2 -2
  9. package/src/database/drivers/mssql/column.js +6 -0
  10. package/src/database/drivers/mssql/columns-index.js +2 -5
  11. package/src/database/drivers/mssql/foreign-key.js +2 -0
  12. package/src/database/drivers/mssql/options.js +25 -0
  13. package/src/database/drivers/mssql/query-parser.js +2 -0
  14. package/src/database/drivers/mysql/options.js +9 -0
  15. package/src/database/drivers/mysql/sql/alter-table.js +2 -0
  16. package/src/database/drivers/mysql/sql/create-database.js +2 -0
  17. package/src/database/drivers/mysql/sql/create-index.js +2 -0
  18. package/src/database/drivers/mysql/sql/create-table.js +2 -0
  19. package/src/database/drivers/mysql/sql/delete.js +2 -0
  20. package/src/database/drivers/mysql/sql/drop-table.js +2 -0
  21. package/src/database/drivers/mysql/sql/insert.js +2 -0
  22. package/src/database/drivers/mysql/sql/update.js +2 -0
  23. package/src/database/drivers/pgsql/column.js +6 -0
  24. package/src/database/drivers/pgsql/columns-index.js +2 -0
  25. package/src/database/drivers/pgsql/foreign-key.js +2 -0
  26. package/src/database/drivers/pgsql/options.js +9 -0
  27. package/src/database/drivers/pgsql/query-parser.js +2 -0
  28. package/src/database/drivers/pgsql/sql/alter-table.js +2 -0
  29. package/src/database/drivers/pgsql/sql/create-database.js +5 -4
  30. package/src/database/drivers/pgsql/sql/create-index.js +2 -0
  31. package/src/database/drivers/pgsql/sql/create-table.js +2 -0
  32. package/src/database/drivers/pgsql/sql/delete.js +2 -0
  33. package/src/database/drivers/pgsql/sql/drop-table.js +2 -0
  34. package/src/database/drivers/pgsql/sql/insert.js +2 -0
  35. package/src/database/drivers/pgsql/sql/update.js +2 -0
  36. package/src/database/drivers/pgsql/table.js +6 -0
  37. package/src/database/drivers/sqlite/columns-index.js +2 -6
  38. package/src/database/drivers/sqlite/connection-remote.js +7 -0
  39. package/src/database/drivers/sqlite/connection-sql-js.js +12 -2
  40. package/src/database/drivers/sqlite/foreign-key.js +7 -0
  41. package/src/database/drivers/sqlite/index.js +7 -1
  42. package/src/database/drivers/sqlite/index.web.js +12 -3
  43. package/src/database/drivers/sqlite/options.js +9 -0
  44. package/src/database/drivers/sqlite/query-parser.js +2 -0
  45. package/src/database/drivers/sqlite/query.js +19 -6
  46. package/src/database/drivers/sqlite/query.web.js +13 -1
  47. package/src/database/initializer-from-require-context.js +11 -1
  48. package/src/database/migrator/types.js +2 -0
  49. package/src/database/pool/base-methods-forward.js +7 -0
  50. package/src/database/query/delete-base.js +8 -0
  51. package/src/database/query/preloader/belongs-to.js +16 -1
  52. package/src/database/query/preloader/has-many.js +19 -1
  53. package/src/database/query/preloader/has-one.js +20 -2
  54. package/src/database/query/preloader.js +19 -4
  55. package/src/database/query/update-base.js +9 -0
  56. package/src/database/query-parser/limit-parser.js +7 -2
  57. package/src/database/query-parser/options.js +47 -6
  58. package/src/database/query-parser/order-parser.js +11 -6
  59. package/src/database/query-parser/select-parser.js +8 -5
  60. package/src/database/query-parser/where-parser.js +11 -5
  61. package/src/database/record/index.js +1 -4
  62. package/src/database/record/instance-relationships/base.js +10 -1
  63. package/src/database/record/record-not-found-error.js +2 -0
  64. package/src/database/record/user-module.js +13 -0
  65. package/src/database/record/validators/uniqueness.js +13 -2
  66. package/src/error-logger.js +17 -3
  67. package/src/http-client/index.js +34 -2
  68. package/src/http-client/request.js +1 -1
  69. package/src/http-server/client/params-to-object.js +28 -0
  70. package/src/initializer.js +2 -0
  71. package/src/routes/app-routes.js +3 -1
  72. package/src/routes/base-route.js +67 -58
  73. package/src/routes/basic-route.js +76 -0
  74. package/src/routes/get-route.js +21 -5
  75. package/src/routes/index.js +10 -0
  76. package/src/routes/namespace-route.js +21 -5
  77. package/src/routes/post-route.js +20 -5
  78. package/src/routes/resolver.js +15 -2
  79. package/src/routes/resource-route.js +21 -5
  80. package/src/routes/root-route.js +3 -3
  81. package/src/testing/request-client.js +19 -14
  82. package/src/testing/test-runner.js +16 -10
  83. package/src/testing/test.js +70 -22
  84. package/src/utils/with-tracked-stack-async-hooks.js +22 -4
  85. package/src/utils/with-tracked-stack.js +9 -0
@@ -1,7 +1,14 @@
1
+ // @ts-check
2
+
1
3
  import BaseForeignKey from "../base-foreign-key.js"
2
4
  import {digg} from "diggerize"
3
5
 
4
6
  export default class VelociousDatabaseDriversSqliteForeignKey extends BaseForeignKey {
7
+ /**
8
+ * @param {Record<string, any>} data
9
+ * @param {object} args
10
+ * @param {string} args.tableName
11
+ */
5
12
  constructor(data, {tableName}) {
6
13
  super(data)
7
14
  this.tableName = tableName
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import fs from "fs/promises"
2
4
  import query from "./query.js"
3
5
  import sqlite3 from "sqlite3"
@@ -30,10 +32,14 @@ export default class VelociousDatabaseDriversSqliteNode extends Base {
30
32
  }
31
33
 
32
34
  async close() {
33
- await this.connection.close()
35
+ await this.connection?.close()
34
36
  this.connection = undefined
35
37
  }
36
38
 
39
+ /**
40
+ * @param {string} sql
41
+ * @returns {Promise<Record<string, any>[]>}
42
+ */
37
43
  async _queryActual(sql) {
38
44
  return await query(this.connection, sql)
39
45
  }
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import BetterLocalStorage from "better-localstorage"
2
4
  import ConnectionSqlJs from "./connection-sql-js"
3
5
  import initSqlJs from "sql.js"
@@ -5,6 +7,9 @@ import initSqlJs from "sql.js"
5
7
  import Base from "./base.js"
6
8
 
7
9
  export default class VelociousDatabaseDriversSqliteWeb extends Base {
10
+ /** @type {BetterLocalStorage | undefined} */
11
+ betterLocalStorage = undefined
12
+
8
13
  async connect() {
9
14
  this.args = this.getArgs()
10
15
 
@@ -32,7 +37,7 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
32
37
  }
33
38
 
34
39
  getConnection() {
35
- if (this.args.getConnection) {
40
+ if (this.args?.getConnection) {
36
41
  return this.args.getConnection()
37
42
  } else {
38
43
  return this._connection
@@ -40,13 +45,17 @@ export default class VelociousDatabaseDriversSqliteWeb extends Base {
40
45
  }
41
46
 
42
47
  localStorageName() {
43
- if (!this.args.name) {
48
+ if (!this.args?.name) {
44
49
  throw new Error("No name given in arguments for SQLite Web database")
45
50
  }
46
51
 
47
- return `VelociousDatabaseDriversSqliteWeb---${this.args.name}`
52
+ return `VelociousDatabaseDriversSqliteWeb---${this.args?.name}`
48
53
  }
49
54
 
55
+ /**
56
+ * @param {string} sql
57
+ * @returns {Promise<Record<string, any>[]>}
58
+ */
50
59
  async _queryActual(sql) {
51
60
  return await this.getConnection().query(sql)
52
61
  }
@@ -1,6 +1,11 @@
1
+ // @ts-check
2
+
1
3
  import QueryParserOptions from "../../query-parser/options.js"
2
4
 
3
5
  export default class VelociousDatabaseDriversSqliteOptions extends QueryParserOptions {
6
+ /**
7
+ * @param {import("../../query-parser/options.js").OptionsObjectArgsType} options
8
+ */
4
9
  constructor(options) {
5
10
  options.columnQuote = "`"
6
11
  options.indexQuote = "`"
@@ -10,6 +15,10 @@ export default class VelociousDatabaseDriversSqliteOptions extends QueryParserOp
10
15
  super(options)
11
16
  }
12
17
 
18
+ /**
19
+ * @param {string} string
20
+ * @returns {number | string}
21
+ */
13
22
  quote(string) {
14
23
  if (!this.driver) throw new Error("Driver not set")
15
24
 
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import BaseQueryParser from "../../query-parser/base-query-parser.js"
2
4
 
3
5
  export default class VelociousDatabaseConnectionDriversSqliteQueryParser extends BaseQueryParser {
@@ -1,8 +1,19 @@
1
- export default async function query(connection, sql) {
2
- let result
1
+ // @ts-check
3
2
 
3
+ /**
4
+ * @param {import("sqlite3").Database} connection
5
+ * @param {string} sql
6
+ * @returns {Promise<Record<string, any>[]>}
7
+ */
8
+ export default async function query(connection, sql) {
4
9
  try {
10
+ /** @type {Record<string, any>[]} */
11
+ let result
12
+
13
+ // @ts-expect-error
5
14
  result = await connection.all(sql)
15
+
16
+ return result
6
17
  } catch (error) {
7
18
  let sqlInErrorMessage = `${sql}`
8
19
 
@@ -10,10 +21,12 @@ export default async function query(connection, sql) {
10
21
  sqlInErrorMessage = `${sqlInErrorMessage.substring(0, 4096)}...`
11
22
  }
12
23
 
13
- error.message += `\n\n${sqlInErrorMessage}`
24
+ if (error instanceof Error) {
25
+ error.message += `\n\n${sqlInErrorMessage}`
14
26
 
15
- throw new Error(error.message)
27
+ throw new Error(error.message)
28
+ } else {
29
+ throw new Error(`An error occurred: ${error}\n\n${sql}`)
30
+ }
16
31
  }
17
-
18
- return result
19
32
  }
@@ -1,3 +1,10 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @param {import("sql.js").Database} connection
5
+ * @param {string} sql
6
+ * @returns {Promise<Record<string, any>[]>}
7
+ */
1
8
  export default async function query(connection, sql) {
2
9
  const rows = []
3
10
  let result
@@ -11,7 +18,11 @@ export default async function query(connection, sql) {
11
18
  sqlInErrorMessage = `${sqlInErrorMessage.substring(0, 4096)}...`
12
19
  }
13
20
 
14
- error.message += `\n\n${sqlInErrorMessage}`
21
+ if (error instanceof Error) {
22
+ error.message += `\n\n${sqlInErrorMessage}`
23
+ } else {
24
+ throw new Error(`An error occurred: ${error}\n\n${sqlInErrorMessage}`)
25
+ }
15
26
 
16
27
  throw error
17
28
  }
@@ -20,6 +31,7 @@ export default async function query(connection, sql) {
20
31
  const columns = result[0].columns
21
32
 
22
33
  for (const rowValues of result[0].values) {
34
+ /** @type {Record<string, any>} */
23
35
  const row = {}
24
36
 
25
37
  for (const columnIndex in columns) {
@@ -1,9 +1,19 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {(id: string) => {default: typeof import("./record/index.js").default}} ModelClassRequireContextIDFunctionType
5
+ * @typedef {ModelClassRequireContextIDFunctionType & {
6
+ * keys: () => string[],
7
+ * id: string
8
+ * }} ModelClassRequireContextType
9
+ */
10
+
1
11
  import restArgsError from "../utils/rest-args-error.js"
2
12
 
3
13
  export default class VelociousDatabaseInitializerFromRequireContext {
4
14
  /**
5
15
  * @param {object} args
6
- * @param {object} args.requireContext
16
+ * @param {ModelClassRequireContextType} args.requireContext
7
17
  */
8
18
  constructor({requireContext, ...restArgs}) {
9
19
  restArgsError(restArgs)
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * @typedef {object} MigrationObjectType
3
5
  * @property {number} date
@@ -1,5 +1,8 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * @param {typeof import("./base.js").default} PoolBase
5
+ * @returns {void}
3
6
  */
4
7
  export default function baseMethodsForward(PoolBase) {
5
8
  const forwardMethods = [
@@ -25,12 +28,16 @@ export default function baseMethodsForward(PoolBase) {
25
28
  ]
26
29
 
27
30
  for (const forwardMethod of forwardMethods) {
31
+ // @ts-expect-error
28
32
  PoolBase.prototype[forwardMethod] = function(...args) {
29
33
  const connection = this.getCurrentConnection()
34
+
35
+ // @ts-expect-error
30
36
  const connectionMethod = connection[forwardMethod]
31
37
 
32
38
  if (!connectionMethod) throw new Error(`${forwardMethod} isn't defined on driver`)
33
39
 
40
+ // @ts-expect-error
34
41
  return connection[forwardMethod](...args)
35
42
  }
36
43
  }
@@ -1,6 +1,14 @@
1
+ // @ts-check
2
+
1
3
  import QueryBase from "./base.js"
2
4
 
3
5
  export default class VelociousDatabaseQueryDeleteBase extends QueryBase {
6
+ /**
7
+ * @param {object} args
8
+ * @param {Record<string, any>} args.conditions
9
+ * @param {import("../drivers/base.js").default} args.driver
10
+ * @param {string} args.tableName
11
+ */
4
12
  constructor({conditions, driver, tableName}) {
5
13
  super({driver})
6
14
  this.conditions = conditions
@@ -1,6 +1,13 @@
1
+ // @ts-check
2
+
1
3
  import restArgsError from "../../../utils/rest-args-error.js"
2
4
 
3
5
  export default class VelociousDatabaseQueryPreloaderBelongsTo {
6
+ /**
7
+ * @param {object} args
8
+ * @param {import("../../record/index.js").default[]} args.models
9
+ * @param {import("../../record/relationships/belongs-to.js").default} args.relationship
10
+ */
4
11
  constructor({models, relationship, ...restArgs}) {
5
12
  restArgsError(restArgs)
6
13
 
@@ -9,6 +16,7 @@ export default class VelociousDatabaseQueryPreloaderBelongsTo {
9
16
  }
10
17
 
11
18
  async run() {
19
+ /** @type {Array<number | string>} */
12
20
  const foreignKeyValues = []
13
21
  const foreignKey = this.relationship.getForeignKey()
14
22
 
@@ -18,13 +26,20 @@ export default class VelociousDatabaseQueryPreloaderBelongsTo {
18
26
  if (!foreignKeyValues.includes(foreignKeyValue)) foreignKeyValues.push(foreignKeyValue)
19
27
  }
20
28
 
29
+ /** @type {Record<string, any>} */
21
30
  const whereArgs = {}
22
31
  const primaryKey = this.relationship.getPrimaryKey()
23
32
 
24
33
  whereArgs[primaryKey] = foreignKeyValues
25
34
 
35
+ const targetModelClass = this.relationship.getTargetModelClass()
36
+
37
+ if (!targetModelClass) throw new Error("No target model class could be gotten from relationship")
38
+
26
39
  // Load target models to be preloaded on the given models
27
- const targetModels = await this.relationship.getTargetModelClass().where(whereArgs).toArray()
40
+ const targetModels = await targetModelClass.where(whereArgs).toArray()
41
+
42
+ /** @type {Record<string, import("../../record/index.js").default>} */
28
43
  const targetModelsById = {}
29
44
 
30
45
  for (const targetModel of targetModels) {
@@ -1,6 +1,13 @@
1
+ // @ts-check
2
+
1
3
  import restArgsError from "../../../utils/rest-args-error.js"
2
4
 
3
5
  export default class VelociousDatabaseQueryPreloaderHasMany {
6
+ /**
7
+ * @param {object} args
8
+ * @param {import("../../record/index.js").default[]} args.models
9
+ * @param {import("../../record/relationships/has-many.js").default} args.relationship
10
+ */
4
11
  constructor({models, relationship, ...restArgs}) {
5
12
  restArgsError(restArgs)
6
13
 
@@ -9,10 +16,16 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
9
16
  }
10
17
 
11
18
  async run() {
19
+ /** @type {Array<number | string>} */
12
20
  const modelsPrimaryKeyValues = []
21
+
22
+ /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
13
23
  const modelsByPrimaryKeyValue = {}
24
+
14
25
  const foreignKey = this.relationship.getForeignKey()
15
26
  const primaryKey = this.relationship.getPrimaryKey()
27
+
28
+ /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
16
29
  const preloadCollections = {}
17
30
 
18
31
  if (!primaryKey) {
@@ -30,12 +43,17 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
30
43
  modelsByPrimaryKeyValue[primaryKeyValue].push(model)
31
44
  }
32
45
 
46
+ /** @type {Record<string, any>} */
33
47
  const whereArgs = {}
34
48
 
35
49
  whereArgs[foreignKey] = modelsPrimaryKeyValues
36
50
 
51
+ const targetModelClass = this.relationship.getTargetModelClass()
52
+
53
+ if (!targetModelClass) throw new Error("No target model class could be gotten from relationship")
54
+
37
55
  // Load target models to be preloaded on the given models
38
- const targetModels = await this.relationship.getTargetModelClass().where(whereArgs).toArray()
56
+ const targetModels = await targetModelClass.where(whereArgs).toArray()
39
57
 
40
58
  for (const targetModel of targetModels) {
41
59
  const foreignKeyValue = targetModel.readColumn(foreignKey)
@@ -1,6 +1,13 @@
1
+ // @ts-check
2
+
1
3
  import restArgsError from "../../../utils/rest-args-error.js"
2
4
 
3
5
  export default class VelociousDatabaseQueryPreloaderHasOne {
6
+ /**
7
+ * @param {object} args
8
+ * @param {Array<import("../../record/index.js").default>} args.models
9
+ * @param {import("../../record/relationships/has-one.js").default} args.relationship
10
+ */
4
11
  constructor({models, relationship, ...restArgs}) {
5
12
  restArgsError(restArgs)
6
13
 
@@ -9,16 +16,22 @@ export default class VelociousDatabaseQueryPreloaderHasOne {
9
16
  }
10
17
 
11
18
  async run() {
19
+ /** @type {Array<number | string>} */
12
20
  const modelsPrimaryKeyValues = []
21
+
22
+ /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
13
23
  const modelsByPrimaryKeyValue = {}
24
+
14
25
  const foreignKey = this.relationship.getForeignKey()
15
26
  const primaryKey = this.relationship.getPrimaryKey()
27
+
28
+ /** @type {Record<number | string, import("../../record/index.js").default | undefined>} */
16
29
  const preloadCollections = {}
17
30
 
18
31
  for (const model of this.models) {
19
32
  const primaryKeyValue = model.readColumn(primaryKey)
20
33
 
21
- preloadCollections[primaryKeyValue] = null
34
+ preloadCollections[primaryKeyValue] = undefined
22
35
 
23
36
  if (!modelsPrimaryKeyValues.includes(primaryKeyValue)) modelsPrimaryKeyValues.push(primaryKeyValue)
24
37
  if (!(primaryKeyValue in modelsByPrimaryKeyValue)) modelsByPrimaryKeyValue[primaryKeyValue] = []
@@ -26,12 +39,17 @@ export default class VelociousDatabaseQueryPreloaderHasOne {
26
39
  modelsByPrimaryKeyValue[primaryKeyValue].push(model)
27
40
  }
28
41
 
42
+ /** @type {Record<string, any>} */
29
43
  const whereArgs = {}
30
44
 
31
45
  whereArgs[foreignKey] = modelsPrimaryKeyValues
32
46
 
47
+ const targetModelClass = this.relationship.getTargetModelClass()
48
+
49
+ if (!targetModelClass) throw new Error("No target model class could be gotten from relationship")
50
+
33
51
  // Load target models to be preloaded on the given models
34
- const targetModels = await this.relationship.getTargetModelClass().where(whereArgs).toArray()
52
+ const targetModels = await targetModelClass.where(whereArgs).toArray()
35
53
 
36
54
  for (const targetModel of targetModels) {
37
55
  const foreignKeyValue = targetModel.readColumn(foreignKey)
@@ -1,9 +1,17 @@
1
+ // @ts-check
2
+
1
3
  import BelongsToPreloader from "./preloader/belongs-to.js"
2
4
  import HasManyPreloader from "./preloader/has-many.js"
3
5
  import HasOnePreloader from "./preloader/has-one.js"
4
6
  import restArgsError from "../../utils/rest-args-error.js"
5
7
 
6
8
  export default class VelociousDatabaseQueryPreloader {
9
+ /**
10
+ * @param {object} args
11
+ * @param {typeof import("../record/index.js").default} args.modelClass
12
+ * @param {import("../record/index.js").default[]} args.models
13
+ * @param {Record<string, any>} args.preload
14
+ */
7
15
  constructor({modelClass, models, preload, ...restArgs}) {
8
16
  restArgsError(restArgs)
9
17
 
@@ -18,15 +26,18 @@ export default class VelociousDatabaseQueryPreloader {
18
26
  let targetModels
19
27
 
20
28
  if (relationship.getType() == "belongsTo") {
21
- const hasManyPreloader = new BelongsToPreloader({models: this.models, relationship: relationship})
29
+ const belongsToRelationship = /** @type {import("../record/relationships/belongs-to.js").default} */ (relationship)
30
+ const hasManyPreloader = new BelongsToPreloader({models: this.models, relationship: belongsToRelationship})
22
31
 
23
32
  targetModels = await hasManyPreloader.run()
24
33
  } else if (relationship.getType() == "hasMany") {
25
- const hasManyPreloader = new HasManyPreloader({models: this.models, relationship: relationship})
34
+ const hasManyRelationship = /** @type {import("../record/relationships/has-many.js").default} */ (relationship)
35
+ const hasManyPreloader = new HasManyPreloader({models: this.models, relationship: hasManyRelationship})
26
36
 
27
37
  targetModels = await hasManyPreloader.run()
28
38
  } else if (relationship.getType() == "hasOne") {
29
- const hasOnePreloader = new HasOnePreloader({models: this.models, relationship: relationship})
39
+ const hasOneRelationship = /** @type {import("../record/relationships/has-one.js").default} */ (relationship)
40
+ const hasOnePreloader = new HasOnePreloader({models: this.models, relationship: hasOneRelationship})
30
41
 
31
42
  targetModels = await hasOnePreloader.run()
32
43
  } else {
@@ -37,7 +48,11 @@ export default class VelociousDatabaseQueryPreloader {
37
48
  const newPreload = this.preload[preloadRelationshipName]
38
49
 
39
50
  if (typeof newPreload == "object" && targetModels.length > 0) {
40
- const preloader = new VelociousDatabaseQueryPreloader({modelClass: relationship.getTargetModelClass(), models: targetModels, preload: newPreload})
51
+ const targetModelClass = relationship.getTargetModelClass()
52
+
53
+ if (!targetModelClass) throw new Error("No target model class could be gotten from relationship")
54
+
55
+ const preloader = new VelociousDatabaseQueryPreloader({modelClass: targetModelClass, models: targetModels, preload: newPreload})
41
56
 
42
57
  await preloader.run()
43
58
  }
@@ -1,4 +1,13 @@
1
+ // @ts-check
2
+
1
3
  export default class VelociousDatabaseQueryUpdateBase {
4
+ /**
5
+ * @param {object} args
6
+ * @param {Record<string, any>} args.conditions
7
+ * @param {Record<string, any>} args.data
8
+ * @param {import("../drivers/base.js").default} args.driver
9
+ * @param {string} args.tableName
10
+ */
2
11
  constructor({conditions, data, driver, tableName}) {
3
12
  this.conditions = conditions
4
13
  this.data = data
@@ -1,13 +1,18 @@
1
- import {digs} from "diggerize"
1
+ // @ts-check
2
2
 
3
3
  export default class VelocuiousDatabaseQueryParserLimitParser {
4
+ /**
5
+ * @param {object} args
6
+ * @param {boolean} args.pretty
7
+ * @param {import("../query/index.js").default} args.query
8
+ */
4
9
  constructor({pretty, query}) {
5
10
  this.pretty = pretty
6
11
  this.query = query
7
12
  }
8
13
 
9
14
  toSql() {
10
- const {pretty, query} = digs(this, "pretty", "query")
15
+ const {pretty, query} = this
11
16
  const driver = query.driver
12
17
  const options = this.query.getOptions()
13
18
  let sql = ""
@@ -1,28 +1,52 @@
1
- import {digg} from "diggerize"
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {object} OptionsObjectArgsType
5
+ * @property {string} columnQuote
6
+ * @property {string} indexQuote
7
+ * @property {import("../drivers/base.js").default} driver
8
+ * @property {string} tableQuote
9
+ * @property {string} stringQuote
10
+ */
2
11
 
3
12
  export default class VelociousDatabaseQueryParserOptions {
13
+ /**
14
+ * @param {OptionsObjectArgsType} options
15
+ */
4
16
  constructor(options) {
5
- this.columnQuote = digg(options, "columnQuote")
6
- this.indexQuote = digg(options, "indexQuote")
7
- this.driver = digg(options, "driver")
8
- this.tableQuote = digg(options, "tableQuote")
9
- this.stringQuote = digg(options, "stringQuote")
17
+ this.columnQuote = options.columnQuote
18
+ this.indexQuote = options.indexQuote
19
+ this.driver = options.driver
20
+ this.tableQuote = options.tableQuote
21
+ this.stringQuote = options.stringQuote
10
22
 
11
23
  if (!this.driver) throw new Error("No driver given to parser options")
12
24
  }
13
25
 
26
+ /**
27
+ * @param {any} value
28
+ * @returns {number | string}
29
+ */
14
30
  quote(value) {
15
31
  if (typeof value == "number") return value
16
32
 
17
33
  return this.quoteString(value)
18
34
  }
19
35
 
36
+ /**
37
+ * @param {string} databaseName
38
+ * @returns {string}
39
+ */
20
40
  quoteDatabaseName(databaseName) {
21
41
  if (databaseName.includes(this.tableQuote)) throw new Error(`Possible SQL injection in database name: ${databaseName}`)
22
42
 
23
43
  return `${this.tableQuote}${databaseName}${this.tableQuote}`
24
44
  }
25
45
 
46
+ /**
47
+ * @param {string} columnName
48
+ * @returns {string}
49
+ */
26
50
  quoteColumnName(columnName) {
27
51
  if (!columnName) throw new Error("No column name was given")
28
52
  if (columnName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${columnName}`)
@@ -30,12 +54,29 @@ export default class VelociousDatabaseQueryParserOptions {
30
54
  return `${this.columnQuote}${columnName}${this.columnQuote}`
31
55
  }
32
56
 
57
+ /**
58
+ * @param {string} indexName
59
+ * @returns {string}
60
+ */
33
61
  quoteIndexName(indexName) {
34
62
  if (!indexName || indexName.includes(this.columnQuote)) throw new Error(`Invalid column name: ${indexName}`)
35
63
 
36
64
  return `${this.columnQuote}${indexName}${this.columnQuote}`
37
65
  }
38
66
 
67
+ /**
68
+ * @abstract
69
+ * @param {any} string
70
+ * @returns {string}
71
+ */
72
+ quoteString(string) { // eslint-disable-line no-unused-vars
73
+ throw new Error("quoteString not implemented")
74
+ }
75
+
76
+ /**
77
+ * @param {string} tableName
78
+ * @returns {string}
79
+ */
39
80
  quoteTableName(tableName) {
40
81
  if (!tableName || tableName.includes(this.tableQuote)) throw new Error(`Invalid table name: ${tableName}`)
41
82
 
@@ -1,13 +1,18 @@
1
- import {digs} from "diggerize"
1
+ // @ts-check
2
2
 
3
3
  export default class VelocuiousDatabaseQueryParserOrderParser {
4
+ /**
5
+ * @param {object} args
6
+ * @param {boolean} args.pretty
7
+ * @param {import("../query/index.js").default} args.query
8
+ */
4
9
  constructor({pretty, query}) {
5
10
  this.pretty = pretty
6
11
  this.query = query
7
12
  }
8
13
 
9
14
  toSql() {
10
- const {pretty, query} = digs(this, "pretty", "query")
15
+ const {pretty, query} = this
11
16
  let sql = ""
12
17
 
13
18
  if (query._orders.length == 0) return sql
@@ -19,11 +24,10 @@ export default class VelocuiousDatabaseQueryParserOrderParser {
19
24
  }
20
25
 
21
26
  sql += "ORDER BY"
27
+ let count = 0
22
28
 
23
- for (const orderKey in query._orders) {
24
- const order = query._orders[orderKey]
25
-
26
- if (orderKey > 0) sql += " ,"
29
+ for (const order of query._orders) {
30
+ if (count > 0) sql += " ,"
27
31
 
28
32
  if (pretty) {
29
33
  sql += "\n "
@@ -32,6 +36,7 @@ export default class VelocuiousDatabaseQueryParserOrderParser {
32
36
  }
33
37
 
34
38
  sql += order.toSql()
39
+ count++
35
40
  }
36
41
 
37
42
  return sql
@@ -1,4 +1,5 @@
1
- import {digs} from "diggerize"
1
+ // @ts-check
2
+
2
3
  import restArgsError from "../../utils/rest-args-error.js"
3
4
 
4
5
  export default class VelociousDatabaseQueryParserSelectParser {
@@ -15,7 +16,7 @@ export default class VelociousDatabaseQueryParserSelectParser {
15
16
  }
16
17
 
17
18
  toSql() {
18
- const {pretty, query} = digs(this, "pretty", "query")
19
+ const {pretty, query} = this
19
20
 
20
21
  let sql = ""
21
22
 
@@ -27,14 +28,14 @@ export default class VelociousDatabaseQueryParserSelectParser {
27
28
  sql += " "
28
29
  }
29
30
 
30
- for (const selectKey in query._selects) {
31
- const selectValue = query._selects[selectKey]
31
+ let count = 0
32
32
 
33
+ for (const selectValue of query._selects) {
33
34
  selectValue.setQuery(query)
34
35
 
35
36
  sql += selectValue.toSql()
36
37
 
37
- if (selectKey + 1 < query._selects.length) {
38
+ if (count + 1 < query._selects.length) {
38
39
  if (pretty) {
39
40
  sql += ","
40
41
  sql += " "
@@ -42,6 +43,8 @@ export default class VelociousDatabaseQueryParserSelectParser {
42
43
  sql += ", "
43
44
  }
44
45
  }
46
+
47
+ count++
45
48
  }
46
49
 
47
50
  if (query.getSelects().length == 0) {