@geekmidas/testkit 10.0.0-alpha.4 → 10.0.0-alpha.40
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/README.md +74 -0
- package/dist/Factory.cjs +51 -2
- package/dist/Factory.cjs.map +1 -0
- package/dist/Factory.d.cts +143 -3
- package/dist/Factory.d.cts.map +1 -0
- package/dist/Factory.d.mts +143 -3
- package/dist/Factory.d.mts.map +1 -0
- package/dist/Factory.mjs +50 -2
- package/dist/Factory.mjs.map +1 -0
- package/dist/KyselyFactory.cjs +237 -4
- package/dist/KyselyFactory.cjs.map +1 -0
- package/dist/KyselyFactory.d.cts +224 -4
- package/dist/KyselyFactory.d.cts.map +1 -0
- package/dist/KyselyFactory.d.mts +224 -4
- package/dist/KyselyFactory.d.mts.map +1 -0
- package/dist/KyselyFactory.mjs +236 -4
- package/dist/KyselyFactory.mjs.map +1 -0
- package/dist/ObjectionFactory.cjs +265 -4
- package/dist/ObjectionFactory.cjs.map +1 -0
- package/dist/ObjectionFactory.d.cts +237 -4
- package/dist/ObjectionFactory.d.cts.map +1 -0
- package/dist/ObjectionFactory.d.mts +237 -4
- package/dist/ObjectionFactory.d.mts.map +1 -0
- package/dist/ObjectionFactory.mjs +264 -4
- package/dist/ObjectionFactory.mjs.map +1 -0
- package/dist/PostgresKyselyMigrator.cjs +94 -3
- package/dist/PostgresKyselyMigrator.cjs.map +1 -0
- package/dist/PostgresKyselyMigrator.d.cts +80 -3
- package/dist/PostgresKyselyMigrator.d.cts.map +1 -0
- package/dist/PostgresKyselyMigrator.d.mts +80 -3
- package/dist/PostgresKyselyMigrator.d.mts.map +1 -0
- package/dist/PostgresKyselyMigrator.mjs +93 -3
- package/dist/PostgresKyselyMigrator.mjs.map +1 -0
- package/dist/{PostgresMigrator-C_QQ6q35.d.mts → PostgresMigrator-CDPnnwMJ.d.cts} +11 -5
- package/dist/PostgresMigrator-CDPnnwMJ.d.cts.map +1 -0
- package/dist/{PostgresMigrator-CeYy-eHF.d.cts → PostgresMigrator-CDPnnwMJ.d.mts} +11 -5
- package/dist/PostgresMigrator-CDPnnwMJ.d.mts.map +1 -0
- package/dist/PostgresMigrator.cjs +178 -2
- package/dist/PostgresMigrator.cjs.map +1 -0
- package/dist/PostgresMigrator.d.cts +1 -1
- package/dist/PostgresMigrator.d.mts +1 -1
- package/dist/PostgresMigrator.mjs +175 -2
- package/dist/PostgresMigrator.mjs.map +1 -0
- package/dist/PostgresObjectionMigrator.cjs +118 -3
- package/dist/PostgresObjectionMigrator.cjs.map +1 -0
- package/dist/PostgresObjectionMigrator.d.cts +75 -3
- package/dist/PostgresObjectionMigrator.d.cts.map +1 -0
- package/dist/PostgresObjectionMigrator.d.mts +75 -3
- package/dist/PostgresObjectionMigrator.d.mts.map +1 -0
- package/dist/PostgresObjectionMigrator.mjs +117 -3
- package/dist/PostgresObjectionMigrator.mjs.map +1 -0
- package/dist/VitestKyselyTransactionIsolator.cjs +66 -3
- package/dist/VitestKyselyTransactionIsolator.cjs.map +1 -0
- package/dist/VitestKyselyTransactionIsolator.d.cts +60 -3
- package/dist/VitestKyselyTransactionIsolator.d.cts.map +1 -0
- package/dist/VitestKyselyTransactionIsolator.d.mts +60 -3
- package/dist/VitestKyselyTransactionIsolator.d.mts.map +1 -0
- package/dist/VitestKyselyTransactionIsolator.mjs +65 -3
- package/dist/VitestKyselyTransactionIsolator.mjs.map +1 -0
- package/dist/VitestObjectionTransactionIsolator.cjs +62 -3
- package/dist/VitestObjectionTransactionIsolator.cjs.map +1 -0
- package/dist/VitestObjectionTransactionIsolator.d.cts +56 -3
- package/dist/VitestObjectionTransactionIsolator.d.cts.map +1 -0
- package/dist/VitestObjectionTransactionIsolator.d.mts +56 -3
- package/dist/VitestObjectionTransactionIsolator.d.mts.map +1 -0
- package/dist/VitestObjectionTransactionIsolator.mjs +61 -3
- package/dist/VitestObjectionTransactionIsolator.mjs.map +1 -0
- package/dist/VitestTransactionIsolator.cjs +187 -4
- package/dist/VitestTransactionIsolator.cjs.map +1 -0
- package/dist/VitestTransactionIsolator.d.cts +219 -2
- package/dist/VitestTransactionIsolator.d.cts.map +1 -0
- package/dist/VitestTransactionIsolator.d.mts +219 -2
- package/dist/VitestTransactionIsolator.d.mts.map +1 -0
- package/dist/VitestTransactionIsolator.mjs +184 -2
- package/dist/VitestTransactionIsolator.mjs.map +1 -0
- package/dist/aws.cjs +3 -4
- package/dist/aws.cjs.map +1 -1
- package/dist/aws.d.cts +3 -8
- package/dist/aws.d.cts.map +1 -1
- package/dist/aws.d.mts +3 -8
- package/dist/aws.d.mts.map +1 -1
- package/dist/aws.mjs +1 -2
- package/dist/aws.mjs.map +1 -1
- package/dist/benchmark.cjs +2 -2
- package/dist/benchmark.cjs.map +1 -1
- package/dist/benchmark.d.cts +4 -6
- package/dist/benchmark.d.cts.map +1 -1
- package/dist/benchmark.d.mts +4 -6
- package/dist/benchmark.d.mts.map +1 -1
- package/dist/benchmark.mjs +1 -1
- package/dist/benchmark.mjs.map +1 -1
- package/dist/better-auth.cjs +17 -8
- package/dist/better-auth.cjs.map +1 -1
- package/dist/better-auth.d.cts +13142 -5
- package/dist/better-auth.d.cts.map +1 -1
- package/dist/better-auth.d.mts +13142 -5
- package/dist/better-auth.d.mts.map +1 -1
- package/dist/better-auth.mjs +15 -6
- package/dist/better-auth.mjs.map +1 -1
- package/dist/browser.cjs +127 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +47 -0
- package/dist/browser.d.cts.map +1 -0
- package/dist/browser.d.mts +47 -0
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.mjs +125 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/context.cjs +80 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +55 -0
- package/dist/context.d.cts.map +1 -0
- package/dist/context.d.mts +55 -0
- package/dist/context.d.mts.map +1 -0
- package/dist/context.mjs +73 -0
- package/dist/context.mjs.map +1 -0
- package/dist/faker.cjs +276 -8
- package/dist/faker.cjs.map +1 -0
- package/dist/faker.d.cts +145 -2
- package/dist/faker.d.cts.map +1 -0
- package/dist/faker.d.mts +145 -2
- package/dist/faker.d.mts.map +1 -0
- package/dist/faker.mjs +269 -2
- package/dist/faker.mjs.map +1 -0
- package/dist/helpers.cjs +6 -5
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +1 -5
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.mts +1 -5
- package/dist/helpers.d.mts.map +1 -1
- package/dist/helpers.mjs +1 -2
- package/dist/helpers.mjs.map +1 -1
- package/dist/initScript.cjs +15 -15
- package/dist/initScript.cjs.map +1 -1
- package/dist/initScript.d.cts +2 -4
- package/dist/initScript.d.cts.map +1 -1
- package/dist/initScript.d.mts +2 -4
- package/dist/initScript.d.mts.map +1 -1
- package/dist/initScript.mjs +10 -12
- package/dist/initScript.mjs.map +1 -1
- package/dist/kysely.cjs +10 -13
- package/dist/kysely.cjs.map +1 -1
- package/dist/kysely.d.cts +10 -14
- package/dist/kysely.d.cts.map +1 -1
- package/dist/kysely.d.mts +10 -14
- package/dist/kysely.d.mts.map +1 -1
- package/dist/kysely.mjs +10 -14
- package/dist/kysely.mjs.map +1 -1
- package/dist/logger.cjs +3 -4
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.d.cts +1 -5
- package/dist/logger.d.cts.map +1 -1
- package/dist/logger.d.mts +1 -5
- package/dist/logger.d.mts.map +1 -1
- package/dist/logger.mjs +1 -2
- package/dist/logger.mjs.map +1 -1
- package/dist/mailbox.cjs +95 -0
- package/dist/mailbox.cjs.map +1 -0
- package/dist/mailbox.d.cts +58 -0
- package/dist/mailbox.d.cts.map +1 -0
- package/dist/mailbox.d.mts +58 -0
- package/dist/mailbox.d.mts.map +1 -0
- package/dist/mailbox.mjs +92 -0
- package/dist/mailbox.mjs.map +1 -0
- package/dist/objection.cjs +10 -13
- package/dist/objection.cjs.map +1 -1
- package/dist/objection.d.cts +10 -14
- package/dist/objection.d.cts.map +1 -1
- package/dist/objection.d.mts +10 -14
- package/dist/objection.d.mts.map +1 -1
- package/dist/objection.mjs +10 -14
- package/dist/objection.mjs.map +1 -1
- package/dist/os/directory.cjs +31 -2
- package/dist/os/directory.cjs.map +1 -0
- package/dist/os/directory.d.cts +9 -2
- package/dist/os/directory.d.cts.map +1 -0
- package/dist/os/directory.d.mts +9 -2
- package/dist/os/directory.d.mts.map +1 -0
- package/dist/os/directory.mjs +25 -2
- package/dist/os/directory.mjs.map +1 -0
- package/dist/os/index.cjs +3 -3
- package/dist/os/index.d.cts +1 -1
- package/dist/os/index.d.mts +1 -1
- package/dist/os/index.mjs +2 -3
- package/dist/requestContext.cjs +10 -11
- package/dist/requestContext.cjs.map +1 -1
- package/dist/requestContext.d.cts +4 -8
- package/dist/requestContext.d.cts.map +1 -1
- package/dist/requestContext.d.mts +4 -8
- package/dist/requestContext.d.mts.map +1 -1
- package/dist/requestContext.mjs +1 -2
- package/dist/requestContext.mjs.map +1 -1
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-VH7oDXx4.cjs} +8 -10
- package/dist/timer.cjs +2 -2
- package/dist/timer.cjs.map +1 -1
- package/dist/timer.d.cts +1 -4
- package/dist/timer.d.cts.map +1 -1
- package/dist/timer.d.mts +1 -4
- package/dist/timer.d.mts.map +1 -1
- package/dist/timer.mjs +1 -1
- package/dist/timer.mjs.map +1 -1
- package/dist/transactions.cjs +123 -0
- package/dist/transactions.cjs.map +1 -0
- package/dist/transactions.d.cts +44 -0
- package/dist/transactions.d.cts.map +1 -0
- package/dist/transactions.d.mts +44 -0
- package/dist/transactions.d.mts.map +1 -0
- package/dist/transactions.mjs +118 -0
- package/dist/transactions.mjs.map +1 -0
- package/package.json +51 -8
- package/dist/Factory-AWn1IulI.d.cts +0 -147
- package/dist/Factory-AWn1IulI.d.cts.map +0 -1
- package/dist/Factory-BFVnMMCC.mjs +0 -51
- package/dist/Factory-BFVnMMCC.mjs.map +0 -1
- package/dist/Factory-BhjUOBWN.cjs +0 -57
- package/dist/Factory-BhjUOBWN.cjs.map +0 -1
- package/dist/Factory-C15SSK8_.d.mts +0 -147
- package/dist/Factory-C15SSK8_.d.mts.map +0 -1
- package/dist/KyselyFactory-BFqVIn_0.cjs +0 -246
- package/dist/KyselyFactory-BFqVIn_0.cjs.map +0 -1
- package/dist/KyselyFactory-C9Snz24z.d.mts +0 -228
- package/dist/KyselyFactory-C9Snz24z.d.mts.map +0 -1
- package/dist/KyselyFactory-CxUJCi--.d.cts +0 -228
- package/dist/KyselyFactory-CxUJCi--.d.cts.map +0 -1
- package/dist/KyselyFactory-DMswpwji.mjs +0 -241
- package/dist/KyselyFactory-DMswpwji.mjs.map +0 -1
- package/dist/ObjectionFactory-BeFBYcan.cjs +0 -272
- package/dist/ObjectionFactory-BeFBYcan.cjs.map +0 -1
- package/dist/ObjectionFactory-CYvaa0kU.d.cts +0 -241
- package/dist/ObjectionFactory-CYvaa0kU.d.cts.map +0 -1
- package/dist/ObjectionFactory-Cf2WI4o_.d.mts +0 -241
- package/dist/ObjectionFactory-Cf2WI4o_.d.mts.map +0 -1
- package/dist/ObjectionFactory-QCJ7u0Ql.mjs +0 -267
- package/dist/ObjectionFactory-QCJ7u0Ql.mjs.map +0 -1
- package/dist/PostgresKyselyMigrator-B2M6Gjvv.d.cts +0 -84
- package/dist/PostgresKyselyMigrator-B2M6Gjvv.d.cts.map +0 -1
- package/dist/PostgresKyselyMigrator-BGBxjnFv.cjs +0 -101
- package/dist/PostgresKyselyMigrator-BGBxjnFv.cjs.map +0 -1
- package/dist/PostgresKyselyMigrator-CvwXycJE.d.mts +0 -84
- package/dist/PostgresKyselyMigrator-CvwXycJE.d.mts.map +0 -1
- package/dist/PostgresKyselyMigrator-PI0QhvB1.mjs +0 -95
- package/dist/PostgresKyselyMigrator-PI0QhvB1.mjs.map +0 -1
- package/dist/PostgresMigrator-C_QQ6q35.d.mts.map +0 -1
- package/dist/PostgresMigrator-CeYy-eHF.d.cts.map +0 -1
- package/dist/PostgresMigrator-DVAY04qN.mjs +0 -166
- package/dist/PostgresMigrator-DVAY04qN.mjs.map +0 -1
- package/dist/PostgresMigrator-M9jpzOvN.cjs +0 -172
- package/dist/PostgresMigrator-M9jpzOvN.cjs.map +0 -1
- package/dist/PostgresObjectionMigrator-1j6YIB1c.d.mts +0 -79
- package/dist/PostgresObjectionMigrator-1j6YIB1c.d.mts.map +0 -1
- package/dist/PostgresObjectionMigrator-DHVC9h_P.d.cts +0 -79
- package/dist/PostgresObjectionMigrator-DHVC9h_P.d.cts.map +0 -1
- package/dist/PostgresObjectionMigrator-DSaPhwjY.cjs +0 -123
- package/dist/PostgresObjectionMigrator-DSaPhwjY.cjs.map +0 -1
- package/dist/PostgresObjectionMigrator-DjPKdUbm.mjs +0 -118
- package/dist/PostgresObjectionMigrator-DjPKdUbm.mjs.map +0 -1
- package/dist/VitestKyselyTransactionIsolator-1Saieke7.mjs +0 -67
- package/dist/VitestKyselyTransactionIsolator-1Saieke7.mjs.map +0 -1
- package/dist/VitestKyselyTransactionIsolator-BjJSXryR.cjs +0 -72
- package/dist/VitestKyselyTransactionIsolator-BjJSXryR.cjs.map +0 -1
- package/dist/VitestKyselyTransactionIsolator-CwlTo6yf.d.mts +0 -64
- package/dist/VitestKyselyTransactionIsolator-CwlTo6yf.d.mts.map +0 -1
- package/dist/VitestKyselyTransactionIsolator-DJasVuIZ.d.cts +0 -64
- package/dist/VitestKyselyTransactionIsolator-DJasVuIZ.d.cts.map +0 -1
- package/dist/VitestObjectionTransactionIsolator-B_VSWFum.mjs +0 -63
- package/dist/VitestObjectionTransactionIsolator-B_VSWFum.mjs.map +0 -1
- package/dist/VitestObjectionTransactionIsolator-CTTjvTPO.d.cts +0 -60
- package/dist/VitestObjectionTransactionIsolator-CTTjvTPO.d.cts.map +0 -1
- package/dist/VitestObjectionTransactionIsolator-CyZG6nq4.d.mts +0 -60
- package/dist/VitestObjectionTransactionIsolator-CyZG6nq4.d.mts.map +0 -1
- package/dist/VitestObjectionTransactionIsolator-DDoJTu7e.cjs +0 -68
- package/dist/VitestObjectionTransactionIsolator-DDoJTu7e.cjs.map +0 -1
- package/dist/VitestTransactionIsolator-BLaw80cx.d.mts +0 -223
- package/dist/VitestTransactionIsolator-BLaw80cx.d.mts.map +0 -1
- package/dist/VitestTransactionIsolator-CvwPecpl.mjs +0 -188
- package/dist/VitestTransactionIsolator-CvwPecpl.mjs.map +0 -1
- package/dist/VitestTransactionIsolator-DyiX-QtK.cjs +0 -206
- package/dist/VitestTransactionIsolator-DyiX-QtK.cjs.map +0 -1
- package/dist/VitestTransactionIsolator-glcxyS_R.d.cts +0 -223
- package/dist/VitestTransactionIsolator-glcxyS_R.d.cts.map +0 -1
- package/dist/directory-BxjqmtCT.mjs +0 -27
- package/dist/directory-BxjqmtCT.mjs.map +0 -1
- package/dist/directory-DD_xQoSh.cjs +0 -33
- package/dist/directory-DD_xQoSh.cjs.map +0 -1
- package/dist/directory-DiQ_DkaF.d.mts +0 -13
- package/dist/directory-DiQ_DkaF.d.mts.map +0 -1
- package/dist/directory-zIEh5ZPl.d.cts +0 -13
- package/dist/directory-zIEh5ZPl.d.cts.map +0 -1
- package/dist/faker-B14IEMIN.cjs +0 -304
- package/dist/faker-B14IEMIN.cjs.map +0 -1
- package/dist/faker-B6bmbGCM.d.mts +0 -166
- package/dist/faker-B6bmbGCM.d.mts.map +0 -1
- package/dist/faker-BGKYFoCT.mjs +0 -262
- package/dist/faker-BGKYFoCT.mjs.map +0 -1
- package/dist/faker-DvxiCtxc.d.cts +0 -166
- package/dist/faker-DvxiCtxc.d.cts.map +0 -1
package/README.md
CHANGED
|
@@ -54,6 +54,12 @@ import { itWithDir } from '@geekmidas/testkit/os';
|
|
|
54
54
|
import { createMockContext, createMockV1Event, createMockV2Event } from '@geekmidas/testkit/aws';
|
|
55
55
|
import { createMockLogger } from '@geekmidas/testkit/logger';
|
|
56
56
|
import { memoryAdapter } from '@geekmidas/testkit/better-auth';
|
|
57
|
+
|
|
58
|
+
// Feature tests: the primitives `@geekmidas/constructs/testing` builds on
|
|
59
|
+
import { Browser } from '@geekmidas/testkit/browser';
|
|
60
|
+
import { createMailbox } from '@geekmidas/testkit/mailbox';
|
|
61
|
+
import { runInTestContext, installContextFetch } from '@geekmidas/testkit/context';
|
|
62
|
+
import { TransactionRegistry } from '@geekmidas/testkit/transactions';
|
|
57
63
|
```
|
|
58
64
|
|
|
59
65
|
## Quick Start
|
|
@@ -321,6 +327,74 @@ describe('Authentication', () => {
|
|
|
321
327
|
});
|
|
322
328
|
```
|
|
323
329
|
|
|
330
|
+
## Feature Test Primitives
|
|
331
|
+
|
|
332
|
+
The pieces a feature test is built from — a test that drives an app the way it
|
|
333
|
+
runs deployed: a browser signs in, calls the API, the API calls the auth server,
|
|
334
|
+
each over a URL, every database in a transaction that is rolled back. The wiring
|
|
335
|
+
that knows about constructs lives in `@geekmidas/constructs/testing`; these know
|
|
336
|
+
nothing about them.
|
|
337
|
+
|
|
338
|
+
### `Browser`
|
|
339
|
+
|
|
340
|
+
A `fetch` with a cookie jar that follows the browser's rules (RFC 6265): a
|
|
341
|
+
`Set-Cookie` lands in the jar, and every later request to a URL the cookie
|
|
342
|
+
belongs to carries it. Redirects are followed hop by hop, keeping each hop's
|
|
343
|
+
cookies. Give it to an app's real clients:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
import { Browser as TestBrowser } from '@geekmidas/testkit/browser';
|
|
347
|
+
|
|
348
|
+
export class Browser extends TestBrowser {
|
|
349
|
+
readonly api = createApi({ baseURL: process.env.API_URL, fetch: this.fetch });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const browser = new Browser();
|
|
353
|
+
await browser.visit(magicLink); // 302 + Set-Cookie → the jar
|
|
354
|
+
await browser.api.get('/profile'); // sent with the session cookie
|
|
355
|
+
const restore = browser.install(); // the global fetch, for module-level clients
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
On the server side of a test — a handler serving a request — `browser.fetch` is
|
|
359
|
+
the plain `fetch`: a server forwards what it was handed and never reaches into a
|
|
360
|
+
browser's jar.
|
|
361
|
+
|
|
362
|
+
### `createMailbox`
|
|
363
|
+
|
|
364
|
+
Reads the mail an app actually sent, from Mailpit's HTTP API. One address per
|
|
365
|
+
test keeps tests apart, since Mailpit has one inbox and no transactions:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
const mailbox = createMailbox({ inbox: process.env.MAILER_INBOX_URL! });
|
|
369
|
+
|
|
370
|
+
const email = await mailbox('ada@shop.test').last(); // waits for it to arrive
|
|
371
|
+
await browser.visit(email.link!);
|
|
372
|
+
await mailbox('ada@shop.test').clear();
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Test context
|
|
376
|
+
|
|
377
|
+
`runInTestContext(id, fn)` carries a test's id through every await;
|
|
378
|
+
`installContextFetch()` stamps it onto every outgoing request as
|
|
379
|
+
`x-test-context-id`, so whatever serves a URL in-process finds the test the
|
|
380
|
+
request belongs to — including a request the code under test made while
|
|
381
|
+
handling another one.
|
|
382
|
+
|
|
383
|
+
### `TransactionRegistry`
|
|
384
|
+
|
|
385
|
+
One transaction per database per test — an app's database and a schema tenant
|
|
386
|
+
each on their own connection, as deployed — opened the first time the test
|
|
387
|
+
touches it and rolled back by `rollbackAll()`. Code under test may use
|
|
388
|
+
transactions freely: a `BEGIN` becomes a savepoint, so nothing it does can end
|
|
389
|
+
the test's transaction.
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const registry = new TransactionRegistry();
|
|
393
|
+
const db = await registry.get('Database', process.env.DATABASE_URL!);
|
|
394
|
+
// …
|
|
395
|
+
await registry.rollbackAll();
|
|
396
|
+
```
|
|
397
|
+
|
|
324
398
|
## Database Migration
|
|
325
399
|
|
|
326
400
|
TestKit includes utilities for managing test database migrations.
|
package/dist/Factory.cjs
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/Factory.ts
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for database factories used in testing.
|
|
5
|
+
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
6
|
+
*
|
|
7
|
+
* @template Builders - Record of builder functions for creating individual entities
|
|
8
|
+
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Define builders for creating individual records
|
|
13
|
+
* const builders = {
|
|
14
|
+
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
15
|
+
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* // Define seeds for complex scenarios
|
|
19
|
+
* const seeds = {
|
|
20
|
+
* userWithPosts: async (attrs, factory) => {
|
|
21
|
+
* const user = await factory.insert('user', attrs);
|
|
22
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
23
|
+
* return user;
|
|
24
|
+
* }
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
var Factory = class {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a typed seed function with proper type inference.
|
|
31
|
+
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
32
|
+
*
|
|
33
|
+
* @template Seed - The seed function type
|
|
34
|
+
* @param seedFn - The seed function to wrap
|
|
35
|
+
* @returns The same seed function with proper typing
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
40
|
+
* const user = await factory.insert('user', attrs);
|
|
41
|
+
* return user;
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
static createSeed(seedFn) {
|
|
46
|
+
return seedFn;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
exports.Factory = Factory;
|
|
2
51
|
|
|
3
|
-
|
|
52
|
+
//# sourceMappingURL=Factory.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.cjs","names":[],"sources":["../src/Factory.ts"],"sourcesContent":["import type { FakerFactory } from './faker';\n\n/**\n * Abstract base class for database factories used in testing.\n * Provides a standardized interface for creating test data using builder and seed patterns.\n *\n * @template Builders - Record of builder functions for creating individual entities\n * @template Seeds - Record of seed functions for creating complex test scenarios\n *\n * @example\n * ```typescript\n * // Define builders for creating individual records\n * const builders = {\n * user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),\n * post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })\n * };\n *\n * // Define seeds for complex scenarios\n * const seeds = {\n * userWithPosts: async (attrs, factory) => {\n * const user = await factory.insert('user', attrs);\n * await factory.insertMany(3, 'post', { userId: user.id });\n * return user;\n * }\n * };\n * ```\n */\nexport abstract class Factory<\n\tBuilders extends Record<string, any>,\n\tSeeds extends Record<string, any>,\n> {\n\t/**\n\t * Creates a typed seed function with proper type inference.\n\t * This is a utility method to help with TypeScript type checking when defining seeds.\n\t *\n\t * @template Seed - The seed function type\n\t * @param seedFn - The seed function to wrap\n\t * @returns The same seed function with proper typing\n\t *\n\t * @example\n\t * ```typescript\n\t * const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {\n\t * const user = await factory.insert('user', attrs);\n\t * return user;\n\t * });\n\t * ```\n\t */\n\tstatic createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {\n\t\treturn seedFn;\n\t}\n\t/**\n\t * Inserts an object into the database using a builder function.\n\t *\n\t * @param builderName - The name of the builder to use\n\t * @param attrs - The attributes to insert\n\t */\n\tabstract insert<K extends keyof Builders>(\n\t\tbuilderName: K,\n\t\tattrs?: Parameters<Builders[K]>[0],\n\t): Promise<Awaited<ReturnType<Builders[K]>>>;\n\n\t/**\n\t * Inserts multiple objects into the database\n\t *\n\t * @param count - Number of objects to insert\n\t * @param builderName - The name of the builder to use\n\t * @param attrs - The attributes to insert\n\t */\n\tabstract insertMany<K extends keyof Builders>(\n\t\tcount: number,\n\t\tbuilderName: K,\n\t\tattrs?:\n\t\t\t| Parameters<Builders[K]>[0]\n\t\t\t| ((\n\t\t\t\t\tidx: number,\n\t\t\t\t\tfaker: FakerFactory,\n\t\t\t ) => Promise<Parameters<Builders[K]>[0]>),\n\t): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n\n\t/**\n\t * Seeds the database using a seed function.\n\t *\n\t * @param seedName - The name of the seed to use\n\t * @returns The result of the seed function\n\t * @param attrs - The attributes to pass to the seed function\n\t */\n\tabstract seed<K extends keyof Seeds>(\n\t\tseedName: K,\n\t\tattrs?: ExtractSeedAttrs<Seeds[K]>,\n\t): ReturnType<Seeds[K]>;\n}\n\n/**\n * Type definition for a factory builder function that can work with different database types.\n * Builders are responsible for creating individual database records with default values and relationships.\n *\n * @template Attrs - The attributes/input type for the builder\n * @template Factory - The factory instance type\n * @template Result - The type of object returned by the builder\n * @template DB - The database connection type (Kysely, Knex, etc.)\n *\n * @param attrs - Partial attributes to override defaults\n * @param factory - The factory instance for creating related records\n * @param db - The database connection\n * @returns The created record or a promise resolving to it\n *\n * @example\n * ```typescript\n * const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =\n * async (attrs, factory, db) => {\n * return {\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * ...attrs\n * };\n * };\n * ```\n */\nexport type MixedFactoryBuilder<\n\tAttrs = any,\n\tFactory = any,\n\tResult = any,\n\tDB = any,\n> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;\n\n/**\n * Type definition for a factory seed function used to create complex test scenarios.\n * Seeds typically create multiple related records to set up a complete test environment.\n *\n * @template Attrs - The attributes/input type for the seed\n * @template Factory - The factory instance type\n * @template Result - The type of object returned by the seed\n * @template DB - The database connection type (Kysely, Knex, etc.)\n *\n * @param context - Object containing attrs, factory, and db\n * @param context.attrs - Configuration attributes for the seed\n * @param context.factory - The factory instance for creating records\n * @param context.db - The database connection\n * @returns A promise resolving to the seed result\n *\n * @example\n * ```typescript\n * const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =\n * async ({ attrs, factory, db }) => {\n * const user = await factory.insert('user', attrs);\n * const postCount = attrs.postCount || 3;\n *\n * for (let i = 0; i < postCount; i++) {\n * await factory.insert('post', { userId: user.id });\n * }\n *\n * return user;\n * };\n * ```\n */\nexport type FactorySeed<\n\tAttrs = any,\n\tFactory = any,\n\tResult = any,\n\tDB = any,\n> = (context: { attrs: Attrs; factory: Factory; db: DB }) => Promise<Result>;\n\n/**\n * Helper type to extract the Attrs type from a FactorySeed function.\n * Used internally by Factory implementations to correctly type the seed method parameters.\n */\nexport type ExtractSeedAttrs<T> = T extends (context: {\n\tattrs: infer A;\n\tfactory: any;\n\tdb: any;\n}) => any\n\t? A\n\t: never;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,UAAtB,MAGE;;;;;;;;;;;;;;;;;CAiBD,OAAO,WAAqC,QAAoB;EAC/D,OAAO;CACR;AAyCD"}
|
package/dist/Factory.d.cts
CHANGED
|
@@ -1,3 +1,143 @@
|
|
|
1
|
-
import "./faker
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { FakerFactory } from "./faker.cjs";
|
|
2
|
+
//#region src/Factory.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for database factories used in testing.
|
|
5
|
+
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
6
|
+
*
|
|
7
|
+
* @template Builders - Record of builder functions for creating individual entities
|
|
8
|
+
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Define builders for creating individual records
|
|
13
|
+
* const builders = {
|
|
14
|
+
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
15
|
+
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* // Define seeds for complex scenarios
|
|
19
|
+
* const seeds = {
|
|
20
|
+
* userWithPosts: async (attrs, factory) => {
|
|
21
|
+
* const user = await factory.insert('user', attrs);
|
|
22
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
23
|
+
* return user;
|
|
24
|
+
* }
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare abstract class Factory<Builders extends Record<string, any>, Seeds extends Record<string, any>> {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a typed seed function with proper type inference.
|
|
31
|
+
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
32
|
+
*
|
|
33
|
+
* @template Seed - The seed function type
|
|
34
|
+
* @param seedFn - The seed function to wrap
|
|
35
|
+
* @returns The same seed function with proper typing
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
40
|
+
* const user = await factory.insert('user', attrs);
|
|
41
|
+
* return user;
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
46
|
+
/**
|
|
47
|
+
* Inserts an object into the database using a builder function.
|
|
48
|
+
*
|
|
49
|
+
* @param builderName - The name of the builder to use
|
|
50
|
+
* @param attrs - The attributes to insert
|
|
51
|
+
*/
|
|
52
|
+
abstract insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
53
|
+
/**
|
|
54
|
+
* Inserts multiple objects into the database
|
|
55
|
+
*
|
|
56
|
+
* @param count - Number of objects to insert
|
|
57
|
+
* @param builderName - The name of the builder to use
|
|
58
|
+
* @param attrs - The attributes to insert
|
|
59
|
+
*/
|
|
60
|
+
abstract insertMany<K extends keyof Builders>(count: number, builderName: K, attrs?: Parameters<Builders[K]>[0] | ((idx: number, faker: FakerFactory) => Promise<Parameters<Builders[K]>[0]>)): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Seeds the database using a seed function.
|
|
63
|
+
*
|
|
64
|
+
* @param seedName - The name of the seed to use
|
|
65
|
+
* @returns The result of the seed function
|
|
66
|
+
* @param attrs - The attributes to pass to the seed function
|
|
67
|
+
*/
|
|
68
|
+
abstract seed<K extends keyof Seeds>(seedName: K, attrs?: ExtractSeedAttrs<Seeds[K]>): ReturnType<Seeds[K]>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Type definition for a factory builder function that can work with different database types.
|
|
72
|
+
* Builders are responsible for creating individual database records with default values and relationships.
|
|
73
|
+
*
|
|
74
|
+
* @template Attrs - The attributes/input type for the builder
|
|
75
|
+
* @template Factory - The factory instance type
|
|
76
|
+
* @template Result - The type of object returned by the builder
|
|
77
|
+
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
78
|
+
*
|
|
79
|
+
* @param attrs - Partial attributes to override defaults
|
|
80
|
+
* @param factory - The factory instance for creating related records
|
|
81
|
+
* @param db - The database connection
|
|
82
|
+
* @returns The created record or a promise resolving to it
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =
|
|
87
|
+
* async (attrs, factory, db) => {
|
|
88
|
+
* return {
|
|
89
|
+
* id: faker.string.uuid(),
|
|
90
|
+
* name: faker.person.fullName(),
|
|
91
|
+
* email: faker.internet.email(),
|
|
92
|
+
* ...attrs
|
|
93
|
+
* };
|
|
94
|
+
* };
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export type MixedFactoryBuilder<Attrs = any, Factory = any, Result = any, DB = any> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;
|
|
98
|
+
/**
|
|
99
|
+
* Type definition for a factory seed function used to create complex test scenarios.
|
|
100
|
+
* Seeds typically create multiple related records to set up a complete test environment.
|
|
101
|
+
*
|
|
102
|
+
* @template Attrs - The attributes/input type for the seed
|
|
103
|
+
* @template Factory - The factory instance type
|
|
104
|
+
* @template Result - The type of object returned by the seed
|
|
105
|
+
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
106
|
+
*
|
|
107
|
+
* @param context - Object containing attrs, factory, and db
|
|
108
|
+
* @param context.attrs - Configuration attributes for the seed
|
|
109
|
+
* @param context.factory - The factory instance for creating records
|
|
110
|
+
* @param context.db - The database connection
|
|
111
|
+
* @returns A promise resolving to the seed result
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =
|
|
116
|
+
* async ({ attrs, factory, db }) => {
|
|
117
|
+
* const user = await factory.insert('user', attrs);
|
|
118
|
+
* const postCount = attrs.postCount || 3;
|
|
119
|
+
*
|
|
120
|
+
* for (let i = 0; i < postCount; i++) {
|
|
121
|
+
* await factory.insert('post', { userId: user.id });
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* return user;
|
|
125
|
+
* };
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export type FactorySeed<Attrs = any, Factory = any, Result = any, DB = any> = (context: {
|
|
129
|
+
attrs: Attrs;
|
|
130
|
+
factory: Factory;
|
|
131
|
+
db: DB;
|
|
132
|
+
}) => Promise<Result>;
|
|
133
|
+
/**
|
|
134
|
+
* Helper type to extract the Attrs type from a FactorySeed function.
|
|
135
|
+
* Used internally by Factory implementations to correctly type the seed method parameters.
|
|
136
|
+
*/
|
|
137
|
+
export type ExtractSeedAttrs<T> = T extends ((context: {
|
|
138
|
+
attrs: infer A;
|
|
139
|
+
factory: any;
|
|
140
|
+
db: any;
|
|
141
|
+
}) => any) ? A : never;
|
|
142
|
+
//#endregion
|
|
143
|
+
//# sourceMappingURL=Factory.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.d.cts","names":[],"sources":["../src/Factory.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;8BA2BsB,QACrB,iBAAiB,qBACjB,cAAc;;;;;;;;;;;;;;;;;SAkBP,WAAW,aAAa,aAAa,QAAQ,OAAO;;;;;;;WASlD,OAAO,gBAAgB,UAC/B,aAAa,GACb,QAAQ,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;WAS9B,WAAW,gBAAgB,UACnC,eACA,aAAa,GACb,QACG,WAAW,SAAS,WAEpB,aACA,OAAO,iBACF,QAAQ,WAAW,SAAS,WAClC,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;WAS9B,KAAK,gBAAgB,OAC7B,UAAU,GACV,QAAQ,iBAAiB,MAAM,MAC7B,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA8BT,oBACX,aACA,eACA,cACA,aACI,OAAO,OAAO,SAAS,SAAS,IAAI,OAAO,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgCrD,YACX,aACA,eACA,cACA,aACI;EAAW,OAAO;EAAO,SAAS;EAAS,IAAI;MAAS,QAAQ;;;;;YAMzD,iBAAiB,KAAK,YAAW;EAC5C,aAAa;EACb;EACA;aAEE"}
|
package/dist/Factory.d.mts
CHANGED
|
@@ -1,3 +1,143 @@
|
|
|
1
|
-
import "./faker
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { FakerFactory } from "./faker.mjs";
|
|
2
|
+
//#region src/Factory.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for database factories used in testing.
|
|
5
|
+
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
6
|
+
*
|
|
7
|
+
* @template Builders - Record of builder functions for creating individual entities
|
|
8
|
+
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Define builders for creating individual records
|
|
13
|
+
* const builders = {
|
|
14
|
+
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
15
|
+
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* // Define seeds for complex scenarios
|
|
19
|
+
* const seeds = {
|
|
20
|
+
* userWithPosts: async (attrs, factory) => {
|
|
21
|
+
* const user = await factory.insert('user', attrs);
|
|
22
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
23
|
+
* return user;
|
|
24
|
+
* }
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare abstract class Factory<Builders extends Record<string, any>, Seeds extends Record<string, any>> {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a typed seed function with proper type inference.
|
|
31
|
+
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
32
|
+
*
|
|
33
|
+
* @template Seed - The seed function type
|
|
34
|
+
* @param seedFn - The seed function to wrap
|
|
35
|
+
* @returns The same seed function with proper typing
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
40
|
+
* const user = await factory.insert('user', attrs);
|
|
41
|
+
* return user;
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
46
|
+
/**
|
|
47
|
+
* Inserts an object into the database using a builder function.
|
|
48
|
+
*
|
|
49
|
+
* @param builderName - The name of the builder to use
|
|
50
|
+
* @param attrs - The attributes to insert
|
|
51
|
+
*/
|
|
52
|
+
abstract insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
53
|
+
/**
|
|
54
|
+
* Inserts multiple objects into the database
|
|
55
|
+
*
|
|
56
|
+
* @param count - Number of objects to insert
|
|
57
|
+
* @param builderName - The name of the builder to use
|
|
58
|
+
* @param attrs - The attributes to insert
|
|
59
|
+
*/
|
|
60
|
+
abstract insertMany<K extends keyof Builders>(count: number, builderName: K, attrs?: Parameters<Builders[K]>[0] | ((idx: number, faker: FakerFactory) => Promise<Parameters<Builders[K]>[0]>)): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Seeds the database using a seed function.
|
|
63
|
+
*
|
|
64
|
+
* @param seedName - The name of the seed to use
|
|
65
|
+
* @returns The result of the seed function
|
|
66
|
+
* @param attrs - The attributes to pass to the seed function
|
|
67
|
+
*/
|
|
68
|
+
abstract seed<K extends keyof Seeds>(seedName: K, attrs?: ExtractSeedAttrs<Seeds[K]>): ReturnType<Seeds[K]>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Type definition for a factory builder function that can work with different database types.
|
|
72
|
+
* Builders are responsible for creating individual database records with default values and relationships.
|
|
73
|
+
*
|
|
74
|
+
* @template Attrs - The attributes/input type for the builder
|
|
75
|
+
* @template Factory - The factory instance type
|
|
76
|
+
* @template Result - The type of object returned by the builder
|
|
77
|
+
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
78
|
+
*
|
|
79
|
+
* @param attrs - Partial attributes to override defaults
|
|
80
|
+
* @param factory - The factory instance for creating related records
|
|
81
|
+
* @param db - The database connection
|
|
82
|
+
* @returns The created record or a promise resolving to it
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =
|
|
87
|
+
* async (attrs, factory, db) => {
|
|
88
|
+
* return {
|
|
89
|
+
* id: faker.string.uuid(),
|
|
90
|
+
* name: faker.person.fullName(),
|
|
91
|
+
* email: faker.internet.email(),
|
|
92
|
+
* ...attrs
|
|
93
|
+
* };
|
|
94
|
+
* };
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export type MixedFactoryBuilder<Attrs = any, Factory = any, Result = any, DB = any> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;
|
|
98
|
+
/**
|
|
99
|
+
* Type definition for a factory seed function used to create complex test scenarios.
|
|
100
|
+
* Seeds typically create multiple related records to set up a complete test environment.
|
|
101
|
+
*
|
|
102
|
+
* @template Attrs - The attributes/input type for the seed
|
|
103
|
+
* @template Factory - The factory instance type
|
|
104
|
+
* @template Result - The type of object returned by the seed
|
|
105
|
+
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
106
|
+
*
|
|
107
|
+
* @param context - Object containing attrs, factory, and db
|
|
108
|
+
* @param context.attrs - Configuration attributes for the seed
|
|
109
|
+
* @param context.factory - The factory instance for creating records
|
|
110
|
+
* @param context.db - The database connection
|
|
111
|
+
* @returns A promise resolving to the seed result
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =
|
|
116
|
+
* async ({ attrs, factory, db }) => {
|
|
117
|
+
* const user = await factory.insert('user', attrs);
|
|
118
|
+
* const postCount = attrs.postCount || 3;
|
|
119
|
+
*
|
|
120
|
+
* for (let i = 0; i < postCount; i++) {
|
|
121
|
+
* await factory.insert('post', { userId: user.id });
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* return user;
|
|
125
|
+
* };
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export type FactorySeed<Attrs = any, Factory = any, Result = any, DB = any> = (context: {
|
|
129
|
+
attrs: Attrs;
|
|
130
|
+
factory: Factory;
|
|
131
|
+
db: DB;
|
|
132
|
+
}) => Promise<Result>;
|
|
133
|
+
/**
|
|
134
|
+
* Helper type to extract the Attrs type from a FactorySeed function.
|
|
135
|
+
* Used internally by Factory implementations to correctly type the seed method parameters.
|
|
136
|
+
*/
|
|
137
|
+
export type ExtractSeedAttrs<T> = T extends ((context: {
|
|
138
|
+
attrs: infer A;
|
|
139
|
+
factory: any;
|
|
140
|
+
db: any;
|
|
141
|
+
}) => any) ? A : never;
|
|
142
|
+
//#endregion
|
|
143
|
+
//# sourceMappingURL=Factory.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.d.mts","names":[],"sources":["../src/Factory.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;8BA2BsB,QACrB,iBAAiB,qBACjB,cAAc;;;;;;;;;;;;;;;;;SAkBP,WAAW,aAAa,aAAa,QAAQ,OAAO;;;;;;;WASlD,OAAO,gBAAgB,UAC/B,aAAa,GACb,QAAQ,WAAW,SAAS,SAC1B,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;WAS9B,WAAW,gBAAgB,UACnC,eACA,aAAa,GACb,QACG,WAAW,SAAS,WAEpB,aACA,OAAO,iBACF,QAAQ,WAAW,SAAS,WAClC,QAAQ,QAAQ,WAAW,SAAS;;;;;;;;WAS9B,KAAK,gBAAgB,OAC7B,UAAU,GACV,QAAQ,iBAAiB,MAAM,MAC7B,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA8BT,oBACX,aACA,eACA,cACA,aACI,OAAO,OAAO,SAAS,SAAS,IAAI,OAAO,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgCrD,YACX,aACA,eACA,cACA,aACI;EAAW,OAAO;EAAO,SAAS;EAAS,IAAI;MAAS,QAAQ;;;;;YAMzD,iBAAiB,KAAK,YAAW;EAC5C,aAAa;EACb;EACA;aAEE"}
|
package/dist/Factory.mjs
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/Factory.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for database factories used in testing.
|
|
4
|
+
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
5
|
+
*
|
|
6
|
+
* @template Builders - Record of builder functions for creating individual entities
|
|
7
|
+
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Define builders for creating individual records
|
|
12
|
+
* const builders = {
|
|
13
|
+
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
14
|
+
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
15
|
+
* };
|
|
16
|
+
*
|
|
17
|
+
* // Define seeds for complex scenarios
|
|
18
|
+
* const seeds = {
|
|
19
|
+
* userWithPosts: async (attrs, factory) => {
|
|
20
|
+
* const user = await factory.insert('user', attrs);
|
|
21
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
22
|
+
* return user;
|
|
23
|
+
* }
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
var Factory = class {
|
|
28
|
+
/**
|
|
29
|
+
* Creates a typed seed function with proper type inference.
|
|
30
|
+
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
31
|
+
*
|
|
32
|
+
* @template Seed - The seed function type
|
|
33
|
+
* @param seedFn - The seed function to wrap
|
|
34
|
+
* @returns The same seed function with proper typing
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
39
|
+
* const user = await factory.insert('user', attrs);
|
|
40
|
+
* return user;
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
static createSeed(seedFn) {
|
|
45
|
+
return seedFn;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { Factory };
|
|
2
50
|
|
|
3
|
-
|
|
51
|
+
//# sourceMappingURL=Factory.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.mjs","names":[],"sources":["../src/Factory.ts"],"sourcesContent":["import type { FakerFactory } from './faker';\n\n/**\n * Abstract base class for database factories used in testing.\n * Provides a standardized interface for creating test data using builder and seed patterns.\n *\n * @template Builders - Record of builder functions for creating individual entities\n * @template Seeds - Record of seed functions for creating complex test scenarios\n *\n * @example\n * ```typescript\n * // Define builders for creating individual records\n * const builders = {\n * user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),\n * post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })\n * };\n *\n * // Define seeds for complex scenarios\n * const seeds = {\n * userWithPosts: async (attrs, factory) => {\n * const user = await factory.insert('user', attrs);\n * await factory.insertMany(3, 'post', { userId: user.id });\n * return user;\n * }\n * };\n * ```\n */\nexport abstract class Factory<\n\tBuilders extends Record<string, any>,\n\tSeeds extends Record<string, any>,\n> {\n\t/**\n\t * Creates a typed seed function with proper type inference.\n\t * This is a utility method to help with TypeScript type checking when defining seeds.\n\t *\n\t * @template Seed - The seed function type\n\t * @param seedFn - The seed function to wrap\n\t * @returns The same seed function with proper typing\n\t *\n\t * @example\n\t * ```typescript\n\t * const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {\n\t * const user = await factory.insert('user', attrs);\n\t * return user;\n\t * });\n\t * ```\n\t */\n\tstatic createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {\n\t\treturn seedFn;\n\t}\n\t/**\n\t * Inserts an object into the database using a builder function.\n\t *\n\t * @param builderName - The name of the builder to use\n\t * @param attrs - The attributes to insert\n\t */\n\tabstract insert<K extends keyof Builders>(\n\t\tbuilderName: K,\n\t\tattrs?: Parameters<Builders[K]>[0],\n\t): Promise<Awaited<ReturnType<Builders[K]>>>;\n\n\t/**\n\t * Inserts multiple objects into the database\n\t *\n\t * @param count - Number of objects to insert\n\t * @param builderName - The name of the builder to use\n\t * @param attrs - The attributes to insert\n\t */\n\tabstract insertMany<K extends keyof Builders>(\n\t\tcount: number,\n\t\tbuilderName: K,\n\t\tattrs?:\n\t\t\t| Parameters<Builders[K]>[0]\n\t\t\t| ((\n\t\t\t\t\tidx: number,\n\t\t\t\t\tfaker: FakerFactory,\n\t\t\t ) => Promise<Parameters<Builders[K]>[0]>),\n\t): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n\n\t/**\n\t * Seeds the database using a seed function.\n\t *\n\t * @param seedName - The name of the seed to use\n\t * @returns The result of the seed function\n\t * @param attrs - The attributes to pass to the seed function\n\t */\n\tabstract seed<K extends keyof Seeds>(\n\t\tseedName: K,\n\t\tattrs?: ExtractSeedAttrs<Seeds[K]>,\n\t): ReturnType<Seeds[K]>;\n}\n\n/**\n * Type definition for a factory builder function that can work with different database types.\n * Builders are responsible for creating individual database records with default values and relationships.\n *\n * @template Attrs - The attributes/input type for the builder\n * @template Factory - The factory instance type\n * @template Result - The type of object returned by the builder\n * @template DB - The database connection type (Kysely, Knex, etc.)\n *\n * @param attrs - Partial attributes to override defaults\n * @param factory - The factory instance for creating related records\n * @param db - The database connection\n * @returns The created record or a promise resolving to it\n *\n * @example\n * ```typescript\n * const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =\n * async (attrs, factory, db) => {\n * return {\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * ...attrs\n * };\n * };\n * ```\n */\nexport type MixedFactoryBuilder<\n\tAttrs = any,\n\tFactory = any,\n\tResult = any,\n\tDB = any,\n> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;\n\n/**\n * Type definition for a factory seed function used to create complex test scenarios.\n * Seeds typically create multiple related records to set up a complete test environment.\n *\n * @template Attrs - The attributes/input type for the seed\n * @template Factory - The factory instance type\n * @template Result - The type of object returned by the seed\n * @template DB - The database connection type (Kysely, Knex, etc.)\n *\n * @param context - Object containing attrs, factory, and db\n * @param context.attrs - Configuration attributes for the seed\n * @param context.factory - The factory instance for creating records\n * @param context.db - The database connection\n * @returns A promise resolving to the seed result\n *\n * @example\n * ```typescript\n * const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =\n * async ({ attrs, factory, db }) => {\n * const user = await factory.insert('user', attrs);\n * const postCount = attrs.postCount || 3;\n *\n * for (let i = 0; i < postCount; i++) {\n * await factory.insert('post', { userId: user.id });\n * }\n *\n * return user;\n * };\n * ```\n */\nexport type FactorySeed<\n\tAttrs = any,\n\tFactory = any,\n\tResult = any,\n\tDB = any,\n> = (context: { attrs: Attrs; factory: Factory; db: DB }) => Promise<Result>;\n\n/**\n * Helper type to extract the Attrs type from a FactorySeed function.\n * Used internally by Factory implementations to correctly type the seed method parameters.\n */\nexport type ExtractSeedAttrs<T> = T extends (context: {\n\tattrs: infer A;\n\tfactory: any;\n\tdb: any;\n}) => any\n\t? A\n\t: never;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,UAAtB,MAGE;;;;;;;;;;;;;;;;;CAiBD,OAAO,WAAqC,QAAoB;EAC/D,OAAO;CACR;AAyCD"}
|