diff --git a/.changeset/unlucky-ghosts-do.md b/.changeset/unlucky-ghosts-do.md
new file mode 100644
index 0000000000..38982f7e1e
--- /dev/null
+++ b/.changeset/unlucky-ghosts-do.md
@@ -0,0 +1,5 @@
+---
+"@trigger.dev/build": minor
+---
+
+Support Prisma's official multi-file schema structure
diff --git a/docs/config/extensions/prismaExtension.mdx b/docs/config/extensions/prismaExtension.mdx
index 2d057cc264..eebc0e285c 100644
--- a/docs/config/extensions/prismaExtension.mdx
+++ b/docs/config/extensions/prismaExtension.mdx
@@ -10,8 +10,7 @@ If you are using Prisma, you should use the prisma build extension.
- Generates the Prisma client during the deploy process
- Optionally will migrate the database during the deploy process
- Support for TypedSQL and multiple schema files
-- You can use `prismaSchemaFolder` to specify just the directory containing your schema file, instead of the full path
-- You can add the extension twice if you have multiple separate schemas in the same project (example below)
+- You can set the schema to be a folder to use Prisma's multi-file schema feature (example [below](#multiple-schemas))
You can use it for a simple Prisma setup like this:
@@ -141,17 +140,32 @@ These environment variables are only used during the build process and are not e
### Multiple schemas
-If you have multiple separate schemas in the same project you can add the extension multiple times:
+Prisma supports splitting your schema into multiple files. To use this, set `schema` to be the folder that contains your root schema (e.g. `schema.prisma`).
-```ts
-prismaExtension({
- schema: 'prisma/schema/main.prisma',
- version: '6.2.0',
- migrate: false,
-}),
+For example, if your root schema is located at `./prisma/schema.prisma`, you would set the `schema` option to `prisma`:
+
+
+
+```ts trigger.config.ts
prismaExtension({
- schema: 'prisma/schema/secondary.prisma',
- version: '6.2.0',
+ schema: 'prisma',
+ version: '6.7.0',
migrate: false,
}),
```
+
+```shell Example structure
+./prisma
+├── migrations
+├── models
+│ ├── posts.prisma
+│ ├── users.prisma
+│ └── ... other `.prisma` files
+└── schema.prisma
+```
+
+
+
+
+ To use this feature you must be using `prisma@6.7.0` or higher. Their official documentation can be found [here](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema).
+
diff --git a/packages/build/src/extensions/prisma.ts b/packages/build/src/extensions/prisma.ts
index b67adc7efc..967d1301b2 100644
--- a/packages/build/src/extensions/prisma.ts
+++ b/packages/build/src/extensions/prisma.ts
@@ -1,6 +1,7 @@
import { BuildManifest, BuildTarget } from "@trigger.dev/core/v3";
import { binaryForRuntime, BuildContext, BuildExtension } from "@trigger.dev/core/v3/build";
import assert from "node:assert";
+import { glob } from 'tinyglobby';
import { existsSync } from "node:fs";
import { cp, readdir } from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
@@ -112,11 +113,18 @@ export class PrismaExtension implements BuildExtension {
context.logger.debug(`PrismaExtension is generating the Prisma client for version ${version}`);
- const usingSchemaFolder = dirname(this._resolvedSchemaPath).endsWith("schema");
+ // Multi-file schemas can be used by specifying a directory instead of a file. https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema
+ const usingSchemaFolder = !this._resolvedSchemaPath.endsWith(".prisma");
+
+ context.logger.debug(`Using schema folder: ${usingSchemaFolder}`);
const commands: string[] = [];
- let prismaDir: string | undefined;
+ const prismaSourceDir = usingSchemaFolder
+ ? this._resolvedSchemaPath
+ : dirname(this._resolvedSchemaPath);
+
+ const prismaDestinationDir = join(manifest.outputPath, "prisma");
const generatorFlags: string[] = [];
@@ -127,14 +135,10 @@ export class PrismaExtension implements BuildExtension {
if (this.options.typedSql) {
generatorFlags.push(`--sql`);
- const prismaDir = usingSchemaFolder
- ? dirname(dirname(this._resolvedSchemaPath))
- : dirname(this._resolvedSchemaPath);
-
context.logger.debug(`Using typedSql`);
// Find all the files prisma/sql/*.sql
- const sqlFiles = await readdir(join(prismaDir, "sql")).then((files) =>
+ const sqlFiles = await readdir(join(prismaSourceDir, "sql")).then((files) =>
files.filter((file) => file.endsWith(".sql"))
);
@@ -142,11 +146,11 @@ export class PrismaExtension implements BuildExtension {
sqlFiles,
});
- const sqlDestinationPath = join(manifest.outputPath, "prisma", "sql");
+ const sqlDestinationPath = join(prismaDestinationDir, "sql");
for (const file of sqlFiles) {
const destination = join(sqlDestinationPath, file);
- const source = join(prismaDir, "sql", file);
+ const source = join(prismaSourceDir, "sql", file);
context.logger.debug(`Copying the sql from ${source} to ${destination}`);
@@ -155,28 +159,20 @@ export class PrismaExtension implements BuildExtension {
}
if (usingSchemaFolder) {
- const schemaDir = dirname(this._resolvedSchemaPath);
-
- prismaDir = dirname(schemaDir);
-
- context.logger.debug(`Using the schema folder: ${schemaDir}`);
+ context.logger.debug(`Using the schema folder: ${this._resolvedSchemaPath}`);
// Find all the files in schemaDir that end with .prisma (excluding the schema.prisma file)
- const prismaFiles = await readdir(schemaDir).then((files) =>
- files.filter((file) => file.endsWith(".prisma"))
- );
+ const prismaFiles = await glob(["**/*.prisma"], {
+ cwd: this._resolvedSchemaPath
+ })
context.logger.debug(`Found prisma files in the schema folder`, {
prismaFiles,
});
- const schemaDestinationPath = join(manifest.outputPath, "prisma", "schema");
-
- const allPrismaFiles = [...prismaFiles];
-
- for (const file of allPrismaFiles) {
- const destination = join(schemaDestinationPath, file);
- const source = join(schemaDir, file);
+ for (const file of prismaFiles) {
+ const destination = join(prismaDestinationDir, file);
+ const source = join(this._resolvedSchemaPath, file);
context.logger.debug(`Copying the prisma schema from ${source} to ${destination}`);
@@ -186,15 +182,14 @@ export class PrismaExtension implements BuildExtension {
commands.push(
`${binaryForRuntime(
manifest.runtime
- )} node_modules/prisma/build/index.js generate ${generatorFlags.join(" ")}` // Don't add the --schema flag or this will fail
+ )} node_modules/prisma/build/index.js generate --schema ./prisma ${generatorFlags.join(" ")}`
);
} else {
- prismaDir = dirname(this._resolvedSchemaPath);
// Now we need to add a layer that:
// Copies the prisma schema to the build outputPath
// Adds the `prisma` CLI dependency to the dependencies
// Adds the `prisma generate` command, which generates the Prisma client
- const schemaDestinationPath = join(manifest.outputPath, "prisma", "schema.prisma");
+ const schemaDestinationPath = join(prismaDestinationDir, "schema.prisma");
// Copy the prisma schema to the build output path
context.logger.debug(
`Copying the prisma schema from ${this._resolvedSchemaPath} to ${schemaDestinationPath}`
@@ -215,8 +210,8 @@ export class PrismaExtension implements BuildExtension {
if (this.options.migrate) {
// Copy the migrations directory to the build output path
- const migrationsDir = join(prismaDir, "migrations");
- const migrationsDestinationPath = join(manifest.outputPath, "prisma", "migrations");
+ const migrationsDir = join(prismaSourceDir, "migrations");
+ const migrationsDestinationPath = join(prismaDestinationDir, "migrations");
context.logger.debug(
`Copying the prisma migrations from ${migrationsDir} to ${migrationsDestinationPath}`
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6decddb309..c4d728df8d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2375,8 +2375,8 @@ importers:
specifier: 1.4.1
version: 1.4.1
'@prisma/client':
- specifier: 5.19.0
- version: 5.19.0(prisma@5.19.0)
+ specifier: 6.8.2
+ version: 6.8.2(prisma@6.8.2)(typescript@5.5.4)
'@react-email/components':
specifier: 0.0.24
version: 0.0.24(react-dom@18.3.1)(react@19.0.0-rc.0)
@@ -2568,8 +2568,8 @@ importers:
specifier: ^0.19.11
version: 0.19.11
prisma:
- specifier: 5.19.0
- version: 5.19.0
+ specifier: 6.8.2
+ version: 6.8.2(typescript@5.5.4)
prisma-kysely:
specifier: ^1.8.0
version: 1.8.0
@@ -11431,8 +11431,8 @@ packages:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false
- /@prisma/client@5.19.0(prisma@5.19.0):
- resolution: {integrity: sha512-CzOpau+q1kEWQyoQMvlnXIHqPvwmWbh48xZ4n8KWbAql0p8PC0BIgSTYW5ncxXa4JSEff0tcoxSZB874wDstdg==}
+ /@prisma/client@5.4.1(prisma@5.4.1):
+ resolution: {integrity: sha512-xyD0DJ3gRNfLbPsC+YfMBBuLJtZKQfy1OD2qU/PZg+HKrr7SO+09174LMeTlWP0YF2wca9LxtVd4HnAiB5ketQ==}
engines: {node: '>=16.13'}
requiresBuild: true
peerDependencies:
@@ -11441,25 +11441,31 @@ packages:
prisma:
optional: true
dependencies:
- prisma: 5.19.0
+ '@prisma/engines-version': 5.4.1-1.2f302df92bd8945e20ad4595a73def5b96afa54f
+ prisma: 5.4.1
dev: false
- /@prisma/client@5.4.1(prisma@5.4.1):
- resolution: {integrity: sha512-xyD0DJ3gRNfLbPsC+YfMBBuLJtZKQfy1OD2qU/PZg+HKrr7SO+09174LMeTlWP0YF2wca9LxtVd4HnAiB5ketQ==}
- engines: {node: '>=16.13'}
+ /@prisma/client@6.8.2(prisma@6.8.2)(typescript@5.5.4):
+ resolution: {integrity: sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==}
+ engines: {node: '>=18.18'}
requiresBuild: true
peerDependencies:
prisma: '*'
+ typescript: '>=5.1.0'
peerDependenciesMeta:
prisma:
optional: true
+ typescript:
+ optional: true
dependencies:
- '@prisma/engines-version': 5.4.1-1.2f302df92bd8945e20ad4595a73def5b96afa54f
- prisma: 5.4.1
+ prisma: 6.8.2(typescript@5.5.4)
+ typescript: 5.5.4
dev: false
- /@prisma/debug@5.19.0:
- resolution: {integrity: sha512-+b/G0ubAZlrS+JSiDhXnYV5DF/aTJ3pinktkiV/L4TtLRLZO6SVGyFELgxBsicCTWJ2ZMu5vEV/jTtYCdjFTRA==}
+ /@prisma/config@6.8.2:
+ resolution: {integrity: sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==}
+ dependencies:
+ jiti: 2.4.2
/@prisma/debug@5.3.1:
resolution: {integrity: sha512-eYrxqslEKf+wpMFIIHgbcNYuZBXUdiJLA85Or3TwOhgPIN1ZoXT9CwJph3ynW8H1Xg0LkdYLwVmuULCwiMoU5A==}
@@ -11471,21 +11477,15 @@ packages:
- supports-color
dev: true
- /@prisma/engines-version@5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f:
- resolution: {integrity: sha512-GimI9aZIFy/yvvR11KfXRn3pliFn1QAkdebVlsXlnoh5uk0YhLblVmeYiHfsu+wDA7BeKqYT4sFfzg8mutzuWw==}
+ /@prisma/debug@6.8.2:
+ resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==}
/@prisma/engines-version@5.4.1-1.2f302df92bd8945e20ad4595a73def5b96afa54f:
resolution: {integrity: sha512-+nUQM/y8C+1GG5Ioeqcu6itFslCfxvQSAUVSMC9XM2G2Fcq0F4Afnp6m0pXF6X6iUBWen7jZBPmM9Qlq4Nr3/A==}
dev: false
- /@prisma/engines@5.19.0:
- resolution: {integrity: sha512-UtW+0m4HYoRSSR3LoDGKF3Ud4BSMWYlLEt4slTnuP1mI+vrV3zaDoiAPmejdAT76vCN5UqnWURbkXxf66nSylQ==}
- requiresBuild: true
- dependencies:
- '@prisma/debug': 5.19.0
- '@prisma/engines-version': 5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f
- '@prisma/fetch-engine': 5.19.0
- '@prisma/get-platform': 5.19.0
+ /@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e:
+ resolution: {integrity: sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==}
/@prisma/engines@5.3.1:
resolution: {integrity: sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==}
@@ -11496,12 +11496,14 @@ packages:
resolution: {integrity: sha512-vJTdY4la/5V3N7SFvWRmSMUh4mIQnyb/MNoDjzVbh9iLmEC+uEykj/1GPviVsorvfz7DbYSQC4RiwmlEpTEvGA==}
requiresBuild: true
- /@prisma/fetch-engine@5.19.0:
- resolution: {integrity: sha512-oOiPNtmJX0cP/ebu7BBEouJvCw8T84/MFD/Hf2zlqjxkK4ojl38bB9i9J5LAxotL6WlYVThKdxc7HqoWnPOhqQ==}
+ /@prisma/engines@6.8.2:
+ resolution: {integrity: sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==}
+ requiresBuild: true
dependencies:
- '@prisma/debug': 5.19.0
- '@prisma/engines-version': 5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f
- '@prisma/get-platform': 5.19.0
+ '@prisma/debug': 6.8.2
+ '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e
+ '@prisma/fetch-engine': 6.8.2
+ '@prisma/get-platform': 6.8.2
/@prisma/fetch-engine@5.3.1:
resolution: {integrity: sha512-w1yk1YiK8N82Pobdq58b85l6e8akyrkxuzwV9DoiUTRf3gpsuhJJesHc4Yi0WzUC9/3znizl1UfCsI6dhkj3Vw==}
@@ -11528,6 +11530,13 @@ packages:
- supports-color
dev: true
+ /@prisma/fetch-engine@6.8.2:
+ resolution: {integrity: sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==}
+ dependencies:
+ '@prisma/debug': 6.8.2
+ '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e
+ '@prisma/get-platform': 6.8.2
+
/@prisma/generator-helper@5.3.1:
resolution: {integrity: sha512-zrYS0iHLgPlOJjYnd5KvVMMvSS+ktOL39EwooS5EnyvfzwfzxlKCeOUgxTfiKYs0WUWqzEvyNAYtramYgSknsQ==}
dependencies:
@@ -11539,11 +11548,6 @@ packages:
- supports-color
dev: true
- /@prisma/get-platform@5.19.0:
- resolution: {integrity: sha512-s9DWkZKnuP4Y8uy6yZfvqQ/9X3/+2KYf3IZUVZz5OstJdGBJrBlbmIuMl81917wp5TuK/1k2TpHNCEdpYLPKmg==}
- dependencies:
- '@prisma/debug': 5.19.0
-
/@prisma/get-platform@5.3.1:
resolution: {integrity: sha512-3IiZY2BUjKnAuZ0569zppZE6/rZbVAM09//c2nvPbbkGG9MqrirA8fbhhF7tfVmhyVfdmVCHnf/ujWPHJ8B46Q==}
dependencies:
@@ -11561,6 +11565,11 @@ packages:
- supports-color
dev: true
+ /@prisma/get-platform@6.8.2:
+ resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==}
+ dependencies:
+ '@prisma/debug': 6.8.2
+
/@prisma/instrumentation@5.11.0:
resolution: {integrity: sha512-ou4nvDpNEY6+t3Dn9juOTz6tK33D0Y4XXkEZ2uPd8KH6Mqmc+4LYOOm470DP7noj7dyJjuGiM+wpPk//HKrcDg==}
dependencies:
@@ -28097,7 +28106,6 @@ packages:
/jiti@2.4.2:
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
hasBin: true
- dev: true
/joi@17.7.0:
resolution: {integrity: sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==}
@@ -32461,23 +32469,28 @@ packages:
- supports-color
dev: true
- /prisma@5.19.0:
- resolution: {integrity: sha512-Pu7lUKpVyTx8cVwM26dYh8NdvMOkMnJXzE8L6cikFuR4JwyMU5NKofQkWyxJKlTT4fNjmcnibTvklV8oVMrn+g==}
+ /prisma@5.4.1:
+ resolution: {integrity: sha512-op9PmU8Bcw5dNAas82wBYTG0yHnpq9/O3bhxbDBrNzwZTwBqsVCxxYRLf6wHNh9HVaDGhgjjHlu1+BcW8qdnBg==}
engines: {node: '>=16.13'}
hasBin: true
requiresBuild: true
dependencies:
- '@prisma/engines': 5.19.0
- optionalDependencies:
- fsevents: 2.3.3
+ '@prisma/engines': 5.4.1
- /prisma@5.4.1:
- resolution: {integrity: sha512-op9PmU8Bcw5dNAas82wBYTG0yHnpq9/O3bhxbDBrNzwZTwBqsVCxxYRLf6wHNh9HVaDGhgjjHlu1+BcW8qdnBg==}
- engines: {node: '>=16.13'}
+ /prisma@6.8.2(typescript@5.5.4):
+ resolution: {integrity: sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==}
+ engines: {node: '>=18.18'}
hasBin: true
requiresBuild: true
+ peerDependencies:
+ typescript: '>=5.1.0'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
dependencies:
- '@prisma/engines': 5.4.1
+ '@prisma/config': 6.8.2
+ '@prisma/engines': 6.8.2
+ typescript: 5.5.4
/prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
diff --git a/references/v3-catalog/package.json b/references/v3-catalog/package.json
index b637520197..c967ca9b37 100644
--- a/references/v3-catalog/package.json
+++ b/references/v3-catalog/package.json
@@ -20,7 +20,7 @@
"@effect/schema": "^0.75.5",
"@infisical/sdk": "^2.3.5",
"@opentelemetry/api": "1.4.1",
- "@prisma/client": "5.19.0",
+ "@prisma/client": "6.8.2",
"@react-email/components": "0.0.24",
"@react-email/render": "1.0.1",
"@sentry/esbuild-plugin": "^2.22.2",
@@ -87,7 +87,7 @@
"@types/fluent-ffmpeg": "^2.1.26",
"@types/react": "^18.3.1",
"esbuild": "^0.19.11",
- "prisma": "5.19.0",
+ "prisma": "6.8.2",
"prisma-kysely": "^1.8.0",
"trigger.dev": "workspace:*",
"ts-node": "^10.9.2",
diff --git a/references/v3-catalog/prisma/schema/post.prisma b/references/v3-catalog/prisma/models/post.prisma
similarity index 100%
rename from references/v3-catalog/prisma/schema/post.prisma
rename to references/v3-catalog/prisma/models/post.prisma
diff --git a/references/v3-catalog/prisma/schema/user.prisma b/references/v3-catalog/prisma/models/user.prisma
similarity index 100%
rename from references/v3-catalog/prisma/schema/user.prisma
rename to references/v3-catalog/prisma/models/user.prisma
diff --git a/references/v3-catalog/prisma/schema/schema.prisma b/references/v3-catalog/prisma/schema.prisma
similarity index 91%
rename from references/v3-catalog/prisma/schema/schema.prisma
rename to references/v3-catalog/prisma/schema.prisma
index 0834802c1f..5a1fc9638a 100644
--- a/references/v3-catalog/prisma/schema/schema.prisma
+++ b/references/v3-catalog/prisma/schema.prisma
@@ -6,7 +6,7 @@
generator client {
provider = "prisma-client-js"
- previewFeatures = ["prismaSchemaFolder", "typedSql"]
+ previewFeatures = ["typedSql"]
}
datasource db {
diff --git a/references/v3-catalog/trigger.config.ts b/references/v3-catalog/trigger.config.ts
index 62698d14fb..cb45459b87 100644
--- a/references/v3-catalog/trigger.config.ts
+++ b/references/v3-catalog/trigger.config.ts
@@ -42,7 +42,7 @@ export default defineConfig({
emitDecoratorMetadata(),
audioWaveform(),
prismaExtension({
- schema: "prisma/schema/schema.prisma",
+ schema: "prisma",
migrate: true,
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
clientGenerator: "client",