@fragno-dev/test 0.1.8 → 0.1.10

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @fragno-dev/test@0.1.8 build /home/runner/work/fragno/fragno/packages/fragno-test
2
+ > @fragno-dev/test@0.1.10 build /home/runner/work/fragno/fragno/packages/fragno-test
3
3
  > tsdown
4
4
 
5
5
  ℹ tsdown v0.15.12 powered by rolldown v1.0.0-beta.45
@@ -7,13 +7,13 @@
7
7
  ℹ entry: src/index.ts
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
- ℹ dist/index.js  2.55 kB │ gzip: 0.80 kB
11
- ℹ dist/adapters.js.map 15.32 kB │ gzip: 3.52 kB
12
- ℹ dist/index.js.map  8.80 kB │ gzip: 2.50 kB
13
- ℹ dist/adapters.js  6.36 kB │ gzip: 1.52 kB
14
- ℹ dist/index.d.ts.map  1.60 kB │ gzip: 0.76 kB
15
- ℹ dist/adapters.d.ts.map  0.85 kB │ gzip: 0.40 kB
16
- ℹ dist/index.d.ts  2.98 kB │ gzip: 0.82 kB
17
- ℹ dist/adapters.d.ts  1.16 kB │ gzip: 0.40 kB
18
- ℹ 8 files, total: 39.61 kB
19
- ✔ Build complete in 22907ms
10
+ ℹ dist/index.js  2.64 kB │ gzip: 0.81 kB
11
+ ℹ dist/adapters.js.map 16.62 kB │ gzip: 3.63 kB
12
+ ℹ dist/index.js.map  9.54 kB │ gzip: 2.63 kB
13
+ ℹ dist/adapters.js  6.74 kB │ gzip: 1.54 kB
14
+ ℹ dist/index.d.ts.map  1.72 kB │ gzip: 0.78 kB
15
+ ℹ dist/adapters.d.ts.map  0.93 kB │ gzip: 0.42 kB
16
+ ℹ dist/index.d.ts  3.34 kB │ gzip: 0.93 kB
17
+ ℹ dist/adapters.d.ts  1.28 kB │ gzip: 0.42 kB
18
+ ℹ 8 files, total: 42.80 kB
19
+ ✔ Build complete in 13034ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # @fragno-dev/test
2
2
 
3
+ ## 0.1.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [b54ff8b]
8
+ - @fragno-dev/db@0.1.13
9
+
10
+ ## 0.1.9
11
+
12
+ ### Patch Changes
13
+
14
+ - be1a630: **BREAKING**: `callRoute` now returns type-safe `FragnoResponse<T>` instead of raw
15
+ `Response`
16
+
17
+ The `callRoute` method on fragment instances now returns a parsed `FragnoResponse<T>`
18
+ discriminated union instead of a raw `Response`. This provides type-safe access to response data
19
+ without manual JSON parsing.
20
+
21
+ **Migration:**
22
+
23
+ Preferably use the new type-safe response:
24
+
25
+ ```diff
26
+ - const response = await fragment.callRoute("GET", "/users");
27
+ - const data = await response.json();
28
+ + const response = await fragment.callRoute("GET", "/users");
29
+ + if (response.type === "json") {
30
+ + const data = response.data; // fully typed!
31
+ + }
32
+ ```
33
+
34
+ - or -
35
+
36
+ Switch to `callRouteRaw` if you need the raw response:
37
+
38
+ ```diff
39
+ - const response = await fragment.callRoute("GET", "/users");
40
+ + const response = await fragment.callRouteRaw("GET", "/users");
41
+ ```
42
+
43
+ - e99ef47: feat: expose `db` object to run queries directly in tests
44
+ - Updated dependencies [be1a630]
45
+ - Updated dependencies [b2a88aa]
46
+ - Updated dependencies [2900bfa]
47
+ - Updated dependencies [059a249]
48
+ - Updated dependencies [f3f7bc2]
49
+ - Updated dependencies [a9f8159]
50
+ - Updated dependencies [9d4cd3a]
51
+ - Updated dependencies [fdb5aaf]
52
+ - @fragno-dev/core@0.1.6
53
+ - @fragno-dev/db@0.1.12
54
+
3
55
  ## 0.1.8
4
56
 
5
57
  ### Patch Changes
@@ -2,6 +2,7 @@ import { Kysely } from "kysely";
2
2
  import { drizzle } from "drizzle-orm/pglite";
3
3
  import { AnySchema } from "@fragno-dev/db/schema";
4
4
  import { DatabaseAdapter } from "@fragno-dev/db/adapters";
5
+ import { AbstractQuery } from "@fragno-dev/db/query";
5
6
 
6
7
  //#region src/adapters.d.ts
7
8
  interface KyselySqliteAdapter {
@@ -17,11 +18,13 @@ interface DrizzlePgliteAdapter {
17
18
  }
18
19
  type SupportedAdapter = KyselySqliteAdapter | KyselyPgliteAdapter | DrizzlePgliteAdapter;
19
20
  type TestContext<T extends SupportedAdapter> = T extends KyselySqliteAdapter | KyselyPgliteAdapter ? {
21
+ readonly db: AbstractQuery<any>;
20
22
  readonly kysely: Kysely<any>;
21
23
  readonly adapter: DatabaseAdapter<any>;
22
24
  resetDatabase: () => Promise<void>;
23
25
  cleanup: () => Promise<void>;
24
26
  } : T extends DrizzlePgliteAdapter ? {
27
+ readonly db: AbstractQuery<any>;
25
28
  readonly drizzle: ReturnType<typeof drizzle<any>>;
26
29
  readonly adapter: DatabaseAdapter<any>;
27
30
  resetDatabase: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.d.ts","names":[],"sources":["../src/adapters.ts"],"sourcesContent":[],"mappings":";;;;;;UAeiB,mBAAA;;AAAjB;AAIiB,UAAA,mBAAA,CAAmB;EAKnB,IAAA,EAAA,eAAA;EAKL,YAAA,CAAA,EAAA,MAAgB;;AAAyB,UALpC,oBAAA,CAKoC;EAAsB,IAAA,EAAA,gBAAA;EAAoB,YAAA,CAAA,EAAA,MAAA;AAG/F;AAAkC,KAHtB,gBAAA,GAAmB,mBAGG,GAHmB,mBAGnB,GAHyC,oBAGzC;AAAoB,KAA1C,WAA0C,CAAA,UAApB,gBAAoB,CAAA,GAAA,CAAA,SAClD,mBADkD,GAElD,mBAFkD,GAAA;EAClD,SAAA,MAAA,EAGmB,MAHnB,CAAA,GAAA,CAAA;EACA,SAAA,OAAA,EAGoB,eAHpB,CAAA,GAAA,CAAA;EAEmB,aAAA,EAAA,GAAA,GAEI,OAFJ,CAAA,IAAA,CAAA;EACC,OAAA,EAAA,GAAA,GAEH,OAFG,CAAA,IAAA,CAAA;CACG,GAGvB,CAHuB,SAGb,oBAHa,GAAA;EACN,SAAA,OAAA,EAIK,UAJL,CAAA,OAIuB,OAJvB,CAAA,GAAA,CAAA,CAAA;EAEjB,SAAA,OAAA,EAGsB,eAHtB,CAAA,GAAA,CAAA;EAAU,aAAA,EAAA,GAAA,GAIe,OAJf,CAAA,IAAA,CAAA;EAE8B,OAAA,EAAA,GAAA,GAGrB,OAHqB,CAAA,IAAA,CAAA;CAAlB,GAAA,KAAA"}
1
+ {"version":3,"file":"adapters.d.ts","names":[],"sources":["../src/adapters.ts"],"sourcesContent":[],"mappings":";;;;;;;UAgBiB,mBAAA;;AAAjB;AAIiB,UAAA,mBAAA,CAAmB;EAKnB,IAAA,EAAA,eAAA;EAKL,YAAA,CAAA,EAAA,MAAgB;;AAAyB,UALpC,oBAAA,CAKoC;EAAsB,IAAA,EAAA,gBAAA;EAAoB,YAAA,CAAA,EAAA,MAAA;AAG/F;AAAkC,KAHtB,gBAAA,GAAmB,mBAGG,GAHmB,mBAGnB,GAHyC,oBAGzC;AAAoB,KAA1C,WAA0C,CAAA,UAApB,gBAAoB,CAAA,GAAA,CAAA,SAClD,mBADkD,GAElD,mBAFkD,GAAA;EAClD,SAAA,EAAA,EAGe,aAHf,CAAA,GAAA,CAAA;EACA,SAAA,MAAA,EAGmB,MAHnB,CAAA,GAAA,CAAA;EAEe,SAAA,OAAA,EAEK,eAFL,CAAA,GAAA,CAAA;EACI,aAAA,EAAA,GAAA,GAEI,OAFJ,CAAA,IAAA,CAAA;EACC,OAAA,EAAA,GAAA,GAEH,OAFG,CAAA,IAAA,CAAA;CACG,GAGvB,CAHuB,SAGb,oBAHa,GAAA;EACN,SAAA,EAAA,EAIA,aAJA,CAAA,GAAA,CAAA;EAEjB,SAAA,OAAA,EAGsB,UAHtB,CAAA,OAGwC,OAHxC,CAAA,GAAA,CAAA,CAAA;EAAU,SAAA,OAAA,EAIY,eAJZ,CAAA,GAAA,CAAA;EAEO,aAAA,EAAA,GAAA,GAGQ,OAHR,CAAA,IAAA,CAAA;EACuB,OAAA,EAAA,GAAA,GAGrB,OAHqB,CAAA,IAAA,CAAA;CAAlB,GAAA,KAAA"}
package/dist/adapters.js CHANGED
@@ -26,21 +26,26 @@ async function createKyselySqliteAdapter(_config, schema, namespace, migrateToVe
26
26
  await (migrateToVersion ? await migrator.prepareMigrationTo(migrateToVersion, { updateSettings: false }) : await migrator.prepareMigration({ updateSettings: false })).execute();
27
27
  return {
28
28
  kysely: kysely$1,
29
- adapter: adapter$1
29
+ adapter: adapter$1,
30
+ orm: adapter$1.createQueryEngine(schema, namespace)
30
31
  };
31
32
  };
32
- let { kysely, adapter } = await createDatabase();
33
+ let { kysely, adapter, orm } = await createDatabase();
33
34
  const resetDatabase = async () => {
34
35
  await kysely.destroy();
35
36
  const newDb = await createDatabase();
36
37
  kysely = newDb.kysely;
37
38
  adapter = newDb.adapter;
39
+ orm = newDb.orm;
38
40
  };
39
41
  const cleanup = async () => {
40
42
  await kysely.destroy();
41
43
  };
42
44
  return {
43
45
  testContext: {
46
+ get db() {
47
+ return orm;
48
+ },
44
49
  get kysely() {
45
50
  return kysely;
46
51
  },
@@ -72,10 +77,11 @@ async function createKyselyPgliteAdapter(config, schema, namespace, migrateToVer
72
77
  return {
73
78
  kysely: kysely$1,
74
79
  adapter: adapter$1,
75
- kyselyPglite: kyselyPglite$1
80
+ kyselyPglite: kyselyPglite$1,
81
+ orm: adapter$1.createQueryEngine(schema, namespace)
76
82
  };
77
83
  };
78
- let { kysely, adapter, kyselyPglite } = await createDatabase();
84
+ let { kysely, adapter, kyselyPglite, orm } = await createDatabase();
79
85
  const resetDatabase = async () => {
80
86
  await kysely.destroy();
81
87
  try {
@@ -85,6 +91,7 @@ async function createKyselyPgliteAdapter(config, schema, namespace, migrateToVer
85
91
  kysely = newDb.kysely;
86
92
  adapter = newDb.adapter;
87
93
  kyselyPglite = newDb.kyselyPglite;
94
+ orm = newDb.orm;
88
95
  };
89
96
  const cleanup = async () => {
90
97
  await kysely.destroy();
@@ -98,6 +105,9 @@ async function createKyselyPgliteAdapter(config, schema, namespace, migrateToVer
98
105
  };
99
106
  return {
100
107
  testContext: {
108
+ get db() {
109
+ return orm;
110
+ },
101
111
  get kysely() {
102
112
  return kysely;
103
113
  },
@@ -145,17 +155,19 @@ async function createDrizzlePgliteAdapter(config, schema, namespace, _migrateToV
145
155
  const db = drizzle(pglite$1, { schema: schemaModule });
146
156
  const migrationStatements = await generateMigration(generateDrizzleJson({}), generateDrizzleJson(schemaModule));
147
157
  for (const statement of migrationStatements) await db.execute(statement);
158
+ const adapter$1 = new DrizzleAdapter({
159
+ db: () => db,
160
+ provider: "postgresql"
161
+ });
148
162
  return {
149
163
  drizzle: db,
150
- adapter: new DrizzleAdapter({
151
- db: () => db,
152
- provider: "postgresql"
153
- }),
164
+ adapter: adapter$1,
154
165
  pglite: pglite$1,
155
- cleanup: cleanup$1
166
+ cleanup: cleanup$1,
167
+ orm: adapter$1.createQueryEngine(schema, namespace)
156
168
  };
157
169
  };
158
- let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup } = await createDatabase();
170
+ let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup, orm } = await createDatabase();
159
171
  const resetDatabase = async () => {
160
172
  await pglite.close();
161
173
  await schemaCleanup();
@@ -164,6 +176,7 @@ async function createDrizzlePgliteAdapter(config, schema, namespace, _migrateToV
164
176
  adapter = newDb.adapter;
165
177
  pglite = newDb.pglite;
166
178
  schemaCleanup = newDb.cleanup;
179
+ orm = newDb.orm;
167
180
  };
168
181
  const cleanup = async () => {
169
182
  await pglite.close();
@@ -175,6 +188,9 @@ async function createDrizzlePgliteAdapter(config, schema, namespace, _migrateToV
175
188
  };
176
189
  return {
177
190
  testContext: {
191
+ get db() {
192
+ return orm;
193
+ },
178
194
  get drizzle() {
179
195
  return drizzleDb;
180
196
  },
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.js","names":["kysely","adapter","kyselyPglite","cleanup","pglite"],"sources":["../src/adapters.ts"],"sourcesContent":["import { Kysely } from \"kysely\";\nimport { SQLocalKysely } from \"sqlocal/kysely\";\nimport { KyselyPGlite } from \"kysely-pglite\";\nimport { drizzle } from \"drizzle-orm/pglite\";\nimport { PGlite } from \"@electric-sql/pglite\";\nimport { KyselyAdapter } from \"@fragno-dev/db/adapters/kysely\";\nimport { DrizzleAdapter } from \"@fragno-dev/db/adapters/drizzle\";\nimport type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db/adapters\";\nimport { createRequire } from \"node:module\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\n// Adapter configuration types\nexport interface KyselySqliteAdapter {\n type: \"kysely-sqlite\";\n}\n\nexport interface KyselyPgliteAdapter {\n type: \"kysely-pglite\";\n databasePath?: string;\n}\n\nexport interface DrizzlePgliteAdapter {\n type: \"drizzle-pglite\";\n databasePath?: string;\n}\n\nexport type SupportedAdapter = KyselySqliteAdapter | KyselyPgliteAdapter | DrizzlePgliteAdapter;\n\n// Conditional return types based on adapter\nexport type TestContext<T extends SupportedAdapter> = T extends\n | KyselySqliteAdapter\n | KyselyPgliteAdapter\n ? {\n readonly kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n }\n : T extends DrizzlePgliteAdapter\n ? {\n readonly drizzle: ReturnType<typeof drizzle<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n }\n : never;\n\n// Factory function return type\ninterface AdapterFactoryResult<T extends SupportedAdapter> {\n testContext: TestContext<T>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n adapter: DatabaseAdapter<any>;\n}\n\n/**\n * Create Kysely + SQLite adapter using SQLocalKysely (always in-memory)\n */\nexport async function createKyselySqliteAdapter(\n _config: KyselySqliteAdapter,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<KyselySqliteAdapter>> {\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Create SQLocalKysely instance (always in-memory for tests)\n const { dialect } = new SQLocalKysely(\":memory:\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kysely = new Kysely<any>({\n dialect,\n });\n\n // Create KyselyAdapter\n const adapter = new KyselyAdapter({\n db: kysely,\n provider: \"sqlite\",\n });\n\n // Run migrations\n const migrator = adapter.createMigrationEngine(schema, namespace);\n const preparedMigration = migrateToVersion\n ? await migrator.prepareMigrationTo(migrateToVersion, {\n updateSettings: false,\n })\n : await migrator.prepareMigration({\n updateSettings: false,\n });\n await preparedMigration.execute();\n\n return { kysely, adapter };\n };\n\n // Create initial database\n let { kysely, adapter } = await createDatabase();\n\n // Reset database function - creates a fresh in-memory database and re-runs migrations\n const resetDatabase = async () => {\n // Destroy the old Kysely instance\n await kysely.destroy();\n\n // Create a new database instance\n const newDb = await createDatabase();\n kysely = newDb.kysely;\n adapter = newDb.adapter;\n };\n\n // Cleanup function - closes connections (no files to delete for in-memory)\n const cleanup = async () => {\n await kysely.destroy();\n };\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create Kysely + PGLite adapter using kysely-pglite\n */\nexport async function createKyselyPgliteAdapter(\n config: KyselyPgliteAdapter,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<KyselyPgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Create KyselyPGlite instance\n const kyselyPglite = await KyselyPGlite.create(databasePath);\n\n // Create Kysely instance with PGlite dialect\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kysely = new Kysely<any>({\n dialect: kyselyPglite.dialect,\n });\n\n // Create KyselyAdapter\n const adapter = new KyselyAdapter({\n db: kysely,\n provider: \"postgresql\",\n });\n\n // Run migrations\n const migrator = adapter.createMigrationEngine(schema, namespace);\n const preparedMigration = migrateToVersion\n ? await migrator.prepareMigrationTo(migrateToVersion, {\n updateSettings: false,\n })\n : await migrator.prepareMigration({\n updateSettings: false,\n });\n await preparedMigration.execute();\n\n return { kysely, adapter, kyselyPglite };\n };\n\n // Create initial database\n let { kysely, adapter, kyselyPglite } = await createDatabase();\n\n // Reset database function - creates a fresh database and re-runs migrations\n const resetDatabase = async () => {\n // Close the old instances\n await kysely.destroy();\n\n try {\n await kyselyPglite.client.close();\n } catch {\n // Ignore if already closed\n }\n\n // Create a new database instance\n const newDb = await createDatabase();\n kysely = newDb.kysely;\n adapter = newDb.adapter;\n kyselyPglite = newDb.kyselyPglite;\n };\n\n // Cleanup function - closes connections and deletes database directory\n const cleanup = async () => {\n await kysely.destroy();\n\n try {\n await kyselyPglite.client.close();\n } catch {\n // Ignore if already closed\n }\n\n // Delete the database directory if it exists and is a file path\n if (databasePath && databasePath !== \":memory:\" && existsSync(databasePath)) {\n await rm(databasePath, { recursive: true, force: true });\n }\n };\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create Drizzle + PGLite adapter using drizzle-orm/pglite\n */\nexport async function createDrizzlePgliteAdapter(\n config: DrizzlePgliteAdapter,\n schema: AnySchema,\n namespace: string,\n _migrateToVersion?: number,\n): Promise<AdapterFactoryResult<DrizzlePgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Import drizzle-kit for migrations\n const require = createRequire(import.meta.url);\n const { generateDrizzleJson, generateMigration } =\n require(\"drizzle-kit/api\") as typeof import(\"drizzle-kit/api\");\n\n // Import generateSchema from the properly exported module\n const { generateSchema } = await import(\"@fragno-dev/db/adapters/drizzle/generate\");\n\n // Helper to write schema to file and dynamically import it\n const writeAndLoadSchema = async () => {\n const testDir = join(import.meta.dirname, \"_generated\", \"drizzle-test\");\n await mkdir(testDir, { recursive: true }).catch(() => {\n // Ignore error if directory already exists\n });\n\n const schemaFilePath = join(\n testDir,\n `test-schema-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.ts`,\n );\n\n // Generate and write the Drizzle schema to file\n const drizzleSchemaTs = generateSchema([{ namespace: namespace ?? \"\", schema }], \"postgresql\");\n await writeFile(schemaFilePath, drizzleSchemaTs, \"utf-8\");\n\n // Dynamically import the generated schema (with cache busting)\n const schemaModule = await import(`${schemaFilePath}?t=${Date.now()}`);\n\n const cleanup = async () => {\n await rm(testDir, { recursive: true, force: true });\n };\n\n return { schemaModule, cleanup };\n };\n\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Write schema to file and load it\n const { schemaModule, cleanup } = await writeAndLoadSchema();\n\n // Create PGlite instance\n const pglite = new PGlite(databasePath);\n\n // Create Drizzle instance with PGlite\n const db = drizzle(pglite, {\n schema: schemaModule,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any;\n\n // Generate and run migrations\n const migrationStatements = await generateMigration(\n generateDrizzleJson({}), // Empty schema (starting state)\n generateDrizzleJson(schemaModule), // Target schema\n );\n\n // Execute migration SQL\n for (const statement of migrationStatements) {\n await db.execute(statement);\n }\n\n // Create DrizzleAdapter\n const adapter = new DrizzleAdapter({\n db: () => db,\n provider: \"postgresql\",\n });\n\n return { drizzle: db, adapter, pglite, cleanup };\n };\n\n // Create initial database\n let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup } = await createDatabase();\n\n // Reset database function - creates a fresh database and re-runs migrations\n const resetDatabase = async () => {\n // Close the old instances and cleanup\n await pglite.close();\n await schemaCleanup();\n\n // Create a new database instance\n const newDb = await createDatabase();\n drizzleDb = newDb.drizzle;\n adapter = newDb.adapter;\n pglite = newDb.pglite;\n schemaCleanup = newDb.cleanup;\n };\n\n // Cleanup function - closes connections and deletes generated files and database directory\n const cleanup = async () => {\n await pglite.close();\n await schemaCleanup();\n\n // Delete the database directory if it exists and is a file path\n if (databasePath && databasePath !== \":memory:\" && existsSync(databasePath)) {\n await rm(databasePath, { recursive: true, force: true });\n }\n };\n\n return {\n testContext: {\n get drizzle() {\n return drizzleDb;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create adapter based on configuration\n */\nexport async function createAdapter<T extends SupportedAdapter>(\n adapterConfig: T,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<T>> {\n if (adapterConfig.type === \"kysely-sqlite\") {\n return createKyselySqliteAdapter(adapterConfig, schema, namespace, migrateToVersion) as Promise<\n AdapterFactoryResult<T>\n >;\n } else if (adapterConfig.type === \"kysely-pglite\") {\n return createKyselyPgliteAdapter(adapterConfig, schema, namespace, migrateToVersion) as Promise<\n AdapterFactoryResult<T>\n >;\n } else if (adapterConfig.type === \"drizzle-pglite\") {\n return createDrizzlePgliteAdapter(\n adapterConfig,\n schema,\n namespace,\n migrateToVersion,\n ) as Promise<AdapterFactoryResult<T>>;\n }\n\n throw new Error(`Unsupported adapter type: ${(adapterConfig as SupportedAdapter).type}`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"adapters.js","names":["kysely","adapter","kyselyPglite","cleanup","pglite"],"sources":["../src/adapters.ts"],"sourcesContent":["import { Kysely } from \"kysely\";\nimport { SQLocalKysely } from \"sqlocal/kysely\";\nimport { KyselyPGlite } from \"kysely-pglite\";\nimport { drizzle } from \"drizzle-orm/pglite\";\nimport { PGlite } from \"@electric-sql/pglite\";\nimport { KyselyAdapter } from \"@fragno-dev/db/adapters/kysely\";\nimport { DrizzleAdapter } from \"@fragno-dev/db/adapters/drizzle\";\nimport type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db/adapters\";\nimport type { AbstractQuery } from \"@fragno-dev/db/query\";\nimport { createRequire } from \"node:module\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\n// Adapter configuration types\nexport interface KyselySqliteAdapter {\n type: \"kysely-sqlite\";\n}\n\nexport interface KyselyPgliteAdapter {\n type: \"kysely-pglite\";\n databasePath?: string;\n}\n\nexport interface DrizzlePgliteAdapter {\n type: \"drizzle-pglite\";\n databasePath?: string;\n}\n\nexport type SupportedAdapter = KyselySqliteAdapter | KyselyPgliteAdapter | DrizzlePgliteAdapter;\n\n// Conditional return types based on adapter\nexport type TestContext<T extends SupportedAdapter> = T extends\n | KyselySqliteAdapter\n | KyselyPgliteAdapter\n ? {\n readonly db: AbstractQuery<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n }\n : T extends DrizzlePgliteAdapter\n ? {\n readonly db: AbstractQuery<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly drizzle: ReturnType<typeof drizzle<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n }\n : never;\n\n// Factory function return type\ninterface AdapterFactoryResult<T extends SupportedAdapter> {\n testContext: TestContext<T>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n adapter: DatabaseAdapter<any>;\n}\n\n/**\n * Create Kysely + SQLite adapter using SQLocalKysely (always in-memory)\n */\nexport async function createKyselySqliteAdapter(\n _config: KyselySqliteAdapter,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<KyselySqliteAdapter>> {\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Create SQLocalKysely instance (always in-memory for tests)\n const { dialect } = new SQLocalKysely(\":memory:\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kysely = new Kysely<any>({\n dialect,\n });\n\n // Create KyselyAdapter\n const adapter = new KyselyAdapter({\n db: kysely,\n provider: \"sqlite\",\n });\n\n // Run migrations\n const migrator = adapter.createMigrationEngine(schema, namespace);\n const preparedMigration = migrateToVersion\n ? await migrator.prepareMigrationTo(migrateToVersion, {\n updateSettings: false,\n })\n : await migrator.prepareMigration({\n updateSettings: false,\n });\n await preparedMigration.execute();\n\n // Create ORM instance\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;\n\n return { kysely, adapter, orm };\n };\n\n // Create initial database\n let { kysely, adapter, orm } = await createDatabase();\n\n // Reset database function - creates a fresh in-memory database and re-runs migrations\n const resetDatabase = async () => {\n // Destroy the old Kysely instance\n await kysely.destroy();\n\n // Create a new database instance\n const newDb = await createDatabase();\n kysely = newDb.kysely;\n adapter = newDb.adapter;\n orm = newDb.orm;\n };\n\n // Cleanup function - closes connections (no files to delete for in-memory)\n const cleanup = async () => {\n await kysely.destroy();\n };\n\n return {\n testContext: {\n get db() {\n return orm;\n },\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create Kysely + PGLite adapter using kysely-pglite\n */\nexport async function createKyselyPgliteAdapter(\n config: KyselyPgliteAdapter,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<KyselyPgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Create KyselyPGlite instance\n const kyselyPglite = await KyselyPGlite.create(databasePath);\n\n // Create Kysely instance with PGlite dialect\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kysely = new Kysely<any>({\n dialect: kyselyPglite.dialect,\n });\n\n // Create KyselyAdapter\n const adapter = new KyselyAdapter({\n db: kysely,\n provider: \"postgresql\",\n });\n\n // Run migrations\n const migrator = adapter.createMigrationEngine(schema, namespace);\n const preparedMigration = migrateToVersion\n ? await migrator.prepareMigrationTo(migrateToVersion, {\n updateSettings: false,\n })\n : await migrator.prepareMigration({\n updateSettings: false,\n });\n await preparedMigration.execute();\n\n // Create ORM instance\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;\n\n return { kysely, adapter, kyselyPglite, orm };\n };\n\n // Create initial database\n let { kysely, adapter, kyselyPglite, orm } = await createDatabase();\n\n // Reset database function - creates a fresh database and re-runs migrations\n const resetDatabase = async () => {\n // Close the old instances\n await kysely.destroy();\n\n try {\n await kyselyPglite.client.close();\n } catch {\n // Ignore if already closed\n }\n\n // Create a new database instance\n const newDb = await createDatabase();\n kysely = newDb.kysely;\n adapter = newDb.adapter;\n kyselyPglite = newDb.kyselyPglite;\n orm = newDb.orm;\n };\n\n // Cleanup function - closes connections and deletes database directory\n const cleanup = async () => {\n await kysely.destroy();\n\n try {\n await kyselyPglite.client.close();\n } catch {\n // Ignore if already closed\n }\n\n // Delete the database directory if it exists and is a file path\n if (databasePath && databasePath !== \":memory:\" && existsSync(databasePath)) {\n await rm(databasePath, { recursive: true, force: true });\n }\n };\n\n return {\n testContext: {\n get db() {\n return orm;\n },\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create Drizzle + PGLite adapter using drizzle-orm/pglite\n */\nexport async function createDrizzlePgliteAdapter(\n config: DrizzlePgliteAdapter,\n schema: AnySchema,\n namespace: string,\n _migrateToVersion?: number,\n): Promise<AdapterFactoryResult<DrizzlePgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Import drizzle-kit for migrations\n const require = createRequire(import.meta.url);\n const { generateDrizzleJson, generateMigration } =\n require(\"drizzle-kit/api\") as typeof import(\"drizzle-kit/api\");\n\n // Import generateSchema from the properly exported module\n const { generateSchema } = await import(\"@fragno-dev/db/adapters/drizzle/generate\");\n\n // Helper to write schema to file and dynamically import it\n const writeAndLoadSchema = async () => {\n const testDir = join(import.meta.dirname, \"_generated\", \"drizzle-test\");\n await mkdir(testDir, { recursive: true }).catch(() => {\n // Ignore error if directory already exists\n });\n\n const schemaFilePath = join(\n testDir,\n `test-schema-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.ts`,\n );\n\n // Generate and write the Drizzle schema to file\n const drizzleSchemaTs = generateSchema([{ namespace: namespace ?? \"\", schema }], \"postgresql\");\n await writeFile(schemaFilePath, drizzleSchemaTs, \"utf-8\");\n\n // Dynamically import the generated schema (with cache busting)\n const schemaModule = await import(`${schemaFilePath}?t=${Date.now()}`);\n\n const cleanup = async () => {\n await rm(testDir, { recursive: true, force: true });\n };\n\n return { schemaModule, cleanup };\n };\n\n // Helper to create a new database instance and run migrations\n const createDatabase = async () => {\n // Write schema to file and load it\n const { schemaModule, cleanup } = await writeAndLoadSchema();\n\n // Create PGlite instance\n const pglite = new PGlite(databasePath);\n\n // Create Drizzle instance with PGlite\n const db = drizzle(pglite, {\n schema: schemaModule,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any;\n\n // Generate and run migrations\n const migrationStatements = await generateMigration(\n generateDrizzleJson({}), // Empty schema (starting state)\n generateDrizzleJson(schemaModule), // Target schema\n );\n\n // Execute migration SQL\n for (const statement of migrationStatements) {\n await db.execute(statement);\n }\n\n // Create DrizzleAdapter\n const adapter = new DrizzleAdapter({\n db: () => db,\n provider: \"postgresql\",\n });\n\n // Create ORM instance\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;\n\n return { drizzle: db, adapter, pglite, cleanup, orm };\n };\n\n // Create initial database\n let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup, orm } = await createDatabase();\n\n // Reset database function - creates a fresh database and re-runs migrations\n const resetDatabase = async () => {\n // Close the old instances and cleanup\n await pglite.close();\n await schemaCleanup();\n\n // Create a new database instance\n const newDb = await createDatabase();\n drizzleDb = newDb.drizzle;\n adapter = newDb.adapter;\n pglite = newDb.pglite;\n schemaCleanup = newDb.cleanup;\n orm = newDb.orm;\n };\n\n // Cleanup function - closes connections and deletes generated files and database directory\n const cleanup = async () => {\n await pglite.close();\n await schemaCleanup();\n\n // Delete the database directory if it exists and is a file path\n if (databasePath && databasePath !== \":memory:\" && existsSync(databasePath)) {\n await rm(databasePath, { recursive: true, force: true });\n }\n };\n\n return {\n testContext: {\n get db() {\n return orm;\n },\n get drizzle() {\n return drizzleDb;\n },\n get adapter() {\n return adapter;\n },\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create adapter based on configuration\n */\nexport async function createAdapter<T extends SupportedAdapter>(\n adapterConfig: T,\n schema: AnySchema,\n namespace: string,\n migrateToVersion?: number,\n): Promise<AdapterFactoryResult<T>> {\n if (adapterConfig.type === \"kysely-sqlite\") {\n return createKyselySqliteAdapter(adapterConfig, schema, namespace, migrateToVersion) as Promise<\n AdapterFactoryResult<T>\n >;\n } else if (adapterConfig.type === \"kysely-pglite\") {\n return createKyselyPgliteAdapter(adapterConfig, schema, namespace, migrateToVersion) as Promise<\n AdapterFactoryResult<T>\n >;\n } else if (adapterConfig.type === \"drizzle-pglite\") {\n return createDrizzlePgliteAdapter(\n adapterConfig,\n schema,\n namespace,\n migrateToVersion,\n ) as Promise<AdapterFactoryResult<T>>;\n }\n\n throw new Error(`Unsupported adapter type: ${(adapterConfig as SupportedAdapter).type}`);\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  import { DrizzlePgliteAdapter, KyselyPgliteAdapter, KyselySqliteAdapter, SupportedAdapter, TestContext } from "./adapters.js";
2
- import { CreateFragmentForTestOptions, CreateFragmentForTestOptions as CreateFragmentForTestOptions$1, FragmentForTest, FragmentForTest as FragmentForTest$1, InitRoutesOverrides, RouteHandlerInputOptions, TestResponse, createFragmentForTest } from "@fragno-dev/core/test";
2
+ import { CreateFragmentForTestOptions, CreateFragmentForTestOptions as CreateFragmentForTestOptions$1, FragmentForTest, FragmentForTest as FragmentForTest$1, RouteHandlerInputOptions, createFragmentForTest } from "@fragno-dev/core/test";
3
3
  import { AnySchema } from "@fragno-dev/db/schema";
4
4
  import { FragnoPublicConfig } from "@fragno-dev/core/api/fragment-instantiation";
5
5
  import { FragmentDefinition } from "@fragno-dev/core/api/fragment-builder";
6
+ import { AnyRouteOrFactory, FlattenRouteFactories } from "@fragno-dev/core/api/route";
7
+ import { FragnoRouteConfig } from "@fragno-dev/core";
8
+ import { HTTPMethod } from "@fragno-dev/core/api";
9
+ import { StandardSchemaV1 } from "@standard-schema/spec";
6
10
 
7
11
  //#region src/index.d.ts
8
12
 
@@ -18,20 +22,19 @@ interface CreateDatabaseFragmentForTestOptions<TConfig, TDeps, TServices, TAddit
18
22
  * Result of creating a database fragment for testing
19
23
  * All properties are getters that return the current fragment instance
20
24
  */
21
- interface DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext extends Record<string, unknown>, TOptions extends FragnoPublicConfig, TAdapter extends SupportedAdapter> {
22
- readonly fragment: FragmentForTest$1<TConfig, TDeps, TServices, TAdditionalContext, TOptions>;
25
+ interface DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext extends Record<string, unknown>, TOptions extends FragnoPublicConfig, TAdapter extends SupportedAdapter, TRoutes extends readonly FragnoRouteConfig<HTTPMethod, string, StandardSchemaV1 | undefined, StandardSchemaV1 | undefined, string, string>[]> {
26
+ readonly fragment: FragmentForTest$1<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TRoutes>;
23
27
  readonly services: TServices;
24
- readonly initRoutes: FragmentForTest$1<TConfig, TDeps, TServices, TAdditionalContext, TOptions>["initRoutes"];
25
- readonly handler: FragmentForTest$1<TConfig, TDeps, TServices, TAdditionalContext, TOptions>["handler"];
28
+ readonly callRoute: FragmentForTest$1<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TRoutes>["callRoute"];
26
29
  readonly config: TConfig;
27
30
  readonly deps: TDeps;
28
31
  readonly additionalContext: TAdditionalContext;
29
32
  test: TestContext<TAdapter>;
30
33
  }
31
- declare function createDatabaseFragmentForTest<const TConfig, const TDeps, const TServices extends Record<string, unknown>, const TAdditionalContext extends Record<string, unknown>, const TOptions extends FragnoPublicConfig, const TSchema extends AnySchema, const TAdapter extends SupportedAdapter>(fragmentBuilder: {
34
+ declare function createDatabaseFragmentForTest<const TConfig, const TDeps, const TServices extends Record<string, unknown>, const TAdditionalContext extends Record<string, unknown>, const TOptions extends FragnoPublicConfig, const TSchema extends AnySchema, const TAdapter extends SupportedAdapter, const TRoutesOrFactories extends readonly AnyRouteOrFactory[]>(fragmentBuilder: {
32
35
  definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;
33
36
  $requiredOptions: TOptions;
34
- }, options: CreateDatabaseFragmentForTestOptions<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter>): Promise<DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter>>;
37
+ }, routesOrFactories: TRoutesOrFactories, options: CreateDatabaseFragmentForTestOptions<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter>): Promise<DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter, FlattenRouteFactories<TRoutesOrFactories>>>;
35
38
  //#endregion
36
- export { CreateDatabaseFragmentForTestOptions, type CreateFragmentForTestOptions, DatabaseFragmentTestResult, type DrizzlePgliteAdapter, type FragmentForTest, type InitRoutesOverrides, type KyselyPgliteAdapter, type KyselySqliteAdapter, type RouteHandlerInputOptions, type SupportedAdapter, type TestContext, type TestResponse, createDatabaseFragmentForTest, createFragmentForTest };
39
+ export { CreateDatabaseFragmentForTestOptions, type CreateFragmentForTestOptions, DatabaseFragmentTestResult, type DrizzlePgliteAdapter, type FragmentForTest, type KyselyPgliteAdapter, type KyselySqliteAdapter, type RouteHandlerInputOptions, type SupportedAdapter, type TestContext, createDatabaseFragmentForTest, createFragmentForTest };
37
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAuCA;;;AAMmB,UANF,oCAME,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,2BAFU,MAEV,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iBADA,kBACA,EAAA,iBAAA,gBAAA,CAAA,SACT,IADS,CAEf,8BAFe,CAEc,OAFd,EAEuB,KAFvB,EAE8B,SAF9B,EAEyC,kBAFzC,EAE6D,QAF7D,CAAA,EAAA,QAAA,CAAA,CAAA;EAEc,OAAA,EAGtB,QAHsB;EAAS,gBAAA,CAAA,EAAA,MAAA;EAAO,MAAA,CAAA,EAKtC,OALsC;;;;;;AADvC,UAaO,0BAbP,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,2BAiBmB,MAjBnB,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iBAkBS,kBAlBT,EAAA,iBAmBS,gBAnBT,CAAA,CAAA;EAAI,SAAA,QAAA,EAqBO,iBArBP,CAqBuB,OArBvB,EAqBgC,KArBhC,EAqBuC,SArBvC,EAqBkD,kBArBlD,EAqBsE,QArBtE,CAAA;EAaG,SAAA,QAAA,EASI,SATJ;EAIY,SAAA,UAAA,EAMN,iBANM,CAOzB,OAPyB,EAQzB,KARyB,EASzB,SATyB,EAUzB,kBAVyB,EAWzB,QAXyB,CAAA,CAAA,YAAA,CAAA;EACV,SAAA,OAAA,EAYC,iBAZD,CAaf,OAbe,EAcf,KAde,EAef,SAfe,EAgBf,kBAhBe,EAiBf,QAjBe,CAAA,CAAA,SAAA,CAAA;EACA,SAAA,MAAA,EAkBA,OAlBA;EAEkB,SAAA,IAAA,EAiBpB,KAjBoB;EAAS,SAAA,iBAAA,EAkBhB,kBAlBgB;EAAO,IAAA,EAmB7C,WAnB6C,CAmBjC,QAnBiC,CAAA;;AAA+B,iBAsB9D,6BAtB8D,CAAA,aAAA,EAAA,WAAA,EAAA,wBAyB1D,MAzB0D,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iCA0BjD,MA1BiD,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,uBA2B3D,kBA3B2D,EAAA,sBA4B5D,SA5B4D,EAAA,uBA6B3D,gBA7B2D,CAAA,CAAA,eAAA,EAAA;EAA/D,UAAA,EAgCL,kBAhCK,CAgCc,OAhCd,EAgCuB,KAhCvB,EAgC8B,SAhC9B,EAgCyC,kBAhCzC,CAAA;EACA,gBAAA,EAgCC,QAhCD;CAEjB,EAAA,OAAA,EAgCO,oCAhCP,CAiCA,OAjCA,EAkCA,KAlCA,EAmCA,SAnCA,EAoCA,kBApCA,EAqCA,QArCA,EAsCA,QAtCA,CAAA,CAAA,EAwCD,OAxCC,CAyCF,0BAzCE,CAyCyB,OAzCzB,EAyCkC,KAzClC,EAyCyC,SAzCzC,EAyCoD,kBAzCpD,EAyCwE,QAzCxE,EAyCkF,QAzClF,CAAA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;AAyCA;;;AAMmB,UANF,oCAME,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,2BAFU,MAEV,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iBADA,kBACA,EAAA,iBAAA,gBAAA,CAAA,SACT,IADS,CAEf,8BAFe,CAEc,OAFd,EAEuB,KAFvB,EAE8B,SAF9B,EAEyC,kBAFzC,EAE6D,QAF7D,CAAA,EAAA,QAAA,CAAA,CAAA;EAEc,OAAA,EAGtB,QAHsB;EAAS,gBAAA,CAAA,EAAA,MAAA;EAAO,MAAA,CAAA,EAKtC,OALsC;;;;;;AADvC,UAaO,0BAbP,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,2BAiBmB,MAjBnB,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iBAkBS,kBAlBT,EAAA,iBAmBS,gBAnBT,EAAA,gBAAA,SAoBiB,iBApBjB,CAqBN,UArBM,EAAA,MAAA,EAuBN,gBAvBM,GAAA,SAAA,EAwBN,gBAxBM,GAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,CAAA;EAAI,SAAA,QAAA,EA6BO,iBA7BP,CA8BV,OA9BU,EA+BV,KA/BU,EAgCV,SAhCU,EAiCV,kBAjCU,EAkCV,QAlCU,EAmCV,OAnCU,CAAA;EAaG,SAAA,QAAA,EAwBI,SAxBJ;EAIY,SAAA,SAAA,EAqBP,iBArBO,CAsBzB,OAtByB,EAuBzB,KAvByB,EAwBzB,SAxByB,EAyBzB,kBAzByB,EA0BzB,QA1ByB,EA2BzB,OA3ByB,CAAA,CAAA,WAAA,CAAA;EACV,SAAA,MAAA,EA4BA,OA5BA;EACA,SAAA,IAAA,EA4BF,KA5BE;EAEf,SAAA,iBAAA,EA2B0B,kBA3B1B;EAEA,IAAA,EA0BI,WA1BJ,CA0BgB,QA1BhB,CAAA;;AAHuB,iBAgCL,6BAhCK,CAAA,aAAA,EAAA,WAAA,EAAA,wBAmCD,MAnCC,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,iCAoCQ,MApCR,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,uBAqCF,kBArCE,EAAA,sBAsCH,SAtCG,EAAA,uBAuCF,gBAvCE,EAAA,iCAAA,SAwCiB,iBAxCjB,EAAA,CAAA,CAAA,eAAA,EAAA;EAUvB,UAAA,EAiCY,kBAjCZ,CAiC+B,OAjC/B,EAiCwC,KAjCxC,EAiC+C,SAjC/C,EAiC0D,kBAjC1D,CAAA;EACA,gBAAA,EAiCkB,QAjClB;CACA,EAAA,iBAAA,EAkCiB,kBAlCjB,EAAA,OAAA,EAmCO,oCAnCP,CAoCA,OApCA,EAqCA,KArCA,EAsCA,SAtCA,EAuCA,kBAvCA,EAwCA,QAxCA,EAyCA,QAzCA,CAAA,CAAA,EA2CD,OA3CC,CA4CF,0BA5CE,CA6CA,OA7CA,EA8CA,KA9CA,EA+CA,SA/CA,EAgDA,kBAhDA,EAiDA,QAjDA,EAkDA,QAlDA,EAmDA,qBAnDA,CAmDsB,kBAnDtB,CAAA,CAAA,CAAA"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createAdapter } from "./adapters.js";
2
2
  import { createFragmentForTest, createFragmentForTest as createFragmentForTest$1 } from "@fragno-dev/core/test";
3
3
 
4
4
  //#region src/index.ts
5
- async function createDatabaseFragmentForTest(fragmentBuilder, options) {
5
+ async function createDatabaseFragmentForTest(fragmentBuilder, routesOrFactories, options) {
6
6
  const { adapter: adapterConfig, migrateToVersion, config, options: fragmentOptions, deps, services, additionalContext } = options;
7
7
  const fragmentAdditionalContext = fragmentBuilder.definition.additionalContext;
8
8
  const schema = fragmentAdditionalContext?.databaseSchema;
@@ -13,7 +13,7 @@ async function createDatabaseFragmentForTest(fragmentBuilder, options) {
13
13
  ...fragmentOptions,
14
14
  databaseAdapter: adapter
15
15
  };
16
- let fragment = createFragmentForTest$1(fragmentBuilder, {
16
+ let fragment = createFragmentForTest$1(fragmentBuilder, routesOrFactories, {
17
17
  config,
18
18
  options: mergedOptions,
19
19
  deps,
@@ -28,11 +28,8 @@ async function createDatabaseFragmentForTest(fragmentBuilder, options) {
28
28
  get services() {
29
29
  return fragment.services;
30
30
  },
31
- get initRoutes() {
32
- return fragment.initRoutes;
33
- },
34
- get handler() {
35
- return fragment.handler;
31
+ get callRoute() {
32
+ return fragment.callRoute;
36
33
  },
37
34
  get config() {
38
35
  return fragment.config;
@@ -44,6 +41,12 @@ async function createDatabaseFragmentForTest(fragmentBuilder, options) {
44
41
  return fragment.additionalContext;
45
42
  },
46
43
  test: Object.create(originalTestContext, {
44
+ db: {
45
+ get() {
46
+ return originalTestContext.db;
47
+ },
48
+ enumerable: true
49
+ },
47
50
  kysely: {
48
51
  get() {
49
52
  return originalTestContext.kysely;
@@ -69,7 +72,7 @@ async function createDatabaseFragmentForTest(fragmentBuilder, options) {
69
72
  ...fragmentOptions,
70
73
  databaseAdapter: originalTestContext.adapter
71
74
  };
72
- fragment = createFragmentForTest$1(fragmentBuilder, {
75
+ fragment = createFragmentForTest$1(fragmentBuilder, routesOrFactories, {
73
76
  config,
74
77
  options: mergedOptions,
75
78
  deps,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["createFragmentForTest"],"sources":["../src/index.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport {\n createFragmentForTest,\n type FragmentForTest,\n type CreateFragmentForTestOptions,\n} from \"@fragno-dev/core/test\";\nimport type { FragnoPublicConfig } from \"@fragno-dev/core/api/fragment-instantiation\";\nimport type { FragmentDefinition } from \"@fragno-dev/core/api/fragment-builder\";\nimport {\n createAdapter,\n type SupportedAdapter,\n type TestContext,\n type KyselySqliteAdapter,\n type KyselyPgliteAdapter,\n type DrizzlePgliteAdapter,\n} from \"./adapters\";\n\n// Re-export utilities from @fragno-dev/core/test\nexport {\n createFragmentForTest,\n type TestResponse,\n type CreateFragmentForTestOptions,\n type RouteHandlerInputOptions,\n type FragmentForTest,\n type InitRoutesOverrides,\n} from \"@fragno-dev/core/test\";\n\n// Re-export adapter types\nexport type {\n SupportedAdapter,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n TestContext,\n} from \"./adapters\";\n\n/**\n * Options for creating a database fragment for testing\n */\nexport interface CreateDatabaseFragmentForTestOptions<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext extends Record<string, unknown>,\n TOptions extends FragnoPublicConfig,\n TAdapter extends SupportedAdapter,\n> extends Omit<\n CreateFragmentForTestOptions<TConfig, TDeps, TServices, TAdditionalContext, TOptions>,\n \"config\"\n > {\n adapter: TAdapter;\n migrateToVersion?: number;\n config?: TConfig;\n}\n\n/**\n * Result of creating a database fragment for testing\n * All properties are getters that return the current fragment instance\n */\nexport interface DatabaseFragmentTestResult<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext extends Record<string, unknown>,\n TOptions extends FragnoPublicConfig,\n TAdapter extends SupportedAdapter,\n> {\n readonly fragment: FragmentForTest<TConfig, TDeps, TServices, TAdditionalContext, TOptions>;\n readonly services: TServices;\n readonly initRoutes: FragmentForTest<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions\n >[\"initRoutes\"];\n readonly handler: FragmentForTest<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions\n >[\"handler\"];\n readonly config: TConfig;\n readonly deps: TDeps;\n readonly additionalContext: TAdditionalContext;\n test: TestContext<TAdapter>;\n}\n\nexport async function createDatabaseFragmentForTest<\n const TConfig,\n const TDeps,\n const TServices extends Record<string, unknown>,\n const TAdditionalContext extends Record<string, unknown>,\n const TOptions extends FragnoPublicConfig,\n const TSchema extends AnySchema,\n const TAdapter extends SupportedAdapter,\n>(\n fragmentBuilder: {\n definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;\n $requiredOptions: TOptions;\n },\n options: CreateDatabaseFragmentForTestOptions<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions,\n TAdapter\n >,\n): Promise<\n DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter>\n> {\n const {\n adapter: adapterConfig,\n migrateToVersion,\n config,\n options: fragmentOptions,\n deps,\n services,\n additionalContext,\n } = options;\n\n // Get schema and namespace from fragment definition's additionalContext\n // Safe cast: DatabaseFragmentBuilder adds databaseSchema and databaseNamespace to additionalContext\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fragmentAdditionalContext = fragmentBuilder.definition.additionalContext as any;\n const schema = fragmentAdditionalContext?.databaseSchema as TSchema | undefined;\n const namespace = (fragmentAdditionalContext?.databaseNamespace as string | undefined) ?? \"\";\n\n if (!schema) {\n throw new Error(\n `Fragment '${fragmentBuilder.definition.name}' does not have a database schema. ` +\n `Make sure you're using defineFragmentWithDatabase().withDatabase(schema).`,\n );\n }\n\n // Create adapter using the factory\n const { testContext: originalTestContext, adapter } = await createAdapter(\n adapterConfig,\n schema,\n namespace,\n migrateToVersion,\n );\n\n // Create fragment with database adapter in options\n // Safe cast: We're merging the user's options with the databaseAdapter, which is required by TOptions\n // The user's TOptions is constrained to FragnoPublicConfig (or a subtype), which we extend with databaseAdapter\n let mergedOptions = {\n ...fragmentOptions,\n databaseAdapter: adapter,\n } as unknown as TOptions;\n\n // Safe cast: If config is not provided, we pass undefined as TConfig.\n // The base createFragmentForTest expects config: TConfig, but if TConfig allows undefined\n // or if the fragment doesn't use config in its dependencies function, this will work correctly.\n let fragment = createFragmentForTest(fragmentBuilder, {\n config: config as TConfig,\n options: mergedOptions,\n deps,\n services,\n additionalContext,\n });\n\n // Wrap resetDatabase to also recreate the fragment with the new adapter\n const originalResetDatabase = originalTestContext.resetDatabase;\n\n // Create test context with getters that always return current values\n // We need to cast to any to avoid TypeScript errors when accessing kysely/drizzle properties\n // that may not exist depending on the adapter type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const testContext: any = Object.create(originalTestContext, {\n kysely: {\n get() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalTestContext as any).kysely;\n },\n enumerable: true,\n },\n drizzle: {\n get() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalTestContext as any).drizzle;\n },\n enumerable: true,\n },\n adapter: {\n get() {\n return originalTestContext.adapter;\n },\n enumerable: true,\n },\n resetDatabase: {\n value: async () => {\n // Call the original reset database function\n await originalResetDatabase();\n\n // Recreate the fragment with the new adapter (which has been updated by the factory's resetDatabase)\n mergedOptions = {\n ...fragmentOptions,\n databaseAdapter: originalTestContext.adapter,\n } as unknown as TOptions;\n\n fragment = createFragmentForTest(fragmentBuilder, {\n config: config as TConfig,\n options: mergedOptions,\n deps,\n services,\n additionalContext,\n });\n },\n enumerable: true,\n },\n cleanup: {\n value: async () => {\n await originalTestContext.cleanup();\n },\n enumerable: true,\n },\n });\n\n // Return an object with getters for fragment properties so they always reference the current fragment\n return {\n get fragment() {\n return fragment;\n },\n get services() {\n return fragment.services;\n },\n get initRoutes() {\n return fragment.initRoutes;\n },\n get handler() {\n return fragment.handler;\n },\n get config() {\n return fragment.config;\n },\n get deps() {\n return fragment.deps;\n },\n get additionalContext() {\n return fragment.additionalContext;\n },\n test: testContext,\n };\n}\n"],"mappings":";;;;AAyFA,eAAsB,8BASpB,iBAIA,SAUA;CACA,MAAM,EACJ,SAAS,eACT,kBACA,QACA,SAAS,iBACT,MACA,UACA,sBACE;CAKJ,MAAM,4BAA4B,gBAAgB,WAAW;CAC7D,MAAM,SAAS,2BAA2B;CAC1C,MAAM,YAAa,2BAA2B,qBAA4C;AAE1F,KAAI,CAAC,OACH,OAAM,IAAI,MACR,aAAa,gBAAgB,WAAW,KAAK,8GAE9C;CAIH,MAAM,EAAE,aAAa,qBAAqB,YAAY,MAAM,cAC1D,eACA,QACA,WACA,iBACD;CAKD,IAAI,gBAAgB;EAClB,GAAG;EACH,iBAAiB;EAClB;CAKD,IAAI,WAAWA,wBAAsB,iBAAiB;EAC5C;EACR,SAAS;EACT;EACA;EACA;EACD,CAAC;CAGF,MAAM,wBAAwB,oBAAoB;AAyDlD,QAAO;EACL,IAAI,WAAW;AACb,UAAO;;EAET,IAAI,WAAW;AACb,UAAO,SAAS;;EAElB,IAAI,aAAa;AACf,UAAO,SAAS;;EAElB,IAAI,UAAU;AACZ,UAAO,SAAS;;EAElB,IAAI,SAAS;AACX,UAAO,SAAS;;EAElB,IAAI,OAAO;AACT,UAAO,SAAS;;EAElB,IAAI,oBAAoB;AACtB,UAAO,SAAS;;EAElB,MAzEuB,OAAO,OAAO,qBAAqB;GAC1D,QAAQ;IACN,MAAM;AAEJ,YAAQ,oBAA4B;;IAEtC,YAAY;IACb;GACD,SAAS;IACP,MAAM;AAEJ,YAAQ,oBAA4B;;IAEtC,YAAY;IACb;GACD,SAAS;IACP,MAAM;AACJ,YAAO,oBAAoB;;IAE7B,YAAY;IACb;GACD,eAAe;IACb,OAAO,YAAY;AAEjB,WAAM,uBAAuB;AAG7B,qBAAgB;MACd,GAAG;MACH,iBAAiB,oBAAoB;MACtC;AAED,gBAAWA,wBAAsB,iBAAiB;MACxC;MACR,SAAS;MACT;MACA;MACA;MACD,CAAC;;IAEJ,YAAY;IACb;GACD,SAAS;IACP,OAAO,YAAY;AACjB,WAAM,oBAAoB,SAAS;;IAErC,YAAY;IACb;GACF,CAAC;EA0BD"}
1
+ {"version":3,"file":"index.js","names":["createFragmentForTest"],"sources":["../src/index.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport {\n createFragmentForTest,\n type FragmentForTest,\n type CreateFragmentForTestOptions,\n} from \"@fragno-dev/core/test\";\nimport type { FragnoPublicConfig } from \"@fragno-dev/core/api/fragment-instantiation\";\nimport type { FragmentDefinition } from \"@fragno-dev/core/api/fragment-builder\";\nimport type { AnyRouteOrFactory, FlattenRouteFactories } from \"@fragno-dev/core/api/route\";\nimport {\n createAdapter,\n type SupportedAdapter,\n type TestContext,\n type KyselySqliteAdapter,\n type KyselyPgliteAdapter,\n type DrizzlePgliteAdapter,\n} from \"./adapters\";\nimport type { FragnoRouteConfig } from \"@fragno-dev/core\";\nimport type { HTTPMethod } from \"@fragno-dev/core/api\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Re-export utilities from @fragno-dev/core/test\nexport {\n createFragmentForTest,\n type CreateFragmentForTestOptions,\n type RouteHandlerInputOptions,\n type FragmentForTest,\n} from \"@fragno-dev/core/test\";\n\n// Re-export adapter types\nexport type {\n SupportedAdapter,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n TestContext,\n} from \"./adapters\";\n\n/**\n * Options for creating a database fragment for testing\n */\nexport interface CreateDatabaseFragmentForTestOptions<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext extends Record<string, unknown>,\n TOptions extends FragnoPublicConfig,\n TAdapter extends SupportedAdapter,\n> extends Omit<\n CreateFragmentForTestOptions<TConfig, TDeps, TServices, TAdditionalContext, TOptions>,\n \"config\"\n > {\n adapter: TAdapter;\n migrateToVersion?: number;\n config?: TConfig;\n}\n\n/**\n * Result of creating a database fragment for testing\n * All properties are getters that return the current fragment instance\n */\nexport interface DatabaseFragmentTestResult<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext extends Record<string, unknown>,\n TOptions extends FragnoPublicConfig,\n TAdapter extends SupportedAdapter,\n TRoutes extends readonly FragnoRouteConfig<\n HTTPMethod,\n string,\n StandardSchemaV1 | undefined,\n StandardSchemaV1 | undefined,\n string,\n string\n >[],\n> {\n readonly fragment: FragmentForTest<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions,\n TRoutes\n >;\n readonly services: TServices;\n readonly callRoute: FragmentForTest<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions,\n TRoutes\n >[\"callRoute\"];\n readonly config: TConfig;\n readonly deps: TDeps;\n readonly additionalContext: TAdditionalContext;\n test: TestContext<TAdapter>;\n}\n\nexport async function createDatabaseFragmentForTest<\n const TConfig,\n const TDeps,\n const TServices extends Record<string, unknown>,\n const TAdditionalContext extends Record<string, unknown>,\n const TOptions extends FragnoPublicConfig,\n const TSchema extends AnySchema,\n const TAdapter extends SupportedAdapter,\n const TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n>(\n fragmentBuilder: {\n definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;\n $requiredOptions: TOptions;\n },\n routesOrFactories: TRoutesOrFactories,\n options: CreateDatabaseFragmentForTestOptions<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions,\n TAdapter\n >,\n): Promise<\n DatabaseFragmentTestResult<\n TConfig,\n TDeps,\n TServices,\n TAdditionalContext,\n TOptions,\n TAdapter,\n FlattenRouteFactories<TRoutesOrFactories>\n >\n> {\n const {\n adapter: adapterConfig,\n migrateToVersion,\n config,\n options: fragmentOptions,\n deps,\n services,\n additionalContext,\n } = options;\n\n // Get schema and namespace from fragment definition's additionalContext\n // Safe cast: DatabaseFragmentBuilder adds databaseSchema and databaseNamespace to additionalContext\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const fragmentAdditionalContext = fragmentBuilder.definition.additionalContext as any;\n const schema = fragmentAdditionalContext?.databaseSchema as TSchema | undefined;\n const namespace = (fragmentAdditionalContext?.databaseNamespace as string | undefined) ?? \"\";\n\n if (!schema) {\n throw new Error(\n `Fragment '${fragmentBuilder.definition.name}' does not have a database schema. ` +\n `Make sure you're using defineFragmentWithDatabase().withDatabase(schema).`,\n );\n }\n\n // Create adapter using the factory\n const { testContext: originalTestContext, adapter } = await createAdapter(\n adapterConfig,\n schema,\n namespace,\n migrateToVersion,\n );\n\n // Create fragment with database adapter in options\n // Safe cast: We're merging the user's options with the databaseAdapter, which is required by TOptions\n // The user's TOptions is constrained to FragnoPublicConfig (or a subtype), which we extend with databaseAdapter\n let mergedOptions = {\n ...fragmentOptions,\n databaseAdapter: adapter,\n } as unknown as TOptions;\n\n let fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {\n // Safe cast: If config is not provided, we pass undefined as TConfig.\n // The base createFragmentForTest expects config: TConfig, but if TConfig allows undefined\n // or if the fragment doesn't use config in its dependencies function, this will work correctly.\n config: config as TConfig,\n options: mergedOptions,\n deps,\n services,\n additionalContext,\n });\n\n // Wrap resetDatabase to also recreate the fragment with the new adapter\n const originalResetDatabase = originalTestContext.resetDatabase;\n\n // Create test context with getters that always return current values\n // We need to cast to any to avoid TypeScript errors when accessing kysely/drizzle properties\n // that may not exist depending on the adapter type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const testContext: any = Object.create(originalTestContext, {\n db: {\n get() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalTestContext as any).db;\n },\n enumerable: true,\n },\n kysely: {\n get() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalTestContext as any).kysely;\n },\n enumerable: true,\n },\n drizzle: {\n get() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalTestContext as any).drizzle;\n },\n enumerable: true,\n },\n adapter: {\n get() {\n return originalTestContext.adapter;\n },\n enumerable: true,\n },\n resetDatabase: {\n value: async () => {\n // Call the original reset database function\n await originalResetDatabase();\n\n // Recreate the fragment with the new adapter (which has been updated by the factory's resetDatabase)\n mergedOptions = {\n ...fragmentOptions,\n databaseAdapter: originalTestContext.adapter,\n } as unknown as TOptions;\n\n fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {\n config: config as TConfig,\n options: mergedOptions,\n deps,\n services,\n additionalContext,\n });\n },\n enumerable: true,\n },\n cleanup: {\n value: async () => {\n await originalTestContext.cleanup();\n },\n enumerable: true,\n },\n });\n\n // Return an object with getters for fragment properties so they always reference the current fragment\n return {\n get fragment() {\n return fragment;\n },\n get services() {\n return fragment.services;\n },\n get callRoute() {\n return fragment.callRoute;\n },\n get config() {\n return fragment.config;\n },\n get deps() {\n return fragment.deps;\n },\n get additionalContext() {\n return fragment.additionalContext;\n },\n test: testContext,\n };\n}\n"],"mappings":";;;;AAoGA,eAAsB,8BAUpB,iBAIA,mBACA,SAkBA;CACA,MAAM,EACJ,SAAS,eACT,kBACA,QACA,SAAS,iBACT,MACA,UACA,sBACE;CAKJ,MAAM,4BAA4B,gBAAgB,WAAW;CAC7D,MAAM,SAAS,2BAA2B;CAC1C,MAAM,YAAa,2BAA2B,qBAA4C;AAE1F,KAAI,CAAC,OACH,OAAM,IAAI,MACR,aAAa,gBAAgB,WAAW,KAAK,8GAE9C;CAIH,MAAM,EAAE,aAAa,qBAAqB,YAAY,MAAM,cAC1D,eACA,QACA,WACA,iBACD;CAKD,IAAI,gBAAgB;EAClB,GAAG;EACH,iBAAiB;EAClB;CAED,IAAI,WAAWA,wBAAsB,iBAAiB,mBAAmB;EAI/D;EACR,SAAS;EACT;EACA;EACA;EACD,CAAC;CAGF,MAAM,wBAAwB,oBAAoB;AAgElD,QAAO;EACL,IAAI,WAAW;AACb,UAAO;;EAET,IAAI,WAAW;AACb,UAAO,SAAS;;EAElB,IAAI,YAAY;AACd,UAAO,SAAS;;EAElB,IAAI,SAAS;AACX,UAAO,SAAS;;EAElB,IAAI,OAAO;AACT,UAAO,SAAS;;EAElB,IAAI,oBAAoB;AACtB,UAAO,SAAS;;EAElB,MA7EuB,OAAO,OAAO,qBAAqB;GAC1D,IAAI;IACF,MAAM;AAEJ,YAAQ,oBAA4B;;IAEtC,YAAY;IACb;GACD,QAAQ;IACN,MAAM;AAEJ,YAAQ,oBAA4B;;IAEtC,YAAY;IACb;GACD,SAAS;IACP,MAAM;AAEJ,YAAQ,oBAA4B;;IAEtC,YAAY;IACb;GACD,SAAS;IACP,MAAM;AACJ,YAAO,oBAAoB;;IAE7B,YAAY;IACb;GACD,eAAe;IACb,OAAO,YAAY;AAEjB,WAAM,uBAAuB;AAG7B,qBAAgB;MACd,GAAG;MACH,iBAAiB,oBAAoB;MACtC;AAED,gBAAWA,wBAAsB,iBAAiB,mBAAmB;MAC3D;MACR,SAAS;MACT;MACA;MACA;MACD,CAAC;;IAEJ,YAAY;IACb;GACD,SAAS;IACP,OAAO,YAAY;AACjB,WAAM,oBAAoB,SAAS;;IAErC,YAAY;IACb;GACF,CAAC;EAuBD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragno-dev/test",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -13,10 +13,11 @@
13
13
  "module": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
15
  "dependencies": {
16
+ "@standard-schema/spec": "^1.0.0",
16
17
  "kysely": "^0.28.7",
17
18
  "sqlocal": "^0.15.2",
18
- "@fragno-dev/db": "0.1.11",
19
- "@fragno-dev/core": "0.1.5"
19
+ "@fragno-dev/core": "0.1.6",
20
+ "@fragno-dev/db": "0.1.13"
20
21
  },
21
22
  "peerDependencies": {
22
23
  "@electric-sql/pglite": "^0.3.11",
@@ -48,8 +49,8 @@
48
49
  "kysely-pglite": "^0.6.1",
49
50
  "vitest": "^3.2.4",
50
51
  "zod": "^4.1.12",
51
- "@fragno-private/vitest-config": "0.0.0",
52
- "@fragno-private/typescript-config": "0.0.1"
52
+ "@fragno-private/typescript-config": "0.0.1",
53
+ "@fragno-private/vitest-config": "0.0.0"
53
54
  },
54
55
  "repository": {
55
56
  "type": "git",
package/src/adapters.ts CHANGED
@@ -7,6 +7,7 @@ import { KyselyAdapter } from "@fragno-dev/db/adapters/kysely";
7
7
  import { DrizzleAdapter } from "@fragno-dev/db/adapters/drizzle";
8
8
  import type { AnySchema } from "@fragno-dev/db/schema";
9
9
  import type { DatabaseAdapter } from "@fragno-dev/db/adapters";
10
+ import type { AbstractQuery } from "@fragno-dev/db/query";
10
11
  import { createRequire } from "node:module";
11
12
  import { mkdir, writeFile, rm } from "node:fs/promises";
12
13
  import { join } from "node:path";
@@ -34,6 +35,7 @@ export type TestContext<T extends SupportedAdapter> = T extends
34
35
  | KyselySqliteAdapter
35
36
  | KyselyPgliteAdapter
36
37
  ? {
38
+ readonly db: AbstractQuery<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
37
39
  readonly kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
38
40
  readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
39
41
  resetDatabase: () => Promise<void>;
@@ -41,6 +43,7 @@ export type TestContext<T extends SupportedAdapter> = T extends
41
43
  }
42
44
  : T extends DrizzlePgliteAdapter
43
45
  ? {
46
+ readonly db: AbstractQuery<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
44
47
  readonly drizzle: ReturnType<typeof drizzle<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any
45
48
  readonly adapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
46
49
  resetDatabase: () => Promise<void>;
@@ -90,11 +93,15 @@ export async function createKyselySqliteAdapter(
90
93
  });
91
94
  await preparedMigration.execute();
92
95
 
93
- return { kysely, adapter };
96
+ // Create ORM instance
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;
99
+
100
+ return { kysely, adapter, orm };
94
101
  };
95
102
 
96
103
  // Create initial database
97
- let { kysely, adapter } = await createDatabase();
104
+ let { kysely, adapter, orm } = await createDatabase();
98
105
 
99
106
  // Reset database function - creates a fresh in-memory database and re-runs migrations
100
107
  const resetDatabase = async () => {
@@ -105,6 +112,7 @@ export async function createKyselySqliteAdapter(
105
112
  const newDb = await createDatabase();
106
113
  kysely = newDb.kysely;
107
114
  adapter = newDb.adapter;
115
+ orm = newDb.orm;
108
116
  };
109
117
 
110
118
  // Cleanup function - closes connections (no files to delete for in-memory)
@@ -114,6 +122,9 @@ export async function createKyselySqliteAdapter(
114
122
 
115
123
  return {
116
124
  testContext: {
125
+ get db() {
126
+ return orm;
127
+ },
117
128
  get kysely() {
118
129
  return kysely;
119
130
  },
@@ -168,11 +179,15 @@ export async function createKyselyPgliteAdapter(
168
179
  });
169
180
  await preparedMigration.execute();
170
181
 
171
- return { kysely, adapter, kyselyPglite };
182
+ // Create ORM instance
183
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
184
+ const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;
185
+
186
+ return { kysely, adapter, kyselyPglite, orm };
172
187
  };
173
188
 
174
189
  // Create initial database
175
- let { kysely, adapter, kyselyPglite } = await createDatabase();
190
+ let { kysely, adapter, kyselyPglite, orm } = await createDatabase();
176
191
 
177
192
  // Reset database function - creates a fresh database and re-runs migrations
178
193
  const resetDatabase = async () => {
@@ -190,6 +205,7 @@ export async function createKyselyPgliteAdapter(
190
205
  kysely = newDb.kysely;
191
206
  adapter = newDb.adapter;
192
207
  kyselyPglite = newDb.kyselyPglite;
208
+ orm = newDb.orm;
193
209
  };
194
210
 
195
211
  // Cleanup function - closes connections and deletes database directory
@@ -210,6 +226,9 @@ export async function createKyselyPgliteAdapter(
210
226
 
211
227
  return {
212
228
  testContext: {
229
+ get db() {
230
+ return orm;
231
+ },
213
232
  get kysely() {
214
233
  return kysely;
215
234
  },
@@ -301,11 +320,15 @@ export async function createDrizzlePgliteAdapter(
301
320
  provider: "postgresql",
302
321
  });
303
322
 
304
- return { drizzle: db, adapter, pglite, cleanup };
323
+ // Create ORM instance
324
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
325
+ const orm = adapter.createQueryEngine(schema, namespace) as AbstractQuery<any>;
326
+
327
+ return { drizzle: db, adapter, pglite, cleanup, orm };
305
328
  };
306
329
 
307
330
  // Create initial database
308
- let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup } = await createDatabase();
331
+ let { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup, orm } = await createDatabase();
309
332
 
310
333
  // Reset database function - creates a fresh database and re-runs migrations
311
334
  const resetDatabase = async () => {
@@ -319,6 +342,7 @@ export async function createDrizzlePgliteAdapter(
319
342
  adapter = newDb.adapter;
320
343
  pglite = newDb.pglite;
321
344
  schemaCleanup = newDb.cleanup;
345
+ orm = newDb.orm;
322
346
  };
323
347
 
324
348
  // Cleanup function - closes connections and deletes generated files and database directory
@@ -334,6 +358,9 @@ export async function createDrizzlePgliteAdapter(
334
358
 
335
359
  return {
336
360
  testContext: {
361
+ get db() {
362
+ return orm;
363
+ },
337
364
  get drizzle() {
338
365
  return drizzleDb;
339
366
  },
package/src/index.test.ts CHANGED
@@ -55,7 +55,7 @@ describe("createDatabaseFragmentForTest", () => {
55
55
  });
56
56
 
57
57
  it("should use in-memory database by default", async () => {
58
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
58
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, [], {
59
59
  adapter: { type: "kysely-sqlite" },
60
60
  });
61
61
 
@@ -79,7 +79,7 @@ describe("createDatabaseFragmentForTest", () => {
79
79
  });
80
80
 
81
81
  it("should create database at specified path", async () => {
82
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
82
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, [], {
83
83
  adapter: { type: "kysely-sqlite", databasePath: testDbPath },
84
84
  });
85
85
 
@@ -103,7 +103,7 @@ describe("createDatabaseFragmentForTest", () => {
103
103
 
104
104
  describe("migrateToVersion option", () => {
105
105
  it("should migrate to latest version by default", async () => {
106
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
106
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, [], {
107
107
  adapter: { type: "kysely-sqlite" },
108
108
  });
109
109
 
@@ -124,7 +124,7 @@ describe("createDatabaseFragmentForTest", () => {
124
124
 
125
125
  it("should migrate to specific version when specified", async () => {
126
126
  // Migrate to version 1 (before 'age' column was added)
127
- const { test } = await createDatabaseFragmentForTest(testFragmentDef, {
127
+ const { test } = await createDatabaseFragmentForTest(testFragmentDef, [], {
128
128
  adapter: { type: "kysely-sqlite" },
129
129
  migrateToVersion: 1,
130
130
  });
@@ -155,7 +155,7 @@ describe("createDatabaseFragmentForTest", () => {
155
155
 
156
156
  it("should allow creating user with age when migrated to version 2", async () => {
157
157
  // Explicitly migrate to version 2
158
- const { fragment, test } = await createDatabaseFragmentForTest(testFragmentDef, {
158
+ const { fragment, test } = await createDatabaseFragmentForTest(testFragmentDef, [], {
159
159
  adapter: { type: "kysely-sqlite" },
160
160
  migrateToVersion: 2,
161
161
  });
@@ -200,7 +200,7 @@ describe("createDatabaseFragmentForTest", () => {
200
200
  });
201
201
 
202
202
  it("should work with both databasePath and migrateToVersion", async () => {
203
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
203
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, [], {
204
204
  adapter: { type: "kysely-sqlite", databasePath: testDbPath },
205
205
  migrateToVersion: 2,
206
206
  });
@@ -231,7 +231,7 @@ describe("createDatabaseFragmentForTest", () => {
231
231
 
232
232
  describe("fragment initialization", () => {
233
233
  it("should provide kysely instance", async () => {
234
- const { test } = await createDatabaseFragmentForTest(testFragmentDef, {
234
+ const { test } = await createDatabaseFragmentForTest(testFragmentDef, [], {
235
235
  adapter: { type: "kysely-sqlite" },
236
236
  });
237
237
 
@@ -240,7 +240,7 @@ describe("createDatabaseFragmentForTest", () => {
240
240
  });
241
241
 
242
242
  it("should provide adapter instance", async () => {
243
- const { test } = await createDatabaseFragmentForTest(testFragmentDef, {
243
+ const { test } = await createDatabaseFragmentForTest(testFragmentDef, [], {
244
244
  adapter: { type: "kysely-sqlite" },
245
245
  });
246
246
 
@@ -249,13 +249,11 @@ describe("createDatabaseFragmentForTest", () => {
249
249
  });
250
250
 
251
251
  it("should have all standard fragment test properties", async () => {
252
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
252
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, [], {
253
253
  adapter: { type: "kysely-sqlite" },
254
254
  });
255
255
 
256
256
  expect(fragment.services).toBeDefined();
257
- expect(fragment.initRoutes).toBeDefined();
258
- expect(fragment.handler).toBeDefined();
259
257
  });
260
258
 
261
259
  it("should throw error for non-database fragment", async () => {
@@ -270,7 +268,7 @@ describe("createDatabaseFragmentForTest", () => {
270
268
 
271
269
  await expect(
272
270
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
273
- createDatabaseFragmentForTest(nonDbFragment as any, {
271
+ createDatabaseFragmentForTest(nonDbFragment as any, [], {
274
272
  adapter: { type: "kysely-sqlite" },
275
273
  }),
276
274
  ).rejects.toThrow("Fragment 'non-db-fragment' does not have a database schema");
@@ -279,10 +277,6 @@ describe("createDatabaseFragmentForTest", () => {
279
277
 
280
278
  describe("route handling with defineRoutes", () => {
281
279
  it("should handle route factory with multiple routes", async () => {
282
- const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, {
283
- adapter: { type: "kysely-sqlite" },
284
- });
285
-
286
280
  type Config = {};
287
281
  type Deps = {};
288
282
  type Services = {
@@ -338,10 +332,11 @@ describe("createDatabaseFragmentForTest", () => {
338
332
  ]);
339
333
 
340
334
  const routes = [routeFactory] as const;
341
- const [createUserRoute, getUsersRoute] = fragment.initRoutes(routes);
342
-
335
+ const { fragment } = await createDatabaseFragmentForTest(testFragmentDef, routes, {
336
+ adapter: { type: "kysely-sqlite" },
337
+ });
343
338
  // Test creating a user
344
- const createResponse = await fragment.handler(createUserRoute, {
339
+ const createResponse = await fragment.callRoute("POST", "/users", {
345
340
  body: { name: "John Doe", email: "john@example.com", age: 30 },
346
341
  });
347
342
 
@@ -356,7 +351,7 @@ describe("createDatabaseFragmentForTest", () => {
356
351
  }
357
352
 
358
353
  // Test getting users
359
- const getUsersResponse = await fragment.handler(getUsersRoute);
354
+ const getUsersResponse = await fragment.callRoute("GET", "/users");
360
355
 
361
356
  expect(getUsersResponse.type).toBe("json");
362
357
  if (getUsersResponse.type === "json") {
@@ -372,53 +367,170 @@ describe("createDatabaseFragmentForTest", () => {
372
367
  });
373
368
 
374
369
  describe("resetDatabase", () => {
375
- it("should clear all data and recreate a fresh database", async () => {
376
- // Don't destructure so we can access the updated fragment through getters after reset
377
- const result = await createDatabaseFragmentForTest(testFragmentDef, {
378
- adapter: { type: "kysely-sqlite" },
379
- });
370
+ const adapters = [
371
+ { name: "Kysely SQLite", adapter: { type: "kysely-sqlite" as const } },
372
+ { name: "Kysely PGLite", adapter: { type: "kysely-pglite" as const } },
373
+ { name: "Drizzle PGLite", adapter: { type: "drizzle-pglite" as const } },
374
+ ];
380
375
 
381
- // Create some users
382
- await result.services.createUser({
383
- name: "User 1",
384
- email: "user1@example.com",
385
- age: 25,
386
- });
387
- await result.services.createUser({
388
- name: "User 2",
389
- email: "user2@example.com",
390
- age: 30,
376
+ for (const { name, adapter } of adapters) {
377
+ describe(name, () => {
378
+ it("should clear all data and recreate a fresh database", async () => {
379
+ // Don't destructure so we can access the updated fragment through getters after reset
380
+ const result = await createDatabaseFragmentForTest(testFragmentDef, [], {
381
+ adapter,
382
+ });
383
+
384
+ // Create some users
385
+ await result.services.createUser({
386
+ name: "User 1",
387
+ email: "user1@example.com",
388
+ age: 25,
389
+ });
390
+ await result.services.createUser({
391
+ name: "User 2",
392
+ email: "user2@example.com",
393
+ age: 30,
394
+ });
395
+
396
+ // Verify users exist
397
+ let users = await result.services.getUsers();
398
+ expect(users).toHaveLength(2);
399
+
400
+ // Reset the database
401
+ await result.test.resetDatabase();
402
+
403
+ // Verify database is empty (accessing through result to get updated fragment)
404
+ users = await result.services.getUsers();
405
+ expect(users).toHaveLength(0);
406
+
407
+ // Verify we can still create new users after reset
408
+ const newUser = await result.services.createUser({
409
+ name: "User After Reset",
410
+ email: "after@example.com",
411
+ age: 35,
412
+ });
413
+
414
+ expect(newUser).toMatchObject({
415
+ id: expect.any(String),
416
+ name: "User After Reset",
417
+ email: "after@example.com",
418
+ age: 35,
419
+ });
420
+
421
+ users = await result.services.getUsers();
422
+ expect(users).toHaveLength(1);
423
+ expect(users[0]).toMatchObject(newUser);
424
+
425
+ // Cleanup
426
+ await result.test.cleanup();
427
+ }, 10000);
391
428
  });
429
+ }
430
+ });
392
431
 
393
- // Verify users exist
394
- let users = await result.services.getUsers();
395
- expect(users).toHaveLength(2);
396
-
397
- // Reset the database
398
- await result.test.resetDatabase();
399
-
400
- // Verify database is empty (accessing through result to get updated fragment)
401
- users = await result.services.getUsers();
402
- expect(users).toHaveLength(0);
403
-
404
- // Verify we can still create new users after reset
405
- const newUser = await result.services.createUser({
406
- name: "User After Reset",
407
- email: "after@example.com",
408
- age: 35,
409
- });
432
+ describe("db property access", () => {
433
+ const adapters = [
434
+ { name: "Kysely SQLite", adapter: { type: "kysely-sqlite" as const } },
435
+ { name: "Kysely PGLite", adapter: { type: "kysely-pglite" as const } },
436
+ { name: "Drizzle PGLite", adapter: { type: "drizzle-pglite" as const } },
437
+ ];
410
438
 
411
- expect(newUser).toMatchObject({
412
- id: expect.any(String),
413
- name: "User After Reset",
414
- email: "after@example.com",
415
- age: 35,
439
+ for (const { name, adapter } of adapters) {
440
+ describe(name, () => {
441
+ it("should expose db property for direct ORM queries", async () => {
442
+ const { test } = await createDatabaseFragmentForTest(testFragmentDef, [], {
443
+ adapter,
444
+ });
445
+
446
+ // Test creating a record directly using test.db
447
+ const userId = await test.db.create("users", {
448
+ name: "Direct DB User",
449
+ email: "direct@example.com",
450
+ age: 28,
451
+ });
452
+
453
+ expect(userId).toBeDefined();
454
+ expect(typeof userId.valueOf()).toBe("string");
455
+
456
+ // Test finding records using test.db
457
+ const users = await test.db.find("users", (b) =>
458
+ b.whereIndex("idx_users_all", (eb) => eb("id", "=", userId)),
459
+ );
460
+
461
+ expect(users).toHaveLength(1);
462
+ expect(users[0]).toMatchObject({
463
+ id: userId,
464
+ name: "Direct DB User",
465
+ email: "direct@example.com",
466
+ age: 28,
467
+ });
468
+
469
+ // Test findFirst using test.db
470
+ const user = await test.db.findFirst("users", (b) =>
471
+ b.whereIndex("idx_users_all", (eb) => eb("id", "=", userId)),
472
+ );
473
+
474
+ expect(user).toMatchObject({
475
+ id: userId,
476
+ name: "Direct DB User",
477
+ email: "direct@example.com",
478
+ age: 28,
479
+ });
480
+
481
+ // Cleanup
482
+ await test.cleanup();
483
+ }, 10000);
484
+
485
+ it("should maintain db property after resetDatabase", async () => {
486
+ const result = await createDatabaseFragmentForTest(testFragmentDef, [], {
487
+ adapter,
488
+ });
489
+
490
+ // Create initial data using test.db
491
+ await result.test.db.create("users", {
492
+ name: "Before Reset",
493
+ email: "before@example.com",
494
+ age: 25,
495
+ });
496
+
497
+ // Verify db works before reset
498
+ expect(result.test.db).toBeDefined();
499
+ expect(typeof result.test.db.create).toBe("function");
500
+
501
+ // Verify data exists
502
+ let users = await result.test.db.find("users");
503
+ expect(users).toHaveLength(1);
504
+
505
+ // Reset database
506
+ await result.test.resetDatabase();
507
+
508
+ // Verify database was actually reset (no data)
509
+ users = await result.test.db.find("users");
510
+ expect(users).toHaveLength(0);
511
+
512
+ // Verify we can still use the ORM after reset
513
+ const newUserId = await result.test.db.create("users", {
514
+ name: "After Reset",
515
+ email: "after@example.com",
516
+ age: 30,
517
+ });
518
+
519
+ expect(newUserId).toBeDefined();
520
+
521
+ const newUsers = await result.test.db.find("users");
522
+ expect(newUsers).toHaveLength(1);
523
+ expect(newUsers[0]).toMatchObject({
524
+ name: "After Reset",
525
+ email: "after@example.com",
526
+ age: 30,
527
+ });
528
+
529
+ // Cleanup
530
+ await result.test.cleanup();
531
+ }, 10000);
416
532
  });
417
-
418
- users = await result.services.getUsers();
419
- expect(users).toHaveLength(1);
420
- expect(users[0]).toMatchObject(newUser);
421
- });
533
+ }
422
534
  });
423
535
 
424
536
  describe("multiple adapters with auth-like schema", () => {
@@ -475,57 +587,49 @@ describe("createDatabaseFragmentForTest", () => {
475
587
 
476
588
  for (const { name, adapter } of adapters) {
477
589
  describe(name, () => {
478
- it(
479
- "should create user and session",
480
- async () => {
481
- const { fragment, test } = await createDatabaseFragmentForTest(authFragmentDef, {
482
- adapter,
483
- });
484
-
485
- // Create a user
486
- const user = await fragment.services.createUser("test@test.com", "hashed-password");
487
- expect(user).toMatchObject({
488
- id: expect.any(String),
489
- email: "test@test.com",
490
- passwordHash: "hashed-password",
491
- });
492
-
493
- // Create a session for the user
494
- const session = await fragment.services.createSession(user.id);
495
- expect(session).toMatchObject({
496
- id: expect.any(String),
497
- userId: user.id,
498
- expiresAt: expect.any(Date),
499
- });
500
-
501
- // Find user by email
502
- const foundUser = await fragment.services.getUserByEmail("test@test.com");
503
- expect(foundUser).toMatchObject({
504
- id: user.id,
505
- email: "test@test.com",
506
- passwordHash: "hashed-password",
507
- });
508
-
509
- // Cleanup
510
- await test.cleanup();
511
- },
512
- { timeout: 10000 },
513
- );
514
-
515
- it(
516
- "should return null when user not found",
517
- async () => {
518
- const { fragment, test } = await createDatabaseFragmentForTest(authFragmentDef, {
519
- adapter,
520
- });
521
-
522
- const notFound = await fragment.services.getUserByEmail("nonexistent@test.com");
523
- expect(notFound).toBeNull();
524
-
525
- await test.cleanup();
526
- },
527
- { timeout: 10000 },
528
- );
590
+ it("should create user and session", async () => {
591
+ const { fragment, test } = await createDatabaseFragmentForTest(authFragmentDef, [], {
592
+ adapter,
593
+ });
594
+
595
+ // Create a user
596
+ const user = await fragment.services.createUser("test@test.com", "hashed-password");
597
+ expect(user).toMatchObject({
598
+ id: expect.any(String),
599
+ email: "test@test.com",
600
+ passwordHash: "hashed-password",
601
+ });
602
+
603
+ // Create a session for the user
604
+ const session = await fragment.services.createSession(user.id);
605
+ expect(session).toMatchObject({
606
+ id: expect.any(String),
607
+ userId: user.id,
608
+ expiresAt: expect.any(Date),
609
+ });
610
+
611
+ // Find user by email
612
+ const foundUser = await fragment.services.getUserByEmail("test@test.com");
613
+ expect(foundUser).toMatchObject({
614
+ id: user.id,
615
+ email: "test@test.com",
616
+ passwordHash: "hashed-password",
617
+ });
618
+
619
+ // Cleanup
620
+ await test.cleanup();
621
+ }, 10000);
622
+
623
+ it("should return null when user not found", async () => {
624
+ const { fragment, test } = await createDatabaseFragmentForTest(authFragmentDef, [], {
625
+ adapter,
626
+ });
627
+
628
+ const notFound = await fragment.services.getUserByEmail("nonexistent@test.com");
629
+ expect(notFound).toBeNull();
630
+
631
+ await test.cleanup();
632
+ }, 10000);
529
633
  });
530
634
  }
531
635
  });
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  } from "@fragno-dev/core/test";
7
7
  import type { FragnoPublicConfig } from "@fragno-dev/core/api/fragment-instantiation";
8
8
  import type { FragmentDefinition } from "@fragno-dev/core/api/fragment-builder";
9
+ import type { AnyRouteOrFactory, FlattenRouteFactories } from "@fragno-dev/core/api/route";
9
10
  import {
10
11
  createAdapter,
11
12
  type SupportedAdapter,
@@ -14,15 +15,16 @@ import {
14
15
  type KyselyPgliteAdapter,
15
16
  type DrizzlePgliteAdapter,
16
17
  } from "./adapters";
18
+ import type { FragnoRouteConfig } from "@fragno-dev/core";
19
+ import type { HTTPMethod } from "@fragno-dev/core/api";
20
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
17
21
 
18
22
  // Re-export utilities from @fragno-dev/core/test
19
23
  export {
20
24
  createFragmentForTest,
21
- type TestResponse,
22
25
  type CreateFragmentForTestOptions,
23
26
  type RouteHandlerInputOptions,
24
27
  type FragmentForTest,
25
- type InitRoutesOverrides,
26
28
  } from "@fragno-dev/core/test";
27
29
 
28
30
  // Re-export adapter types
@@ -64,23 +66,32 @@ export interface DatabaseFragmentTestResult<
64
66
  TAdditionalContext extends Record<string, unknown>,
65
67
  TOptions extends FragnoPublicConfig,
66
68
  TAdapter extends SupportedAdapter,
69
+ TRoutes extends readonly FragnoRouteConfig<
70
+ HTTPMethod,
71
+ string,
72
+ StandardSchemaV1 | undefined,
73
+ StandardSchemaV1 | undefined,
74
+ string,
75
+ string
76
+ >[],
67
77
  > {
68
- readonly fragment: FragmentForTest<TConfig, TDeps, TServices, TAdditionalContext, TOptions>;
69
- readonly services: TServices;
70
- readonly initRoutes: FragmentForTest<
78
+ readonly fragment: FragmentForTest<
71
79
  TConfig,
72
80
  TDeps,
73
81
  TServices,
74
82
  TAdditionalContext,
75
- TOptions
76
- >["initRoutes"];
77
- readonly handler: FragmentForTest<
83
+ TOptions,
84
+ TRoutes
85
+ >;
86
+ readonly services: TServices;
87
+ readonly callRoute: FragmentForTest<
78
88
  TConfig,
79
89
  TDeps,
80
90
  TServices,
81
91
  TAdditionalContext,
82
- TOptions
83
- >["handler"];
92
+ TOptions,
93
+ TRoutes
94
+ >["callRoute"];
84
95
  readonly config: TConfig;
85
96
  readonly deps: TDeps;
86
97
  readonly additionalContext: TAdditionalContext;
@@ -95,11 +106,13 @@ export async function createDatabaseFragmentForTest<
95
106
  const TOptions extends FragnoPublicConfig,
96
107
  const TSchema extends AnySchema,
97
108
  const TAdapter extends SupportedAdapter,
109
+ const TRoutesOrFactories extends readonly AnyRouteOrFactory[],
98
110
  >(
99
111
  fragmentBuilder: {
100
112
  definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;
101
113
  $requiredOptions: TOptions;
102
114
  },
115
+ routesOrFactories: TRoutesOrFactories,
103
116
  options: CreateDatabaseFragmentForTestOptions<
104
117
  TConfig,
105
118
  TDeps,
@@ -109,7 +122,15 @@ export async function createDatabaseFragmentForTest<
109
122
  TAdapter
110
123
  >,
111
124
  ): Promise<
112
- DatabaseFragmentTestResult<TConfig, TDeps, TServices, TAdditionalContext, TOptions, TAdapter>
125
+ DatabaseFragmentTestResult<
126
+ TConfig,
127
+ TDeps,
128
+ TServices,
129
+ TAdditionalContext,
130
+ TOptions,
131
+ TAdapter,
132
+ FlattenRouteFactories<TRoutesOrFactories>
133
+ >
113
134
  > {
114
135
  const {
115
136
  adapter: adapterConfig,
@@ -151,10 +172,10 @@ export async function createDatabaseFragmentForTest<
151
172
  databaseAdapter: adapter,
152
173
  } as unknown as TOptions;
153
174
 
154
- // Safe cast: If config is not provided, we pass undefined as TConfig.
155
- // The base createFragmentForTest expects config: TConfig, but if TConfig allows undefined
156
- // or if the fragment doesn't use config in its dependencies function, this will work correctly.
157
- let fragment = createFragmentForTest(fragmentBuilder, {
175
+ let fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {
176
+ // Safe cast: If config is not provided, we pass undefined as TConfig.
177
+ // The base createFragmentForTest expects config: TConfig, but if TConfig allows undefined
178
+ // or if the fragment doesn't use config in its dependencies function, this will work correctly.
158
179
  config: config as TConfig,
159
180
  options: mergedOptions,
160
181
  deps,
@@ -170,6 +191,13 @@ export async function createDatabaseFragmentForTest<
170
191
  // that may not exist depending on the adapter type
171
192
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
193
  const testContext: any = Object.create(originalTestContext, {
194
+ db: {
195
+ get() {
196
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
197
+ return (originalTestContext as any).db;
198
+ },
199
+ enumerable: true,
200
+ },
173
201
  kysely: {
174
202
  get() {
175
203
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -201,7 +229,7 @@ export async function createDatabaseFragmentForTest<
201
229
  databaseAdapter: originalTestContext.adapter,
202
230
  } as unknown as TOptions;
203
231
 
204
- fragment = createFragmentForTest(fragmentBuilder, {
232
+ fragment = createFragmentForTest(fragmentBuilder, routesOrFactories, {
205
233
  config: config as TConfig,
206
234
  options: mergedOptions,
207
235
  deps,
@@ -227,11 +255,8 @@ export async function createDatabaseFragmentForTest<
227
255
  get services() {
228
256
  return fragment.services;
229
257
  },
230
- get initRoutes() {
231
- return fragment.initRoutes;
232
- },
233
- get handler() {
234
- return fragment.handler;
258
+ get callRoute() {
259
+ return fragment.callRoute;
235
260
  },
236
261
  get config() {
237
262
  return fragment.config;