Skip to content

Commit f638d12

Browse files
authored
fix(db): treat files in db/schema/ beside db/schema.ts as schema files (#504)
Refs #472 Same cause as #472, hit by the default output of `void gen model`. The #472 layout is not fixed here. `void gen model` writes `db/schema/<name>.ts`, re-exports it from `db/schema.ts`, and the generated file imports `sql` from `void/db`. When `db/schema.ts` exists, the plugin treats only that file as a schema file. `db/schema/<name>.ts` gets `virtual:void-db`, which imports the schema, so the import goes around: `db/schema.ts` → `db/schema/<name>.ts` → `virtual:void-db` → `db/schema.ts`. In dev, `sql` is not ready yet and every page that imports `void/db` returns 500 (`TypeError: __vite_ssr_import_1__.sql is not a function`). `vp build` → `vp preview` works. To reproduce: ```sh pnpm create void my-app # React / D1 cd my-app pnpm add zod pnpm exec void gen model todos title:string done:boolean pnpm exec void db generate pnpm dev # / and /api/todos return 500 ``` This PR also treats files under `db/schema/` as schema files when `db/schema.ts` exists. The folder comes from `paths.schemaDir`, the same path `gen model` writes to. Out of scope: the #472 layout (a file outside `db/schema/` re-exported from `db/schema.ts`). Moving the `drizzle-orm` re-export above the schema import in `virtual:void-db` makes `sql` ready in dev for that case too (checked locally), but it makes the import order matter, so it is not in this PR. Checked: - `plugin-drizzle.test.ts` (1 new test, fails without the fix) - typecheck for `void` - an app after `gen model`: dev (500 → 200) and `vp build` → `vp preview` (200 before and after) 14 tests in `init.test.ts` and 1 in `nitro.test.ts` fail locally on main too. This PR adds no new failures.
1 parent 3b5a6fc commit f638d12

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

‎packages/void/src/plugin-drizzle.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ function createVoidDbModule(
106106
// but schema.path from Node's path.join uses backslashes on Windows.
107107
const normalizedImporter = normalizePath(importer);
108108
const normalizedSchemaPath = normalizePath(schema.path);
109-
if (schema.type === 'file' && normalizedImporter === normalizedSchemaPath) {
109+
if (
110+
schema.type === 'file' &&
111+
(normalizedImporter === normalizedSchemaPath ||
112+
normalizedImporter.startsWith(normalizePath(paths.schemaDir) + '/'))
113+
) {
110114
return VIRTUAL_SCHEMA_DB_ID;
111115
}
112116
if (schema.type === 'directory' && normalizedImporter.startsWith(normalizedSchemaPath)) {

‎packages/void/test/unit/plugin-drizzle.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,24 @@ export const requestPoolOptions = (env) =>
750750
expect(code).not.toContain('requireRuntimeBinding');
751751
});
752752

753+
it('treats files in db/schema/ beside db/schema.ts as schema files', () => {
754+
// `void gen model` writes db/schema/<name>.ts and re-exports it from db/schema.ts.
755+
const root = createProjectRoot();
756+
const plugin = drizzlePlugin(root, false, 'sqlite');
757+
const resolveId = getHookHandler(plugin.resolveId) as (
758+
this: { environment: { name: string } },
759+
source: string,
760+
importer: string | undefined,
761+
options: { isEntry: boolean },
762+
) => string | undefined;
763+
const resolve = (importer: string) =>
764+
resolveId.call({ environment: { name: 'ssr' } }, 'void/db', importer, { isEntry: false });
765+
766+
expect(resolve(join(root, 'db', 'schema', 'todos.ts'))).toBe('\0virtual:void-db-schema');
767+
expect(resolve(join(root, 'db', 'schema-helpers.ts'))).toBe('\0virtual:void-db');
768+
expect(resolve(join(root, 'routes', 'api', 'todos', 'index.ts'))).toBe('\0virtual:void-db');
769+
});
770+
753771
it('can virtualize void/db without a user schema when forced', () => {
754772
const root = createProjectRoot({ schema: false });
755773
const plugin = drizzlePlugin(root, false, 'postgresql', { forceVirtualDb: true });

0 commit comments

Comments
 (0)