Add databaseTypes.ts file generation#16
Conversation
WalkthroughAdds a dedicated database type generator and a new Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as scaffold.ts
participant Init as initializeRoot
participant FS as File System
participant ScDB as scaffoldDatabase
participant GenSchema as generateDrizzleSchema
participant GenTypes as generateDatabaseTypes
CLI->>Init: initializeRoot(projectName, templatesDirectory)
Init->>FS: create `src/types` (typesDirectory)
Init-->>CLI: {backendDir, frontendDir, assetsDir, typesDir}
CLI->>ScDB: scaffoldDatabase(..., typesDir)
alt orm === "drizzle"
ScDB->>GenSchema: generateDrizzleSchema({databaseEngine, authProvider})
GenSchema-->>ScDB: schema string
ScDB->>FS: write schema file
ScDB->>GenTypes: generateDatabaseTypes({databaseHost, authProvider})
GenTypes-->>ScDB: types string
ScDB->>FS: write typesDir/databaseTypes.ts
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/generators/configurations/initializeRoot.ts(2 hunks)src/generators/db/generateDatabaseTypes.ts(1 hunks)src/generators/db/generateDrizzleSchema.ts(1 hunks)src/generators/db/scaffoldDatabase.ts(4 hunks)src/scaffold.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/generators/db/scaffoldDatabase.ts (1)
src/generators/db/generateDatabaseTypes.ts (1)
generateDatabaseTypes(8-42)
src/generators/db/generateDatabaseTypes.ts (1)
src/types.ts (2)
DatabaseHost(49-49)AuthProvider(40-40)
🔇 Additional comments (14)
src/generators/configurations/initializeRoot.ts (2)
17-18: LGTM!The types directory creation follows the same pattern as other directories in this initialization function and is properly placed within the src directory structure.
44-49: LGTM!The return object is correctly extended to include
typesDirectory, maintaining backwards compatibility by preserving all existing fields.src/scaffold.ts (2)
49-54: LGTM!The destructuring correctly extracts the new
typesDirectoryfield frominitalizeRoot's return value.
110-111: LGTM!The
typesDirectoryparameter is correctly passed toscaffoldDatabase, completing the propagation of the types directory path through the scaffolding pipeline.src/generators/db/scaffoldDatabase.ts (4)
9-9: LGTM!The import of
generateDatabaseTypesis correctly added to support the new type generation functionality.
26-26: LGTM!The
typesDirectoryparameter is correctly added to both the type definition and function signature, maintaining consistency with other directory parameters.Also applies to: 36-37
91-94: LGTM!The removal of
databaseHostfromgenerateDrizzleSchemais correct, as database-specific type generation has been decoupled and moved togenerateDatabaseTypes.
101-105: I need to search the codebase directly for the type definitions and validation ofdatabaseHost. Let me check the relevant files:Based on my verification, I found that the original review comment flagged a legitimate concern about the
generateDatabaseTypesfunction. The search results confirm that:
generateDatabaseTypesinsrc/generators/db/generateDatabaseTypes.tsonly explicitly handles three cases:'neon','planetscale', and'turso'- There is no else clause or default case after line 24, which means if
databaseHostis any other value (including'none'orundefined), noDatabaseTypeexport is generated- The function is called with
databaseHostparameter at line 101-105 inscaffoldDatabase.tsHowever, I was unable to definitively verify:
- Whether
databaseHostcan actually reach this code path with'none'orundefinedvalues in practice- Whether any code actually imports and uses the generated
DatabaseTypetype- Whether upstream validation prevents invalid
databaseHostvalues from reaching this functionThe original issue is valid in principle—incomplete type generation for unhandled cases is a code quality concern—but the actual impact depends on runtime constraints and usage patterns that require manual verification.
Verify handling of unhandled
databaseHostvalues ingenerateDatabaseTypesfunction.The function at
src/generators/db/generateDatabaseTypes.tsonly handles three cases ('neon','planetscale','turso'). IfdatabaseHosthas any other value, theDatabaseTypetype export is omitted from the generated file. Confirm whether:
- Code paths can reach this function with values other than the three handled cases
- Whether any module imports the generated
DatabaseTypeand would fail if missing- Whether upstream validation prevents invalid
databaseHostvaluessrc/generators/db/generateDatabaseTypes.ts (3)
1-6: LGTM!The type definition and imports are appropriate for the function's requirements.
26-35: LGTM!The conditional logic for
authProvidercorrectly generates appropriate imports and type exports. The relative import path'../../db/schema'assumes the generated file will be atsrc/types/databaseTypes.tswith the schema atsrc/db/schema.ts, which aligns with the directory structure created byinitializeRoot.
37-41: Template assembly is correct but depends on upstream validation.The string template correctly assembles the type definitions. However, the conditional on Line 40 that adds extra newlines only when
dbTypeLineexists means the generated file structure will differ based on whether a validdatabaseHostwas provided. This is related to the issue flagged in lines 12-24 regarding unhandleddatabaseHostvalues.src/generators/db/generateDrizzleSchema.ts (3)
1-1: LGTM!The removal of
DatabaseHostfrom imports is correct, as this parameter is no longer used in schema generation.
54-64: LGTM!The removal of
databaseHostfrom the function signature is correct and represents a clean separation of concerns. Schema generation now focuses solely on table definitions, while database-specific type generation is handled separately bygenerateDatabaseTypes.
121-134: LGTM!The schema export correctly provides the
SchemaTypethat is consumed bygenerateDatabaseTypesto create type-safe database type definitions. The integration between schema generation and type generation is well-structured.
| let dbImport = ''; | ||
| let dbTypeLine = ''; | ||
| if (databaseHost === 'neon') { | ||
| dbImport = `import { NeonHttpDatabase } from 'drizzle-orm/neon-http';`; | ||
| dbTypeLine = 'export type DatabaseType = NeonHttpDatabase<SchemaType>;'; | ||
| } else if (databaseHost === 'planetscale') { | ||
| dbImport = `import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless';`; | ||
| dbTypeLine = | ||
| 'export type DatabaseType = PlanetScaleDatabase<SchemaType>;'; | ||
| } else if (databaseHost === 'turso') { | ||
| dbImport = `import { LibSQLDatabase } from 'drizzle-orm/libsql';`; | ||
| dbTypeLine = 'export type DatabaseType = LibSQLDatabase<SchemaType>;'; | ||
| } |
There was a problem hiding this comment.
Add handling for unhandled databaseHost values.
The function only handles 'neon', 'planetscale', and 'turso' as databaseHost values, but according to the type definition, databaseHost can also be undefined or 'none'. When an unhandled value is provided, dbImport and dbTypeLine remain empty strings, resulting in a generated file without a DatabaseType export. This will cause TypeScript compilation errors if downstream code imports or references DatabaseType.
Consider one of the following approaches:
- Add validation to prevent calling this function with unsupported
databaseHostvalues - Add a default case that throws an error for unsupported values
- Return early or skip file generation for non-hosted database scenarios
Apply this diff to add validation:
export const generateDatabaseTypes = ({
databaseHost,
authProvider
}: GenerateTypesProps) => {
+ // Skip type generation for non-hosted databases
+ if (!databaseHost || databaseHost === 'none') {
+ return null;
+ }
+
let dbImport = '';
let dbTypeLine = '';
if (databaseHost === 'neon') {
dbImport = `import { NeonHttpDatabase } from 'drizzle-orm/neon-http';`;
dbTypeLine = 'export type DatabaseType = NeonHttpDatabase<SchemaType>;';
} else if (databaseHost === 'planetscale') {
dbImport = `import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless';`;
dbTypeLine =
'export type DatabaseType = PlanetScaleDatabase<SchemaType>;';
} else if (databaseHost === 'turso') {
dbImport = `import { LibSQLDatabase } from 'drizzle-orm/libsql';`;
dbTypeLine = 'export type DatabaseType = LibSQLDatabase<SchemaType>;';
+ } else {
+ throw new Error(`Unsupported databaseHost: ${databaseHost}`);
}Then update the caller in scaffoldDatabase.ts to handle the null return:
const drizzleTypes = generateDatabaseTypes({
authProvider,
databaseHost
});
if (drizzleTypes !== null) {
writeFileSync(join(typesDirectory, 'databaseTypes.ts'), drizzleTypes);
}| ...(authProvider === 'absoluteAuth' | ||
| ? [`import { schema } from '../../db/schema'`, `import { User } from '../types/databaseTypes'`] | ||
| : [`import { schema } from '../../db/schema'`]) |
There was a problem hiding this comment.
🧩 Analysis chain
Verify the import path and User type availability.
The User type import has been moved from '../../db/schema' to '../types/databaseTypes'. Ensure that:
- The relative path
'../types/databaseTypes'correctly resolves to the new typesDirectory location from the generated backend file - The
Usertype is properly exported from the generateddatabaseTypes.tsfile
Run the following script to verify the import path and type availability:
🏁 Script executed:
#!/bin/bash
# Description: Verify the User type is exported from the new databaseTypes file and check path consistency
# Find where generateDatabaseTypes creates the types file
echo "=== Checking generateDatabaseTypes implementation ==="
ast-grep --pattern 'export $_ generateDatabaseTypes($$$) {
$$$
}'
# Search for User type exports in database type generation
echo -e "\n=== Searching for User type exports ==="
rg -nP --type=ts 'export\s+(type|interface)\s+User\b' -C 3
# Check where the imports are being written relative to backend directory
echo -e "\n=== Checking typesDirectory usage in scaffolding ==="
rg -nP --type=ts 'typesDirectory' -C 2
# Verify the generated imports structure
echo -e "\n=== Checking other usages of schema imports ==="
rg -nP --type=ts "from ['\"].*db/schema['\"]" -C 1Length of output: 5506
Fix relative import path for User type.
The User type is correctly exported from the generated databaseTypes.ts file, but the relative import path is incorrect. The path should be '../../types/databaseTypes' (not '../types/databaseTypes') to correctly resolve from the generated backend file location to src/types/databaseTypes.ts.
Update line 163 in src/generators/project/generateImportsBlock.ts:
? [`import { schema } from '../../db/schema'`, `import { User } from '../../types/databaseTypes'`]
🤖 Prompt for AI Agents
In src/generators/project/generateImportsBlock.ts around lines 162 to 164, the
relative import for the User type is wrong; change the second import path from
'../types/databaseTypes' to '../../types/databaseTypes' so the generated backend
file correctly resolves src/types/databaseTypes.ts. Update the array returned
when authProvider === 'absoluteAuth' to use `import { User } from
'../../types/databaseTypes'` while keeping the schema import as-is.
There was a problem hiding this comment.
The path is correct as the import is in src/backend/server.ts and the types file is in src/types/databaseTypes.ts
There was a problem hiding this comment.
@bnziv, you're absolutely right! I apologize for the confusion.
From src/backend/server.ts to src/types/databaseTypes.ts, the relative path '../types/databaseTypes' is indeed correct:
../goes up frombackend/tosrc/types/databaseTypesthen navigates into thetypesdirectory
The import path as written in the code is accurate. Thank you for the clarification!
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.