@fragno-dev/test 0.1.14 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @fragno-dev/test@0.1.14 build /home/runner/work/fragno/fragno/packages/fragno-test
2
+ > @fragno-dev/test@1.0.0 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
@@ -8,16 +8,16 @@
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
10
  ℹ dist/index.js  0.71 kB │ gzip: 0.40 kB
11
- ℹ dist/db-test.js.map 23.72 kB │ gzip: 5.83 kB
12
- ℹ dist/adapters.js.map 18.56 kB │ gzip: 4.04 kB
13
- ℹ dist/adapters.js  7.97 kB │ gzip: 1.74 kB
14
- ℹ dist/db-test.js  7.25 kB │ gzip: 2.14 kB
11
+ ℹ dist/db-test.js.map 24.19 kB │ gzip: 5.91 kB
12
+ ℹ dist/adapters.js.map 16.98 kB │ gzip: 3.34 kB
13
+ ℹ dist/adapters.js  7.53 kB │ gzip: 1.45 kB
14
+ ℹ dist/db-test.js  7.43 kB │ gzip: 2.18 kB
15
15
  ℹ dist/db-test.d.ts.map  3.19 kB │ gzip: 1.47 kB
16
- ℹ dist/index.js.map  2.44 kB │ gzip: 0.96 kB
16
+ ℹ dist/index.js.map  2.46 kB │ gzip: 0.96 kB
17
17
  ℹ dist/index.d.ts.map  0.55 kB │ gzip: 0.31 kB
18
18
  ℹ dist/adapters.d.ts.map  0.42 kB │ gzip: 0.27 kB
19
- ℹ dist/index.d.ts  1.79 kB │ gzip: 0.68 kB
20
- ℹ dist/db-test.d.ts  6.67 kB │ gzip: 1.80 kB
21
- ℹ dist/adapters.d.ts  0.95 kB │ gzip: 0.37 kB
22
- ℹ 12 files, total: 74.22 kB
23
- ✔ Build complete in 13633ms
19
+ ℹ dist/index.d.ts  1.81 kB │ gzip: 0.68 kB
20
+ ℹ dist/db-test.d.ts  6.68 kB │ gzip: 1.80 kB
21
+ ℹ dist/adapters.d.ts  0.96 kB │ gzip: 0.38 kB
22
+ ℹ 12 files, total: 72.92 kB
23
+ ✔ Build complete in 13104ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @fragno-dev/test
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - f9ae2d3: fix: database namespace generation
8
+ - Updated dependencies [8429960]
9
+ - Updated dependencies [4d897c9]
10
+ - Updated dependencies [a46b59c]
11
+ - Updated dependencies [bc072dd]
12
+ - Updated dependencies [e46d2a7]
13
+ - Updated dependencies [fcce048]
14
+ - Updated dependencies [147bdd6]
15
+ - Updated dependencies [f9ae2d3]
16
+ - Updated dependencies [f3b7084]
17
+ - Updated dependencies [c3870ec]
18
+ - Updated dependencies [75e298f]
19
+ - @fragno-dev/db@0.2.0
20
+ - @fragno-dev/core@0.1.11
21
+
3
22
  ## 0.1.14
4
23
 
5
24
  ### Patch Changes
@@ -2,7 +2,7 @@ import "./index.js";
2
2
  import { Kysely } from "kysely";
3
3
  import { drizzle } from "drizzle-orm/pglite";
4
4
  import { AnySchema } from "@fragno-dev/db/schema";
5
- import { AbstractQuery } from "@fragno-dev/db/query";
5
+ import { SimpleQueryInterface } from "@fragno-dev/db/query";
6
6
 
7
7
  //#region src/adapters.d.ts
8
8
  interface KyselySqliteAdapter {
package/dist/adapters.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { createCommonTestContextMethods } from "./index.js";
2
- import { createRequire } from "node:module";
3
2
  import { Kysely } from "kysely";
4
3
  import { SQLocalKysely } from "sqlocal/kysely";
5
4
  import { KyselyPGlite } from "kysely-pglite";
@@ -7,9 +6,10 @@ import { drizzle } from "drizzle-orm/pglite";
7
6
  import { PGlite } from "@electric-sql/pglite";
8
7
  import { KyselyAdapter } from "@fragno-dev/db/adapters/kysely";
9
8
  import { DrizzleAdapter } from "@fragno-dev/db/adapters/drizzle";
10
- import { mkdir, rm, writeFile } from "node:fs/promises";
11
- import { join } from "node:path";
9
+ import { rm } from "node:fs/promises";
12
10
  import { existsSync } from "node:fs";
11
+ import { PGLiteDriverConfig, SQLocalDriverConfig } from "@fragno-dev/db/drivers";
12
+ import { internalFragmentDef } from "@fragno-dev/db";
13
13
 
14
14
  //#region src/adapters.ts
15
15
  /**
@@ -21,13 +21,14 @@ async function createKyselySqliteAdapter(_config, schemas) {
21
21
  const { dialect } = new SQLocalKysely(":memory:");
22
22
  const kysely$1 = new Kysely({ dialect });
23
23
  const adapter$1 = new KyselyAdapter({
24
- db: kysely$1,
25
- provider: "sqlite"
24
+ dialect,
25
+ driverConfig: new SQLocalDriverConfig()
26
26
  });
27
27
  const ormMap$1 = /* @__PURE__ */ new Map();
28
28
  for (const { schema, namespace, migrateToVersion } of schemas) {
29
- const migrator = adapter$1.createMigrationEngine(schema, namespace);
30
- await (migrateToVersion ? await migrator.prepareMigrationTo(migrateToVersion, { updateSettings: false }) : await migrator.prepareMigration({ updateSettings: false })).execute();
29
+ const preparedMigrations = adapter$1.prepareMigrations(schema, namespace);
30
+ if (migrateToVersion !== void 0) await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
31
+ else await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
31
32
  const orm = adapter$1.createQueryEngine(schema, namespace);
32
33
  ormMap$1.set(namespace, orm);
33
34
  }
@@ -77,13 +78,14 @@ async function createKyselyPgliteAdapter(config, schemas) {
77
78
  const kyselyPglite$1 = await KyselyPGlite.create(databasePath);
78
79
  const kysely$1 = new Kysely({ dialect: kyselyPglite$1.dialect });
79
80
  const adapter$1 = new KyselyAdapter({
80
- db: kysely$1,
81
- provider: "postgresql"
81
+ dialect: kyselyPglite$1.dialect,
82
+ driverConfig: new PGLiteDriverConfig()
82
83
  });
83
84
  const ormMap$1 = /* @__PURE__ */ new Map();
84
85
  for (const { schema, namespace, migrateToVersion } of schemas) {
85
- const migrator = adapter$1.createMigrationEngine(schema, namespace);
86
- await (migrateToVersion ? await migrator.prepareMigrationTo(migrateToVersion, { updateSettings: false }) : await migrator.prepareMigration({ updateSettings: false })).execute();
86
+ const preparedMigrations = adapter$1.prepareMigrations(schema, namespace);
87
+ if (migrateToVersion !== void 0) await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
88
+ else await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
87
89
  const orm = adapter$1.createQueryEngine(schema, namespace);
88
90
  ormMap$1.set(namespace, orm);
89
91
  }
@@ -138,52 +140,34 @@ async function createKyselyPgliteAdapter(config, schemas) {
138
140
  */
139
141
  async function createDrizzlePgliteAdapter(config, schemas) {
140
142
  const databasePath = config.databasePath;
141
- const { generateDrizzleJson, generateMigration } = createRequire(import.meta.url)("drizzle-kit/api");
142
- const { generateSchema } = await import("@fragno-dev/db/adapters/drizzle/generate");
143
- const writeAndLoadSchema = async () => {
144
- const testDir = join(import.meta.dirname, "_generated", "drizzle-test");
145
- await mkdir(testDir, { recursive: true }).catch(() => {});
146
- const schemaFilePath = join(testDir, `test-schema-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.ts`);
147
- await writeFile(schemaFilePath, generateSchema(schemas.map(({ schema, namespace }) => ({
148
- namespace: namespace ?? "",
149
- schema
150
- })), "postgresql"), "utf-8");
151
- const schemaModule = await import(`${schemaFilePath}?t=${Date.now()}`);
152
- const cleanup$1 = async () => {
153
- await rm(testDir, {
154
- recursive: true,
155
- force: true
156
- });
157
- };
158
- return {
159
- schemaModule,
160
- cleanup: cleanup$1
161
- };
162
- };
163
143
  const createDatabase = async () => {
164
- const { schemaModule, cleanup: cleanup$1 } = await writeAndLoadSchema();
165
- const pglite$1 = new PGlite(databasePath);
166
- const db = drizzle(pglite$1, { schema: schemaModule });
167
- const migrationStatements = await generateMigration(generateDrizzleJson({}), generateDrizzleJson(schemaModule));
168
- for (const statement of migrationStatements) await db.execute(statement);
144
+ const pglite = new PGlite(databasePath);
145
+ const { dialect } = new KyselyPGlite(pglite);
169
146
  const adapter$1 = new DrizzleAdapter({
170
- db: () => db,
171
- provider: "postgresql"
147
+ dialect,
148
+ driverConfig: new PGLiteDriverConfig()
172
149
  });
173
150
  const ormMap$1 = /* @__PURE__ */ new Map();
174
- for (const { schema, namespace } of schemas) {
151
+ const databaseDeps = internalFragmentDef.dependencies?.({
152
+ config: {},
153
+ options: { databaseAdapter: adapter$1 }
154
+ });
155
+ if (databaseDeps?.schema) await adapter$1.prepareMigrations(databaseDeps.schema, databaseDeps.namespace).executeWithDriver(adapter$1.driver, 0);
156
+ for (const { schema, namespace, migrateToVersion } of schemas) {
157
+ const preparedMigrations = adapter$1.prepareMigrations(schema, namespace);
158
+ if (migrateToVersion !== void 0) await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
159
+ else await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
175
160
  const orm = adapter$1.createQueryEngine(schema, namespace);
176
161
  ormMap$1.set(namespace, orm);
177
162
  }
178
163
  return {
179
- drizzle: db,
164
+ drizzle: drizzle(pglite),
180
165
  adapter: adapter$1,
181
- pglite: pglite$1,
182
- cleanup: cleanup$1,
166
+ pglite,
183
167
  ormMap: ormMap$1
184
168
  };
185
169
  };
186
- const { drizzle: drizzleDb, adapter, pglite, cleanup: schemaCleanup, ormMap } = await createDatabase();
170
+ const { drizzle: drizzleDb, adapter, ormMap } = await createDatabase();
187
171
  const resetDatabase = async () => {
188
172
  if (databasePath && databasePath !== ":memory:") throw new Error("resetDatabase is only supported for in-memory databases");
189
173
  for (const { schema, namespace } of schemas) {
@@ -195,8 +179,7 @@ async function createDrizzlePgliteAdapter(config, schemas) {
195
179
  }
196
180
  };
197
181
  const cleanup = async () => {
198
- await pglite.close();
199
- await schemaCleanup();
182
+ await adapter.close();
200
183
  if (databasePath && databasePath !== ":memory:" && existsSync(databasePath)) await rm(databasePath, {
201
184
  recursive: true,
202
185
  force: true
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.js","names":["kysely","adapter","ormMap","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\";\nimport type { BaseTestContext } from \".\";\nimport { createCommonTestContextMethods } from \".\";\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// Schema configuration for multi-schema adapters\nexport interface SchemaConfig {\n schema: AnySchema;\n namespace: string;\n migrateToVersion?: number;\n}\n\n// Internal test context extends BaseTestContext with getOrm (not exposed publicly)\ninterface InternalTestContext extends BaseTestContext {\n getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;\n}\n\n// Conditional return types based on adapter (adapter-specific properties only)\nexport type AdapterContext<T extends SupportedAdapter> = T extends\n | KyselySqliteAdapter\n | KyselyPgliteAdapter\n ? {\n readonly kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n : T extends DrizzlePgliteAdapter\n ? {\n readonly drizzle: ReturnType<typeof drizzle<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n : never;\n\n// Factory function return type\ninterface AdapterFactoryResult<T extends SupportedAdapter> {\n testContext: InternalTestContext & AdapterContext<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 * Supports multiple schemas with separate namespaces\n */\nexport async function createKyselySqliteAdapter(\n _config: KyselySqliteAdapter,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<KyselySqliteAdapter>> {\n // Helper to create a new database instance and run migrations for all schemas\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 for all schemas in order\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, AbstractQuery<any, any>>();\n\n for (const { schema, namespace, migrateToVersion } of schemas) {\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 and store in map\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n return { kysely, adapter, ormMap };\n };\n\n // Create initial database\n let { kysely, adapter, ormMap } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n // For SQLite, truncate all tables by deleting rows\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await kysely.deleteFrom(physicalTableName).execute();\n }\n }\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\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 * Supports multiple schemas with separate namespaces\n */\nexport async function createKyselyPgliteAdapter(\n config: KyselyPgliteAdapter,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<KyselyPgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Helper to create a new database instance and run migrations for all schemas\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 for all schemas in order\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, AbstractQuery<any, any>>();\n\n for (const { schema, namespace, migrateToVersion } of schemas) {\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 and store in map\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n return { kysely, adapter, kyselyPglite, ormMap };\n };\n\n // Create initial database\n const { kysely, adapter, kyselyPglite, ormMap } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n if (databasePath && databasePath !== \":memory:\") {\n throw new Error(\"resetDatabase is only supported for in-memory databases\");\n }\n\n // Truncate all tables\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await kysely.deleteFrom(physicalTableName).execute();\n }\n }\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\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 * Supports multiple schemas with separate namespaces\n */\nexport async function createDrizzlePgliteAdapter(\n config: DrizzlePgliteAdapter,\n schemas: SchemaConfig[],\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 // Combine all schemas into a single Drizzle schema with namespaced tables\n const schemaConfigs = schemas.map(({ schema, namespace }) => ({\n namespace: namespace ?? \"\",\n schema,\n }));\n\n const drizzleSchemaTs = generateSchema(schemaConfigs, \"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 for all schemas\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 instances for each schema and store in map\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, AbstractQuery<any, any>>();\n\n for (const { schema, namespace } of schemas) {\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n return { drizzle: db, adapter, pglite, cleanup, ormMap };\n };\n\n // Create initial database\n const {\n drizzle: drizzleDb,\n adapter,\n pglite,\n cleanup: schemaCleanup,\n ormMap,\n } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n if (databasePath && databasePath !== \":memory:\") {\n throw new Error(\"resetDatabase is only supported for in-memory databases\");\n }\n\n // Truncate all tables by deleting rows\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await drizzleDb.execute(`DELETE FROM \"${physicalTableName}\"`);\n }\n }\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get drizzle() {\n return drizzleDb;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create adapter based on configuration\n * Supports multiple schemas with separate namespaces\n */\nexport async function createAdapter<T extends SupportedAdapter>(\n adapterConfig: T,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<T>> {\n if (adapterConfig.type === \"kysely-sqlite\") {\n return createKyselySqliteAdapter(adapterConfig, schemas) as Promise<AdapterFactoryResult<T>>;\n } else if (adapterConfig.type === \"kysely-pglite\") {\n return createKyselyPgliteAdapter(adapterConfig, schemas) as Promise<AdapterFactoryResult<T>>;\n } else if (adapterConfig.type === \"drizzle-pglite\") {\n return createDrizzlePgliteAdapter(adapterConfig, schemas) 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","ormMap","kyselyPglite"],"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 { rm } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport type { BaseTestContext } from \".\";\nimport { createCommonTestContextMethods } from \".\";\nimport { PGLiteDriverConfig, SQLocalDriverConfig } from \"@fragno-dev/db/drivers\";\nimport { internalFragmentDef } from \"@fragno-dev/db\";\nimport type { SimpleQueryInterface } from \"@fragno-dev/db/query\";\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// Schema configuration for multi-schema adapters\nexport interface SchemaConfig {\n schema: AnySchema;\n namespace: string;\n migrateToVersion?: number;\n}\n\n// Internal test context extends BaseTestContext with getOrm (not exposed publicly)\ninterface InternalTestContext extends BaseTestContext {\n getOrm: <TSchema extends AnySchema>(namespace: string) => SimpleQueryInterface<TSchema>;\n}\n\n// Conditional return types based on adapter (adapter-specific properties only)\nexport type AdapterContext<T extends SupportedAdapter> = T extends\n | KyselySqliteAdapter\n | KyselyPgliteAdapter\n ? {\n readonly kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n : T extends DrizzlePgliteAdapter\n ? {\n readonly drizzle: ReturnType<typeof drizzle<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n : never;\n\n// Factory function return type\ninterface AdapterFactoryResult<T extends SupportedAdapter> {\n testContext: InternalTestContext & AdapterContext<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 * Supports multiple schemas with separate namespaces\n */\nexport async function createKyselySqliteAdapter(\n _config: KyselySqliteAdapter,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<KyselySqliteAdapter>> {\n // Helper to create a new database instance and run migrations for all schemas\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 dialect,\n driverConfig: new SQLocalDriverConfig(),\n });\n\n // Run migrations for all schemas in order\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, SimpleQueryInterface<any, any>>();\n\n for (const { schema, namespace, migrateToVersion } of schemas) {\n // Run migrations\n const preparedMigrations = adapter.prepareMigrations(schema, namespace);\n if (migrateToVersion !== undefined) {\n await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });\n } else {\n await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });\n }\n\n // Create ORM instance and store in map\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n return { kysely, adapter, ormMap };\n };\n\n // Create initial database\n let { kysely, adapter, ormMap } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n // For SQLite, truncate all tables by deleting rows\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await kysely.deleteFrom(physicalTableName).execute();\n }\n }\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\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 * Supports multiple schemas with separate namespaces\n */\nexport async function createKyselyPgliteAdapter(\n config: KyselyPgliteAdapter,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<KyselyPgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Helper to create a new database instance and run migrations for all schemas\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 dialect: kyselyPglite.dialect,\n driverConfig: new PGLiteDriverConfig(),\n });\n\n // Run migrations for all schemas in order\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, SimpleQueryInterface<any, any>>();\n\n for (const { schema, namespace, migrateToVersion } of schemas) {\n // Run migrations\n const preparedMigrations = adapter.prepareMigrations(schema, namespace);\n if (migrateToVersion !== undefined) {\n await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });\n } else {\n await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });\n }\n\n // Create ORM instance and store in map\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n return { kysely, adapter, kyselyPglite, ormMap };\n };\n\n // Create initial database\n const { kysely, adapter, kyselyPglite, ormMap } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n if (databasePath && databasePath !== \":memory:\") {\n throw new Error(\"resetDatabase is only supported for in-memory databases\");\n }\n\n // Truncate all tables\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await kysely.deleteFrom(physicalTableName).execute();\n }\n }\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get kysely() {\n return kysely;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\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 * Supports multiple schemas with separate namespaces\n */\nexport async function createDrizzlePgliteAdapter(\n config: DrizzlePgliteAdapter,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<DrizzlePgliteAdapter>> {\n const databasePath = config.databasePath;\n\n // Helper to create a new database instance and run migrations for all schemas\n const createDatabase = async () => {\n const pglite = new PGlite(databasePath);\n\n const { dialect } = new KyselyPGlite(pglite);\n\n const adapter = new DrizzleAdapter({\n dialect,\n driverConfig: new PGLiteDriverConfig(),\n });\n\n // Run migrations for all schemas\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ormMap = new Map<string, SimpleQueryInterface<any, any>>();\n\n const databaseDeps = internalFragmentDef.dependencies?.({\n config: {},\n options: { databaseAdapter: adapter },\n });\n if (databaseDeps?.schema) {\n const migrations = adapter.prepareMigrations(databaseDeps.schema, databaseDeps.namespace);\n await migrations.executeWithDriver(adapter.driver, 0);\n }\n\n for (const { schema, namespace, migrateToVersion } of schemas) {\n const preparedMigrations = adapter.prepareMigrations(schema, namespace);\n if (migrateToVersion !== undefined) {\n await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });\n } else {\n await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });\n }\n\n // Create ORM instance and store in map\n const orm = adapter.createQueryEngine(schema, namespace);\n ormMap.set(namespace, orm);\n }\n\n // Create Drizzle instance for backward compatibility (if needed)\n const db = drizzle(pglite) as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n return { drizzle: db, adapter, pglite, ormMap };\n };\n\n // Create initial database\n const { drizzle: drizzleDb, adapter, ormMap } = await createDatabase();\n\n // Reset database function - truncates all tables (only supported for in-memory databases)\n const resetDatabase = async () => {\n if (databasePath && databasePath !== \":memory:\") {\n throw new Error(\"resetDatabase is only supported for in-memory databases\");\n }\n\n // Truncate all tables by deleting rows\n for (const { schema, namespace } of schemas) {\n const mapper = adapter.createTableNameMapper(namespace);\n for (const tableName of Object.keys(schema.tables)) {\n const physicalTableName = mapper.toPhysical(tableName);\n await drizzleDb.execute(`DELETE FROM \"${physicalTableName}\"`);\n }\n }\n };\n\n // Cleanup function - closes connections and deletes database directory\n const cleanup = async () => {\n // Close the adapter (which will handle closing the underlying database connection)\n await adapter.close();\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 const commonMethods = createCommonTestContextMethods(ormMap);\n\n return {\n testContext: {\n get drizzle() {\n return drizzleDb;\n },\n get adapter() {\n return adapter;\n },\n ...commonMethods,\n resetDatabase,\n cleanup,\n },\n get adapter() {\n return adapter;\n },\n };\n}\n\n/**\n * Create adapter based on configuration\n * Supports multiple schemas with separate namespaces\n */\nexport async function createAdapter<T extends SupportedAdapter>(\n adapterConfig: T,\n schemas: SchemaConfig[],\n): Promise<AdapterFactoryResult<T>> {\n if (adapterConfig.type === \"kysely-sqlite\") {\n return createKyselySqliteAdapter(adapterConfig, schemas) as Promise<AdapterFactoryResult<T>>;\n } else if (adapterConfig.type === \"kysely-pglite\") {\n return createKyselyPgliteAdapter(adapterConfig, schemas) as Promise<AdapterFactoryResult<T>>;\n } else if (adapterConfig.type === \"drizzle-pglite\") {\n return createDrizzlePgliteAdapter(adapterConfig, schemas) 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/db-test.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { AdapterContext, SupportedAdapter } from "./adapters.js";
2
2
  import { BaseTestContext } from "./index.js";
3
- import { AnySchema } from "@fragno-dev/db/schema";
4
- import { AbstractQuery } from "@fragno-dev/db/query";
5
3
  import { DatabaseAdapter } from "@fragno-dev/db";
4
+ import { AnySchema } from "@fragno-dev/db/schema";
5
+ import { SimpleQueryInterface } from "@fragno-dev/db/query";
6
6
  import { FragmentInstantiationBuilder, FragnoInstantiatedFragment, FragnoPublicConfig, RequestThisContext } from "@fragno-dev/core";
7
7
  import { AnyRouteOrFactory, FlattenRouteFactories } from "@fragno-dev/core/route";
8
8
 
@@ -19,7 +19,7 @@ TSchema$1 extends AnySchema, TLinkedFragments extends AnyLinkedFragments = {}> {
19
19
  services: TServices;
20
20
  deps: TDeps;
21
21
  callRoute: FragnoInstantiatedFragment<TRoutes, TDeps, TServices, TServiceThisContext, THandlerThisContext, TRequestStorage, FragnoPublicConfig, TLinkedFragments>["callRoute"];
22
- db: AbstractQuery<TSchema$1>;
22
+ db: SimpleQueryInterface<TSchema$1>;
23
23
  }
24
24
  type AnyFragmentResult = FragmentResult<any,
25
25
  // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -1 +1 @@
1
- {"version":3,"file":"db-test.d.ts","names":[],"sources":["../src/db-test.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"db-test.d.ts","names":[],"sources":["../src/db-test.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/db-test.js CHANGED
@@ -44,7 +44,7 @@ var DatabaseFragmentsTestBuilder = class {
44
44
  const builder = fragmentConfig.builder;
45
45
  const definition = builder.definition;
46
46
  let schema;
47
- const namespace = definition.name + "-db";
47
+ let namespace;
48
48
  if (definition.dependencies) try {
49
49
  const mockAdapter = {
50
50
  createQueryEngine: () => ({ schema: null }),
@@ -55,12 +55,16 @@ var DatabaseFragmentsTestBuilder = class {
55
55
  config: actualConfig,
56
56
  options: { databaseAdapter: mockAdapter }
57
57
  });
58
- if (deps && typeof deps === "object" && "schema" in deps) schema = deps.schema;
58
+ if (deps && typeof deps === "object" && "schema" in deps) {
59
+ schema = deps.schema;
60
+ namespace = deps.namespace;
61
+ }
59
62
  } catch (error) {
60
63
  const errorMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "Unknown error";
61
64
  throw new Error(`Failed to extract schema from fragment '${definition.name}'.\nOriginal error: ${errorMessage}\n\nMake sure the fragment is a database fragment using defineFragment().extend(withDatabase(schema)).`);
62
65
  }
63
66
  if (!schema) throw new Error(`Fragment '${definition.name}' does not have a database schema. Make sure you're using defineFragment().extend(withDatabase(schema)).`);
67
+ if (!namespace) throw new Error(`Fragment '${definition.name}' does not have a namespace in dependencies. This should be automatically provided by withDatabase().`);
64
68
  schemaConfigs.push({
65
69
  schema,
66
70
  namespace,
@@ -1 +1 @@
1
- {"version":3,"file":"db-test.js","names":["#adapter","#fragments","schemaConfigs: SchemaConfig[]","builderConfigs: Array<{ config: any; routes: any; options: any }>","schema: AnySchema | undefined","providedServicesByName: Record<string, { service: any; orm: any }>","fragmentResults: any[]","serviceImplementations: Record<string, any>","fragmentResults"],"sources":["../src/db-test.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type {\n RequestThisContext,\n FragnoPublicConfig,\n FragmentInstantiationBuilder,\n FragnoInstantiatedFragment,\n FragmentDefinition,\n} from \"@fragno-dev/core\";\nimport type { AnyRouteOrFactory, FlattenRouteFactories } from \"@fragno-dev/core/route\";\nimport {\n createAdapter,\n type SupportedAdapter,\n type AdapterContext,\n type SchemaConfig,\n} from \"./adapters\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db\";\nimport type { AbstractQuery } from \"@fragno-dev/db/query\";\nimport type { BaseTestContext } from \".\";\n\n// BoundServices is an internal type that strips 'this' parameters from service methods\n// It's used to represent services after they've been bound to a context\ntype BoundServices<T> = {\n [K in keyof T]: T[K] extends (this: any, ...args: infer A) => infer R // eslint-disable-line @typescript-eslint/no-explicit-any\n ? (...args: A) => R\n : T[K] extends Record<string, unknown>\n ? BoundServices<T[K]>\n : T[K];\n};\n\n// Extract the schema type from database fragment dependencies\n// Database fragments have ImplicitDatabaseDependencies<TSchema> which includes `schema: TSchema`\ntype ExtractSchemaFromDeps<TDeps> = TDeps extends { schema: infer TSchema extends AnySchema }\n ? TSchema\n : AnySchema;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyLinkedFragments = Record<string, any>;\n\n// Forward declarations for recursive type references\ninterface FragmentResult<\n TDeps,\n TServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutes extends readonly any[], // eslint-disable-line @typescript-eslint/no-explicit-any\n TSchema extends AnySchema,\n TLinkedFragments extends AnyLinkedFragments = {},\n> {\n fragment: FragnoInstantiatedFragment<\n TRoutes,\n TDeps,\n TServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FragnoPublicConfig,\n TLinkedFragments\n >;\n services: TServices;\n deps: TDeps;\n callRoute: FragnoInstantiatedFragment<\n TRoutes,\n TDeps,\n TServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FragnoPublicConfig,\n TLinkedFragments\n >[\"callRoute\"];\n db: AbstractQuery<TSchema>;\n}\n\n// Safe: Catch-all for any fragment result type\ntype AnyFragmentResult = FragmentResult<\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any // eslint-disable-line @typescript-eslint/no-explicit-any\n>;\n\n// Safe: Catch-all for any fragment builder config type\ntype AnyFragmentBuilderConfig = FragmentBuilderConfig<\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any // eslint-disable-line @typescript-eslint/no-explicit-any\n>;\n\n/**\n * Configuration for a single fragment in the test builder\n */\ninterface FragmentBuilderConfig<\n TConfig,\n TOptions extends FragnoPublicConfig,\n TDeps,\n TBaseServices extends Record<string, unknown>,\n TServices extends Record<string, unknown>,\n TServiceDependencies,\n TPrivateServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n TLinkedFragments extends AnyLinkedFragments,\n> {\n definition: FragmentDefinition<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TLinkedFragments\n >;\n builder: FragmentInstantiationBuilder<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TRoutesOrFactories,\n TLinkedFragments\n >;\n migrateToVersion?: number;\n}\n\n/**\n * Test context combining base and adapter-specific functionality\n */\ntype TestContext<\n T extends SupportedAdapter,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> = BaseTestContext &\n AdapterContext<T> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n adapter: DatabaseAdapter<any>;\n /**\n * Execute a callback within the first fragment's request context.\n * This is useful for calling services outside of route handlers in tests.\n */\n inContext<TResult>(callback: (this: TFirstFragmentThisContext) => TResult): TResult;\n inContext<TResult>(\n callback: (this: TFirstFragmentThisContext) => Promise<TResult>,\n ): Promise<TResult>;\n };\n\n/**\n * Result of building the database fragments test\n */\ninterface DatabaseFragmentsTestResult<\n TFragments extends Record<string, AnyFragmentResult>,\n TAdapter extends SupportedAdapter,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> {\n fragments: TFragments;\n test: TestContext<TAdapter, TFirstFragmentThisContext>;\n}\n\n/**\n * Internal storage for fragment configurations\n */\ntype FragmentConfigMap = Map<string, AnyFragmentBuilderConfig>;\n\n/**\n * Builder for creating multiple database fragments for testing\n */\nexport class DatabaseFragmentsTestBuilder<\n TFragments extends Record<string, AnyFragmentResult>,\n TAdapter extends SupportedAdapter | undefined = undefined,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> {\n #adapter?: SupportedAdapter;\n #fragments: FragmentConfigMap = new Map();\n\n /**\n * Set the test adapter configuration\n */\n withTestAdapter<TNewAdapter extends SupportedAdapter>(\n adapter: TNewAdapter,\n ): DatabaseFragmentsTestBuilder<TFragments, TNewAdapter, TFirstFragmentThisContext> {\n this.#adapter = adapter;\n return this as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n\n /**\n * Add a fragment to the test setup\n *\n * @param name - Unique name for the fragment\n * @param builder - Pre-configured instantiation builder\n * @param options - Additional options (optional)\n */\n withFragment<\n TName extends string,\n TConfig,\n TOptions extends FragnoPublicConfig,\n TDeps,\n TBaseServices extends Record<string, unknown>,\n TServices extends Record<string, unknown>,\n TServiceDependencies,\n TPrivateServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n TLinkedFragments extends AnyLinkedFragments,\n >(\n name: TName,\n builder: FragmentInstantiationBuilder<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TRoutesOrFactories,\n TLinkedFragments\n >,\n options?: {\n migrateToVersion?: number;\n },\n ): DatabaseFragmentsTestBuilder<\n TFragments & {\n [K in TName]: FragmentResult<\n TDeps,\n BoundServices<TBaseServices & TServices>,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FlattenRouteFactories<TRoutesOrFactories>,\n ExtractSchemaFromDeps<TDeps>, // Extract actual schema type from deps\n TLinkedFragments\n >;\n },\n TAdapter,\n // If this is the first fragment (TFragments is empty {}), use THandlerThisContext; otherwise keep existing\n keyof TFragments extends never ? THandlerThisContext : TFirstFragmentThisContext\n > {\n this.#fragments.set(name, {\n definition: builder.definition,\n builder,\n migrateToVersion: options?.migrateToVersion,\n });\n return this as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n\n /**\n * Build the test setup and return fragments and test context\n */\n async build(): Promise<\n TAdapter extends SupportedAdapter\n ? DatabaseFragmentsTestResult<TFragments, TAdapter, TFirstFragmentThisContext>\n : never\n > {\n if (!this.#adapter) {\n throw new Error(\"Test adapter must be set using withTestAdapter()\");\n }\n\n if (this.#fragments.size === 0) {\n throw new Error(\"At least one fragment must be added using withFragment()\");\n }\n\n const adapterConfig = this.#adapter;\n\n // Extract fragment names and configs\n const fragmentNames = Array.from(this.#fragments.keys());\n const fragmentConfigs = Array.from(this.#fragments.values());\n\n // Extract schemas from definitions and prepare schema configs\n const schemaConfigs: SchemaConfig[] = [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const builderConfigs: Array<{ config: any; routes: any; options: any }> = [];\n\n for (const fragmentConfig of fragmentConfigs) {\n const builder = fragmentConfig.builder;\n const definition = builder.definition;\n\n // Extract schema from definition by calling dependencies with a mock adapter\n let schema: AnySchema | undefined;\n const namespace = definition.name + \"-db\";\n\n if (definition.dependencies) {\n try {\n // Create a mock adapter to extract the schema\n const mockAdapter = {\n createQueryEngine: () => ({ schema: null }),\n contextStorage: { run: (_data: unknown, fn: () => unknown) => fn() },\n };\n\n // Use the actual config from the builder instead of an empty mock\n // This ensures dependencies can be properly initialized (e.g., Stripe with API keys)\n const actualConfig = builder.config ?? {};\n\n const deps = definition.dependencies({\n config: actualConfig,\n options: {\n databaseAdapter: mockAdapter as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n });\n\n // The schema is in deps.schema for database fragments\n if (deps && typeof deps === \"object\" && \"schema\" in deps) {\n schema = (deps as any).schema; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n } catch (error) {\n // If extraction fails, provide a helpful error message\n const errorMessage =\n error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown error\";\n\n throw new Error(\n `Failed to extract schema from fragment '${definition.name}'.\\n` +\n `Original error: ${errorMessage}\\n\\n` +\n `Make sure the fragment is a database fragment using defineFragment().extend(withDatabase(schema)).`,\n );\n }\n }\n\n if (!schema) {\n throw new Error(\n `Fragment '${definition.name}' does not have a database schema. ` +\n `Make sure you're using defineFragment().extend(withDatabase(schema)).`,\n );\n }\n\n schemaConfigs.push({\n schema,\n namespace,\n migrateToVersion: fragmentConfig.migrateToVersion,\n });\n\n // Extract config, routes, and options from builder using public getters\n builderConfigs.push({\n config: builder.config ?? {},\n routes: builder.routes ?? [],\n options: builder.options ?? {},\n });\n }\n\n // Create adapter with all schemas\n const { testContext, adapter } = await createAdapter(adapterConfig, schemaConfigs);\n\n // Helper to create fragments with service wiring\n const createFragments = () => {\n // First pass: create fragments without service dependencies to extract provided services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const providedServicesByName: Record<string, { service: any; orm: any }> = {};\n const fragmentResults: any[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (let i = 0; i < fragmentConfigs.length; i++) {\n const fragmentConfig = fragmentConfigs[i]!;\n const builderConfig = builderConfigs[i]!;\n const namespace = schemaConfigs[i]!.namespace;\n const schema = schemaConfigs[i]!.schema;\n const orm = testContext.getOrm(namespace);\n\n // Merge builder options with database adapter\n const mergedOptions = {\n ...builderConfig.options,\n databaseAdapter: adapter,\n };\n\n // Instantiate fragment using the builder\n const fragment = fragmentConfig.builder.withOptions(mergedOptions).build();\n\n // Extract provided services based on serviceDependencies metadata\n // Note: serviceDependencies lists services this fragment USES, not provides\n // For provided services, we need to check what's actually in fragment.services\n // and match against other fragments' service dependencies\n\n // Store all services as potentially provided\n for (const [serviceName, serviceImpl] of Object.entries(fragment.services)) {\n providedServicesByName[serviceName] = {\n service: serviceImpl,\n orm,\n };\n }\n\n // Store the fragment result\n const deps = fragment.$internal?.deps;\n\n fragmentResults.push({\n fragment,\n services: fragment.services,\n deps: deps || {},\n callRoute: fragment.callRoute.bind(fragment),\n get db() {\n return orm;\n },\n _orm: orm,\n _schema: schema,\n });\n }\n\n // Second pass: rebuild fragments with service dependencies wired up\n for (let i = 0; i < fragmentConfigs.length; i++) {\n const fragmentConfig = fragmentConfigs[i]!;\n const definition = fragmentConfig.builder.definition;\n const builderConfig = builderConfigs[i]!;\n const namespace = schemaConfigs[i]!.namespace;\n const schema = schemaConfigs[i]!.schema;\n const orm = testContext.getOrm(namespace);\n\n // Build service implementations for services this fragment uses\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const serviceImplementations: Record<string, any> = {};\n const serviceDependencies = definition.serviceDependencies;\n\n if (serviceDependencies) {\n for (const serviceName of Object.keys(serviceDependencies)) {\n if (providedServicesByName[serviceName]) {\n serviceImplementations[serviceName] = providedServicesByName[serviceName]!.service;\n }\n }\n }\n\n // Merge builder options with database adapter\n const mergedOptions = {\n ...builderConfig.options,\n databaseAdapter: adapter,\n };\n\n // Rebuild the fragment with service implementations using the builder\n const fragment = fragmentConfig.builder\n .withOptions(mergedOptions)\n .withServices(serviceImplementations as any) // eslint-disable-line @typescript-eslint/no-explicit-any\n .build();\n\n // Update the result\n // Access deps from the internal property\n const deps = fragment.$internal?.deps;\n\n fragmentResults[i] = {\n fragment,\n services: fragment.services,\n deps: deps || {},\n callRoute: fragment.callRoute.bind(fragment),\n get db() {\n return orm;\n },\n _orm: orm,\n _schema: schema,\n };\n }\n\n return fragmentResults;\n };\n\n const fragmentResults = createFragments();\n\n // Wrap resetDatabase to also recreate all fragments\n const originalResetDatabase = testContext.resetDatabase;\n const resetDatabase = async () => {\n await originalResetDatabase();\n\n // Recreate all fragments with service wiring\n const newFragmentResults = createFragments();\n\n // Update the result objects\n newFragmentResults.forEach((newResult, index) => {\n const result = fragmentResults[index]!;\n result.fragment = newResult.fragment;\n result.services = newResult.services;\n result.deps = newResult.deps;\n result.callRoute = newResult.callRoute;\n result._orm = newResult._orm;\n });\n };\n\n // Get the first fragment's inContext method\n const firstFragment = fragmentResults[0]?.fragment;\n if (!firstFragment) {\n throw new Error(\"At least one fragment must be added\");\n }\n\n const finalTestContext = {\n ...testContext,\n resetDatabase,\n adapter,\n inContext: firstFragment.inContext.bind(firstFragment),\n };\n\n // Build result object with named fragments\n const fragmentsObject = Object.fromEntries(\n fragmentNames.map((name, index) => [name, fragmentResults[index]]),\n );\n\n // Safe cast: We've already validated that adapterConfig is SupportedAdapter at the beginning of build()\n // TypeScript can't infer this through the conditional return type, so we use 'as any'\n return {\n fragments: fragmentsObject as TFragments,\n test: finalTestContext,\n } as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n}\n\n/**\n * Create a builder for setting up multiple database fragments for testing.\n * This is the new builder-based API that works with the new fragment instantiation builders.\n *\n * @example\n * ```typescript\n * const userFragmentDef = defineFragment(\"user\")\n * .extend(withDatabase(userSchema))\n * .withDependencies(...)\n * .build();\n *\n * const postFragmentDef = defineFragment(\"post\")\n * .extend(withDatabase(postSchema))\n * .withDependencies(...)\n * .build();\n *\n * const { fragments, test } = await buildDatabaseFragmentsTest()\n * .withTestAdapter({ type: \"kysely-sqlite\" })\n * .withFragment(\"user\",\n * instantiate(userFragmentDef)\n * .withConfig({ ... })\n * .withRoutes([...])\n * )\n * .withFragment(\"post\",\n * instantiate(postFragmentDef)\n * .withRoutes([...])\n * )\n * .build();\n *\n * // Access fragments by name\n * await fragments.user.services.createUser(...);\n * await fragments.post.services.createPost(...);\n *\n * // Access dependencies directly\n * const userDeps = fragments.user.deps;\n *\n * // Shared test context\n * await test.resetDatabase();\n * await test.cleanup();\n * const adapter = test.adapter; // Access the database adapter\n * ```\n */\nexport function buildDatabaseFragmentsTest(): DatabaseFragmentsTestBuilder<\n {},\n undefined,\n RequestThisContext\n> {\n return new DatabaseFragmentsTestBuilder();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-test.js","names":["#adapter","#fragments","schemaConfigs: SchemaConfig[]","builderConfigs: Array<{ config: any; routes: any; options: any }>","schema: AnySchema | undefined","namespace: string | undefined","providedServicesByName: Record<string, { service: any; orm: any }>","fragmentResults: any[]","serviceImplementations: Record<string, any>","fragmentResults"],"sources":["../src/db-test.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type {\n RequestThisContext,\n FragnoPublicConfig,\n FragmentInstantiationBuilder,\n FragnoInstantiatedFragment,\n FragmentDefinition,\n} from \"@fragno-dev/core\";\nimport type { AnyRouteOrFactory, FlattenRouteFactories } from \"@fragno-dev/core/route\";\nimport {\n createAdapter,\n type SupportedAdapter,\n type AdapterContext,\n type SchemaConfig,\n} from \"./adapters\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db\";\nimport type { SimpleQueryInterface } from \"@fragno-dev/db/query\";\nimport type { BaseTestContext } from \".\";\n\n// BoundServices is an internal type that strips 'this' parameters from service methods\n// It's used to represent services after they've been bound to a context\ntype BoundServices<T> = {\n [K in keyof T]: T[K] extends (this: any, ...args: infer A) => infer R // eslint-disable-line @typescript-eslint/no-explicit-any\n ? (...args: A) => R\n : T[K] extends Record<string, unknown>\n ? BoundServices<T[K]>\n : T[K];\n};\n\n// Extract the schema type from database fragment dependencies\n// Database fragments have ImplicitDatabaseDependencies<TSchema> which includes `schema: TSchema`\ntype ExtractSchemaFromDeps<TDeps> = TDeps extends { schema: infer TSchema extends AnySchema }\n ? TSchema\n : AnySchema;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyLinkedFragments = Record<string, any>;\n\n// Forward declarations for recursive type references\ninterface FragmentResult<\n TDeps,\n TServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutes extends readonly any[], // eslint-disable-line @typescript-eslint/no-explicit-any\n TSchema extends AnySchema,\n TLinkedFragments extends AnyLinkedFragments = {},\n> {\n fragment: FragnoInstantiatedFragment<\n TRoutes,\n TDeps,\n TServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FragnoPublicConfig,\n TLinkedFragments\n >;\n services: TServices;\n deps: TDeps;\n callRoute: FragnoInstantiatedFragment<\n TRoutes,\n TDeps,\n TServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FragnoPublicConfig,\n TLinkedFragments\n >[\"callRoute\"];\n db: SimpleQueryInterface<TSchema>;\n}\n\n// Safe: Catch-all for any fragment result type\ntype AnyFragmentResult = FragmentResult<\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any // eslint-disable-line @typescript-eslint/no-explicit-any\n>;\n\n// Safe: Catch-all for any fragment builder config type\ntype AnyFragmentBuilderConfig = FragmentBuilderConfig<\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any, // eslint-disable-line @typescript-eslint/no-explicit-any\n any // eslint-disable-line @typescript-eslint/no-explicit-any\n>;\n\n/**\n * Configuration for a single fragment in the test builder\n */\ninterface FragmentBuilderConfig<\n TConfig,\n TOptions extends FragnoPublicConfig,\n TDeps,\n TBaseServices extends Record<string, unknown>,\n TServices extends Record<string, unknown>,\n TServiceDependencies,\n TPrivateServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n TLinkedFragments extends AnyLinkedFragments,\n> {\n definition: FragmentDefinition<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TLinkedFragments\n >;\n builder: FragmentInstantiationBuilder<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TRoutesOrFactories,\n TLinkedFragments\n >;\n migrateToVersion?: number;\n}\n\n/**\n * Test context combining base and adapter-specific functionality\n */\ntype TestContext<\n T extends SupportedAdapter,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> = BaseTestContext &\n AdapterContext<T> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n adapter: DatabaseAdapter<any>;\n /**\n * Execute a callback within the first fragment's request context.\n * This is useful for calling services outside of route handlers in tests.\n */\n inContext<TResult>(callback: (this: TFirstFragmentThisContext) => TResult): TResult;\n inContext<TResult>(\n callback: (this: TFirstFragmentThisContext) => Promise<TResult>,\n ): Promise<TResult>;\n };\n\n/**\n * Result of building the database fragments test\n */\ninterface DatabaseFragmentsTestResult<\n TFragments extends Record<string, AnyFragmentResult>,\n TAdapter extends SupportedAdapter,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> {\n fragments: TFragments;\n test: TestContext<TAdapter, TFirstFragmentThisContext>;\n}\n\n/**\n * Internal storage for fragment configurations\n */\ntype FragmentConfigMap = Map<string, AnyFragmentBuilderConfig>;\n\n/**\n * Builder for creating multiple database fragments for testing\n */\nexport class DatabaseFragmentsTestBuilder<\n TFragments extends Record<string, AnyFragmentResult>,\n TAdapter extends SupportedAdapter | undefined = undefined,\n TFirstFragmentThisContext extends RequestThisContext = RequestThisContext,\n> {\n #adapter?: SupportedAdapter;\n #fragments: FragmentConfigMap = new Map();\n\n /**\n * Set the test adapter configuration\n */\n withTestAdapter<TNewAdapter extends SupportedAdapter>(\n adapter: TNewAdapter,\n ): DatabaseFragmentsTestBuilder<TFragments, TNewAdapter, TFirstFragmentThisContext> {\n this.#adapter = adapter;\n return this as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n\n /**\n * Add a fragment to the test setup\n *\n * @param name - Unique name for the fragment\n * @param builder - Pre-configured instantiation builder\n * @param options - Additional options (optional)\n */\n withFragment<\n TName extends string,\n TConfig,\n TOptions extends FragnoPublicConfig,\n TDeps,\n TBaseServices extends Record<string, unknown>,\n TServices extends Record<string, unknown>,\n TServiceDependencies,\n TPrivateServices extends Record<string, unknown>,\n TServiceThisContext extends RequestThisContext,\n THandlerThisContext extends RequestThisContext,\n TRequestStorage,\n TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n TLinkedFragments extends AnyLinkedFragments,\n >(\n name: TName,\n builder: FragmentInstantiationBuilder<\n TConfig,\n TOptions,\n TDeps,\n TBaseServices,\n TServices,\n TServiceDependencies,\n TPrivateServices,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n TRoutesOrFactories,\n TLinkedFragments\n >,\n options?: {\n migrateToVersion?: number;\n },\n ): DatabaseFragmentsTestBuilder<\n TFragments & {\n [K in TName]: FragmentResult<\n TDeps,\n BoundServices<TBaseServices & TServices>,\n TServiceThisContext,\n THandlerThisContext,\n TRequestStorage,\n FlattenRouteFactories<TRoutesOrFactories>,\n ExtractSchemaFromDeps<TDeps>, // Extract actual schema type from deps\n TLinkedFragments\n >;\n },\n TAdapter,\n // If this is the first fragment (TFragments is empty {}), use THandlerThisContext; otherwise keep existing\n keyof TFragments extends never ? THandlerThisContext : TFirstFragmentThisContext\n > {\n this.#fragments.set(name, {\n definition: builder.definition,\n builder,\n migrateToVersion: options?.migrateToVersion,\n });\n return this as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n\n /**\n * Build the test setup and return fragments and test context\n */\n async build(): Promise<\n TAdapter extends SupportedAdapter\n ? DatabaseFragmentsTestResult<TFragments, TAdapter, TFirstFragmentThisContext>\n : never\n > {\n if (!this.#adapter) {\n throw new Error(\"Test adapter must be set using withTestAdapter()\");\n }\n\n if (this.#fragments.size === 0) {\n throw new Error(\"At least one fragment must be added using withFragment()\");\n }\n\n const adapterConfig = this.#adapter;\n\n // Extract fragment names and configs\n const fragmentNames = Array.from(this.#fragments.keys());\n const fragmentConfigs = Array.from(this.#fragments.values());\n\n // Extract schemas from definitions and prepare schema configs\n const schemaConfigs: SchemaConfig[] = [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const builderConfigs: Array<{ config: any; routes: any; options: any }> = [];\n\n for (const fragmentConfig of fragmentConfigs) {\n const builder = fragmentConfig.builder;\n const definition = builder.definition;\n\n // Extract schema and namespace from definition by calling dependencies with a mock adapter\n let schema: AnySchema | undefined;\n let namespace: string | undefined;\n\n if (definition.dependencies) {\n try {\n // Create a mock adapter to extract the schema\n const mockAdapter = {\n createQueryEngine: () => ({ schema: null }),\n contextStorage: { run: (_data: unknown, fn: () => unknown) => fn() },\n };\n\n // Use the actual config from the builder instead of an empty mock\n // This ensures dependencies can be properly initialized (e.g., Stripe with API keys)\n const actualConfig = builder.config ?? {};\n\n const deps = definition.dependencies({\n config: actualConfig,\n options: {\n databaseAdapter: mockAdapter as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n } as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n });\n\n // The schema and namespace are in deps for database fragments\n if (deps && typeof deps === \"object\" && \"schema\" in deps) {\n schema = (deps as any).schema; // eslint-disable-line @typescript-eslint/no-explicit-any\n namespace = (deps as any).namespace; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n } catch (error) {\n // If extraction fails, provide a helpful error message\n const errorMessage =\n error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown error\";\n\n throw new Error(\n `Failed to extract schema from fragment '${definition.name}'.\\n` +\n `Original error: ${errorMessage}\\n\\n` +\n `Make sure the fragment is a database fragment using defineFragment().extend(withDatabase(schema)).`,\n );\n }\n }\n\n if (!schema) {\n throw new Error(\n `Fragment '${definition.name}' does not have a database schema. ` +\n `Make sure you're using defineFragment().extend(withDatabase(schema)).`,\n );\n }\n\n if (!namespace) {\n throw new Error(\n `Fragment '${definition.name}' does not have a namespace in dependencies. ` +\n `This should be automatically provided by withDatabase().`,\n );\n }\n\n schemaConfigs.push({\n schema,\n namespace,\n migrateToVersion: fragmentConfig.migrateToVersion,\n });\n\n // Extract config, routes, and options from builder using public getters\n builderConfigs.push({\n config: builder.config ?? {},\n routes: builder.routes ?? [],\n options: builder.options ?? {},\n });\n }\n\n // Create adapter with all schemas\n const { testContext, adapter } = await createAdapter(adapterConfig, schemaConfigs);\n\n // Helper to create fragments with service wiring\n const createFragments = () => {\n // First pass: create fragments without service dependencies to extract provided services\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const providedServicesByName: Record<string, { service: any; orm: any }> = {};\n const fragmentResults: any[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (let i = 0; i < fragmentConfigs.length; i++) {\n const fragmentConfig = fragmentConfigs[i]!;\n const builderConfig = builderConfigs[i]!;\n const namespace = schemaConfigs[i]!.namespace;\n const schema = schemaConfigs[i]!.schema;\n const orm = testContext.getOrm(namespace);\n\n // Merge builder options with database adapter\n const mergedOptions = {\n ...builderConfig.options,\n databaseAdapter: adapter,\n };\n\n // Instantiate fragment using the builder\n const fragment = fragmentConfig.builder.withOptions(mergedOptions).build();\n\n // Extract provided services based on serviceDependencies metadata\n // Note: serviceDependencies lists services this fragment USES, not provides\n // For provided services, we need to check what's actually in fragment.services\n // and match against other fragments' service dependencies\n\n // Store all services as potentially provided\n for (const [serviceName, serviceImpl] of Object.entries(fragment.services)) {\n providedServicesByName[serviceName] = {\n service: serviceImpl,\n orm,\n };\n }\n\n // Store the fragment result\n const deps = fragment.$internal?.deps;\n\n fragmentResults.push({\n fragment,\n services: fragment.services,\n deps: deps || {},\n callRoute: fragment.callRoute.bind(fragment),\n get db() {\n return orm;\n },\n _orm: orm,\n _schema: schema,\n });\n }\n\n // Second pass: rebuild fragments with service dependencies wired up\n for (let i = 0; i < fragmentConfigs.length; i++) {\n const fragmentConfig = fragmentConfigs[i]!;\n const definition = fragmentConfig.builder.definition;\n const builderConfig = builderConfigs[i]!;\n const namespace = schemaConfigs[i]!.namespace;\n const schema = schemaConfigs[i]!.schema;\n const orm = testContext.getOrm(namespace);\n\n // Build service implementations for services this fragment uses\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const serviceImplementations: Record<string, any> = {};\n const serviceDependencies = definition.serviceDependencies;\n\n if (serviceDependencies) {\n for (const serviceName of Object.keys(serviceDependencies)) {\n if (providedServicesByName[serviceName]) {\n serviceImplementations[serviceName] = providedServicesByName[serviceName]!.service;\n }\n }\n }\n\n // Merge builder options with database adapter\n const mergedOptions = {\n ...builderConfig.options,\n databaseAdapter: adapter,\n };\n\n // Rebuild the fragment with service implementations using the builder\n const fragment = fragmentConfig.builder\n .withOptions(mergedOptions)\n .withServices(serviceImplementations as any) // eslint-disable-line @typescript-eslint/no-explicit-any\n .build();\n\n // Update the result\n // Access deps from the internal property\n const deps = fragment.$internal?.deps;\n\n fragmentResults[i] = {\n fragment,\n services: fragment.services,\n deps: deps || {},\n callRoute: fragment.callRoute.bind(fragment),\n get db() {\n return orm;\n },\n _orm: orm,\n _schema: schema,\n };\n }\n\n return fragmentResults;\n };\n\n const fragmentResults = createFragments();\n\n // Wrap resetDatabase to also recreate all fragments\n const originalResetDatabase = testContext.resetDatabase;\n const resetDatabase = async () => {\n await originalResetDatabase();\n\n // Recreate all fragments with service wiring\n const newFragmentResults = createFragments();\n\n // Update the result objects\n newFragmentResults.forEach((newResult, index) => {\n const result = fragmentResults[index]!;\n result.fragment = newResult.fragment;\n result.services = newResult.services;\n result.deps = newResult.deps;\n result.callRoute = newResult.callRoute;\n result._orm = newResult._orm;\n });\n };\n\n // Get the first fragment's inContext method\n const firstFragment = fragmentResults[0]?.fragment;\n if (!firstFragment) {\n throw new Error(\"At least one fragment must be added\");\n }\n\n const finalTestContext = {\n ...testContext,\n resetDatabase,\n adapter,\n inContext: firstFragment.inContext.bind(firstFragment),\n };\n\n // Build result object with named fragments\n const fragmentsObject = Object.fromEntries(\n fragmentNames.map((name, index) => [name, fragmentResults[index]]),\n );\n\n // Safe cast: We've already validated that adapterConfig is SupportedAdapter at the beginning of build()\n // TypeScript can't infer this through the conditional return type, so we use 'as any'\n return {\n fragments: fragmentsObject as TFragments,\n test: finalTestContext,\n } as any; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n}\n\n/**\n * Create a builder for setting up multiple database fragments for testing.\n * This is the new builder-based API that works with the new fragment instantiation builders.\n *\n * @example\n * ```typescript\n * const userFragmentDef = defineFragment(\"user\")\n * .extend(withDatabase(userSchema))\n * .withDependencies(...)\n * .build();\n *\n * const postFragmentDef = defineFragment(\"post\")\n * .extend(withDatabase(postSchema))\n * .withDependencies(...)\n * .build();\n *\n * const { fragments, test } = await buildDatabaseFragmentsTest()\n * .withTestAdapter({ type: \"kysely-sqlite\" })\n * .withFragment(\"user\",\n * instantiate(userFragmentDef)\n * .withConfig({ ... })\n * .withRoutes([...])\n * )\n * .withFragment(\"post\",\n * instantiate(postFragmentDef)\n * .withRoutes([...])\n * )\n * .build();\n *\n * // Access fragments by name\n * await fragments.user.services.createUser(...);\n * await fragments.post.services.createPost(...);\n *\n * // Access dependencies directly\n * const userDeps = fragments.user.deps;\n *\n * // Shared test context\n * await test.resetDatabase();\n * await test.cleanup();\n * const adapter = test.adapter; // Access the database adapter\n * ```\n */\nexport function buildDatabaseFragmentsTest(): DatabaseFragmentsTestBuilder<\n {},\n undefined,\n RequestThisContext\n> {\n return new DatabaseFragmentsTestBuilder();\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { AdapterContext, DrizzlePgliteAdapter, KyselyPgliteAdapter, KyselySqliteAdapter, SupportedAdapter } from "./adapters.js";
2
2
  import { DatabaseFragmentsTestBuilder, buildDatabaseFragmentsTest } from "./db-test.js";
3
3
  import { CreateFragmentForTestOptions, RouteHandlerInputOptions, createFragmentForTest } from "@fragno-dev/core/test";
4
- import { AnySchema } from "@fragno-dev/db/schema";
5
- import { AbstractQuery } from "@fragno-dev/db/query";
6
4
  import { DatabaseAdapter } from "@fragno-dev/db";
5
+ import { AnySchema } from "@fragno-dev/db/schema";
6
+ import { SimpleQueryInterface } from "@fragno-dev/db/query";
7
7
 
8
8
  //#region src/index.d.ts
9
9
 
@@ -19,13 +19,13 @@ interface BaseTestContext {
19
19
  * Internal interface with getOrm for adapter implementations
20
20
  */
21
21
  interface InternalTestContextMethods {
22
- getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;
22
+ getOrm: <TSchema extends AnySchema>(namespace: string) => SimpleQueryInterface<TSchema>;
23
23
  }
24
24
  /**
25
25
  * Helper to create common test context methods from an ORM map
26
26
  * This is used internally by adapter implementations to avoid code duplication
27
27
  */
28
- declare function createCommonTestContextMethods(ormMap: Map<string, AbstractQuery<any>>): InternalTestContextMethods;
28
+ declare function createCommonTestContextMethods(ormMap: Map<string, SimpleQueryInterface<any>>): InternalTestContextMethods;
29
29
  /**
30
30
  * Complete test context combining base and adapter-specific functionality
31
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAiCA;;AAGuB,UAHN,eAAA,CAGM;EACN,SAAA,OAAA,EAFG,eAEH,CAAA,GAAA,CAAA;EAAO,aAAA,EAAA,GAAA,GADD,OACC,CAAA,IAAA,CAAA;EAMP,OAAA,EAAA,GAAA,GANA,OAMA,CAAA,IAAA,CAAA;;;;;AAQD,UARC,0BAAA,CAQ6B;EAExB,MAAA,EAAA,CAAA,gBATK,SASL,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,GATsC,aAStC,CAToD,OASpD,CAAA;;;;AAgBtB;;AAAsD,iBAlBtC,8BAAA,CAkBsC,MAAA,EAhB5C,GAgB4C,CAAA,MAAA,EAhBhC,aAgBgC,CAAA,GAAA,CAAA,CAAA,CAAA,EAfnD,0BAemD;;;;KAA1C,sBAAsB,oBAAoB,kBAAkB,eAAe"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAiCA;;AAGuB,UAHN,eAAA,CAGM;EACN,SAAA,OAAA,EAFG,eAEH,CAAA,GAAA,CAAA;EAAO,aAAA,EAAA,GAAA,GADD,OACC,CAAA,IAAA,CAAA;EAMP,OAAA,EAAA,GAAA,GANA,OAMA,CAAA,IAAA,CAAA;;;;;AAQD,UARC,0BAAA,CAQ6B;EAExB,MAAA,EAAA,CAAA,gBATK,SASL,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,GATsC,oBAStC,CAT2D,OAS3D,CAAA;;;;AAgBtB;;AAAsD,iBAlBtC,8BAAA,CAkBsC,MAAA,EAhB5C,GAgB4C,CAAA,MAAA,EAhBhC,oBAgBgC,CAAA,GAAA,CAAA,CAAA,CAAA,EAfnD,0BAemD;;;;KAA1C,sBAAsB,oBAAoB,kBAAkB,eAAe"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type {\n SupportedAdapter,\n AdapterContext,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n} from \"./adapters\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db\";\nimport type { AbstractQuery } from \"@fragno-dev/db/query\";\n\n// Re-export utilities from @fragno-dev/core/test\nexport {\n createFragmentForTest,\n type CreateFragmentForTestOptions,\n type RouteHandlerInputOptions,\n} from \"@fragno-dev/core/test\";\n\n// Re-export adapter types\nexport type {\n SupportedAdapter,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n AdapterContext,\n} from \"./adapters\";\n\n// Re-export new builder-based database test utilities\nexport { buildDatabaseFragmentsTest, DatabaseFragmentsTestBuilder } from \"./db-test\";\n\n/**\n * Base test context with common functionality across all adapters\n */\nexport interface BaseTestContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>;\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n}\n\n/**\n * Internal interface with getOrm for adapter implementations\n */\nexport interface InternalTestContextMethods {\n getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;\n}\n\n/**\n * Helper to create common test context methods from an ORM map\n * This is used internally by adapter implementations to avoid code duplication\n */\nexport function createCommonTestContextMethods(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ormMap: Map<string, AbstractQuery<any>>,\n): InternalTestContextMethods {\n return {\n getOrm: <TSchema extends AnySchema>(namespace: string) => {\n const orm = ormMap.get(namespace);\n if (!orm) {\n throw new Error(`No ORM found for namespace: ${namespace}`);\n }\n return orm as AbstractQuery<TSchema>;\n },\n };\n}\n\n/**\n * Complete test context combining base and adapter-specific functionality\n */\nexport type TestContext<T extends SupportedAdapter> = BaseTestContext & AdapterContext<T>;\n"],"mappings":";;;;;;;;AAmDA,SAAgB,+BAEd,QAC4B;AAC5B,QAAO,EACL,SAAoC,cAAsB;EACxD,MAAM,MAAM,OAAO,IAAI,UAAU;AACjC,MAAI,CAAC,IACH,OAAM,IAAI,MAAM,+BAA+B,YAAY;AAE7D,SAAO;IAEV"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type {\n SupportedAdapter,\n AdapterContext,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n} from \"./adapters\";\nimport type { DatabaseAdapter } from \"@fragno-dev/db\";\nimport type { SimpleQueryInterface } from \"@fragno-dev/db/query\";\n\n// Re-export utilities from @fragno-dev/core/test\nexport {\n createFragmentForTest,\n type CreateFragmentForTestOptions,\n type RouteHandlerInputOptions,\n} from \"@fragno-dev/core/test\";\n\n// Re-export adapter types\nexport type {\n SupportedAdapter,\n KyselySqliteAdapter,\n KyselyPgliteAdapter,\n DrizzlePgliteAdapter,\n AdapterContext,\n} from \"./adapters\";\n\n// Re-export new builder-based database test utilities\nexport { buildDatabaseFragmentsTest, DatabaseFragmentsTestBuilder } from \"./db-test\";\n\n/**\n * Base test context with common functionality across all adapters\n */\nexport interface BaseTestContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly adapter: DatabaseAdapter<any>;\n resetDatabase: () => Promise<void>;\n cleanup: () => Promise<void>;\n}\n\n/**\n * Internal interface with getOrm for adapter implementations\n */\nexport interface InternalTestContextMethods {\n getOrm: <TSchema extends AnySchema>(namespace: string) => SimpleQueryInterface<TSchema>;\n}\n\n/**\n * Helper to create common test context methods from an ORM map\n * This is used internally by adapter implementations to avoid code duplication\n */\nexport function createCommonTestContextMethods(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ormMap: Map<string, SimpleQueryInterface<any>>,\n): InternalTestContextMethods {\n return {\n getOrm: <TSchema extends AnySchema>(namespace: string) => {\n const orm = ormMap.get(namespace);\n if (!orm) {\n throw new Error(`No ORM found for namespace: ${namespace}`);\n }\n return orm as SimpleQueryInterface<TSchema>;\n },\n };\n}\n\n/**\n * Complete test context combining base and adapter-specific functionality\n */\nexport type TestContext<T extends SupportedAdapter> = BaseTestContext & AdapterContext<T>;\n"],"mappings":";;;;;;;;AAmDA,SAAgB,+BAEd,QAC4B;AAC5B,QAAO,EACL,SAAoC,cAAsB;EACxD,MAAM,MAAM,OAAO,IAAI,UAAU;AACjC,MAAI,CAAC,IACH,OAAM,IAAI,MAAM,+BAA+B,YAAY;AAE7D,SAAO;IAEV"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragno-dev/test",
3
- "version": "0.1.14",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -19,11 +19,11 @@
19
19
  },
20
20
  "peerDependencies": {
21
21
  "@electric-sql/pglite": "^0.3.11",
22
- "drizzle-kit": "^0.30.3",
22
+ "drizzle-kit": "^0.31.7",
23
23
  "drizzle-orm": "^0.44.7",
24
24
  "kysely-pglite": "^0.6.1",
25
- "@fragno-dev/core": "0.1.10",
26
- "@fragno-dev/db": "0.1.15"
25
+ "@fragno-dev/core": "0.1.11",
26
+ "@fragno-dev/db": "0.2.0"
27
27
  },
28
28
  "peerDependenciesMeta": {
29
29
  "@electric-sql/pglite": {
@@ -44,13 +44,13 @@
44
44
  "@libsql/client": "^0.14.0",
45
45
  "@types/node": "^22",
46
46
  "@vitest/coverage-istanbul": "^3.2.4",
47
- "drizzle-kit": "^0.30.3",
47
+ "drizzle-kit": "^0.31.7",
48
48
  "drizzle-orm": "^0.44.7",
49
49
  "kysely-pglite": "^0.6.1",
50
50
  "vitest": "^3.2.4",
51
51
  "zod": "^4.1.12",
52
- "@fragno-dev/core": "0.1.10",
53
- "@fragno-dev/db": "0.1.15",
52
+ "@fragno-dev/core": "0.1.11",
53
+ "@fragno-dev/db": "0.2.0",
54
54
  "@fragno-private/typescript-config": "0.0.1",
55
55
  "@fragno-private/vitest-config": "0.0.0"
56
56
  },
package/src/adapters.ts CHANGED
@@ -7,13 +7,13 @@ 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";
11
- import { createRequire } from "node:module";
12
- import { mkdir, writeFile, rm } from "node:fs/promises";
13
- import { join } from "node:path";
10
+ import { rm } from "node:fs/promises";
14
11
  import { existsSync } from "node:fs";
15
12
  import type { BaseTestContext } from ".";
16
13
  import { createCommonTestContextMethods } from ".";
14
+ import { PGLiteDriverConfig, SQLocalDriverConfig } from "@fragno-dev/db/drivers";
15
+ import { internalFragmentDef } from "@fragno-dev/db";
16
+ import type { SimpleQueryInterface } from "@fragno-dev/db/query";
17
17
 
18
18
  // Adapter configuration types
19
19
  export interface KyselySqliteAdapter {
@@ -41,7 +41,7 @@ export interface SchemaConfig {
41
41
 
42
42
  // Internal test context extends BaseTestContext with getOrm (not exposed publicly)
43
43
  interface InternalTestContext extends BaseTestContext {
44
- getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;
44
+ getOrm: <TSchema extends AnySchema>(namespace: string) => SimpleQueryInterface<TSchema>;
45
45
  }
46
46
 
47
47
  // Conditional return types based on adapter (adapter-specific properties only)
@@ -83,25 +83,22 @@ export async function createKyselySqliteAdapter(
83
83
 
84
84
  // Create KyselyAdapter
85
85
  const adapter = new KyselyAdapter({
86
- db: kysely,
87
- provider: "sqlite",
86
+ dialect,
87
+ driverConfig: new SQLocalDriverConfig(),
88
88
  });
89
89
 
90
90
  // Run migrations for all schemas in order
91
91
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
- const ormMap = new Map<string, AbstractQuery<any, any>>();
92
+ const ormMap = new Map<string, SimpleQueryInterface<any, any>>();
93
93
 
94
94
  for (const { schema, namespace, migrateToVersion } of schemas) {
95
95
  // Run migrations
96
- const migrator = adapter.createMigrationEngine(schema, namespace);
97
- const preparedMigration = migrateToVersion
98
- ? await migrator.prepareMigrationTo(migrateToVersion, {
99
- updateSettings: false,
100
- })
101
- : await migrator.prepareMigration({
102
- updateSettings: false,
103
- });
104
- await preparedMigration.execute();
96
+ const preparedMigrations = adapter.prepareMigrations(schema, namespace);
97
+ if (migrateToVersion !== undefined) {
98
+ await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
99
+ } else {
100
+ await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
101
+ }
105
102
 
106
103
  // Create ORM instance and store in map
107
104
  const orm = adapter.createQueryEngine(schema, namespace);
@@ -174,25 +171,22 @@ export async function createKyselyPgliteAdapter(
174
171
 
175
172
  // Create KyselyAdapter
176
173
  const adapter = new KyselyAdapter({
177
- db: kysely,
178
- provider: "postgresql",
174
+ dialect: kyselyPglite.dialect,
175
+ driverConfig: new PGLiteDriverConfig(),
179
176
  });
180
177
 
181
178
  // Run migrations for all schemas in order
182
179
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
- const ormMap = new Map<string, AbstractQuery<any, any>>();
180
+ const ormMap = new Map<string, SimpleQueryInterface<any, any>>();
184
181
 
185
182
  for (const { schema, namespace, migrateToVersion } of schemas) {
186
183
  // Run migrations
187
- const migrator = adapter.createMigrationEngine(schema, namespace);
188
- const preparedMigration = migrateToVersion
189
- ? await migrator.prepareMigrationTo(migrateToVersion, {
190
- updateSettings: false,
191
- })
192
- : await migrator.prepareMigration({
193
- updateSettings: false,
194
- });
195
- await preparedMigration.execute();
184
+ const preparedMigrations = adapter.prepareMigrations(schema, namespace);
185
+ if (migrateToVersion !== undefined) {
186
+ await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
187
+ } else {
188
+ await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
189
+ }
196
190
 
197
191
  // Create ORM instance and store in map
198
192
  const orm = adapter.createQueryEngine(schema, namespace);
@@ -267,96 +261,51 @@ export async function createDrizzlePgliteAdapter(
267
261
  ): Promise<AdapterFactoryResult<DrizzlePgliteAdapter>> {
268
262
  const databasePath = config.databasePath;
269
263
 
270
- // Import drizzle-kit for migrations
271
- const require = createRequire(import.meta.url);
272
- const { generateDrizzleJson, generateMigration } =
273
- require("drizzle-kit/api") as typeof import("drizzle-kit/api");
274
-
275
- // Import generateSchema from the properly exported module
276
- const { generateSchema } = await import("@fragno-dev/db/adapters/drizzle/generate");
277
-
278
- // Helper to write schema to file and dynamically import it
279
- const writeAndLoadSchema = async () => {
280
- const testDir = join(import.meta.dirname, "_generated", "drizzle-test");
281
- await mkdir(testDir, { recursive: true }).catch(() => {
282
- // Ignore error if directory already exists
283
- });
284
-
285
- const schemaFilePath = join(
286
- testDir,
287
- `test-schema-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.ts`,
288
- );
289
-
290
- // Combine all schemas into a single Drizzle schema with namespaced tables
291
- const schemaConfigs = schemas.map(({ schema, namespace }) => ({
292
- namespace: namespace ?? "",
293
- schema,
294
- }));
295
-
296
- const drizzleSchemaTs = generateSchema(schemaConfigs, "postgresql");
297
- await writeFile(schemaFilePath, drizzleSchemaTs, "utf-8");
298
-
299
- // Dynamically import the generated schema (with cache busting)
300
- const schemaModule = await import(`${schemaFilePath}?t=${Date.now()}`);
301
-
302
- const cleanup = async () => {
303
- await rm(testDir, { recursive: true, force: true });
304
- };
305
-
306
- return { schemaModule, cleanup };
307
- };
308
-
309
264
  // Helper to create a new database instance and run migrations for all schemas
310
265
  const createDatabase = async () => {
311
- // Write schema to file and load it
312
- const { schemaModule, cleanup } = await writeAndLoadSchema();
313
-
314
- // Create PGlite instance
315
266
  const pglite = new PGlite(databasePath);
316
267
 
317
- // Create Drizzle instance with PGlite
318
- const db = drizzle(pglite, {
319
- schema: schemaModule,
320
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
321
- }) as any;
322
-
323
- // Generate and run migrations
324
- const migrationStatements = await generateMigration(
325
- generateDrizzleJson({}), // Empty schema (starting state)
326
- generateDrizzleJson(schemaModule), // Target schema
327
- );
328
-
329
- // Execute migration SQL
330
- for (const statement of migrationStatements) {
331
- await db.execute(statement);
332
- }
268
+ const { dialect } = new KyselyPGlite(pglite);
333
269
 
334
- // Create DrizzleAdapter
335
270
  const adapter = new DrizzleAdapter({
336
- db: () => db,
337
- provider: "postgresql",
271
+ dialect,
272
+ driverConfig: new PGLiteDriverConfig(),
338
273
  });
339
274
 
340
- // Create ORM instances for each schema and store in map
275
+ // Run migrations for all schemas
341
276
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
342
- const ormMap = new Map<string, AbstractQuery<any, any>>();
277
+ const ormMap = new Map<string, SimpleQueryInterface<any, any>>();
343
278
 
344
- for (const { schema, namespace } of schemas) {
279
+ const databaseDeps = internalFragmentDef.dependencies?.({
280
+ config: {},
281
+ options: { databaseAdapter: adapter },
282
+ });
283
+ if (databaseDeps?.schema) {
284
+ const migrations = adapter.prepareMigrations(databaseDeps.schema, databaseDeps.namespace);
285
+ await migrations.executeWithDriver(adapter.driver, 0);
286
+ }
287
+
288
+ for (const { schema, namespace, migrateToVersion } of schemas) {
289
+ const preparedMigrations = adapter.prepareMigrations(schema, namespace);
290
+ if (migrateToVersion !== undefined) {
291
+ await preparedMigrations.execute(0, migrateToVersion, { updateVersionInMigration: false });
292
+ } else {
293
+ await preparedMigrations.execute(0, schema.version, { updateVersionInMigration: false });
294
+ }
295
+
296
+ // Create ORM instance and store in map
345
297
  const orm = adapter.createQueryEngine(schema, namespace);
346
298
  ormMap.set(namespace, orm);
347
299
  }
348
300
 
349
- return { drizzle: db, adapter, pglite, cleanup, ormMap };
301
+ // Create Drizzle instance for backward compatibility (if needed)
302
+ const db = drizzle(pglite) as any; // eslint-disable-line @typescript-eslint/no-explicit-any
303
+
304
+ return { drizzle: db, adapter, pglite, ormMap };
350
305
  };
351
306
 
352
307
  // Create initial database
353
- const {
354
- drizzle: drizzleDb,
355
- adapter,
356
- pglite,
357
- cleanup: schemaCleanup,
358
- ormMap,
359
- } = await createDatabase();
308
+ const { drizzle: drizzleDb, adapter, ormMap } = await createDatabase();
360
309
 
361
310
  // Reset database function - truncates all tables (only supported for in-memory databases)
362
311
  const resetDatabase = async () => {
@@ -374,10 +323,10 @@ export async function createDrizzlePgliteAdapter(
374
323
  }
375
324
  };
376
325
 
377
- // Cleanup function - closes connections and deletes generated files and database directory
326
+ // Cleanup function - closes connections and deletes database directory
378
327
  const cleanup = async () => {
379
- await pglite.close();
380
- await schemaCleanup();
328
+ // Close the adapter (which will handle closing the underlying database connection)
329
+ await adapter.close();
381
330
 
382
331
  // Delete the database directory if it exists and is a file path
383
332
  if (databasePath && databasePath !== ":memory:" && existsSync(databasePath)) {
package/src/db-test.ts CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  type SchemaConfig,
15
15
  } from "./adapters";
16
16
  import type { DatabaseAdapter } from "@fragno-dev/db";
17
- import type { AbstractQuery } from "@fragno-dev/db/query";
17
+ import type { SimpleQueryInterface } from "@fragno-dev/db/query";
18
18
  import type { BaseTestContext } from ".";
19
19
 
20
20
  // BoundServices is an internal type that strips 'this' parameters from service methods
@@ -69,7 +69,7 @@ interface FragmentResult<
69
69
  FragnoPublicConfig,
70
70
  TLinkedFragments
71
71
  >["callRoute"];
72
- db: AbstractQuery<TSchema>;
72
+ db: SimpleQueryInterface<TSchema>;
73
73
  }
74
74
 
75
75
  // Safe: Catch-all for any fragment result type
@@ -301,9 +301,9 @@ export class DatabaseFragmentsTestBuilder<
301
301
  const builder = fragmentConfig.builder;
302
302
  const definition = builder.definition;
303
303
 
304
- // Extract schema from definition by calling dependencies with a mock adapter
304
+ // Extract schema and namespace from definition by calling dependencies with a mock adapter
305
305
  let schema: AnySchema | undefined;
306
- const namespace = definition.name + "-db";
306
+ let namespace: string | undefined;
307
307
 
308
308
  if (definition.dependencies) {
309
309
  try {
@@ -324,9 +324,10 @@ export class DatabaseFragmentsTestBuilder<
324
324
  } as any, // eslint-disable-line @typescript-eslint/no-explicit-any
325
325
  });
326
326
 
327
- // The schema is in deps.schema for database fragments
327
+ // The schema and namespace are in deps for database fragments
328
328
  if (deps && typeof deps === "object" && "schema" in deps) {
329
329
  schema = (deps as any).schema; // eslint-disable-line @typescript-eslint/no-explicit-any
330
+ namespace = (deps as any).namespace; // eslint-disable-line @typescript-eslint/no-explicit-any
330
331
  }
331
332
  } catch (error) {
332
333
  // If extraction fails, provide a helpful error message
@@ -352,6 +353,13 @@ export class DatabaseFragmentsTestBuilder<
352
353
  );
353
354
  }
354
355
 
356
+ if (!namespace) {
357
+ throw new Error(
358
+ `Fragment '${definition.name}' does not have a namespace in dependencies. ` +
359
+ `This should be automatically provided by withDatabase().`,
360
+ );
361
+ }
362
+
355
363
  schemaConfigs.push({
356
364
  schema,
357
365
  namespace,
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ import type {
7
7
  DrizzlePgliteAdapter,
8
8
  } from "./adapters";
9
9
  import type { DatabaseAdapter } from "@fragno-dev/db";
10
- import type { AbstractQuery } from "@fragno-dev/db/query";
10
+ import type { SimpleQueryInterface } from "@fragno-dev/db/query";
11
11
 
12
12
  // Re-export utilities from @fragno-dev/core/test
13
13
  export {
@@ -42,7 +42,7 @@ export interface BaseTestContext {
42
42
  * Internal interface with getOrm for adapter implementations
43
43
  */
44
44
  export interface InternalTestContextMethods {
45
- getOrm: <TSchema extends AnySchema>(namespace: string) => AbstractQuery<TSchema>;
45
+ getOrm: <TSchema extends AnySchema>(namespace: string) => SimpleQueryInterface<TSchema>;
46
46
  }
47
47
 
48
48
  /**
@@ -51,7 +51,7 @@ export interface InternalTestContextMethods {
51
51
  */
52
52
  export function createCommonTestContextMethods(
53
53
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- ormMap: Map<string, AbstractQuery<any>>,
54
+ ormMap: Map<string, SimpleQueryInterface<any>>,
55
55
  ): InternalTestContextMethods {
56
56
  return {
57
57
  getOrm: <TSchema extends AnySchema>(namespace: string) => {
@@ -59,7 +59,7 @@ export function createCommonTestContextMethods(
59
59
  if (!orm) {
60
60
  throw new Error(`No ORM found for namespace: ${namespace}`);
61
61
  }
62
- return orm as AbstractQuery<TSchema>;
62
+ return orm as SimpleQueryInterface<TSchema>;
63
63
  },
64
64
  };
65
65
  }