trigger.dev
Version:
A Command-Line Interface for Trigger.dev projects
162 lines • 7.23 kB
JavaScript
import { bundleWorker, createBuildManifestFromBundle } from "./bundle.js";
import { createBuildContext, notifyExtensionOnBuildComplete, notifyExtensionOnBuildStart, resolvePluginsForContext, } from "./extensions.js";
import { createExternalsBuildExtension } from "./externals.js";
import { join, relative, sep } from "node:path";
import { generateContainerfile } from "../deploy/buildImage.js";
import { writeFile } from "node:fs/promises";
import { buildManifestToJSON } from "../utilities/buildManifest.js";
import { readPackageJSON } from "pkg-types";
import { writeJSONFile } from "../utilities/fileSystem.js";
import { isWindows } from "std-env";
import { pathToFileURL } from "node:url";
import { logger } from "../utilities/logger.js";
import { SdkVersionExtractor } from "./plugins.js";
import { spinner } from "../utilities/windows.js";
export async function buildWorker(options) {
logger.debug("Starting buildWorker", {
options,
});
const resolvedConfig = options.resolvedConfig;
const externalsExtension = createExternalsBuildExtension(options.target, resolvedConfig, options.forcedExternals);
const buildContext = createBuildContext(options.target, resolvedConfig, {
logger: options.plain
? {
debug: (...args) => console.log(...args),
log: (...args) => console.log(...args),
warn: (...args) => console.log(...args),
progress: (message) => console.log(message),
spinner: (message) => {
const $spinner = spinner({ plain: true });
$spinner.start(message);
return $spinner;
},
}
: undefined,
});
buildContext.prependExtension(externalsExtension);
await notifyExtensionOnBuildStart(buildContext);
const pluginsFromExtensions = resolvePluginsForContext(buildContext);
const sdkVersionExtractor = new SdkVersionExtractor();
options.listener?.onBundleStart?.();
const bundleResult = await bundleWorker({
target: options.target,
cwd: resolvedConfig.workingDir,
destination: options.destination,
watch: false,
resolvedConfig,
plugins: [sdkVersionExtractor.plugin, ...pluginsFromExtensions],
jsxFactory: resolvedConfig.build.jsx.factory,
jsxFragment: resolvedConfig.build.jsx.fragment,
jsxAutomatic: resolvedConfig.build.jsx.automatic,
});
options.listener?.onBundleComplete?.(bundleResult);
let buildManifest = await createBuildManifestFromBundle({
bundle: bundleResult,
destination: options.destination,
resolvedConfig,
environment: options.environment,
branch: options.branch,
target: options.target,
envVars: options.envVars,
});
buildManifest = await notifyExtensionOnBuildComplete(buildContext, buildManifest);
if (options.target !== "dev") {
buildManifest = options.rewritePaths
? rewriteBuildManifestPaths(buildManifest, options.destination)
: buildManifest;
await writeDeployFiles({
buildManifest,
resolvedConfig,
outputPath: options.destination,
bundleResult,
});
}
return buildManifest;
}
export function rewriteBuildManifestPaths(buildManifest, destinationDir) {
return {
...buildManifest,
files: buildManifest.files.map((file) => ({
...file,
entry: cleanEntryPath(file.entry),
out: rewriteOutputPath(destinationDir, file.out),
})),
outputPath: rewriteOutputPath(destinationDir, buildManifest.outputPath),
configPath: rewriteOutputPath(destinationDir, buildManifest.configPath),
runControllerEntryPoint: buildManifest.runControllerEntryPoint
? rewriteOutputPath(destinationDir, buildManifest.runControllerEntryPoint)
: undefined,
runWorkerEntryPoint: rewriteOutputPath(destinationDir, buildManifest.runWorkerEntryPoint),
indexControllerEntryPoint: buildManifest.indexControllerEntryPoint
? rewriteOutputPath(destinationDir, buildManifest.indexControllerEntryPoint)
: undefined,
indexWorkerEntryPoint: rewriteOutputPath(destinationDir, buildManifest.indexWorkerEntryPoint),
loaderEntryPoint: buildManifest.loaderEntryPoint
? rewriteOutputPath(destinationDir, buildManifest.loaderEntryPoint)
: undefined,
initEntryPoint: buildManifest.initEntryPoint
? rewriteOutputPath(destinationDir, buildManifest.initEntryPoint)
: undefined,
};
}
// Remove any query parameters from the entry path
// For example, src/trigger/ai.ts?sentryProxyModule=true -> src/trigger/ai.ts
function cleanEntryPath(entry) {
return entry.split("?")[0];
}
function rewriteOutputPath(destinationDir, filePath) {
if (isWindows) {
return `/app/${relative(pathToFileURL(destinationDir).pathname, pathToFileURL(filePath).pathname)
.split(sep)
.join("/")}`;
}
else {
return `/app/${relative(destinationDir, filePath)}`;
}
}
async function writeDeployFiles({ buildManifest, resolvedConfig, outputPath, bundleResult, }) {
// Step 1. Read the package.json file
const packageJson = await readProjectPackageJson(resolvedConfig.packageJsonPath);
if (!packageJson) {
throw new Error("Could not read the package.json file");
}
const dependencies = buildManifest.externals?.reduce((acc, external) => {
acc[external.name] = external.version;
return acc;
}, {}) ?? {};
// Step 3: Write the resolved dependencies to the package.json file
await writeJSONFile(join(outputPath, "package.json"), {
...packageJson,
name: packageJson.name ?? "trigger-project",
dependencies: {
...dependencies,
},
trustedDependencies: Object.keys(dependencies).sort(),
devDependencies: {},
peerDependencies: {},
scripts: {},
}, true);
await writeJSONFile(join(outputPath, "build.json"), buildManifestToJSON(buildManifest));
await writeContainerfile(outputPath, buildManifest);
}
async function readProjectPackageJson(packageJsonPath) {
const packageJson = await readPackageJSON(packageJsonPath);
return packageJson;
}
async function writeContainerfile(outputPath, buildManifest) {
if (!buildManifest.runControllerEntryPoint || !buildManifest.indexControllerEntryPoint) {
throw new Error("Something went wrong with the build. Aborting deployment. [code 7789]");
}
const containerfile = await generateContainerfile({
runtime: buildManifest.runtime,
entrypoint: buildManifest.runControllerEntryPoint,
build: buildManifest.build,
image: buildManifest.image,
indexScript: buildManifest.indexControllerEntryPoint,
});
const containerfilePath = join(outputPath, "Containerfile");
logger.debug("Writing Containerfile", { containerfilePath });
logger.debug(containerfile);
await writeFile(containerfilePath, containerfile);
}
//# sourceMappingURL=buildWorker.js.map