@geekmidas/testkit 1.0.7 → 1.0.8
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.
- package/CHANGELOG.md +9 -0
- package/dist/{Factory-_w0_BN4J.d.mts → Factory-C6W78ulZ.d.mts} +2 -2
- package/dist/{Factory-_w0_BN4J.d.mts.map → Factory-C6W78ulZ.d.mts.map} +1 -1
- package/dist/Factory.d.mts +2 -2
- package/dist/{KyselyFactory-BFxq2hz5.d.mts → KyselyFactory-Cc2UmOJk.d.mts} +3 -3
- package/dist/{KyselyFactory-BFxq2hz5.d.mts.map → KyselyFactory-Cc2UmOJk.d.mts.map} +1 -1
- package/dist/KyselyFactory.d.mts +3 -3
- package/dist/{ObjectionFactory-C4IsQ_wj.d.mts → ObjectionFactory-BYnPr9ZP.d.mts} +3 -3
- package/dist/{ObjectionFactory-C4IsQ_wj.d.mts.map → ObjectionFactory-BYnPr9ZP.d.mts.map} +1 -1
- package/dist/ObjectionFactory.d.mts +3 -3
- package/dist/better-auth.d.mts +2 -2
- package/dist/{directory-DAVs0Yaq.d.mts → directory-DGOcVlKD.d.cts} +3 -3
- package/dist/{directory-DAVs0Yaq.d.mts.map → directory-DGOcVlKD.d.cts.map} +1 -1
- package/dist/{directory-DAnMWi50.d.cts → directory-DiQ_DkaF.d.mts} +3 -3
- package/dist/{directory-DAnMWi50.d.cts.map → directory-DiQ_DkaF.d.mts.map} +1 -1
- package/dist/{faker-Br8MzXil.d.mts → faker-D9gz7KjY.d.mts} +3 -3
- package/dist/{faker-Br8MzXil.d.mts.map → faker-D9gz7KjY.d.mts.map} +1 -1
- package/dist/faker.d.mts +1 -1
- package/dist/kysely.d.mts +3 -3
- package/dist/objection.d.mts +3 -3
- package/dist/os/directory.d.cts +1 -1
- package/dist/os/directory.d.mts +1 -1
- package/dist/os/index.d.cts +1 -1
- package/dist/os/index.d.mts +1 -1
- package/dist/requestContext.cjs +80 -0
- package/dist/requestContext.cjs.map +1 -0
- package/dist/requestContext.d.cts +75 -0
- package/dist/requestContext.d.cts.map +1 -0
- package/dist/requestContext.d.mts +75 -0
- package/dist/requestContext.d.mts.map +1 -0
- package/dist/requestContext.mjs +77 -0
- package/dist/requestContext.mjs.map +1 -0
- package/package.json +18 -3
- package/src/__tests__/requestContext.spec.ts +109 -0
- package/src/requestContext.ts +119 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @geekmidas/testkit
|
|
2
2
|
|
|
3
|
+
## 1.0.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ✨ [`351f73b`](https://github.com/geekmidas/toolbox/commit/351f73b032bc0742b7f611a9fbcdfc85bbfd69a8) Thanks [@geekmidas](https://github.com/geekmidas)! - Update request context and add support for trpc
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`351f73b`](https://github.com/geekmidas/toolbox/commit/351f73b032bc0742b7f611a9fbcdfc85bbfd69a8)]:
|
|
10
|
+
- @geekmidas/services@1.0.3
|
|
11
|
+
|
|
3
12
|
## 1.0.7
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
1
|
+
import { FakerFactory } from "./faker-D9gz7KjY.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/Factory.d.ts
|
|
4
4
|
|
|
@@ -144,4 +144,4 @@ type ExtractSeedAttrs<T> = T extends ((context: {
|
|
|
144
144
|
//# sourceMappingURL=Factory.d.ts.map
|
|
145
145
|
//#endregion
|
|
146
146
|
export { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder };
|
|
147
|
-
//# sourceMappingURL=Factory-
|
|
147
|
+
//# sourceMappingURL=Factory-C6W78ulZ.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Factory-
|
|
1
|
+
{"version":3,"file":"Factory-C6W78ulZ.d.mts","names":[],"sources":["../src/Factory.ts"],"sourcesContent":[],"mappings":";;;;;;AA2BA;;;;;;;;;;;;;;;;;;;;;;;AAiD6B,uBAjDP,OAiDO,CAAA,iBAhDX,MAgDW,CAAA,MAAA,EAAA,GAAA,CAAA,EAAA,cA/Cd,MA+Cc,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA;EAAQ;;;;;;;;;;;;;;;;EAavB,OAAA,UAAA,CAAA,aA1CkB,WA0ClB,CAAA,CAAA,MAAA,EA1CuC,IA0CvC,CAAA,EA1C8C,IA0C9C;EA8BF;;;;;;EAK0C,SAAW,MAAA,CAAA,UAAA,MApEhC,QAoEgC,CAAA,CAAA,WAAA,EAnElD,CAmEkD,EAAA,KAAA,CAAA,EAlEvD,UAkEuD,CAlE5C,QAkE4C,CAlEnC,CAkEmC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAjE7D,OAiE6D,CAjErD,OAiEqD,CAjE7C,UAiE6C,CAjElC,QAiEkC,CAjEzB,CAiEyB,CAAA,CAAA,CAAA,CAAA;EAAM;AAAP;AAgChE;;;;;EAKsD,SAAe,UAAA,CAAA,UAAA,MA7FhC,QA6FgC,CAAA,CAAA,KAAA,EAAA,MAAA,EAAA,WAAA,EA3FtD,CA2FsD,EAAA,KAAA,CAAA,EAzFhE,UAyFgE,CAzFrD,QAyFqD,CAzF5C,CAyF4C,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,GAAA,EAAA,MAAA,EAAA,KAAA,EAtFzD,YAsFyD,EAAA,GArF3D,OAqF2D,CArFnD,UAqFmD,CArFxC,QAqFwC,CArF/B,CAqF+B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EApFjE,OAoFiE,CApFzD,OAoFyD,CApFjD,UAoFiD,CApFtC,QAoFsC,CApF7B,CAoF6B,CAAA,CAAA,CAAA,EAAA,CAAA;EAAM;AAAP;AAMpE;;;;AAKI;gCAtF2B,iBACnB,WACF,iBAAiB,MAAM,MAC7B,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8BT,kFAKA,gBAAgB,aAAa,OAAO,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCrD;SAKW;WAAgB;MAAa;MAAS,QAAQ;;;;;KAMzD,sBAAsB;;;;aAK/B"}
|
package/dist/Factory.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder } from "./Factory-
|
|
1
|
+
import "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder } from "./Factory-C6W78ulZ.mjs";
|
|
3
3
|
export { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
2
|
-
import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-
|
|
1
|
+
import { FakerFactory } from "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-C6W78ulZ.mjs";
|
|
3
3
|
import { ControlledTransaction, Insertable, Kysely, Selectable } from "kysely";
|
|
4
4
|
|
|
5
5
|
//#region src/KyselyFactory.d.ts
|
|
@@ -225,4 +225,4 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
|
|
|
225
225
|
//# sourceMappingURL=KyselyFactory.d.ts.map
|
|
226
226
|
//#endregion
|
|
227
227
|
export { KyselyFactory };
|
|
228
|
-
//# sourceMappingURL=KyselyFactory-
|
|
228
|
+
//# sourceMappingURL=KyselyFactory-Cc2UmOJk.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KyselyFactory-
|
|
1
|
+
{"version":3,"file":"KyselyFactory-Cc2UmOJk.d.mts","names":[],"sources":["../src/KyselyFactory.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA+CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4GK,cA5GQ,aA4GR,CAAA,EAAA,EAAA,iBA1Ga,MA0Gb,CAAA,MAAA,EAAA,GAAA,CAAA,EAAA,cAzGU,MAyGV,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,SAxGK,OAwGL,CAxGa,QAwGb,EAxGuB,KAwGvB,CAAA,CAAA;EAAO,QACoB,QAAA;EAAE,QAAC,KAAA;EAAS,QAAvB,EAAA;EAAU;;;;;;;;;;;;;;;;;;;;;EAwJf,OACK,UAAA,CAAA,aA5OoB,WA4OpB,CAAA,CAAA,MAAA,EA5OyC,IA4OzC,CAAA,EA5OgD,IA4OhD;EAAQ;;;;;;;EAClB,WACuB,CAAA,QAAA,EAlOd,QAkOc,EAAA,KAAA,EAjOjB,KAiOiB,EAAA,EAAA,EAhOpB,MAgOoB,CAhOb,EAgOa,CAAA,GAhOP,qBAgOO,CAhOe,EAgOf,EAAA,EAAA,CAAA;EAAQ;;;;;;;;;;;;;;;;;;;;;;;AApQzB;;;;;;;;;;;;;;;;;;;;;;;;mDA0FS,2BACV,QAAQ,WAAW,GAAG,eAAe,QAClD,WAAW,GAAG,sCAGN,WAAW,GAAG,oBAEhB;WAEC;aACE;QACL,OAAO;WACJ;QAEL,QAAQ,WAAW,GAAG,eACtB,QAAQ,QAAQ,WAAW,GAAG,8CAG1B,gBACE,aACL,OAAO,YACJ,iBACH,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAuEgB,uBACf,WACL,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAqEN,sCAEnB,WACL,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;6BACN,sCAEnB,+BAGL,iBACH,WAAW,SAAS,SAAS,QAAQ,WAAW,SAAS,UAC5D,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAsDlB,iBACV,WACF,iBAAiB,MAAM,MAC7B,WAAW,MAAM"}
|
package/dist/KyselyFactory.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { KyselyFactory } from "./KyselyFactory-
|
|
1
|
+
import "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import "./Factory-C6W78ulZ.mjs";
|
|
3
|
+
import { KyselyFactory } from "./KyselyFactory-Cc2UmOJk.mjs";
|
|
4
4
|
export { KyselyFactory };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
2
|
-
import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-
|
|
1
|
+
import { FakerFactory } from "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-C6W78ulZ.mjs";
|
|
3
3
|
import { Knex } from "knex";
|
|
4
4
|
import { Model } from "objection";
|
|
5
5
|
|
|
@@ -238,4 +238,4 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
|
|
|
238
238
|
//# sourceMappingURL=ObjectionFactory.d.ts.map
|
|
239
239
|
//#endregion
|
|
240
240
|
export { ObjectionFactory };
|
|
241
|
-
//# sourceMappingURL=ObjectionFactory-
|
|
241
|
+
//# sourceMappingURL=ObjectionFactory-BYnPr9ZP.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectionFactory-
|
|
1
|
+
{"version":3,"file":"ObjectionFactory-BYnPr9ZP.d.mts","names":[],"sources":["../src/ObjectionFactory.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAyCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0Gc,cA1GD,gBA0GC,CAAA,iBAzGI,MAyGJ,CAAA,MAAA,EAAA,GAAA,CAAA,EAAA,cAxGC,MAwGD,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,SAvGJ,OAuGI,CAvGI,QAuGJ,EAvGc,KAuGd,CAAA,CAAA;EAAM,QAAd,QAAA;EAAO,QAqDO,KAAA;EAAQ,QACX,EAAA;EAAK;;;;;;;;;;;;;;;;;;;;;EA2GX,OACuB,UAAA,CAAA,aAnPO,WAmPP,CAAA,CAAA,MAAA,EAnP4B,IAmP5B,CAAA,EAnPmC,IAmPnC;EAAQ;;;;;;;;;;;;;;;;;;;AAzQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAmFO,qBACR,QAAQ,aAAa,WAAW,QAAQ,aAAa,kCAE1D,aAAa,qBAEV;WAEJ;aACE;QACL;WACG;QAEL,QAAQ,aAAa,WACrB,QAAQ,QAAQ,aAAa,0CAGzB,gBACE,aACL,aACG,iBACH,QAAQ;;;;;;;;wBAqDM,iBACH,WACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAoCgB,uBACf,WACL,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA+DN,sCAEnB,WACL,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;6BACN,sCAEnB,+BACe,iBAAiB,WAAW,SAAS,SAC/D,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAgFlB,iBACV,WACF,iBAAiB,MAAM,MAC7B,WAAW,MAAM"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
1
|
+
import "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import "./Factory-C6W78ulZ.mjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-BYnPr9ZP.mjs";
|
|
4
4
|
export { ObjectionFactory };
|
package/dist/better-auth.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as better_auth_adapters6 from "better-auth/adapters";
|
|
2
2
|
import { DBAdapterDebugLogOption } from "better-auth/adapters";
|
|
3
3
|
|
|
4
4
|
//#region src/better-auth.d.ts
|
|
@@ -7,7 +7,7 @@ interface MemoryAdapterConfig {
|
|
|
7
7
|
usePlural?: boolean;
|
|
8
8
|
initialData?: Record<string, any[]>;
|
|
9
9
|
}
|
|
10
|
-
declare const memoryAdapter: (config?: MemoryAdapterConfig, store?: Map<any, any>) =>
|
|
10
|
+
declare const memoryAdapter: (config?: MemoryAdapterConfig, store?: Map<any, any>) => better_auth_adapters6.AdapterFactory & {
|
|
11
11
|
clear: () => void;
|
|
12
12
|
getAllData: () => Record<string, any[]>;
|
|
13
13
|
getStore: () => Map<any, any>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as vitest6 from "vitest";
|
|
2
2
|
|
|
3
3
|
//#region src/os/directory.d.ts
|
|
4
|
-
declare const itWithDir:
|
|
4
|
+
declare const itWithDir: vitest6.TestAPI<{
|
|
5
5
|
dir: string;
|
|
6
6
|
}>;
|
|
7
7
|
interface DirectoryFixtures {
|
|
@@ -10,4 +10,4 @@ interface DirectoryFixtures {
|
|
|
10
10
|
//# sourceMappingURL=directory.d.ts.map
|
|
11
11
|
//#endregion
|
|
12
12
|
export { DirectoryFixtures, itWithDir };
|
|
13
|
-
//# sourceMappingURL=directory-
|
|
13
|
+
//# sourceMappingURL=directory-DGOcVlKD.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-
|
|
1
|
+
{"version":3,"file":"directory-DGOcVlKD.d.cts","names":[],"sources":["../src/os/directory.ts"],"sourcesContent":[],"mappings":";;;cAMa,WAeX,OAAA,CAfoB;;;AAAT,UAiBI,iBAAA,CAjBK;EAiBL,GAAA,EAAA,MAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as vitest5 from "vitest";
|
|
2
2
|
|
|
3
3
|
//#region src/os/directory.d.ts
|
|
4
|
-
declare const itWithDir:
|
|
4
|
+
declare const itWithDir: vitest5.TestAPI<{
|
|
5
5
|
dir: string;
|
|
6
6
|
}>;
|
|
7
7
|
interface DirectoryFixtures {
|
|
@@ -10,4 +10,4 @@ interface DirectoryFixtures {
|
|
|
10
10
|
//# sourceMappingURL=directory.d.ts.map
|
|
11
11
|
//#endregion
|
|
12
12
|
export { DirectoryFixtures, itWithDir };
|
|
13
|
-
//# sourceMappingURL=directory-
|
|
13
|
+
//# sourceMappingURL=directory-DiQ_DkaF.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-
|
|
1
|
+
{"version":3,"file":"directory-DiQ_DkaF.d.mts","names":[],"sources":["../src/os/directory.ts"],"sourcesContent":[],"mappings":";;;cAMa,WAeX,OAAA,CAfoB;;;AAAT,UAiBI,iBAAA,CAjBK;EAiBL,GAAA,EAAA,MAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _faker_js_faker0 from "@faker-js/faker";
|
|
2
2
|
|
|
3
3
|
//#region src/faker.d.ts
|
|
4
4
|
|
|
@@ -134,7 +134,7 @@ declare function coordinateOutsideRadius(center: Coordinate, minRadiusMeters: nu
|
|
|
134
134
|
* const productPrice = faker.price();
|
|
135
135
|
* ```
|
|
136
136
|
*/
|
|
137
|
-
declare const faker$1: Readonly<
|
|
137
|
+
declare const faker$1: Readonly<_faker_js_faker0.Faker & {
|
|
138
138
|
timestamps: typeof timestamps;
|
|
139
139
|
identifier: typeof identifier;
|
|
140
140
|
sequence: typeof sequence;
|
|
@@ -163,4 +163,4 @@ type Timestamps = {
|
|
|
163
163
|
type FakerFactory = typeof faker$1;
|
|
164
164
|
//#endregion
|
|
165
165
|
export { FakerFactory, Timestamps, coordinateInRadius, faker$1 as faker, identifier, resetAllSequences, resetSequence, sequence, timestamps };
|
|
166
|
-
//# sourceMappingURL=faker-
|
|
166
|
+
//# sourceMappingURL=faker-D9gz7KjY.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faker-
|
|
1
|
+
{"version":3,"file":"faker-D9gz7KjY.d.mts","names":[],"sources":["../src/faker.ts"],"sourcesContent":[],"mappings":";;;;;;;AAkFA;AA2BA;AAmCA;AA2BA;AA0BA;AAEC;AAca;AASd;;;;AAGa;AA4BZ;;;;AAMY;AA2DA,iBA5OG,UAAA,CAAA,CAyPf,EAzP6B,UAyP7B;;;;;;;;;;;;AAbiB;AAmBlB;;AAEY,iBAtOI,UAAA,CAsOJ,MAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;AAEI;AAOhB;;;;;;;;;;;;;;;;;;iBA5MgB,QAAA;;;;;;;;;;;;;;;;;;;iBA2BA,aAAA;;;;;;;;;;;;;;;;;;iBA0BA,iBAAA,CAAA;;;;;;;;;;;;;iBAgBP,KAAA,CAAA;KAIJ,UAAA;;;;iBAKW,kBAAA,SACP,6BAEN;iBA8BM,uBAAA,SACA,+DAGN;;;;;;;;;;;;;;;;;;;;cA2DU,SAAK,SAajB,gBAAA,CAbiB,KAAA;qBAAA;;;;;;;;;;;;;;;KAmBN,UAAA;;aAEA;;aAEA;;;;;;KAOA,YAAA,UAAsB"}
|
package/dist/faker.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps } from "./faker-
|
|
1
|
+
import { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps } from "./faker-D9gz7KjY.mjs";
|
|
2
2
|
export { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps };
|
package/dist/kysely.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FakerFactory, faker } from "./faker-
|
|
2
|
-
import { ExtractSeedAttrs, FactorySeed } from "./Factory-
|
|
3
|
-
import { KyselyFactory } from "./KyselyFactory-
|
|
1
|
+
import { FakerFactory, faker } from "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import { ExtractSeedAttrs, FactorySeed } from "./Factory-C6W78ulZ.mjs";
|
|
3
|
+
import { KyselyFactory } from "./KyselyFactory-Cc2UmOJk.mjs";
|
|
4
4
|
import "./PostgresMigrator-C_QQ6q35.mjs";
|
|
5
5
|
import { PostgresKyselyMigrator } from "./PostgresKyselyMigrator-x0uvWs3U.mjs";
|
|
6
6
|
import { DatabaseConnection, DatabaseFixtures, ExtendedDatabaseFixtures, FixtureCreators, IsolationLevel, TestWithExtendedFixtures, TransactionWrapperOptions } from "./VitestTransactionIsolator-BNWJqh9f.mjs";
|
package/dist/objection.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FakerFactory, faker } from "./faker-
|
|
2
|
-
import { ExtractSeedAttrs, FactorySeed } from "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
1
|
+
import { FakerFactory, faker } from "./faker-D9gz7KjY.mjs";
|
|
2
|
+
import { ExtractSeedAttrs, FactorySeed } from "./Factory-C6W78ulZ.mjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-BYnPr9ZP.mjs";
|
|
4
4
|
import "./PostgresMigrator-C_QQ6q35.mjs";
|
|
5
5
|
import { PostgresObjectionMigrator } from "./PostgresObjectionMigrator-1j6YIB1c.mjs";
|
|
6
6
|
import { DatabaseConnection, DatabaseFixtures, ExtendedDatabaseFixtures, FixtureCreators, IsolationLevel, TestWithExtendedFixtures, TransactionWrapperOptions } from "./VitestTransactionIsolator-BNWJqh9f.mjs";
|
package/dist/os/directory.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DirectoryFixtures, itWithDir } from "../directory-
|
|
1
|
+
import { DirectoryFixtures, itWithDir } from "../directory-DGOcVlKD.cjs";
|
|
2
2
|
export { DirectoryFixtures, itWithDir };
|
package/dist/os/directory.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DirectoryFixtures, itWithDir } from "../directory-
|
|
1
|
+
import { DirectoryFixtures, itWithDir } from "../directory-DiQ_DkaF.mjs";
|
|
2
2
|
export { DirectoryFixtures, itWithDir };
|
package/dist/os/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { itWithDir } from "../directory-
|
|
1
|
+
import { itWithDir } from "../directory-DGOcVlKD.cjs";
|
|
2
2
|
export { itWithDir };
|
package/dist/os/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { itWithDir } from "../directory-
|
|
1
|
+
import { itWithDir } from "../directory-DiQ_DkaF.mjs";
|
|
2
2
|
export { itWithDir };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const node_crypto = require_chunk.__toESM(require("node:crypto"));
|
|
3
|
+
const __geekmidas_logger_console = require_chunk.__toESM(require("@geekmidas/logger/console"));
|
|
4
|
+
const __geekmidas_services = require_chunk.__toESM(require("@geekmidas/services"));
|
|
5
|
+
|
|
6
|
+
//#region src/requestContext.ts
|
|
7
|
+
function resolveContext(opts = {}) {
|
|
8
|
+
return {
|
|
9
|
+
logger: opts.logger ?? new __geekmidas_logger_console.ConsoleLogger({ app: "test" }),
|
|
10
|
+
requestId: opts.requestId ?? (0, node_crypto.randomUUID)(),
|
|
11
|
+
startTime: opts.startTime ?? Date.now()
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Run a function inside a request context with test-friendly defaults.
|
|
16
|
+
* Useful when you need `serviceContext` to be available for a single call
|
|
17
|
+
* (e.g. invoking `Service.register({ context })` outside a wrapped test).
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* await runInRequestContext(() =>
|
|
22
|
+
* discovery.register([databaseService]),
|
|
23
|
+
* );
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function runInRequestContext(fn, opts = {}) {
|
|
27
|
+
return (0, __geekmidas_services.runWithRequestContext)(resolveContext(opts), fn);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Vitest fixture creator. Spread the result into `.extend()` and every test
|
|
31
|
+
* runs inside `runWithRequestContext`, even tests that don't destructure
|
|
32
|
+
* `requestContext` directly (the fixture is registered as `auto`).
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const it = test.extend({ ...requestContextFixture() });
|
|
37
|
+
*
|
|
38
|
+
* it('registers services with context', async ({ requestContext }) => {
|
|
39
|
+
* await discovery.register([databaseService]);
|
|
40
|
+
* expect(requestContext.getRequestId()).toBeDefined();
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
function requestContextFixture(opts = {}) {
|
|
45
|
+
return { requestContext: [async ({}, use) => {
|
|
46
|
+
(0, __geekmidas_services.enterRequestContext)(resolveContext(opts));
|
|
47
|
+
try {
|
|
48
|
+
await use(__geekmidas_services.serviceContext);
|
|
49
|
+
} finally {
|
|
50
|
+
(0, __geekmidas_services.exitRequestContext)();
|
|
51
|
+
}
|
|
52
|
+
}, { auto: true }] };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Wrap any Vitest `TestAPI` (including the one returned by
|
|
56
|
+
* `wrapVitestKyselyTransaction`) so every test runs inside
|
|
57
|
+
* `runWithRequestContext`. Compose with the transaction wrappers:
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';
|
|
62
|
+
* import { withRequestContext } from '@geekmidas/testkit/request-context';
|
|
63
|
+
*
|
|
64
|
+
* const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });
|
|
65
|
+
* const itWithCtx = withRequestContext(baseIt);
|
|
66
|
+
*
|
|
67
|
+
* itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {
|
|
68
|
+
* // serviceContext is set up; Service.register({ context }) works here.
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function withRequestContext(testApi, opts = {}) {
|
|
73
|
+
return testApi.extend(requestContextFixture(opts));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.requestContextFixture = requestContextFixture;
|
|
78
|
+
exports.runInRequestContext = runInRequestContext;
|
|
79
|
+
exports.withRequestContext = withRequestContext;
|
|
80
|
+
//# sourceMappingURL=requestContext.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestContext.cjs","names":["opts: RequestContextOptions","ConsoleLogger","fn: () => T | Promise<T>","use: (value: ServiceContext) => Promise<void>","serviceContext","testApi: T"],"sources":["../src/requestContext.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport {\n\tenterRequestContext,\n\texitRequestContext,\n\trunWithRequestContext,\n\ttype ServiceContext,\n\tserviceContext,\n} from '@geekmidas/services';\nimport type { TestAPI } from 'vitest';\n\n/**\n * Options for setting up a request context in tests. Any field omitted\n * is filled with a test-friendly default (ConsoleLogger, random UUID,\n * Date.now()).\n */\nexport interface RequestContextOptions {\n\t/** Logger exposed via serviceContext.getLogger(). */\n\tlogger?: Logger;\n\t/** Request id exposed via serviceContext.getRequestId(). */\n\trequestId?: string;\n\t/** Start time exposed via serviceContext.getRequestStartTime(). */\n\tstartTime?: number;\n}\n\nfunction resolveContext(opts: RequestContextOptions = {}) {\n\treturn {\n\t\tlogger: opts.logger ?? new ConsoleLogger({ app: 'test' }),\n\t\trequestId: opts.requestId ?? randomUUID(),\n\t\tstartTime: opts.startTime ?? Date.now(),\n\t};\n}\n\n/**\n * Run a function inside a request context with test-friendly defaults.\n * Useful when you need `serviceContext` to be available for a single call\n * (e.g. invoking `Service.register({ context })` outside a wrapped test).\n *\n * @example\n * ```ts\n * await runInRequestContext(() =>\n * discovery.register([databaseService]),\n * );\n * ```\n */\nexport function runInRequestContext<T>(\n\tfn: () => T | Promise<T>,\n\topts: RequestContextOptions = {},\n): T | Promise<T> {\n\treturn runWithRequestContext(resolveContext(opts), fn);\n}\n\n/**\n * Vitest fixture creator. Spread the result into `.extend()` and every test\n * runs inside `runWithRequestContext`, even tests that don't destructure\n * `requestContext` directly (the fixture is registered as `auto`).\n *\n * @example\n * ```ts\n * const it = test.extend({ ...requestContextFixture() });\n *\n * it('registers services with context', async ({ requestContext }) => {\n * await discovery.register([databaseService]);\n * expect(requestContext.getRequestId()).toBeDefined();\n * });\n * ```\n */\nexport function requestContextFixture(opts: RequestContextOptions = {}) {\n\treturn {\n\t\trequestContext: [\n\t\t\tasync (\n\t\t\t\t// biome-ignore lint/correctness/noEmptyPattern: vitest fixture signature\n\t\t\t\t{}: {},\n\t\t\t\tuse: (value: ServiceContext) => Promise<void>,\n\t\t\t) => {\n\t\t\t\t// Vitest suspends the fixture on `await use(...)` and runs the test\n\t\t\t\t// body in a continuation of the runner's async context. A scoped\n\t\t\t\t// `runWithRequestContext` callback ends as soon as we hand control\n\t\t\t\t// to the runner, so the test body would see no context. Instead,\n\t\t\t\t// mutate the current task's store with `enterRequestContext` —\n\t\t\t\t// async/await preserves that store across the suspension, so the\n\t\t\t\t// test body sees it. We restore on the way out so subsequent tests\n\t\t\t\t// don't inherit the value.\n\t\t\t\tenterRequestContext(resolveContext(opts));\n\t\t\t\ttry {\n\t\t\t\t\tawait use(serviceContext);\n\t\t\t\t} finally {\n\t\t\t\t\texitRequestContext();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ auto: true },\n\t\t] as const,\n\t};\n}\n\n/**\n * Wrap any Vitest `TestAPI` (including the one returned by\n * `wrapVitestKyselyTransaction`) so every test runs inside\n * `runWithRequestContext`. Compose with the transaction wrappers:\n *\n * @example\n * ```ts\n * import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';\n * import { withRequestContext } from '@geekmidas/testkit/request-context';\n *\n * const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });\n * const itWithCtx = withRequestContext(baseIt);\n *\n * itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {\n * // serviceContext is set up; Service.register({ context }) works here.\n * });\n * ```\n */\nexport function withRequestContext<\n\tT extends TestAPI | ReturnType<TestAPI['extend']>,\n>(testApi: T, opts: RequestContextOptions = {}): T {\n\treturn (testApi as any).extend(requestContextFixture(opts));\n}\n"],"mappings":";;;;;;AA0BA,SAAS,eAAeA,OAA8B,CAAE,GAAE;AACzD,QAAO;EACN,QAAQ,KAAK,UAAU,IAAIC,yCAAc,EAAE,KAAK,OAAQ;EACxD,WAAW,KAAK,aAAa,6BAAY;EACzC,WAAW,KAAK,aAAa,KAAK,KAAK;CACvC;AACD;;;;;;;;;;;;;AAcD,SAAgB,oBACfC,IACAF,OAA8B,CAAE,GACf;AACjB,QAAO,gDAAsB,eAAe,KAAK,EAAE,GAAG;AACtD;;;;;;;;;;;;;;;;AAiBD,SAAgB,sBAAsBA,OAA8B,CAAE,GAAE;AACvE,QAAO,EACN,gBAAgB,CACf,OAEC,EAAM,EACNG,QACI;AASJ,gDAAoB,eAAe,KAAK,CAAC;AACzC,MAAI;AACH,SAAM,IAAIC,oCAAe;EACzB,UAAS;AACT,iDAAoB;EACpB;CACD,GACD,EAAE,MAAM,KAAM,CACd,EACD;AACD;;;;;;;;;;;;;;;;;;;AAoBD,SAAgB,mBAEdC,SAAYL,OAA8B,CAAE,GAAK;AAClD,QAAO,AAAC,QAAgB,OAAO,sBAAsB,KAAK,CAAC;AAC3D"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TestAPI } from "vitest";
|
|
2
|
+
import { Logger } from "@geekmidas/logger";
|
|
3
|
+
import { ServiceContext } from "@geekmidas/services";
|
|
4
|
+
|
|
5
|
+
//#region src/requestContext.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for setting up a request context in tests. Any field omitted
|
|
9
|
+
* is filled with a test-friendly default (ConsoleLogger, random UUID,
|
|
10
|
+
* Date.now()).
|
|
11
|
+
*/
|
|
12
|
+
interface RequestContextOptions {
|
|
13
|
+
/** Logger exposed via serviceContext.getLogger(). */
|
|
14
|
+
logger?: Logger;
|
|
15
|
+
/** Request id exposed via serviceContext.getRequestId(). */
|
|
16
|
+
requestId?: string;
|
|
17
|
+
/** Start time exposed via serviceContext.getRequestStartTime(). */
|
|
18
|
+
startTime?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a function inside a request context with test-friendly defaults.
|
|
22
|
+
* Useful when you need `serviceContext` to be available for a single call
|
|
23
|
+
* (e.g. invoking `Service.register({ context })` outside a wrapped test).
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* await runInRequestContext(() =>
|
|
28
|
+
* discovery.register([databaseService]),
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function runInRequestContext<T>(fn: () => T | Promise<T>, opts?: RequestContextOptions): T | Promise<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Vitest fixture creator. Spread the result into `.extend()` and every test
|
|
35
|
+
* runs inside `runWithRequestContext`, even tests that don't destructure
|
|
36
|
+
* `requestContext` directly (the fixture is registered as `auto`).
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const it = test.extend({ ...requestContextFixture() });
|
|
41
|
+
*
|
|
42
|
+
* it('registers services with context', async ({ requestContext }) => {
|
|
43
|
+
* await discovery.register([databaseService]);
|
|
44
|
+
* expect(requestContext.getRequestId()).toBeDefined();
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function requestContextFixture(opts?: RequestContextOptions): {
|
|
49
|
+
requestContext: readonly [({}: {}, use: (value: ServiceContext) => Promise<void>) => Promise<void>, {
|
|
50
|
+
readonly auto: true;
|
|
51
|
+
}];
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Wrap any Vitest `TestAPI` (including the one returned by
|
|
55
|
+
* `wrapVitestKyselyTransaction`) so every test runs inside
|
|
56
|
+
* `runWithRequestContext`. Compose with the transaction wrappers:
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';
|
|
61
|
+
* import { withRequestContext } from '@geekmidas/testkit/request-context';
|
|
62
|
+
*
|
|
63
|
+
* const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });
|
|
64
|
+
* const itWithCtx = withRequestContext(baseIt);
|
|
65
|
+
*
|
|
66
|
+
* itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {
|
|
67
|
+
* // serviceContext is set up; Service.register({ context }) works here.
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare function withRequestContext<T extends TestAPI | ReturnType<TestAPI['extend']>>(testApi: T, opts?: RequestContextOptions): T;
|
|
72
|
+
//# sourceMappingURL=requestContext.d.ts.map
|
|
73
|
+
//#endregion
|
|
74
|
+
export { RequestContextOptions, requestContextFixture, runInRequestContext, withRequestContext };
|
|
75
|
+
//# sourceMappingURL=requestContext.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestContext.d.cts","names":[],"sources":["../src/requestContext.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAiBA;AA6BA;;AACW,UA9BM,qBAAA,CA8BN;EAAC;EAAY,MAAT,CAAA,EA5BL,MA4BK;EAAO;EACW,SAC9B,CAAA,EAAA,MAAA;EAAC;EAAY,SAAT,CAAA,EAAA,MAAA;AAAO;AAmBd;;;;;;AAMiD;AAwCjD;;;;;AAEW,iBAtEK,mBAsEL,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,GAAA,GArEA,CAqEA,GArEI,OAqEJ,CArEY,CAqEZ,CAAA,EAAA,IAAA,CAAA,EApEJ,qBAoEI,CAAA,EAnER,CAmEQ,GAnEJ,OAmEI,CAnEI,CAmEJ,CAAA;;;AAAuC;;;;;;;;;;;;;iBAhDlC,qBAAA,QAA4B;kDAM3B,mBAAmB,kBAAa;;;;;;;;;;;;;;;;;;;;;;iBAwCjC,6BACL,UAAU,WAAW,6BACrB,UAAS,wBAA6B"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TestAPI } from "vitest";
|
|
2
|
+
import { ServiceContext } from "@geekmidas/services";
|
|
3
|
+
import { Logger } from "@geekmidas/logger";
|
|
4
|
+
|
|
5
|
+
//#region src/requestContext.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for setting up a request context in tests. Any field omitted
|
|
9
|
+
* is filled with a test-friendly default (ConsoleLogger, random UUID,
|
|
10
|
+
* Date.now()).
|
|
11
|
+
*/
|
|
12
|
+
interface RequestContextOptions {
|
|
13
|
+
/** Logger exposed via serviceContext.getLogger(). */
|
|
14
|
+
logger?: Logger;
|
|
15
|
+
/** Request id exposed via serviceContext.getRequestId(). */
|
|
16
|
+
requestId?: string;
|
|
17
|
+
/** Start time exposed via serviceContext.getRequestStartTime(). */
|
|
18
|
+
startTime?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a function inside a request context with test-friendly defaults.
|
|
22
|
+
* Useful when you need `serviceContext` to be available for a single call
|
|
23
|
+
* (e.g. invoking `Service.register({ context })` outside a wrapped test).
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* await runInRequestContext(() =>
|
|
28
|
+
* discovery.register([databaseService]),
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function runInRequestContext<T>(fn: () => T | Promise<T>, opts?: RequestContextOptions): T | Promise<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Vitest fixture creator. Spread the result into `.extend()` and every test
|
|
35
|
+
* runs inside `runWithRequestContext`, even tests that don't destructure
|
|
36
|
+
* `requestContext` directly (the fixture is registered as `auto`).
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const it = test.extend({ ...requestContextFixture() });
|
|
41
|
+
*
|
|
42
|
+
* it('registers services with context', async ({ requestContext }) => {
|
|
43
|
+
* await discovery.register([databaseService]);
|
|
44
|
+
* expect(requestContext.getRequestId()).toBeDefined();
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function requestContextFixture(opts?: RequestContextOptions): {
|
|
49
|
+
requestContext: readonly [({}: {}, use: (value: ServiceContext) => Promise<void>) => Promise<void>, {
|
|
50
|
+
readonly auto: true;
|
|
51
|
+
}];
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Wrap any Vitest `TestAPI` (including the one returned by
|
|
55
|
+
* `wrapVitestKyselyTransaction`) so every test runs inside
|
|
56
|
+
* `runWithRequestContext`. Compose with the transaction wrappers:
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';
|
|
61
|
+
* import { withRequestContext } from '@geekmidas/testkit/request-context';
|
|
62
|
+
*
|
|
63
|
+
* const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });
|
|
64
|
+
* const itWithCtx = withRequestContext(baseIt);
|
|
65
|
+
*
|
|
66
|
+
* itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {
|
|
67
|
+
* // serviceContext is set up; Service.register({ context }) works here.
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare function withRequestContext<T extends TestAPI | ReturnType<TestAPI['extend']>>(testApi: T, opts?: RequestContextOptions): T;
|
|
72
|
+
//# sourceMappingURL=requestContext.d.ts.map
|
|
73
|
+
//#endregion
|
|
74
|
+
export { RequestContextOptions, requestContextFixture, runInRequestContext, withRequestContext };
|
|
75
|
+
//# sourceMappingURL=requestContext.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestContext.d.mts","names":[],"sources":["../src/requestContext.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAiBA;AA6BA;;AACW,UA9BM,qBAAA,CA8BN;EAAC;EAAY,MAAT,CAAA,EA5BL,MA4BK;EAAO;EACW,SAC9B,CAAA,EAAA,MAAA;EAAC;EAAY,SAAT,CAAA,EAAA,MAAA;AAAO;AAmBd;;;;;;AAMiD;AAwCjD;;;;;AAEW,iBAtEK,mBAsEL,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,GAAA,GArEA,CAqEA,GArEI,OAqEJ,CArEY,CAqEZ,CAAA,EAAA,IAAA,CAAA,EApEJ,qBAoEI,CAAA,EAnER,CAmEQ,GAnEJ,OAmEI,CAnEI,CAmEJ,CAAA;;;AAAuC;;;;;;;;;;;;;iBAhDlC,qBAAA,QAA4B;kDAM3B,mBAAmB,kBAAa;;;;;;;;;;;;;;;;;;;;;;iBAwCjC,6BACL,UAAU,WAAW,6BACrB,UAAS,wBAA6B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { ConsoleLogger } from "@geekmidas/logger/console";
|
|
3
|
+
import { enterRequestContext, exitRequestContext, runWithRequestContext, serviceContext } from "@geekmidas/services";
|
|
4
|
+
|
|
5
|
+
//#region src/requestContext.ts
|
|
6
|
+
function resolveContext(opts = {}) {
|
|
7
|
+
return {
|
|
8
|
+
logger: opts.logger ?? new ConsoleLogger({ app: "test" }),
|
|
9
|
+
requestId: opts.requestId ?? randomUUID(),
|
|
10
|
+
startTime: opts.startTime ?? Date.now()
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Run a function inside a request context with test-friendly defaults.
|
|
15
|
+
* Useful when you need `serviceContext` to be available for a single call
|
|
16
|
+
* (e.g. invoking `Service.register({ context })` outside a wrapped test).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* await runInRequestContext(() =>
|
|
21
|
+
* discovery.register([databaseService]),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function runInRequestContext(fn, opts = {}) {
|
|
26
|
+
return runWithRequestContext(resolveContext(opts), fn);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Vitest fixture creator. Spread the result into `.extend()` and every test
|
|
30
|
+
* runs inside `runWithRequestContext`, even tests that don't destructure
|
|
31
|
+
* `requestContext` directly (the fixture is registered as `auto`).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const it = test.extend({ ...requestContextFixture() });
|
|
36
|
+
*
|
|
37
|
+
* it('registers services with context', async ({ requestContext }) => {
|
|
38
|
+
* await discovery.register([databaseService]);
|
|
39
|
+
* expect(requestContext.getRequestId()).toBeDefined();
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
function requestContextFixture(opts = {}) {
|
|
44
|
+
return { requestContext: [async ({}, use) => {
|
|
45
|
+
enterRequestContext(resolveContext(opts));
|
|
46
|
+
try {
|
|
47
|
+
await use(serviceContext);
|
|
48
|
+
} finally {
|
|
49
|
+
exitRequestContext();
|
|
50
|
+
}
|
|
51
|
+
}, { auto: true }] };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Wrap any Vitest `TestAPI` (including the one returned by
|
|
55
|
+
* `wrapVitestKyselyTransaction`) so every test runs inside
|
|
56
|
+
* `runWithRequestContext`. Compose with the transaction wrappers:
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';
|
|
61
|
+
* import { withRequestContext } from '@geekmidas/testkit/request-context';
|
|
62
|
+
*
|
|
63
|
+
* const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });
|
|
64
|
+
* const itWithCtx = withRequestContext(baseIt);
|
|
65
|
+
*
|
|
66
|
+
* itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {
|
|
67
|
+
* // serviceContext is set up; Service.register({ context }) works here.
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function withRequestContext(testApi, opts = {}) {
|
|
72
|
+
return testApi.extend(requestContextFixture(opts));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { requestContextFixture, runInRequestContext, withRequestContext };
|
|
77
|
+
//# sourceMappingURL=requestContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestContext.mjs","names":["opts: RequestContextOptions","fn: () => T | Promise<T>","use: (value: ServiceContext) => Promise<void>","testApi: T"],"sources":["../src/requestContext.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport {\n\tenterRequestContext,\n\texitRequestContext,\n\trunWithRequestContext,\n\ttype ServiceContext,\n\tserviceContext,\n} from '@geekmidas/services';\nimport type { TestAPI } from 'vitest';\n\n/**\n * Options for setting up a request context in tests. Any field omitted\n * is filled with a test-friendly default (ConsoleLogger, random UUID,\n * Date.now()).\n */\nexport interface RequestContextOptions {\n\t/** Logger exposed via serviceContext.getLogger(). */\n\tlogger?: Logger;\n\t/** Request id exposed via serviceContext.getRequestId(). */\n\trequestId?: string;\n\t/** Start time exposed via serviceContext.getRequestStartTime(). */\n\tstartTime?: number;\n}\n\nfunction resolveContext(opts: RequestContextOptions = {}) {\n\treturn {\n\t\tlogger: opts.logger ?? new ConsoleLogger({ app: 'test' }),\n\t\trequestId: opts.requestId ?? randomUUID(),\n\t\tstartTime: opts.startTime ?? Date.now(),\n\t};\n}\n\n/**\n * Run a function inside a request context with test-friendly defaults.\n * Useful when you need `serviceContext` to be available for a single call\n * (e.g. invoking `Service.register({ context })` outside a wrapped test).\n *\n * @example\n * ```ts\n * await runInRequestContext(() =>\n * discovery.register([databaseService]),\n * );\n * ```\n */\nexport function runInRequestContext<T>(\n\tfn: () => T | Promise<T>,\n\topts: RequestContextOptions = {},\n): T | Promise<T> {\n\treturn runWithRequestContext(resolveContext(opts), fn);\n}\n\n/**\n * Vitest fixture creator. Spread the result into `.extend()` and every test\n * runs inside `runWithRequestContext`, even tests that don't destructure\n * `requestContext` directly (the fixture is registered as `auto`).\n *\n * @example\n * ```ts\n * const it = test.extend({ ...requestContextFixture() });\n *\n * it('registers services with context', async ({ requestContext }) => {\n * await discovery.register([databaseService]);\n * expect(requestContext.getRequestId()).toBeDefined();\n * });\n * ```\n */\nexport function requestContextFixture(opts: RequestContextOptions = {}) {\n\treturn {\n\t\trequestContext: [\n\t\t\tasync (\n\t\t\t\t// biome-ignore lint/correctness/noEmptyPattern: vitest fixture signature\n\t\t\t\t{}: {},\n\t\t\t\tuse: (value: ServiceContext) => Promise<void>,\n\t\t\t) => {\n\t\t\t\t// Vitest suspends the fixture on `await use(...)` and runs the test\n\t\t\t\t// body in a continuation of the runner's async context. A scoped\n\t\t\t\t// `runWithRequestContext` callback ends as soon as we hand control\n\t\t\t\t// to the runner, so the test body would see no context. Instead,\n\t\t\t\t// mutate the current task's store with `enterRequestContext` —\n\t\t\t\t// async/await preserves that store across the suspension, so the\n\t\t\t\t// test body sees it. We restore on the way out so subsequent tests\n\t\t\t\t// don't inherit the value.\n\t\t\t\tenterRequestContext(resolveContext(opts));\n\t\t\t\ttry {\n\t\t\t\t\tawait use(serviceContext);\n\t\t\t\t} finally {\n\t\t\t\t\texitRequestContext();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ auto: true },\n\t\t] as const,\n\t};\n}\n\n/**\n * Wrap any Vitest `TestAPI` (including the one returned by\n * `wrapVitestKyselyTransaction`) so every test runs inside\n * `runWithRequestContext`. Compose with the transaction wrappers:\n *\n * @example\n * ```ts\n * import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';\n * import { withRequestContext } from '@geekmidas/testkit/request-context';\n *\n * const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });\n * const itWithCtx = withRequestContext(baseIt);\n *\n * itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {\n * // serviceContext is set up; Service.register({ context }) works here.\n * });\n * ```\n */\nexport function withRequestContext<\n\tT extends TestAPI | ReturnType<TestAPI['extend']>,\n>(testApi: T, opts: RequestContextOptions = {}): T {\n\treturn (testApi as any).extend(requestContextFixture(opts));\n}\n"],"mappings":";;;;;AA0BA,SAAS,eAAeA,OAA8B,CAAE,GAAE;AACzD,QAAO;EACN,QAAQ,KAAK,UAAU,IAAI,cAAc,EAAE,KAAK,OAAQ;EACxD,WAAW,KAAK,aAAa,YAAY;EACzC,WAAW,KAAK,aAAa,KAAK,KAAK;CACvC;AACD;;;;;;;;;;;;;AAcD,SAAgB,oBACfC,IACAD,OAA8B,CAAE,GACf;AACjB,QAAO,sBAAsB,eAAe,KAAK,EAAE,GAAG;AACtD;;;;;;;;;;;;;;;;AAiBD,SAAgB,sBAAsBA,OAA8B,CAAE,GAAE;AACvE,QAAO,EACN,gBAAgB,CACf,OAEC,EAAM,EACNE,QACI;AASJ,sBAAoB,eAAe,KAAK,CAAC;AACzC,MAAI;AACH,SAAM,IAAI,eAAe;EACzB,UAAS;AACT,uBAAoB;EACpB;CACD,GACD,EAAE,MAAM,KAAM,CACd,EACD;AACD;;;;;;;;;;;;;;;;;;;AAoBD,SAAgB,mBAEdC,SAAYH,OAA8B,CAAE,GAAK;AAClD,QAAO,AAAC,QAAgB,OAAO,sBAAsB,KAAK,CAAC;AAC3D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/testkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -103,6 +103,16 @@
|
|
|
103
103
|
"types": "./dist/initScript.d.cts",
|
|
104
104
|
"default": "./dist/initScript.cjs"
|
|
105
105
|
}
|
|
106
|
+
},
|
|
107
|
+
"./request-context": {
|
|
108
|
+
"import": {
|
|
109
|
+
"types": "./dist/requestContext.d.mts",
|
|
110
|
+
"default": "./dist/requestContext.mjs"
|
|
111
|
+
},
|
|
112
|
+
"require": {
|
|
113
|
+
"types": "./dist/requestContext.d.cts",
|
|
114
|
+
"default": "./dist/requestContext.cjs"
|
|
115
|
+
}
|
|
106
116
|
}
|
|
107
117
|
},
|
|
108
118
|
"dependencies": {
|
|
@@ -111,7 +121,8 @@
|
|
|
111
121
|
"devDependencies": {
|
|
112
122
|
"@types/pg": "~8.15.4",
|
|
113
123
|
"@geekmidas/envkit": "^1.0.7",
|
|
114
|
-
"@geekmidas/logger": "^1.0.2"
|
|
124
|
+
"@geekmidas/logger": "^1.0.2",
|
|
125
|
+
"@geekmidas/services": "^1.0.3"
|
|
115
126
|
},
|
|
116
127
|
"repository": {
|
|
117
128
|
"type": "git",
|
|
@@ -131,7 +142,8 @@
|
|
|
131
142
|
"@types/aws-lambda": ">=8.10.92",
|
|
132
143
|
"better-auth": ">=1.3.34",
|
|
133
144
|
"@geekmidas/envkit": "^1.0.7",
|
|
134
|
-
"@geekmidas/logger": "^1.0.2"
|
|
145
|
+
"@geekmidas/logger": "^1.0.2",
|
|
146
|
+
"@geekmidas/services": "^1.0.3"
|
|
135
147
|
},
|
|
136
148
|
"peerDependenciesMeta": {
|
|
137
149
|
"@geekmidas/envkit": {
|
|
@@ -140,6 +152,9 @@
|
|
|
140
152
|
"@geekmidas/logger": {
|
|
141
153
|
"optional": true
|
|
142
154
|
},
|
|
155
|
+
"@geekmidas/services": {
|
|
156
|
+
"optional": true
|
|
157
|
+
},
|
|
143
158
|
"kysely": {
|
|
144
159
|
"optional": true
|
|
145
160
|
},
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
2
|
+
import { ConsoleLogger } from '@geekmidas/logger/console';
|
|
3
|
+
import {
|
|
4
|
+
type Service,
|
|
5
|
+
ServiceDiscovery,
|
|
6
|
+
serviceContext,
|
|
7
|
+
} from '@geekmidas/services';
|
|
8
|
+
import { afterEach, describe, expect, test } from 'vitest';
|
|
9
|
+
import {
|
|
10
|
+
requestContextFixture,
|
|
11
|
+
runInRequestContext,
|
|
12
|
+
withRequestContext,
|
|
13
|
+
} from '../requestContext';
|
|
14
|
+
|
|
15
|
+
describe('runInRequestContext', () => {
|
|
16
|
+
test('runs callback inside request context with defaults', async () => {
|
|
17
|
+
expect(serviceContext.hasContext()).toBe(false);
|
|
18
|
+
|
|
19
|
+
const result = await runInRequestContext(() => {
|
|
20
|
+
expect(serviceContext.hasContext()).toBe(true);
|
|
21
|
+
expect(typeof serviceContext.getRequestId()).toBe('string');
|
|
22
|
+
expect(typeof serviceContext.getRequestStartTime()).toBe('number');
|
|
23
|
+
return 'ok';
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(result).toBe('ok');
|
|
27
|
+
expect(serviceContext.hasContext()).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('uses caller-supplied logger and request id', async () => {
|
|
31
|
+
const logger = new ConsoleLogger({ app: 'spec' });
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
|
|
34
|
+
await runInRequestContext(
|
|
35
|
+
() => {
|
|
36
|
+
expect(serviceContext.getLogger()).toBe(logger);
|
|
37
|
+
expect(serviceContext.getRequestId()).toBe('req-42');
|
|
38
|
+
expect(serviceContext.getRequestStartTime()).toBe(startTime);
|
|
39
|
+
},
|
|
40
|
+
{ logger, requestId: 'req-42', startTime },
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('lets services that consume context register successfully', async () => {
|
|
45
|
+
(ServiceDiscovery as unknown as { _instance?: unknown })._instance =
|
|
46
|
+
undefined;
|
|
47
|
+
const envParser = new EnvironmentParser({ ...process.env });
|
|
48
|
+
|
|
49
|
+
const recorded: { requestId?: string } = {};
|
|
50
|
+
const recordingService = {
|
|
51
|
+
serviceName: 'recorder' as const,
|
|
52
|
+
register({ context }) {
|
|
53
|
+
recorded.requestId = context.getRequestId();
|
|
54
|
+
return { recorded };
|
|
55
|
+
},
|
|
56
|
+
} satisfies Service<'recorder', { recorded: typeof recorded }>;
|
|
57
|
+
|
|
58
|
+
await runInRequestContext(
|
|
59
|
+
async () => {
|
|
60
|
+
const discovery = ServiceDiscovery.getInstance(envParser);
|
|
61
|
+
await discovery.register([recordingService]);
|
|
62
|
+
},
|
|
63
|
+
{ requestId: 'from-test' },
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
expect(recorded.requestId).toBe('from-test');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('requestContextFixture', () => {
|
|
71
|
+
const itWithCtx = test.extend({
|
|
72
|
+
...requestContextFixture({ requestId: 'fixture-req' }),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
itWithCtx(
|
|
76
|
+
'exposes serviceContext via fixture',
|
|
77
|
+
async ({ requestContext }) => {
|
|
78
|
+
expect(requestContext.getRequestId()).toBe('fixture-req');
|
|
79
|
+
expect(serviceContext.getRequestId()).toBe('fixture-req');
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
itWithCtx(
|
|
84
|
+
'runs the test body inside the ALS even without destructuring',
|
|
85
|
+
() => {
|
|
86
|
+
// `auto: true` means we get context here even though we didn't ask for it
|
|
87
|
+
expect(serviceContext.hasContext()).toBe(true);
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('withRequestContext', () => {
|
|
93
|
+
const itWithCtx = withRequestContext(test, { requestId: 'wrapped-req' });
|
|
94
|
+
|
|
95
|
+
itWithCtx('wraps an existing TestAPI', () => {
|
|
96
|
+
expect(serviceContext.hasContext()).toBe(true);
|
|
97
|
+
expect(serviceContext.getRequestId()).toBe('wrapped-req');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('isolation between tests', () => {
|
|
102
|
+
afterEach(() => {
|
|
103
|
+
expect(serviceContext.hasContext()).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('does not leak context outside runInRequestContext', async () => {
|
|
107
|
+
await runInRequestContext(() => undefined);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import type { Logger } from '@geekmidas/logger';
|
|
3
|
+
import { ConsoleLogger } from '@geekmidas/logger/console';
|
|
4
|
+
import {
|
|
5
|
+
enterRequestContext,
|
|
6
|
+
exitRequestContext,
|
|
7
|
+
runWithRequestContext,
|
|
8
|
+
type ServiceContext,
|
|
9
|
+
serviceContext,
|
|
10
|
+
} from '@geekmidas/services';
|
|
11
|
+
import type { TestAPI } from 'vitest';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Options for setting up a request context in tests. Any field omitted
|
|
15
|
+
* is filled with a test-friendly default (ConsoleLogger, random UUID,
|
|
16
|
+
* Date.now()).
|
|
17
|
+
*/
|
|
18
|
+
export interface RequestContextOptions {
|
|
19
|
+
/** Logger exposed via serviceContext.getLogger(). */
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
/** Request id exposed via serviceContext.getRequestId(). */
|
|
22
|
+
requestId?: string;
|
|
23
|
+
/** Start time exposed via serviceContext.getRequestStartTime(). */
|
|
24
|
+
startTime?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resolveContext(opts: RequestContextOptions = {}) {
|
|
28
|
+
return {
|
|
29
|
+
logger: opts.logger ?? new ConsoleLogger({ app: 'test' }),
|
|
30
|
+
requestId: opts.requestId ?? randomUUID(),
|
|
31
|
+
startTime: opts.startTime ?? Date.now(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Run a function inside a request context with test-friendly defaults.
|
|
37
|
+
* Useful when you need `serviceContext` to be available for a single call
|
|
38
|
+
* (e.g. invoking `Service.register({ context })` outside a wrapped test).
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* await runInRequestContext(() =>
|
|
43
|
+
* discovery.register([databaseService]),
|
|
44
|
+
* );
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function runInRequestContext<T>(
|
|
48
|
+
fn: () => T | Promise<T>,
|
|
49
|
+
opts: RequestContextOptions = {},
|
|
50
|
+
): T | Promise<T> {
|
|
51
|
+
return runWithRequestContext(resolveContext(opts), fn);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Vitest fixture creator. Spread the result into `.extend()` and every test
|
|
56
|
+
* runs inside `runWithRequestContext`, even tests that don't destructure
|
|
57
|
+
* `requestContext` directly (the fixture is registered as `auto`).
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const it = test.extend({ ...requestContextFixture() });
|
|
62
|
+
*
|
|
63
|
+
* it('registers services with context', async ({ requestContext }) => {
|
|
64
|
+
* await discovery.register([databaseService]);
|
|
65
|
+
* expect(requestContext.getRequestId()).toBeDefined();
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function requestContextFixture(opts: RequestContextOptions = {}) {
|
|
70
|
+
return {
|
|
71
|
+
requestContext: [
|
|
72
|
+
async (
|
|
73
|
+
// biome-ignore lint/correctness/noEmptyPattern: vitest fixture signature
|
|
74
|
+
{}: {},
|
|
75
|
+
use: (value: ServiceContext) => Promise<void>,
|
|
76
|
+
) => {
|
|
77
|
+
// Vitest suspends the fixture on `await use(...)` and runs the test
|
|
78
|
+
// body in a continuation of the runner's async context. A scoped
|
|
79
|
+
// `runWithRequestContext` callback ends as soon as we hand control
|
|
80
|
+
// to the runner, so the test body would see no context. Instead,
|
|
81
|
+
// mutate the current task's store with `enterRequestContext` —
|
|
82
|
+
// async/await preserves that store across the suspension, so the
|
|
83
|
+
// test body sees it. We restore on the way out so subsequent tests
|
|
84
|
+
// don't inherit the value.
|
|
85
|
+
enterRequestContext(resolveContext(opts));
|
|
86
|
+
try {
|
|
87
|
+
await use(serviceContext);
|
|
88
|
+
} finally {
|
|
89
|
+
exitRequestContext();
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{ auto: true },
|
|
93
|
+
] as const,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Wrap any Vitest `TestAPI` (including the one returned by
|
|
99
|
+
* `wrapVitestKyselyTransaction`) so every test runs inside
|
|
100
|
+
* `runWithRequestContext`. Compose with the transaction wrappers:
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { wrapVitestKyselyTransaction } from '@geekmidas/testkit/kysely';
|
|
105
|
+
* import { withRequestContext } from '@geekmidas/testkit/request-context';
|
|
106
|
+
*
|
|
107
|
+
* const baseIt = wrapVitestKyselyTransaction<DB>(it, { connection: db });
|
|
108
|
+
* const itWithCtx = withRequestContext(baseIt);
|
|
109
|
+
*
|
|
110
|
+
* itWithCtx('runs inside trx + context', async ({ trx, requestContext }) => {
|
|
111
|
+
* // serviceContext is set up; Service.register({ context }) works here.
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function withRequestContext<
|
|
116
|
+
T extends TestAPI | ReturnType<TestAPI['extend']>,
|
|
117
|
+
>(testApi: T, opts: RequestContextOptions = {}): T {
|
|
118
|
+
return (testApi as any).extend(requestContextFixture(opts));
|
|
119
|
+
}
|