@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.
Files changed (35) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/{Factory-_w0_BN4J.d.mts → Factory-C6W78ulZ.d.mts} +2 -2
  3. package/dist/{Factory-_w0_BN4J.d.mts.map → Factory-C6W78ulZ.d.mts.map} +1 -1
  4. package/dist/Factory.d.mts +2 -2
  5. package/dist/{KyselyFactory-BFxq2hz5.d.mts → KyselyFactory-Cc2UmOJk.d.mts} +3 -3
  6. package/dist/{KyselyFactory-BFxq2hz5.d.mts.map → KyselyFactory-Cc2UmOJk.d.mts.map} +1 -1
  7. package/dist/KyselyFactory.d.mts +3 -3
  8. package/dist/{ObjectionFactory-C4IsQ_wj.d.mts → ObjectionFactory-BYnPr9ZP.d.mts} +3 -3
  9. package/dist/{ObjectionFactory-C4IsQ_wj.d.mts.map → ObjectionFactory-BYnPr9ZP.d.mts.map} +1 -1
  10. package/dist/ObjectionFactory.d.mts +3 -3
  11. package/dist/better-auth.d.mts +2 -2
  12. package/dist/{directory-DAVs0Yaq.d.mts → directory-DGOcVlKD.d.cts} +3 -3
  13. package/dist/{directory-DAVs0Yaq.d.mts.map → directory-DGOcVlKD.d.cts.map} +1 -1
  14. package/dist/{directory-DAnMWi50.d.cts → directory-DiQ_DkaF.d.mts} +3 -3
  15. package/dist/{directory-DAnMWi50.d.cts.map → directory-DiQ_DkaF.d.mts.map} +1 -1
  16. package/dist/{faker-Br8MzXil.d.mts → faker-D9gz7KjY.d.mts} +3 -3
  17. package/dist/{faker-Br8MzXil.d.mts.map → faker-D9gz7KjY.d.mts.map} +1 -1
  18. package/dist/faker.d.mts +1 -1
  19. package/dist/kysely.d.mts +3 -3
  20. package/dist/objection.d.mts +3 -3
  21. package/dist/os/directory.d.cts +1 -1
  22. package/dist/os/directory.d.mts +1 -1
  23. package/dist/os/index.d.cts +1 -1
  24. package/dist/os/index.d.mts +1 -1
  25. package/dist/requestContext.cjs +80 -0
  26. package/dist/requestContext.cjs.map +1 -0
  27. package/dist/requestContext.d.cts +75 -0
  28. package/dist/requestContext.d.cts.map +1 -0
  29. package/dist/requestContext.d.mts +75 -0
  30. package/dist/requestContext.d.mts.map +1 -0
  31. package/dist/requestContext.mjs +77 -0
  32. package/dist/requestContext.mjs.map +1 -0
  33. package/package.json +18 -3
  34. package/src/__tests__/requestContext.spec.ts +109 -0
  35. 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-Br8MzXil.mjs";
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-_w0_BN4J.d.mts.map
147
+ //# sourceMappingURL=Factory-C6W78ulZ.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Factory-_w0_BN4J.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"}
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"}
@@ -1,3 +1,3 @@
1
- import "./faker-Br8MzXil.mjs";
2
- import { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder } from "./Factory-_w0_BN4J.mjs";
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-Br8MzXil.mjs";
2
- import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-_w0_BN4J.mjs";
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-BFxq2hz5.d.mts.map
228
+ //# sourceMappingURL=KyselyFactory-Cc2UmOJk.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"KyselyFactory-BFxq2hz5.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"}
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"}
@@ -1,4 +1,4 @@
1
- import "./faker-Br8MzXil.mjs";
2
- import "./Factory-_w0_BN4J.mjs";
3
- import { KyselyFactory } from "./KyselyFactory-BFxq2hz5.mjs";
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-Br8MzXil.mjs";
2
- import { ExtractSeedAttrs, Factory, FactorySeed } from "./Factory-_w0_BN4J.mjs";
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-C4IsQ_wj.d.mts.map
241
+ //# sourceMappingURL=ObjectionFactory-BYnPr9ZP.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectionFactory-C4IsQ_wj.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
+ {"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-Br8MzXil.mjs";
2
- import "./Factory-_w0_BN4J.mjs";
3
- import { ObjectionFactory } from "./ObjectionFactory-C4IsQ_wj.mjs";
1
+ import "./faker-D9gz7KjY.mjs";
2
+ import "./Factory-C6W78ulZ.mjs";
3
+ import { ObjectionFactory } from "./ObjectionFactory-BYnPr9ZP.mjs";
4
4
  export { ObjectionFactory };
@@ -1,4 +1,4 @@
1
- import * as better_auth_adapters4 from "better-auth/adapters";
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>) => better_auth_adapters4.AdapterFactory & {
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 vitest3 from "vitest";
1
+ import * as vitest6 from "vitest";
2
2
 
3
3
  //#region src/os/directory.d.ts
4
- declare const itWithDir: vitest3.TestAPI<{
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-DAVs0Yaq.d.mts.map
13
+ //# sourceMappingURL=directory-DGOcVlKD.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory-DAVs0Yaq.d.mts","names":[],"sources":["../src/os/directory.ts"],"sourcesContent":[],"mappings":";;;cAMa,WAeX,OAAA,CAfoB;;;AAAT,UAiBI,iBAAA,CAjBK;EAiBL,GAAA,EAAA,MAAA"}
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 vitest4 from "vitest";
1
+ import * as vitest5 from "vitest";
2
2
 
3
3
  //#region src/os/directory.d.ts
4
- declare const itWithDir: vitest4.TestAPI<{
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-DAnMWi50.d.cts.map
13
+ //# sourceMappingURL=directory-DiQ_DkaF.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory-DAnMWi50.d.cts","names":[],"sources":["../src/os/directory.ts"],"sourcesContent":[],"mappings":";;;cAMa,WAeX,OAAA,CAfoB;;;AAAT,UAiBI,iBAAA,CAjBK;EAiBL,GAAA,EAAA,MAAA"}
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 _faker_js_faker2 from "@faker-js/faker";
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<_faker_js_faker2.Faker & {
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-Br8MzXil.d.mts.map
166
+ //# sourceMappingURL=faker-D9gz7KjY.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"faker-Br8MzXil.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"}
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-Br8MzXil.mjs";
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-Br8MzXil.mjs";
2
- import { ExtractSeedAttrs, FactorySeed } from "./Factory-_w0_BN4J.mjs";
3
- import { KyselyFactory } from "./KyselyFactory-BFxq2hz5.mjs";
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";
@@ -1,6 +1,6 @@
1
- import { FakerFactory, faker } from "./faker-Br8MzXil.mjs";
2
- import { ExtractSeedAttrs, FactorySeed } from "./Factory-_w0_BN4J.mjs";
3
- import { ObjectionFactory } from "./ObjectionFactory-C4IsQ_wj.mjs";
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";
@@ -1,2 +1,2 @@
1
- import { DirectoryFixtures, itWithDir } from "../directory-DAnMWi50.cjs";
1
+ import { DirectoryFixtures, itWithDir } from "../directory-DGOcVlKD.cjs";
2
2
  export { DirectoryFixtures, itWithDir };
@@ -1,2 +1,2 @@
1
- import { DirectoryFixtures, itWithDir } from "../directory-DAVs0Yaq.mjs";
1
+ import { DirectoryFixtures, itWithDir } from "../directory-DiQ_DkaF.mjs";
2
2
  export { DirectoryFixtures, itWithDir };
@@ -1,2 +1,2 @@
1
- import { itWithDir } from "../directory-DAnMWi50.cjs";
1
+ import { itWithDir } from "../directory-DGOcVlKD.cjs";
2
2
  export { itWithDir };
@@ -1,2 +1,2 @@
1
- import { itWithDir } from "../directory-DAVs0Yaq.mjs";
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.7",
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
+ }