diff --git a/.changeset/six-vans-rhyme.md b/.changeset/six-vans-rhyme.md new file mode 100644 index 0000000000..78a661bd9f --- /dev/null +++ b/.changeset/six-vans-rhyme.md @@ -0,0 +1,383 @@ +--- +"@trigger.dev/build": patch +--- + +The `prismaExtension` has been completely redesigned to support multiple Prisma versions and deployment strategies. This update introduces **three distinct modes** to handle the evolving Prisma ecosystem, from legacy setups to the upcoming Prisma 7. + +**Highlights:** + +- 🎯 Three modes: Legacy, Engine-Only, and Modern +- 🎉 **NEW:** Support for `prisma.config.ts` files (Legacy Mode) +- 🔍 **NEW:** Enhanced version detection with filesystem fallback + +## Breaking Changes + +⚠️ **MIGRATION REQUIRED**: The `prismaExtension` now requires an explicit `mode` parameter. Existing configurations without a `mode` will need to be updated. + +**Note:** All other existing options remain backward compatible. The new `configFile` option is optional and doesn't affect existing setups using the `schema` option. + +### Before (Old API) + +```ts +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +extensions: [ + prismaExtension({ + schema: "prisma/schema.prisma", + migrate: true, + typedSql: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", + }), +]; +``` + +### After (New API) + +```ts +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +extensions: [ + prismaExtension({ + mode: "legacy", // ← MODE IS NOW REQUIRED + schema: "prisma/schema.prisma", + migrate: true, + typedSql: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", + }), +]; +``` + +## New Features + +### 1. Legacy Mode + +**Use when:** You're using Prisma 6.x or earlier with the `prisma-client-js` provider. + +**Features:** + +- Automatic `prisma generate` during deployment +- Supports single-file schemas (`prisma/schema.prisma`) +- Supports multi-file schemas (Prisma 6.7+, directory-based schemas) +- **NEW:** Supports Prisma config files (`prisma.config.ts`) via `@prisma/config` package +- Migration support with `migrate: true` +- TypedSQL support with `typedSql: true` +- Custom generator selection +- Handles Prisma client versioning automatically (with filesystem fallback detection) +- Automatic extraction of schema and migrations paths from config files + +**Schema Configuration:** + +```prisma +generator client { + provider = "prisma-client-js" + previewFeatures = ["typedSql"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} +``` + +**Extension Configuration:** + +```ts +// Single-file schema +prismaExtension({ + mode: "legacy", + schema: "prisma/schema.prisma", + migrate: true, + typedSql: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", +}); + +// Multi-file schema (Prisma 6.7+) +prismaExtension({ + mode: "legacy", + schema: "./prisma", // ← Point to directory + migrate: true, + typedSql: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", +}); +``` + +**Tested Versions:** + +- Prisma 6.14.0 ✅ +- Prisma 6.7.0+ (multi-file schema support) ✅ +- Prisma 5.x ✅ + +--- + +### 2. Engine-Only Mode + +**Use when:** You have a custom Prisma client output path and want to manage `prisma generate` yourself. + +**Features:** + +- Only installs Prisma engine binaries (no client generation) +- Automatic version detection from `@prisma/client` +- Manual override of version and binary target +- Minimal overhead - just ensures engines are available +- You control when and how `prisma generate` runs + +**Schema Configuration:** + +```prisma +generator client { + provider = "prisma-client-js" + output = "../src/generated/prisma" + // Ensure the "debian-openssl-3.0.x" binary target is included for deployment to the trigger.dev cloud + binaryTargets = ["native", "debian-openssl-3.0.x"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} +``` + +**Extension Configuration:** + +```ts +// Auto-detect version +prismaExtension({ + mode: "engine-only", +}); + +// Explicit version (recommended for reproducible builds) +prismaExtension({ + mode: "engine-only", + version: "6.19.0", +}); +``` + +**Important Notes:** + +- You **must** run `prisma generate` yourself (typically in a prebuild script) +- Your schema **must** include the correct `binaryTargets` for deployment to the trigger.dev cloud. The binary target is `debian-openssl-3.0.x`. +- The extension sets `PRISMA_QUERY_ENGINE_LIBRARY` and `PRISMA_QUERY_ENGINE_SCHEMA_ENGINE` environment variables to the correct paths for the binary targets. + +**package.json Example:** + +```json +{ + "scripts": { + "prebuild": "prisma generate", + "dev": "trigger dev", + "deploy": "trigger deploy" + } +} +``` + +**Tested Versions:** + +- Prisma 6.19.0 ✅ +- Prisma 6.16.0+ ✅ + +--- + +### 3. Modern Mode + +**Use when:** You're using Prisma 6.16+ with the new `prisma-client` provider (with `engineType = "client"`) or preparing for Prisma 7. + +**Features:** + +- Designed for the new Prisma architecture +- Zero configuration required +- Automatically marks `@prisma/client` as external +- Works with Prisma 7 beta releases & Prisma 7 when released +- You manage client generation (like engine-only mode) + +**Schema Configuration (Prisma 6.16+ with engineType):** + +```prisma +generator client { + provider = "prisma-client" + output = "../src/generated/prisma" + engineType = "client" + previewFeatures = ["views"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} +``` + +**Schema Configuration (Prisma 7):** + +```prisma +generator client { + provider = "prisma-client" + output = "../src/generated/prisma" +} + +datasource db { + provider = "postgresql" +} +``` + +**Extension Configuration:** + +```ts +prismaExtension({ + mode: "modern", +}); +``` + +**Prisma Config (Prisma 7):** + +```ts +// prisma.config.ts +import { defineConfig, env } from "prisma/config"; +import "dotenv/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: env("DATABASE_URL"), + }, +}); +``` + +**Important Notes:** + +- You **must** run `prisma generate` yourself +- Requires Prisma 6.16.0+ or Prisma 7 beta +- The new `prisma-client` provider generates plain TypeScript (no Rust binaries) +- Requires database adapters (e.g., `@prisma/adapter-pg` for PostgreSQL) + +**Tested Versions:** + +- Prisma 6.16.0 with `engineType = "client"` ✅ +- Prisma 6.20.0-integration-next.8 (Prisma 7 beta) ✅ + +--- + +## Migration Guide + +### From Old prismaExtension to Legacy Mode + +If you were using the previous `prismaExtension`, migrate to **Legacy Mode**: + +```ts +// Old +prismaExtension({ + schema: "prisma/schema.prisma", + migrate: true, +}); + +// New +prismaExtension({ + mode: "legacy", // ← Add this + schema: "prisma/schema.prisma", + migrate: true, +}); +``` + +### From Managing Your Own Prisma Setup + +If you previously handled Prisma generation yourself and just needed engine binaries, use **Engine-Only Mode**: + +```ts +prismaExtension({ + mode: "engine-only", + version: "6.19.0", // Match your @prisma/client version +}); +``` + +### Preparing for Prisma 7 + +If you want to adopt the new Prisma architecture, use **Modern Mode**: + +1. Update your schema to use `prisma-client` provider +2. Add database adapters to your dependencies +3. Configure the extension: + +```ts +prismaExtension({ + mode: "modern", +}); +``` + +--- + +## Version Compatibility Matrix + +| Prisma Version | Recommended Mode | Notes | +| ---------------- | --------------------- | -------------------------------------------- | +| < 5.0 | Legacy | Older Prisma versions | +| 5.0 - 6.15 | Legacy | Standard Prisma setup | +| 6.7+ | Legacy | Multi-file schema support | +| 6.16+ | Engine-Only or Modern | Modern mode requires `engineType = "client"` | +| 6.20+ (7.0 beta) | Modern | Prisma 7 with new architecture | + +--- + +## Prisma Config File Support (Prisma 6+) + +**NEW:** Legacy Mode now supports loading configuration from a `prisma.config.ts` file using the official `@prisma/config` package. + +**Use when:** You want to use Prisma's new config file format (Prisma 6+) to centralize your Prisma configuration. + +**Benefits:** + +- Single source of truth for Prisma configuration +- Automatic extraction of schema location and migrations path +- Type-safe configuration with TypeScript +- Works seamlessly with Prisma 7's config-first approach + +**prisma.config.ts:** + +```ts +import { defineConfig, env } from "prisma/config"; +import "dotenv/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: env("DATABASE_URL"), + directUrl: env("DATABASE_URL_UNPOOLED"), + }, +}); +``` + +**trigger.config.ts:** + +```ts +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +prismaExtension({ + mode: "legacy", + configFile: "./prisma.config.ts", // ← Use config file instead of schema + migrate: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", // For migrations +}); +``` + +**What gets extracted:** + +- `schema` - The schema file or directory path +- `migrations.path` - The migrations directory path (if specified) + +**Note:** Either `schema` or `configFile` must be specified, but not both. + +**When to use which:** + +| Use `schema` option | Use `configFile` option | +| ---------------------------- | --------------------------------- | +| Standard Prisma setup | Using Prisma 6+ with config files | +| Single or multi-file schemas | Preparing for Prisma 7 | +| No `prisma.config.ts` file | Centralized configuration needed | +| Simple setup | Want migrations path in config | + diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index db78308a43..72ffd3290a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,7 +36,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 - name: 📥 Download deps run: pnpm install --frozen-lockfile --filter trigger.dev... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 686240aaef..120b0bda92 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 cache: "pnpm" - name: 📥 Download deps diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index acd1fb3d64..baaec51c95 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -24,7 +24,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 cache: "pnpm" - name: 📥 Download deps diff --git a/.github/workflows/unit-tests-internal.yml b/.github/workflows/unit-tests-internal.yml index 5acac054a6..bd685813ea 100644 --- a/.github/workflows/unit-tests-internal.yml +++ b/.github/workflows/unit-tests-internal.yml @@ -58,7 +58,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 cache: "pnpm" # ..to avoid rate limits when pulling images @@ -116,7 +116,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 # no cache enabled, we're not installing deps - name: Download blob reports from GitHub Actions Artifacts diff --git a/.github/workflows/unit-tests-packages.yml b/.github/workflows/unit-tests-packages.yml index cfa5e88baa..d37213529c 100644 --- a/.github/workflows/unit-tests-packages.yml +++ b/.github/workflows/unit-tests-packages.yml @@ -58,7 +58,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 cache: "pnpm" # ..to avoid rate limits when pulling images @@ -116,7 +116,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 # no cache enabled, we're not installing deps - name: Download blob reports from GitHub Actions Artifacts diff --git a/.github/workflows/unit-tests-webapp.yml b/.github/workflows/unit-tests-webapp.yml index ff00525825..1ede8b252f 100644 --- a/.github/workflows/unit-tests-webapp.yml +++ b/.github/workflows/unit-tests-webapp.yml @@ -58,7 +58,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 cache: "pnpm" # ..to avoid rate limits when pulling images @@ -124,7 +124,7 @@ jobs: - name: ⎔ Setup node uses: buildjet/setup-node@v4 with: - node-version: 20.11.1 + node-version: 20.19.0 # no cache enabled, we're not installing deps - name: Download blob reports from GitHub Actions Artifacts diff --git a/.nvmrc b/.nvmrc index 2efc7e111f..3bf34c2761 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v20.11.1 \ No newline at end of file +v20.19.0 \ No newline at end of file diff --git a/packages/build/package.json b/packages/build/package.json index fc8f4009db..52cab43dc3 100644 --- a/packages/build/package.json +++ b/packages/build/package.json @@ -77,17 +77,21 @@ "check-exports": "attw --pack ." }, "dependencies": { + "@prisma/config": "^6.10.0", "@trigger.dev/core": "workspace:4.1.0", + "mlly": "^1.7.1", "pkg-types": "^1.1.3", + "resolve": "^1.22.8", "tinyglobby": "^0.2.2", "tsconfck": "3.1.3" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.15.4", + "@types/resolve": "^1.20.6", + "esbuild": "^0.23.0", "rimraf": "6.0.1", "tshy": "^3.0.2", - "tsx": "4.17.0", - "esbuild": "^0.23.0", - "@arethetypeswrong/cli": "^0.15.4" + "tsx": "4.17.0" }, "engines": { "node": ">=18.20.0" diff --git a/packages/build/src/extensions/prisma.ts b/packages/build/src/extensions/prisma.ts index b67adc7efc..35589eeca5 100644 --- a/packages/build/src/extensions/prisma.ts +++ b/packages/build/src/extensions/prisma.ts @@ -1,63 +1,418 @@ import { BuildManifest, BuildTarget } from "@trigger.dev/core/v3"; import { binaryForRuntime, BuildContext, BuildExtension } from "@trigger.dev/core/v3/build"; import assert from "node:assert"; -import { existsSync } from "node:fs"; -import { cp, readdir } from "node:fs/promises"; +import { existsSync, statSync } from "node:fs"; +import { cp, readdir, readFile } from "node:fs/promises"; import { dirname, join, resolve } from "node:path"; +import { resolvePathSync as esmResolveSync } from "../imports/mlly.js"; +import { resolvePackageJSON } from "pkg-types"; +import { LoadConfigFromFileError } from "@prisma/config"; -export type PrismaExtensionOptions = { - schema: string; - migrate?: boolean; - version?: string; - /** - * Adds the `--sql` flag to the `prisma generate` command. This will generate the SQL files for the Prisma schema. Requires the `typedSql preview feature and prisma 5.19.0 or later. - */ - typedSql?: boolean; +export type PrismaLegacyModeExtensionOptions = { /** - * The client generator to use. Set this param to prevent all generators in the prisma schema from being generated. + * Legacy mode configuration for Prisma 5.x/6.x with the `prisma-client-js` provider. * - * @example + * **Use this mode when:** + * - Using Prisma 5.x or 6.x with `prisma-client-js` provider + * - You want automatic `prisma generate` during deployment + * - You need migration support * - * ### Prisma schema + * **Key features:** + * - Automatic client generation + * - Multi-file schema support (Prisma 6.7+) + * - Config file support (`prisma.config.ts`) + * - TypedSQL support + * - Automatic version detection + */ + mode: "legacy"; + /** + * Path to your Prisma schema file or directory. * - * ```prisma - * generator client { - * provider = "prisma-client-js" - * } + * **Examples:** + * - Single file: `"./prisma/schema.prisma"` + * - Multi-file (Prisma 6.7+): `"./prisma"` * - * generator typegraphql { - * provider = "typegraphql-prisma" - * output = "./generated/type-graphql" - * } - * ``` + * **Note:** Either `schema` or `configFile` must be specified, but not both. + */ + schema?: string; + /** + * Path to your Prisma config file (`prisma.config.ts`). * - * ### PrismaExtension + * Uses `@prisma/config` to automatically extract schema and migrations paths. + * Requires Prisma 6+ with config file support. * + * **Example:** * ```ts * prismaExtension({ - * schema: "./prisma/schema.prisma", - * clientGenerator: "client" + * mode: "legacy", + * configFile: "./prisma.config.ts", + * migrate: true, * }); * ``` + * + * **Note:** Either `schema` or `configFile` must be specified, but not both. + */ + configFile?: string; + /** + * Enable automatic database migrations during deployment. + * + * Runs `prisma migrate deploy` before generating the client. + * Requires `directUrlEnvVarName` to be set. + */ + migrate?: boolean; + /** + * Override the auto-detected Prisma version. + * + * **Auto-detection:** Checks externals, then `@prisma/client` in node_modules, then `prisma` package. + */ + version?: string; + /** + * Enable TypedSQL support. Adds `--sql` flag to `prisma generate`. + * + * Requires Prisma 5.19+ and `previewFeatures = ["typedSql"]` in your schema. + */ + typedSql?: boolean; + /** + * Specify which generator to use when you have multiple generators. + * + * Adds `--generator=` to only generate the specified generator. + * Useful for skipping extra generators like `typegraphql-prisma`. */ clientGenerator?: string; + /** + * Environment variable name for the direct (unpooled) database connection. + * + * Required for migrations. Common values: `"DATABASE_URL_UNPOOLED"`, `"DIRECT_URL"`. + */ directUrlEnvVarName?: string; }; +export type PrismaEngineOnlyModeExtensionOptions = { + /** + * Engine-only mode for custom Prisma client output paths. + * + * **Use this mode when:** + * - You're using a custom output path for Prisma Client + * - You want to control when `prisma generate` runs + * - You run `prisma generate` in your build pipeline + * + * **What it does:** + * - Installs engine binaries only (no client generation) + * - Sets `PRISMA_QUERY_ENGINE_LIBRARY` and `PRISMA_QUERY_ENGINE_SCHEMA_ENGINE` env vars + * - Auto-detects version from filesystem + * + * **You must:** Run `prisma generate` yourself and include correct `binaryTargets` in your schema. + */ + mode: "engine-only"; + /** + * Prisma version to use. Auto-detected from `@prisma/client` or `prisma` package if omitted. + * + * **Recommended:** Specify explicitly for reproducible builds. + */ + version?: string; + + /** + * Binary target platform for Prisma engines. + * + * **Default:** `"debian-openssl-3.0.x"` (for Trigger.dev Cloud) + * **Local Docker on ARM:** `"linux-arm64-openssl-3.0.x"` + */ + binaryTarget?: string; + + /** + * Suppress progress messages during the build. + */ + silent?: boolean; +}; + +export type PrismaEngineModernModeExtensionOptions = { + /** + * Modern mode for Prisma 6.16+ (with `prisma-client` provider) and Prisma 7. + * + * **Use this mode when:** + * - Using Prisma 6.16+ with `provider = "prisma-client"` and `engineType = "client"` + * - Using Prisma 7 beta or later + * - Using database adapters (e.g., `@prisma/adapter-pg`) + * + * **What it does:** + * - Marks `@prisma/client` as external (zero config) + * - Works with TypeScript-only client (no Rust binaries) + * + * **You must:** Run `prisma generate` yourself and install database adapters. + */ + mode: "modern"; +}; + +export type PrismaExtensionOptions = + | PrismaLegacyModeExtensionOptions + | PrismaEngineOnlyModeExtensionOptions + | PrismaEngineModernModeExtensionOptions; + const BINARY_TARGET = "linux-arm64-openssl-3.0.x"; -export function prismaExtension(options: PrismaExtensionOptions): PrismaExtension { - return new PrismaExtension(options); +/** + * Attempts to resolve the Prisma client version from the project. + * Tries @prisma/client first, then falls back to the prisma package. + */ +async function resolvePrismaClientVersion( + workingDir: string, + logger: { + debug: (message: string, data?: any) => void; + } +): Promise { + // Try @prisma/client first + const clientVersion = await tryResolvePrismaPackageVersion("@prisma/client", workingDir, logger); + if (clientVersion) { + return clientVersion; + } + + // Fall back to prisma package + const prismaVersion = await tryResolvePrismaPackageVersion("prisma", workingDir, logger); + if (prismaVersion) { + return prismaVersion; + } + + return undefined; +} + +/** + * Attempts to resolve a specific Prisma package and extract its version + */ +async function tryResolvePrismaPackageVersion( + packageName: string, + workingDir: string, + logger: { + debug: (message: string, data?: any) => void; + } +): Promise { + try { + // Try to resolve the package using esmResolveSync + const resolvedPath = esmResolveSync(packageName, { + url: workingDir, + }); + + logger.debug(`Resolved ${packageName} module path`, { + resolvedPath, + workingDir, + packageName, + }); + + // Find the package.json for this resolved module + const packageJsonPath = await resolvePackageJSON(dirname(resolvedPath), { + test: async (filePath) => { + try { + const content = await readFile(filePath, "utf-8"); + const candidate = JSON.parse(content); + + // Exclude esm type markers + return Object.keys(candidate).length > 1 || !candidate.type; + } catch (error) { + logger.debug("Error during package.json test", { + error: error instanceof Error ? error.message : error, + filePath, + }); + + return false; + } + }, + }); + + if (!packageJsonPath) { + logger.debug(`No package.json found for ${packageName}`, { + resolvedPath, + }); + return undefined; + } + + logger.debug(`Found package.json for ${packageName}`, { + packageJsonPath, + }); + + // Read and parse the package.json + const packageJsonContent = await readFile(packageJsonPath, "utf-8"); + const packageJson = JSON.parse(packageJsonContent); + + if (packageJson.name === packageName && packageJson.version) { + logger.debug(`Detected ${packageName} version`, { + version: packageJson.version, + }); + return packageJson.version; + } + + logger.debug(`Package name mismatch or no version in package.json for ${packageName}`, { + expectedName: packageName, + actualName: packageJson.name, + version: packageJson.version, + }); + + return undefined; + } catch (error) { + logger.debug(`Failed to resolve ${packageName}`, { + error: error instanceof Error ? error.message : error, + workingDir, + }); + + return undefined; + } +} + +/** + * Loads a Prisma config file using @prisma/config and extracts the schema path and other configuration + */ +async function loadPrismaConfig( + configFilePath: string, + workingDir: string, + logger: { + debug: (message: string, data?: any) => void; + } +): Promise<{ + schema: string; + migrationsPath?: string; +}> { + try { + // Resolve the config file path relative to the working directory + const resolvedConfigPath = resolve(workingDir, configFilePath); + + logger.debug(`[PrismaExtension] loadPrismaConfig called`, { + configFilePath, + resolvedConfigPath, + workingDir, + }); + + // Check that the config file exists + if (!existsSync(resolvedConfigPath)) { + throw new Error( + `Prisma config file not found at ${resolvedConfigPath}. Make sure the path is correct: ${configFilePath}, relative to the working dir ${workingDir}` + ); + } + + logger.debug(`[PrismaExtension] Config file exists, loading with @prisma/config`); + + // Dynamically import @prisma/config + const { loadConfigFromFile } = await import("@prisma/config"); + + // Load the config using @prisma/config + const configResult = await loadConfigFromFile({ + configFile: resolvedConfigPath, + configRoot: workingDir, + }); + + logger.debug(`[PrismaExtension] loadConfigFromFile completed`, { + hasError: !!configResult.error, + errorTag: configResult.error?._tag, + }); + + function prettyConfigError(error: LoadConfigFromFileError): string { + switch (error._tag) { + case "ConfigFileNotFound": + return `Config file not found at ${resolvedConfigPath}`; + case "ConfigLoadError": + return `Config file parse error: ${error.error.message}`; + case "ConfigFileSyntaxError": + return `Config file syntax error: ${error.error.message}`; + default: + return `Unknown config error: ${String(error.error.message)}`; + } + } + + if (configResult.error) { + throw new Error( + `Failed to load Prisma config from ${resolvedConfigPath}: ${prettyConfigError( + configResult.error + )}` + ); + } + + logger.debug(`[PrismaExtension] Config parsed successfully`, { + schema: configResult.config.schema, + migrationsPath: configResult.config.migrations?.path, + fullMigrations: configResult.config.migrations, + }); + + // Extract the schema path + if (!configResult.config.schema) { + throw new Error(`Prisma config file at ${resolvedConfigPath} does not specify a schema path`); + } + + const result = { + schema: configResult.config.schema, + migrationsPath: configResult.config.migrations?.path, + }; + + logger.debug(`[PrismaExtension] Returning config result`, result); + + return result; + } catch (error) { + logger.debug(`[PrismaExtension] Error loading config`, { + error: error instanceof Error ? error.message : error, + stack: error instanceof Error ? error.stack : undefined, + }); + throw new Error( + `Failed to load Prisma config from ${configFilePath}: ${ + error instanceof Error ? error.message : error + }` + ); + } +} + +/** + * Prisma build extension for Trigger.dev deployments. + * + * **Three modes available:** + * - `"legacy"` - Prisma 5.x/6.x with `prisma-client-js`, automatic generation + * - `"engine-only"` - Custom output paths, manual generation control + * - `"modern"` - Prisma 6.16+/7.x with `prisma-client` provider + * + * @example Legacy mode (most common) + * ```ts + * prismaExtension({ + * mode: "legacy", + * schema: "prisma/schema.prisma", + * migrate: true, + * typedSql: true, + * }); + * ``` + * + * @example Engine-only mode (custom output) + * ```ts + * prismaExtension({ + * mode: "engine-only", + * version: "6.19.0", + * }); + * ``` + * + * @example Modern mode (Prisma 7) + * ```ts + * prismaExtension({ + * mode: "modern", + * }); + * ``` + */ +export function prismaExtension(options: PrismaExtensionOptions): BuildExtension { + switch (options.mode) { + case "legacy": + return new PrismaLegacyModeExtension(options); + case "engine-only": + return new PrismaEngineOnlyModeExtension(options); + case "modern": + return new PrismaEngineModernModeExtension(options); + default: + return new PrismaLegacyModeExtension(options); + } } -export class PrismaExtension implements BuildExtension { +export class PrismaLegacyModeExtension implements BuildExtension { moduleExternals: string[]; public readonly name = "PrismaExtension"; private _resolvedSchemaPath?: string; + private _loadedConfig?: { + schema: string; + migrationsPath?: string; + }; - constructor(private options: PrismaExtensionOptions) { + constructor(private options: PrismaLegacyModeExtensionOptions) { this.moduleExternals = ["@prisma/client", "@prisma/engines"]; } @@ -74,17 +429,74 @@ export class PrismaExtension implements BuildExtension { return; } + context.logger.debug(`[PrismaExtension] onBuildStart called`, { + workingDir: context.workingDir, + options: { + schema: this.options.schema, + configFile: this.options.configFile, + migrate: this.options.migrate, + version: this.options.version, + typedSql: this.options.typedSql, + clientGenerator: this.options.clientGenerator, + directUrlEnvVarName: this.options.directUrlEnvVarName, + }, + }); + + // Validate that either schema or configFile is provided, but not both + if (!this.options.schema && !this.options.configFile) { + throw new Error( + `PrismaExtension requires either 'schema' or 'configFile' to be specified in the options` + ); + } + + if (this.options.schema && this.options.configFile) { + throw new Error( + `PrismaExtension cannot have both 'schema' and 'configFile' specified. Please use only one.` + ); + } + + let schemaPath: string; + + // If configFile is specified, load it and extract the schema path + if (this.options.configFile) { + context.logger.debug( + `[PrismaExtension] Loading Prisma config from ${this.options.configFile}` + ); + + this._loadedConfig = await loadPrismaConfig( + this.options.configFile, + context.workingDir, + context.logger + ); + + schemaPath = this._loadedConfig.schema; + + context.logger.debug(`[PrismaExtension] Config loaded successfully`, { + schema: this._loadedConfig.schema, + migrationsPath: this._loadedConfig.migrationsPath, + }); + } else { + schemaPath = this.options.schema!; + context.logger.debug(`[PrismaExtension] Using schema from options: ${schemaPath}`); + } + // Resolve the path to the prisma schema, relative to the config.directory - this._resolvedSchemaPath = resolve(context.workingDir, this.options.schema); + this._resolvedSchemaPath = resolve(context.workingDir, schemaPath); - context.logger.debug(`Resolved the prisma schema to: ${this._resolvedSchemaPath}`); + context.logger.debug(`[PrismaExtension] Resolved schema path`, { + schemaPath, + resolvedSchemaPath: this._resolvedSchemaPath, + workingDir: context.workingDir, + }); // Check that the prisma schema exists if (!existsSync(this._resolvedSchemaPath)) { throw new Error( - `PrismaExtension could not find the prisma schema at ${this._resolvedSchemaPath}. Make sure the path is correct: ${this.options.schema}, relative to the working dir ${context.workingDir}` + `PrismaExtension could not find the prisma schema at ${this._resolvedSchemaPath}. Make sure the path is correct: ${schemaPath}, relative to the working dir ${context.workingDir}` ); } + + context.logger.debug(`[PrismaExtension] Schema file exists at ${this._resolvedSchemaPath}`); } async onBuildComplete(context: BuildContext, manifest: BuildManifest) { @@ -92,9 +504,11 @@ export class PrismaExtension implements BuildExtension { return; } + context.logger.debug(`[PrismaExtension] onBuildComplete called`); + assert(this._resolvedSchemaPath, "Resolved schema path is not set"); - context.logger.debug("Looking for @prisma/client in the externals", { + context.logger.debug(`[PrismaExtension] Looking for @prisma/client in the externals`, { externals: manifest.externals, }); @@ -102,7 +516,20 @@ export class PrismaExtension implements BuildExtension { (external) => external.name === "@prisma/client" ); - const version = prismaExternal?.version ?? this.options.version; + let version = prismaExternal?.version ?? this.options.version; + + // If we couldn't find the version in externals or options, try to resolve it from the filesystem + if (!version) { + context.logger.debug( + `[PrismaExtension] Version not found in externals, attempting to detect from filesystem` + ); + + version = await resolvePrismaClientVersion(context.workingDir, context.logger); + + if (version) { + context.logger.debug(`[PrismaExtension] Detected version from filesystem: ${version}`); + } + } if (!version) { throw new Error( @@ -110,11 +537,22 @@ export class PrismaExtension implements BuildExtension { ); } - context.logger.debug(`PrismaExtension is generating the Prisma client for version ${version}`); + context.logger.debug(`[PrismaExtension] Using Prisma version ${version}`, { + source: prismaExternal ? "externals" : this.options.version ? "options" : "filesystem", + }); + + // Detect if this is a multi-file schema (directory) or single file schema + const isMultiFileSchema = statSync(this._resolvedSchemaPath).isDirectory(); + const usingSchemaFolder = + !isMultiFileSchema && dirname(this._resolvedSchemaPath).endsWith("schema"); - const usingSchemaFolder = dirname(this._resolvedSchemaPath).endsWith("schema"); + context.logger.debug(`Schema detection`, { + isMultiFileSchema, + usingSchemaFolder, + resolvedSchemaPath: this._resolvedSchemaPath, + }); - const commands: string[] = []; + let commands: string[] = []; let prismaDir: string | undefined; @@ -127,14 +565,25 @@ export class PrismaExtension implements BuildExtension { if (this.options.typedSql) { generatorFlags.push(`--sql`); - const prismaDir = usingSchemaFolder - ? dirname(dirname(this._resolvedSchemaPath)) - : dirname(this._resolvedSchemaPath); + // Determine the prisma directory based on the schema structure + let prismaDirForSql: string; + if (isMultiFileSchema) { + // For multi-file schemas, the resolved path IS the prisma directory + prismaDirForSql = this._resolvedSchemaPath; + } else if (usingSchemaFolder) { + // For schema folders (e.g., prisma/schema/*.prisma), go up two levels + prismaDirForSql = dirname(dirname(this._resolvedSchemaPath)); + } else { + // For single file schemas (e.g., prisma/schema.prisma), go up one level + prismaDirForSql = dirname(this._resolvedSchemaPath); + } - context.logger.debug(`Using typedSql`); + context.logger.debug(`Using typedSql`, { + prismaDirForSql, + }); // Find all the files prisma/sql/*.sql - const sqlFiles = await readdir(join(prismaDir, "sql")).then((files) => + const sqlFiles = await readdir(join(prismaDirForSql, "sql")).then((files) => files.filter((file) => file.endsWith(".sql")) ); @@ -146,7 +595,7 @@ export class PrismaExtension implements BuildExtension { for (const file of sqlFiles) { const destination = join(sqlDestinationPath, file); - const source = join(prismaDir, "sql", file); + const source = join(prismaDirForSql, "sql", file); context.logger.debug(`Copying the sql from ${source} to ${destination}`); @@ -154,7 +603,36 @@ export class PrismaExtension implements BuildExtension { } } - if (usingSchemaFolder) { + if (isMultiFileSchema) { + // For multi-file schemas, the resolved path IS the prisma directory + prismaDir = this._resolvedSchemaPath; + + context.logger.debug(`Using multi-file schema directory: ${prismaDir}`); + + // Copy the entire prisma directory to the build output path + const prismaDestinationPath = join(manifest.outputPath, "prisma"); + + context.logger.debug( + `Copying the prisma directory from ${prismaDir} to ${prismaDestinationPath}` + ); + + const prismaDirForFilter = prismaDir; + await cp(prismaDir, prismaDestinationPath, { + recursive: true, + // Filter out migrations and sql directories as they're handled separately if needed + filter: (source) => { + const relativePath = source.replace(prismaDirForFilter, ""); + // Skip migrations and sql directories during initial copy + return !relativePath.startsWith("/migrations") && !relativePath.startsWith("/sql"); + }, + }); + + commands.push( + `${binaryForRuntime( + manifest.runtime + )} node_modules/prisma/build/index.js generate ${generatorFlags.join(" ")}` // Don't add the --schema flag when using directory + ); + } else if (usingSchemaFolder) { const schemaDir = dirname(this._resolvedSchemaPath); prismaDir = dirname(schemaDir); @@ -213,24 +691,73 @@ export class PrismaExtension implements BuildExtension { const env: Record = {}; - 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"); + context.logger.debug(`[PrismaExtension] Checking if migrations are enabled`, { + migrate: this.options.migrate, + loadedConfigMigrationsPath: this._loadedConfig?.migrationsPath, + prismaDir, + }); + if (this.options.migrate) { context.logger.debug( - `Copying the prisma migrations from ${migrationsDir} to ${migrationsDestinationPath}` + `[PrismaExtension] Migrations enabled, determining migrations directory` ); - await cp(migrationsDir, migrationsDestinationPath, { recursive: true }); + // Determine the migrations directory path + let migrationsDir: string; + + if (this._loadedConfig?.migrationsPath) { + // Use the migrations path from the config file + migrationsDir = resolve(context.workingDir, this._loadedConfig.migrationsPath); + context.logger.debug(`[PrismaExtension] Using migrations path from config`, { + configMigrationsPath: this._loadedConfig.migrationsPath, + resolvedMigrationsDir: migrationsDir, + workingDir: context.workingDir, + }); + } else { + // Fall back to the default migrations directory + migrationsDir = join(prismaDir, "migrations"); + context.logger.debug(`[PrismaExtension] Using default migrations path`, { + prismaDir, + migrationsDir, + }); + } - commands.push( - `${binaryForRuntime(manifest.runtime)} node_modules/prisma/build/index.js migrate deploy` + const migrationsDestinationPath = join(manifest.outputPath, "prisma", "migrations"); + + context.logger.debug(`[PrismaExtension] Checking if migrations directory exists`, { + migrationsDir, + exists: existsSync(migrationsDir), + }); + + if (!existsSync(migrationsDir)) { + context.logger.warn( + `[PrismaExtension] Migrations directory not found at ${migrationsDir}. Skipping migrations copy.` + ); + } else { + context.logger.debug( + `[PrismaExtension] Copying prisma migrations from ${migrationsDir} to ${migrationsDestinationPath}` + ); + + await cp(migrationsDir, migrationsDestinationPath, { recursive: true }); + + context.logger.debug(`[PrismaExtension] Migrations copied successfully`); + + commands = [ + `${binaryForRuntime(manifest.runtime)} node_modules/prisma/build/index.js migrate deploy`, + ...commands, + ]; + + context.logger.debug(`[PrismaExtension] Added migrate deploy command to commands array`); + } + } else { + context.logger.debug( + `[PrismaExtension] Migrations not enabled (migrate: ${this.options.migrate})` ); } env.DATABASE_URL = manifest.deploy.env?.DATABASE_URL; + // Handle directUrl environment variable configuration if (this.options.directUrlEnvVarName) { env[this.options.directUrlEnvVarName] = manifest.deploy.env?.[this.options.directUrlEnvVarName] ?? @@ -252,14 +779,19 @@ export class PrismaExtension implements BuildExtension { ); } - context.logger.debug(`Adding the prisma layer with the following commands`, { + context.logger.debug(`[PrismaExtension] Final layer configuration`, { commands, - env, + commandsCount: commands.length, + env: Object.keys(env), dependencies: { prisma: version, }, }); + context.logger.debug(`[PrismaExtension] Commands to be executed:`, { + commands: commands.map((cmd, idx) => `${idx + 1}. ${cmd}`), + }); + context.addLayer({ id: "prisma", commands, @@ -270,5 +802,97 @@ export class PrismaExtension implements BuildExtension { env, }, }); + + context.logger.debug(`[PrismaExtension] Layer added successfully`); + } +} + +export class PrismaEngineOnlyModeExtension implements BuildExtension { + public readonly name = "PrismaEngineOnlyModeExtension"; + private _binaryTarget: string; + + constructor(private options: PrismaEngineOnlyModeExtensionOptions) { + this._binaryTarget = options.binaryTarget ?? "debian-openssl-3.0.x"; + } + + async onBuildComplete(context: BuildContext, manifest: BuildManifest) { + if (context.target === "dev") { + return; + } + + // Try to detect the version if not provided + let version = this.options.version; + + if (!version) { + context.logger.debug("Attempting to detect @prisma/client version from the project"); + + version = await resolvePrismaClientVersion(context.workingDir, context.logger); + + if (version) { + // Log a nice message to the user which version was detected, and give them instructions on how to override it + context.logger.progress( + `prismaExtension: detected prisma ${version}. Override via prismaExtension({ mode: "engine-only", version: "6.19.0" })` + ); + } + } + + if (!version) { + throw new Error( + `PrismaEngineOnlyModeExtension could not determine the version of @prisma/client. Please provide a version in the PrismaExtension options: prismaExtension({ mode: "engine-only", version: "6.19.0" })` + ); + } + + context.logger.debug( + `PrismaEngineOnlyModeExtension is installing engines for version ${version}` + ); + + const commands: string[] = [ + // Install the engines package + `npm install @prisma/engines@${version}`, + ...generateCpCommandsForLocation("/app/prisma-engines", this._binaryTarget), + ]; + + context.addLayer({ + id: "prisma-engines", + commands, + deploy: { + env: { + PRISMA_QUERY_ENGINE_LIBRARY: `/app/prisma-engines/libquery_engine-${this._binaryTarget}.so.node`, + PRISMA_QUERY_ENGINE_SCHEMA_ENGINE: `/app/prisma-engines/schema-engine-${this._binaryTarget}`, + }, + }, + }); + + if (!this.options.silent) { + context.logger.progress( + "prismaExtension: setting PRISMA_QUERY_ENGINE_LIBRARY and PRISMA_QUERY_ENGINE_SCHEMA_ENGINE env variables" + ); + // Now logs output a pretty message to the user that they need to make sure they have already run `prisma generate` and they also have added + // the binary target to the prisma schema file like so: binaryTargets = ["native", "debian-openssl-3.0.x"] + context.logger.progress( + `prismaExtension: in engine-only mode you are required to run \`prisma generate\` and ensure your schema.prisma file has binaryTargets = ["native", "${this._binaryTarget}"]` + ); + } + } +} + +function generateCpCommandsForLocation(location: string, binaryTarget: string) { + return [ + `mkdir -p ${location} && cp node_modules/@prisma/engines/libquery_engine-${binaryTarget}.so.node ${location}/`, + `mkdir -p ${location} && cp node_modules/@prisma/engines/schema-engine-${binaryTarget} ${location}/`, + ]; +} + +export class PrismaEngineModernModeExtension implements BuildExtension { + moduleExternals: string[]; + + public readonly name = "PrismaEngineModernModeExtension"; + + constructor(private options: PrismaEngineModernModeExtensionOptions) { + this.moduleExternals = ["@prisma/client"]; + } + + externalsForTarget(target: BuildTarget) { + return this.moduleExternals; } } diff --git a/packages/build/src/imports/mlly-cjs.cts b/packages/build/src/imports/mlly-cjs.cts new file mode 100644 index 0000000000..cd89f8df66 --- /dev/null +++ b/packages/build/src/imports/mlly-cjs.cts @@ -0,0 +1,5 @@ +// @ts-ignore +const { resolvePathSync } = require("mlly"); + +// @ts-ignore +module.exports.resolvePathSync = resolvePathSync; diff --git a/packages/build/src/imports/mlly.ts b/packages/build/src/imports/mlly.ts new file mode 100644 index 0000000000..d0bf9ffb85 --- /dev/null +++ b/packages/build/src/imports/mlly.ts @@ -0,0 +1,5 @@ +// @ts-ignore +import { resolvePathSync } from "mlly"; + +// @ts-ignore +export { resolvePathSync }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e64aab9459..8c02907dd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1275,12 +1275,21 @@ importers: packages/build: dependencies: + '@prisma/config': + specifier: ^6.10.0 + version: 6.19.0 '@trigger.dev/core': specifier: workspace:4.1.0 version: link:../core + mlly: + specifier: ^1.7.1 + version: 1.7.4 pkg-types: specifier: ^1.1.3 version: 1.1.3 + resolve: + specifier: ^1.22.8 + version: 1.22.8 tinyglobby: specifier: ^0.2.2 version: 0.2.2 @@ -1291,6 +1300,9 @@ importers: '@arethetypeswrong/cli': specifier: ^0.15.4 version: 0.15.4 + '@types/resolve': + specifier: ^1.20.6 + version: 1.20.6 esbuild: specifier: ^0.23.0 version: 0.23.0 @@ -2365,6 +2377,129 @@ importers: specifier: workspace:* version: link:../../packages/cli-v3 + references/prisma-6: + dependencies: + '@prisma/client': + specifier: 6.14.0 + version: 6.14.0(prisma@6.14.0)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + prisma: + specifier: 6.14.0 + version: 6.14.0(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + + references/prisma-6-client: + dependencies: + '@prisma/adapter-pg': + specifier: 6.16.0 + version: 6.16.0 + '@prisma/client': + specifier: 6.16.0 + version: 6.16.0(prisma@6.16.0)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + prisma: + specifier: 6.16.0 + version: 6.16.0(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + + references/prisma-6-config: + dependencies: + '@prisma/client': + specifier: 6.19.0 + version: 6.19.0(prisma@6.19.0)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + prisma: + specifier: 6.19.0 + version: 6.19.0(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + + references/prisma-6-multi-file: + dependencies: + '@prisma/client': + specifier: 6.14.0 + version: 6.14.0(prisma@6.14.0)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + prisma: + specifier: 6.14.0 + version: 6.14.0(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + + references/prisma-6-output: + dependencies: + '@prisma/client': + specifier: 6.19.0 + version: 6.19.0(prisma@6.19.0)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + prisma: + specifier: 6.19.0 + version: 6.19.0(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + + references/prisma-7: + dependencies: + '@prisma/adapter-pg': + specifier: 6.20.0-integration-next.8 + version: 6.20.0-integration-next.8 + '@prisma/client': + specifier: 6.20.0-integration-next.8 + version: 6.20.0-integration-next.8(prisma@6.20.0-integration-next.8)(typescript@5.5.4) + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + devDependencies: + prisma: + specifier: 6.20.0-integration-next.8 + version: 6.20.0-integration-next.8(@types/react@18.2.69)(react-dom@18.2.0)(react@18.3.1)(typescript@5.5.4) + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + references/python-catalog: dependencies: '@trigger.dev/python': @@ -10827,6 +10962,30 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false + /@prisma/adapter-pg@6.16.0: + resolution: {integrity: sha512-zNMQyIrkcVFMYFuVeO9GhK9dc5kMSvqwqL+pNMM9oK4+mj7HcKws780ZXhAgV149kcg2kDisHPHO5nE4gkG+oA==} + dependencies: + '@prisma/driver-adapter-utils': 6.16.0 + pg: 8.15.6 + postgres-array: 3.0.4 + transitivePeerDependencies: + - pg-native + dev: false + + /@prisma/adapter-pg@6.20.0-integration-next.8: + resolution: {integrity: sha512-5+ZjSPMzyfDYMmWLH1IaQIOQGa8eJrqEz5A9V4vS4+b6LV6qvCOHjqlnbRQ5IKSNCwFP055SJ54RsPES+0jOyA==} + dependencies: + '@prisma/driver-adapter-utils': 6.20.0-integration-next.8 + pg: 8.16.3 + postgres-array: 3.0.4 + transitivePeerDependencies: + - pg-native + dev: false + + /@prisma/client-runtime-utils@6.20.0-integration-next.8: + resolution: {integrity: sha512-prENLjPislFvRWDHNgXmg9yzixQYsFPVQGtDv5zIMs4pV2KPdNc5pCiZ3n77hAinvqGJVafASa+eU4TfpVphdA==} + dev: false + /@prisma/client@6.14.0(prisma@6.14.0)(typescript@5.5.4): resolution: {integrity: sha512-8E/Nk3eL5g7RQIg/LUj1ICyDmhD053STjxrPxUtCRybs2s/2sOEcx9NpITuAOPn07HEpWBfhAVe1T/HYWXUPOw==} engines: {node: '>=18.18'} @@ -10844,6 +11003,57 @@ packages: typescript: 5.5.4 dev: false + /@prisma/client@6.16.0(prisma@6.16.0)(typescript@5.5.4): + resolution: {integrity: sha512-FYkFJtgwpwJRMxtmrB26y7gtpR372kyChw6lWng5TMmvn5V+uisy0OyllO5EJD1s8lX78V8X3XjhiXOoMLnu3w==} + engines: {node: '>=18.18'} + requiresBuild: true + peerDependencies: + prisma: '*' + typescript: '>=5.1.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + dependencies: + prisma: 6.16.0(typescript@5.5.4) + typescript: 5.5.4 + dev: false + + /@prisma/client@6.19.0(prisma@6.19.0)(typescript@5.5.4): + resolution: {integrity: sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g==} + engines: {node: '>=18.18'} + requiresBuild: true + peerDependencies: + prisma: '*' + typescript: '>=5.1.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + dependencies: + prisma: 6.19.0(typescript@5.5.4) + typescript: 5.5.4 + dev: false + + /@prisma/client@6.20.0-integration-next.8(prisma@6.20.0-integration-next.8)(typescript@5.5.4): + resolution: {integrity: sha512-cSxdnyO3nBr+JQFsW8j4C3JvMWiknSoZktmMNRNtXQ7bmUeG4IyQks97bjzeAUP8feJechk5casCIq3p26GDvA==} + engines: {node: ^20.19 || ^22.12 || ^24.0} + peerDependencies: + prisma: '*' + typescript: '>=5.4.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + dependencies: + '@prisma/client-runtime-utils': 6.20.0-integration-next.8 + prisma: 6.20.0-integration-next.8(@types/react@18.2.69)(react-dom@18.2.0)(react@18.3.1)(typescript@5.5.4) + typescript: 5.5.4 + dev: false + /@prisma/config@6.14.0: resolution: {integrity: sha512-IwC7o5KNNGhmblLs23swnfBjADkacBb7wvyDXUWLwuvUQciKJZqyecU0jw0d7JRkswrj+XTL8fdr0y2/VerKQQ==} dependencies: @@ -10854,12 +11064,72 @@ packages: transitivePeerDependencies: - magicast + /@prisma/config@6.16.0: + resolution: {integrity: sha512-Q9TgfnllVehvQziY9lJwRJLGmziX0OimZUEQ/MhCUBoJMSScj2VivCjw/Of2vlO1FfyaHXxrvjZAr7ASl7DVcw==} + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.16.12 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + /@prisma/config@6.19.0: + resolution: {integrity: sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==} + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + /@prisma/config@6.20.0-integration-next.8: + resolution: {integrity: sha512-nwf+tczfiGSn0tnuHmBpnK+wmaYzcC20sn9Zt8BSoJVCewJxf8ASHPxZEGgvFLl05zbCfFtq3rMc6ZnAiYjowg==} + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + /@prisma/debug@6.14.0: resolution: {integrity: sha512-j4Lf+y+5QIJgQD4sJWSbkOD7geKx9CakaLp/TyTy/UDu9Wo0awvWCBH/BAxTHUaCpIl9USA5VS/KJhDqKJSwug==} + /@prisma/debug@6.16.0: + resolution: {integrity: sha512-bxzro5vbVqAPkWyDs2A6GpQtRZunD8tyrLmSAchx9u0b+gWCDY6eV+oh5A0YtYT9245dIxQBswckayHuJG4u3w==} + + /@prisma/debug@6.19.0: + resolution: {integrity: sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==} + + /@prisma/debug@6.20.0-integration-next.8: + resolution: {integrity: sha512-PqUUFXf8MDoIrsKMzpF4NYqA3gHE8l/CUWVnYa4hNIbynCcEhvk7iT+6ve0u9w1TiGVUFnIVMuqFGEb2aHCuFw==} + + /@prisma/driver-adapter-utils@6.16.0: + resolution: {integrity: sha512-dsRHvEnifJ3xqpMKGBy1jRwR8yc+7Ko4TcHrdTQJIfq6NYN2gNoOf0k91hcbzs5AH19wDxjuHXCveklWq5AJdA==} + dependencies: + '@prisma/debug': 6.16.0 + dev: false + + /@prisma/driver-adapter-utils@6.20.0-integration-next.8: + resolution: {integrity: sha512-TXpFugr3sCl2bHechoG3p9mvlq2Z3GgA0Cp73lUOEWQyUuoG8NW/4UA56Ax1r5fBUAs9hKbr20Ld6wKCZhnz8Q==} + dependencies: + '@prisma/debug': 6.20.0-integration-next.8 + dev: false + /@prisma/engines-version@6.14.0-25.717184b7b35ea05dfa71a3236b7af656013e1e49: resolution: {integrity: sha512-EgN9ODJpiX45yvwcngoStp3uQPJ3l+AEVoQ6dMMO2QvmwIlnxfApzKmJQExzdo7/hqQANrz5txHJdGYHzOnGHA==} + /@prisma/engines-version@6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43: + resolution: {integrity: sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==} + + /@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773: + resolution: {integrity: sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==} + + /@prisma/engines-version@6.20.0-11.next-80ee0a44bf5668992b0c909c946a755b86b56c95: + resolution: {integrity: sha512-DqrQqRIgeocvWpgN7t9PymiJdV8ISSSrZCuilAtpKEaKIt4JUGIxsAdWNMRSHk188hYA2W1YFG5KvWUYBaCO1A==} + /@prisma/engines@6.14.0: resolution: {integrity: sha512-LhJjqsALFEcoAtF07nSaOkVguaxw/ZsgfROIYZ8bAZDobe7y8Wy+PkYQaPOK1iLSsFgV2MhCO/eNrI1gdSOj6w==} requiresBuild: true @@ -10869,6 +11139,33 @@ packages: '@prisma/fetch-engine': 6.14.0 '@prisma/get-platform': 6.14.0 + /@prisma/engines@6.16.0: + resolution: {integrity: sha512-RHJGCH/zi017W4CWYWqg0Sv1pquGGFVo8T3auJ9sodDNaiRzbeNldydjaQzszVS8nscdtcvLuJzy7e65C3puqQ==} + requiresBuild: true + dependencies: + '@prisma/debug': 6.16.0 + '@prisma/engines-version': 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + '@prisma/fetch-engine': 6.16.0 + '@prisma/get-platform': 6.16.0 + + /@prisma/engines@6.19.0: + resolution: {integrity: sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==} + requiresBuild: true + dependencies: + '@prisma/debug': 6.19.0 + '@prisma/engines-version': 6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773 + '@prisma/fetch-engine': 6.19.0 + '@prisma/get-platform': 6.19.0 + + /@prisma/engines@6.20.0-integration-next.8: + resolution: {integrity: sha512-XdzTxN0PFLIW2DcprG9xlMy39FrsjxW5J2qtHQ58FBtbllHSZGD0pK2nzATw5dRh7nGhmX+uNA02cqHv5oND3A==} + requiresBuild: true + dependencies: + '@prisma/debug': 6.20.0-integration-next.8 + '@prisma/engines-version': 6.20.0-11.next-80ee0a44bf5668992b0c909c946a755b86b56c95 + '@prisma/fetch-engine': 6.20.0-integration-next.8 + '@prisma/get-platform': 6.20.0-integration-next.8 + /@prisma/fetch-engine@6.14.0: resolution: {integrity: sha512-MPzYPOKMENYOaY3AcAbaKrfvXVlvTc6iHmTXsp9RiwCX+bPyfDMqMFVUSVXPYrXnrvEzhGHfyiFy0PRLHPysNg==} dependencies: @@ -10876,11 +11173,47 @@ packages: '@prisma/engines-version': 6.14.0-25.717184b7b35ea05dfa71a3236b7af656013e1e49 '@prisma/get-platform': 6.14.0 + /@prisma/fetch-engine@6.16.0: + resolution: {integrity: sha512-Mx5rml0XRIDizhB9eZxSP8c0nMoXYVITTiJJwxlWn9rNCel8mG8NAqIw+vJlN3gPR+kt3IBkP1SQVsplPPpYrA==} + dependencies: + '@prisma/debug': 6.16.0 + '@prisma/engines-version': 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + '@prisma/get-platform': 6.16.0 + + /@prisma/fetch-engine@6.19.0: + resolution: {integrity: sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==} + dependencies: + '@prisma/debug': 6.19.0 + '@prisma/engines-version': 6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773 + '@prisma/get-platform': 6.19.0 + + /@prisma/fetch-engine@6.20.0-integration-next.8: + resolution: {integrity: sha512-zVNM5Q1hFclpqD1y7wujDzyc3l01S8ZMuP0Zddzuda4LOA7/F2enjro48VcD2/fxkBgzkkmO/quLOGnbQDKO7g==} + dependencies: + '@prisma/debug': 6.20.0-integration-next.8 + '@prisma/engines-version': 6.20.0-11.next-80ee0a44bf5668992b0c909c946a755b86b56c95 + '@prisma/get-platform': 6.20.0-integration-next.8 + /@prisma/get-platform@6.14.0: resolution: {integrity: sha512-7VjuxKNwjnBhKfqPpMeWiHEa2sVjYzmHdl1slW6STuUCe9QnOY0OY1ljGSvz6wpG4U8DfbDqkG1yofd/1GINww==} dependencies: '@prisma/debug': 6.14.0 + /@prisma/get-platform@6.16.0: + resolution: {integrity: sha512-eaJOOvAoGslSUTjiQrtE9E0hoBdfL43j8SymOGD6LbdrKRNtIoiy6qiBaEr2fNYD+R/Qns7QOwPhl7SVHJayKA==} + dependencies: + '@prisma/debug': 6.16.0 + + /@prisma/get-platform@6.19.0: + resolution: {integrity: sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==} + dependencies: + '@prisma/debug': 6.19.0 + + /@prisma/get-platform@6.20.0-integration-next.8: + resolution: {integrity: sha512-21jEfhFpC8FuvPD7JEf1Qu02engBCBa3+1il3UiyHKcKS3Kbp9IgR+DVqqrqSWIGJg8+1oTfF/3AgbjunaQ1Ag==} + dependencies: + '@prisma/debug': 6.20.0-integration-next.8 + /@prisma/instrumentation@6.11.1(@opentelemetry/api@1.9.0): resolution: {integrity: sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==} peerDependencies: @@ -10903,6 +11236,17 @@ packages: - supports-color dev: false + /@prisma/studio-core-licensed@0.6.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.3.1): + resolution: {integrity: sha512-LNC8ohLosuWz6n9oKNqfR5Ep/JYiPavk4RxrU6inOS4LEvMQts8N+Vtt7NAB9i06BaiIRKnPsg1Hcaao5pRjSw==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + dependencies: + '@types/react': 18.2.69 + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + /@protobuf-ts/runtime@2.11.1: resolution: {integrity: sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==} dev: false @@ -19836,7 +20180,7 @@ packages: resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} dependencies: '@types/node': 20.14.14 - pg-protocol: 1.9.5 + pg-protocol: 1.10.3 pg-types: 2.2.0 dev: false @@ -22078,11 +22422,11 @@ packages: chokidar: 3.6.0 confbox: 0.1.8 defu: 6.1.4 - dotenv: 16.4.5 + dotenv: 16.4.7 giget: 1.2.3 jiti: 1.21.6 magicast: 0.3.4 - mlly: 1.7.1 + mlly: 1.7.4 ohash: 1.1.3 pathe: 1.1.2 perfect-debounce: 1.0.0 @@ -23899,12 +24243,16 @@ packages: /dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} - dev: true /dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + /dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + dev: false + /dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -24011,6 +24359,12 @@ packages: fast-check: 3.23.2 dev: false + /effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + dependencies: + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 + /effect@3.7.2: resolution: {integrity: sha512-pV7l1+LSZFvVObj4zuy4nYiBaC7qZOfrKV6s/Ef4p3KueiQwZFgamazklwyZ+x7Nyj2etRDFvHE/xkThTfQD1w==} dev: false @@ -24819,7 +25173,7 @@ packages: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} dependencies: debug: 3.2.7 - is-core-module: 2.13.0 + is-core-module: 2.14.0 resolve: 1.22.8 transitivePeerDependencies: - supports-color @@ -24849,7 +25203,7 @@ packages: eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-typescript@3.5.5)(eslint@8.31.0) get-tsconfig: 4.7.2 globby: 13.2.2 - is-core-module: 2.13.0 + is-core-module: 2.14.0 is-glob: 4.0.3 synckit: 0.8.5 transitivePeerDependencies: @@ -27350,12 +27704,6 @@ packages: ci-info: 3.8.0 dev: false - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} - dependencies: - has: 1.0.3 - dev: true - /is-core-module@2.14.0: resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} engines: {node: '>= 0.4'} @@ -29921,6 +30269,7 @@ packages: pathe: 1.1.2 pkg-types: 1.1.3 ufo: 1.5.4 + dev: false /mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -31269,6 +31618,10 @@ packages: resolution: {integrity: sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow==} dev: false + /pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} + dev: false + /pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} @@ -31277,6 +31630,14 @@ packages: resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} engines: {node: '>=4'} + /pg-pool@3.10.1(pg@8.16.3): + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} + peerDependencies: + pg: '>=8.0' + dependencies: + pg: 8.16.3 + dev: false + /pg-pool@3.6.2(pg@8.11.5): resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==} peerDependencies: @@ -31293,6 +31654,10 @@ packages: pg: 8.15.6 dev: false + /pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + dev: false + /pg-protocol@1.6.1: resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} @@ -31315,7 +31680,7 @@ packages: dependencies: pg-int8: 1.0.1 pg-numeric: 1.0.2 - postgres-array: 3.0.2 + postgres-array: 3.0.4 postgres-bytea: 3.0.0 postgres-date: 2.1.0 postgres-interval: 3.0.0 @@ -31357,6 +31722,24 @@ packages: pg-cloudflare: 1.2.7 dev: false + /pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + dependencies: + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.2.7 + dev: false + /pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} dependencies: @@ -31454,7 +31837,7 @@ packages: resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} dependencies: confbox: 0.1.8 - mlly: 1.7.1 + mlly: 1.7.4 pathe: 1.1.2 /pkg-types@1.3.1: @@ -31546,7 +31929,7 @@ packages: postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.4 + resolve: 1.22.8 dev: true /postcss-js@2.0.3: @@ -31844,8 +32227,8 @@ packages: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} - /postgres-array@3.0.2: - resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} + /postgres-array@3.0.4: + resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} engines: {node: '>=12'} /postgres-bytea@1.0.0: @@ -31879,6 +32262,10 @@ packages: /postgres-range@1.1.4: resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} + /postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} + engines: {node: '>=12'} + /posthog-js@1.93.3: resolution: {integrity: sha512-jEOWwaQpTRbqLPrDLY6eZr7t95h+LyXqN7Yq1/K6u3V0Y1C9xHtYhpuGzYamirVnCDTbVq22RM++OBUaIpp9Wg==} dependencies: @@ -32056,6 +32443,62 @@ packages: transitivePeerDependencies: - magicast + /prisma@6.16.0(typescript@5.5.4): + resolution: {integrity: sha512-TTh+H1Kw8N68KN9cDzdAyMroqMOvdCO/Z+kS2wKEVYR1nuR21qH5Q/Db/bZHsAgw7l/TPHtM/veG5VABcdwPDw==} + engines: {node: '>=18.18'} + hasBin: true + requiresBuild: true + peerDependencies: + typescript: '>=5.1.0' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@prisma/config': 6.16.0 + '@prisma/engines': 6.16.0 + typescript: 5.5.4 + transitivePeerDependencies: + - magicast + + /prisma@6.19.0(typescript@5.5.4): + resolution: {integrity: sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==} + engines: {node: '>=18.18'} + hasBin: true + requiresBuild: true + peerDependencies: + typescript: '>=5.1.0' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@prisma/config': 6.19.0 + '@prisma/engines': 6.19.0 + typescript: 5.5.4 + transitivePeerDependencies: + - magicast + + /prisma@6.20.0-integration-next.8(@types/react@18.2.69)(react-dom@18.2.0)(react@18.3.1)(typescript@5.5.4): + resolution: {integrity: sha512-KUVwHRuyvl57CpEU6kZc5eMdbhUogmneo2a7jF1GKEZwPZscAU+FXIDsgCH+U4BCpKlm0NVrRd0YKz9+7zBWFQ==} + engines: {node: ^20.19 || ^22.12 || ^24.0} + hasBin: true + requiresBuild: true + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@prisma/config': 6.20.0-integration-next.8 + '@prisma/engines': 6.20.0-integration-next.8 + '@prisma/studio-core-licensed': 0.6.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.3.1) + postgres: 3.4.7 + typescript: 5.5.4 + transitivePeerDependencies: + - '@types/react' + - magicast + - react + - react-dom + /prismjs@1.29.0: resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} engines: {node: '>=6'} @@ -32488,7 +32931,6 @@ packages: loose-envify: 1.4.0 react: 18.3.1 scheduler: 0.23.0 - dev: false /react-dom@19.0.0(react@19.0.0): resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} @@ -33523,15 +33965,6 @@ packages: engines: {node: '>=10'} dev: true - /resolve@1.22.4: - resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} - hasBin: true - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -36224,6 +36657,7 @@ packages: /ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + dev: false /ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} diff --git a/references/prisma-6-client/.env.example b/references/prisma-6-client/.env.example new file mode 100644 index 0000000000..6e4ca028ec --- /dev/null +++ b/references/prisma-6-client/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-6-client?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-6-client?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-6-client/.gitignore b/references/prisma-6-client/.gitignore new file mode 100644 index 0000000000..e251c56238 --- /dev/null +++ b/references/prisma-6-client/.gitignore @@ -0,0 +1 @@ +/src/generated/prisma \ No newline at end of file diff --git a/references/prisma-6-client/package.json b/references/prisma-6-client/package.json new file mode 100644 index 0000000000..98cccc59ed --- /dev/null +++ b/references/prisma-6-client/package.json @@ -0,0 +1,20 @@ +{ + "name": "references-prisma-6-client", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "prisma": "6.16.0" + }, + "dependencies": { + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "6.16.0", + "@prisma/adapter-pg": "6.16.0" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate" + } +} \ No newline at end of file diff --git a/references/prisma-6-client/prisma/migrations/20251114141701_add_initial_migration/migration.sql b/references/prisma-6-client/prisma/migrations/20251114141701_add_initial_migration/migration.sql new file mode 100644 index 0000000000..b493315249 --- /dev/null +++ b/references/prisma-6-client/prisma/migrations/20251114141701_add_initial_migration/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "public"."User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "public"."User"("email"); diff --git a/references/prisma-6-client/prisma/migrations/20251114143739_add_product_model/migration.sql b/references/prisma-6-client/prisma/migrations/20251114143739_add_product_model/migration.sql new file mode 100644 index 0000000000..35f0cc2a13 --- /dev/null +++ b/references/prisma-6-client/prisma/migrations/20251114143739_add_product_model/migration.sql @@ -0,0 +1,10 @@ +-- CreateTable +CREATE TABLE "public"."Product" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "price" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Product_pkey" PRIMARY KEY ("id") +); diff --git a/references/prisma-6-client/prisma/migrations/migration_lock.toml b/references/prisma-6-client/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-6-client/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-6-client/prisma/schema.prisma b/references/prisma-6-client/prisma/schema.prisma new file mode 100644 index 0000000000..86805822c9 --- /dev/null +++ b/references/prisma-6-client/prisma/schema.prisma @@ -0,0 +1,36 @@ +// 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" + output = "../src/generated/prisma" + engineType = "client" + previewFeatures = ["views"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Product { + id Int @id @default(autoincrement()) + name String + price Int + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-6-client/src/db.ts b/references/prisma-6-client/src/db.ts new file mode 100644 index 0000000000..86d879afb8 --- /dev/null +++ b/references/prisma-6-client/src/db.ts @@ -0,0 +1,8 @@ +import { PrismaClient } from "./generated/prisma/client.js"; +import { PrismaPg } from "@prisma/adapter-pg"; + +const adapter = new PrismaPg({ + connectionString: process.env.DATABASE_URL!, +}); + +export const db = new PrismaClient({ adapter }); diff --git a/references/prisma-6-client/src/trigger/tasks.ts b/references/prisma-6-client/src/trigger/tasks.ts new file mode 100644 index 0000000000..df93d70f77 --- /dev/null +++ b/references/prisma-6-client/src/trigger/tasks.ts @@ -0,0 +1,12 @@ +import { AbortTaskRunError, task } from "@trigger.dev/sdk"; +import { db } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-6-client/trigger.config.ts b/references/prisma-6-client/trigger.config.ts new file mode 100644 index 0000000000..85bbb26504 --- /dev/null +++ b/references/prisma-6-client/trigger.config.ts @@ -0,0 +1,26 @@ +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; +import { defineConfig } from "@trigger.dev/sdk"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "modern", + }), + ], + }, +}); diff --git a/references/prisma-6-client/tsconfig.json b/references/prisma-6-client/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-6-client/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} diff --git a/references/prisma-6-config/.env.example b/references/prisma-6-config/.env.example new file mode 100644 index 0000000000..a7011cc439 --- /dev/null +++ b/references/prisma-6-config/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-6-output?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-6-output?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-6-config/.gitignore b/references/prisma-6-config/.gitignore new file mode 100644 index 0000000000..e251c56238 --- /dev/null +++ b/references/prisma-6-config/.gitignore @@ -0,0 +1 @@ +/src/generated/prisma \ No newline at end of file diff --git a/references/prisma-6-config/package.json b/references/prisma-6-config/package.json new file mode 100644 index 0000000000..a8e15a4b10 --- /dev/null +++ b/references/prisma-6-config/package.json @@ -0,0 +1,19 @@ +{ + "name": "references-prisma-6-config", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "prisma": "6.19.0" + }, + "dependencies": { + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "6.19.0" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate" + } +} \ No newline at end of file diff --git a/references/prisma-6-config/prisma.config.ts b/references/prisma-6-config/prisma.config.ts new file mode 100644 index 0000000000..8e4e6fd806 --- /dev/null +++ b/references/prisma-6-config/prisma.config.ts @@ -0,0 +1,13 @@ +import { defineConfig, env } from "prisma/config"; +import "dotenv/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: env("DATABASE_URL"), + directUrl: env("DATABASE_URL_UNPOOLED"), + }, +}); diff --git a/references/prisma-6-config/prisma/migrations/20251117171313_add_initial_migration/migration.sql b/references/prisma-6-config/prisma/migrations/20251117171313_add_initial_migration/migration.sql new file mode 100644 index 0000000000..f8f03ea885 --- /dev/null +++ b/references/prisma-6-config/prisma/migrations/20251117171313_add_initial_migration/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/references/prisma-6-config/prisma/migrations/migration_lock.toml b/references/prisma-6-config/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-6-config/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-6-config/prisma/schema.prisma b/references/prisma-6-config/prisma/schema.prisma new file mode 100644 index 0000000000..7b29b00029 --- /dev/null +++ b/references/prisma-6-config/prisma/schema.prisma @@ -0,0 +1,27 @@ +// 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 = "../src/generated/prisma" + binaryTargets = ["native", "linux-arm64-openssl-3.0.x", "debian-openssl-3.0.x"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-6-config/src/db.ts b/references/prisma-6-config/src/db.ts new file mode 100644 index 0000000000..388ebf3e2c --- /dev/null +++ b/references/prisma-6-config/src/db.ts @@ -0,0 +1,9 @@ +import { PrismaClient } from "./generated/prisma/client.js"; + +export const db = new PrismaClient({ + datasources: { + db: { + url: process.env.DATABASE_URL, + }, + }, +}); diff --git a/references/prisma-6-config/src/trigger/tasks.ts b/references/prisma-6-config/src/trigger/tasks.ts new file mode 100644 index 0000000000..ed656c01bd --- /dev/null +++ b/references/prisma-6-config/src/trigger/tasks.ts @@ -0,0 +1,22 @@ +import { AbortTaskRunError, task } from "@trigger.dev/sdk"; +import { db } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const existingUser = await db.user.findUnique({ + where: { + email: payload.email, + }, + }); + + if (existingUser) { + throw new AbortTaskRunError("User already exists"); + } + + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-6-config/trigger.config.ts b/references/prisma-6-config/trigger.config.ts new file mode 100644 index 0000000000..bfbf2aa323 --- /dev/null +++ b/references/prisma-6-config/trigger.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "@trigger.dev/sdk"; +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "legacy", + configFile: "./prisma.config.ts", + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", + migrate: true, + }), + ], + }, +}); diff --git a/references/prisma-6-config/tsconfig.json b/references/prisma-6-config/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-6-config/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} diff --git a/references/prisma-6-multi-file/.env.example b/references/prisma-6-multi-file/.env.example new file mode 100644 index 0000000000..7e8fc31772 --- /dev/null +++ b/references/prisma-6-multi-file/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-6-multi-file?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-6-multi-file?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-6-multi-file/package.json b/references/prisma-6-multi-file/package.json new file mode 100644 index 0000000000..01e760200b --- /dev/null +++ b/references/prisma-6-multi-file/package.json @@ -0,0 +1,22 @@ +{ + "name": "references-prisma-6-multi-file", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "prisma": "6.14.0" + }, + "dependencies": { + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "6.14.0" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate --sql" + }, + "prisma": { + "schema": "./prisma" + } +} \ No newline at end of file diff --git a/references/prisma-6-multi-file/prisma/migrations/20251113161257_add_initial_migration/migration.sql b/references/prisma-6-multi-file/prisma/migrations/20251113161257_add_initial_migration/migration.sql new file mode 100644 index 0000000000..04378290f0 --- /dev/null +++ b/references/prisma-6-multi-file/prisma/migrations/20251113161257_add_initial_migration/migration.sql @@ -0,0 +1,29 @@ +-- CreateTable +CREATE TABLE "public"."Post" ( + "id" TEXT NOT NULL, + "title" TEXT NOT NULL, + "content" TEXT NOT NULL, + "authorId" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Post_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "public"."User"("email"); + +-- AddForeignKey +ALTER TABLE "public"."Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "public"."User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/references/prisma-6-multi-file/prisma/migrations/migration_lock.toml b/references/prisma-6-multi-file/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-6-multi-file/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-6-multi-file/prisma/models/posts.prisma b/references/prisma-6-multi-file/prisma/models/posts.prisma new file mode 100644 index 0000000000..dfb0df9ceb --- /dev/null +++ b/references/prisma-6-multi-file/prisma/models/posts.prisma @@ -0,0 +1,9 @@ +model Post { + id String @id @default(cuid()) + title String + content String + authorId String + author User @relation(fields: [authorId], references: [id]) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-6-multi-file/prisma/models/users.prisma b/references/prisma-6-multi-file/prisma/models/users.prisma new file mode 100644 index 0000000000..ed1c18a205 --- /dev/null +++ b/references/prisma-6-multi-file/prisma/models/users.prisma @@ -0,0 +1,11 @@ +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + posts Post[] +} diff --git a/references/prisma-6-multi-file/prisma/schema.prisma b/references/prisma-6-multi-file/prisma/schema.prisma new file mode 100644 index 0000000000..11ef81665f --- /dev/null +++ b/references/prisma-6-multi-file/prisma/schema.prisma @@ -0,0 +1,16 @@ +// 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 = ["typedSql"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} diff --git a/references/prisma-6-multi-file/prisma/sql/getUserByEmail.sql b/references/prisma-6-multi-file/prisma/sql/getUserByEmail.sql new file mode 100644 index 0000000000..579143f33c --- /dev/null +++ b/references/prisma-6-multi-file/prisma/sql/getUserByEmail.sql @@ -0,0 +1,3 @@ +SELECT u.id, u.name +FROM "User" u +WHERE u.email = $1 \ No newline at end of file diff --git a/references/prisma-6-multi-file/src/db.ts b/references/prisma-6-multi-file/src/db.ts new file mode 100644 index 0000000000..88a4c0f17b --- /dev/null +++ b/references/prisma-6-multi-file/src/db.ts @@ -0,0 +1,10 @@ +import { PrismaClient } from "@prisma/client"; +export * as sql from "@prisma/client/sql"; + +export const db = new PrismaClient({ + datasources: { + db: { + url: process.env.DATABASE_URL, + }, + }, +}); diff --git a/references/prisma-6-multi-file/src/trigger/tasks.ts b/references/prisma-6-multi-file/src/trigger/tasks.ts new file mode 100644 index 0000000000..018cec35a1 --- /dev/null +++ b/references/prisma-6-multi-file/src/trigger/tasks.ts @@ -0,0 +1,18 @@ +import { AbortTaskRunError, task } from "@trigger.dev/sdk"; +import { db, sql } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const existingUser = await db.$queryRawTyped(sql.getUserByEmail(payload.email)); + + if (existingUser.length > 0) { + throw new AbortTaskRunError("User already exists"); + } + + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-6-multi-file/trigger.config.ts b/references/prisma-6-multi-file/trigger.config.ts new file mode 100644 index 0000000000..5bcbc2f48b --- /dev/null +++ b/references/prisma-6-multi-file/trigger.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from "@trigger.dev/sdk"; +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "legacy", + schema: "./prisma", + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", + migrate: true, + typedSql: true, + }), + ], + }, +}); diff --git a/references/prisma-6-multi-file/tsconfig.json b/references/prisma-6-multi-file/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-6-multi-file/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} diff --git a/references/prisma-6-output/.env.example b/references/prisma-6-output/.env.example new file mode 100644 index 0000000000..a7011cc439 --- /dev/null +++ b/references/prisma-6-output/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-6-output?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-6-output?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-6-output/.gitignore b/references/prisma-6-output/.gitignore new file mode 100644 index 0000000000..e251c56238 --- /dev/null +++ b/references/prisma-6-output/.gitignore @@ -0,0 +1 @@ +/src/generated/prisma \ No newline at end of file diff --git a/references/prisma-6-output/package.json b/references/prisma-6-output/package.json new file mode 100644 index 0000000000..fd94cba7a5 --- /dev/null +++ b/references/prisma-6-output/package.json @@ -0,0 +1,19 @@ +{ + "name": "references-prisma-6-output", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "prisma": "6.19.0" + }, + "dependencies": { + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "6.19.0" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate --sql" + } +} \ No newline at end of file diff --git a/references/prisma-6-output/prisma/migrations/20251113213202_add_initial_migration/migration.sql b/references/prisma-6-output/prisma/migrations/20251113213202_add_initial_migration/migration.sql new file mode 100644 index 0000000000..b493315249 --- /dev/null +++ b/references/prisma-6-output/prisma/migrations/20251113213202_add_initial_migration/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "public"."User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "public"."User"("email"); diff --git a/references/prisma-6-output/prisma/migrations/migration_lock.toml b/references/prisma-6-output/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-6-output/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-6-output/prisma/schema.prisma b/references/prisma-6-output/prisma/schema.prisma new file mode 100644 index 0000000000..abbff158c1 --- /dev/null +++ b/references/prisma-6-output/prisma/schema.prisma @@ -0,0 +1,28 @@ +// 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 = "../src/generated/prisma" + previewFeatures = ["typedSql"] + binaryTargets = ["native", "linux-arm64-openssl-3.0.x"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-6-output/prisma/sql/getUserByEmail.sql b/references/prisma-6-output/prisma/sql/getUserByEmail.sql new file mode 100644 index 0000000000..579143f33c --- /dev/null +++ b/references/prisma-6-output/prisma/sql/getUserByEmail.sql @@ -0,0 +1,3 @@ +SELECT u.id, u.name +FROM "User" u +WHERE u.email = $1 \ No newline at end of file diff --git a/references/prisma-6-output/src/db.ts b/references/prisma-6-output/src/db.ts new file mode 100644 index 0000000000..3fa57fb5cf --- /dev/null +++ b/references/prisma-6-output/src/db.ts @@ -0,0 +1,10 @@ +import { PrismaClient } from "./generated/prisma/client.js"; +export * as sql from "./generated/prisma/sql/index.js"; + +export const db = new PrismaClient({ + datasources: { + db: { + url: process.env.DATABASE_URL, + }, + }, +}); diff --git a/references/prisma-6-output/src/trigger/tasks.ts b/references/prisma-6-output/src/trigger/tasks.ts new file mode 100644 index 0000000000..018cec35a1 --- /dev/null +++ b/references/prisma-6-output/src/trigger/tasks.ts @@ -0,0 +1,18 @@ +import { AbortTaskRunError, task } from "@trigger.dev/sdk"; +import { db, sql } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const existingUser = await db.$queryRawTyped(sql.getUserByEmail(payload.email)); + + if (existingUser.length > 0) { + throw new AbortTaskRunError("User already exists"); + } + + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-6-output/trigger.config.ts b/references/prisma-6-output/trigger.config.ts new file mode 100644 index 0000000000..1f73c6be93 --- /dev/null +++ b/references/prisma-6-output/trigger.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from "@trigger.dev/sdk"; +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "engine-only", + version: "6.19.0", + binaryTarget: "linux-arm64-openssl-3.0.x", + }), + ], + }, +}); diff --git a/references/prisma-6-output/tsconfig.json b/references/prisma-6-output/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-6-output/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} diff --git a/references/prisma-6/.env.example b/references/prisma-6/.env.example new file mode 100644 index 0000000000..0accda31a8 --- /dev/null +++ b/references/prisma-6/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-6?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-6?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-6/package.json b/references/prisma-6/package.json new file mode 100644 index 0000000000..b46902f5fe --- /dev/null +++ b/references/prisma-6/package.json @@ -0,0 +1,19 @@ +{ + "name": "references-prisma-6", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "prisma": "6.14.0" + }, + "dependencies": { + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "6.14.0" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate --sql" + } +} \ No newline at end of file diff --git a/references/prisma-6/prisma/migrations/20251113155334_add_initial_migration/migration.sql b/references/prisma-6/prisma/migrations/20251113155334_add_initial_migration/migration.sql new file mode 100644 index 0000000000..b493315249 --- /dev/null +++ b/references/prisma-6/prisma/migrations/20251113155334_add_initial_migration/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "public"."User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "public"."User"("email"); diff --git a/references/prisma-6/prisma/migrations/migration_lock.toml b/references/prisma-6/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-6/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-6/prisma/schema.prisma b/references/prisma-6/prisma/schema.prisma new file mode 100644 index 0000000000..724a9ebc00 --- /dev/null +++ b/references/prisma-6/prisma/schema.prisma @@ -0,0 +1,26 @@ +// 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 = ["typedSql"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DATABASE_URL_UNPOOLED") +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-6/prisma/sql/getUserByEmail.sql b/references/prisma-6/prisma/sql/getUserByEmail.sql new file mode 100644 index 0000000000..579143f33c --- /dev/null +++ b/references/prisma-6/prisma/sql/getUserByEmail.sql @@ -0,0 +1,3 @@ +SELECT u.id, u.name +FROM "User" u +WHERE u.email = $1 \ No newline at end of file diff --git a/references/prisma-6/src/db.ts b/references/prisma-6/src/db.ts new file mode 100644 index 0000000000..88a4c0f17b --- /dev/null +++ b/references/prisma-6/src/db.ts @@ -0,0 +1,10 @@ +import { PrismaClient } from "@prisma/client"; +export * as sql from "@prisma/client/sql"; + +export const db = new PrismaClient({ + datasources: { + db: { + url: process.env.DATABASE_URL, + }, + }, +}); diff --git a/references/prisma-6/src/trigger/tasks.ts b/references/prisma-6/src/trigger/tasks.ts new file mode 100644 index 0000000000..018cec35a1 --- /dev/null +++ b/references/prisma-6/src/trigger/tasks.ts @@ -0,0 +1,18 @@ +import { AbortTaskRunError, task } from "@trigger.dev/sdk"; +import { db, sql } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const existingUser = await db.$queryRawTyped(sql.getUserByEmail(payload.email)); + + if (existingUser.length > 0) { + throw new AbortTaskRunError("User already exists"); + } + + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-6/trigger.config.ts b/references/prisma-6/trigger.config.ts new file mode 100644 index 0000000000..07d91101d2 --- /dev/null +++ b/references/prisma-6/trigger.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from "@trigger.dev/sdk"; +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "legacy", + schema: "prisma/schema.prisma", + migrate: true, + typedSql: true, + directUrlEnvVarName: "DATABASE_URL_UNPOOLED", + }), + ], + }, +}); diff --git a/references/prisma-6/tsconfig.json b/references/prisma-6/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-6/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} diff --git a/references/prisma-7/.env.example b/references/prisma-7/.env.example new file mode 100644 index 0000000000..a3195b263a --- /dev/null +++ b/references/prisma-7/.env.example @@ -0,0 +1,12 @@ +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL=postgresql://postgres:postgres@localhost:5432/references-prisma-7?schema=public +DATABASE_URL_UNPOOLED=postgresql://postgres:postgres@localhost:5432/references-prisma-7?schema=public + +# Trigger.dev env vars, see our guide on API Keys here: https://trigger.dev/docs/apikeys +TRIGGER_PROJECT_REF="" + diff --git a/references/prisma-7/.gitignore b/references/prisma-7/.gitignore new file mode 100644 index 0000000000..126419ded6 --- /dev/null +++ b/references/prisma-7/.gitignore @@ -0,0 +1,5 @@ +node_modules +# Keep environment variables out of version control +.env + +/src/generated/prisma diff --git a/references/prisma-7/.nvmrc b/references/prisma-7/.nvmrc new file mode 100644 index 0000000000..829e9737e4 --- /dev/null +++ b/references/prisma-7/.nvmrc @@ -0,0 +1 @@ +20.19.0 \ No newline at end of file diff --git a/references/prisma-7/package.json b/references/prisma-7/package.json new file mode 100644 index 0000000000..2fff27d997 --- /dev/null +++ b/references/prisma-7/package.json @@ -0,0 +1,21 @@ +{ + "name": "references-prisma-7", + "private": true, + "type": "module", + "devDependencies": { + "prisma": "6.20.0-integration-next.8", + "trigger.dev": "workspace:*" + }, + "dependencies": { + "@prisma/client": "6.20.0-integration-next.8", + "@prisma/adapter-pg": "6.20.0-integration-next.8", + "@trigger.dev/build": "workspace:*", + "@trigger.dev/sdk": "workspace:*", + "dotenv": "^17.2.3" + }, + "scripts": { + "dev": "trigger dev", + "deploy": "trigger deploy", + "prisma:generate": "prisma generate" + } +} \ No newline at end of file diff --git a/references/prisma-7/prisma.config.ts b/references/prisma-7/prisma.config.ts new file mode 100644 index 0000000000..fa89f0f3c2 --- /dev/null +++ b/references/prisma-7/prisma.config.ts @@ -0,0 +1,12 @@ +import { defineConfig, env } from "prisma/config"; +import "dotenv/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: env("DATABASE_URL"), + }, +}); diff --git a/references/prisma-7/prisma/migrations/20251113162106_add_initial_migration/migration.sql b/references/prisma-7/prisma/migrations/20251113162106_add_initial_migration/migration.sql new file mode 100644 index 0000000000..f8f03ea885 --- /dev/null +++ b/references/prisma-7/prisma/migrations/20251113162106_add_initial_migration/migration.sql @@ -0,0 +1,14 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "avatarUrl" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/references/prisma-7/prisma/migrations/migration_lock.toml b/references/prisma-7/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..044d57cdb0 --- /dev/null +++ b/references/prisma-7/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/references/prisma-7/prisma/schema.prisma b/references/prisma-7/prisma/schema.prisma new file mode 100644 index 0000000000..c47a551bd4 --- /dev/null +++ b/references/prisma-7/prisma/schema.prisma @@ -0,0 +1,24 @@ +// 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" + output = "../src/generated/prisma" +} + +datasource db { + provider = "postgresql" +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + avatarUrl String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/references/prisma-7/src/db.ts b/references/prisma-7/src/db.ts new file mode 100644 index 0000000000..86d879afb8 --- /dev/null +++ b/references/prisma-7/src/db.ts @@ -0,0 +1,8 @@ +import { PrismaClient } from "./generated/prisma/client.js"; +import { PrismaPg } from "@prisma/adapter-pg"; + +const adapter = new PrismaPg({ + connectionString: process.env.DATABASE_URL!, +}); + +export const db = new PrismaClient({ adapter }); diff --git a/references/prisma-7/src/trigger/tasks.ts b/references/prisma-7/src/trigger/tasks.ts new file mode 100644 index 0000000000..b52b70f0dd --- /dev/null +++ b/references/prisma-7/src/trigger/tasks.ts @@ -0,0 +1,12 @@ +import { task } from "@trigger.dev/sdk"; +import { db } from "../db.js"; + +export const createUserTask = task({ + id: "create-user", + run: async (payload: { email: string; name: string; avatarUrl: string }) => { + const user = await db.user.create({ + data: payload, + }); + return user; + }, +}); diff --git a/references/prisma-7/trigger.config.ts b/references/prisma-7/trigger.config.ts new file mode 100644 index 0000000000..85bbb26504 --- /dev/null +++ b/references/prisma-7/trigger.config.ts @@ -0,0 +1,26 @@ +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; +import { defineConfig } from "@trigger.dev/sdk"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_REF!, + logLevel: "debug", + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + machine: "small-1x", + build: { + extensions: [ + prismaExtension({ + mode: "modern", + }), + ], + }, +}); diff --git a/references/prisma-7/tsconfig.json b/references/prisma-7/tsconfig.json new file mode 100644 index 0000000000..9a5ee0b9d6 --- /dev/null +++ b/references/prisma-7/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +}