velocious 1.0.96 → 1.0.98

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 (86) hide show
  1. package/eslint.config.js +1 -0
  2. package/package.json +2 -1
  3. package/spec/database/connection/drivers/mysql/query-parser-spec.js +4 -4
  4. package/spec/http-server/post-spec.js +2 -0
  5. package/src/application.js +27 -9
  6. package/src/configuration-resolver.js +29 -10
  7. package/src/configuration-types.js +44 -0
  8. package/src/configuration.js +63 -33
  9. package/src/database/drivers/base-column.js +6 -1
  10. package/src/database/drivers/base-columns-index.js +11 -1
  11. package/src/database/drivers/base-foreign-key.js +45 -0
  12. package/src/database/drivers/base-table.js +24 -2
  13. package/src/database/drivers/base.js +211 -39
  14. package/src/database/drivers/mssql/index.js +1 -3
  15. package/src/database/drivers/sqlite/sql/alter-table.js +4 -2
  16. package/src/database/handler.js +5 -0
  17. package/src/database/migration/index.js +77 -19
  18. package/src/database/migrator/files-finder.js +21 -22
  19. package/src/database/migrator/types.js +29 -0
  20. package/src/database/migrator.js +98 -59
  21. package/src/database/pool/async-tracked-multi-connection.js +42 -7
  22. package/src/database/pool/base-methods-forward.js +37 -0
  23. package/src/database/pool/base.js +79 -46
  24. package/src/database/pool/single-multi-use.js +18 -3
  25. package/src/database/query/alter-table-base.js +4 -4
  26. package/src/database/query/base.js +9 -2
  27. package/src/database/query/create-database-base.js +8 -0
  28. package/src/database/query/create-index-base.js +20 -5
  29. package/src/database/query/create-table-base.js +28 -9
  30. package/src/database/query/from-base.js +17 -0
  31. package/src/database/query/from-plain.js +8 -3
  32. package/src/database/query/from-table.js +8 -3
  33. package/src/database/query/index.js +43 -32
  34. package/src/database/query/join-base.js +28 -1
  35. package/src/database/query/join-object.js +67 -0
  36. package/src/database/query/join-plain.js +6 -1
  37. package/src/database/query/order-base.js +18 -0
  38. package/src/database/query/order-plain.js +8 -2
  39. package/src/database/query/select-base.js +15 -0
  40. package/src/database/query/select-plain.js +6 -1
  41. package/src/database/query/select-table-and-column.js +8 -2
  42. package/src/database/query/where-base.js +23 -1
  43. package/src/database/query/where-hash.js +15 -0
  44. package/src/database/query/where-plain.js +6 -0
  45. package/src/database/query-parser/base-query-parser.js +8 -2
  46. package/src/database/query-parser/from-parser.js +2 -0
  47. package/src/database/query-parser/joins-parser.js +10 -45
  48. package/src/database/query-parser/select-parser.js +2 -0
  49. package/src/database/record/index.js +1 -1
  50. package/src/database/table-data/index.js +39 -121
  51. package/src/database/table-data/table-column.js +54 -25
  52. package/src/database/table-data/table-foreign-key.js +5 -3
  53. package/src/database/table-data/table-index.js +12 -6
  54. package/src/database/table-data/table-reference.js +2 -0
  55. package/src/database/use-database.js +4 -2
  56. package/src/environment-handlers/base.js +41 -8
  57. package/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -0
  58. package/src/environment-handlers/node/cli/commands/generate/migration.js +3 -0
  59. package/src/environment-handlers/node/cli/commands/generate/model.js +3 -0
  60. package/src/environment-handlers/node/cli/commands/init.js +3 -0
  61. package/src/environment-handlers/node/cli/commands/test.js +17 -3
  62. package/src/environment-handlers/node.js +59 -28
  63. package/src/http-client/header.js +6 -0
  64. package/src/http-client/request.js +31 -5
  65. package/src/http-client/response.js +31 -7
  66. package/src/http-server/client/index.js +24 -4
  67. package/src/http-server/client/request-buffer/form-data-part.js +11 -0
  68. package/src/http-server/client/request-buffer/header.js +6 -0
  69. package/src/http-server/client/request-buffer/index.js +91 -13
  70. package/src/http-server/client/request-parser.js +26 -0
  71. package/src/http-server/client/request-runner.js +15 -3
  72. package/src/http-server/client/request.js +17 -0
  73. package/src/http-server/client/response.js +41 -1
  74. package/src/http-server/index.js +32 -4
  75. package/src/http-server/server-client.js +33 -2
  76. package/src/http-server/worker-handler/index.js +42 -9
  77. package/src/http-server/worker-handler/worker-script.js +2 -0
  78. package/src/http-server/worker-handler/worker-thread.js +34 -6
  79. package/src/logger.js +21 -15
  80. package/src/routes/app-routes.js +1 -1
  81. package/src/testing/test-files-finder.js +96 -9
  82. package/src/testing/test-runner.js +77 -25
  83. package/src/utils/backtrace-cleaner.js +6 -4
  84. package/src/utils/ensure-error.js +13 -0
  85. package/src/utils/file-exists.js +3 -1
  86. package/src/utils/rest-args-error.js +2 -0
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import {addTrackedStackToError} from "../utils/with-tracked-stack.js"
2
4
  import Application from "../../src/application.js"
3
5
  import BacktraceCleaner from "../utils/backtrace-cleaner.js"
@@ -5,6 +7,34 @@ import RequestClient from "./request-client.js"
5
7
  import restArgsError from "../utils/rest-args-error.js"
6
8
  import {tests} from "./test.js"
7
9
 
10
+ /**
11
+ * @typedef {object} TestArgs
12
+ * @property {Application} application
13
+ * @property {RequestClient} client
14
+ * @property {boolean} focus
15
+ * @property {string} type
16
+ */
17
+
18
+ /**
19
+ * @typedef {object} TestData
20
+ * @property {TestArgs} args
21
+ * @property {function(TestArgs) : Promise<void>} function
22
+ */
23
+
24
+ /**
25
+ * @typedef {object} AfterBeforeEachCallback
26
+ * @property {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : Promise<void>} callback
27
+ */
28
+
29
+ /**
30
+ * @typedef {object} TestsArgument
31
+ * @property {boolean} [anyTestsFocussed]
32
+ * @property {AfterBeforeEachCallback[]} afterEaches
33
+ * @property {AfterBeforeEachCallback[]} beforeEaches
34
+ * @property {Record<string, TestData>} tests - A unique identifier for the node.
35
+ * @property {Record<string, TestsArgument>} subs - Optional child nodes. Each item is another `Node`, allowing recursion.
36
+ */
37
+
8
38
  export default class TestRunner {
9
39
  /**
10
40
  * @param {object} args
@@ -18,6 +48,10 @@ export default class TestRunner {
18
48
 
19
49
  this._configuration = configuration
20
50
  this._testFiles = testFiles
51
+
52
+ this._failedTests = 0
53
+ this._successfulTests = 0
54
+ this._testsCount = 0
21
55
  }
22
56
 
23
57
  /**
@@ -26,7 +60,7 @@ export default class TestRunner {
26
60
  getConfiguration() { return this._configuration }
27
61
 
28
62
  /**
29
- * @returns {Array<string>}
63
+ * @returns {string[]}
30
64
  */
31
65
  getTestFiles() { return this._testFiles }
32
66
 
@@ -37,13 +71,6 @@ export default class TestRunner {
37
71
  if (!this._application) {
38
72
  this._application = new Application({
39
73
  configuration: this.getConfiguration(),
40
- databases: {
41
- default: {
42
- host: "mysql",
43
- username: "user",
44
- password: ""
45
- }
46
- },
47
74
  httpServer: {port: 31006},
48
75
  type: "test-runner"
49
76
  })
@@ -56,7 +83,7 @@ export default class TestRunner {
56
83
  }
57
84
 
58
85
  /**
59
- * @returns {RequestClient}
86
+ * @returns {Promise<RequestClient>}
60
87
  */
61
88
  async requestClient() {
62
89
  if (!this._requestClient) {
@@ -67,7 +94,7 @@ export default class TestRunner {
67
94
  }
68
95
 
69
96
  /**
70
- * @returns {void}
97
+ * @returns {Promise<void>}
71
98
  */
72
99
  async importTestFiles() {
73
100
  await this.getConfiguration().getEnvironmentHandler().importTestFiles(this.getTestFiles())
@@ -76,25 +103,37 @@ export default class TestRunner {
76
103
  /**
77
104
  * @returns {boolean}
78
105
  */
79
- isFailed() { return this._failedTests > 0 }
106
+ isFailed() { return this._failedTests !== undefined && this._failedTests > 0 }
80
107
 
81
108
  /**
82
109
  * @returns {number}
83
110
  */
84
- getFailedTests() { return this._failedTests }
111
+ getFailedTests() {
112
+ if (this._failedTests === undefined) throw new Error("Tests hasn't been run yet")
113
+
114
+ return this._failedTests
115
+ }
85
116
 
86
117
  /**
87
118
  * @returns {number}
88
119
  */
89
- getSuccessfulTests() { return this._successfulTests }
120
+ getSuccessfulTests() {
121
+ if (this._successfulTests === undefined) throw new Error("Tests hasn't been run yet")
122
+
123
+ return this._successfulTests
124
+ }
90
125
 
91
126
  /**
92
127
  * @returns {number}
93
128
  */
94
- getTestsCount() { return this._testsCount }
129
+ getTestsCount() {
130
+ if (this._testsCount === undefined) throw new Error("Tests hasn't been run yet")
131
+
132
+ return this._testsCount
133
+ }
95
134
 
96
135
  /**
97
- * @returns {void}
136
+ * @returns {Promise<void>}
98
137
  */
99
138
  async prepare() {
100
139
  this.anyTestsFocussed = false
@@ -124,7 +163,7 @@ export default class TestRunner {
124
163
  }
125
164
 
126
165
  /**
127
- * @returns {void}
166
+ * @returns {Promise<void>}
128
167
  */
129
168
  async run() {
130
169
  await this.getConfiguration().ensureConnections(async () => {
@@ -139,7 +178,8 @@ export default class TestRunner {
139
178
  }
140
179
 
141
180
  /**
142
- * @returns {object}
181
+ * @param {TestsArgument} tests
182
+ * @returns {{anyTestsFocussed: boolean}}
143
183
  */
144
184
  analyzeTests(tests) {
145
185
  let anyTestsFocussedFound = false
@@ -171,6 +211,12 @@ export default class TestRunner {
171
211
  }
172
212
 
173
213
  /**
214
+ * @param {object} args
215
+ * @param {Array<AfterBeforeEachCallback>} args.afterEaches
216
+ * @param {Array<AfterBeforeEachCallback>} args.beforeEaches
217
+ * @param {TestsArgument} args.tests
218
+ * @param {string[]} args.descriptions
219
+ * @param {number} args.indentLevel
174
220
  * @returns {Promise<void>}
175
221
  */
176
222
  async runTests({afterEaches, beforeEaches, tests, descriptions, indentLevel}) {
@@ -180,7 +226,7 @@ export default class TestRunner {
180
226
 
181
227
  for (const testDescription in tests.tests) {
182
228
  const testData = tests.tests[testDescription]
183
- const testArgs = Object.assign({}, testData.args)
229
+ const testArgs = /** @type {TestArgs} */ (Object.assign({}, testData.args))
184
230
 
185
231
  if (this._onlyFocussed && !testArgs.focus) continue
186
232
 
@@ -204,15 +250,21 @@ export default class TestRunner {
204
250
  } catch (error) {
205
251
  this._failedTests++
206
252
 
207
- console.error(`${leftPadding} Test failed: ${error.message}`)
208
- addTrackedStackToError(error)
253
+ if (error instanceof Error) {
254
+ console.error(`${leftPadding} Test failed:`, error.message)
255
+ addTrackedStackToError(error)
209
256
 
210
- const backtraceCleaner = new BacktraceCleaner(error)
211
- const cleanedStack = backtraceCleaner.getCleanedStack()
212
- const stackLines = cleanedStack.split("\n")
257
+ const backtraceCleaner = new BacktraceCleaner(error)
258
+ const cleanedStack = backtraceCleaner.getCleanedStack()
259
+ const stackLines = cleanedStack?.split("\n")
213
260
 
214
- for (const stackLine of stackLines) {
215
- console.error(`${leftPadding} ${stackLine}`)
261
+ if (stackLines) {
262
+ for (const stackLine of stackLines) {
263
+ console.error(`${leftPadding} ${stackLine}`)
264
+ }
265
+ }
266
+ } else {
267
+ console.error(`${leftPadding} Test failed with a ${typeof error}:`, error)
216
268
  }
217
269
  } finally {
218
270
  for (const afterEachData of newAfterEaches) {
@@ -1,7 +1,9 @@
1
+ // @ts-check
2
+
1
3
  export default class BacktraceCleaner {
2
4
  /**
3
5
  * @param {Error} error
4
- * @returns {string}
6
+ * @returns {string | undefined}
5
7
  */
6
8
  static getCleanedStack(error) {
7
9
  return new BacktraceCleaner(error).getCleanedStack()
@@ -15,11 +17,11 @@ export default class BacktraceCleaner {
15
17
  }
16
18
 
17
19
  /**
18
- * @returns {string}
20
+ * @returns {string | undefined}
19
21
  */
20
22
  getCleanedStack() {
21
- const backtrace = this.error.stack.split("\n")
23
+ const backtrace = this.error?.stack?.split("\n")
22
24
 
23
- return backtrace.filter((line) => !line.includes("node_modules") && !line.includes("(node:internal/process/")).join("\n")
25
+ return backtrace?.filter((line) => !line.includes("node_modules") && !line.includes("(node:internal/process/")).join("\n")
24
26
  }
25
27
  }
@@ -0,0 +1,13 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @param {any} error
5
+ * @returns {Error}
6
+ */
7
+ export default function ensureError(error) {
8
+ if (error instanceof Error) {
9
+ return error
10
+ } else {
11
+ return new Error(`Unknown error type ${typeof error}: ${error}`)
12
+ }
13
+ }
@@ -1,8 +1,10 @@
1
+ // @ts-check
2
+
1
3
  import fs from "fs/promises"
2
4
 
3
5
  /**
4
6
  * @param {string} path
5
- * @returns {boolean}
7
+ * @returns {Promise<boolean>}
6
8
  */
7
9
  export default async function fileExists(path) {
8
10
  try {
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * @param {object} restArgs
3
5
  * @returns {void}