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,10 +1,15 @@
1
+ // @ts-check
2
+
1
3
  import restArgsError from "../utils/rest-args-error.js"
2
- import BaseRoute, {initBaseRoute} from "./base-route.js"
4
+ import BaseRoute from "./base-route.js"
5
+ import BasicRoute from "./base-route.js"
3
6
  import escapeStringRegexp from "escape-string-regexp"
4
7
 
5
- initBaseRoute()
6
-
7
- export default class VelociousRouteNamespaceRoute extends BaseRoute {
8
+ class VelociousRouteNamespaceRoute extends BasicRoute {
9
+ /**
10
+ * @param {object} args
11
+ * @param {string} args.name
12
+ */
8
13
  constructor({name, ...restArgs}) {
9
14
  super()
10
15
  restArgsError(restArgs)
@@ -12,7 +17,14 @@ export default class VelociousRouteNamespaceRoute extends BaseRoute {
12
17
  this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
13
18
  }
14
19
 
15
- matchWithPath({params, path}) {
20
+ /**
21
+ * @param {object} args
22
+ * @param {Record<string, any>} args.params
23
+ * @param {string} args.path
24
+ * @param {import("../http-server/client/request.js").default} args.request
25
+ * @returns {{restPath: string} | undefined}
26
+ */
27
+ matchWithPath({params, path, request}) { // eslint-disable-line no-unused-vars
16
28
  const match = path.match(this.regExp)
17
29
 
18
30
  if (match) {
@@ -24,3 +36,7 @@ export default class VelociousRouteNamespaceRoute extends BaseRoute {
24
36
  }
25
37
  }
26
38
  }
39
+
40
+ BaseRoute.registerRouteNamespaceType(VelociousRouteNamespaceRoute)
41
+
42
+ export default VelociousRouteNamespaceRoute
@@ -1,10 +1,14 @@
1
- import BaseRoute, {initBaseRoute} from "./base-route.js"
1
+ // @ts-check
2
+
3
+ import BaseRoute from "./base-route.js"
2
4
  import escapeStringRegexp from "escape-string-regexp"
3
5
  import restArgsError from "../utils/rest-args-error.js"
4
6
 
5
- initBaseRoute()
6
-
7
- export default class VelociousRoutePostRoute extends BaseRoute {
7
+ class VelociousRoutePostRoute extends BaseRoute {
8
+ /**
9
+ * @param {object} args
10
+ * @param {string} args.name
11
+ */
8
12
  constructor({name, ...restArgs}) {
9
13
  super()
10
14
  restArgsError(restArgs)
@@ -12,7 +16,14 @@ export default class VelociousRoutePostRoute extends BaseRoute {
12
16
  this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
13
17
  }
14
18
 
15
- matchWithPath({params, path}) {
19
+ /**
20
+ * @param {object} args
21
+ * @param {Record<string, any>} args.params
22
+ * @param {string} args.path
23
+ * @param {import("../http-server/client/request.js").default} args.request
24
+ * @returns {{restPath: string} | undefined}
25
+ */
26
+ matchWithPath({params, path, request}) { // eslint-disable-line no-unused-vars
16
27
  const match = path.match(this.regExp)
17
28
 
18
29
  if (match) {
@@ -24,3 +35,7 @@ export default class VelociousRoutePostRoute extends BaseRoute {
24
35
  }
25
36
  }
26
37
  }
38
+
39
+ BaseRoute.registerRoutePostType(VelociousRoutePostRoute)
40
+
41
+ export default VelociousRoutePostRoute
@@ -1,10 +1,18 @@
1
- import {digg, digs} from "diggerize"
1
+ // @ts-check
2
+
3
+ import {digg} from "diggerize"
2
4
  import {dirname} from "path"
3
5
  import {fileURLToPath} from "url"
4
6
  import fs from "fs/promises"
5
7
  import * as inflection from "inflection"
6
8
 
7
9
  export default class VelociousRoutesResolver {
10
+ /**
11
+ * @param {object} args
12
+ * @param {import("../configuration.js").default} args.configuration
13
+ * @param {import("../http-server/client/request.js").default} args.request
14
+ * @param {import("../http-server/client/response.js").default} args.response
15
+ */
8
16
  constructor({configuration, request, response}) {
9
17
  if (!configuration) throw new Error("No configuration given")
10
18
  if (!request) throw new Error("No request given")
@@ -65,6 +73,11 @@ export default class VelociousRoutesResolver {
65
73
  })
66
74
  }
67
75
 
76
+ /**
77
+ * @param {import("./base-route.js").default} route
78
+ * @param {string} path
79
+ * @returns {{restPath: string} | undefined}
80
+ */
68
81
  matchPathWithRoutes(route, path) {
69
82
  const pathWithoutSlash = path.replace(/^\//, "")
70
83
 
@@ -77,7 +90,7 @@ export default class VelociousRoutesResolver {
77
90
 
78
91
  if (!matchResult) continue
79
92
 
80
- const {restPath} = digs(matchResult, "restPath")
93
+ const {restPath} = matchResult
81
94
 
82
95
  if (restPath) {
83
96
  return this.matchPathWithRoutes(subRoute, restPath)
@@ -1,10 +1,15 @@
1
- import BaseRoute, {initBaseRoute} from "./base-route.js"
1
+ // @ts-check
2
+
3
+ import BaseRoute from "./base-route.js"
4
+ import BasicRoute from "./basic-route.js"
2
5
  import escapeStringRegexp from "escape-string-regexp"
3
6
  import restArgsError from "../utils/rest-args-error.js"
4
7
 
5
- initBaseRoute()
6
-
7
- export default class VelociousRouteResourceRoute extends BaseRoute {
8
+ class VelociousRouteResourceRoute extends BasicRoute {
9
+ /**
10
+ * @param {object} args
11
+ * @param {string} args.name
12
+ */
8
13
  constructor({name, ...restArgs}) {
9
14
  super()
10
15
  restArgsError(restArgs)
@@ -12,6 +17,13 @@ export default class VelociousRouteResourceRoute extends BaseRoute {
12
17
  this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
13
18
  }
14
19
 
20
+ /**
21
+ * @param {object} args
22
+ * @param {Record<string, any>} args.params
23
+ * @param {string} args.path
24
+ * @param {import("../http-server/client/request.js").default} args.request
25
+ * @returns {{restPath: string} | undefined}
26
+ */
15
27
  matchWithPath({params, path, request}) {
16
28
  const match = path.match(this.regExp)
17
29
 
@@ -22,7 +34,7 @@ export default class VelociousRouteResourceRoute extends BaseRoute {
22
34
  let subRoutesMatchesRestPath = false
23
35
 
24
36
  for (const route of this.routes) {
25
- if (route.matchWithPath({path: restPath})) {
37
+ if (route.matchWithPath({params, path: restPath, request})) {
26
38
  subRoutesMatchesRestPath = true
27
39
  }
28
40
  }
@@ -43,3 +55,7 @@ export default class VelociousRouteResourceRoute extends BaseRoute {
43
55
  }
44
56
  }
45
57
  }
58
+
59
+ BaseRoute.registerRouteResourceType(VelociousRouteResourceRoute)
60
+
61
+ export default VelociousRouteResourceRoute
@@ -1,6 +1,6 @@
1
- import BaseRoute, {initBaseRoute} from "./base-route.js"
1
+ // @ts-check
2
2
 
3
- initBaseRoute()
3
+ import BasicRoute from "./basic-route.js"
4
4
 
5
- export default class VelociousRootRoute extends BaseRoute {
5
+ export default class VelociousRootRoute extends BasicRoute {
6
6
  }
@@ -1,10 +1,15 @@
1
+ // @ts-check
2
+
1
3
  class Response {
4
+ /**
5
+ * @param {globalThis.Response} fetchResponse
6
+ */
2
7
  constructor(fetchResponse) {
3
8
  this.fetchResponse = fetchResponse
4
9
  }
5
10
 
6
11
  /**
7
- * @returns {void}
12
+ * @returns {Promise<void>}
8
13
  */
9
14
  async parse() {
10
15
  this._body = await this.fetchResponse.text()
@@ -12,19 +17,19 @@ class Response {
12
17
  if (this.statusCode() != 200) throw new Error(`Request failed with code ${this.statusCode()} and body: ${this.body()}`)
13
18
  }
14
19
 
15
- /**
16
- * @returns {string}
17
- */
18
- body() { return this._body }
20
+ /** @returns {string} */
21
+ body() {
22
+ if (!this._body) throw new Error("Response body not parsed yet. Call parse() first.")
19
23
 
20
- /**
21
- * @returns {string}
22
- */
23
- contentType() { return this.fetchResponse.headers.get("content-type") }
24
+ return this._body
25
+ }
24
26
 
25
- /**
26
- * @returns {string}
27
- */
27
+ /** @returns {string | null} */
28
+ contentType() {
29
+ return this.fetchResponse.headers.get("content-type")
30
+ }
31
+
32
+ /** @returns {number} */
28
33
  statusCode() { return this.fetchResponse.status }
29
34
  }
30
35
 
@@ -34,7 +39,7 @@ export default class RequestClient {
34
39
 
35
40
  /**
36
41
  * @param {string} path
37
- * @returns {Response}
42
+ * @returns {Promise<Response>}
38
43
  */
39
44
  async get(path) {
40
45
  const fetchResponse = await fetch(`http://${this.host}:${this.port}${path}`)
@@ -48,7 +53,7 @@ export default class RequestClient {
48
53
  /**
49
54
  * @param {string} path
50
55
  * @param {object} data
51
- * @returns {Response}
56
+ * @returns {Promise<Response>}
52
57
  */
53
58
  async post(path, data) {
54
59
  const fetchResponse = await fetch(
@@ -9,10 +9,11 @@ import {tests} from "./test.js"
9
9
 
10
10
  /**
11
11
  * @typedef {object} TestArgs
12
- * @property {Application} application
13
- * @property {RequestClient} client
14
- * @property {boolean} focus
15
- * @property {string} type
12
+ * @property {Application} [application]
13
+ * @property {RequestClient} [client]
14
+ * @property {boolean} [focus]
15
+ * @property {() => Promise<void>} [function]
16
+ * @property {string} [type]
16
17
  */
17
18
 
18
19
  /**
@@ -22,15 +23,20 @@ import {tests} from "./test.js"
22
23
  */
23
24
 
24
25
  /**
25
- * @typedef {object} AfterBeforeEachCallback
26
- * @property {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : Promise<void>} callback
26
+ * @typedef {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : Promise<void>} AfterBeforeEachCallbackType
27
+ */
28
+
29
+ /**
30
+ * @typedef {object} AfterBeforeEachCallbackObjectType
31
+ * @property {AfterBeforeEachCallbackType} callback
27
32
  */
28
33
 
29
34
  /**
30
35
  * @typedef {object} TestsArgument
36
+ * @property {Record<string, TestData>} args
31
37
  * @property {boolean} [anyTestsFocussed]
32
- * @property {AfterBeforeEachCallback[]} afterEaches
33
- * @property {AfterBeforeEachCallback[]} beforeEaches
38
+ * @property {AfterBeforeEachCallbackObjectType[]} afterEaches
39
+ * @property {AfterBeforeEachCallbackObjectType[]} beforeEaches
34
40
  * @property {Record<string, TestData>} tests - A unique identifier for the node.
35
41
  * @property {Record<string, TestsArgument>} subs - Optional child nodes. Each item is another `Node`, allowing recursion.
36
42
  */
@@ -212,8 +218,8 @@ export default class TestRunner {
212
218
 
213
219
  /**
214
220
  * @param {object} args
215
- * @param {Array<AfterBeforeEachCallback>} args.afterEaches
216
- * @param {Array<AfterBeforeEachCallback>} args.beforeEaches
221
+ * @param {Array<AfterBeforeEachCallbackObjectType>} args.afterEaches
222
+ * @param {Array<AfterBeforeEachCallbackObjectType>} args.beforeEaches
217
223
  * @param {TestsArgument} args.tests
218
224
  * @param {string[]} args.descriptions
219
225
  * @param {number} args.indentLevel
@@ -1,9 +1,15 @@
1
+ // @ts-check
2
+
1
3
  import {anythingDifferent} from "set-state-compare/src/diff-utils.js"
2
4
  import restArgsError from "../utils/rest-args-error.js"
3
5
 
6
+ /** @type {import("./test-runner.js").TestsArgument} */
4
7
  const tests = {
8
+ /** @type {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} */
5
9
  afterEaches: [],
6
10
  args: {},
11
+
12
+ /** @type {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} */
7
13
  beforeEaches: [],
8
14
  subs: {},
9
15
  tests: {}
@@ -12,7 +18,7 @@ const tests = {
12
18
  let currentPath = [tests]
13
19
 
14
20
  /**
15
- * @param {function() : void} callback
21
+ * @param {import("./test-runner.js").AfterBeforeEachCallbackType} callback
16
22
  * @returns {void}
17
23
  */
18
24
  function beforeEach(callback) {
@@ -22,7 +28,7 @@ function beforeEach(callback) {
22
28
  }
23
29
 
24
30
  /**
25
- * @param {function() : void} callback
31
+ * @param {import("./test-runner.js").AfterBeforeEachCallbackType} callback
26
32
  * @returns {void}
27
33
  */
28
34
  function afterEach(callback) {
@@ -31,8 +37,28 @@ function afterEach(callback) {
31
37
  currentTest.afterEaches.push({callback})
32
38
  }
33
39
 
34
- class ExpectToChange {
40
+ class BaseExpect {
41
+ /**
42
+ * @abstract
43
+ * @returns {Promise<void>}
44
+ */
45
+ async runBefore() { /* do nothing */ }
46
+
47
+ /**
48
+ * @abstract
49
+ * @returns {Promise<void>}
50
+ */
51
+ async runAfter() { /* do nothing */ }
52
+ }
53
+
54
+ class ExpectToChange extends BaseExpect {
55
+ /**
56
+ * @param {object} args
57
+ * @param {function(): Promise<number>} args.changeCallback
58
+ * @param {Expect} args.expect
59
+ */
35
60
  constructor({changeCallback, expect, ...restArgs}) {
61
+ super()
36
62
  restArgsError(restArgs)
37
63
 
38
64
  this.expect = expect
@@ -58,9 +84,13 @@ class ExpectToChange {
58
84
  }
59
85
 
60
86
  /**
61
- * @returns {void}
87
+ * @returns {Promise<void>}
62
88
  */
63
89
  async execute() {
90
+ if (this.newCount === undefined || this.oldCount === undefined) {
91
+ throw new Error("ExpectToChange not executed properly")
92
+ }
93
+
64
94
  const difference = this.newCount - this.oldCount
65
95
 
66
96
  if (difference != this.count) {
@@ -69,20 +99,24 @@ class ExpectToChange {
69
99
  }
70
100
  }
71
101
 
72
- class Expect {
102
+ class Expect extends BaseExpect {
73
103
  /**
74
104
  * @param {any} object
75
105
  */
76
106
  constructor(object) {
107
+ super()
77
108
  this._object = object
109
+
110
+ /** @type {Array<Expect | ExpectToChange>} */
78
111
  this.expectations = []
79
112
  }
80
113
 
81
114
  /**
115
+ * @param {function(): Promise<number>} changeCallback
82
116
  * @returns {ExpectToChange}
83
117
  */
84
- andChange(...args) {
85
- return this.toChange(...args)
118
+ andChange(changeCallback) {
119
+ return this.toChange(changeCallback)
86
120
  }
87
121
 
88
122
  /**
@@ -126,6 +160,7 @@ class Expect {
126
160
  }
127
161
 
128
162
  /**
163
+ * @param {Function} klass
129
164
  * @returns {void}
130
165
  */
131
166
  toBeInstanceOf(klass) {
@@ -156,7 +191,7 @@ class Expect {
156
191
  }
157
192
 
158
193
  /**
159
- * @param {function(): void} changeCallback
194
+ * @param {function(): Promise<number>} changeCallback
160
195
  * @returns {ExpectToChange}
161
196
  */
162
197
  toChange(changeCallback) {
@@ -230,7 +265,7 @@ class Expect {
230
265
  /**
231
266
  * @template T extends Error
232
267
  * @param {string|T} expectedError
233
- * @returns {void}
268
+ * @returns {Promise<void>}
234
269
  */
235
270
  async toThrowError(expectedError) {
236
271
  if (this._not) throw new Error("not stub")
@@ -249,14 +284,18 @@ class Expect {
249
284
 
250
285
  if (typeof failedError == "string") {
251
286
  failedErrorMessage = failedError
252
- } else {
287
+ } else if (failedError instanceof Error) {
253
288
  failedErrorMessage = failedError.message
289
+ } else {
290
+ failedErrorMessage = String(failedError)
254
291
  }
255
292
 
256
293
  if (typeof expectedError == "string") {
257
294
  expectedErrorMessage = expectedError
258
- } else {
295
+ } else if (expectedError instanceof Error) {
259
296
  expectedErrorMessage = expectedError.message
297
+ } else {
298
+ expectedErrorMessage = String(expectedError)
260
299
  }
261
300
 
262
301
  if (failedErrorMessage != expectedErrorMessage) {
@@ -265,7 +304,7 @@ class Expect {
265
304
  }
266
305
 
267
306
  /**
268
- * @returns {any}
307
+ * @returns {Promise<any>}
269
308
  */
270
309
  async execute() {
271
310
  for (const expectation of this.expectations) {
@@ -286,12 +325,13 @@ class Expect {
286
325
  }
287
326
 
288
327
  /**
289
- * @param {object} result
328
+ * @param {Record<string, any>} result
290
329
  * @returns {void}
291
330
  */
292
331
  toHaveAttributes(result) {
293
332
  if (this._not) throw new Error("not stub")
294
333
 
334
+ /** @type {Record<string, any[]>} */
295
335
  const differences = {}
296
336
 
297
337
  for (const key in result) {
@@ -314,9 +354,9 @@ class Expect {
314
354
 
315
355
  /**
316
356
  * @param {string} description
317
- * @param {object|() => Promise<void>} arg1
318
- * @param {undefined|() => Promise<void>} [arg2]
319
- * @returns {void}
357
+ * @param {object|(() => Promise<void>)} arg1
358
+ * @param {undefined|(() => Promise<void>)} [arg2]
359
+ * @returns {Promise<void>}
320
360
  */
321
361
  async function describe(description, arg1, arg2) {
322
362
  let testArgs, testFunction
@@ -360,15 +400,19 @@ function expect(arg) {
360
400
 
361
401
  /**
362
402
  * @param {string} description
363
- * @param {object|() => Promise<void>} arg1
364
- * @param {undefined|() => Promise<void>} [arg2]
403
+ * @param {object|(() => Promise<void>)} arg1
404
+ * @param {undefined|(() => Promise<void>)} [arg2]
365
405
  * @returns {void}
366
406
  */
367
407
  function it(description, arg1, arg2) {
368
408
  const currentTest = currentPath[currentPath.length - 1]
369
- let testArgs, testFunction
409
+ let testArgs
410
+
411
+ /** @type {() => Promise<void>} */
412
+ let testFunction
370
413
 
371
414
  if (typeof arg1 == "function") {
415
+ // @ts-expect-error
372
416
  testFunction = arg1
373
417
  testArgs = {}
374
418
  } else if (typeof arg2 == "function") {
@@ -385,14 +429,18 @@ function it(description, arg1, arg2) {
385
429
 
386
430
  /**
387
431
  * @param {string} description
388
- * @param {object|() => Promise<void>} arg1
389
- * @param {undefined|() => Promise<void>} [arg2]
432
+ * @param {object|(() => Promise<void>)} arg1
433
+ * @param {undefined|(() => Promise<void>)} [arg2]
390
434
  * @returns {void}
391
435
  */
392
436
  function fit(description, arg1, arg2) {
393
- let testArgs, testFunction
437
+ let testArgs
438
+
439
+ /** @type {() => Promise<void>} */
440
+ let testFunction
394
441
 
395
442
  if (typeof arg1 == "function") {
443
+ // @ts-expect-error
396
444
  testFunction = arg1
397
445
  testArgs = {focus: true}
398
446
  } else if (typeof arg2 == "function") {
@@ -1,11 +1,15 @@
1
+ // @ts-check
2
+
1
3
  import {AsyncLocalStorage} from "async_hooks"
2
4
 
5
+ /** @type {AsyncLocalStorage<Array<string[]>> | undefined} */
3
6
  let asyncLocalStorage
4
7
 
5
8
  if (AsyncLocalStorage) {
6
9
  asyncLocalStorage = new AsyncLocalStorage()
7
10
  }
8
11
 
12
+ /** @param {Error} error */
9
13
  function addTrackedStackToError(error) {
10
14
  // Not supported
11
15
  if (!asyncLocalStorage) return
@@ -23,15 +27,27 @@ function addTrackedStackToError(error) {
23
27
  error.stack += "\n" + additionalStackLines.join("\n")
24
28
  }
25
29
 
30
+ /**
31
+ *
32
+ * @param {() => Promise<void> | string} arg1
33
+ * @param {() => Promise<void> | Error} [arg2]
34
+ * @returns {Promise<void>}
35
+ */
26
36
  async function withTrackedStack(arg1, arg2) {
27
- let callback, stack
37
+ /** @type {() => Promise<void>} */
38
+ let callback
39
+
40
+ /** @type {string} */
41
+ let stack
28
42
 
29
- if (arg2) {
43
+ if (typeof arg2 == "function" && typeof arg1 == "string") {
44
+ // @ts-expect-error
30
45
  callback = arg2
31
46
  stack = arg1
32
47
  } else {
48
+ // @ts-expect-error
33
49
  callback = arg1
34
- stack = Error().stack
50
+ stack = Error().stack || ""
35
51
  }
36
52
 
37
53
  // Not supported
@@ -56,13 +72,15 @@ async function withTrackedStack(arg1, arg2) {
56
72
  const newStacks = [additionalStackLines, ...parentStacks]
57
73
 
58
74
  await asyncLocalStorage.run(newStacks, async () => {
59
- return await callback()
75
+ await callback()
60
76
  })
61
77
  }
62
78
 
79
+ // @ts-expect-error
63
80
  if (globalThis.withTrackedStack) {
64
81
  console.warn("globalThis.withTrackedStack was already defined")
65
82
  } else {
83
+ // @ts-expect-error
66
84
  globalThis.withTrackedStack = {addTrackedStackToError, withTrackedStack}
67
85
  }
68
86
 
@@ -1,8 +1,17 @@
1
+ // @ts-check
2
+
3
+ /** @param {Error} error */
1
4
  function addTrackedStackToError(error) {
5
+ // @ts-expect-error
2
6
  globalThis.withTrackedStack?.addTrackedStackToError(error)
3
7
  }
4
8
 
9
+ /**
10
+ * @param {...any} args
11
+ * @returns {Promise<any>}
12
+ */
5
13
  async function withTrackedStack(...args) {
14
+ // @ts-expect-error
6
15
  const withTrackedStack = globalThis.withTrackedStack?.withTrackedStack
7
16
 
8
17
  let callback