@geekmidas/testkit 3.1.1 → 10.0.0-alpha.0

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 (129) hide show
  1. package/dist/{Factory-CUM2767q.d.cts → Factory-C6W78ulZ.d.mts} +2 -2
  2. package/dist/{Factory-SFupxRC2.d.mts.map → Factory-C6W78ulZ.d.mts.map} +1 -1
  3. package/dist/{Factory-SFupxRC2.d.mts → Factory-DSEADOaF.d.cts} +2 -2
  4. package/dist/{Factory-CUM2767q.d.cts.map → Factory-DSEADOaF.d.cts.map} +1 -1
  5. package/dist/Factory.d.cts +2 -2
  6. package/dist/Factory.d.mts +2 -2
  7. package/dist/{KyselyFactory-vAxYodck.d.mts → KyselyFactory-Cc2UmOJk.d.mts} +3 -3
  8. package/dist/{KyselyFactory-OMwcuAX_.d.cts.map → KyselyFactory-Cc2UmOJk.d.mts.map} +1 -1
  9. package/dist/{KyselyFactory-OMwcuAX_.d.cts → KyselyFactory-DzH0N1zr.d.cts} +3 -3
  10. package/dist/{KyselyFactory-vAxYodck.d.mts.map → KyselyFactory-DzH0N1zr.d.cts.map} +1 -1
  11. package/dist/KyselyFactory.d.cts +3 -3
  12. package/dist/KyselyFactory.d.mts +3 -3
  13. package/dist/{ObjectionFactory-BWjB49-i.d.mts → ObjectionFactory-BYnPr9ZP.d.mts} +3 -3
  14. package/dist/{ObjectionFactory-BWjB49-i.d.mts.map → ObjectionFactory-BYnPr9ZP.d.mts.map} +1 -1
  15. package/dist/{ObjectionFactory-DvmZVHhe.d.cts → ObjectionFactory-BmKdG0nT.d.cts} +3 -3
  16. package/dist/{ObjectionFactory-DvmZVHhe.d.cts.map → ObjectionFactory-BmKdG0nT.d.cts.map} +1 -1
  17. package/dist/ObjectionFactory.d.cts +3 -3
  18. package/dist/ObjectionFactory.d.mts +3 -3
  19. package/dist/{VitestKyselyTransactionIsolator-CfSMOFlN.mjs → VitestKyselyTransactionIsolator-1Saieke7.mjs} +10 -3
  20. package/dist/VitestKyselyTransactionIsolator-1Saieke7.mjs.map +1 -0
  21. package/dist/{VitestKyselyTransactionIsolator-0CqOsuc9.cjs → VitestKyselyTransactionIsolator-BjJSXryR.cjs} +10 -3
  22. package/dist/VitestKyselyTransactionIsolator-BjJSXryR.cjs.map +1 -0
  23. package/dist/{VitestKyselyTransactionIsolator-CduJlHoT.d.cts → VitestKyselyTransactionIsolator-CwlTo6yf.d.mts} +8 -3
  24. package/dist/VitestKyselyTransactionIsolator-CwlTo6yf.d.mts.map +1 -0
  25. package/dist/{VitestKyselyTransactionIsolator-Cswnnj0k.d.mts → VitestKyselyTransactionIsolator-DJasVuIZ.d.cts} +8 -3
  26. package/dist/VitestKyselyTransactionIsolator-DJasVuIZ.d.cts.map +1 -0
  27. package/dist/VitestKyselyTransactionIsolator.cjs +2 -2
  28. package/dist/VitestKyselyTransactionIsolator.d.cts +2 -2
  29. package/dist/VitestKyselyTransactionIsolator.d.mts +2 -2
  30. package/dist/VitestKyselyTransactionIsolator.mjs +2 -2
  31. package/dist/{VitestObjectionTransactionIsolator-CNo40EdC.mjs → VitestObjectionTransactionIsolator-B_VSWFum.mjs} +2 -2
  32. package/dist/{VitestObjectionTransactionIsolator-CNo40EdC.mjs.map → VitestObjectionTransactionIsolator-B_VSWFum.mjs.map} +1 -1
  33. package/dist/{VitestObjectionTransactionIsolator-BXoR6xdG.d.cts → VitestObjectionTransactionIsolator-CTTjvTPO.d.cts} +2 -2
  34. package/dist/{VitestObjectionTransactionIsolator-BXoR6xdG.d.cts.map → VitestObjectionTransactionIsolator-CTTjvTPO.d.cts.map} +1 -1
  35. package/dist/{VitestObjectionTransactionIsolator-x6hY5j4u.d.mts → VitestObjectionTransactionIsolator-CyZG6nq4.d.mts} +2 -2
  36. package/dist/{VitestObjectionTransactionIsolator-x6hY5j4u.d.mts.map → VitestObjectionTransactionIsolator-CyZG6nq4.d.mts.map} +1 -1
  37. package/dist/{VitestObjectionTransactionIsolator-B5J9jjKq.cjs → VitestObjectionTransactionIsolator-DDoJTu7e.cjs} +2 -2
  38. package/dist/{VitestObjectionTransactionIsolator-B5J9jjKq.cjs.map → VitestObjectionTransactionIsolator-DDoJTu7e.cjs.map} +1 -1
  39. package/dist/VitestObjectionTransactionIsolator.cjs +2 -2
  40. package/dist/VitestObjectionTransactionIsolator.d.cts +2 -2
  41. package/dist/VitestObjectionTransactionIsolator.d.mts +2 -2
  42. package/dist/VitestObjectionTransactionIsolator.mjs +2 -2
  43. package/dist/{VitestTransactionIsolator-BNWJqh9f.d.mts → VitestTransactionIsolator-BLaw80cx.d.mts} +20 -4
  44. package/dist/VitestTransactionIsolator-BLaw80cx.d.mts.map +1 -0
  45. package/dist/{VitestTransactionIsolator-D6ZxLWys.mjs → VitestTransactionIsolator-CvwPecpl.mjs} +17 -4
  46. package/dist/VitestTransactionIsolator-CvwPecpl.mjs.map +1 -0
  47. package/dist/{VitestTransactionIsolator-CtZaOUjH.cjs → VitestTransactionIsolator-DyiX-QtK.cjs} +17 -4
  48. package/dist/VitestTransactionIsolator-DyiX-QtK.cjs.map +1 -0
  49. package/dist/{VitestTransactionIsolator-CSroc7Df.d.cts → VitestTransactionIsolator-glcxyS_R.d.cts} +20 -4
  50. package/dist/VitestTransactionIsolator-glcxyS_R.d.cts.map +1 -0
  51. package/dist/VitestTransactionIsolator.cjs +1 -1
  52. package/dist/VitestTransactionIsolator.d.cts +2 -2
  53. package/dist/VitestTransactionIsolator.d.mts +2 -2
  54. package/dist/VitestTransactionIsolator.mjs +1 -1
  55. package/dist/better-auth.d.cts +2 -2
  56. package/dist/better-auth.d.mts +2 -2
  57. package/dist/{directory-Bpz5c5pj.d.cts → directory-DGOcVlKD.d.cts} +3 -3
  58. package/dist/{directory-Bpz5c5pj.d.cts.map → directory-DGOcVlKD.d.cts.map} +1 -1
  59. package/dist/{faker-DHh7xs4u.d.mts → faker-D9gz7KjY.d.mts} +3 -3
  60. package/dist/{faker-DHh7xs4u.d.mts.map → faker-D9gz7KjY.d.mts.map} +1 -1
  61. package/dist/{faker-zVCm31nU.d.cts → faker-km9UhOS6.d.cts} +3 -3
  62. package/dist/{faker-zVCm31nU.d.cts.map → faker-km9UhOS6.d.cts.map} +1 -1
  63. package/dist/faker.d.cts +1 -1
  64. package/dist/faker.d.mts +1 -1
  65. package/dist/kysely.cjs +2 -2
  66. package/dist/kysely.d.cts +5 -5
  67. package/dist/kysely.d.mts +5 -5
  68. package/dist/kysely.mjs +2 -2
  69. package/dist/objection.cjs +2 -2
  70. package/dist/objection.d.cts +5 -5
  71. package/dist/objection.d.mts +5 -5
  72. package/dist/objection.mjs +2 -2
  73. package/dist/os/directory.d.cts +1 -1
  74. package/dist/os/index.d.cts +1 -1
  75. package/dist/requestContext.cjs +1 -1
  76. package/dist/requestContext.d.cts +1 -1
  77. package/dist/requestContext.d.mts +1 -1
  78. package/dist/requestContext.mjs +1 -1
  79. package/package.json +10 -7
  80. package/CHANGELOG.md +0 -128
  81. package/dist/VitestKyselyTransactionIsolator-0CqOsuc9.cjs.map +0 -1
  82. package/dist/VitestKyselyTransactionIsolator-CduJlHoT.d.cts.map +0 -1
  83. package/dist/VitestKyselyTransactionIsolator-CfSMOFlN.mjs.map +0 -1
  84. package/dist/VitestKyselyTransactionIsolator-Cswnnj0k.d.mts.map +0 -1
  85. package/dist/VitestTransactionIsolator-BNWJqh9f.d.mts.map +0 -1
  86. package/dist/VitestTransactionIsolator-CSroc7Df.d.cts.map +0 -1
  87. package/dist/VitestTransactionIsolator-CtZaOUjH.cjs.map +0 -1
  88. package/dist/VitestTransactionIsolator-D6ZxLWys.mjs.map +0 -1
  89. package/src/Factory.ts +0 -174
  90. package/src/KyselyFactory.ts +0 -391
  91. package/src/ObjectionFactory.ts +0 -412
  92. package/src/PostgresKyselyMigrator.ts +0 -104
  93. package/src/PostgresMigrator.ts +0 -193
  94. package/src/PostgresObjectionMigrator.ts +0 -138
  95. package/src/VitestKyselyTransactionIsolator.ts +0 -72
  96. package/src/VitestObjectionTransactionIsolator.ts +0 -75
  97. package/src/VitestTransactionIsolator.ts +0 -348
  98. package/src/__tests__/Factory.spec.ts +0 -178
  99. package/src/__tests__/KyselyFactory.spec.ts +0 -458
  100. package/src/__tests__/ObjectionFactory.spec.ts +0 -586
  101. package/src/__tests__/PostgresKyselyMigrator.spec.ts +0 -794
  102. package/src/__tests__/PostgresMigrator.spec.ts +0 -471
  103. package/src/__tests__/PostgresObjectionMigrator.spec.ts +0 -634
  104. package/src/__tests__/VitestObjectionTransactionIsolator.spec.ts +0 -138
  105. package/src/__tests__/benchmark.spec.ts +0 -140
  106. package/src/__tests__/better-auth.spec.ts +0 -21
  107. package/src/__tests__/faker.spec.ts +0 -231
  108. package/src/__tests__/initScript.spec.ts +0 -332
  109. package/src/__tests__/integration.spec.ts +0 -610
  110. package/src/__tests__/requestContext.spec.ts +0 -113
  111. package/src/__tests__/utilities.spec.ts +0 -211
  112. package/src/aws.ts +0 -131
  113. package/src/benchmark.ts +0 -48
  114. package/src/better-auth.ts +0 -310
  115. package/src/faker.ts +0 -349
  116. package/src/helpers.ts +0 -45
  117. package/src/initScript.ts +0 -122
  118. package/src/kysely.ts +0 -166
  119. package/src/logger.ts +0 -18
  120. package/src/objection.ts +0 -157
  121. package/src/os/directory.ts +0 -26
  122. package/src/os/index.ts +0 -1
  123. package/src/requestContext.ts +0 -119
  124. package/src/timer.ts +0 -3
  125. package/test/globalSetup.ts +0 -54
  126. package/test/helpers.ts +0 -268
  127. package/test/migrations/1749664623372_user.ts +0 -22
  128. package/tsconfig.json +0 -9
  129. package/vitest.config.ts +0 -8
package/src/objection.ts DELETED
@@ -1,157 +0,0 @@
1
- import type { Knex } from 'knex';
2
- import type { TestAPI } from 'vitest';
3
- import { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';
4
- import {
5
- extendWithFixtures as baseExtendWithFixtures,
6
- type DatabaseConnection,
7
- type FixtureCreators,
8
- type IsolationLevel,
9
- } from './VitestTransactionIsolator';
10
-
11
- /**
12
- * Objection.js-specific exports for test utilities.
13
- * Provides factory implementation for creating test data with Objection.js ORM
14
- * and transaction isolation for test suites.
15
- */
16
-
17
- export type { ExtractSeedAttrs, FactorySeed } from './Factory';
18
- export { ObjectionFactory } from './ObjectionFactory';
19
- export { PostgresObjectionMigrator } from './PostgresObjectionMigrator';
20
- export { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';
21
- export type {
22
- DatabaseFixtures,
23
- ExtendedDatabaseFixtures,
24
- FixtureCreators,
25
- TestWithExtendedFixtures,
26
- TransactionWrapperOptions,
27
- } from './VitestTransactionIsolator';
28
- export { IsolationLevel } from './VitestTransactionIsolator';
29
-
30
- /**
31
- * Objection.js-specific options for transaction wrapping.
32
- */
33
- export interface ObjectionTransactionOptions<
34
- Extended extends Record<string, unknown> = {},
35
- > {
36
- /** Function that creates or returns a Knex database connection */
37
- connection: DatabaseConnection<Knex>;
38
- /** Optional setup function to run within the transaction before each test */
39
- setup?: (trx: Knex.Transaction) => Promise<void>;
40
- /** Transaction isolation level (defaults to REPEATABLE_READ) */
41
- isolationLevel?: IsolationLevel;
42
- /** Additional fixtures that depend on the transaction */
43
- fixtures?: FixtureCreators<Knex.Transaction, Extended>;
44
- }
45
-
46
- // Re-export faker and FakerFactory for type portability in declaration files
47
- export { type FakerFactory, faker } from './faker';
48
-
49
- /**
50
- * Creates a wrapped Vitest test API with automatic transaction rollback for Objection.js.
51
- * Each test runs in an isolated database transaction that is rolled back after completion.
52
- * This ensures tests don't affect each other's data and run faster than truncating tables.
53
- *
54
- * @template Extended - Additional fixtures to provide
55
- * @param api - The Vitest test API (usually `test` from vitest)
56
- * @param options - Configuration options for transaction wrapping
57
- * @returns A wrapped test API that provides transaction isolation
58
- *
59
- * @example
60
- * ```typescript
61
- * import { test } from 'vitest';
62
- * import { wrapVitestObjectionTransaction } from '@geekmidas/testkit/objection';
63
- * import { knex } from './database';
64
- * import { User } from './models';
65
- *
66
- * // Create isolated test with automatic rollback
67
- * const isolatedTest = wrapVitestObjectionTransaction(test, {
68
- * connection: knex,
69
- * });
70
- *
71
- * // Use in tests - each test gets its own transaction
72
- * isolatedTest('should create user', async ({ trx }) => {
73
- * const user = await User.query(trx)
74
- * .insert({ name: 'Test User', email: 'test@example.com' });
75
- *
76
- * expect(user).toBeDefined();
77
- * });
78
- *
79
- * // With fixtures for factories
80
- * const it = wrapVitestObjectionTransaction<{ factory: Factory }>(test, {
81
- * connection: knex,
82
- * fixtures: {
83
- * factory: (trx) => new Factory(trx),
84
- * },
85
- * });
86
- *
87
- * it('should create user with factory', async ({ trx, factory }) => {
88
- * const user = await factory.insert('user', { name: 'Test' });
89
- * expect(user.id).toBeDefined();
90
- * });
91
- * ```
92
- */
93
- export function wrapVitestObjectionTransaction<
94
- Extended extends Record<string, unknown> = {},
95
- >(api: TestAPI, options: ObjectionTransactionOptions<Extended>) {
96
- const wrapper = new VitestObjectionTransactionIsolator(api);
97
-
98
- return wrapper.wrapVitestWithTransaction(options);
99
- }
100
-
101
- /**
102
- * Extends an Objection.js transaction-wrapped test with additional fixtures.
103
- * Each fixture receives the transaction and can create dependencies like factories or repositories.
104
- *
105
- * @template Extended - The type of additional fixtures to provide
106
- * @param wrappedTest - The base wrapped test from wrapVitestObjectionTransaction
107
- * @param fixtures - Object mapping fixture names to creator functions
108
- * @returns An extended test API with both trx and the additional fixtures
109
- *
110
- * @example
111
- * ```typescript
112
- * import { test } from 'vitest';
113
- * import { wrapVitestObjectionTransaction, extendWithFixtures, ObjectionFactory } from '@geekmidas/testkit/objection';
114
- * import { User } from './models';
115
- *
116
- * // Define your builders
117
- * const builders = {
118
- * user: ObjectionFactory.createBuilder(User, ({ faker }) => ({
119
- * name: faker.person.fullName(),
120
- * email: faker.internet.email(),
121
- * })),
122
- * };
123
- *
124
- * // Create base wrapped test
125
- * const baseTest = wrapVitestObjectionTransaction(test, {
126
- * connection: knex,
127
- * setup: createTestTables,
128
- * });
129
- *
130
- * // Extend with fixtures - each fixture receives the transaction
131
- * const it = extendWithFixtures<{ factory: ObjectionFactory<typeof builders, {}> }>(
132
- * baseTest,
133
- * {
134
- * factory: (trx) => new ObjectionFactory(builders, {}, trx),
135
- * }
136
- * );
137
- *
138
- * // Use in tests - both trx and factory are available
139
- * it('should create user with factory', async ({ trx, factory }) => {
140
- * const user = await factory.insert('user', { name: 'Test User' });
141
- * expect(user.id).toBeDefined();
142
- *
143
- * // Verify in database
144
- * const found = await User.query(trx).findById(user.id);
145
- * expect(found?.name).toBe('Test User');
146
- * });
147
- * ```
148
- */
149
- export function extendWithFixtures<
150
- Extended extends Record<string, unknown>,
151
- T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>,
152
- >(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>) {
153
- return baseExtendWithFixtures<Knex.Transaction, Extended, T>(
154
- wrappedTest,
155
- fixtures,
156
- );
157
- }
@@ -1,26 +0,0 @@
1
- import crypto from 'node:crypto';
2
- import fs from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { it } from 'vitest';
6
-
7
- export const itWithDir = it.extend<DirectoryFixtures>({
8
- // This fixture automatically provides a transaction to each test
9
- // biome-ignore lint/correctness/noEmptyPattern: this has to be like this to satisfy Biome
10
- dir: async ({}, use) => {
11
- const tempDir = os.tmpdir();
12
- const directoryName = crypto.randomUUID().replace(/-/g, '').toUpperCase();
13
- const dir = path.join(tempDir, directoryName);
14
- await fs.mkdir(dir, { recursive: true });
15
- await use(dir);
16
- await fs.rm(dir, { recursive: true, force: true });
17
-
18
- // Clean up keystore directory that may have been created at ~/.gkm/{directoryName}
19
- const keystoreDir = path.join(os.homedir(), '.gkm', directoryName);
20
- await fs.rm(keystoreDir, { recursive: true, force: true });
21
- },
22
- });
23
-
24
- export interface DirectoryFixtures {
25
- dir: string;
26
- }
package/src/os/index.ts DELETED
@@ -1 +0,0 @@
1
- export { itWithDir } from './directory';
@@ -1,119 +0,0 @@
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
- }
package/src/timer.ts DELETED
@@ -1,3 +0,0 @@
1
- export function waitFor(ms: number) {
2
- return new Promise((resolve) => setTimeout(resolve, ms));
3
- }
@@ -1,54 +0,0 @@
1
- import { Client } from 'pg';
2
-
3
- const TEST_DATABASE_NAME = 'geekmidas_test';
4
-
5
- export const TEST_DATABASE_CONFIG = {
6
- host: 'localhost',
7
- port: 5432,
8
- user: 'geekmidas',
9
- password: 'geekmidas',
10
- database: TEST_DATABASE_NAME,
11
- };
12
-
13
- export default async function globalSetup() {
14
- const adminConfig = {
15
- host: TEST_DATABASE_CONFIG.host,
16
- port: TEST_DATABASE_CONFIG.port,
17
- user: TEST_DATABASE_CONFIG.user,
18
- password: TEST_DATABASE_CONFIG.password,
19
- database: 'postgres', // Connect to default postgres database
20
- };
21
-
22
- const client = new Client(adminConfig);
23
-
24
- try {
25
- await client.connect();
26
-
27
- // Check if test database exists
28
- const result = await client.query(
29
- `SELECT * FROM pg_catalog.pg_database WHERE datname = $1`,
30
- [TEST_DATABASE_NAME],
31
- );
32
-
33
- // Create test database if it doesn't exist
34
- if (result.rowCount === 0) {
35
- await client.query(`CREATE DATABASE "${TEST_DATABASE_NAME}"`);
36
- } else {
37
- }
38
- } finally {
39
- await client.end();
40
- }
41
-
42
- // Return cleanup function that drops the database
43
- return async () => {
44
- const cleanupClient = new Client(adminConfig);
45
- try {
46
- await cleanupClient.connect();
47
- await cleanupClient.query(
48
- `DROP DATABASE IF EXISTS "${TEST_DATABASE_NAME}"`,
49
- );
50
- } finally {
51
- await cleanupClient.end();
52
- }
53
- };
54
- }
package/test/helpers.ts DELETED
@@ -1,268 +0,0 @@
1
- import type { Knex } from 'knex';
2
- import knex from 'knex';
3
- import {
4
- CamelCasePlugin,
5
- type ControlledTransaction,
6
- Kysely,
7
- PostgresDialect,
8
- sql,
9
- } from 'kysely';
10
- // `Migrator` moved to the 'kysely/migration' subpath in kysely 0.29+.
11
- import type { Migrator } from 'kysely/migration';
12
- import pg from 'pg';
13
- import { TEST_DATABASE_CONFIG } from './globalSetup';
14
-
15
- export interface TestDatabase {
16
- users: {
17
- id: number;
18
- name: string;
19
- email: string;
20
- role?: 'admin' | 'user';
21
- createdAt: Date;
22
- updatedAt?: Date;
23
- };
24
- posts: {
25
- id: number;
26
- title: string;
27
- content: string;
28
- userId: number;
29
- published?: boolean;
30
- createdAt: Date;
31
- updatedAt?: Date;
32
- };
33
- comments: {
34
- id: number;
35
- content: string;
36
- postId: number;
37
- userId: number;
38
- createdAt: Date;
39
- };
40
- }
41
-
42
- /**
43
- * Creates a Kysely database instance for testing
44
- */
45
- export function createKyselyDb(): Kysely<TestDatabase> {
46
- return new Kysely({
47
- dialect: new PostgresDialect({
48
- pool: new pg.Pool(TEST_DATABASE_CONFIG),
49
- }),
50
- plugins: [new CamelCasePlugin()],
51
- });
52
- }
53
-
54
- /**
55
- * Creates a Knex database instance for testing
56
- */
57
- export function createKnexDb(): Knex {
58
- return knex({
59
- client: 'pg',
60
- connection: TEST_DATABASE_CONFIG,
61
- });
62
- }
63
-
64
- /**
65
- * Test setup helper that creates tables within a transaction and returns cleanup
66
- */
67
- export async function setupKyselyTest(db: Kysely<TestDatabase>): Promise<{
68
- db: Kysely<TestDatabase>;
69
- trx: ControlledTransaction<TestDatabase, []>;
70
- cleanup: () => Promise<void>;
71
- }> {
72
- const trx = await db.startTransaction().execute();
73
-
74
- // Create tables within the transaction
75
- await createTestTables(db);
76
-
77
- const cleanup = async () => {
78
- await trx.rollback().execute();
79
- await db.destroy();
80
- };
81
-
82
- return { db, trx, cleanup };
83
- }
84
-
85
- /**
86
- * Test setup helper for Knex/Objection that creates tables within a transaction
87
- */
88
- export async function setupKnexTest(): Promise<{
89
- db: Knex;
90
- trx: Knex.Transaction;
91
- cleanup: () => Promise<void>;
92
- }> {
93
- const db = createKnexDb();
94
- const trx = await db.transaction();
95
-
96
- // Create tables within the transaction
97
- await createTestTablesKnex(trx);
98
-
99
- const cleanup = async () => {
100
- await trx.rollback();
101
- await db.destroy();
102
- };
103
-
104
- return { db, trx, cleanup };
105
- }
106
-
107
- /**
108
- * Creates test tables using Kysely
109
- */
110
- export async function createTestTables(
111
- db: Kysely<TestDatabase> | ControlledTransaction<TestDatabase, []>,
112
- ): Promise<void> {
113
- // Create users table
114
- await db.schema
115
- .createTable('users')
116
- .addColumn('id', 'bigserial', (col) => col.primaryKey())
117
- .addColumn('name', 'varchar', (col) => col.notNull())
118
- .addColumn('email', 'varchar', (col) => col.notNull().unique())
119
- .addColumn('role', 'varchar', (col) => col.defaultTo('user'))
120
- .addColumn('created_at', 'timestamp', (col) =>
121
- col.defaultTo(sql`now()`).notNull(),
122
- )
123
- .addColumn('updated_at', 'timestamp', (col) =>
124
- col.defaultTo(sql`now()`).notNull(),
125
- )
126
- .execute();
127
-
128
- // Create posts table
129
- await db.schema
130
- .createTable('posts')
131
- .addColumn('id', 'bigserial', (col) => col.primaryKey())
132
- .addColumn('title', 'varchar', (col) => col.notNull())
133
- .addColumn('content', 'text', (col) => col.notNull())
134
- .addColumn('user_id', 'bigint', (col) =>
135
- col.notNull().references('users.id').onDelete('cascade'),
136
- )
137
- .addColumn('published', 'boolean', (col) => col.defaultTo(false))
138
- .addColumn('created_at', 'timestamp', (col) =>
139
- col.defaultTo(sql`now()`).notNull(),
140
- )
141
- .addColumn('updated_at', 'timestamp', (col) =>
142
- col.defaultTo(sql`now()`).notNull(),
143
- )
144
- .execute();
145
-
146
- // Create comments table
147
- await db.schema
148
- .createTable('comments')
149
- .addColumn('id', 'bigserial', (col) => col.primaryKey())
150
- .addColumn('content', 'text', (col) => col.notNull())
151
- .addColumn('post_id', 'bigint', (col) =>
152
- col.notNull().references('posts.id').onDelete('cascade'),
153
- )
154
- .addColumn('user_id', 'bigint', (col) =>
155
- col.notNull().references('users.id').onDelete('cascade'),
156
- )
157
- .addColumn('created_at', 'timestamp', (col) =>
158
- col.defaultTo(sql`now()`).notNull(),
159
- )
160
- .execute();
161
- }
162
-
163
- /**
164
- * Creates test tables using Knex
165
- */
166
- export async function createTestTablesKnex(
167
- trx: Knex.Transaction,
168
- ): Promise<void> {
169
- // Create simple users table for testing factory
170
- await trx.raw(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`);
171
- await trx.schema.createTableIfNotExists('users', (table) => {
172
- table.uuid('id').primary().defaultTo(trx.raw('uuid_generate_v4()'));
173
- table.string('name').notNullable();
174
- });
175
-
176
- // Create simple posts table for testing factory
177
- await trx.schema.createTableIfNotExists('posts', (table) => {
178
- table.uuid('id').primary().defaultTo(trx.raw('uuid_generate_v4()'));
179
- table.string('title').notNullable();
180
- table
181
- .uuid('user_id')
182
- .notNullable()
183
- .references('id')
184
- .inTable('users')
185
- .onDelete('cascade');
186
- });
187
-
188
- // Create simple comments table for testing factory
189
- await trx.schema.createTableIfNotExists('comments', (table) => {
190
- table.uuid('id').primary().defaultTo(trx.raw('uuid_generate_v4()'));
191
- table.text('content').notNullable();
192
- table
193
- .uuid('post_id')
194
- .notNullable()
195
- .references('id')
196
- .inTable('posts')
197
- .onDelete('cascade');
198
- table
199
- .uuid('user_id')
200
- .notNullable()
201
- .references('id')
202
- .inTable('users')
203
- .onDelete('cascade');
204
- });
205
- }
206
-
207
- /**
208
- * Helper for PostgresMigrator tests - creates a separate test database
209
- */
210
- export async function createTestDatabase(
211
- dbName: string,
212
- ): Promise<() => Promise<void>> {
213
- const adminConfig = {
214
- host: TEST_DATABASE_CONFIG.host,
215
- port: TEST_DATABASE_CONFIG.port,
216
- user: TEST_DATABASE_CONFIG.user,
217
- password: TEST_DATABASE_CONFIG.password,
218
- database: 'postgres',
219
- };
220
-
221
- const client = new pg.Client(adminConfig);
222
-
223
- try {
224
- await client.connect();
225
-
226
- // Drop database if it exists, then create it
227
- await client.query(`DROP DATABASE IF EXISTS "${dbName}"`);
228
- await client.query(`CREATE DATABASE "${dbName}"`);
229
- } finally {
230
- await client.end();
231
- }
232
-
233
- // Return cleanup function
234
- return async () => {
235
- const cleanupClient = new pg.Client(adminConfig);
236
- try {
237
- await cleanupClient.connect();
238
- await cleanupClient.query(`DROP DATABASE IF EXISTS "${dbName}"`);
239
- } finally {
240
- await cleanupClient.end();
241
- }
242
- };
243
- }
244
-
245
- /**
246
- * Creates a Kysely migrator for testing
247
- */
248
- export function createTestMigrator(
249
- db: Kysely<any>,
250
- migrations: Record<
251
- string,
252
- {
253
- up: (db: Kysely<any>) => Promise<void>;
254
- down: (db: Kysely<any>) => Promise<void>;
255
- }
256
- >,
257
- ): Migrator {
258
- const { Migrator } = require('kysely/migration');
259
-
260
- return new Migrator({
261
- db,
262
- provider: {
263
- async getMigrations() {
264
- return migrations;
265
- },
266
- },
267
- });
268
- }
@@ -1,22 +0,0 @@
1
- import { type Kysely, sql } from 'kysely';
2
-
3
- // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface.
4
- export async function up(db: Kysely<any>): Promise<void> {
5
- await db.schema
6
- .createTable('users')
7
- .addColumn('id', 'bigserial', (col) => col.primaryKey())
8
- .addColumn('email', 'varchar', (col) => col.notNull().unique())
9
- .addColumn('name', 'varchar', (col) => col.notNull())
10
- .addColumn('created_at', 'timestamp', (col) =>
11
- col.defaultTo(sql`now()`).notNull(),
12
- )
13
- .addColumn('updated_at', 'timestamp', (col) =>
14
- col.defaultTo(sql`now()`).notNull(),
15
- )
16
- .execute();
17
- }
18
-
19
- // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface.
20
- export async function down(db: Kysely<any>): Promise<void> {
21
- await db.schema.dropTable('users').execute();
22
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src",
6
- "composite": true
7
- },
8
- "include": ["src/**/*"]
9
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineProject } from 'vitest/config';
2
-
3
- export default defineProject({
4
- test: {
5
- globalSetup: ['test/globalSetup.ts'],
6
- pool: 'forks',
7
- },
8
- });