trigger.dev 3.0.0-beta.14 → 3.0.0-beta.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- FROM node:20-bookworm-slim@sha256:d4cdfc305abe5ea78da7167bf78263c22596dc332f2654b662890777ea166224 AS base
1
+ FROM node:21-bookworm-slim@sha256:fb82287cf66ca32d854c05f54251fca8b572149163f154248df7e800003c90b5 AS base
2
2
 
3
3
  ENV DEBIAN_FRONTEND=noninteractive
4
4
  RUN apt-get update && apt-get install -y --no-install-recommends \
package/dist/index.js CHANGED
@@ -795,12 +795,12 @@ import { readFileSync as readFileSync2 } from "node:fs";
795
795
  import { copyFile, mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
796
796
  import { dirname, join as join5, relative as relative3, posix } from "node:path";
797
797
  import { setTimeout as setTimeout2 } from "node:timers/promises";
798
- import terminalLink from "terminal-link";
798
+ import terminalLink2 from "terminal-link";
799
799
  import invariant from "tiny-invariant";
800
800
  import { z as z4 } from "zod";
801
801
 
802
802
  // package.json
803
- var version = "3.0.0-beta.14";
803
+ var version = "3.0.0-beta.16";
804
804
  var dependencies = {
805
805
  "@clack/prompts": "^0.7.0",
806
806
  "@depot/cli": "0.0.1-cli.2.55.0",
@@ -816,7 +816,7 @@ var dependencies = {
816
816
  "@opentelemetry/sdk-trace-base": "^1.22.0",
817
817
  "@opentelemetry/sdk-trace-node": "^1.22.0",
818
818
  "@opentelemetry/semantic-conventions": "^1.22.0",
819
- "@trigger.dev/core": "workspace:^3.0.0-beta.14",
819
+ "@trigger.dev/core": "workspace:^3.0.0-beta.16",
820
820
  "@types/degit": "^2.8.3",
821
821
  chalk: "^5.2.0",
822
822
  chokidar: "^3.5.3",
@@ -2954,6 +2954,20 @@ function getLoaderForFile(file) {
2954
2954
  import chalk4 from "chalk";
2955
2955
  import { relative as relative2 } from "node:path";
2956
2956
  import { groupTaskMetadataIssuesByTask } from "@trigger.dev/core/v3";
2957
+ import terminalLink from "terminal-link";
2958
+
2959
+ // src/utilities/links.ts
2960
+ var docs = {
2961
+ config: {
2962
+ home: "https://trigger.dev/docs/v3/trigger-config",
2963
+ esm: "https://trigger.dev/docs/v3/trigger-config#esm-only-packages",
2964
+ prisma: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators",
2965
+ additionalPackages: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators"
2966
+ }
2967
+ };
2968
+ var getInTouch = "https://trigger.dev/contact";
2969
+
2970
+ // src/utilities/deployErrors.ts
2957
2971
  function errorIsErrorLike(error) {
2958
2972
  return error instanceof Error || typeof error === "object" && error !== null && "message" in error;
2959
2973
  }
@@ -3019,6 +3033,10 @@ ${chalkGrey("\u25CB")} Dynamically import the module in your code: ${chalkGrey(
3019
3033
  `
3020
3034
  );
3021
3035
  }
3036
+ logger.log(
3037
+ `${chalkGrey("\u25CB")} For more info see the ${terminalLink("relevant docs", docs.config.esm)}.
3038
+ `
3039
+ );
3022
3040
  }
3023
3041
  function parseNpmInstallError(error) {
3024
3042
  if (typeof error === "string") {
@@ -3313,7 +3331,8 @@ var DeployCommandOptions = CommonCommandOptions.extend({
3313
3331
  config: z4.string().optional(),
3314
3332
  projectRef: z4.string().optional(),
3315
3333
  outputMetafile: z4.string().optional(),
3316
- apiUrl: z4.string().optional()
3334
+ apiUrl: z4.string().optional(),
3335
+ saveLogs: z4.boolean().default(false)
3317
3336
  });
3318
3337
  function configureDeployCommand(program2) {
3319
3338
  return commonOptions(
@@ -3360,6 +3379,11 @@ function configureDeployCommand(program2) {
3360
3379
  "--output-metafile <path>",
3361
3380
  "If provided, will save the esbuild metafile for the build to the specified path"
3362
3381
  ).hideHelp()
3382
+ ).addOption(
3383
+ new CommandOption(
3384
+ "--save-logs",
3385
+ "If provided, will save logs even for successful builds"
3386
+ ).hideHelp()
3363
3387
  ).action(async (path7, options) => {
3364
3388
  await handleTelemetry(async () => {
3365
3389
  await printStandloneInitialBanner(true);
@@ -3494,19 +3518,35 @@ async function _deployCommand(dir, options) {
3494
3518
  );
3495
3519
  };
3496
3520
  const image = await buildImage();
3521
+ const warnings = checkLogsForWarnings(image.logs);
3522
+ if (!warnings.ok) {
3523
+ await failDeploy(
3524
+ deploymentResponse.data.shortCode,
3525
+ warnings.summary,
3526
+ image.logs,
3527
+ deploymentSpinner,
3528
+ warnings.warnings,
3529
+ warnings.errors
3530
+ );
3531
+ throw new SkipLoggingError(`Failed to build project image: ${warnings.summary}`);
3532
+ }
3497
3533
  if (!image.ok) {
3498
- deploymentSpinner.stop(`Failed to build project.`);
3499
- if (image.logs.trim() !== "") {
3500
- const logPath = join5(await createTempDir(), `build-${deploymentResponse.data.shortCode}.log`);
3501
- await writeFile2(logPath, image.logs);
3502
- logger.log(
3503
- `${chalkError("X Error:")} ${image.error}. Full build logs have been saved to ${logPath})`
3504
- );
3505
- } else {
3506
- logger.log(`${chalkError("X Error:")} ${image.error}.`);
3507
- }
3534
+ await failDeploy(
3535
+ deploymentResponse.data.shortCode,
3536
+ image.error,
3537
+ image.logs,
3538
+ deploymentSpinner,
3539
+ warnings.warnings
3540
+ );
3508
3541
  throw new SkipLoggingError(`Failed to build project image: ${image.error}`);
3509
3542
  }
3543
+ const preExitTasks = async () => {
3544
+ printWarnings(warnings.warnings);
3545
+ if (options.saveLogs) {
3546
+ const logPath = await saveLogs(deploymentResponse.data.shortCode, image.logs);
3547
+ log3.info(`Build logs have been saved to ${logPath}`);
3548
+ }
3549
+ };
3510
3550
  const imageReference = options.selfHosted ? `${selfHostedRegistryHost ? `${selfHostedRegistryHost}/` : ""}${image.image}${image.digest ? `@${image.digest}` : ""}` : `${registryHost}/${image.image}${image.digest ? `@${image.digest}` : ""}`;
3511
3551
  span?.setAttributes({
3512
3552
  "image.reference": imageReference
@@ -3515,6 +3555,7 @@ async function _deployCommand(dir, options) {
3515
3555
  deploymentSpinner.stop(
3516
3556
  `Project image built: ${imageReference}. Skipping deployment as requested`
3517
3557
  );
3558
+ await preExitTasks();
3518
3559
  throw new SkipCommandError("Skipping deployment as requested");
3519
3560
  }
3520
3561
  deploymentSpinner.message(
@@ -3529,6 +3570,7 @@ async function _deployCommand(dir, options) {
3529
3570
  );
3530
3571
  if (!startIndexingResponse.success) {
3531
3572
  deploymentSpinner.stop(`Failed to start indexing: ${startIndexingResponse.error}`);
3573
+ await preExitTasks();
3532
3574
  throw new SkipLoggingError(`Failed to start indexing: ${startIndexingResponse.error}`);
3533
3575
  }
3534
3576
  const finishedDeployment = await waitForDeploymentToFinish(
@@ -3537,19 +3579,26 @@ async function _deployCommand(dir, options) {
3537
3579
  );
3538
3580
  if (!finishedDeployment) {
3539
3581
  deploymentSpinner.stop(`Deployment failed to complete`);
3582
+ await preExitTasks();
3540
3583
  throw new SkipLoggingError("Deployment failed to complete: unknown issue");
3541
3584
  }
3542
3585
  if (typeof finishedDeployment === "string") {
3543
3586
  deploymentSpinner.stop(`Deployment failed to complete: ${finishedDeployment}`);
3587
+ await preExitTasks();
3544
3588
  throw new SkipLoggingError(`Deployment failed to complete: ${finishedDeployment}`);
3545
3589
  }
3546
- const deploymentLink = terminalLink(
3590
+ const deploymentLink = terminalLink2(
3547
3591
  "View deployment",
3548
3592
  `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.config.project}/deployments/${finishedDeployment.shortCode}`
3549
3593
  );
3550
3594
  switch (finishedDeployment.status) {
3551
3595
  case "DEPLOYED": {
3552
- deploymentSpinner.stop("Deployment completed");
3596
+ if (warnings.warnings.length > 0) {
3597
+ deploymentSpinner.stop("Deployment completed with warnings");
3598
+ } else {
3599
+ deploymentSpinner.stop("Deployment completed");
3600
+ }
3601
+ await preExitTasks();
3553
3602
  const taskCount = finishedDeployment.worker?.tasks.length ?? 0;
3554
3603
  if (taskCount === 0) {
3555
3604
  outro3(
@@ -3571,6 +3620,7 @@ async function _deployCommand(dir, options) {
3571
3620
  if (parsedError2.success) {
3572
3621
  deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
3573
3622
  logTaskMetadataParseError(parsedError2.data.zodIssues, parsedError2.data.tasks);
3623
+ await preExitTasks();
3574
3624
  throw new SkipLoggingError(
3575
3625
  `Deployment encountered an error: ${finishedDeployment.errorData.name}`
3576
3626
  );
@@ -3585,6 +3635,7 @@ async function _deployCommand(dir, options) {
3585
3635
  deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
3586
3636
  logESMRequireError(parsedError, resolvedConfig);
3587
3637
  }
3638
+ await preExitTasks();
3588
3639
  throw new SkipLoggingError(
3589
3640
  `Deployment encountered an error: ${finishedDeployment.errorData.name}`
3590
3641
  );
@@ -3592,19 +3643,133 @@ async function _deployCommand(dir, options) {
3592
3643
  deploymentSpinner.stop(
3593
3644
  `Deployment failed with an unknown error. Please contact eric@trigger.dev for help. ${deploymentLink}`
3594
3645
  );
3646
+ await preExitTasks();
3595
3647
  throw new SkipLoggingError("Deployment failed with an unknown error");
3596
3648
  }
3597
3649
  }
3598
3650
  case "CANCELED": {
3599
3651
  deploymentSpinner.stop(`Deployment was canceled. ${deploymentLink}`);
3652
+ await preExitTasks();
3600
3653
  throw new SkipLoggingError("Deployment was canceled");
3601
3654
  }
3602
3655
  case "TIMED_OUT": {
3603
3656
  deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
3657
+ await preExitTasks();
3604
3658
  throw new SkipLoggingError("Deployment timed out");
3605
3659
  }
3606
3660
  }
3607
3661
  }
3662
+ function printErrors(errors) {
3663
+ for (const error of errors ?? []) {
3664
+ log3.error(`${chalkError("Error:")} ${error}`);
3665
+ }
3666
+ }
3667
+ function printWarnings(warnings) {
3668
+ for (const warning of warnings ?? []) {
3669
+ log3.warn(`${chalkWarning("Warning:")} ${warning}`);
3670
+ }
3671
+ }
3672
+ function checkLogsForWarnings(logs) {
3673
+ const warnings = [
3674
+ {
3675
+ regex: /prisma:warn We could not find your Prisma schema/,
3676
+ message: `Prisma generate failed to find the default schema. Did you include it in config.additionalFiles? ${terminalLink2(
3677
+ "Config docs",
3678
+ docs.config.prisma
3679
+ )}
3680
+ Custom schema paths require a postinstall script like this: \`prisma generate --schema=./custom/path/to/schema.prisma\``,
3681
+ shouldFail: true
3682
+ }
3683
+ ];
3684
+ const errorMessages2 = [];
3685
+ const warningMessages = [];
3686
+ let shouldFail = false;
3687
+ for (const warning of warnings) {
3688
+ const matches = logs.match(warning.regex);
3689
+ if (!matches) {
3690
+ continue;
3691
+ }
3692
+ const message = getMessageFromTemplate(warning.message, matches.groups);
3693
+ if (warning.shouldFail) {
3694
+ shouldFail = true;
3695
+ errorMessages2.push(message);
3696
+ } else {
3697
+ warningMessages.push(message);
3698
+ }
3699
+ }
3700
+ if (shouldFail) {
3701
+ return {
3702
+ ok: false,
3703
+ summary: "Build succeeded with critical warnings. Will not proceed",
3704
+ warnings: warningMessages,
3705
+ errors: errorMessages2
3706
+ };
3707
+ }
3708
+ return {
3709
+ ok: true,
3710
+ warnings: warningMessages
3711
+ };
3712
+ }
3713
+ function checkLogsForErrors(logs) {
3714
+ const errors = [
3715
+ {
3716
+ regex: /Error: Provided --schema at (?<schema>.*) doesn't exist/,
3717
+ message: `Prisma generate failed to find the specified schema at "$schema".
3718
+ Did you include it in config.additionalFiles? ${terminalLink2(
3719
+ "Config docs",
3720
+ docs.config.prisma
3721
+ )}`
3722
+ },
3723
+ {
3724
+ regex: /sh: 1: (?<packageOrBinary>.*): not found/,
3725
+ message: `$packageOrBinary not found
3726
+
3727
+ If it's a package: Include it in ${terminalLink2(
3728
+ "config.additionalPackages",
3729
+ docs.config.prisma
3730
+ )}
3731
+ If it's a binary: Please ${terminalLink2(
3732
+ "get in touch",
3733
+ getInTouch
3734
+ )} and we'll see what we can do!`
3735
+ }
3736
+ ];
3737
+ for (const error of errors) {
3738
+ const matches = logs.match(error.regex);
3739
+ if (!matches) {
3740
+ continue;
3741
+ }
3742
+ const message = getMessageFromTemplate(error.message, matches.groups);
3743
+ log3.error(`${chalkError("Error:")} ${message}`);
3744
+ break;
3745
+ }
3746
+ }
3747
+ function getMessageFromTemplate(template, replacer) {
3748
+ let message = template;
3749
+ if (replacer) {
3750
+ for (const [key, value] of Object.entries(replacer)) {
3751
+ message = message.replaceAll(`$${key}`, value);
3752
+ }
3753
+ }
3754
+ return message;
3755
+ }
3756
+ async function saveLogs(shortCode, logs) {
3757
+ const logPath = join5(await createTempDir(), `build-${shortCode}.log`);
3758
+ await writeFile2(logPath, logs);
3759
+ return logPath;
3760
+ }
3761
+ async function failDeploy(shortCode, errorSummary, logs, deploymentSpinner, warnings, errors) {
3762
+ deploymentSpinner.stop(`Failed to deploy project`);
3763
+ if (logs.trim() !== "") {
3764
+ const logPath = await saveLogs(shortCode, logs);
3765
+ printWarnings(warnings);
3766
+ printErrors(errors);
3767
+ checkLogsForErrors(logs);
3768
+ outro3(`${chalkError("Error:")} ${errorSummary}. Full build logs have been saved to ${logPath}`);
3769
+ } else {
3770
+ outro3(`${chalkError("Error:")} ${errorSummary}.`);
3771
+ }
3772
+ }
3608
3773
  async function checkEnvVars(envVars, config, options, environmentClient, apiUrl) {
3609
3774
  return await tracer.startActiveSpan("detectEnvVars", async (span) => {
3610
3775
  try {
@@ -3623,7 +3788,7 @@ async function checkEnvVars(envVars, config, options, environmentClient, apiUrl)
3623
3788
  `Found missing env vars in ${options.env}: ${arrayToSentence(
3624
3789
  missingEnvironmentVariables
3625
3790
  )}. ${options.ignoreEnvVarCheck ? "Continuing deployment because of --ignore-env-var-check. " : "Aborting deployment. "}${chalk5.bgBlueBright(
3626
- terminalLink(
3791
+ terminalLink2(
3627
3792
  "Manage env vars",
3628
3793
  `${apiUrl}/projects/v3/${config.project}/environment-variables`
3629
3794
  )
@@ -3926,7 +4091,7 @@ async function compileProject(config, options, configPath) {
3926
4091
  join5(cliRootPath(), "workers", "prod", "worker-facade.js"),
3927
4092
  "utf-8"
3928
4093
  );
3929
- const workerSetupPath = join5(cliRootPath(), "workers", "dev", "worker-setup.js");
4094
+ const workerSetupPath = join5(cliRootPath(), "workers", "prod", "worker-setup.js");
3930
4095
  let workerContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
3931
4096
  "__WORKER_SETUP__",
3932
4097
  `import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
@@ -4078,8 +4243,22 @@ async function compileProject(config, options, configPath) {
4078
4243
  }
4079
4244
  };
4080
4245
  await writeJSONFile(join5(tempDir, "package.json"), packageJsonContents);
4081
- await copyAdditionalFiles(config, tempDir);
4082
- compileSpinner.stop("Project built successfully");
4246
+ const copyResult = await copyAdditionalFiles(config, tempDir);
4247
+ if (!copyResult.ok) {
4248
+ compileSpinner.stop("Project built with warnings");
4249
+ log3.warn(
4250
+ `No additionalFiles matches for:
4251
+
4252
+ ${copyResult.noMatches.map((glob) => `- "${glob}"`).join("\n")}
4253
+
4254
+ If this is unexpected you should check your ${terminalLink2(
4255
+ "glob patterns",
4256
+ "https://github.com/isaacs/node-glob?tab=readme-ov-file#glob-primer"
4257
+ )} are valid.`
4258
+ );
4259
+ } else {
4260
+ compileSpinner.stop("Project built successfully");
4261
+ }
4083
4262
  const resolvingDependenciesResult = await resolveDependencies(
4084
4263
  tempDir,
4085
4264
  packageJsonContents,
@@ -4286,8 +4465,9 @@ async function gatherRequiredDependencies(imports, config, project) {
4286
4465
  }
4287
4466
  async function copyAdditionalFiles(config, tempDir) {
4288
4467
  const additionalFiles = config.additionalFiles ?? [];
4468
+ const noMatches = [];
4289
4469
  if (additionalFiles.length === 0) {
4290
- return;
4470
+ return { ok: true };
4291
4471
  }
4292
4472
  return await tracer.startActiveSpan(
4293
4473
  "copyAdditionalFiles",
@@ -4301,22 +4481,55 @@ async function copyAdditionalFiles(config, tempDir) {
4301
4481
  logger.debug(`Copying files to ${tempDir}`, {
4302
4482
  additionalFiles
4303
4483
  });
4304
- const glob = new Glob(additionalFiles, {
4484
+ const globOptions = {
4305
4485
  withFileTypes: true,
4306
4486
  ignore: ["node_modules"],
4307
4487
  cwd: config.projectDir,
4308
4488
  nodir: true
4309
- });
4310
- for await (const file of glob) {
4311
- const relativeDestinationPath = join5(
4312
- tempDir,
4313
- relative3(config.projectDir, file.fullpath())
4314
- );
4315
- logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
4316
- await mkdir(dirname(relativeDestinationPath), { recursive: true });
4317
- await copyFile(file.fullpath(), relativeDestinationPath);
4489
+ };
4490
+ const globs = [];
4491
+ let i = 0;
4492
+ for (const additionalFile of additionalFiles) {
4493
+ let glob;
4494
+ if (i === 0) {
4495
+ glob = new Glob(additionalFile, globOptions);
4496
+ } else {
4497
+ const previousGlob = globs[i - 1];
4498
+ if (!previousGlob) {
4499
+ logger.error("No previous glob, this shouldn't happen", { i, additionalFiles });
4500
+ continue;
4501
+ }
4502
+ glob = new Glob(additionalFile, previousGlob);
4503
+ }
4504
+ if (!(Symbol.asyncIterator in glob)) {
4505
+ logger.error("Glob should be an async iterator", { glob });
4506
+ throw new Error("Unrecoverable error while copying additional files");
4507
+ }
4508
+ let matches = 0;
4509
+ for await (const file of glob) {
4510
+ matches++;
4511
+ const pathInsideTempDir = relative3(config.projectDir, file.fullpath()).split(posix.sep).filter((p) => p !== "..").join(posix.sep);
4512
+ const relativeDestinationPath = join5(tempDir, pathInsideTempDir);
4513
+ logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
4514
+ await mkdir(dirname(relativeDestinationPath), { recursive: true });
4515
+ await copyFile(file.fullpath(), relativeDestinationPath);
4516
+ }
4517
+ if (matches === 0) {
4518
+ noMatches.push(additionalFile);
4519
+ }
4520
+ globs[i] = glob;
4521
+ i++;
4318
4522
  }
4319
4523
  span.end();
4524
+ if (noMatches.length > 0) {
4525
+ return {
4526
+ ok: false,
4527
+ noMatches
4528
+ };
4529
+ }
4530
+ return {
4531
+ ok: true
4532
+ };
4320
4533
  } catch (error) {
4321
4534
  recordSpanException4(span, error);
4322
4535
  span.end();
@@ -4413,7 +4626,7 @@ import dotenv from "dotenv";
4413
4626
  import { Evt } from "evt";
4414
4627
  import { fork } from "node:child_process";
4415
4628
  import { dirname as dirname2, resolve as resolve2 } from "node:path";
4416
- import terminalLink2 from "terminal-link";
4629
+ import terminalLink3 from "terminal-link";
4417
4630
  var BackgroundWorkerCoordinator = class {
4418
4631
  constructor(baseURL) {
4419
4632
  this.baseURL = baseURL;
@@ -4498,7 +4711,7 @@ var BackgroundWorkerCoordinator = class {
4498
4711
  const logsUrl = `${this.baseURL}/runs/${execution.run.id}`;
4499
4712
  const pipe = chalkGrey("|");
4500
4713
  const bullet = chalkGrey("\u25CB");
4501
- const link = chalkLink(terminalLink2("View logs", logsUrl));
4714
+ const link = chalkLink(terminalLink3("View logs", logsUrl));
4502
4715
  let timestampPrefix = chalkGrey(prettyPrintDate(payload.execution.attempt.startedAt));
4503
4716
  const workerPrefix = chalkWorker(record.version);
4504
4717
  const taskPrefix = chalkTask(execution.task.id);
@@ -4865,6 +5078,12 @@ var TaskRunProcess = class {
4865
5078
  kill
4866
5079
  });
4867
5080
  this._isBeingKilled = kill;
5081
+ setTimeout(() => {
5082
+ if (this._child && !this._child.killed) {
5083
+ logger.debug(`[${this.execution.run.id}] killing task run process after timeout`);
5084
+ this._child.kill();
5085
+ }
5086
+ }, 5e3);
4868
5087
  }
4869
5088
  async executeTaskRun(payload) {
4870
5089
  let resolver;
@@ -4921,6 +5140,7 @@ var TaskRunProcess = class {
4921
5140
  break;
4922
5141
  }
4923
5142
  case "READY_TO_DISPOSE": {
5143
+ logger.debug(`[${this.execution.run.id}] task run process is ready to dispose`);
4924
5144
  this.#kill();
4925
5145
  break;
4926
5146
  }
@@ -4983,6 +5203,7 @@ var TaskRunProcess = class {
4983
5203
  }
4984
5204
  #kill() {
4985
5205
  if (this._child && !this._child.killed) {
5206
+ logger.debug(`[${this.execution.run.id}] killing task run process`);
4986
5207
  this._child?.kill();
4987
5208
  }
4988
5209
  }
@@ -5620,7 +5841,7 @@ import { execa as execa3 } from "execa";
5620
5841
  import { applyEdits, modify } from "jsonc-parser";
5621
5842
  import { writeFile as writeFile3 } from "node:fs/promises";
5622
5843
  import { join as join7, relative as relative4, resolve as resolve3 } from "node:path";
5623
- import terminalLink3 from "terminal-link";
5844
+ import terminalLink4 from "terminal-link";
5624
5845
  import { z as z6 } from "zod";
5625
5846
 
5626
5847
  // src/utilities/createFileFromTemplate.ts
@@ -5746,7 +5967,7 @@ async function _initCommand(dir, options) {
5746
5967
  await writeConfigFile(dir, selectedProject, options, triggerDir);
5747
5968
  await addConfigFileToTsConfig(dir, options);
5748
5969
  await gitIgnoreDotTriggerDir(dir, options);
5749
- const projectDashboard = terminalLink3(
5970
+ const projectDashboard = terminalLink4(
5750
5971
  "project dashboard",
5751
5972
  `${authorization.dashboardUrl}/projects/v3/${selectedProject.externalRef}`
5752
5973
  );
@@ -5759,13 +5980,13 @@ async function _initCommand(dir, options) {
5759
5980
  );
5760
5981
  log4.info(` 2. Visit your ${projectDashboard} to view your newly created tasks.`);
5761
5982
  log4.info(
5762
- ` 3. Head over to our ${terminalLink3(
5983
+ ` 3. Head over to our ${terminalLink4(
5763
5984
  "v3 docs",
5764
5985
  "https://trigger.dev/docs/v3"
5765
5986
  )} to learn more.`
5766
5987
  );
5767
5988
  log4.info(
5768
- ` 4. Need help? Join our ${terminalLink3(
5989
+ ` 4. Need help? Join our ${terminalLink4(
5769
5990
  "Discord community",
5770
5991
  "https://trigger.dev/discord"
5771
5992
  )} or email us at ${chalk6.cyan("help@trigger.dev")}`
@@ -6017,7 +6238,7 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
6017
6238
  throw new Error(`Failed to get projects: ${projectsResponse.error}`);
6018
6239
  }
6019
6240
  if (projectsResponse.data.length === 0) {
6020
- const newProjectLink = terminalLink3(
6241
+ const newProjectLink = terminalLink4(
6021
6242
  "Create new project",
6022
6243
  `${dashboardUrl}/projects/new?version=v3`
6023
6244
  );