build extensions can now install custom packages and run instructions in the image. Also prisma extension now works and also works with multiple schema files
This commit is contained in:
@@ -126,37 +126,37 @@ function applyLayerToManifest(layer: BuildLayer, manifest: BuildManifest): Build
|
||||
let $manifest = { ...manifest };
|
||||
|
||||
if (layer.commands) {
|
||||
manifest.build.commands ??= [];
|
||||
manifest.build.commands = manifest.build.commands.concat(layer.commands);
|
||||
$manifest.build.commands ??= [];
|
||||
$manifest.build.commands = $manifest.build.commands.concat(layer.commands);
|
||||
}
|
||||
|
||||
if (layer.build?.env) {
|
||||
manifest.build.env ??= {};
|
||||
Object.assign(manifest.build.env, layer.build.env);
|
||||
$manifest.build.env ??= {};
|
||||
Object.assign($manifest.build.env, layer.build.env);
|
||||
}
|
||||
|
||||
if (layer.deploy?.env) {
|
||||
manifest.deploy.env ??= {};
|
||||
manifest.deploy.sync ??= {};
|
||||
manifest.deploy.sync.env ??= {};
|
||||
$manifest.deploy.env ??= {};
|
||||
$manifest.deploy.sync ??= {};
|
||||
$manifest.deploy.sync.env ??= {};
|
||||
|
||||
for (const [key, value] of Object.entries(layer.deploy.env)) {
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layer.deploy.override || manifest.deploy.env[key] === undefined) {
|
||||
const existingValue = manifest.deploy.env[key];
|
||||
if (layer.deploy.override || $manifest.deploy.env[key] === undefined) {
|
||||
const existingValue = $manifest.deploy.env[key];
|
||||
|
||||
if (existingValue !== value) {
|
||||
manifest.deploy.sync.env[key] = value;
|
||||
$manifest.deploy.sync.env[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.dependencies) {
|
||||
const externals = manifest.externals ?? [];
|
||||
const externals = $manifest.externals ?? [];
|
||||
|
||||
for (const [name, version] of Object.entries(layer.dependencies)) {
|
||||
externals.push({ name, version });
|
||||
@@ -165,6 +165,21 @@ function applyLayerToManifest(layer: BuildLayer, manifest: BuildManifest): Build
|
||||
$manifest.externals = externals;
|
||||
}
|
||||
|
||||
if (layer.image) {
|
||||
$manifest.image ??= {};
|
||||
$manifest.image.instructions ??= [];
|
||||
$manifest.image.pkgs ??= [];
|
||||
|
||||
if (layer.image.instructions) {
|
||||
$manifest.image.instructions = $manifest.image.instructions.concat(layer.image.instructions);
|
||||
}
|
||||
|
||||
if (layer.image.pkgs) {
|
||||
$manifest.image.pkgs = $manifest.image.pkgs.concat(layer.image.pkgs);
|
||||
$manifest.image.pkgs = Array.from(new Set($manifest.image.pkgs));
|
||||
}
|
||||
}
|
||||
|
||||
return $manifest;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,6 +378,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
|
||||
apiKey: projectClient.client.accessToken!,
|
||||
authAccessToken: authorization.auth.accessToken,
|
||||
compilationPath: destination.path,
|
||||
buildEnvVars: buildManifest.build.env,
|
||||
});
|
||||
|
||||
logger.debug("Build result", buildResult);
|
||||
@@ -564,6 +565,7 @@ async function writeContainerfile(outputPath: string, buildManifest: BuildManife
|
||||
runtime: buildManifest.runtime,
|
||||
entrypoint: buildManifest.runControllerEntryPoint,
|
||||
build: buildManifest.build,
|
||||
image: buildManifest.image,
|
||||
indexScript: buildManifest.indexControllerEntryPoint,
|
||||
});
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface BuildImageOptions {
|
||||
extraCACerts?: string;
|
||||
apiUrl: string;
|
||||
apiKey: string;
|
||||
buildEnvVars?: Record<string, string | undefined>;
|
||||
|
||||
// Optional deployment spinner
|
||||
deploymentSpinner?: any; // Replace 'any' with the actual type if known
|
||||
@@ -62,6 +63,7 @@ export async function buildImage(options: BuildImageOptions) {
|
||||
extraCACerts,
|
||||
apiUrl,
|
||||
apiKey,
|
||||
buildEnvVars,
|
||||
} = options;
|
||||
|
||||
if (selfHosted) {
|
||||
@@ -81,6 +83,7 @@ export async function buildImage(options: BuildImageOptions) {
|
||||
extraCACerts: extraCACerts,
|
||||
apiUrl,
|
||||
apiKey,
|
||||
buildEnvVars,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,6 +112,7 @@ export async function buildImage(options: BuildImageOptions) {
|
||||
extraCACerts,
|
||||
apiUrl,
|
||||
apiKey,
|
||||
buildEnvVars,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -131,6 +135,7 @@ export interface DepotBuildImageOptions {
|
||||
loadImage?: boolean;
|
||||
noCache?: boolean;
|
||||
extraCACerts?: string;
|
||||
buildEnvVars?: Record<string, string | undefined>;
|
||||
}
|
||||
|
||||
type BuildImageSuccess = {
|
||||
@@ -156,6 +161,10 @@ async function depotBuildImage(options: DepotBuildImageOptions): Promise<BuildIm
|
||||
password: options.auth,
|
||||
});
|
||||
|
||||
const buildArgs = Object.entries(options.buildEnvVars || {})
|
||||
.filter(([key, value]) => value)
|
||||
.flatMap(([key, value]) => ["--build-arg", `${key}=${value}`]);
|
||||
|
||||
const args = [
|
||||
"build",
|
||||
"-f",
|
||||
@@ -179,6 +188,7 @@ async function depotBuildImage(options: DepotBuildImageOptions): Promise<BuildIm
|
||||
`TRIGGER_API_URL=${options.apiUrl}`,
|
||||
"--build-arg",
|
||||
`TRIGGER_SECRET_KEY=${options.apiKey}`,
|
||||
...(buildArgs || []),
|
||||
...(options.extraCACerts ? ["--build-arg", `NODE_EXTRA_CA_CERTS=${options.extraCACerts}`] : []),
|
||||
"--progress",
|
||||
"plain",
|
||||
@@ -266,6 +276,7 @@ interface SelfHostedBuildImageOptions {
|
||||
apiKey: string;
|
||||
noCache?: boolean;
|
||||
extraCACerts?: string;
|
||||
buildEnvVars?: Record<string, string | undefined>;
|
||||
}
|
||||
|
||||
async function selfHostedBuildImage(
|
||||
@@ -273,7 +284,11 @@ async function selfHostedBuildImage(
|
||||
): Promise<BuildImageResults> {
|
||||
const imageRef = `${options.registryHost ? `${options.registryHost}/` : ""}${options.imageTag}`;
|
||||
|
||||
const buildArgs = [
|
||||
const buildArgs = Object.entries(options.buildEnvVars || {})
|
||||
.filter(([key, value]) => value)
|
||||
.flatMap(([key, value]) => ["--build-arg", `${key}=${value}`]);
|
||||
|
||||
const args = [
|
||||
"build",
|
||||
"-f",
|
||||
"Containerfile",
|
||||
@@ -294,6 +309,7 @@ async function selfHostedBuildImage(
|
||||
`TRIGGER_API_URL=${options.apiUrl}`,
|
||||
"--build-arg",
|
||||
`TRIGGER_SECRET_KEY=${options.apiKey}`,
|
||||
...(buildArgs || []),
|
||||
...(options.extraCACerts ? ["--build-arg", `NODE_EXTRA_CA_CERTS=${options.extraCACerts}`] : []),
|
||||
"--progress",
|
||||
"plain",
|
||||
@@ -302,7 +318,7 @@ async function selfHostedBuildImage(
|
||||
".", // The build context
|
||||
].filter(Boolean) as string[];
|
||||
|
||||
logger.debug(`docker ${buildArgs.join(" ")}`, {
|
||||
logger.debug(`docker ${args.join(" ")}`, {
|
||||
cwd: options.cwd,
|
||||
});
|
||||
|
||||
@@ -310,7 +326,7 @@ async function selfHostedBuildImage(
|
||||
let digest: string | undefined;
|
||||
|
||||
// Build the image
|
||||
const buildProcess = x("docker", buildArgs, {
|
||||
const buildProcess = x("docker", args, {
|
||||
nodeOptions: { cwd: options.cwd },
|
||||
});
|
||||
|
||||
@@ -408,10 +424,13 @@ function extractImageDigest(outputs: string[]) {
|
||||
export type GenerateContainerfileOptions = {
|
||||
runtime: BuildRuntime;
|
||||
build: BuildManifest["build"];
|
||||
image: BuildManifest["image"];
|
||||
indexScript: string;
|
||||
entrypoint: string;
|
||||
};
|
||||
|
||||
const DEFAULT_PACKAGES = ["busybox", "ca-certificates", "dumb-init", "git", "openssl"];
|
||||
|
||||
export async function generateContainerfile(options: GenerateContainerfileOptions) {
|
||||
switch (options.runtime) {
|
||||
case "node": {
|
||||
@@ -434,9 +453,18 @@ async function generateBunContainerfile(options: GenerateContainerfileOptions) {
|
||||
|
||||
const postInstallCommands = (options.build.commands || []).map((cmd) => `RUN ${cmd}`).join("\n");
|
||||
|
||||
const baseInstructions = (options.image?.instructions || []).join("\n");
|
||||
const packages = Array.from(new Set(DEFAULT_PACKAGES.concat(options.image?.pkgs || []))).join(
|
||||
" "
|
||||
);
|
||||
|
||||
return `
|
||||
FROM imbios/bun-node:22-debian AS base
|
||||
RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends busybox ca-certificates dumb-init git openssl && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
${baseInstructions}
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends ${packages} && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM base AS build
|
||||
|
||||
@@ -530,10 +558,18 @@ async function generateNodeContainerfile(options: GenerateContainerfileOptions)
|
||||
|
||||
const postInstallCommands = (options.build.commands || []).map((cmd) => `RUN ${cmd}`).join("\n");
|
||||
|
||||
const baseInstructions = (options.image?.instructions || []).join("\n");
|
||||
const packages = Array.from(new Set(DEFAULT_PACKAGES.concat(options.image?.pkgs || []))).join(
|
||||
" "
|
||||
);
|
||||
|
||||
return `
|
||||
FROM node:21-bookworm-slim@sha256:99afef5df7400a8d118e0504576d32ca700de5034c4f9271d2ff7c91cc12d170 AS base
|
||||
|
||||
${baseInstructions}
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends busybox ca-certificates dumb-init git openssl && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends ${packages} && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM base AS build
|
||||
|
||||
|
||||
@@ -56,6 +56,10 @@ export interface BuildLayer {
|
||||
id: string;
|
||||
commands?: string[];
|
||||
files?: Record<string, string>;
|
||||
image?: {
|
||||
pkgs?: string[];
|
||||
instructions?: string[];
|
||||
};
|
||||
build?: {
|
||||
env?: Record<string, string | undefined>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { BuildContext, BuildExtension } from "../build/extensions.js";
|
||||
import { BuildManifest } from "../schemas/build.js";
|
||||
|
||||
export type AudioWaveformOptions = {
|
||||
version?: string;
|
||||
checksum?: string;
|
||||
};
|
||||
|
||||
const AUDIOWAVEFORM_VERSION = "1.10.1";
|
||||
const AUDIOWAVEFORM_CHECKSUM =
|
||||
"sha256:00b41ea4d6e7a5b4affcfe4ac99951ec89da81a8cba40af19e9b98c3a8f9b4b8";
|
||||
|
||||
export function audioWaveform(options: AudioWaveformOptions = {}): BuildExtension {
|
||||
return new AudioWaveformExtension();
|
||||
}
|
||||
|
||||
class AudioWaveformExtension implements BuildExtension {
|
||||
public readonly name = "AudioWaveformExtension";
|
||||
|
||||
constructor(private options: AudioWaveformOptions = {}) {}
|
||||
|
||||
async onBuildComplete(context: BuildContext, manifest: BuildManifest) {
|
||||
if (context.target === "dev") {
|
||||
return;
|
||||
}
|
||||
|
||||
const opts = this.options.version
|
||||
? {
|
||||
version: this.options.version,
|
||||
checksum: this.options.checksum,
|
||||
}
|
||||
: {
|
||||
version: AUDIOWAVEFORM_VERSION,
|
||||
checksum: AUDIOWAVEFORM_CHECKSUM,
|
||||
};
|
||||
|
||||
context.logger.debug("Adding audiowaveform to the build", {
|
||||
...opts,
|
||||
});
|
||||
|
||||
const instructions = [
|
||||
`ADD ${
|
||||
opts.checksum ? `--checksum=${opts.checksum}` : ""
|
||||
} https://github.com/bbc/audiowaveform/releases/download/${opts.version}/audiowaveform_${
|
||||
opts.version
|
||||
}-1-12_amd64.deb .`,
|
||||
`RUN dpkg -i audiowaveform_${opts.version}-1-12_amd64.deb || true`,
|
||||
`RUN rm audiowaveform*.deb`,
|
||||
];
|
||||
|
||||
context.addLayer({
|
||||
id: "audiowaveform",
|
||||
image: {
|
||||
pkgs: ["sox"],
|
||||
instructions,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,4 @@ export * from "./additionalFiles.js";
|
||||
export * from "./additionalPackages.js";
|
||||
export * from "./prisma.js";
|
||||
export * from "./syncEnvVars.js";
|
||||
export * from "./audioWaveform.js";
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import assert from "node:assert";
|
||||
import { existsSync } from "node:fs";
|
||||
import { cp } from "node:fs/promises";
|
||||
import { join, resolve } from "node:path";
|
||||
import { cp, readdir } from "node:fs/promises";
|
||||
import { dirname, join, resolve } from "node:path";
|
||||
import { BuildContext, BuildExtension } from "../build/extensions.js";
|
||||
import { BuildManifest, BuildTarget } from "../schemas/build.js";
|
||||
import { binaryForRuntime } from "../build/runtime.js";
|
||||
import { BuildManifest, BuildTarget } from "../schemas/build.js";
|
||||
|
||||
export type PrismaExtensionOptions = {
|
||||
schema: string;
|
||||
migrate?: boolean;
|
||||
version?: string;
|
||||
directUrlEnvVarName?: string;
|
||||
};
|
||||
|
||||
const BINARY_TARGET = "linux-arm64-openssl-3.0.x";
|
||||
|
||||
export function prismaExtension(options: PrismaExtensionOptions): PrismaExtension {
|
||||
return new PrismaExtension(options);
|
||||
}
|
||||
|
||||
export class PrismaExtension implements BuildExtension {
|
||||
moduleExternals: string[];
|
||||
|
||||
@@ -76,51 +81,109 @@ export class PrismaExtension implements BuildExtension {
|
||||
|
||||
context.logger.debug(`PrismaExtension is generating the Prisma client for version ${version}`);
|
||||
|
||||
// Now we need to add a layer that:
|
||||
// Copies the prisma schema to the build outputPath
|
||||
// Adds the `prisma` CLI dependency to the dependencies
|
||||
// Adds the `prisma generate` command, which generates the Prisma client
|
||||
const schemaDestinationPath = join(manifest.outputPath, "prisma", "schema.prisma");
|
||||
// Copy the prisma schema to the build output path
|
||||
context.logger.debug(
|
||||
`Copying the prisma schema from ${this._resolvedSchemaPath} to ${schemaDestinationPath}`
|
||||
);
|
||||
const usingSchemaFolder = dirname(this._resolvedSchemaPath).endsWith("schema");
|
||||
|
||||
await cp(this._resolvedSchemaPath, schemaDestinationPath);
|
||||
const commands: string[] = [];
|
||||
|
||||
const commands = [
|
||||
`${binaryForRuntime(
|
||||
manifest.runtime
|
||||
)} node_modules/prisma/build/index.js generate --schema=./prisma/schema.prisma`,
|
||||
];
|
||||
let prismaDir: string | undefined;
|
||||
|
||||
if (usingSchemaFolder) {
|
||||
const schemaDir = dirname(this._resolvedSchemaPath);
|
||||
|
||||
prismaDir = dirname(schemaDir);
|
||||
|
||||
context.logger.debug(`Using the schema folder: ${schemaDir}`);
|
||||
|
||||
// Find all the files in schemaDir that end with .prisma (excluding the schema.prisma file)
|
||||
const prismaFiles = await readdir(schemaDir).then((files) =>
|
||||
files.filter((file) => file.endsWith(".prisma"))
|
||||
);
|
||||
|
||||
context.logger.debug(`Found prisma files in the schema folder`, {
|
||||
prismaFiles,
|
||||
});
|
||||
|
||||
const schemaDestinationPath = join(manifest.outputPath, "prisma", "schema");
|
||||
|
||||
const allPrismaFiles = [...prismaFiles];
|
||||
|
||||
for (const file of allPrismaFiles) {
|
||||
const destination = join(schemaDestinationPath, file);
|
||||
const source = join(schemaDir, file);
|
||||
|
||||
context.logger.debug(`Copying the prisma schema from ${source} to ${destination}`);
|
||||
|
||||
await cp(source, destination);
|
||||
}
|
||||
|
||||
commands.push(
|
||||
`${binaryForRuntime(manifest.runtime)} node_modules/prisma/build/index.js generate` // Don't add the --schema flag or this will fail
|
||||
);
|
||||
} else {
|
||||
prismaDir = dirname(this._resolvedSchemaPath);
|
||||
// Now we need to add a layer that:
|
||||
// Copies the prisma schema to the build outputPath
|
||||
// Adds the `prisma` CLI dependency to the dependencies
|
||||
// Adds the `prisma generate` command, which generates the Prisma client
|
||||
const schemaDestinationPath = join(manifest.outputPath, "prisma", "schema.prisma");
|
||||
// Copy the prisma schema to the build output path
|
||||
context.logger.debug(
|
||||
`Copying the prisma schema from ${this._resolvedSchemaPath} to ${schemaDestinationPath}`
|
||||
);
|
||||
|
||||
await cp(this._resolvedSchemaPath, schemaDestinationPath);
|
||||
|
||||
commands.push(
|
||||
`${binaryForRuntime(
|
||||
manifest.runtime
|
||||
)} node_modules/prisma/build/index.js generate --schema=./prisma/schema.prisma`
|
||||
);
|
||||
}
|
||||
|
||||
const env: Record<string, string | undefined> = {};
|
||||
|
||||
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(
|
||||
`Copying the prisma migrations from ${migrationsDir} to ${migrationsDestinationPath}`
|
||||
);
|
||||
|
||||
await cp(migrationsDir, migrationsDestinationPath, { recursive: true });
|
||||
|
||||
commands.push(
|
||||
`${binaryForRuntime(manifest.runtime)} node_modules/prisma/build/index.js migrate deploy`
|
||||
);
|
||||
|
||||
env.DATABASE_URL = manifest.deploy.env?.DATABASE_URL;
|
||||
|
||||
if (this.options.directUrlEnvVarName) {
|
||||
env[this.options.directUrlEnvVarName] =
|
||||
manifest.deploy.env?.[this.options.directUrlEnvVarName];
|
||||
} else {
|
||||
env.DIRECT_URL = manifest.deploy.env?.DIRECT_URL;
|
||||
}
|
||||
}
|
||||
|
||||
context.logger.debug(`Adding the prisma layer with the following commands`, {
|
||||
commands,
|
||||
env,
|
||||
dependencies: {
|
||||
prisma: version,
|
||||
},
|
||||
});
|
||||
|
||||
context.addLayer({
|
||||
id: "prisma",
|
||||
commands,
|
||||
dependencies: {
|
||||
prisma: version,
|
||||
},
|
||||
build: this.options.migrate
|
||||
? {
|
||||
env: {
|
||||
DATABASE_URL: manifest.deploy.env?.DATABASE_URL,
|
||||
DATABASE_DIRECT_URL:
|
||||
manifest.deploy.env?.DATABASE_DIRECT_URL ??
|
||||
manifest.deploy.env?.DIRECT_URL ??
|
||||
manifest.deploy.env?.DATABASE_URL,
|
||||
DIRECT_URL:
|
||||
manifest.deploy.env?.DATABASE_DIRECT_URL ??
|
||||
manifest.deploy.env?.DIRECT_URL ??
|
||||
manifest.deploy.env?.DATABASE_URL,
|
||||
},
|
||||
}
|
||||
: {},
|
||||
build: {
|
||||
env,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,12 @@ export const BuildManifest = z.object({
|
||||
})
|
||||
.optional(),
|
||||
}),
|
||||
image: z
|
||||
.object({
|
||||
pkgs: z.array(z.string()).optional(),
|
||||
instructions: z.array(z.string()).optional(),
|
||||
})
|
||||
.optional(),
|
||||
otelImportHook: z
|
||||
.object({
|
||||
include: z.array(z.string()).optional(),
|
||||
|
||||
Generated
+54
@@ -1354,6 +1354,9 @@ importers:
|
||||
'@opentelemetry/api':
|
||||
specifier: 1.4.1
|
||||
version: 1.4.1
|
||||
'@prisma/client':
|
||||
specifier: 5.18.0
|
||||
version: 5.18.0(prisma@5.18.0)
|
||||
'@react-email/components':
|
||||
specifier: ^0.0.17
|
||||
version: 0.0.17(@types/react@18.3.1)(react@18.2.0)
|
||||
@@ -1475,6 +1478,9 @@ importers:
|
||||
esbuild:
|
||||
specifier: ^0.19.11
|
||||
version: 0.19.11
|
||||
prisma:
|
||||
specifier: 5.18.0
|
||||
version: 5.18.0
|
||||
trigger.dev:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/cli-v3
|
||||
@@ -7878,6 +7884,19 @@ packages:
|
||||
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
|
||||
dev: false
|
||||
|
||||
/@prisma/client@5.18.0(prisma@5.18.0):
|
||||
resolution: {integrity: sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==}
|
||||
engines: {node: '>=16.13'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
prisma: '*'
|
||||
peerDependenciesMeta:
|
||||
prisma:
|
||||
optional: true
|
||||
dependencies:
|
||||
prisma: 5.18.0
|
||||
dev: false
|
||||
|
||||
/@prisma/client@5.4.1(prisma@5.4.1):
|
||||
resolution: {integrity: sha512-xyD0DJ3gRNfLbPsC+YfMBBuLJtZKQfy1OD2qU/PZg+HKrr7SO+09174LMeTlWP0YF2wca9LxtVd4HnAiB5ketQ==}
|
||||
engines: {node: '>=16.13'}
|
||||
@@ -7892,14 +7911,41 @@ packages:
|
||||
prisma: 5.4.1
|
||||
dev: false
|
||||
|
||||
/@prisma/debug@5.18.0:
|
||||
resolution: {integrity: sha512-f+ZvpTLidSo3LMJxQPVgAxdAjzv5OpzAo/eF8qZqbwvgi2F5cTOI9XCpdRzJYA0iGfajjwjOKKrVq64vkxEfUw==}
|
||||
|
||||
/@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169:
|
||||
resolution: {integrity: sha512-a/+LpJj8vYU3nmtkg+N3X51ddbt35yYrRe8wqHTJtYQt7l1f8kjIBcCs6sHJvodW/EK5XGvboOiwm47fmNrbgg==}
|
||||
|
||||
/@prisma/engines-version@5.4.1-1.2f302df92bd8945e20ad4595a73def5b96afa54f:
|
||||
resolution: {integrity: sha512-+nUQM/y8C+1GG5Ioeqcu6itFslCfxvQSAUVSMC9XM2G2Fcq0F4Afnp6m0pXF6X6iUBWen7jZBPmM9Qlq4Nr3/A==}
|
||||
dev: false
|
||||
|
||||
/@prisma/engines@5.18.0:
|
||||
resolution: {integrity: sha512-ofmpGLeJ2q2P0wa/XaEgTnX/IsLnvSp/gZts0zjgLNdBhfuj2lowOOPmDcfKljLQUXMvAek3lw5T01kHmCG8rg==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@prisma/debug': 5.18.0
|
||||
'@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169
|
||||
'@prisma/fetch-engine': 5.18.0
|
||||
'@prisma/get-platform': 5.18.0
|
||||
|
||||
/@prisma/engines@5.4.1:
|
||||
resolution: {integrity: sha512-vJTdY4la/5V3N7SFvWRmSMUh4mIQnyb/MNoDjzVbh9iLmEC+uEykj/1GPviVsorvfz7DbYSQC4RiwmlEpTEvGA==}
|
||||
requiresBuild: true
|
||||
|
||||
/@prisma/fetch-engine@5.18.0:
|
||||
resolution: {integrity: sha512-I/3u0x2n31rGaAuBRx2YK4eB7R/1zCuayo2DGwSpGyrJWsZesrV7QVw7ND0/Suxeo/vLkJ5OwuBqHoCxvTHpOg==}
|
||||
dependencies:
|
||||
'@prisma/debug': 5.18.0
|
||||
'@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169
|
||||
'@prisma/get-platform': 5.18.0
|
||||
|
||||
/@prisma/get-platform@5.18.0:
|
||||
resolution: {integrity: sha512-Tk+m7+uhqcKDgnMnFN0lRiH7Ewea0OEsZZs9pqXa7i3+7svS3FSCqDBCaM9x5fmhhkufiG0BtunJVDka+46DlA==}
|
||||
dependencies:
|
||||
'@prisma/debug': 5.18.0
|
||||
|
||||
/@prisma/instrumentation@5.11.0:
|
||||
resolution: {integrity: sha512-ou4nvDpNEY6+t3Dn9juOTz6tK33D0Y4XXkEZ2uPd8KH6Mqmc+4LYOOm470DP7noj7dyJjuGiM+wpPk//HKrcDg==}
|
||||
dependencies:
|
||||
@@ -23543,6 +23589,14 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/prisma@5.18.0:
|
||||
resolution: {integrity: sha512-+TrSIxZsh64OPOmaSgVPH7ALL9dfU0jceYaMJXsNrTkFHO7/3RANi5K2ZiPB1De9+KDxCWn7jvRq8y8pvk+o9g==}
|
||||
engines: {node: '>=16.13'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@prisma/engines': 5.18.0
|
||||
|
||||
/prisma@5.4.1:
|
||||
resolution: {integrity: sha512-op9PmU8Bcw5dNAas82wBYTG0yHnpq9/O3bhxbDBrNzwZTwBqsVCxxYRLf6wHNh9HVaDGhgjjHlu1+BcW8qdnBg==}
|
||||
engines: {node: '>=16.13'}
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
"build:client": "tsup-node ./src/clientUsage.ts --format esm,cjs",
|
||||
"client": "ts-node -r dotenv/config -r tsconfig-paths/register ./src/clientUsage.ts",
|
||||
"triggerWithLargePayload": "ts-node -r dotenv/config -r tsconfig-paths/register ./src/triggerWithLargePayload.ts",
|
||||
"postinstall": "echo 'package.json postinstall'"
|
||||
"postinstall": "prisma generate --no-hints"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "5.18.0",
|
||||
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
||||
"@ffprobe-installer/ffprobe": "^2.1.2",
|
||||
"@infisical/sdk": "^2.1.9",
|
||||
@@ -66,6 +67,7 @@
|
||||
"trigger.dev": "workspace:*",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.5.4"
|
||||
"typescript": "^5.5.4",
|
||||
"prisma": "5.18.0"
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Post" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"authorId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
@@ -1,14 +0,0 @@
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
directUrl = env("DIRECT_URL")
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// post.prisma
|
||||
model Post {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
content String
|
||||
authorId Int
|
||||
author User @relation(fields: [authorId], references: [id])
|
||||
}
|
||||
@@ -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 = ["prismaSchemaFolder"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
directUrl = env("DATABASE_URL_UNPOOLED")
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// user.prisma
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
posts Post[]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
export const prisma = new PrismaClient();
|
||||
@@ -0,0 +1,17 @@
|
||||
import { prisma } from "@/db.js";
|
||||
import { task } from "@trigger.dev/sdk/v3";
|
||||
|
||||
export const prismaTask = task({
|
||||
id: "prisma-task",
|
||||
run: async () => {
|
||||
const users = await prisma.user.findMany();
|
||||
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
name: "Alice",
|
||||
},
|
||||
});
|
||||
|
||||
return users;
|
||||
},
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai";
|
||||
import { defineConfig, ResolveEnvironmentVariablesFunction } from "@trigger.dev/sdk/v3";
|
||||
import { emitDecoratorMetadata } from "@trigger.dev/sdk/v3/extensions";
|
||||
import {
|
||||
emitDecoratorMetadata,
|
||||
audioWaveform,
|
||||
prismaExtension,
|
||||
} from "@trigger.dev/sdk/v3/extensions";
|
||||
import { InfisicalClient } from "@infisical/sdk";
|
||||
|
||||
export const resolveEnvVars: ResolveEnvironmentVariablesFunction = async (ctx) => {
|
||||
@@ -55,7 +59,15 @@ export default defineConfig({
|
||||
console.log(`Task ${ctx.task.id} failed ${ctx.run.id}`);
|
||||
},
|
||||
build: {
|
||||
extensions: [emitDecoratorMetadata()],
|
||||
extensions: [
|
||||
emitDecoratorMetadata(),
|
||||
audioWaveform(),
|
||||
prismaExtension({
|
||||
schema: "prisma/schema/schema.prisma",
|
||||
migrate: true,
|
||||
directUrlEnvVarName: "DATABASE_URL_UNPOOLED",
|
||||
}),
|
||||
],
|
||||
external: ["@ffmpeg-installer/ffmpeg", "re2"],
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user