Skip to content

Commit 4bd7345

Browse files
committed
auto|off|config.
1 parent 2a246c5 commit 4bd7345

File tree

4 files changed

+120
-41
lines changed

4 files changed

+120
-41
lines changed

src/commands/seed/make.mts

+72-34
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import { join } from 'pathe'
55
import { CommonArgs } from '../../arguments/common.mjs'
66
import { ExtensionArg, assertExtension } from '../../arguments/extension.mjs'
77
import { getConfigOrFail } from '../../config/get-config.mjs'
8+
import type { HasCWD } from '../../config/get-cwd.mjs'
9+
import type {
10+
DatabaseInterface,
11+
DatabaseInterfaceConfig,
12+
} from '../../config/kysely-ctl-config.mjs'
813
import { createSubcommand } from '../../utils/create-subcommand.mjs'
9-
import {
10-
getKyselyCodegenInstalledVersion,
11-
getPrismaKyselyInstalledVersion,
12-
} from '../../utils/version.mjs'
14+
import { getKyselyCodegenInstalledVersion } from '../../utils/version.mjs'
1315

1416
const args = {
1517
...CommonArgs,
@@ -58,50 +60,86 @@ const BaseMakeCommand = {
5860

5961
consola.debug('File path:', destinationFilePath)
6062

61-
const databaseInterfacePath =
62-
seeds.databaseInterfacePath ||
63-
((await getKyselyCodegenInstalledVersion(args))
64-
? 'kysely-codegen'
65-
: undefined)
63+
const databaseInterfaceConfig = await resolveDatabaseInterfaceConfig(
64+
args,
65+
seeds.databaseInterface,
66+
)
67+
consola.debug('Database interface config:', databaseInterfaceConfig)
6668

67-
consola.debug('Database interface path:', databaseInterfacePath)
69+
if (!databaseInterfaceConfig) {
70+
consola.debug('using non-type-safe seed template')
6871

69-
if (!databaseInterfacePath) {
7072
await copyFile(
7173
join(__dirname, 'templates/seed-template.ts'),
7274
destinationFilePath,
7375
)
74-
} else {
75-
const templateFile = await readFile(
76-
join(__dirname, 'templates/seed-type-safe-template.ts'),
77-
{ encoding: 'utf8' },
78-
)
7976

80-
consola.debug('templateFile', templateFile)
77+
return printSuccess(destinationFilePath)
78+
}
8179

82-
const [
83-
databaseInterfaceFilePath,
84-
databaseInterfaceName = databaseInterfaceFilePath ===
85-
'kysely-codegen' || (await getPrismaKyselyInstalledVersion(args))
86-
? 'DB'
87-
: 'Database',
88-
] = databaseInterfacePath.split('#')
80+
consola.debug('using type-safe seed template')
8981

90-
consola.debug('Database interface file path: ', databaseInterfaceFilePath)
91-
consola.debug('Database interface name: ', databaseInterfaceName)
82+
const templateFile = await readFile(
83+
join(__dirname, 'templates/seed-type-safe-template.ts'),
84+
{ encoding: 'utf8' },
85+
)
86+
consola.debug('Template file:', templateFile)
87+
88+
const databaseInterfaceName = databaseInterfaceConfig.name || 'DB'
89+
90+
const populatedTemplateFile = templateFile
91+
.replace(
92+
/<import>/,
93+
`import type ${
94+
databaseInterfaceConfig.isDefaultExport
95+
? databaseInterfaceName
96+
: `{ ${databaseInterfaceName} }`
97+
} from '${databaseInterfaceConfig.path}'`,
98+
)
99+
.replace(/<name>/, databaseInterfaceName)
100+
consola.debug('Populated template file: ', populatedTemplateFile)
92101

93-
const populatedTemplateFile = templateFile
94-
.replace(/<typename>/g, databaseInterfaceName)
95-
.replace(/<path>/g, databaseInterfaceFilePath)
102+
await writeFile(destinationFilePath, populatedTemplateFile)
96103

97-
consola.debug('Populated template file: ', populatedTemplateFile)
104+
printSuccess(destinationFilePath)
105+
},
106+
} satisfies CommandDef<typeof args>
98107

99-
await writeFile(destinationFilePath, populatedTemplateFile)
108+
function printSuccess(destinationFilePath: string): void {
109+
consola.success(`Created seed file at ${destinationFilePath}`)
110+
}
111+
112+
async function resolveDatabaseInterfaceConfig(
113+
args: HasCWD,
114+
databaseInterface: DatabaseInterface | undefined,
115+
): Promise<DatabaseInterfaceConfig | null> {
116+
if (databaseInterface === 'off') {
117+
return null
118+
}
119+
120+
if (typeof databaseInterface === 'object') {
121+
return databaseInterface
122+
}
123+
124+
if (await getKyselyCodegenInstalledVersion(args)) {
125+
return {
126+
isDefaultExport: false,
127+
name: 'DB',
128+
path: 'kysely-codegen',
100129
}
130+
}
101131

102-
consola.success(`Created seed file at ${destinationFilePath}`)
103-
},
104-
} satisfies CommandDef<typeof args>
132+
// if (await getPrismaKyselyInstalledVersion(config)) {
133+
// TODO: generates by default to ./prisma/generated/types.ts#DB
134+
// but configurable at the kysely generator config level located in ./prisma/schema.prisma
135+
// }
136+
137+
// if (await getKanelKyselyInstalledVersion(config)) {
138+
// TODO: generates by default to
139+
// }
140+
141+
return null
142+
}
105143

106144
export const MakeCommand = createSubcommand('make', BaseMakeCommand)
107145
export const LegacyMakeCommand = createSubcommand('seed:make', BaseMakeCommand)

src/config/kysely-ctl-config.mts

+40-5
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ type MigratorlessMigrationsConfig = MigrationsBaseConfig &
134134
}
135135
)
136136

137-
type SeederfulSeedsConfig = Pick<SeedsBaseConfig, 'getSeedPrefix'> & {
137+
type SeederfulSeedsConfig = Pick<
138+
SeedsBaseConfig,
139+
'databaseInterface' | 'getSeedPrefix'
140+
> & {
138141
allowJS?: never
139142
provider?: never
140143
seeder: Seeder
@@ -187,12 +190,44 @@ export type MigrationsBaseConfig = Omit<MigratorProps, 'db' | 'provider'> & {
187190

188191
export type SeedsBaseConfig = Omit<SeederProps, 'db' | 'provider'> & {
189192
/**
190-
* `Database` interface relative-to-seed-folder path, e.g. `kysely-codegen`, `../path/to/database#MyDatabaseTypeName`.
193+
* Generate type-safe seed files that rely on an existing database interface.
194+
*
195+
* Default is `'auto'`.
196+
*
197+
* When `'auto'`:
191198
*
192-
* Default is `kysely-codegen` if it is installed, otherwise `Kysely<any>`.
199+
* - When `kysely-codegen` is installed, it will use `import type { DB } from 'kysely-codegen'`.
200+
* - **SOON** When `prisma-kysely` is installed, it will try to find the right path and use `import type { DB } from 'path/to/types'`.
201+
* - **SOON** When `kanel-kysely` is installed, it will try to find the right path and use `import type Database from 'path/to/Database'`.
202+
* - Otherwise, it will fallback to `Kysely<any>`.
193203
*
194-
* If `prisma-kysely` is installed, you can leave out the `#MyDatabaseTypeName` part, it will default to `<path>#DB`.
204+
* When `'off'`, it will fallback to `Kysely<any>`.
205+
*
206+
* When a config object is passed, it will use the specified database interface path and name.
195207
*/
196-
databaseInterfacePath?: string
208+
databaseInterface?: 'auto' | 'off' | DatabaseInterfaceConfig
197209
getSeedPrefix?(): string | Promise<string>
198210
}
211+
212+
export type DatabaseInterface = 'auto' | 'off' | DatabaseInterfaceConfig
213+
214+
export interface DatabaseInterfaceConfig {
215+
/**
216+
* Whether the database interface is the default export.
217+
*
218+
* Default is `false`.
219+
*/
220+
isDefaultExport?: boolean
221+
222+
/**
223+
* Name of the database interface.
224+
*
225+
* Default is `'DB'`.
226+
*/
227+
name?: string
228+
229+
/**
230+
* Path to the database interface, relative to the seed folder.
231+
*/
232+
path: string
233+
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { <typename> } from '<path>'
21
import type { Kysely } from 'kysely'
2+
<import>
33

4-
export async function seed(db: Kysely<<typename>>): Promise<void> {
4+
export async function seed(db: Kysely<<name>>): Promise<void> {
55
// seed code goes here...
66
// note: this function is mandatory. you must implement this function.
77
}

src/utils/version.mts

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ export async function getPrismaKyselyInstalledVersion(
2727
return await getInstalledVersionFromConsumerPackageJSON(args, 'prisma-kysely')
2828
}
2929

30+
export async function getKanelKyselyInstalledVersion(
31+
args: HasCWD,
32+
): Promise<string | null> {
33+
return await getInstalledVersionFromConsumerPackageJSON(args, 'kanel-kysely')
34+
}
35+
3036
async function getInstalledVersionFromConsumerPackageJSON(
3137
args: HasCWD,
3238
name: string,

0 commit comments

Comments
 (0)