velocious 1.0.103 → 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 (88) hide show
  1. package/package.json +1 -1
  2. package/spec/database/record/create-spec.js +7 -0
  3. package/spec/dummy/dummy-directory.js +2 -0
  4. package/spec/dummy/index.js +5 -1
  5. package/spec/dummy/src/model-bases/project.js +18 -0
  6. package/src/application.js +1 -0
  7. package/src/configuration-types.js +6 -0
  8. package/src/controller.js +44 -24
  9. package/src/database/drivers/base-foreign-key.js +1 -1
  10. package/src/database/drivers/base.js +2 -2
  11. package/src/database/drivers/mssql/column.js +6 -0
  12. package/src/database/drivers/mssql/columns-index.js +2 -5
  13. package/src/database/drivers/mssql/foreign-key.js +2 -0
  14. package/src/database/drivers/mssql/options.js +25 -0
  15. package/src/database/drivers/mssql/query-parser.js +2 -0
  16. package/src/database/drivers/mysql/options.js +9 -0
  17. package/src/database/drivers/mysql/sql/alter-table.js +2 -0
  18. package/src/database/drivers/mysql/sql/create-database.js +2 -0
  19. package/src/database/drivers/mysql/sql/create-index.js +2 -0
  20. package/src/database/drivers/mysql/sql/create-table.js +2 -0
  21. package/src/database/drivers/mysql/sql/delete.js +2 -0
  22. package/src/database/drivers/mysql/sql/drop-table.js +2 -0
  23. package/src/database/drivers/mysql/sql/insert.js +2 -0
  24. package/src/database/drivers/mysql/sql/update.js +2 -0
  25. package/src/database/drivers/pgsql/column.js +6 -0
  26. package/src/database/drivers/pgsql/columns-index.js +2 -0
  27. package/src/database/drivers/pgsql/foreign-key.js +2 -0
  28. package/src/database/drivers/pgsql/options.js +9 -0
  29. package/src/database/drivers/pgsql/query-parser.js +2 -0
  30. package/src/database/drivers/pgsql/sql/alter-table.js +2 -0
  31. package/src/database/drivers/pgsql/sql/create-database.js +5 -4
  32. package/src/database/drivers/pgsql/sql/create-index.js +2 -0
  33. package/src/database/drivers/pgsql/sql/create-table.js +2 -0
  34. package/src/database/drivers/pgsql/sql/delete.js +2 -0
  35. package/src/database/drivers/pgsql/sql/drop-table.js +2 -0
  36. package/src/database/drivers/pgsql/sql/insert.js +2 -0
  37. package/src/database/drivers/pgsql/sql/update.js +2 -0
  38. package/src/database/drivers/pgsql/table.js +6 -0
  39. package/src/database/drivers/sqlite/columns-index.js +2 -6
  40. package/src/database/drivers/sqlite/connection-remote.js +7 -0
  41. package/src/database/drivers/sqlite/connection-sql-js.js +12 -2
  42. package/src/database/drivers/sqlite/foreign-key.js +7 -0
  43. package/src/database/drivers/sqlite/index.js +7 -1
  44. package/src/database/drivers/sqlite/index.web.js +12 -3
  45. package/src/database/drivers/sqlite/options.js +9 -0
  46. package/src/database/drivers/sqlite/query-parser.js +2 -0
  47. package/src/database/drivers/sqlite/query.js +19 -6
  48. package/src/database/drivers/sqlite/query.web.js +13 -1
  49. package/src/database/initializer-from-require-context.js +11 -1
  50. package/src/database/migrator/types.js +2 -0
  51. package/src/database/pool/base-methods-forward.js +7 -0
  52. package/src/database/query/delete-base.js +8 -0
  53. package/src/database/query/preloader/belongs-to.js +16 -1
  54. package/src/database/query/preloader/has-many.js +19 -1
  55. package/src/database/query/preloader/has-one.js +20 -2
  56. package/src/database/query/preloader.js +19 -4
  57. package/src/database/query/update-base.js +9 -0
  58. package/src/database/query-parser/limit-parser.js +7 -2
  59. package/src/database/query-parser/options.js +47 -6
  60. package/src/database/query-parser/order-parser.js +11 -6
  61. package/src/database/query-parser/select-parser.js +8 -5
  62. package/src/database/query-parser/where-parser.js +11 -5
  63. package/src/database/record/index.js +28 -24
  64. package/src/database/record/instance-relationships/base.js +10 -1
  65. package/src/database/record/record-not-found-error.js +2 -0
  66. package/src/database/record/user-module.js +13 -0
  67. package/src/database/record/validators/uniqueness.js +13 -2
  68. package/src/environment-handlers/node/cli/commands/generate/base-models.js +19 -0
  69. package/src/error-logger.js +17 -3
  70. package/src/http-client/index.js +34 -2
  71. package/src/http-client/request.js +1 -1
  72. package/src/http-server/client/params-to-object.js +28 -0
  73. package/src/initializer.js +2 -0
  74. package/src/routes/app-routes.js +3 -1
  75. package/src/routes/base-route.js +67 -58
  76. package/src/routes/basic-route.js +76 -0
  77. package/src/routes/get-route.js +21 -5
  78. package/src/routes/index.js +10 -0
  79. package/src/routes/namespace-route.js +21 -5
  80. package/src/routes/post-route.js +20 -5
  81. package/src/routes/resolver.js +15 -2
  82. package/src/routes/resource-route.js +21 -5
  83. package/src/routes/root-route.js +3 -3
  84. package/src/testing/request-client.js +19 -14
  85. package/src/testing/test-runner.js +16 -10
  86. package/src/testing/test.js +70 -22
  87. package/src/utils/with-tracked-stack-async-hooks.js +22 -4
  88. package/src/utils/with-tracked-stack.js +9 -0
@@ -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) {
@@ -1,13 +1,18 @@
1
- import {digs} from "diggerize"
1
+ // @ts-check
2
2
 
3
3
  export default class VelocuiousDatabaseQueryParserWhereParser {
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._wheres.length == 0) return sql
@@ -20,10 +25,10 @@ export default class VelocuiousDatabaseQueryParserWhereParser {
20
25
 
21
26
  sql += "WHERE"
22
27
 
23
- for (const whereKey in query._wheres) {
24
- const where = query._wheres[whereKey]
28
+ let count = 0
25
29
 
26
- if (whereKey > 0) sql += " AND"
30
+ for (const where of query._wheres) {
31
+ if (count > 0) sql += " AND"
27
32
 
28
33
  if (pretty) {
29
34
  sql += "\n "
@@ -32,6 +37,7 @@ export default class VelocuiousDatabaseQueryParserWhereParser {
32
37
  }
33
38
 
34
39
  sql += where.toSql()
40
+ count++
35
41
  }
36
42
 
37
43
  return sql
@@ -468,9 +468,6 @@ class VelociousDatabaseRecord {
468
468
  const columnNameToAttributeName = this.getColumnNameToAttributeNameMap()
469
469
  const attributeNameToColumnName = this.getAttributeNameToColumnNameMap()
470
470
 
471
- /** @type {Record<string, (this: VelociousDatabaseRecord) => unknown>} */
472
- const proto = /** @type {any} */ (this.prototype);
473
-
474
471
  for (const column of this._columns) {
475
472
  this._columnsAsHash[column.getName()] = column
476
473
 
@@ -480,17 +477,18 @@ class VelociousDatabaseRecord {
480
477
  attributeNameToColumnName[camelizedColumnName] = column.getName()
481
478
  columnNameToAttributeName[column.getName()] = camelizedColumnName
482
479
 
483
- proto[camelizedColumnName] = function() {
480
+ // @ts-expect-error
481
+ this.prototype[camelizedColumnName] = function() {
484
482
  return this.readAttribute(camelizedColumnName)
485
483
  }
486
484
 
487
485
  // @ts-expect-error
488
- proto[`set${camelizedColumnNameBigFirst}`] = function(newValue) {
489
- // @ts-expect-error
486
+ this.prototype[`set${camelizedColumnNameBigFirst}`] = function(newValue) {
490
487
  return this._setColumnAttribute(camelizedColumnName, newValue)
491
488
  }
492
489
 
493
- proto[`has${camelizedColumnNameBigFirst}`] = function() {
490
+ // @ts-expect-error
491
+ this.prototype[`has${camelizedColumnNameBigFirst}`] = function() {
494
492
  // @ts-expect-error
495
493
  let value = this[camelizedColumnName]()
496
494
 
@@ -539,24 +537,20 @@ class VelociousDatabaseRecord {
539
537
  const nameCamelized = inflection.camelize(name)
540
538
  const setterMethodName = `set${nameCamelized}`
541
539
 
542
- /** @type {Record<string, unknown>} */
543
540
  // @ts-expect-error
544
- const self = this
545
-
546
- /** @type {Record<string, (this: VelociousDatabaseRecord) => unknown>} */
547
- const proto = /** @type {any} */ (this.prototype);
548
-
549
- proto[name] = function getTranslatedAttribute() {
541
+ this.prototype[name] = function getTranslatedAttribute() {
550
542
  const locale = this._getConfiguration().getLocale()
551
543
 
552
544
  return this._getTranslatedAttributeWithFallback(name, locale)
553
545
  }
554
546
 
555
- proto[`has${nameCamelized}`] = function hasTranslatedAttribute() {
556
- const candidate = self[name]
547
+ // @ts-expect-error
548
+ this.prototype[`has${nameCamelized}`] = function hasTranslatedAttribute() {
549
+ // @ts-expect-error
550
+ const candidate = this[name]
557
551
 
558
552
  if (typeof candidate == "function") {
559
- const value = candidate()
553
+ const value = candidate.bind(this)()
560
554
 
561
555
  return this._hasAttribute(value)
562
556
  } else {
@@ -565,11 +559,9 @@ class VelociousDatabaseRecord {
565
559
  }
566
560
 
567
561
  // @ts-expect-error
568
- proto[setterMethodName] = function setTranslatedAttribute(newValue) {
569
- // @ts-expect-error
562
+ this.prototype[setterMethodName] = function setTranslatedAttribute(newValue) {
570
563
  const locale = this._getConfiguration().getLocale()
571
564
 
572
- // @ts-expect-error
573
565
  return this._setTranslatedAttribute(name, locale, newValue)
574
566
  }
575
567
 
@@ -577,6 +569,7 @@ class VelociousDatabaseRecord {
577
569
  const localeCamelized = inflection.camelize(locale)
578
570
  const getterMethodNameLocalized = `${name}${localeCamelized}`
579
571
  const setterMethodNameLocalized = `${setterMethodName}${localeCamelized}`
572
+ const hasMethodNameLocalized = `has${inflection.camelize(name)}${localeCamelized}`
580
573
 
581
574
  // @ts-expect-error
582
575
  this.prototype[getterMethodNameLocalized] = function getTranslatedAttributeWithLocale() {
@@ -587,6 +580,20 @@ class VelociousDatabaseRecord {
587
580
  this.prototype[setterMethodNameLocalized] = function setTranslatedAttributeWithLocale(newValue) {
588
581
  return this._setTranslatedAttribute(name, locale, newValue)
589
582
  }
583
+
584
+ // @ts-expect-error
585
+ this.prototype[hasMethodNameLocalized] = function hasTranslatedAttribute() {
586
+ // @ts-expect-error
587
+ const candidate = this[getterMethodNameLocalized]
588
+
589
+ if (typeof candidate == "function") {
590
+ const value = candidate.bind(this)()
591
+
592
+ return this._hasAttribute(value)
593
+ } else {
594
+ throw new Error(`Expected candidate to be a function but it was: ${typeof candidate}`)
595
+ }
596
+ }
590
597
  }
591
598
  }
592
599
  }
@@ -621,10 +628,7 @@ class VelociousDatabaseRecord {
621
628
  return this._attributes[columnName]
622
629
  }
623
630
 
624
- /**
625
- *
626
- * @returns {typeof VelociousDatabaseRecord}
627
- */
631
+ /** @returns {typeof VelociousDatabaseRecord} */
628
632
  getModelClass() {
629
633
  const modelClass = /** @type {typeof VelociousDatabaseRecord} */ (this.constructor)
630
634
 
@@ -15,6 +15,15 @@ export default class VelociousDatabaseRecordBaseInstanceRelationship {
15
15
  this.relationship = relationship
16
16
  }
17
17
 
18
+ /**
19
+ * @abstract
20
+ * @param {import("../index.js").default[]} records
21
+ * @returns {void}
22
+ */
23
+ addToLoaded(records) { // eslint-disable-line no-unused-vars
24
+ throw new Error("addToLoaded not implemented")
25
+ }
26
+
18
27
  /**
19
28
  * @abstract
20
29
  * @param {Record<string, any>} attributes
@@ -62,7 +71,7 @@ export default class VelociousDatabaseRecordBaseInstanceRelationship {
62
71
  return this._loaded
63
72
  }
64
73
 
65
- /** @param {import("../index.js").default|Array<import("../index.js").default>} model */
74
+ /** @param {import("../index.js").default|Array<import("../index.js").default>|undefined} model */
66
75
  setLoaded(model) { this._loaded = model }
67
76
 
68
77
  /** @returns {import("../index.js").default | import("../index.js").default[] | undefined} */
@@ -1 +1,3 @@
1
+ // @ts-check
2
+
1
3
  export default class RecordNotFoundError extends Error {}
@@ -1,7 +1,13 @@
1
+ // @ts-check
2
+
1
3
  import bcryptjs from "bcryptjs"
2
4
  import restArgsError from "../../utils/rest-args-error.js"
3
5
 
4
6
  export default class UserModule {
7
+ /**
8
+ * @param {object} args
9
+ * @param {string} args.secretKey
10
+ */
5
11
  constructor({secretKey, ...restArgs}) {
6
12
  restArgsError(restArgs)
7
13
 
@@ -10,18 +16,25 @@ export default class UserModule {
10
16
  this.secretKey = secretKey
11
17
  }
12
18
 
19
+ /**
20
+ * @param {typeof import("./index.js").default} UserClass
21
+ */
13
22
  attachTo(UserClass) {
23
+ // @ts-expect-error
14
24
  UserClass.prototype.setPassword = function(newPassword) {
15
25
  const salt = bcryptjs.genSaltSync(10)
16
26
  const encryptedPassword = bcryptjs.hashSync(newPassword, salt)
17
27
 
28
+ // @ts-expect-error
18
29
  this.setEncryptedPassword(encryptedPassword)
19
30
  }
20
31
 
32
+ // @ts-expect-error
21
33
  UserClass.prototype.setPasswordConfirmation = function(newPasswordConfirmation) {
22
34
  const salt = bcryptjs.genSaltSync(10)
23
35
  const encryptedPassword = bcryptjs.hashSync(newPasswordConfirmation, salt)
24
36
 
37
+ // @ts-expect-error
25
38
  this._encryptedPasswordConfirmation = encryptedPassword
26
39
  }
27
40
  }
@@ -1,18 +1,29 @@
1
+ // @ts-check
2
+
1
3
  import Base from "./base.js"
2
4
  import * as inflection from "inflection"
3
5
 
4
6
  export default class VelociousDatabaseRecordValidatorsUniqueness extends Base {
7
+ /**
8
+ * @param {object} args
9
+ * @param {import("../index.js").default} args.model
10
+ * @param {string} args.attributeName
11
+ * @returns {Promise<void>}
12
+ */
5
13
  async validate({model, attributeName}) {
6
- const modelClass = model.constructor
14
+ const modelClass = /** @type {typeof import("../index.js").default} */ (model.constructor)
15
+
7
16
  const connection = modelClass.connection()
8
17
  const tableName = modelClass._getTable().getName()
9
18
  const attributeValue = model.readAttribute(attributeName)
10
19
  const attributeNameUnderscore = inflection.underscore(attributeName)
20
+
21
+ /** @type {Record<string, any>} */
11
22
  const whereArgs = {}
12
23
 
13
24
  whereArgs[attributeNameUnderscore] = attributeValue
14
25
 
15
- let existingRecordQuery = model.constructor
26
+ let existingRecordQuery = modelClass
16
27
  .select(modelClass.primaryKey())
17
28
  .where(whereArgs)
18
29
 
@@ -98,6 +98,16 @@ export default class DbGenerateModel extends BaseCommand {
98
98
  fileContent += ` ${name}() { return this._getTranslatedAttributeWithFallback("${name}", this._getConfiguration().getLocale()) }\n`
99
99
  methodsCount++
100
100
 
101
+ const hasName = `has${inflection.camelize(name)}`
102
+
103
+ fileContent += `\n`
104
+ fileContent += " /**\n"
105
+ fileContent += ` * @abstract\n`
106
+ fileContent += ` * @returns {boolean}\n`
107
+ fileContent += " */\n"
108
+ fileContent += ` ${hasName}() { throw new Error("${hasName} not implemented") }\n`
109
+ methodsCount++
110
+
101
111
  for (const locale of this.getConfiguration().getLocales()) {
102
112
  const localeMethodName = `${name}${inflection.camelize(locale)}`
103
113
 
@@ -109,7 +119,16 @@ export default class DbGenerateModel extends BaseCommand {
109
119
  }
110
120
 
111
121
  fileContent += ` ${localeMethodName}() { return this._getTranslatedAttributeWithFallback("${name}", "${locale}") }\n`
122
+ methodsCount++
123
+
124
+ const localeHasName = `has${inflection.camelize(localeMethodName)}`
112
125
 
126
+ fileContent += `\n`
127
+ fileContent += " /**\n"
128
+ fileContent += ` * @abstract\n`
129
+ fileContent += ` * @returns {boolean}\n`
130
+ fileContent += " */\n"
131
+ fileContent += ` ${localeHasName}() { throw new Error("${localeHasName} not implemented") }\n`
113
132
  methodsCount++
114
133
  }
115
134
  }
@@ -1,13 +1,27 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @param {(...args: any[]) => Promise<void>} callback
5
+ */
1
6
  export default function errorLogger(callback) {
7
+ /**
8
+ * @param {...any} args
9
+ * @returns {Promise<void>}
10
+ */
2
11
  return async function(...args) {
3
12
  try {
4
13
  await callback(...args)
5
14
  } catch (error) {
6
- console.error(`ErrorLogger: ${error.message}`)
15
+ if (error instanceof Error) {
16
+ console.error(`ErrorLogger: ${error.message}`)
7
17
 
8
- if (error.stack) {
9
- console.error("Stack", error.stack)
18
+ if (error.stack) {
19
+ console.error("Stack", error.stack)
20
+ } else {
21
+ console.error("No stack")
22
+ }
10
23
  } else {
24
+ console.error(`ErrorLogger: ${error}`)
11
25
  console.error("No stack")
12
26
  }
13
27
 
@@ -1,9 +1,17 @@
1
+ // @ts-check
2
+
1
3
  import net from "net"
2
4
  import Request from "./request.js"
3
5
  import Response from "./response.js"
4
6
  import {Logger} from "../logger.js"
5
7
 
6
8
  export default class HttpClient {
9
+ /**
10
+ * @param {object} args
11
+ * @param {boolean} [args.debug]
12
+ * @param {Array<import("./header.js").default>} [args.headers]
13
+ * @param {string} [args.version]
14
+ */
7
15
  constructor({debug = false, headers, version = "1.1"}) {
8
16
  this.headers = headers || []
9
17
  this.logger = new Logger(this, {debug})
@@ -15,7 +23,7 @@ export default class HttpClient {
15
23
  this.connectionReject = reject
16
24
  this.connection = net.createConnection(3006, "127.0.0.1", () => {
17
25
  this.connectionReject = null
18
- resolve()
26
+ resolve(null)
19
27
  })
20
28
 
21
29
  this.connection.on("data", this.onConnectionData)
@@ -24,6 +32,12 @@ export default class HttpClient {
24
32
  })
25
33
  }
26
34
 
35
+ /**
36
+ * @param {string} path
37
+ * @param {object} [options]
38
+ * @param {Array<import("./header.js").default>} [options.headers]
39
+ * @returns {Promise<{request: import("./request.js").default, response: import("./response.js").default}>}
40
+ */
27
41
  get(path, {headers} = {}) {
28
42
  if (!this.connection) throw new Error("Not connected yet")
29
43
 
@@ -41,7 +55,7 @@ export default class HttpClient {
41
55
 
42
56
  for (const header of this.headers) {
43
57
  const existingNewHeader = newHeaders.find((newHeader) => {
44
- return newHeader.key.toLowerCase().trim() === header.key.toLowerCase().trim()
58
+ return newHeader.getName().toLowerCase().trim() === header.getName().toLowerCase().trim()
45
59
  })
46
60
 
47
61
  if (!existingNewHeader) {
@@ -56,8 +70,14 @@ export default class HttpClient {
56
70
  this.currentRequest.stream((chunk) => {
57
71
  this.logger.debug(() => [`Writing: ${chunk}`])
58
72
 
73
+ if (!this.connection) {
74
+ throw new Error("No connection to write to")
75
+ }
76
+
59
77
  this.connection.write(chunk, "utf8", (error) => {
60
78
  if (error) {
79
+ if (!this.currentRequestReject) throw new Error("No current request reject function")
80
+
61
81
  this.currentRequestReject(error)
62
82
  }
63
83
  })
@@ -65,7 +85,12 @@ export default class HttpClient {
65
85
  })
66
86
  }
67
87
 
88
+ /**
89
+ * @param {Buffer} data
90
+ */
68
91
  onConnectionData = (data) => {
92
+ if (!this.currentResponse) throw new Error("No current response to feed data to")
93
+
69
94
  this.currentResponse.feed(data)
70
95
  }
71
96
 
@@ -73,6 +98,9 @@ export default class HttpClient {
73
98
  this.connection = null
74
99
  }
75
100
 
101
+ /**
102
+ * @param {Error} error
103
+ */
76
104
  onConnectionError = (error) => {
77
105
  if (this.connectionReject) {
78
106
  this.connectionReject(error)
@@ -90,6 +118,10 @@ export default class HttpClient {
90
118
  }
91
119
 
92
120
  onResponseComplete = () => {
121
+ if (!this.currentRequestResolve) throw new Error("No current request resolve function")
122
+ if (!this.currentRequest) throw new Error("No current request")
123
+ if (!this.currentResponse) throw new Error("No current response")
124
+
93
125
  this.currentRequestResolve({
94
126
  request: this.currentRequest,
95
127
  response: this.currentResponse
@@ -5,7 +5,7 @@ import Header from "./header.js"
5
5
  export default class Request {
6
6
  /**
7
7
  * @param {object} args
8
- * @param {string} args.body
8
+ * @param {string} [args.body]
9
9
  * @param {string} args.method
10
10
  * @param {Header[]} args.headers
11
11
  * @param {string} args.path
@@ -1,4 +1,9 @@
1
+ // @ts-check
2
+
1
3
  export default class ParamsToObject {
4
+ /**
5
+ * @param {Record<string, string>} object
6
+ */
2
7
  constructor(object) {
3
8
  this.object = object
4
9
  }
@@ -15,6 +20,11 @@ export default class ParamsToObject {
15
20
  return result
16
21
  }
17
22
 
23
+ /**
24
+ * @param {string} key
25
+ * @param {string} value
26
+ * @param {Record<string, any> | any[]} result
27
+ */
18
28
  treatInitial(key, value, result) {
19
29
  const firstMatch = key.match(/^(.+?)(\[([\s\S]+$))/)
20
30
 
@@ -22,43 +32,61 @@ export default class ParamsToObject {
22
32
  const inputName = firstMatch[1]
23
33
  const rest = firstMatch[2]
24
34
 
35
+ /** @type {Array<any> | Record<string, any>} */
25
36
  let newResult
26
37
 
27
38
  if (inputName in result) {
39
+ // @ts-expect-error
28
40
  newResult = result[inputName]
29
41
  } else if (rest == "[]") {
30
42
  newResult = []
43
+ // @ts-expect-error
31
44
  result[inputName] = newResult
32
45
  } else {
33
46
  newResult = {}
47
+ // @ts-expect-error
34
48
  result[inputName] = newResult
35
49
  }
36
50
 
37
51
  this.treatSecond(value, rest, newResult)
38
52
  } else {
53
+ // @ts-expect-error
39
54
  result[key] = value
40
55
  }
41
56
  }
42
57
 
58
+ /**
59
+ * @param {string} value
60
+ * @param {string} rest
61
+ * @param {Record<string, any> | any[]} result
62
+ */
43
63
  treatSecond(value, rest, result) {
44
64
  const secondMatch = rest.match(/^\[(.*?)\]([\s\S]*)$/)
65
+
66
+ if (!secondMatch) throw new Error(`Could not parse rest part: ${rest}`)
67
+
45
68
  const key = secondMatch[1]
46
69
  const newRest = secondMatch[2]
47
70
 
71
+ /** @type {Array<any> | Record<string, any>} */
48
72
  let newResult
49
73
 
50
74
  if (rest == "[]") {
51
75
  result.push(value)
52
76
  } else if (newRest == "") {
77
+ // @ts-expect-error
53
78
  result[key] = value
54
79
  } else {
55
80
  if (typeof result == "object" && key in result) {
81
+ // @ts-expect-error
56
82
  newResult = result[key]
57
83
  } else if (newRest == "[]") {
58
84
  newResult = []
85
+ // @ts-expect-error
59
86
  result[key] = newResult
60
87
  } else {
61
88
  newResult = {}
89
+ // @ts-expect-error
62
90
  result[key] = newResult
63
91
  }
64
92
 
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import restArgsError from "./utils/rest-args-error.js"
2
4
 
3
5
  export default class VelociousInitializer {
@@ -1,9 +1,11 @@
1
+ // @ts-check
2
+
1
3
  import {digg} from "diggerize"
2
4
 
3
5
  export default class VelociousRoutesAppRoutes {
4
6
  /**
5
7
  * @param {import("../configuration.js").default} configuration
6
- * @returns {import("./index.js").default}
8
+ * @returns {Promise<import("./index.js").default>}
7
9
  */
8
10
  static async getRoutes(configuration) {
9
11
  // Every client need to make their own routes because they probably can't be shared across different worker threads