diff --git a/packages/cli/src/Init.ts b/packages/cli/src/Init.ts index 22ccc90f50c5..7c044c88b76f 100644 --- a/packages/cli/src/Init.ts +++ b/packages/cli/src/Init.ts @@ -20,19 +20,20 @@ import { match, P } from 'ts-pattern' import { isError } from 'util' import { printError } from './utils/prompt/utils/print' -import { getDefaultSchemaModel, getSchemaModelCockroachDb, getSchemaModelMongoDb } from './utils/schemaGenerator' export const defaultSchema = (props?: { datasourceProvider?: ConnectorType generatorProvider?: string previewFeatures?: string[] output?: string + withModel?: boolean }) => { const { datasourceProvider = 'postgresql', generatorProvider = defaultGeneratorProvider, previewFeatures = defaultPreviewFeatures, output = defaultOutput, + withModel = false, } = props || {} const aboutAccelerate = `\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? @@ -40,7 +41,7 @@ export const defaultSchema = (props?: { const isProviderCompatibleWithAccelerate = datasourceProvider !== 'sqlite' - return `// This is your Prisma schema file, + let schema = `// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema ${isProviderCompatibleWithAccelerate ? aboutAccelerate : ''} generator client { @@ -56,17 +57,40 @@ datasource db { url = env("DATABASE_URL") } ` -} -export const withModelSchema = (provider: ConnectorType = 'postgresql') => { - switch (provider) { - case 'mongodb': - return getSchemaModelMongoDb(provider) - case 'cockroachdb': - return getSchemaModelCockroachDb(provider) - default: - return getDefaultSchemaModel(provider) + // We add a model to the schema file if the user passed the --with-model flag + if (withModel) { + const defaultAttributes = `email String @unique + name String?` + + switch (datasourceProvider) { + case 'mongodb': + schema += ` +model User { + id String @id @default(auto()) @map("_id") @db.ObjectId + ${defaultAttributes} +} +` + break + case 'cockroachdb': + schema += ` +model User { + id BigInt @id @default(sequence()) + ${defaultAttributes} +} +` + break + default: + schema += ` +model User { + id Int @id @default(autoincrement()) + ${defaultAttributes} +} +` + } } + + return schema } export const defaultEnv = ( @@ -84,8 +108,8 @@ export const defaultEnv = ( return env } -export const defaultPort = (provider: ConnectorType) => { - switch (provider) { +export const defaultPort = (datasourceProvider: ConnectorType) => { + switch (datasourceProvider) { case 'mysql': return 3306 case 'sqlserver': @@ -101,8 +125,12 @@ export const defaultPort = (provider: ConnectorType) => { return undefined } -export const defaultURL = (provider: ConnectorType, port = defaultPort(provider), schema = 'public') => { - switch (provider) { +export const defaultURL = ( + datasourceProvider: ConnectorType, + port = defaultPort(datasourceProvider), + schema = 'public', +) => { + switch (datasourceProvider) { case 'postgresql': return `postgresql://johndoe:randompassword@localhost:${port}/mydb?schema=${schema}` case 'cockroachdb': @@ -240,22 +268,28 @@ export class Init implements Command { process.exit(1) } - const { provider, url } = await match(args) + const { datasourceProvider, url } = await match(args) .with( { - '--datasource-provider': P.when((provider): provider is string => Boolean(provider)), + '--datasource-provider': P.when((datasourceProvider): datasourceProvider is string => + Boolean(datasourceProvider), + ), }, (input) => { - const providerLowercase = input['--datasource-provider'].toLowerCase() - if (!['postgresql', 'mysql', 'sqlserver', 'sqlite', 'mongodb', 'cockroachdb'].includes(providerLowercase)) { + const datasourceProviderLowercase = input['--datasource-provider'].toLowerCase() + if ( + !['postgresql', 'mysql', 'sqlserver', 'sqlite', 'mongodb', 'cockroachdb'].includes( + datasourceProviderLowercase, + ) + ) { throw new Error( `Provider "${args['--datasource-provider']}" is invalid or not supported. Try again with "postgresql", "mysql", "sqlite", "sqlserver", "mongodb" or "cockroachdb".`, ) } - const provider = providerLowercase as ConnectorType - const url = defaultURL(provider) + const datasourceProvider = datasourceProviderLowercase as ConnectorType + const url = defaultURL(datasourceProvider) return Promise.resolve({ - provider, + datasourceProvider, url, }) }, @@ -280,14 +314,14 @@ export class Init implements Command { } } - const provider = protocolToConnectorType(`${url.split(':')[0]}:`) - return { provider, url } + const datasourceProvider = protocolToConnectorType(`${url.split(':')[0]}:`) + return { datasourceProvider, url } }, ) .otherwise(() => { // Default to PostgreSQL return Promise.resolve({ - provider: 'postgresql' as ConnectorType, + datasourceProvider: 'postgresql' as ConnectorType, url: undefined, }) }) @@ -307,19 +341,16 @@ export class Init implements Command { fs.mkdirSync(prismaFolder) } - if (args['--with-model']) { - fs.writeFileSync(path.join(prismaFolder, 'schema.prisma'), withModelSchema(provider)) - } else { - fs.writeFileSync( - path.join(prismaFolder, 'schema.prisma'), - defaultSchema({ - datasourceProvider: provider, - generatorProvider, - previewFeatures, - output, - }), - ) - } + fs.writeFileSync( + path.join(prismaFolder, 'schema.prisma'), + defaultSchema({ + datasourceProvider, + generatorProvider, + previewFeatures, + output, + withModel: args['--with-model'], + }), + ) const warnings: string[] = [] const envPath = path.join(outputDir, '.env') @@ -356,7 +387,7 @@ export class Init implements Command { const steps: string[] = [] - if (provider === 'mongodb') { + if (datasourceProvider === 'mongodb') { steps.push(`Define models in the schema.prisma file.`) } else { steps.push( diff --git a/packages/cli/src/__tests__/commands/Init.test.ts b/packages/cli/src/__tests__/commands/Init.test.ts index cd6c26c79476..d286cf034f74 100644 --- a/packages/cli/src/__tests__/commands/Init.test.ts +++ b/packages/cli/src/__tests__/commands/Init.test.ts @@ -3,7 +3,7 @@ import fs from 'fs' import { join } from 'path' import stripAnsi from 'strip-ansi' -import { defaultEnv, defaultGitIgnore, defaultSchema, withModelSchema } from '../../Init' +import { defaultEnv, defaultGitIgnore, defaultSchema } from '../../Init' const ctx = jestContext.new().add(jestConsoleContext()).assemble() @@ -237,7 +237,7 @@ test('works with --with-model param postgresql', async () => { expect(stripAnsi(result.stdout)).toMatchSnapshot() const schema = fs.readFileSync(join(ctx.tmpDir, 'prisma', 'schema.prisma'), 'utf-8') - expect(schema).toMatch(withModelSchema('postgresql')) + expect(schema).toMatch(defaultSchema({ withModel: true, datasourceProvider: 'postgresql' })) expect(schema).toMatchSnapshot() }) @@ -247,7 +247,7 @@ test('works with --with-model param mongodb', async () => { expect(stripAnsi(result.stdout)).toMatchSnapshot() const schema = fs.readFileSync(join(ctx.tmpDir, 'prisma', 'schema.prisma'), 'utf-8') - expect(schema).toMatch(withModelSchema('mongodb')) + expect(schema).toMatch(defaultSchema({ withModel: true, datasourceProvider: 'mongodb' })) expect(schema).toMatchSnapshot() }) @@ -257,7 +257,7 @@ test('works with --with-model param cockroachdb', async () => { expect(stripAnsi(result.stdout)).toMatchSnapshot() const schema = fs.readFileSync(join(ctx.tmpDir, 'prisma', 'schema.prisma'), 'utf-8') - expect(schema).toMatch(withModelSchema('cockroachdb')) + expect(schema).toMatch(defaultSchema({ withModel: true, datasourceProvider: 'cockroachdb' })) }) test('works with generator param - `go run github.com/steebchen/prisma-client-go`', async () => { @@ -277,6 +277,8 @@ test('works with generator param - `go run github.com/steebchen/prisma-client-go test('works with preview features - mock test', async () => { ctx.fixture('init') const result = await ctx.cli('init', '--preview-feature', 'mock-123') + expect(stripAnsi(result.stdout)).toMatchSnapshot() + const schema = fs.readFileSync(join(ctx.tmpDir, 'prisma', 'schema.prisma'), 'utf-8') expect(schema).toMatch( defaultSchema({ diff --git a/packages/cli/src/__tests__/commands/__snapshots__/Init.test.ts.snap b/packages/cli/src/__tests__/commands/__snapshots__/Init.test.ts.snap index c7e9b4095500..11ba73841b90 100644 --- a/packages/cli/src/__tests__/commands/__snapshots__/Init.test.ts.snap +++ b/packages/cli/src/__tests__/commands/__snapshots__/Init.test.ts.snap @@ -135,16 +135,15 @@ datasource db { " `; -exports[`works with custom output 1`] = ` +exports[`works with --with-model param cockroachdb 1`] = ` " ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. Next steps: 1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started -2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb. -3. Run prisma db pull to turn your database schema into a Prisma schema. -4. Run prisma generate to generate the Prisma Client. You can then start querying your database. +2. Run prisma db pull to turn your database schema into a Prisma schema. +3. Run prisma generate to generate the Prisma Client. You can then start querying your database. More information in our documentation: https://pris.ly/d/getting-started @@ -157,35 +156,15 @@ https://pris.ly/d/getting-started " `; -exports[`works with custom output 2`] = ` -"// This is your Prisma schema file, -// learn more about it in the docs: https://pris.ly/d/prisma-schema - -// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? -// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init - -generator client { - provider = "prisma-client-js" - output = "./db" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} -" -`; - -exports[`works with generator param - \`go run github.com/steebchen/prisma-client-go\` 1`] = ` +exports[`works with --with-model param mongodb 1`] = ` " ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. Next steps: 1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started -2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb. -3. Run prisma db pull to turn your database schema into a Prisma schema. -4. Run prisma generate to generate the Prisma Client. You can then start querying your database. +2. Define models in the schema.prisma file. +3. Run prisma generate to generate the Prisma Client. You can then start querying your database. More information in our documentation: https://pris.ly/d/getting-started @@ -198,7 +177,7 @@ https://pris.ly/d/getting-started " `; -exports[`works with generator param - \`go run github.com/steebchen/prisma-client-go\` 2`] = ` +exports[`works with --with-model param mongodb 2`] = ` "// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema @@ -206,17 +185,23 @@ exports[`works with generator param - \`go run github.com/steebchen/prisma-clien // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init generator client { - provider = "go run github.com/steebchen/prisma-client-go" + provider = "prisma-client-js" } datasource db { - provider = "postgresql" + provider = "mongodb" url = env("DATABASE_URL") } + +model User { + id String @id @default(auto()) @map("_id") @db.ObjectId + email String @unique + name String? +} " `; -exports[`works with preview features - mock test 1`] = ` +exports[`works with --with-model param postgresql 1`] = ` " ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. @@ -238,7 +223,7 @@ https://pris.ly/d/getting-started " `; -exports[`works with preview features - mock test 2`] = ` +exports[`works with --with-model param postgresql 2`] = ` "// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema @@ -247,17 +232,22 @@ exports[`works with preview features - mock test 2`] = ` generator client { provider = "prisma-client-js" - previewFeatures = ["mock-123"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? +} " `; -exports[`works with preview features - multiple 1`] = ` +exports[`works with custom output 1`] = ` " ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. @@ -279,7 +269,7 @@ https://pris.ly/d/getting-started " `; -exports[`works with preview features - multiple 2`] = ` +exports[`works with custom output 2`] = ` "// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema @@ -288,7 +278,7 @@ exports[`works with preview features - multiple 2`] = ` generator client { provider = "prisma-client-js" - previewFeatures = ["mock-123", "mock-456"] + output = "./db" } datasource db { @@ -298,80 +288,89 @@ datasource db { " `; -exports[`works with --with-model param cockroachdb 1`] = ` - +exports[`works with generator param - \`go run github.com/steebchen/prisma-client-go\` 1`] = ` +" ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. Next steps: 1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started -2. Run prisma db pull to turn your database schema into a Prisma schema. -3. Run prisma generate to generate the Prisma Client. You can then start querying your database. +2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb. +3. Run prisma db pull to turn your database schema into a Prisma schema. +4. Run prisma generate to generate the Prisma Client. You can then start querying your database. More information in our documentation: https://pris.ly/d/getting-started - + +┌────────────────────────────────────────────────────────────────┐ +│ Developing real-time features? │ +│ Prisma Pulse lets you respond instantly to database changes. │ +│ https://pris.ly/cli/pulse │ +└────────────────────────────────────────────────────────────────┘ + " `; -exports[`works with --with-model param cockroachdb 2`] = ` -// This is your Prisma schema file, +exports[`works with generator param - \`go run github.com/steebchen/prisma-client-go\` 2`] = ` +"// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + generator client { - provider = "prisma-client-js" + provider = "go run github.com/steebchen/prisma-client-go" } datasource db { - provider = "cockroachdb" + provider = "postgresql" url = env("DATABASE_URL") } - -model User { - id BigInt @id @default(sequence()) - email String @unique - name String? -} - +" `; -exports[`works with --with-model param mongodb 1`] = ` - +exports[`works with preview features - mock test 1`] = ` +" ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. Next steps: 1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started -2. Define models in the schema.prisma file. -3. Run prisma generate to generate the Prisma Client. You can then start querying your database. +2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb. +3. Run prisma db pull to turn your database schema into a Prisma schema. +4. Run prisma generate to generate the Prisma Client. You can then start querying your database. More information in our documentation: https://pris.ly/d/getting-started - + +┌────────────────────────────────────────────────────────────────┐ +│ Developing real-time features? │ +│ Prisma Pulse lets you respond instantly to database changes. │ +│ https://pris.ly/cli/pulse │ +└────────────────────────────────────────────────────────────────┘ + " `; -exports[`works with --with-model param mongodb 2`] = ` -// This is your Prisma schema file, +exports[`works with preview features - mock test 2`] = ` +"// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + generator client { provider = "prisma-client-js" + previewFeatures = ["mock-123"] } datasource db { - provider = "mongodb" + provider = "postgresql" url = env("DATABASE_URL") } - -model User { - id String @id @default(auto()) @map("_id") @db.ObjectId - email String @unique - name String? -} - +" `; -exports[`works with --with-model param postgresql 1`] = ` - +exports[`works with preview features - multiple 1`] = ` +" ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. @@ -383,28 +382,32 @@ Next steps: More information in our documentation: https://pris.ly/d/getting-started - + +┌────────────────────────────────────────────────────────────────┐ +│ Developing real-time features? │ +│ Prisma Pulse lets you respond instantly to database changes. │ +│ https://pris.ly/cli/pulse │ +└────────────────────────────────────────────────────────────────┘ + " `; -exports[`works with --with-model param postgresql 2`] = ` -// This is your Prisma schema file, +exports[`works with preview features - multiple 2`] = ` +"// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + generator client { provider = "prisma-client-js" + previewFeatures = ["mock-123", "mock-456"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } - -model User { - id Int @id @default(autoincrement()) - email String @unique - name String? -} - +" `; exports[`works with provider and url params - cockroachdb 1`] = ` diff --git a/packages/cli/src/utils/schemaGenerator.ts b/packages/cli/src/utils/schemaGenerator.ts deleted file mode 100644 index 8b3aa2f9f66a..000000000000 --- a/packages/cli/src/utils/schemaGenerator.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ConnectorType } from '@prisma/generator-helper' - -import { defaultSchema } from '../Init' - -const defaultAttributes = `email String @unique - name String?` - -export const getDefaultSchemaModel = (provider: ConnectorType) => { - return defaultSchema(provider).concat(` -model User { - id Int @id @default(autoincrement()) - ${defaultAttributes} -} -`) -} - -export const getSchemaModelMongoDb = (provider: ConnectorType) => { - return defaultSchema(provider).concat(` -model User { - id String @id @default(auto()) @map("_id") @db.ObjectId - ${defaultAttributes} -} -`) -} - -export const getSchemaModelCockroachDb = (provider: ConnectorType) => { - return defaultSchema(provider).concat(` -model User { - id BigInt @id @default(sequence()) - ${defaultAttributes} -} -`) -}