[FEATURE]: Better migration creation error messaging with improper schema.ts design
Describe what you want
I was very confused with how i should setup my schema.ts files - if I export some functions/config objects there, apart from the main pgTable and run drizzle-kit generate:pg --config=drizzle.config.ts I'm getting a ReferenceError: Cannot access 'users' before initialization (this applies to the first declared variable in the schema.ts file(s) mentioned in drizzle.config file)
In my opinion there could be a better message informing about what is happening, I tried debugging this for very long taking the ReferenceError into consideration before even trying to run the command with the exported functions commented out.
Something like a Warning: Improperly configurated file would be great
Example: this works (migrations are generated):
import { InferInsertModel, InferSelectModel, eq, relations } from 'drizzle-orm';
import { ...columntypes... } from 'drizzle-orm/pg-core';
// User Schema
export const users = pgTable('users', {
id: uuid('id').defaultRandom().primaryKey(),
// other colums
});
export type User = InferSelectModel<typeof users>;
export type NewUser = InferInsertModel<typeof users>;
This does not work (getting an error ReferenceError: Cannot access 'users' before initialization):
import { InferInsertModel, InferSelectModel, eq, relations } from 'drizzle-orm';
import { ...columntypes... } from 'drizzle-orm/pg-core';
export const userConfig = {
minUsernameLength: 5,
maxUsernameLength: 32,
maxEmailLength: 256,
maxPasswordLength: 128,
minPasswordLength: 128,
roleEnum: pgEnum('role', ['user', 'mod', 'admin']),
};
// User Schema
export const users = pgTable('users', {
id: uuid('id').defaultRandom().primaryKey(),
username: varchar('username', { length: userConfig.maxUsernameLength }).notNull().unique(),
// other colums
});
export type User = InferSelectModel<typeof users>;
export type NewUser = InferInsertModel<typeof users>;
export function validateNewUser(
newUserData: Partial<NewUser>
): AppError | null {
const { username, email, password } = newUserData;
// function logic
}
Both the function and the config object cause the ReferenceError, it just points to the first variable declared in the schema file (in the code above it points to the userConfig being accessed before initialization, if the export is removed it points to the pgTable). The problem is resolved when the only exported variable is the schema itself (the types are okay)
I think the part that made me confused is this part of the documentation:
https://orm.drizzle.team/docs/sql-schema-declaration
The last code example contains a insertUser function which made me think it's okay to put other functions in the schema file
I also noticed today - when running into the same error - that when there are circular dependencies between two files, where one of them is the schema, the same error is outputted. In this case I was completely helpless, wouldn't make it out alive if not for phind.com chatbot :ppp
This issue could have been easily avoided if that schema documentation had been properly proofread. Just wasted many hours debugging this issue :/
This should be addressed better in newer versions of Drizzle ORM and Kit. Kit will filter for only DB entities (tables, enums, etc.) and the documentation now recommends having the schema declaration separate from custom logic. If anything can be improved then anyone can feel free to open a new issue.