@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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import { Kysely, PostgresDialect } from "kysely";
|
|
3
|
+
//#region src/transactions.ts
|
|
4
|
+
/**
|
|
5
|
+
* A transaction per database, per test — as each runs deployed.
|
|
6
|
+
*
|
|
7
|
+
* An app's database and a schema tenant such as the auth server's are separate
|
|
8
|
+
* databases to the code using them: separate connections, credentials, roles
|
|
9
|
+
* and search paths. A test keeps them that way. Each gets its own connection,
|
|
10
|
+
* opened into a transaction the first time the test touches it, and every one
|
|
11
|
+
* is rolled back when the test ends.
|
|
12
|
+
*
|
|
13
|
+
* Code under test must be free to use transactions itself, and better-auth
|
|
14
|
+
* does — it also calls `db.connection()`, which Kysely refuses on a
|
|
15
|
+
* `Transaction`. So what a test hands over is not a `Transaction` but a Kysely
|
|
16
|
+
* over the one connection already inside the test's transaction, on which a
|
|
17
|
+
* `BEGIN` becomes a savepoint and a `COMMIT` releases it. Nothing the code does
|
|
18
|
+
* can end the transaction the test will roll back.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The connection settings for a database URL.
|
|
22
|
+
*
|
|
23
|
+
* `?search_path=` is not a libpq parameter: a URL carrying it connects and then
|
|
24
|
+
* resolves every name against `public`. Postgres takes it as a startup option,
|
|
25
|
+
* which is what a schema tenant's URL needs to reach its own tables.
|
|
26
|
+
*/
|
|
27
|
+
function connectionConfig(url) {
|
|
28
|
+
const parsed = new URL(url);
|
|
29
|
+
const searchPath = parsed.searchParams.get("search_path");
|
|
30
|
+
if (!searchPath) return { connectionString: url };
|
|
31
|
+
parsed.searchParams.delete("search_path");
|
|
32
|
+
return {
|
|
33
|
+
connectionString: parsed.toString(),
|
|
34
|
+
options: `-c search_path=${searchPath}`
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Open a connection to `url` and begin the transaction a test will roll back.
|
|
39
|
+
*
|
|
40
|
+
* `config` is what the database's own clients are built with — its plugins
|
|
41
|
+
* above all. The code under test is handed this Kysely in place of its own, so
|
|
42
|
+
* one built without them runs different queries than production does.
|
|
43
|
+
*/
|
|
44
|
+
async function openBoundTransaction(url, config = {}) {
|
|
45
|
+
const client = new pg.Client(connectionConfig(url));
|
|
46
|
+
await client.connect();
|
|
47
|
+
await client.query("BEGIN");
|
|
48
|
+
return {
|
|
49
|
+
db: new Kysely({
|
|
50
|
+
...config,
|
|
51
|
+
dialect: new PostgresDialect({ pool: {
|
|
52
|
+
connect: async () => savepointing(client),
|
|
53
|
+
end: async () => {}
|
|
54
|
+
} })
|
|
55
|
+
}),
|
|
56
|
+
async rollback() {
|
|
57
|
+
try {
|
|
58
|
+
await client.query("ROLLBACK");
|
|
59
|
+
} finally {
|
|
60
|
+
await client.end();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The client, with transaction control turned into savepoints.
|
|
67
|
+
*
|
|
68
|
+
* Kysely issues `begin`/`commit`/`rollback` as plain statements; this is the
|
|
69
|
+
* one place they can be caught. A depth counter names the savepoints, so
|
|
70
|
+
* nested transactions nest.
|
|
71
|
+
*/
|
|
72
|
+
function savepointing(client) {
|
|
73
|
+
let depth = 0;
|
|
74
|
+
const query = client.query.bind(client);
|
|
75
|
+
const wrapped = Object.create(client);
|
|
76
|
+
Object.assign(wrapped, {
|
|
77
|
+
query: (text, ...rest) => {
|
|
78
|
+
const statement = typeof text === "string" ? text.trim().toLowerCase() : void 0;
|
|
79
|
+
if (statement === "begin" || statement?.startsWith("start transaction")) {
|
|
80
|
+
depth++;
|
|
81
|
+
return query(`SAVEPOINT test_sp_${depth}`);
|
|
82
|
+
}
|
|
83
|
+
if (statement === "commit") return query(`RELEASE SAVEPOINT test_sp_${depth--}`);
|
|
84
|
+
if (statement === "rollback") return query(`ROLLBACK TO SAVEPOINT test_sp_${depth--}`);
|
|
85
|
+
return query(text, ...rest);
|
|
86
|
+
},
|
|
87
|
+
release: () => {}
|
|
88
|
+
});
|
|
89
|
+
return wrapped;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The transactions one test has opened, by database.
|
|
93
|
+
*
|
|
94
|
+
* `get` opens a database's transaction the first time it is asked for and
|
|
95
|
+
* hands back the same one after that — including to a caller that asks while
|
|
96
|
+
* it is still opening. `rollbackAll` ends every one of them.
|
|
97
|
+
*/
|
|
98
|
+
var TransactionRegistry = class {
|
|
99
|
+
open = /* @__PURE__ */ new Map();
|
|
100
|
+
get(key, url, config) {
|
|
101
|
+
let transaction = this.open.get(key);
|
|
102
|
+
if (!transaction) {
|
|
103
|
+
transaction = openBoundTransaction(url, config);
|
|
104
|
+
this.open.set(key, transaction);
|
|
105
|
+
}
|
|
106
|
+
return transaction.then(({ db }) => db);
|
|
107
|
+
}
|
|
108
|
+
async rollbackAll() {
|
|
109
|
+
const transactions = [...this.open.values()];
|
|
110
|
+
this.open.clear();
|
|
111
|
+
const failed = (await Promise.allSettled(transactions.map(async (transaction) => (await transaction).rollback()))).find((result) => result.status === "rejected");
|
|
112
|
+
if (failed) throw failed.reason;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
116
|
+
export { TransactionRegistry, connectionConfig, openBoundTransaction };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=transactions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactions.mjs","names":[],"sources":["../src/transactions.ts"],"sourcesContent":["/**\n * A transaction per database, per test — as each runs deployed.\n *\n * An app's database and a schema tenant such as the auth server's are separate\n * databases to the code using them: separate connections, credentials, roles\n * and search paths. A test keeps them that way. Each gets its own connection,\n * opened into a transaction the first time the test touches it, and every one\n * is rolled back when the test ends.\n *\n * Code under test must be free to use transactions itself, and better-auth\n * does — it also calls `db.connection()`, which Kysely refuses on a\n * `Transaction`. So what a test hands over is not a `Transaction` but a Kysely\n * over the one connection already inside the test's transaction, on which a\n * `BEGIN` becomes a savepoint and a `COMMIT` releases it. Nothing the code does\n * can end the transaction the test will roll back.\n */\n\nimport { Kysely, type KyselyConfig, PostgresDialect } from 'kysely';\nimport pg from 'pg';\n\n/** How to reach one database: a URL, and its search path as a startup option. */\nexport interface ConnectionConfig {\n\tconnectionString: string;\n\toptions?: string;\n}\n\n/**\n * The connection settings for a database URL.\n *\n * `?search_path=` is not a libpq parameter: a URL carrying it connects and then\n * resolves every name against `public`. Postgres takes it as a startup option,\n * which is what a schema tenant's URL needs to reach its own tables.\n */\nexport function connectionConfig(url: string): ConnectionConfig {\n\tconst parsed = new URL(url);\n\tconst searchPath = parsed.searchParams.get('search_path');\n\tif (!searchPath) return { connectionString: url };\n\n\tparsed.searchParams.delete('search_path');\n\treturn {\n\t\tconnectionString: parsed.toString(),\n\t\toptions: `-c search_path=${searchPath}`,\n\t};\n}\n\n/** One database's connection, inside a transaction the test will roll back. */\nexport interface BoundTransaction {\n\t/** Everything queried through this runs inside the test's transaction. */\n\treadonly db: Kysely<any>;\n\t/** Undo everything, and let the connection go. */\n\trollback(): Promise<void>;\n}\n\n/**\n * Open a connection to `url` and begin the transaction a test will roll back.\n *\n * `config` is what the database's own clients are built with — its plugins\n * above all. The code under test is handed this Kysely in place of its own, so\n * one built without them runs different queries than production does.\n */\nexport async function openBoundTransaction(\n\turl: string,\n\tconfig: Omit<KyselyConfig, 'dialect'> = {},\n): Promise<BoundTransaction> {\n\tconst client = new pg.Client(connectionConfig(url));\n\tawait client.connect();\n\tawait client.query('BEGIN');\n\n\treturn {\n\t\tdb: new Kysely({\n\t\t\t...config,\n\t\t\tdialect: new PostgresDialect({\n\t\t\t\t// A \"pool\" of the one connection. Released never, ended never: the\n\t\t\t\t// test owns it, and it closes in `rollback`.\n\t\t\t\tpool: {\n\t\t\t\t\tconnect: async () => savepointing(client),\n\t\t\t\t\tend: async () => {},\n\t\t\t\t} as unknown as pg.Pool,\n\t\t\t}),\n\t\t}),\n\t\tasync rollback() {\n\t\t\ttry {\n\t\t\t\tawait client.query('ROLLBACK');\n\t\t\t} finally {\n\t\t\t\tawait client.end();\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * The client, with transaction control turned into savepoints.\n *\n * Kysely issues `begin`/`commit`/`rollback` as plain statements; this is the\n * one place they can be caught. A depth counter names the savepoints, so\n * nested transactions nest.\n */\nfunction savepointing(client: pg.Client): pg.PoolClient {\n\tlet depth = 0;\n\tconst query = client.query.bind(client) as (...args: unknown[]) => unknown;\n\n\tconst wrapped = Object.create(client) as pg.PoolClient;\n\tObject.assign(wrapped, {\n\t\tquery: (text: unknown, ...rest: unknown[]) => {\n\t\t\tconst statement =\n\t\t\t\ttypeof text === 'string' ? text.trim().toLowerCase() : undefined;\n\n\t\t\tif (statement === 'begin' || statement?.startsWith('start transaction')) {\n\t\t\t\tdepth++;\n\t\t\t\treturn query(`SAVEPOINT test_sp_${depth}`);\n\t\t\t}\n\t\t\tif (statement === 'commit') {\n\t\t\t\treturn query(`RELEASE SAVEPOINT test_sp_${depth--}`);\n\t\t\t}\n\t\t\tif (statement === 'rollback') {\n\t\t\t\treturn query(`ROLLBACK TO SAVEPOINT test_sp_${depth--}`);\n\t\t\t}\n\t\t\treturn query(text, ...rest);\n\t\t},\n\t\trelease: () => {},\n\t});\n\treturn wrapped;\n}\n\n/**\n * The transactions one test has opened, by database.\n *\n * `get` opens a database's transaction the first time it is asked for and\n * hands back the same one after that — including to a caller that asks while\n * it is still opening. `rollbackAll` ends every one of them.\n */\nexport class TransactionRegistry<TKey = string> {\n\tprivate readonly open = new Map<TKey, Promise<BoundTransaction>>();\n\n\tget(\n\t\tkey: TKey,\n\t\turl: string,\n\t\tconfig?: Omit<KyselyConfig, 'dialect'>,\n\t): Promise<Kysely<any>> {\n\t\tlet transaction = this.open.get(key);\n\t\tif (!transaction) {\n\t\t\ttransaction = openBoundTransaction(url, config);\n\t\t\tthis.open.set(key, transaction);\n\t\t}\n\t\treturn transaction.then(({ db }) => db);\n\t}\n\n\tasync rollbackAll(): Promise<void> {\n\t\tconst transactions = [...this.open.values()];\n\t\tthis.open.clear();\n\n\t\tconst results = await Promise.allSettled(\n\t\t\ttransactions.map(async (transaction) => (await transaction).rollback()),\n\t\t);\n\t\tconst failed = results.find(\n\t\t\t(result): result is PromiseRejectedResult => result.status === 'rejected',\n\t\t);\n\t\tif (failed) throw failed.reason;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,iBAAiB,KAA+B;CAC/D,MAAM,SAAS,IAAI,IAAI,GAAG;CAC1B,MAAM,aAAa,OAAO,aAAa,IAAI,aAAa;CACxD,IAAI,CAAC,YAAY,OAAO,EAAE,kBAAkB,IAAI;CAEhD,OAAO,aAAa,OAAO,aAAa;CACxC,OAAO;EACN,kBAAkB,OAAO,SAAS;EAClC,SAAS,kBAAkB;CAC5B;AACD;;;;;;;;AAiBA,eAAsB,qBACrB,KACA,SAAwC,CAAC,GACb;CAC5B,MAAM,SAAS,IAAI,GAAG,OAAO,iBAAiB,GAAG,CAAC;CAClD,MAAM,OAAO,QAAQ;CACrB,MAAM,OAAO,MAAM,OAAO;CAE1B,OAAO;EACN,IAAI,IAAI,OAAO;GACd,GAAG;GACH,SAAS,IAAI,gBAAgB,EAG5B,MAAM;IACL,SAAS,YAAY,aAAa,MAAM;IACxC,KAAK,YAAY,CAAC;GACnB,EACD,CAAC;EACF,CAAC;EACD,MAAM,WAAW;GAChB,IAAI;IACH,MAAM,OAAO,MAAM,UAAU;GAC9B,UAAU;IACT,MAAM,OAAO,IAAI;GAClB;EACD;CACD;AACD;;;;;;;;AASA,SAAS,aAAa,QAAkC;CACvD,IAAI,QAAQ;CACZ,MAAM,QAAQ,OAAO,MAAM,KAAK,MAAM;CAEtC,MAAM,UAAU,OAAO,OAAO,MAAM;CACpC,OAAO,OAAO,SAAS;EACtB,QAAQ,MAAe,GAAG,SAAoB;GAC7C,MAAM,YACL,OAAO,SAAS,WAAW,KAAK,KAAK,CAAC,CAAC,YAAY,IAAI,KAAA;GAExD,IAAI,cAAc,WAAW,WAAW,WAAW,mBAAmB,GAAG;IACxE;IACA,OAAO,MAAM,qBAAqB,OAAO;GAC1C;GACA,IAAI,cAAc,UACjB,OAAO,MAAM,6BAA6B,SAAS;GAEpD,IAAI,cAAc,YACjB,OAAO,MAAM,iCAAiC,SAAS;GAExD,OAAO,MAAM,MAAM,GAAG,IAAI;EAC3B;EACA,eAAe,CAAC;CACjB,CAAC;CACD,OAAO;AACR;;;;;;;;AASA,IAAa,sBAAb,MAAgD;CAC/C,uBAAwB,IAAI,IAAqC;CAEjE,IACC,KACA,KACA,QACuB;EACvB,IAAI,cAAc,KAAK,KAAK,IAAI,GAAG;EACnC,IAAI,CAAC,aAAa;GACjB,cAAc,qBAAqB,KAAK,MAAM;GAC9C,KAAK,KAAK,IAAI,KAAK,WAAW;EAC/B;EACA,OAAO,YAAY,MAAM,EAAE,SAAS,EAAE;CACvC;CAEA,MAAM,cAA6B;EAClC,MAAM,eAAe,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC;EAC3C,KAAK,KAAK,MAAM;EAKhB,MAAM,UAAS,MAHO,QAAQ,WAC7B,aAAa,IAAI,OAAO,iBAAiB,MAAM,YAAA,CAAa,SAAS,CAAC,CACvE,EAAA,CACuB,MACrB,WAA4C,OAAO,WAAW,UAChE;EACA,IAAI,QAAQ,MAAM,OAAO;CAC1B;AACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/testkit",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.40",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -113,6 +113,46 @@
|
|
|
113
113
|
"types": "./dist/requestContext.d.cts",
|
|
114
114
|
"default": "./dist/requestContext.cjs"
|
|
115
115
|
}
|
|
116
|
+
},
|
|
117
|
+
"./browser": {
|
|
118
|
+
"import": {
|
|
119
|
+
"types": "./dist/browser.d.mts",
|
|
120
|
+
"default": "./dist/browser.mjs"
|
|
121
|
+
},
|
|
122
|
+
"require": {
|
|
123
|
+
"types": "./dist/browser.d.cts",
|
|
124
|
+
"default": "./dist/browser.cjs"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"./context": {
|
|
128
|
+
"import": {
|
|
129
|
+
"types": "./dist/context.d.mts",
|
|
130
|
+
"default": "./dist/context.mjs"
|
|
131
|
+
},
|
|
132
|
+
"require": {
|
|
133
|
+
"types": "./dist/context.d.cts",
|
|
134
|
+
"default": "./dist/context.cjs"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"./mailbox": {
|
|
138
|
+
"import": {
|
|
139
|
+
"types": "./dist/mailbox.d.mts",
|
|
140
|
+
"default": "./dist/mailbox.mjs"
|
|
141
|
+
},
|
|
142
|
+
"require": {
|
|
143
|
+
"types": "./dist/mailbox.d.cts",
|
|
144
|
+
"default": "./dist/mailbox.cjs"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"./transactions": {
|
|
148
|
+
"import": {
|
|
149
|
+
"types": "./dist/transactions.d.mts",
|
|
150
|
+
"default": "./dist/transactions.mjs"
|
|
151
|
+
},
|
|
152
|
+
"require": {
|
|
153
|
+
"types": "./dist/transactions.d.cts",
|
|
154
|
+
"default": "./dist/transactions.cjs"
|
|
155
|
+
}
|
|
116
156
|
}
|
|
117
157
|
},
|
|
118
158
|
"files": [
|
|
@@ -120,15 +160,18 @@
|
|
|
120
160
|
],
|
|
121
161
|
"dependencies": {
|
|
122
162
|
"@faker-js/faker": "~10.6.0",
|
|
123
|
-
"
|
|
124
|
-
"@geekmidas/
|
|
125
|
-
"@geekmidas/logger": "^10.0.0-alpha.
|
|
163
|
+
"tough-cookie": "~6.0.2",
|
|
164
|
+
"@geekmidas/envkit": "^10.0.0-alpha.40",
|
|
165
|
+
"@geekmidas/logger": "^10.0.0-alpha.40",
|
|
166
|
+
"@geekmidas/services": "^10.0.0-alpha.40"
|
|
126
167
|
},
|
|
127
168
|
"devDependencies": {
|
|
169
|
+
"@better-auth/test-utils": "~1.7.6",
|
|
128
170
|
"@types/pg": "~8.23.1",
|
|
129
|
-
"
|
|
130
|
-
"@geekmidas/
|
|
131
|
-
"@geekmidas/
|
|
171
|
+
"better-auth": "~1.7.6",
|
|
172
|
+
"@geekmidas/envkit": "^10.0.0-alpha.40",
|
|
173
|
+
"@geekmidas/logger": "^10.0.0-alpha.40",
|
|
174
|
+
"@geekmidas/services": "^10.0.0-alpha.40"
|
|
132
175
|
},
|
|
133
176
|
"repository": {
|
|
134
177
|
"type": "git",
|
|
@@ -144,7 +187,7 @@
|
|
|
144
187
|
"knex": ">=3.3.0",
|
|
145
188
|
"objection": ">=3.1.5",
|
|
146
189
|
"db-errors": "~0.2.3",
|
|
147
|
-
"vitest": "~
|
|
190
|
+
"vitest": "~5.0.2",
|
|
148
191
|
"@types/aws-lambda": ">=8.10.163",
|
|
149
192
|
"better-auth": ">=1.7.5"
|
|
150
193
|
},
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-DvxiCtxc.cjs";
|
|
2
|
-
|
|
3
|
-
//#region src/Factory.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Abstract base class for database factories used in testing.
|
|
7
|
-
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
8
|
-
*
|
|
9
|
-
* @template Builders - Record of builder functions for creating individual entities
|
|
10
|
-
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* // Define builders for creating individual records
|
|
15
|
-
* const builders = {
|
|
16
|
-
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
17
|
-
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
18
|
-
* };
|
|
19
|
-
*
|
|
20
|
-
* // Define seeds for complex scenarios
|
|
21
|
-
* const seeds = {
|
|
22
|
-
* userWithPosts: async (attrs, factory) => {
|
|
23
|
-
* const user = await factory.insert('user', attrs);
|
|
24
|
-
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
25
|
-
* return user;
|
|
26
|
-
* }
|
|
27
|
-
* };
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
declare abstract class Factory<Builders extends Record<string, any>, Seeds extends Record<string, any>> {
|
|
31
|
-
/**
|
|
32
|
-
* Creates a typed seed function with proper type inference.
|
|
33
|
-
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
34
|
-
*
|
|
35
|
-
* @template Seed - The seed function type
|
|
36
|
-
* @param seedFn - The seed function to wrap
|
|
37
|
-
* @returns The same seed function with proper typing
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
42
|
-
* const user = await factory.insert('user', attrs);
|
|
43
|
-
* return user;
|
|
44
|
-
* });
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
48
|
-
/**
|
|
49
|
-
* Inserts an object into the database using a builder function.
|
|
50
|
-
*
|
|
51
|
-
* @param builderName - The name of the builder to use
|
|
52
|
-
* @param attrs - The attributes to insert
|
|
53
|
-
*/
|
|
54
|
-
abstract insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
55
|
-
/**
|
|
56
|
-
* Inserts multiple objects into the database
|
|
57
|
-
*
|
|
58
|
-
* @param count - Number of objects to insert
|
|
59
|
-
* @param builderName - The name of the builder to use
|
|
60
|
-
* @param attrs - The attributes to insert
|
|
61
|
-
*/
|
|
62
|
-
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]>>[]>;
|
|
63
|
-
/**
|
|
64
|
-
* Seeds the database using a seed function.
|
|
65
|
-
*
|
|
66
|
-
* @param seedName - The name of the seed to use
|
|
67
|
-
* @returns The result of the seed function
|
|
68
|
-
* @param attrs - The attributes to pass to the seed function
|
|
69
|
-
*/
|
|
70
|
-
abstract seed<K extends keyof Seeds>(seedName: K, attrs?: ExtractSeedAttrs<Seeds[K]>): ReturnType<Seeds[K]>;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Type definition for a factory builder function that can work with different database types.
|
|
74
|
-
* Builders are responsible for creating individual database records with default values and relationships.
|
|
75
|
-
*
|
|
76
|
-
* @template Attrs - The attributes/input type for the builder
|
|
77
|
-
* @template Factory - The factory instance type
|
|
78
|
-
* @template Result - The type of object returned by the builder
|
|
79
|
-
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
80
|
-
*
|
|
81
|
-
* @param attrs - Partial attributes to override defaults
|
|
82
|
-
* @param factory - The factory instance for creating related records
|
|
83
|
-
* @param db - The database connection
|
|
84
|
-
* @returns The created record or a promise resolving to it
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =
|
|
89
|
-
* async (attrs, factory, db) => {
|
|
90
|
-
* return {
|
|
91
|
-
* id: faker.string.uuid(),
|
|
92
|
-
* name: faker.person.fullName(),
|
|
93
|
-
* email: faker.internet.email(),
|
|
94
|
-
* ...attrs
|
|
95
|
-
* };
|
|
96
|
-
* };
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
type MixedFactoryBuilder<Attrs = any, Factory = any, Result = any, DB = any> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;
|
|
100
|
-
/**
|
|
101
|
-
* Type definition for a factory seed function used to create complex test scenarios.
|
|
102
|
-
* Seeds typically create multiple related records to set up a complete test environment.
|
|
103
|
-
*
|
|
104
|
-
* @template Attrs - The attributes/input type for the seed
|
|
105
|
-
* @template Factory - The factory instance type
|
|
106
|
-
* @template Result - The type of object returned by the seed
|
|
107
|
-
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
108
|
-
*
|
|
109
|
-
* @param context - Object containing attrs, factory, and db
|
|
110
|
-
* @param context.attrs - Configuration attributes for the seed
|
|
111
|
-
* @param context.factory - The factory instance for creating records
|
|
112
|
-
* @param context.db - The database connection
|
|
113
|
-
* @returns A promise resolving to the seed result
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =
|
|
118
|
-
* async ({ attrs, factory, db }) => {
|
|
119
|
-
* const user = await factory.insert('user', attrs);
|
|
120
|
-
* const postCount = attrs.postCount || 3;
|
|
121
|
-
*
|
|
122
|
-
* for (let i = 0; i < postCount; i++) {
|
|
123
|
-
* await factory.insert('post', { userId: user.id });
|
|
124
|
-
* }
|
|
125
|
-
*
|
|
126
|
-
* return user;
|
|
127
|
-
* };
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
type FactorySeed<Attrs = any, Factory = any, Result = any, DB = any> = (context: {
|
|
131
|
-
attrs: Attrs;
|
|
132
|
-
factory: Factory;
|
|
133
|
-
db: DB;
|
|
134
|
-
}) => Promise<Result>;
|
|
135
|
-
/**
|
|
136
|
-
* Helper type to extract the Attrs type from a FactorySeed function.
|
|
137
|
-
* Used internally by Factory implementations to correctly type the seed method parameters.
|
|
138
|
-
*/
|
|
139
|
-
type ExtractSeedAttrs<T> = T extends ((context: {
|
|
140
|
-
attrs: infer A;
|
|
141
|
-
factory: any;
|
|
142
|
-
db: any;
|
|
143
|
-
}) => any) ? A : never;
|
|
144
|
-
//# sourceMappingURL=Factory.d.ts.map
|
|
145
|
-
//#endregion
|
|
146
|
-
export { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder };
|
|
147
|
-
//# sourceMappingURL=Factory-AWn1IulI.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Factory-AWn1IulI.d.cts","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,51 +0,0 @@
|
|
|
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
|
-
|
|
49
|
-
//#endregion
|
|
50
|
-
export { Factory };
|
|
51
|
-
//# sourceMappingURL=Factory-BFVnMMCC.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Factory-BFVnMMCC.mjs","names":["seedFn: Seed"],"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,WAAqCA,QAAoB;AAC/D,SAAO;CACP;AAyCD"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
Object.defineProperty(exports, 'Factory', {
|
|
52
|
-
enumerable: true,
|
|
53
|
-
get: function () {
|
|
54
|
-
return Factory;
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
//# sourceMappingURL=Factory-BhjUOBWN.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Factory-BhjUOBWN.cjs","names":["seedFn: Seed"],"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,WAAqCA,QAAoB;AAC/D,SAAO;CACP;AAyCD"}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-B6bmbGCM.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/Factory.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Abstract base class for database factories used in testing.
|
|
7
|
-
* Provides a standardized interface for creating test data using builder and seed patterns.
|
|
8
|
-
*
|
|
9
|
-
* @template Builders - Record of builder functions for creating individual entities
|
|
10
|
-
* @template Seeds - Record of seed functions for creating complex test scenarios
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* // Define builders for creating individual records
|
|
15
|
-
* const builders = {
|
|
16
|
-
* user: (attrs) => ({ name: 'Test User', email: 'test@example.com', ...attrs }),
|
|
17
|
-
* post: (attrs) => ({ title: 'Test Post', content: 'Content', ...attrs })
|
|
18
|
-
* };
|
|
19
|
-
*
|
|
20
|
-
* // Define seeds for complex scenarios
|
|
21
|
-
* const seeds = {
|
|
22
|
-
* userWithPosts: async (attrs, factory) => {
|
|
23
|
-
* const user = await factory.insert('user', attrs);
|
|
24
|
-
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
25
|
-
* return user;
|
|
26
|
-
* }
|
|
27
|
-
* };
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
declare abstract class Factory<Builders extends Record<string, any>, Seeds extends Record<string, any>> {
|
|
31
|
-
/**
|
|
32
|
-
* Creates a typed seed function with proper type inference.
|
|
33
|
-
* This is a utility method to help with TypeScript type checking when defining seeds.
|
|
34
|
-
*
|
|
35
|
-
* @template Seed - The seed function type
|
|
36
|
-
* @param seedFn - The seed function to wrap
|
|
37
|
-
* @returns The same seed function with proper typing
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
42
|
-
* const user = await factory.insert('user', attrs);
|
|
43
|
-
* return user;
|
|
44
|
-
* });
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
48
|
-
/**
|
|
49
|
-
* Inserts an object into the database using a builder function.
|
|
50
|
-
*
|
|
51
|
-
* @param builderName - The name of the builder to use
|
|
52
|
-
* @param attrs - The attributes to insert
|
|
53
|
-
*/
|
|
54
|
-
abstract insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
55
|
-
/**
|
|
56
|
-
* Inserts multiple objects into the database
|
|
57
|
-
*
|
|
58
|
-
* @param count - Number of objects to insert
|
|
59
|
-
* @param builderName - The name of the builder to use
|
|
60
|
-
* @param attrs - The attributes to insert
|
|
61
|
-
*/
|
|
62
|
-
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]>>[]>;
|
|
63
|
-
/**
|
|
64
|
-
* Seeds the database using a seed function.
|
|
65
|
-
*
|
|
66
|
-
* @param seedName - The name of the seed to use
|
|
67
|
-
* @returns The result of the seed function
|
|
68
|
-
* @param attrs - The attributes to pass to the seed function
|
|
69
|
-
*/
|
|
70
|
-
abstract seed<K extends keyof Seeds>(seedName: K, attrs?: ExtractSeedAttrs<Seeds[K]>): ReturnType<Seeds[K]>;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Type definition for a factory builder function that can work with different database types.
|
|
74
|
-
* Builders are responsible for creating individual database records with default values and relationships.
|
|
75
|
-
*
|
|
76
|
-
* @template Attrs - The attributes/input type for the builder
|
|
77
|
-
* @template Factory - The factory instance type
|
|
78
|
-
* @template Result - The type of object returned by the builder
|
|
79
|
-
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
80
|
-
*
|
|
81
|
-
* @param attrs - Partial attributes to override defaults
|
|
82
|
-
* @param factory - The factory instance for creating related records
|
|
83
|
-
* @param db - The database connection
|
|
84
|
-
* @returns The created record or a promise resolving to it
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* const userBuilder: MixedFactoryBuilder<UserAttrs, Factory, User, Kysely<DB>> =
|
|
89
|
-
* async (attrs, factory, db) => {
|
|
90
|
-
* return {
|
|
91
|
-
* id: faker.string.uuid(),
|
|
92
|
-
* name: faker.person.fullName(),
|
|
93
|
-
* email: faker.internet.email(),
|
|
94
|
-
* ...attrs
|
|
95
|
-
* };
|
|
96
|
-
* };
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
type MixedFactoryBuilder<Attrs = any, Factory = any, Result = any, DB = any> = (attrs: Attrs, factory: Factory, db: DB) => Result | Promise<Result>;
|
|
100
|
-
/**
|
|
101
|
-
* Type definition for a factory seed function used to create complex test scenarios.
|
|
102
|
-
* Seeds typically create multiple related records to set up a complete test environment.
|
|
103
|
-
*
|
|
104
|
-
* @template Attrs - The attributes/input type for the seed
|
|
105
|
-
* @template Factory - The factory instance type
|
|
106
|
-
* @template Result - The type of object returned by the seed
|
|
107
|
-
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
108
|
-
*
|
|
109
|
-
* @param context - Object containing attrs, factory, and db
|
|
110
|
-
* @param context.attrs - Configuration attributes for the seed
|
|
111
|
-
* @param context.factory - The factory instance for creating records
|
|
112
|
-
* @param context.db - The database connection
|
|
113
|
-
* @returns A promise resolving to the seed result
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =
|
|
118
|
-
* async ({ attrs, factory, db }) => {
|
|
119
|
-
* const user = await factory.insert('user', attrs);
|
|
120
|
-
* const postCount = attrs.postCount || 3;
|
|
121
|
-
*
|
|
122
|
-
* for (let i = 0; i < postCount; i++) {
|
|
123
|
-
* await factory.insert('post', { userId: user.id });
|
|
124
|
-
* }
|
|
125
|
-
*
|
|
126
|
-
* return user;
|
|
127
|
-
* };
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
type FactorySeed<Attrs = any, Factory = any, Result = any, DB = any> = (context: {
|
|
131
|
-
attrs: Attrs;
|
|
132
|
-
factory: Factory;
|
|
133
|
-
db: DB;
|
|
134
|
-
}) => Promise<Result>;
|
|
135
|
-
/**
|
|
136
|
-
* Helper type to extract the Attrs type from a FactorySeed function.
|
|
137
|
-
* Used internally by Factory implementations to correctly type the seed method parameters.
|
|
138
|
-
*/
|
|
139
|
-
type ExtractSeedAttrs<T> = T extends ((context: {
|
|
140
|
-
attrs: infer A;
|
|
141
|
-
factory: any;
|
|
142
|
-
db: any;
|
|
143
|
-
}) => any) ? A : never;
|
|
144
|
-
//# sourceMappingURL=Factory.d.ts.map
|
|
145
|
-
//#endregion
|
|
146
|
-
export { ExtractSeedAttrs, Factory, FactorySeed, MixedFactoryBuilder };
|
|
147
|
-
//# sourceMappingURL=Factory-C15SSK8_.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Factory-C15SSK8_.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"}
|