diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index acb12ad..75af853 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,7 +36,7 @@ jobs: - run: npm run dev -- -- --ci # This is what the user would do, minus actually starting the application - - run: cd my-sidebase-app && npx prisma generate + - run: cd my-sidebase-app && npx prisma db push && npx prisma generate # start app and curl from it - run: "cd my-sidebase-app && timeout 30 npm run dev & (sleep 10 && curl --fail localhost:3000)" diff --git a/src/messages.ts b/src/messages.ts index 13f3c15..f756bc0 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -68,6 +68,7 @@ export const sayGoodbye = (preferences: Preferences) => { } if (preferences.addModules?.includes("prisma") || preferences.setStack === "cheviot") { + sayCommand("npx prisma db push", "Initialize the database") sayCommand("npx prisma generate", "Initialize the Prisma client") } diff --git a/src/steps/2.addModules/moduleConfigs.ts b/src/steps/2.addModules/moduleConfigs.ts index ddedbc5..a4f6db1 100644 --- a/src/steps/2.addModules/moduleConfigs.ts +++ b/src/steps/2.addModules/moduleConfigs.ts @@ -2,7 +2,7 @@ import { NuxtConfig } from "@nuxt/schema" import { Dependency } from "../../utils/addPackageDependency" /** - * PRISMA FILE CONTENTS, from: `npx prisma init` + * PRISMA FILE CONTENTS */ const prismaFile = `// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema @@ -29,6 +29,75 @@ const prismaEnvFile = `# Prisma DATABASE_URL=file:./db.sqlite ` +const prismaExampleEndpoint = `/** + * Fetch all \`examples\` from the database. Run \`npx prisma generate\` and \`npx prisma db push\` for this to work. + * + * If you are using \`tRPC\` you can access the prisma-client by adding it to the context: + * \`\`\`ts + * export async function createContext(event: H3Event) { + * return { prisma: event.context.prisma } + * } + * + * export type Context = inferAsyncReturnType; + * \`\`\` + */ +export default defineEventHandler(event => event.context.prisma.example.findMany()) +` + +const prismaServerMiddleware = `import { PrismaClient } from '@prisma/client' + +let prisma: PrismaClient + +declare module 'h3' { + interface H3EventContext { + prisma: PrismaClient + } +} + +export default eventHandler((event) => { + if (!prisma) { + prisma = new PrismaClient() + } + event.context.prisma = prisma +}) +` + +const prismaUtils = `import { execSync } from 'child_process' + +/** + * Helper to reset the database via a programmatic prisma invocation. Helpful to add to \`beforeEach\` or \`beforeAll\` of your testing setup. + * + * WARNING: Never run this in production. + * + * Taken from https://github.com/prisma/prisma/issues/13549#issuecomment-1144883246 + * + * @param databaseUrl Connection URL to database. Inferred from \`process.env.DATABASE_URL\` if not provided + */ +export const resetDatabase = (databaseUrl?: string) => { + const url = databaseUrl || process.env.DATABASE_URL + if (!url) { + throw new Error('Cannot reset database - connection string could not be inferred.') + } + + if (process.env.NODE_ENV === 'production') { + throw new Error('This utility should not be called in production. It is meant for testing and development') + } + + execSync(\`cd \${process.cwd()} && DATABASE_URL=\${url} npx prisma db push --force-reset\`, { stdio: 'inherit' }) +} +` + +const prismaExamplePage = ` + + +` + /** * NUXT AUTH FILE CONTENTS, from: sidebase.io/nuxt-auth/ */ @@ -153,13 +222,10 @@ import type { H3Event } from 'h3' */ export async function createContext(event: H3Event) { /** - * Add any trpc-request context here. E.g., you could add \`prisma\` like this if you've set it up: + * Add any trpc-request context here. E.g., you could add \`prisma\` like this (if you've added it via sidebase): + * \`\`\`ts + * return { prisma: event.context.prisma } * \`\`\` - * const prisma = usePrisma(event) - * return { prisma } - * \`\`\` - * - * You can import \`usePrisma\` like this: \`import { usePrisma } from '@sidebase/nuxt-prisma'\` */ return {} } @@ -249,27 +315,34 @@ export const moduleConfigs: Record = { name: "@prisma/client", version: "^4.8.0", isDev: false - }, - { - name: "@sidebase/nuxt-prisma", - version: "^0.1.2", - isDev: false } ], - nuxtConfig: { - extends: ["@sidebase/nuxt-prisma"], - }, + nuxtConfig: {}, files: [{ path: ".env", content: prismaEnvFile }, { path: "prisma/schema.prisma", content: prismaFile + }, { + path: "server/api/examples.get.ts", + content: prismaExampleEndpoint + }, { + path: "server/middleware/0.prisma.ts", + content: prismaServerMiddleware + }, { + path: "prisma/utils.ts", + content: prismaUtils + }, { + path: "pages/prisma.vue", + content: prismaExamplePage }], tasksPostInstall: [ "- [ ] Prisma: Edit your `prisma/prisma.schema` to your liking", - "- [ ] Prisma: Run `npx prisma db push` to sync the schema to your database after changing it" - ] + "- [ ] Prisma: Run `npx prisma db push` to sync the schema to your database after changing the schema", + "- [ ] Prisma: Run `npx prisma generate` to re-generate the client after changing the schema" + ], + htmlForIndexVue: "

Checkout the Prisma ORM demo page here: Click me to test the Prisma ORM setup!

" }, "auth": { humanReadableName: "nuxt-auth",