trigger.dev 3.0.0-beta.1 → 3.0.0-beta.11
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.
- package/dist/Containerfile.prod +11 -2
- package/dist/index.js +913 -310
- package/dist/index.js.map +1 -1
- package/dist/templates/trigger.config.ts.template +2 -1
- package/dist/workers/dev/worker-facade.js +20 -8
- package/dist/workers/prod/entry-point.js +79 -53
- package/dist/workers/prod/worker-facade.js +23 -9
- package/package.json +5 -8
package/dist/index.js
CHANGED
|
@@ -781,11 +781,12 @@ import { intro as intro3, log as log2, outro as outro3, spinner as spinner4 } fr
|
|
|
781
781
|
import { depot } from "@depot/cli";
|
|
782
782
|
import { context, trace as trace2 } from "@opentelemetry/api";
|
|
783
783
|
import {
|
|
784
|
+
TaskMetadataFailedToParseData,
|
|
784
785
|
detectDependencyVersion,
|
|
785
786
|
flattenAttributes as flattenAttributes2,
|
|
786
787
|
recordSpanException as recordSpanException4
|
|
787
788
|
} from "@trigger.dev/core/v3";
|
|
788
|
-
import
|
|
789
|
+
import chalk5 from "chalk";
|
|
789
790
|
import { Option as CommandOption } from "commander";
|
|
790
791
|
import { build as build2 } from "esbuild";
|
|
791
792
|
import { execa as execa2 } from "execa";
|
|
@@ -793,14 +794,14 @@ import { resolve as importResolve } from "import-meta-resolve";
|
|
|
793
794
|
import { createHash } from "node:crypto";
|
|
794
795
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
795
796
|
import { copyFile, mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
796
|
-
import { dirname, join as
|
|
797
|
+
import { dirname, join as join5, relative as relative3 } from "node:path";
|
|
797
798
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
798
799
|
import terminalLink from "terminal-link";
|
|
799
800
|
import invariant from "tiny-invariant";
|
|
800
801
|
import { z as z4 } from "zod";
|
|
801
802
|
|
|
802
803
|
// package.json
|
|
803
|
-
var version = "3.0.0-beta.
|
|
804
|
+
var version = "3.0.0-beta.11";
|
|
804
805
|
var dependencies = {
|
|
805
806
|
"@clack/prompts": "^0.7.0",
|
|
806
807
|
"@depot/cli": "0.0.1-cli.2.55.0",
|
|
@@ -816,7 +817,7 @@ var dependencies = {
|
|
|
816
817
|
"@opentelemetry/sdk-trace-base": "^1.22.0",
|
|
817
818
|
"@opentelemetry/sdk-trace-node": "^1.22.0",
|
|
818
819
|
"@opentelemetry/semantic-conventions": "^1.22.0",
|
|
819
|
-
"@trigger.dev/core": "workspace:^3.0.0-beta.
|
|
820
|
+
"@trigger.dev/core": "workspace:^3.0.0-beta.11",
|
|
820
821
|
"@types/degit": "^2.8.3",
|
|
821
822
|
chalk: "^5.2.0",
|
|
822
823
|
chokidar: "^3.5.3",
|
|
@@ -833,7 +834,6 @@ var dependencies = {
|
|
|
833
834
|
"import-meta-resolve": "^4.0.0",
|
|
834
835
|
ink: "^4.4.1",
|
|
835
836
|
"jsonc-parser": "^3.2.1",
|
|
836
|
-
jsonlines: "^0.1.1",
|
|
837
837
|
liquidjs: "^10.9.2",
|
|
838
838
|
"mock-fs": "^5.2.0",
|
|
839
839
|
nanoid: "^4.0.2",
|
|
@@ -850,7 +850,6 @@ var dependencies = {
|
|
|
850
850
|
"simple-git": "^3.19.0",
|
|
851
851
|
"socket.io-client": "^4.7.4",
|
|
852
852
|
"source-map-support": "^0.5.21",
|
|
853
|
-
"supports-color": "^9.4.0",
|
|
854
853
|
"terminal-link": "^3.0.0",
|
|
855
854
|
"tiny-invariant": "^1.2.0",
|
|
856
855
|
"tsconfig-paths": "^4.2.0",
|
|
@@ -894,13 +893,12 @@ var package_default = {
|
|
|
894
893
|
type: "module",
|
|
895
894
|
exports: "./dist/index.js",
|
|
896
895
|
bin: {
|
|
897
|
-
|
|
896
|
+
triggerdev: "./dist/index.js"
|
|
898
897
|
},
|
|
899
898
|
devDependencies: {
|
|
900
899
|
"@trigger.dev/core-apps": "workspace:*",
|
|
901
900
|
"@trigger.dev/tsconfig": "workspace:*",
|
|
902
901
|
"@types/gradient-string": "^1.1.2",
|
|
903
|
-
"@types/jsonlines": "^0.1.5",
|
|
904
902
|
"@types/mock-fs": "^4.13.1",
|
|
905
903
|
"@types/node": "18",
|
|
906
904
|
"@types/object-hash": "^3.0.6",
|
|
@@ -1307,7 +1305,7 @@ var Logger = class {
|
|
|
1307
1305
|
const kind = LOGGER_LEVEL_FORMAT_TYPE_MAP[level];
|
|
1308
1306
|
if (kind) {
|
|
1309
1307
|
const [firstLine, ...otherLines] = message.split("\n");
|
|
1310
|
-
const notes = otherLines.length > 0 ? otherLines.map((
|
|
1308
|
+
const notes = otherLines.length > 0 ? otherLines.map((text3) => ({ text: text3 })) : void 0;
|
|
1311
1309
|
return formatMessagesSync([{ text: firstLine, notes }], {
|
|
1312
1310
|
color: true,
|
|
1313
1311
|
kind,
|
|
@@ -1322,6 +1320,58 @@ var logger = new Logger();
|
|
|
1322
1320
|
|
|
1323
1321
|
// src/cli/common.ts
|
|
1324
1322
|
import { outro } from "@clack/prompts";
|
|
1323
|
+
|
|
1324
|
+
// src/utilities/cliOutput.ts
|
|
1325
|
+
import chalk2 from "chalk";
|
|
1326
|
+
var green = "#4FFF54";
|
|
1327
|
+
var purple = "#735BF3";
|
|
1328
|
+
function chalkGreen(text3) {
|
|
1329
|
+
return chalk2.hex(green)(text3);
|
|
1330
|
+
}
|
|
1331
|
+
function chalkPurple(text3) {
|
|
1332
|
+
return chalk2.hex(purple)(text3);
|
|
1333
|
+
}
|
|
1334
|
+
function chalkGrey(text3) {
|
|
1335
|
+
return chalk2.hex("#878C99")(text3);
|
|
1336
|
+
}
|
|
1337
|
+
function chalkError(text3) {
|
|
1338
|
+
return chalk2.hex("#E11D48")(text3);
|
|
1339
|
+
}
|
|
1340
|
+
function chalkWarning(text3) {
|
|
1341
|
+
return chalk2.yellow(text3);
|
|
1342
|
+
}
|
|
1343
|
+
function chalkSuccess(text3) {
|
|
1344
|
+
return chalk2.hex("#28BF5C")(text3);
|
|
1345
|
+
}
|
|
1346
|
+
function chalkLink(text3) {
|
|
1347
|
+
return chalk2.underline.hex("#D7D9DD")(text3);
|
|
1348
|
+
}
|
|
1349
|
+
function chalkWorker(text3) {
|
|
1350
|
+
return chalk2.hex("#FFFF89")(text3);
|
|
1351
|
+
}
|
|
1352
|
+
function chalkTask(text3) {
|
|
1353
|
+
return chalk2.hex("#60A5FA")(text3);
|
|
1354
|
+
}
|
|
1355
|
+
function chalkRun(text3) {
|
|
1356
|
+
return chalk2.hex("#A78BFA")(text3);
|
|
1357
|
+
}
|
|
1358
|
+
function logo() {
|
|
1359
|
+
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1360
|
+
}
|
|
1361
|
+
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1362
|
+
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1363
|
+
month: "short",
|
|
1364
|
+
day: "2-digit",
|
|
1365
|
+
hour: "2-digit",
|
|
1366
|
+
minute: "2-digit",
|
|
1367
|
+
second: "2-digit",
|
|
1368
|
+
hour12: false
|
|
1369
|
+
}).format(date);
|
|
1370
|
+
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1371
|
+
return formattedDate;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// src/cli/common.ts
|
|
1325
1375
|
var CommonCommandOptions = z.object({
|
|
1326
1376
|
apiUrl: z.string().optional(),
|
|
1327
1377
|
logLevel: z.enum(["debug", "info", "log", "warn", "error", "none"]).default("log"),
|
|
@@ -1331,7 +1381,7 @@ var CommonCommandOptions = z.object({
|
|
|
1331
1381
|
function commonOptions(command) {
|
|
1332
1382
|
return command.option("--profile <profile>", "The login profile to use", "default").option("-a, --api-url <value>", "Override the API URL", "https://api.trigger.dev").option(
|
|
1333
1383
|
"-l, --log-level <level>",
|
|
1334
|
-
"The log level to use (debug, info, log, warn, error, none)",
|
|
1384
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
1335
1385
|
"log"
|
|
1336
1386
|
).option("--skip-telemetry", "Opt-out of sending telemetry");
|
|
1337
1387
|
}
|
|
@@ -1377,7 +1427,7 @@ async function wrapCommandAction(name, schema, options, action) {
|
|
|
1377
1427
|
} else if (e instanceof SkipCommandError) {
|
|
1378
1428
|
} else {
|
|
1379
1429
|
recordSpanException(span, e);
|
|
1380
|
-
logger.
|
|
1430
|
+
logger.log(`${chalkError("X Error:")} ${e instanceof Error ? e.message : String(e)}`);
|
|
1381
1431
|
}
|
|
1382
1432
|
span.end();
|
|
1383
1433
|
throw e;
|
|
@@ -1535,6 +1585,11 @@ function readAuthConfigProfile(profile = "default") {
|
|
|
1535
1585
|
return void 0;
|
|
1536
1586
|
}
|
|
1537
1587
|
}
|
|
1588
|
+
function deleteAuthConfigProfile(profile = "default") {
|
|
1589
|
+
const existingConfig = readAuthConfigFile() || {};
|
|
1590
|
+
delete existingConfig[profile];
|
|
1591
|
+
writeAuthConfigFile(existingConfig);
|
|
1592
|
+
}
|
|
1538
1593
|
function readAuthConfigFile() {
|
|
1539
1594
|
try {
|
|
1540
1595
|
const authConfigFilePath = getAuthConfigFilePath();
|
|
@@ -1601,7 +1656,8 @@ async function readConfig(dir, options) {
|
|
|
1601
1656
|
});
|
|
1602
1657
|
const userConfigModule = await import(builtConfigFileHref);
|
|
1603
1658
|
const rawConfig = await normalizeConfig(
|
|
1604
|
-
userConfigModule
|
|
1659
|
+
userConfigModule?.config,
|
|
1660
|
+
options?.projectRef ? { project: options?.projectRef } : void 0
|
|
1605
1661
|
);
|
|
1606
1662
|
const config = Config.parse(rawConfig);
|
|
1607
1663
|
return {
|
|
@@ -1626,66 +1682,20 @@ async function resolveConfig(path6, config) {
|
|
|
1626
1682
|
}
|
|
1627
1683
|
return config;
|
|
1628
1684
|
}
|
|
1629
|
-
async function normalizeConfig(config) {
|
|
1685
|
+
async function normalizeConfig(config, overrides) {
|
|
1686
|
+
let normalized = config;
|
|
1630
1687
|
if (typeof config === "function") {
|
|
1631
|
-
|
|
1688
|
+
normalized = await config();
|
|
1632
1689
|
}
|
|
1633
|
-
|
|
1690
|
+
normalized = { ...normalized, ...overrides };
|
|
1691
|
+
return normalized;
|
|
1634
1692
|
}
|
|
1635
1693
|
|
|
1636
1694
|
// src/utilities/initialBanner.ts
|
|
1637
1695
|
import { spinner } from "@clack/prompts";
|
|
1638
1696
|
import chalk3 from "chalk";
|
|
1639
|
-
import supportsColor from "supports-color";
|
|
1640
1697
|
import checkForUpdate from "update-check";
|
|
1641
1698
|
|
|
1642
|
-
// src/utilities/cliOutput.ts
|
|
1643
|
-
import chalk2 from "chalk";
|
|
1644
|
-
var green = "#4FFF54";
|
|
1645
|
-
var purple = "#735BF3";
|
|
1646
|
-
function chalkPurple(text2) {
|
|
1647
|
-
return chalk2.hex(purple)(text2);
|
|
1648
|
-
}
|
|
1649
|
-
function chalkGrey(text2) {
|
|
1650
|
-
return chalk2.hex("#878C99")(text2);
|
|
1651
|
-
}
|
|
1652
|
-
function chalkError(text2) {
|
|
1653
|
-
return chalk2.hex("#E11D48")(text2);
|
|
1654
|
-
}
|
|
1655
|
-
function chalkWarning(text2) {
|
|
1656
|
-
return chalk2.yellow(text2);
|
|
1657
|
-
}
|
|
1658
|
-
function chalkSuccess(text2) {
|
|
1659
|
-
return chalk2.hex("#28BF5C")(text2);
|
|
1660
|
-
}
|
|
1661
|
-
function chalkLink(text2) {
|
|
1662
|
-
return chalk2.underline.hex("#D7D9DD")(text2);
|
|
1663
|
-
}
|
|
1664
|
-
function chalkWorker(text2) {
|
|
1665
|
-
return chalk2.hex("#FFFF89")(text2);
|
|
1666
|
-
}
|
|
1667
|
-
function chalkTask(text2) {
|
|
1668
|
-
return chalk2.hex("#60A5FA")(text2);
|
|
1669
|
-
}
|
|
1670
|
-
function chalkRun(text2) {
|
|
1671
|
-
return chalk2.hex("#A78BFA")(text2);
|
|
1672
|
-
}
|
|
1673
|
-
function logo() {
|
|
1674
|
-
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1675
|
-
}
|
|
1676
|
-
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1677
|
-
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1678
|
-
month: "short",
|
|
1679
|
-
day: "2-digit",
|
|
1680
|
-
hour: "2-digit",
|
|
1681
|
-
minute: "2-digit",
|
|
1682
|
-
second: "2-digit",
|
|
1683
|
-
hour12: false
|
|
1684
|
-
}).format(date);
|
|
1685
|
-
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1686
|
-
return formattedDate;
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
1699
|
// src/utilities/getVersion.ts
|
|
1690
1700
|
import path3 from "path";
|
|
1691
1701
|
function getVersion() {
|
|
@@ -1697,10 +1707,10 @@ function getVersion() {
|
|
|
1697
1707
|
// src/utilities/initialBanner.ts
|
|
1698
1708
|
async function printInitialBanner(performUpdateCheck = true) {
|
|
1699
1709
|
const packageVersion = getVersion();
|
|
1700
|
-
const
|
|
1710
|
+
const text3 = `
|
|
1701
1711
|
${logo()} ${chalkGrey(`(${packageVersion})`)}
|
|
1702
1712
|
`;
|
|
1703
|
-
logger.info(
|
|
1713
|
+
logger.info(text3);
|
|
1704
1714
|
let maybeNewVersion;
|
|
1705
1715
|
if (performUpdateCheck) {
|
|
1706
1716
|
const loadingSpinner = spinner();
|
|
@@ -1724,19 +1734,19 @@ After installation, run Trigger.dev with \`npx trigger.dev\`.`
|
|
|
1724
1734
|
}
|
|
1725
1735
|
async function printStandloneInitialBanner(performUpdateCheck = true) {
|
|
1726
1736
|
const packageVersion = getVersion();
|
|
1727
|
-
let
|
|
1737
|
+
let text3 = `
|
|
1728
1738
|
${logo()} ${chalkGrey("(v3 Developer Preview)")}`;
|
|
1729
1739
|
if (performUpdateCheck) {
|
|
1730
1740
|
const maybeNewVersion = await updateCheck();
|
|
1731
1741
|
if (maybeNewVersion !== void 0) {
|
|
1732
|
-
|
|
1742
|
+
text3 = `${text3} (update available ${chalk3.green(maybeNewVersion)})`;
|
|
1733
1743
|
}
|
|
1734
1744
|
}
|
|
1735
|
-
logger.log(
|
|
1745
|
+
logger.log(text3 + "\n" + chalkGrey("-".repeat(54)));
|
|
1736
1746
|
}
|
|
1737
1747
|
function printDevBanner() {
|
|
1738
1748
|
logger.log(
|
|
1739
|
-
`${chalkGrey("Key:")} ${chalkWorker("
|
|
1749
|
+
`${chalkGrey("Key:")} ${chalkWorker("Version")} ${chalkGrey("|")} ${chalkTask(
|
|
1740
1750
|
"Task"
|
|
1741
1751
|
)} ${chalkGrey("|")} ${chalkRun("Run")}`
|
|
1742
1752
|
);
|
|
@@ -1764,20 +1774,14 @@ async function installPackages(packages, options) {
|
|
|
1764
1774
|
const cwd = options?.cwd ?? process.cwd();
|
|
1765
1775
|
logger.debug("Installing packages", { packages });
|
|
1766
1776
|
await setPackageJsonDeps(join3(cwd, "package.json"), packages);
|
|
1767
|
-
|
|
1777
|
+
await execa(
|
|
1768
1778
|
"npm",
|
|
1769
1779
|
["install", "--install-strategy", "nested", "--ignore-scripts", "--no-audit", "--no-fund"],
|
|
1770
1780
|
{
|
|
1771
1781
|
cwd,
|
|
1772
|
-
stderr: "
|
|
1782
|
+
stderr: "pipe"
|
|
1773
1783
|
}
|
|
1774
1784
|
);
|
|
1775
|
-
await new Promise((res, rej) => {
|
|
1776
|
-
childProcess2.on("error", (e) => rej(e));
|
|
1777
|
-
childProcess2.on("close", () => res());
|
|
1778
|
-
});
|
|
1779
|
-
await childProcess2;
|
|
1780
|
-
return;
|
|
1781
1785
|
}
|
|
1782
1786
|
function detectPackageNameFromImportPath(path6) {
|
|
1783
1787
|
if (path6.startsWith("@")) {
|
|
@@ -2521,6 +2525,29 @@ async function login(options) {
|
|
|
2521
2525
|
if (!opts.embedded) {
|
|
2522
2526
|
intro2("Logging in to Trigger.dev");
|
|
2523
2527
|
}
|
|
2528
|
+
const accessTokenFromEnv = process.env.TRIGGER_ACCESS_TOKEN;
|
|
2529
|
+
if (accessTokenFromEnv) {
|
|
2530
|
+
const auth = {
|
|
2531
|
+
accessToken: accessTokenFromEnv,
|
|
2532
|
+
apiUrl: process.env.TRIGGER_API_URL ?? "https://api.trigger.dev"
|
|
2533
|
+
};
|
|
2534
|
+
const apiClient3 = new CliApiClient(auth.apiUrl, auth.accessToken);
|
|
2535
|
+
const userData = await apiClient3.whoAmI();
|
|
2536
|
+
if (!userData.success) {
|
|
2537
|
+
throw new Error(userData.error);
|
|
2538
|
+
}
|
|
2539
|
+
return {
|
|
2540
|
+
ok: true,
|
|
2541
|
+
profile: options?.profile ?? "default",
|
|
2542
|
+
userId: userData.data.userId,
|
|
2543
|
+
email: userData.data.email,
|
|
2544
|
+
dashboardUrl: userData.data.dashboardUrl,
|
|
2545
|
+
auth: {
|
|
2546
|
+
accessToken: auth.accessToken,
|
|
2547
|
+
apiUrl: auth.apiUrl
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2524
2551
|
const authConfig = readAuthConfigProfile(options?.profile);
|
|
2525
2552
|
if (authConfig && authConfig.accessToken) {
|
|
2526
2553
|
const whoAmIResult = await whoAmI(
|
|
@@ -2721,10 +2748,45 @@ ${authorizationCodeResult.error}`
|
|
|
2721
2748
|
});
|
|
2722
2749
|
}
|
|
2723
2750
|
|
|
2751
|
+
// src/commands/deploy.ts
|
|
2752
|
+
import { Glob } from "glob";
|
|
2753
|
+
|
|
2724
2754
|
// src/utilities/build.ts
|
|
2755
|
+
import { readFileSync } from "node:fs";
|
|
2725
2756
|
import { extname, isAbsolute } from "node:path";
|
|
2726
2757
|
import tsConfigPaths from "tsconfig-paths";
|
|
2727
|
-
|
|
2758
|
+
function bundleTriggerDevCore(buildIdentifier, tsconfigPath) {
|
|
2759
|
+
return {
|
|
2760
|
+
name: "trigger-bundle-core",
|
|
2761
|
+
setup(build3) {
|
|
2762
|
+
build3.onResolve({ filter: /.*/ }, (args) => {
|
|
2763
|
+
if (args.path !== "@trigger.dev/core/v3") {
|
|
2764
|
+
return void 0;
|
|
2765
|
+
}
|
|
2766
|
+
const triggerSdkPath = __require.resolve("@trigger.dev/sdk/v3", { paths: [process.cwd()] });
|
|
2767
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Resolved @trigger.dev/sdk/v3`, {
|
|
2768
|
+
...args,
|
|
2769
|
+
triggerSdkPath
|
|
2770
|
+
});
|
|
2771
|
+
const resolvedPath = __require.resolve("@trigger.dev/core/v3", {
|
|
2772
|
+
paths: [triggerSdkPath]
|
|
2773
|
+
});
|
|
2774
|
+
logger.debug(
|
|
2775
|
+
`[${buildIdentifier}][trigger-bundle-core] Externalizing @trigger.dev/core/v3`,
|
|
2776
|
+
{
|
|
2777
|
+
...args,
|
|
2778
|
+
triggerSdkPath,
|
|
2779
|
+
resolvedPath
|
|
2780
|
+
}
|
|
2781
|
+
);
|
|
2782
|
+
return {
|
|
2783
|
+
path: resolvedPath,
|
|
2784
|
+
external: false
|
|
2785
|
+
};
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2788
|
+
};
|
|
2789
|
+
}
|
|
2728
2790
|
function workerSetupImportConfigPlugin(configPath) {
|
|
2729
2791
|
return {
|
|
2730
2792
|
name: "trigger-worker-setup",
|
|
@@ -2751,8 +2813,8 @@ function workerSetupImportConfigPlugin(configPath) {
|
|
|
2751
2813
|
}
|
|
2752
2814
|
};
|
|
2753
2815
|
}
|
|
2754
|
-
function bundleDependenciesPlugin(
|
|
2755
|
-
const matchPath =
|
|
2816
|
+
function bundleDependenciesPlugin(buildIdentifier, dependenciesToBundle, tsconfigPath) {
|
|
2817
|
+
const matchPath = tsconfigPath ? createMatchPath(tsconfigPath) : void 0;
|
|
2756
2818
|
function resolvePath(id) {
|
|
2757
2819
|
if (!matchPath) {
|
|
2758
2820
|
return id;
|
|
@@ -2764,26 +2826,7 @@ function bundleDependenciesPlugin(config) {
|
|
|
2764
2826
|
setup(build3) {
|
|
2765
2827
|
build3.onResolve({ filter: /.*/ }, (args) => {
|
|
2766
2828
|
const resolvedPath = resolvePath(args.path);
|
|
2767
|
-
logger.ignore(`Checking if ${args.path} should be bundled or external`, {
|
|
2768
|
-
...args,
|
|
2769
|
-
resolvedPath
|
|
2770
|
-
});
|
|
2771
2829
|
if (!isBareModuleId(resolvedPath)) {
|
|
2772
|
-
logger.ignore(`Bundling ${args.path} because its not a bareModuleId`, {
|
|
2773
|
-
...args
|
|
2774
|
-
});
|
|
2775
|
-
return void 0;
|
|
2776
|
-
}
|
|
2777
|
-
if (args.path.startsWith("@trigger.dev/")) {
|
|
2778
|
-
logger.ignore(`Bundling ${args.path} because its a trigger.dev package`, {
|
|
2779
|
-
...args
|
|
2780
|
-
});
|
|
2781
|
-
return void 0;
|
|
2782
|
-
}
|
|
2783
|
-
if (args.path === "superjson" || args.path === "copy-anything" || args.path === "is-what") {
|
|
2784
|
-
logger.debug(`Bundling ${args.path} because its superjson/copy-anything/is-what`, {
|
|
2785
|
-
...args
|
|
2786
|
-
});
|
|
2787
2830
|
return void 0;
|
|
2788
2831
|
}
|
|
2789
2832
|
let loader;
|
|
@@ -2797,12 +2840,12 @@ function bundleDependenciesPlugin(config) {
|
|
|
2797
2840
|
if (loader === "file") {
|
|
2798
2841
|
return void 0;
|
|
2799
2842
|
}
|
|
2800
|
-
for (let pattern of
|
|
2843
|
+
for (let pattern of dependenciesToBundle ?? []) {
|
|
2801
2844
|
if (typeof pattern === "string" ? args.path === pattern : pattern.test(args.path)) {
|
|
2802
2845
|
return void 0;
|
|
2803
2846
|
}
|
|
2804
2847
|
}
|
|
2805
|
-
logger.ignore(`Externalizing ${args.path}`, {
|
|
2848
|
+
logger.ignore(`[${buildIdentifier}] Externalizing ${args.path}`, {
|
|
2806
2849
|
...args
|
|
2807
2850
|
});
|
|
2808
2851
|
return {
|
|
@@ -2890,8 +2933,347 @@ function getLoaderForFile(file) {
|
|
|
2890
2933
|
throw new Error(`Cannot get loader for file ${file}`);
|
|
2891
2934
|
}
|
|
2892
2935
|
|
|
2936
|
+
// src/utilities/deployErrors.ts
|
|
2937
|
+
import chalk4 from "chalk";
|
|
2938
|
+
import { relative as relative2 } from "node:path";
|
|
2939
|
+
import { groupTaskMetadataIssuesByTask } from "@trigger.dev/core/v3";
|
|
2940
|
+
function errorIsErrorLike(error) {
|
|
2941
|
+
return error instanceof Error || typeof error === "object" && error !== null && "message" in error;
|
|
2942
|
+
}
|
|
2943
|
+
function parseBuildErrorStack(error) {
|
|
2944
|
+
if (typeof error === "string") {
|
|
2945
|
+
return error;
|
|
2946
|
+
}
|
|
2947
|
+
if (errorIsErrorLike(error)) {
|
|
2948
|
+
if (typeof error.stack === "string") {
|
|
2949
|
+
const isErrRequireEsm = error.stack.includes("ERR_REQUIRE_ESM");
|
|
2950
|
+
let moduleName = null;
|
|
2951
|
+
if (isErrRequireEsm) {
|
|
2952
|
+
const moduleRegex = /node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)\/[^\/]+\s/;
|
|
2953
|
+
const match = moduleRegex.exec(error.stack);
|
|
2954
|
+
if (match) {
|
|
2955
|
+
moduleName = match[1];
|
|
2956
|
+
return {
|
|
2957
|
+
type: "esm-require-error",
|
|
2958
|
+
moduleName
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
} else {
|
|
2963
|
+
return error.message;
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
function logESMRequireError(parsedError, resolvedConfig) {
|
|
2968
|
+
logger.log(
|
|
2969
|
+
`
|
|
2970
|
+
${chalkError("X Error:")} The ${chalkPurple(
|
|
2971
|
+
parsedError.moduleName
|
|
2972
|
+
)} module is being required even though it's ESM only, and builds only support CommonJS. There are two ${chalk4.underline(
|
|
2973
|
+
"possible"
|
|
2974
|
+
)} ways to fix this:`
|
|
2975
|
+
);
|
|
2976
|
+
logger.log(
|
|
2977
|
+
`
|
|
2978
|
+
${chalkGrey("\u25CB")} Dynamically import the module in your code: ${chalkGrey(
|
|
2979
|
+
`const myModule = await import("${parsedError.moduleName}");`
|
|
2980
|
+
)}`
|
|
2981
|
+
);
|
|
2982
|
+
if (resolvedConfig.status === "file") {
|
|
2983
|
+
const relativePath = relative2(resolvedConfig.config.projectDir, resolvedConfig.path).replace(
|
|
2984
|
+
/\\/g,
|
|
2985
|
+
"/"
|
|
2986
|
+
);
|
|
2987
|
+
logger.log(
|
|
2988
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
2989
|
+
parsedError.moduleName
|
|
2990
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
2991
|
+
`(${relativePath})`
|
|
2992
|
+
)}. This will bundle the module with your code.
|
|
2993
|
+
`
|
|
2994
|
+
);
|
|
2995
|
+
} else {
|
|
2996
|
+
logger.log(
|
|
2997
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
2998
|
+
parsedError.moduleName
|
|
2999
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3000
|
+
"(you'll need to create one)"
|
|
3001
|
+
)}. This will bundle the module with your code.
|
|
3002
|
+
`
|
|
3003
|
+
);
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
function parseNpmInstallError(error) {
|
|
3007
|
+
if (typeof error === "string") {
|
|
3008
|
+
return error;
|
|
3009
|
+
}
|
|
3010
|
+
if (error instanceof Error) {
|
|
3011
|
+
if (typeof error.stack === "string") {
|
|
3012
|
+
const isPackageNotFoundError = error.stack.includes("ERR! 404 Not Found") && error.stack.includes("is not in this registry");
|
|
3013
|
+
let packageName = null;
|
|
3014
|
+
if (isPackageNotFoundError) {
|
|
3015
|
+
const packageNameRegex = /'([^']+)' is not in this registry/;
|
|
3016
|
+
const match = packageNameRegex.exec(error.stack);
|
|
3017
|
+
if (match) {
|
|
3018
|
+
packageName = match[1];
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
if (packageName) {
|
|
3022
|
+
return {
|
|
3023
|
+
type: "package-not-found-error",
|
|
3024
|
+
packageName
|
|
3025
|
+
};
|
|
3026
|
+
}
|
|
3027
|
+
const noMatchingVersionRegex = /No matching version found for ([^\s]+)\s/;
|
|
3028
|
+
const noMatchingVersionMatch = noMatchingVersionRegex.exec(error.stack);
|
|
3029
|
+
if (noMatchingVersionMatch) {
|
|
3030
|
+
return {
|
|
3031
|
+
type: "no-matching-version-error",
|
|
3032
|
+
packageName: noMatchingVersionMatch[1].replace(/.$/, "")
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
3035
|
+
return error.message;
|
|
3036
|
+
} else {
|
|
3037
|
+
return error.message;
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
return "Unknown error";
|
|
3041
|
+
}
|
|
3042
|
+
function logTaskMetadataParseError(zodIssues, tasks) {
|
|
3043
|
+
logger.log(
|
|
3044
|
+
`
|
|
3045
|
+
${chalkError("X Error:")} Failed to start. The following ${zodIssues.length === 1 ? "task issue was" : "task issues were"} found:`
|
|
3046
|
+
);
|
|
3047
|
+
const groupedIssues = groupTaskMetadataIssuesByTask(tasks, zodIssues);
|
|
3048
|
+
for (const key in groupedIssues) {
|
|
3049
|
+
const taskWithIssues = groupedIssues[key];
|
|
3050
|
+
if (!taskWithIssues) {
|
|
3051
|
+
continue;
|
|
3052
|
+
}
|
|
3053
|
+
logger.log(
|
|
3054
|
+
`
|
|
3055
|
+
${chalkWarning("\u276F")} ${taskWithIssues.exportName} ${chalkGrey("in")} ${taskWithIssues.filePath}`
|
|
3056
|
+
);
|
|
3057
|
+
for (const issue of taskWithIssues.issues) {
|
|
3058
|
+
if (issue.path) {
|
|
3059
|
+
logger.log(` ${chalkError("x")} ${issue.path} ${chalkGrey(issue.message)}`);
|
|
3060
|
+
} else {
|
|
3061
|
+
logger.log(` ${chalkError("x")} ${chalkGrey(issue.message)}`);
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
// src/utilities/safeJsonParse.ts
|
|
3068
|
+
function safeJsonParse(json) {
|
|
3069
|
+
if (!json) {
|
|
3070
|
+
return void 0;
|
|
3071
|
+
}
|
|
3072
|
+
try {
|
|
3073
|
+
return JSON.parse(json);
|
|
3074
|
+
} catch {
|
|
3075
|
+
return void 0;
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
// src/utilities/javascriptProject.ts
|
|
3080
|
+
import { $ } from "execa";
|
|
3081
|
+
import { join as join4 } from "node:path";
|
|
3082
|
+
|
|
3083
|
+
// src/utilities/getUserPackageManager.ts
|
|
3084
|
+
import { findUp as findUp2 } from "find-up";
|
|
3085
|
+
async function getUserPackageManager(path6) {
|
|
3086
|
+
try {
|
|
3087
|
+
return await detectPackageManagerFromArtifacts(path6);
|
|
3088
|
+
} catch (error) {
|
|
3089
|
+
return detectPackageManagerFromCurrentCommand();
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
function detectPackageManagerFromCurrentCommand() {
|
|
3093
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
3094
|
+
if (userAgent) {
|
|
3095
|
+
if (userAgent.startsWith("yarn")) {
|
|
3096
|
+
return "yarn";
|
|
3097
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
3098
|
+
return "pnpm";
|
|
3099
|
+
} else {
|
|
3100
|
+
return "npm";
|
|
3101
|
+
}
|
|
3102
|
+
} else {
|
|
3103
|
+
return "npm";
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
async function detectPackageManagerFromArtifacts(path6) {
|
|
3107
|
+
const packageFiles = [
|
|
3108
|
+
{ name: "yarn.lock", pm: "yarn" },
|
|
3109
|
+
{ name: "pnpm-lock.yaml", pm: "pnpm" },
|
|
3110
|
+
{ name: "package-lock.json", pm: "npm" },
|
|
3111
|
+
{ name: "npm-shrinkwrap.json", pm: "npm" }
|
|
3112
|
+
];
|
|
3113
|
+
for (const { name, pm } of packageFiles) {
|
|
3114
|
+
const foundPath = await findUp2(name, { cwd: path6 });
|
|
3115
|
+
if (typeof foundPath === "string") {
|
|
3116
|
+
return pm;
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
throw new Error("Could not detect package manager from artifacts");
|
|
3120
|
+
}
|
|
3121
|
+
|
|
3122
|
+
// src/utilities/javascriptProject.ts
|
|
3123
|
+
var BuiltInModules = /* @__PURE__ */ new Set([
|
|
3124
|
+
"assert",
|
|
3125
|
+
"async_hooks",
|
|
3126
|
+
"buffer",
|
|
3127
|
+
"child_process",
|
|
3128
|
+
"cluster",
|
|
3129
|
+
"console",
|
|
3130
|
+
"constants",
|
|
3131
|
+
"crypto",
|
|
3132
|
+
"dgram",
|
|
3133
|
+
"dns",
|
|
3134
|
+
"domain",
|
|
3135
|
+
"events",
|
|
3136
|
+
"fs",
|
|
3137
|
+
"http",
|
|
3138
|
+
"http2",
|
|
3139
|
+
"https",
|
|
3140
|
+
"inspector",
|
|
3141
|
+
"module",
|
|
3142
|
+
"net",
|
|
3143
|
+
"os",
|
|
3144
|
+
"path",
|
|
3145
|
+
"perf_hooks",
|
|
3146
|
+
"process",
|
|
3147
|
+
"punycode",
|
|
3148
|
+
"querystring",
|
|
3149
|
+
"readline",
|
|
3150
|
+
"repl",
|
|
3151
|
+
"stream",
|
|
3152
|
+
"string_decoder",
|
|
3153
|
+
"timers",
|
|
3154
|
+
"tls",
|
|
3155
|
+
"trace_events",
|
|
3156
|
+
"tty",
|
|
3157
|
+
"url",
|
|
3158
|
+
"util",
|
|
3159
|
+
"v8",
|
|
3160
|
+
"vm",
|
|
3161
|
+
"worker_threads",
|
|
3162
|
+
"zlib"
|
|
3163
|
+
]);
|
|
3164
|
+
var JavascriptProject = class {
|
|
3165
|
+
constructor(projectPath) {
|
|
3166
|
+
this.projectPath = projectPath;
|
|
3167
|
+
}
|
|
3168
|
+
_packageJson;
|
|
3169
|
+
_packageManager;
|
|
3170
|
+
get packageJson() {
|
|
3171
|
+
if (!this._packageJson) {
|
|
3172
|
+
this._packageJson = readJSONFileSync(join4(this.projectPath, "package.json"));
|
|
3173
|
+
}
|
|
3174
|
+
return this._packageJson;
|
|
3175
|
+
}
|
|
3176
|
+
get scripts() {
|
|
3177
|
+
return {
|
|
3178
|
+
postinstall: this.packageJson.scripts?.postinstall
|
|
3179
|
+
};
|
|
3180
|
+
}
|
|
3181
|
+
async resolve(packageName, options) {
|
|
3182
|
+
if (BuiltInModules.has(packageName)) {
|
|
3183
|
+
return void 0;
|
|
3184
|
+
}
|
|
3185
|
+
if (!this._packageManager) {
|
|
3186
|
+
this._packageManager = await getUserPackageManager(this.projectPath);
|
|
3187
|
+
}
|
|
3188
|
+
const packageManager = this._packageManager;
|
|
3189
|
+
const opts = { allowDev: false, ...options };
|
|
3190
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3191
|
+
if (typeof packageJsonVersion === "string") {
|
|
3192
|
+
return packageJsonVersion;
|
|
3193
|
+
}
|
|
3194
|
+
if (opts.allowDev) {
|
|
3195
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3196
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3197
|
+
return devPackageJsonVersion;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
const command = packageManager === "npm" ? new NPMCommands() : packageManager === "pnpm" ? new PNPMCommands() : new YarnCommands();
|
|
3201
|
+
try {
|
|
3202
|
+
const version2 = await command.resolveDependencyVersion(packageName, {
|
|
3203
|
+
cwd: this.projectPath
|
|
3204
|
+
});
|
|
3205
|
+
if (version2) {
|
|
3206
|
+
return version2;
|
|
3207
|
+
}
|
|
3208
|
+
} catch (error) {
|
|
3209
|
+
logger.debug(`Failed to resolve dependency version using ${command.name}`, {
|
|
3210
|
+
packageName,
|
|
3211
|
+
error
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
};
|
|
3216
|
+
var PNPMCommands = class {
|
|
3217
|
+
get name() {
|
|
3218
|
+
return "pnpm";
|
|
3219
|
+
}
|
|
3220
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3221
|
+
const cmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
3222
|
+
const { stdout } = await $({ cwd: options.cwd })`${cmd} list ${packageName} -r --json`;
|
|
3223
|
+
const result = JSON.parse(stdout);
|
|
3224
|
+
logger.debug(`Resolving ${packageName} version using pnpm`, { result });
|
|
3225
|
+
for (const dep of result) {
|
|
3226
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3227
|
+
if (dependency) {
|
|
3228
|
+
return dependency.version;
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
};
|
|
3233
|
+
var NPMCommands = class {
|
|
3234
|
+
get name() {
|
|
3235
|
+
return "npm";
|
|
3236
|
+
}
|
|
3237
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3238
|
+
const cmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
3239
|
+
const { stdout } = await $({ cwd: options.cwd })`${cmd} list ${packageName} --json`;
|
|
3240
|
+
const output = JSON.parse(stdout);
|
|
3241
|
+
logger.debug(`Resolving ${packageName} version using npm`, { output });
|
|
3242
|
+
return this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3243
|
+
}
|
|
3244
|
+
#recursivelySearchDependencies(dependencies2, packageName) {
|
|
3245
|
+
for (const [name, dependency] of Object.entries(dependencies2)) {
|
|
3246
|
+
if (name === packageName) {
|
|
3247
|
+
return dependency.version;
|
|
3248
|
+
}
|
|
3249
|
+
if (dependency.dependencies) {
|
|
3250
|
+
const result = this.#recursivelySearchDependencies(dependency.dependencies, packageName);
|
|
3251
|
+
if (result) {
|
|
3252
|
+
return result;
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
};
|
|
3258
|
+
var YarnCommands = class {
|
|
3259
|
+
get name() {
|
|
3260
|
+
return "yarn";
|
|
3261
|
+
}
|
|
3262
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3263
|
+
const cmd = process.platform === "win32" ? "yarn.cmd" : "yarn";
|
|
3264
|
+
const { stdout } = await $({ cwd: options.cwd })`${cmd} info ${packageName} --json`;
|
|
3265
|
+
const lines = stdout.split("\n");
|
|
3266
|
+
logger.debug(`Resolving ${packageName} version using yarn`, { lines });
|
|
3267
|
+
for (const line of lines) {
|
|
3268
|
+
const json = JSON.parse(line);
|
|
3269
|
+
if (json.value === packageName) {
|
|
3270
|
+
return json.children.Version;
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
};
|
|
3275
|
+
|
|
2893
3276
|
// src/commands/deploy.ts
|
|
2894
|
-
import { Glob } from "glob";
|
|
2895
3277
|
var DeployCommandOptions = CommonCommandOptions.extend({
|
|
2896
3278
|
skipTypecheck: z4.boolean().default(false),
|
|
2897
3279
|
skipDeploy: z4.boolean().default(false),
|
|
@@ -2918,7 +3300,7 @@ function configureDeployCommand(program2) {
|
|
|
2918
3300
|
"Detected missing environment variables won't block deployment"
|
|
2919
3301
|
).option("-c, --config <config file>", "The name of the config file, found at [path]").option(
|
|
2920
3302
|
"-p, --project-ref <project ref>",
|
|
2921
|
-
"The project ref. Required if there is no config file."
|
|
3303
|
+
"The project ref. Required if there is no config file. This will override the project specified in the config file."
|
|
2922
3304
|
)
|
|
2923
3305
|
).addOption(
|
|
2924
3306
|
new CommandOption(
|
|
@@ -3065,26 +3447,38 @@ async function _deployCommand(dir, options) {
|
|
|
3065
3447
|
"Failed to initialize deployment. The deployment does not have any external build data. To deploy this project, you must use the --self-hosted flag to build and push the image yourself."
|
|
3066
3448
|
);
|
|
3067
3449
|
}
|
|
3068
|
-
return buildAndPushImage(
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3450
|
+
return buildAndPushImage(
|
|
3451
|
+
{
|
|
3452
|
+
registryHost,
|
|
3453
|
+
auth: authorization.auth.accessToken,
|
|
3454
|
+
imageTag: deploymentResponse.data.imageTag,
|
|
3455
|
+
buildId: deploymentResponse.data.externalBuildData.buildId,
|
|
3456
|
+
buildToken: deploymentResponse.data.externalBuildData.buildToken,
|
|
3457
|
+
buildProjectId: deploymentResponse.data.externalBuildData.projectId,
|
|
3458
|
+
cwd: compilation.path,
|
|
3459
|
+
projectId: resolvedConfig.config.project,
|
|
3460
|
+
deploymentId: deploymentResponse.data.id,
|
|
3461
|
+
deploymentVersion: deploymentResponse.data.version,
|
|
3462
|
+
contentHash: deploymentResponse.data.contentHash,
|
|
3463
|
+
projectRef: resolvedConfig.config.project,
|
|
3464
|
+
loadImage: options.loadImage,
|
|
3465
|
+
buildPlatform: options.buildPlatform
|
|
3466
|
+
},
|
|
3467
|
+
deploymentSpinner
|
|
3468
|
+
);
|
|
3084
3469
|
};
|
|
3085
3470
|
const image = await buildImage();
|
|
3086
3471
|
if (!image.ok) {
|
|
3087
|
-
deploymentSpinner.stop(`Failed to build project
|
|
3472
|
+
deploymentSpinner.stop(`Failed to build project.`);
|
|
3473
|
+
if (image.logs.trim() !== "") {
|
|
3474
|
+
const logPath = join5(await createTempDir(), `build-${deploymentResponse.data.shortCode}.log`);
|
|
3475
|
+
await writeFile2(logPath, image.logs);
|
|
3476
|
+
logger.log(
|
|
3477
|
+
`${chalkError("X Error:")} ${image.error}. Full build logs have been saved to ${logPath})`
|
|
3478
|
+
);
|
|
3479
|
+
} else {
|
|
3480
|
+
logger.log(`${chalkError("X Error:")} ${image.error}.`);
|
|
3481
|
+
}
|
|
3088
3482
|
throw new SkipLoggingError(`Failed to build project image: ${image.error}`);
|
|
3089
3483
|
}
|
|
3090
3484
|
const imageReference = options.selfHosted ? `${selfHostedRegistryHost ? `${selfHostedRegistryHost}/` : ""}${image.image}${image.digest ? `@${image.digest}` : ""}` : `${registryHost}/${image.image}${image.digest ? `@${image.digest}` : ""}`;
|
|
@@ -3144,10 +3538,27 @@ async function _deployCommand(dir, options) {
|
|
|
3144
3538
|
}
|
|
3145
3539
|
case "FAILED": {
|
|
3146
3540
|
if (finishedDeployment.errorData) {
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3541
|
+
if (finishedDeployment.errorData.name === "TaskMetadataParseError") {
|
|
3542
|
+
const errorJson = safeJsonParse(finishedDeployment.errorData.stack);
|
|
3543
|
+
if (errorJson) {
|
|
3544
|
+
const parsedError2 = TaskMetadataFailedToParseData.safeParse(errorJson);
|
|
3545
|
+
if (parsedError2.success) {
|
|
3546
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3547
|
+
logTaskMetadataParseError(parsedError2.data.zodIssues, parsedError2.data.tasks);
|
|
3548
|
+
throw new SkipLoggingError(
|
|
3549
|
+
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3550
|
+
);
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
}
|
|
3554
|
+
const parsedError = finishedDeployment.errorData.stack ? parseBuildErrorStack(finishedDeployment.errorData) ?? finishedDeployment.errorData.message : finishedDeployment.errorData.message;
|
|
3555
|
+
if (typeof parsedError === "string") {
|
|
3556
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3557
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
3558
|
+
} else {
|
|
3559
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3560
|
+
logESMRequireError(parsedError, resolvedConfig);
|
|
3561
|
+
}
|
|
3151
3562
|
throw new SkipLoggingError(
|
|
3152
3563
|
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3153
3564
|
);
|
|
@@ -3185,7 +3596,7 @@ async function checkEnvVars(envVars, config, options, environmentClient, apiUrl)
|
|
|
3185
3596
|
environmentVariablesSpinner.stop(
|
|
3186
3597
|
`Found missing env vars in ${options.env}: ${arrayToSentence(
|
|
3187
3598
|
missingEnvironmentVariables
|
|
3188
|
-
)}. ${options.ignoreEnvVarCheck ? "Continuing deployment because of --ignore-env-var-check. " : "Aborting deployment. "}${
|
|
3599
|
+
)}. ${options.ignoreEnvVarCheck ? "Continuing deployment because of --ignore-env-var-check. " : "Aborting deployment. "}${chalk5.bgBlueBright(
|
|
3189
3600
|
terminalLink(
|
|
3190
3601
|
"Manage env vars",
|
|
3191
3602
|
`${apiUrl}/projects/v3/${config.project}/environment-variables`
|
|
@@ -3246,7 +3657,7 @@ async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds
|
|
|
3246
3657
|
}
|
|
3247
3658
|
});
|
|
3248
3659
|
}
|
|
3249
|
-
async function buildAndPushImage(options) {
|
|
3660
|
+
async function buildAndPushImage(options, updater) {
|
|
3250
3661
|
return tracer.startActiveSpan("buildAndPushImage", async (span) => {
|
|
3251
3662
|
span.setAttributes({
|
|
3252
3663
|
"options.registryHost": options.registryHost,
|
|
@@ -3302,15 +3713,24 @@ async function buildAndPushImage(options) {
|
|
|
3302
3713
|
});
|
|
3303
3714
|
const errors = [];
|
|
3304
3715
|
try {
|
|
3305
|
-
await new Promise((res, rej) => {
|
|
3716
|
+
const processCode = await new Promise((res, rej) => {
|
|
3306
3717
|
childProcess2.stderr?.on("data", (data) => {
|
|
3307
|
-
const
|
|
3308
|
-
|
|
3309
|
-
|
|
3718
|
+
const text3 = data.toString();
|
|
3719
|
+
const lines = text3.split("\n").filter(Boolean);
|
|
3720
|
+
errors.push(...lines);
|
|
3721
|
+
logger.debug(text3);
|
|
3310
3722
|
});
|
|
3311
3723
|
childProcess2.on("error", (e) => rej(e));
|
|
3312
|
-
childProcess2.on("close", () => res());
|
|
3724
|
+
childProcess2.on("close", (code) => res(code));
|
|
3313
3725
|
});
|
|
3726
|
+
const logs = extractLogs(errors);
|
|
3727
|
+
if (processCode !== 0) {
|
|
3728
|
+
return {
|
|
3729
|
+
ok: false,
|
|
3730
|
+
error: `Error building image`,
|
|
3731
|
+
logs
|
|
3732
|
+
};
|
|
3733
|
+
}
|
|
3314
3734
|
const digest = extractImageDigest(errors);
|
|
3315
3735
|
span.setAttributes({
|
|
3316
3736
|
"image.digest": digest
|
|
@@ -3319,6 +3739,7 @@ async function buildAndPushImage(options) {
|
|
|
3319
3739
|
return {
|
|
3320
3740
|
ok: true,
|
|
3321
3741
|
image: options.imageTag,
|
|
3742
|
+
logs,
|
|
3322
3743
|
digest
|
|
3323
3744
|
};
|
|
3324
3745
|
} catch (e) {
|
|
@@ -3326,7 +3747,8 @@ async function buildAndPushImage(options) {
|
|
|
3326
3747
|
span.end();
|
|
3327
3748
|
return {
|
|
3328
3749
|
ok: false,
|
|
3329
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
3750
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
3751
|
+
logs: extractLogs(errors)
|
|
3330
3752
|
};
|
|
3331
3753
|
}
|
|
3332
3754
|
});
|
|
@@ -3372,15 +3794,22 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3372
3794
|
const errors = [];
|
|
3373
3795
|
let digest;
|
|
3374
3796
|
try {
|
|
3375
|
-
await new Promise((res, rej) => {
|
|
3797
|
+
const processCode = await new Promise((res, rej) => {
|
|
3376
3798
|
buildProcess.stderr?.on("data", (data) => {
|
|
3377
|
-
const
|
|
3378
|
-
errors.push(
|
|
3379
|
-
logger.debug(
|
|
3799
|
+
const text3 = data.toString();
|
|
3800
|
+
errors.push(text3);
|
|
3801
|
+
logger.debug(text3);
|
|
3380
3802
|
});
|
|
3381
3803
|
buildProcess.on("error", (e) => rej(e));
|
|
3382
|
-
buildProcess.on("close", () => res());
|
|
3804
|
+
buildProcess.on("close", (code) => res(code));
|
|
3383
3805
|
});
|
|
3806
|
+
if (processCode !== 0) {
|
|
3807
|
+
return {
|
|
3808
|
+
ok: false,
|
|
3809
|
+
error: "Error building image",
|
|
3810
|
+
logs: extractLogs(errors)
|
|
3811
|
+
};
|
|
3812
|
+
}
|
|
3384
3813
|
digest = extractImageDigest(errors);
|
|
3385
3814
|
span.setAttributes({
|
|
3386
3815
|
"image.digest": digest
|
|
@@ -3390,7 +3819,8 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3390
3819
|
span.end();
|
|
3391
3820
|
return {
|
|
3392
3821
|
ok: false,
|
|
3393
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
3822
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
3823
|
+
logs: extractLogs(errors)
|
|
3394
3824
|
};
|
|
3395
3825
|
}
|
|
3396
3826
|
const pushArgs = ["push", imageRef].filter(Boolean);
|
|
@@ -3401,25 +3831,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3401
3831
|
cwd: options.cwd
|
|
3402
3832
|
});
|
|
3403
3833
|
try {
|
|
3404
|
-
await new Promise((res, rej) => {
|
|
3834
|
+
const processCode = await new Promise((res, rej) => {
|
|
3405
3835
|
pushProcess.stdout?.on("data", (data) => {
|
|
3406
|
-
const
|
|
3407
|
-
logger.debug(
|
|
3836
|
+
const text3 = data.toString();
|
|
3837
|
+
logger.debug(text3);
|
|
3408
3838
|
});
|
|
3409
3839
|
pushProcess.stderr?.on("data", (data) => {
|
|
3410
|
-
const
|
|
3411
|
-
logger.debug(
|
|
3840
|
+
const text3 = data.toString();
|
|
3841
|
+
logger.debug(text3);
|
|
3412
3842
|
});
|
|
3413
3843
|
pushProcess.on("error", (e) => rej(e));
|
|
3414
|
-
pushProcess.on("close", () => res());
|
|
3844
|
+
pushProcess.on("close", (code) => res(code));
|
|
3415
3845
|
});
|
|
3846
|
+
if (processCode !== 0) {
|
|
3847
|
+
return {
|
|
3848
|
+
ok: false,
|
|
3849
|
+
error: "Error pushing image",
|
|
3850
|
+
logs: extractLogs(errors)
|
|
3851
|
+
};
|
|
3852
|
+
}
|
|
3416
3853
|
span.end();
|
|
3417
3854
|
} catch (e) {
|
|
3418
3855
|
recordSpanException4(span, e);
|
|
3419
3856
|
span.end();
|
|
3420
3857
|
return {
|
|
3421
3858
|
ok: false,
|
|
3422
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
3859
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
3860
|
+
logs: extractLogs(errors)
|
|
3423
3861
|
};
|
|
3424
3862
|
}
|
|
3425
3863
|
}
|
|
@@ -3427,21 +3865,25 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3427
3865
|
return {
|
|
3428
3866
|
ok: true,
|
|
3429
3867
|
image: options.imageTag,
|
|
3430
|
-
digest
|
|
3868
|
+
digest,
|
|
3869
|
+
logs: extractLogs(errors)
|
|
3431
3870
|
};
|
|
3432
3871
|
});
|
|
3433
3872
|
}
|
|
3434
3873
|
function extractImageDigest(outputs) {
|
|
3435
|
-
const imageDigestRegex = /sha256:[a-f0-9]{64}/;
|
|
3874
|
+
const imageDigestRegex = /pushing manifest for .+(?<digest>sha256:[a-f0-9]{64})/;
|
|
3436
3875
|
for (const line of outputs) {
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
}
|
|
3876
|
+
const imageDigestMatch = line.match(imageDigestRegex);
|
|
3877
|
+
const digest = imageDigestMatch?.groups?.digest;
|
|
3878
|
+
if (digest) {
|
|
3879
|
+
return digest;
|
|
3442
3880
|
}
|
|
3443
3881
|
}
|
|
3444
3882
|
}
|
|
3883
|
+
function extractLogs(outputs) {
|
|
3884
|
+
const cleanedOutputs = outputs.map((line) => line.trim()).filter((line) => line !== "");
|
|
3885
|
+
return cleanedOutputs.map((line) => line.trim()).join("\n");
|
|
3886
|
+
}
|
|
3445
3887
|
async function compileProject(config, options, configPath) {
|
|
3446
3888
|
return await tracer.startActiveSpan("compileProject", async (span) => {
|
|
3447
3889
|
try {
|
|
@@ -3499,7 +3941,14 @@ async function compileProject(config, options, configPath) {
|
|
|
3499
3941
|
TRIGGER_API_URL: `"${config.triggerUrl}"`,
|
|
3500
3942
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
3501
3943
|
},
|
|
3502
|
-
plugins: [
|
|
3944
|
+
plugins: [
|
|
3945
|
+
bundleDependenciesPlugin(
|
|
3946
|
+
"workerFacade",
|
|
3947
|
+
config.dependenciesToBundle,
|
|
3948
|
+
config.tsconfigPath
|
|
3949
|
+
),
|
|
3950
|
+
workerSetupImportConfigPlugin(configPath)
|
|
3951
|
+
]
|
|
3503
3952
|
});
|
|
3504
3953
|
if (result.errors.length > 0) {
|
|
3505
3954
|
compileSpinner.stop("Build failed, aborting deployment");
|
|
@@ -3511,7 +3960,7 @@ async function compileProject(config, options, configPath) {
|
|
|
3511
3960
|
throw new Error("Build failed, aborting deployment");
|
|
3512
3961
|
}
|
|
3513
3962
|
if (options.outputMetafile) {
|
|
3514
|
-
await writeJSONFile(
|
|
3963
|
+
await writeJSONFile(join5(options.outputMetafile, "worker.json"), result.metafile);
|
|
3515
3964
|
}
|
|
3516
3965
|
const entryPointContents = readFileSync2(
|
|
3517
3966
|
new URL(importResolve("./workers/prod/entry-point.js", import.meta.url)).href.replace(
|
|
@@ -3531,17 +3980,23 @@ async function compileProject(config, options, configPath) {
|
|
|
3531
3980
|
write: false,
|
|
3532
3981
|
minify: false,
|
|
3533
3982
|
sourcemap: false,
|
|
3534
|
-
packages: "external",
|
|
3535
|
-
// https://esbuild.github.io/api/#packages
|
|
3536
3983
|
logLevel: "error",
|
|
3537
3984
|
platform: "node",
|
|
3985
|
+
packages: "external",
|
|
3538
3986
|
format: "cjs",
|
|
3539
3987
|
// This is needed to support opentelemetry instrumentation that uses module patching
|
|
3540
3988
|
target: ["node18", "es2020"],
|
|
3541
3989
|
outdir: "out",
|
|
3542
3990
|
define: {
|
|
3543
3991
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
3544
|
-
}
|
|
3992
|
+
},
|
|
3993
|
+
plugins: [
|
|
3994
|
+
bundleDependenciesPlugin(
|
|
3995
|
+
"entryPoint.ts",
|
|
3996
|
+
config.dependenciesToBundle,
|
|
3997
|
+
config.tsconfigPath
|
|
3998
|
+
)
|
|
3999
|
+
]
|
|
3545
4000
|
});
|
|
3546
4001
|
if (entryPointResult.errors.length > 0) {
|
|
3547
4002
|
compileSpinner.stop("Build failed, aborting deployment");
|
|
@@ -3554,52 +4009,52 @@ async function compileProject(config, options, configPath) {
|
|
|
3554
4009
|
}
|
|
3555
4010
|
if (options.outputMetafile) {
|
|
3556
4011
|
await writeJSONFile(
|
|
3557
|
-
|
|
4012
|
+
join5(options.outputMetafile, "entry-point.json"),
|
|
3558
4013
|
entryPointResult.metafile
|
|
3559
4014
|
);
|
|
3560
4015
|
}
|
|
3561
4016
|
const tempDir = await createTempDir();
|
|
3562
4017
|
logger.debug(`Writing compiled files to ${tempDir}`);
|
|
3563
|
-
const metaOutput = result.metafile.outputs[
|
|
4018
|
+
const metaOutput = result.metafile.outputs[join5("out", "stdin.js")];
|
|
3564
4019
|
invariant(metaOutput, "Meta output for the result build is missing");
|
|
3565
|
-
const entryPointMetaOutput = entryPointResult.metafile.outputs[
|
|
4020
|
+
const entryPointMetaOutput = entryPointResult.metafile.outputs[join5("out", "stdin.js")];
|
|
3566
4021
|
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
|
|
3567
4022
|
const workerOutputFile = result.outputFiles.find(
|
|
3568
|
-
(file) => file.path ===
|
|
4023
|
+
(file) => file.path === join5(config.projectDir, "out", "stdin.js")
|
|
3569
4024
|
);
|
|
3570
4025
|
invariant(workerOutputFile, "Output file for the result build is missing");
|
|
3571
4026
|
const workerSourcemapFile = result.outputFiles.find(
|
|
3572
|
-
(file) => file.path ===
|
|
4027
|
+
(file) => file.path === join5(config.projectDir, "out", "stdin.js.map")
|
|
3573
4028
|
);
|
|
3574
4029
|
invariant(workerSourcemapFile, "Sourcemap file for the result build is missing");
|
|
3575
4030
|
const entryPointOutputFile = entryPointResult.outputFiles.find(
|
|
3576
|
-
(file) => file.path ===
|
|
4031
|
+
(file) => file.path === join5(config.projectDir, "out", "stdin.js")
|
|
3577
4032
|
);
|
|
3578
4033
|
invariant(entryPointOutputFile, "Output file for the entryPoint build is missing");
|
|
3579
4034
|
await writeFile2(
|
|
3580
|
-
|
|
4035
|
+
join5(tempDir, "worker.js"),
|
|
3581
4036
|
`${workerOutputFile.text}
|
|
3582
4037
|
//# sourceMappingURL=worker.js.map`
|
|
3583
4038
|
);
|
|
3584
|
-
await writeFile2(
|
|
3585
|
-
await writeFile2(
|
|
4039
|
+
await writeFile2(join5(tempDir, "worker.js.map"), workerSourcemapFile.text);
|
|
4040
|
+
await writeFile2(join5(tempDir, "index.js"), entryPointOutputFile.text);
|
|
4041
|
+
logger.debug("Getting the imports for the worker and entryPoint builds", {
|
|
4042
|
+
workerImports: metaOutput.imports,
|
|
4043
|
+
entryPointImports: entryPointMetaOutput.imports
|
|
4044
|
+
});
|
|
3586
4045
|
const allImports = [...metaOutput.imports, ...entryPointMetaOutput.imports];
|
|
3587
|
-
const
|
|
3588
|
-
const dependencies2 = await gatherRequiredDependencies(
|
|
3589
|
-
allImports,
|
|
3590
|
-
config,
|
|
3591
|
-
externalPackageJson
|
|
3592
|
-
);
|
|
4046
|
+
const javascriptProject = new JavascriptProject(config.projectDir);
|
|
4047
|
+
const dependencies2 = await gatherRequiredDependencies(allImports, config, javascriptProject);
|
|
3593
4048
|
const packageJsonContents = {
|
|
3594
4049
|
name: "trigger-worker",
|
|
3595
4050
|
version: "0.0.0",
|
|
3596
4051
|
description: "",
|
|
3597
4052
|
dependencies: dependencies2,
|
|
3598
4053
|
scripts: {
|
|
3599
|
-
|
|
4054
|
+
...javascriptProject.scripts
|
|
3600
4055
|
}
|
|
3601
4056
|
};
|
|
3602
|
-
await writeJSONFile(
|
|
4057
|
+
await writeJSONFile(join5(tempDir, "package.json"), packageJsonContents);
|
|
3603
4058
|
await copyAdditionalFiles(config, tempDir);
|
|
3604
4059
|
compileSpinner.stop("Project built successfully");
|
|
3605
4060
|
const resolvingDependenciesResult = await resolveDependencies(
|
|
@@ -3609,12 +4064,12 @@ async function compileProject(config, options, configPath) {
|
|
|
3609
4064
|
options
|
|
3610
4065
|
);
|
|
3611
4066
|
if (!resolvingDependenciesResult) {
|
|
3612
|
-
throw new
|
|
4067
|
+
throw new SkipLoggingError("Failed to resolve dependencies");
|
|
3613
4068
|
}
|
|
3614
4069
|
const containerFilePath = new URL(
|
|
3615
4070
|
importResolve("./Containerfile.prod", import.meta.url)
|
|
3616
4071
|
).href.replace("file://", "");
|
|
3617
|
-
await copyFile(containerFilePath,
|
|
4072
|
+
await copyFile(containerFilePath, join5(tempDir, "Containerfile"));
|
|
3618
4073
|
const contentHasher = createHash("sha256");
|
|
3619
4074
|
contentHasher.update(Buffer.from(entryPointOutputFile.text));
|
|
3620
4075
|
contentHasher.update(Buffer.from(workerOutputFile.text));
|
|
@@ -3646,8 +4101,8 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3646
4101
|
const hasher = createHash("sha256");
|
|
3647
4102
|
hasher.update(JSON.stringify(packageJsonContents));
|
|
3648
4103
|
const digest = hasher.digest("hex").slice(0, 16);
|
|
3649
|
-
const cacheDir =
|
|
3650
|
-
const cachePath =
|
|
4104
|
+
const cacheDir = join5(config.projectDir, ".trigger", "cache");
|
|
4105
|
+
const cachePath = join5(cacheDir, `${digest}.json`);
|
|
3651
4106
|
span.setAttributes({
|
|
3652
4107
|
"packageJson.digest": digest,
|
|
3653
4108
|
"cache.path": cachePath,
|
|
@@ -3656,7 +4111,7 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3656
4111
|
try {
|
|
3657
4112
|
const cachedPackageLock = await readFile2(cachePath, "utf-8");
|
|
3658
4113
|
logger.debug(`Using cached package-lock.json for ${digest}`);
|
|
3659
|
-
await writeFile2(
|
|
4114
|
+
await writeFile2(join5(projectDir, "package-lock.json"), cachedPackageLock);
|
|
3660
4115
|
span.setAttributes({
|
|
3661
4116
|
"cache.hit": true
|
|
3662
4117
|
});
|
|
@@ -3679,21 +4134,44 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3679
4134
|
cwd: projectDir,
|
|
3680
4135
|
stdio: logger.loggerLevel === "debug" ? "inherit" : "pipe"
|
|
3681
4136
|
});
|
|
3682
|
-
const packageLockContents = await readFile2(
|
|
4137
|
+
const packageLockContents = await readFile2(join5(projectDir, "package-lock.json"), "utf-8");
|
|
3683
4138
|
logger.debug(`Writing package-lock.json to cache for ${digest}`);
|
|
3684
4139
|
await mkdir(cacheDir, { recursive: true });
|
|
3685
4140
|
await writeFile2(cachePath, packageLockContents);
|
|
3686
|
-
await writeFile2(
|
|
4141
|
+
await writeFile2(join5(projectDir, "package-lock.json"), packageLockContents);
|
|
3687
4142
|
span.end();
|
|
3688
4143
|
resolvingDepsSpinner.stop("Dependencies resolved");
|
|
3689
4144
|
return true;
|
|
3690
4145
|
} catch (installError) {
|
|
3691
|
-
logger.debug(`Failed to resolve dependencies: ${JSON.stringify(installError)}`);
|
|
3692
4146
|
recordSpanException4(span, installError);
|
|
3693
4147
|
span.end();
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
4148
|
+
const parsedError = parseNpmInstallError(installError);
|
|
4149
|
+
if (typeof parsedError === "string") {
|
|
4150
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies: ${parsedError}`);
|
|
4151
|
+
} else {
|
|
4152
|
+
switch (parsedError.type) {
|
|
4153
|
+
case "package-not-found-error": {
|
|
4154
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4155
|
+
logger.log(
|
|
4156
|
+
`
|
|
4157
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4158
|
+
parsedError.packageName
|
|
4159
|
+
)} could not be found in the npm registry.`
|
|
4160
|
+
);
|
|
4161
|
+
break;
|
|
4162
|
+
}
|
|
4163
|
+
case "no-matching-version-error": {
|
|
4164
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4165
|
+
logger.log(
|
|
4166
|
+
`
|
|
4167
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4168
|
+
parsedError.packageName
|
|
4169
|
+
)} could not resolve because the version doesn't exist`
|
|
4170
|
+
);
|
|
4171
|
+
break;
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
3697
4175
|
return false;
|
|
3698
4176
|
}
|
|
3699
4177
|
}
|
|
@@ -3737,17 +4215,17 @@ async function typecheckProject(config, options) {
|
|
|
3737
4215
|
}
|
|
3738
4216
|
});
|
|
3739
4217
|
}
|
|
3740
|
-
async function gatherRequiredDependencies(imports, config,
|
|
4218
|
+
async function gatherRequiredDependencies(imports, config, project) {
|
|
3741
4219
|
const dependencies2 = {};
|
|
3742
4220
|
for (const file of imports) {
|
|
3743
|
-
if (file.kind !== "require-call" || !file.external) {
|
|
4221
|
+
if (file.kind !== "require-call" && file.kind !== "dynamic-import" || !file.external) {
|
|
3744
4222
|
continue;
|
|
3745
4223
|
}
|
|
3746
4224
|
const packageName = detectPackageNameFromImportPath(file.path);
|
|
3747
4225
|
if (dependencies2[packageName]) {
|
|
3748
4226
|
continue;
|
|
3749
4227
|
}
|
|
3750
|
-
const externalDependencyVersion = (
|
|
4228
|
+
const externalDependencyVersion = await project.resolve(packageName);
|
|
3751
4229
|
if (externalDependencyVersion) {
|
|
3752
4230
|
dependencies2[packageName] = stripWorkspaceFromVersion(externalDependencyVersion);
|
|
3753
4231
|
continue;
|
|
@@ -3767,16 +4245,17 @@ async function gatherRequiredDependencies(imports, config, projectPackageJson) {
|
|
|
3767
4245
|
dependencies2[packageParts.name] = packageParts.version;
|
|
3768
4246
|
continue;
|
|
3769
4247
|
} else {
|
|
3770
|
-
const externalDependencyVersion = {
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
}[packageName];
|
|
4248
|
+
const externalDependencyVersion = await project.resolve(packageParts.name, {
|
|
4249
|
+
allowDev: true
|
|
4250
|
+
});
|
|
3774
4251
|
if (externalDependencyVersion) {
|
|
3775
4252
|
dependencies2[packageParts.name] = externalDependencyVersion;
|
|
3776
4253
|
continue;
|
|
3777
4254
|
} else {
|
|
3778
|
-
logger.
|
|
3779
|
-
|
|
4255
|
+
logger.log(
|
|
4256
|
+
`${chalkWarning("X Warning:")} Could not find version for package ${chalkPurple(
|
|
4257
|
+
packageName
|
|
4258
|
+
)}, add a version specifier to the package name (e.g. ${packageParts.name}@latest) or add it to your project's package.json`
|
|
3780
4259
|
);
|
|
3781
4260
|
}
|
|
3782
4261
|
}
|
|
@@ -3808,9 +4287,9 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3808
4287
|
nodir: true
|
|
3809
4288
|
});
|
|
3810
4289
|
for await (const file of glob) {
|
|
3811
|
-
const relativeDestinationPath =
|
|
4290
|
+
const relativeDestinationPath = join5(
|
|
3812
4291
|
tempDir,
|
|
3813
|
-
|
|
4292
|
+
relative3(config.projectDir, file.fullpath())
|
|
3814
4293
|
);
|
|
3815
4294
|
logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
|
|
3816
4295
|
await mkdir(dirname(relativeDestinationPath), { recursive: true });
|
|
@@ -3827,7 +4306,7 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3827
4306
|
}
|
|
3828
4307
|
async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
3829
4308
|
const tmpDir = await createTempDir();
|
|
3830
|
-
const dockerConfigPath =
|
|
4309
|
+
const dockerConfigPath = join5(tmpDir, "config.json");
|
|
3831
4310
|
await writeJSONFile(dockerConfigPath, {
|
|
3832
4311
|
auths: {
|
|
3833
4312
|
[registryHost]: {
|
|
@@ -3842,7 +4321,7 @@ async function findAllEnvironmentVariableReferencesInFile(filePath) {
|
|
|
3842
4321
|
const fileContents = await readFile2(filePath, "utf-8");
|
|
3843
4322
|
return findAllEnvironmentVariableReferences(fileContents);
|
|
3844
4323
|
}
|
|
3845
|
-
var IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH"];
|
|
4324
|
+
var IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH", "DEBUG"];
|
|
3846
4325
|
function findAllEnvironmentVariableReferences(code) {
|
|
3847
4326
|
const regex = /\bprocess\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
|
|
3848
4327
|
const matches = code.matchAll(regex);
|
|
@@ -3874,7 +4353,7 @@ import { resolve as importResolve2 } from "import-meta-resolve";
|
|
|
3874
4353
|
import { render, useInput } from "ink";
|
|
3875
4354
|
import { createHash as createHash2 } from "node:crypto";
|
|
3876
4355
|
import fs7, { readFileSync as readFileSync3 } from "node:fs";
|
|
3877
|
-
import { basename, dirname as dirname3, join as
|
|
4356
|
+
import { basename, dirname as dirname3, join as join6 } from "node:path";
|
|
3878
4357
|
import pDebounce from "p-debounce";
|
|
3879
4358
|
import { WebSocket } from "partysocket";
|
|
3880
4359
|
import React, { Suspense, useEffect } from "react";
|
|
@@ -3890,6 +4369,14 @@ var UncaughtExceptionError = class extends Error {
|
|
|
3890
4369
|
this.name = "UncaughtExceptionError";
|
|
3891
4370
|
}
|
|
3892
4371
|
};
|
|
4372
|
+
var TaskMetadataParseError = class extends Error {
|
|
4373
|
+
constructor(zodIssues, tasks) {
|
|
4374
|
+
super(`Failed to parse task metadata`);
|
|
4375
|
+
this.zodIssues = zodIssues;
|
|
4376
|
+
this.tasks = tasks;
|
|
4377
|
+
this.name = "TaskMetadataParseError";
|
|
4378
|
+
}
|
|
4379
|
+
};
|
|
3893
4380
|
|
|
3894
4381
|
// src/workers/dev/backgroundWorker.ts
|
|
3895
4382
|
import {
|
|
@@ -4099,6 +4586,12 @@ var BackgroundWorker = class {
|
|
|
4099
4586
|
await installPackages(this.params.dependencies, { cwd: dirname2(this.path) });
|
|
4100
4587
|
}
|
|
4101
4588
|
let resolved = false;
|
|
4589
|
+
const cwd = dirname2(this.path);
|
|
4590
|
+
const fullEnv = {
|
|
4591
|
+
...this.params.env,
|
|
4592
|
+
...this.#readEnvVars()
|
|
4593
|
+
};
|
|
4594
|
+
logger.debug("Initializing worker", { path: this.path, cwd, fullEnv });
|
|
4102
4595
|
this.tasks = await new Promise((resolve4, reject) => {
|
|
4103
4596
|
const child = fork(this.path, {
|
|
4104
4597
|
stdio: [
|
|
@@ -4110,10 +4603,8 @@ var BackgroundWorker = class {
|
|
|
4110
4603
|
"pipe",
|
|
4111
4604
|
"ipc"
|
|
4112
4605
|
],
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
...this.#readEnvVars()
|
|
4116
|
-
}
|
|
4606
|
+
cwd,
|
|
4607
|
+
env: fullEnv
|
|
4117
4608
|
});
|
|
4118
4609
|
const timeout = setTimeout(() => {
|
|
4119
4610
|
if (resolved) {
|
|
@@ -4135,6 +4626,11 @@ var BackgroundWorker = class {
|
|
|
4135
4626
|
resolved = true;
|
|
4136
4627
|
reject(new UncaughtExceptionError(message.payload.error, message.payload.origin));
|
|
4137
4628
|
child.kill();
|
|
4629
|
+
} else if (message.type === "TASKS_FAILED_TO_PARSE") {
|
|
4630
|
+
clearTimeout(timeout);
|
|
4631
|
+
resolved = true;
|
|
4632
|
+
reject(new TaskMetadataParseError(message.payload.zodIssues, message.payload.tasks));
|
|
4633
|
+
child.kill();
|
|
4138
4634
|
}
|
|
4139
4635
|
});
|
|
4140
4636
|
child.on("exit", (code) => {
|
|
@@ -4160,7 +4656,7 @@ var BackgroundWorker = class {
|
|
|
4160
4656
|
}
|
|
4161
4657
|
if (!this._taskRunProcesses.has(payload.execution.run.id)) {
|
|
4162
4658
|
const taskRunProcess = new TaskRunProcess(
|
|
4163
|
-
payload.execution
|
|
4659
|
+
payload.execution,
|
|
4164
4660
|
this.path,
|
|
4165
4661
|
{
|
|
4166
4662
|
...this.params.env,
|
|
@@ -4270,8 +4766,8 @@ var BackgroundWorker = class {
|
|
|
4270
4766
|
}
|
|
4271
4767
|
};
|
|
4272
4768
|
var TaskRunProcess = class {
|
|
4273
|
-
constructor(
|
|
4274
|
-
this.
|
|
4769
|
+
constructor(execution, path6, env, metadata, worker) {
|
|
4770
|
+
this.execution = execution;
|
|
4275
4771
|
this.path = path6;
|
|
4276
4772
|
this.env = env;
|
|
4277
4773
|
this.metadata = metadata;
|
|
@@ -4302,9 +4798,20 @@ var TaskRunProcess = class {
|
|
|
4302
4798
|
await this.cleanup(true);
|
|
4303
4799
|
}
|
|
4304
4800
|
async initialize() {
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4801
|
+
const fullEnv = {
|
|
4802
|
+
...this.execution.run.isTest ? { TRIGGER_LOG_LEVEL: "debug" } : {},
|
|
4803
|
+
...this.env,
|
|
4804
|
+
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
4805
|
+
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
4806
|
+
}),
|
|
4807
|
+
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
4808
|
+
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
4809
|
+
};
|
|
4810
|
+
const cwd = dirname2(this.path);
|
|
4811
|
+
logger.debug(`[${this.execution.run.id}] initializing task run process`, {
|
|
4812
|
+
env: fullEnv,
|
|
4813
|
+
path: this.path,
|
|
4814
|
+
cwd
|
|
4308
4815
|
});
|
|
4309
4816
|
this._child = fork(this.path, {
|
|
4310
4817
|
stdio: [
|
|
@@ -4316,15 +4823,8 @@ var TaskRunProcess = class {
|
|
|
4316
4823
|
"pipe",
|
|
4317
4824
|
"ipc"
|
|
4318
4825
|
],
|
|
4319
|
-
cwd
|
|
4320
|
-
env:
|
|
4321
|
-
...this.env,
|
|
4322
|
-
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
4323
|
-
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
4324
|
-
}),
|
|
4325
|
-
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
4326
|
-
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
4327
|
-
},
|
|
4826
|
+
cwd,
|
|
4827
|
+
env: fullEnv,
|
|
4328
4828
|
execArgv: this.worker.debuggerOn ? ["--inspect-brk", "--trace-uncaught", "--no-warnings=ExperimentalWarning"] : ["--trace-uncaught", "--no-warnings=ExperimentalWarning"]
|
|
4329
4829
|
});
|
|
4330
4830
|
this._child.on("message", this.#handleMessage.bind(this));
|
|
@@ -4336,7 +4836,7 @@ var TaskRunProcess = class {
|
|
|
4336
4836
|
if (kill && this._isBeingKilled) {
|
|
4337
4837
|
return;
|
|
4338
4838
|
}
|
|
4339
|
-
logger.debug(`[${this.
|
|
4839
|
+
logger.debug(`[${this.execution.run.id}] cleaning up task run process`, { kill });
|
|
4340
4840
|
await this._sender.send("CLEANUP", {
|
|
4341
4841
|
flush: true,
|
|
4342
4842
|
kill
|
|
@@ -4367,10 +4867,13 @@ var TaskRunProcess = class {
|
|
|
4367
4867
|
if (!completion.ok && typeof completion.retry !== "undefined") {
|
|
4368
4868
|
return;
|
|
4369
4869
|
}
|
|
4370
|
-
if (execution.run.id === this.
|
|
4870
|
+
if (execution.run.id === this.execution.run.id) {
|
|
4371
4871
|
return;
|
|
4372
4872
|
}
|
|
4373
|
-
logger.debug(`[${this.
|
|
4873
|
+
logger.debug(`[${this.execution.run.id}] task run completed notification`, {
|
|
4874
|
+
completion,
|
|
4875
|
+
execution
|
|
4876
|
+
});
|
|
4374
4877
|
this._sender.send("TASK_RUN_COMPLETED_NOTIFICATION", {
|
|
4375
4878
|
completion,
|
|
4376
4879
|
execution
|
|
@@ -4408,7 +4911,7 @@ var TaskRunProcess = class {
|
|
|
4408
4911
|
}
|
|
4409
4912
|
}
|
|
4410
4913
|
async #handleExit(code) {
|
|
4411
|
-
logger.debug(`[${this.
|
|
4914
|
+
logger.debug(`[${this.execution.run.id}] task run process exiting`, { code });
|
|
4412
4915
|
for (const [id, status] of this._attemptStatuses.entries()) {
|
|
4413
4916
|
if (status === "PENDING") {
|
|
4414
4917
|
this._attemptStatuses.set(id, "REJECTED");
|
|
@@ -4455,7 +4958,27 @@ var TaskRunProcess = class {
|
|
|
4455
4958
|
}
|
|
4456
4959
|
};
|
|
4457
4960
|
|
|
4961
|
+
// src/utilities/runtimeCheck.ts
|
|
4962
|
+
function runtimeCheck(minimumMajor, minimumMinor) {
|
|
4963
|
+
if (typeof process === "undefined") {
|
|
4964
|
+
throw "The dev CLI can only be run in a Node.js compatible environment";
|
|
4965
|
+
}
|
|
4966
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
4967
|
+
const isBun = typeof process.versions.bun === "string";
|
|
4968
|
+
if (major < minimumMajor || major === minimumMajor && minor < minimumMinor) {
|
|
4969
|
+
if (isBun) {
|
|
4970
|
+
throw `The dev CLI requires at least Node.js ${minimumMajor}.${minimumMinor}. You are running Bun ${process.versions.bun}, which is compatible with Node.js ${process.versions.node}`;
|
|
4971
|
+
} else {
|
|
4972
|
+
throw `The dev CLI requires at least Node.js ${minimumMajor}.${minimumMinor}. You are running Node.js ${process.versions.node}`;
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
logger.debug(
|
|
4976
|
+
`Node.js version: ${process.versions.node}${isBun ? ` (Bun ${process.versions.bun})` : ""}`
|
|
4977
|
+
);
|
|
4978
|
+
}
|
|
4979
|
+
|
|
4458
4980
|
// src/commands/dev.tsx
|
|
4981
|
+
import { findUp as findUp3, pathExists as pathExists2 } from "find-up";
|
|
4459
4982
|
var apiClient;
|
|
4460
4983
|
var DevCommandOptions = CommonCommandOptions.extend({
|
|
4461
4984
|
debugger: z5.boolean().default(false),
|
|
@@ -4465,7 +4988,7 @@ var DevCommandOptions = CommonCommandOptions.extend({
|
|
|
4465
4988
|
});
|
|
4466
4989
|
function configureDevCommand(program2) {
|
|
4467
4990
|
return commonOptions(
|
|
4468
|
-
program2.command("dev").description("Run your Trigger.dev tasks locally").argument("[path]", "The path to the project", ".").option("-c, --config <config file>", "The name of the config file, found at [path]").option(
|
|
4991
|
+
program2.command("dev").description("Run your Trigger.dev tasks locally").argument("[path]", "The path to the project", ".").option("-c, --config <config file>", "The name of the config file, found at [path].").option(
|
|
4469
4992
|
"-p, --project-ref <project ref>",
|
|
4470
4993
|
"The project ref. Required if there is no config file."
|
|
4471
4994
|
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging")
|
|
@@ -4475,22 +4998,35 @@ function configureDevCommand(program2) {
|
|
|
4475
4998
|
});
|
|
4476
4999
|
});
|
|
4477
5000
|
}
|
|
5001
|
+
var MINIMUM_NODE_MAJOR = 18;
|
|
5002
|
+
var MINIMUM_NODE_MINOR = 16;
|
|
4478
5003
|
async function devCommand(dir, options) {
|
|
5004
|
+
try {
|
|
5005
|
+
runtimeCheck(MINIMUM_NODE_MAJOR, MINIMUM_NODE_MINOR);
|
|
5006
|
+
} catch (e) {
|
|
5007
|
+
logger.log(`${chalkError("X Error:")} ${e}`);
|
|
5008
|
+
process.exitCode = 1;
|
|
5009
|
+
return;
|
|
5010
|
+
}
|
|
4479
5011
|
const authorization = await isLoggedIn(options.profile);
|
|
4480
5012
|
if (!authorization.ok) {
|
|
4481
5013
|
if (authorization.error === "fetch failed") {
|
|
4482
|
-
logger.
|
|
5014
|
+
logger.log(
|
|
5015
|
+
`${chalkError(
|
|
5016
|
+
"X Error:"
|
|
5017
|
+
)} Connecting to the server failed. Please check your internet connection or contact eric@trigger.dev for help.`
|
|
5018
|
+
);
|
|
4483
5019
|
} else {
|
|
4484
|
-
logger.
|
|
5020
|
+
logger.log(`${chalkError("X Error:")} You must login first. Use the \`login\` CLI command.`);
|
|
4485
5021
|
}
|
|
4486
5022
|
process.exitCode = 1;
|
|
4487
5023
|
return;
|
|
4488
5024
|
}
|
|
4489
|
-
const devInstance = await startDev(dir, options, authorization.auth);
|
|
5025
|
+
const devInstance = await startDev(dir, options, authorization.auth, authorization.dashboardUrl);
|
|
4490
5026
|
const { waitUntilExit } = devInstance.devReactElement;
|
|
4491
5027
|
await waitUntilExit();
|
|
4492
5028
|
}
|
|
4493
|
-
async function startDev(dir, options, authorization) {
|
|
5029
|
+
async function startDev(dir, options, authorization, dashboardUrl) {
|
|
4494
5030
|
let rerender;
|
|
4495
5031
|
try {
|
|
4496
5032
|
if (options.logLevel) {
|
|
@@ -4528,6 +5064,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4528
5064
|
return /* @__PURE__ */ React.createElement(
|
|
4529
5065
|
DevUI,
|
|
4530
5066
|
{
|
|
5067
|
+
dashboardUrl,
|
|
4531
5068
|
config: configParam,
|
|
4532
5069
|
apiUrl,
|
|
4533
5070
|
apiKey: devEnv.data.apiKey,
|
|
@@ -4559,6 +5096,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4559
5096
|
}
|
|
4560
5097
|
function useDev({
|
|
4561
5098
|
config,
|
|
5099
|
+
dashboardUrl,
|
|
4562
5100
|
apiUrl,
|
|
4563
5101
|
apiKey,
|
|
4564
5102
|
environmentClient,
|
|
@@ -4588,7 +5126,7 @@ function useDev({
|
|
|
4588
5126
|
}
|
|
4589
5127
|
});
|
|
4590
5128
|
const backgroundWorkerCoordinator = new BackgroundWorkerCoordinator(
|
|
4591
|
-
`${
|
|
5129
|
+
`${dashboardUrl}/projects/v3/${config.project}`
|
|
4592
5130
|
);
|
|
4593
5131
|
websocket.addEventListener("open", async (event) => {
|
|
4594
5132
|
});
|
|
@@ -4708,7 +5246,12 @@ function useDev({
|
|
|
4708
5246
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
4709
5247
|
},
|
|
4710
5248
|
plugins: [
|
|
4711
|
-
|
|
5249
|
+
bundleTriggerDevCore("workerFacade", config.tsconfigPath),
|
|
5250
|
+
bundleDependenciesPlugin(
|
|
5251
|
+
"workerFacade",
|
|
5252
|
+
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
|
|
5253
|
+
config.tsconfigPath
|
|
5254
|
+
),
|
|
4712
5255
|
workerSetupImportConfigPlugin(configPath),
|
|
4713
5256
|
{
|
|
4714
5257
|
name: "trigger.dev v3",
|
|
@@ -4723,19 +5266,19 @@ function useDev({
|
|
|
4723
5266
|
if (!firstBuild) {
|
|
4724
5267
|
logger.log(chalkGrey("\u25CB Building background worker\u2026"));
|
|
4725
5268
|
}
|
|
4726
|
-
const metaOutputKey =
|
|
5269
|
+
const metaOutputKey = join6("out", `stdin.js`);
|
|
4727
5270
|
const metaOutput = result.metafile.outputs[metaOutputKey];
|
|
4728
5271
|
if (!metaOutput) {
|
|
4729
5272
|
throw new Error(`Could not find metafile`);
|
|
4730
5273
|
}
|
|
4731
|
-
const outputFileKey =
|
|
5274
|
+
const outputFileKey = join6(config.projectDir, metaOutputKey);
|
|
4732
5275
|
const outputFile = result.outputFiles.find((file) => file.path === outputFileKey);
|
|
4733
5276
|
if (!outputFile) {
|
|
4734
5277
|
throw new Error(
|
|
4735
5278
|
`Could not find output file for entry point ${metaOutput.entryPoint}`
|
|
4736
5279
|
);
|
|
4737
5280
|
}
|
|
4738
|
-
const sourceMapFileKey =
|
|
5281
|
+
const sourceMapFileKey = join6(config.projectDir, `${metaOutputKey}.map`);
|
|
4739
5282
|
const sourceMapFile = result.outputFiles.find(
|
|
4740
5283
|
(file) => file.path === sourceMapFileKey
|
|
4741
5284
|
);
|
|
@@ -4746,7 +5289,7 @@ function useDev({
|
|
|
4746
5289
|
logger.log(chalkGrey("\u25CB No changes detected, skipping build\u2026"));
|
|
4747
5290
|
return;
|
|
4748
5291
|
}
|
|
4749
|
-
const fullPath =
|
|
5292
|
+
const fullPath = join6(config.projectDir, ".trigger", `${contentHash}.js`);
|
|
4750
5293
|
const sourceMapPath = `${fullPath}.map`;
|
|
4751
5294
|
const outputFileWithSourceMap = `${outputFile.text}
|
|
4752
5295
|
//# sourceMappingURL=${basename(sourceMapPath)}`;
|
|
@@ -4759,7 +5302,7 @@ function useDev({
|
|
|
4759
5302
|
await fs7.promises.writeFile(sourceMapPath2, sourceMapFile.text);
|
|
4760
5303
|
}
|
|
4761
5304
|
const environmentVariablesResponse = await environmentClient.getEnvironmentVariables(config.project);
|
|
4762
|
-
const processEnv = gatherProcessEnv();
|
|
5305
|
+
const processEnv = await gatherProcessEnv();
|
|
4763
5306
|
const backgroundWorker = new BackgroundWorker(fullPath, {
|
|
4764
5307
|
projectConfig: config,
|
|
4765
5308
|
dependencies: dependencies2,
|
|
@@ -4827,17 +5370,52 @@ function useDev({
|
|
|
4827
5370
|
backgroundWorker
|
|
4828
5371
|
);
|
|
4829
5372
|
} catch (e) {
|
|
4830
|
-
if (e instanceof
|
|
5373
|
+
if (e instanceof TaskMetadataParseError) {
|
|
5374
|
+
logTaskMetadataParseError(e.zodIssues, e.tasks);
|
|
5375
|
+
return;
|
|
5376
|
+
} else if (e instanceof UncaughtExceptionError) {
|
|
5377
|
+
const parsedBuildError = parseBuildErrorStack(e.originalError);
|
|
5378
|
+
if (parsedBuildError && typeof parsedBuildError !== "string") {
|
|
5379
|
+
logESMRequireError(
|
|
5380
|
+
parsedBuildError,
|
|
5381
|
+
configPath ? { status: "file", path: configPath, config } : { status: "in-memory", config }
|
|
5382
|
+
);
|
|
5383
|
+
return;
|
|
5384
|
+
} else {
|
|
5385
|
+
}
|
|
4831
5386
|
if (e.originalError.stack) {
|
|
4832
|
-
logger.
|
|
5387
|
+
logger.log(
|
|
5388
|
+
`${chalkError("X Error:")} Worker failed to start`,
|
|
5389
|
+
e.originalError.stack
|
|
5390
|
+
);
|
|
4833
5391
|
}
|
|
4834
5392
|
return;
|
|
4835
5393
|
}
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
5394
|
+
const parsedError = parseNpmInstallError(e);
|
|
5395
|
+
if (typeof parsedError === "string") {
|
|
5396
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
5397
|
+
} else {
|
|
5398
|
+
switch (parsedError.type) {
|
|
5399
|
+
case "package-not-found-error": {
|
|
5400
|
+
logger.log(
|
|
5401
|
+
`
|
|
5402
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
5403
|
+
parsedError.packageName
|
|
5404
|
+
)} could not be found in the npm registry.`
|
|
5405
|
+
);
|
|
5406
|
+
break;
|
|
5407
|
+
}
|
|
5408
|
+
case "no-matching-version-error": {
|
|
5409
|
+
logger.log(
|
|
5410
|
+
`
|
|
5411
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
5412
|
+
parsedError.packageName
|
|
5413
|
+
)} could not resolve because the version doesn't exist`
|
|
5414
|
+
);
|
|
5415
|
+
break;
|
|
5416
|
+
}
|
|
5417
|
+
}
|
|
4839
5418
|
}
|
|
4840
|
-
logger.error(`Background worker failed to start: ${e}`);
|
|
4841
5419
|
}
|
|
4842
5420
|
});
|
|
4843
5421
|
}
|
|
@@ -4901,8 +5479,11 @@ function WebsocketFactory(apiKey) {
|
|
|
4901
5479
|
}
|
|
4902
5480
|
async function gatherRequiredDependencies2(outputMeta, config) {
|
|
4903
5481
|
const dependencies2 = {};
|
|
5482
|
+
logger.debug("Gathering required dependencies from imports", {
|
|
5483
|
+
imports: outputMeta.imports
|
|
5484
|
+
});
|
|
4904
5485
|
for (const file of outputMeta.imports) {
|
|
4905
|
-
if (file.kind !== "require-call" || !file.external) {
|
|
5486
|
+
if (file.kind !== "require-call" && file.kind !== "dynamic-import" || !file.external) {
|
|
4906
5487
|
continue;
|
|
4907
5488
|
}
|
|
4908
5489
|
const packageName = detectPackageNameFromImportPath(file.path);
|
|
@@ -4915,7 +5496,7 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4915
5496
|
}
|
|
4916
5497
|
}
|
|
4917
5498
|
if (config.additionalPackages) {
|
|
4918
|
-
const projectPackageJson = await readJSONFile(
|
|
5499
|
+
const projectPackageJson = await readJSONFile(join6(config.projectDir, "package.json"));
|
|
4919
5500
|
for (const packageName of config.additionalPackages) {
|
|
4920
5501
|
if (dependencies2[packageName]) {
|
|
4921
5502
|
continue;
|
|
@@ -4945,16 +5526,14 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4945
5526
|
function createDuplicateTaskIdOutputErrorMessage(duplicateTaskIds, taskResources) {
|
|
4946
5527
|
const duplicateTable = duplicateTaskIds.map((id) => {
|
|
4947
5528
|
const tasks = taskResources.filter((task) => task.id === id);
|
|
4948
|
-
return `
|
|
4949
|
-
${tasks.map((task) => `${task.filePath} -> ${task.exportName}`).join("\n")}`;
|
|
4950
|
-
}).join("\n\n");
|
|
4951
|
-
return `Duplicate task ids detected:
|
|
5529
|
+
return `
|
|
4952
5530
|
|
|
4953
|
-
${
|
|
4954
|
-
|
|
4955
|
-
|
|
5531
|
+
${chalkTask(id)} was found in:${tasks.map((task) => `
|
|
5532
|
+
${task.filePath} -> ${task.exportName}`).join("")}`;
|
|
5533
|
+
}).join("");
|
|
5534
|
+
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
|
|
4956
5535
|
}
|
|
4957
|
-
function gatherProcessEnv() {
|
|
5536
|
+
async function gatherProcessEnv() {
|
|
4958
5537
|
const env = {
|
|
4959
5538
|
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
4960
5539
|
PATH: process.env.PATH,
|
|
@@ -4965,12 +5544,37 @@ function gatherProcessEnv() {
|
|
|
4965
5544
|
NVM_BIN: process.env.NVM_BIN,
|
|
4966
5545
|
LANG: process.env.LANG,
|
|
4967
5546
|
TERM: process.env.TERM,
|
|
4968
|
-
NODE_PATH: process.env.NODE_PATH,
|
|
5547
|
+
NODE_PATH: await amendNodePathWithPnpmNodeModules(process.env.NODE_PATH),
|
|
4969
5548
|
HOME: process.env.HOME,
|
|
4970
5549
|
BUN_INSTALL: process.env.BUN_INSTALL
|
|
4971
5550
|
};
|
|
4972
5551
|
return Object.fromEntries(Object.entries(env).filter(([key, value]) => value !== void 0));
|
|
4973
5552
|
}
|
|
5553
|
+
async function amendNodePathWithPnpmNodeModules(nodePath) {
|
|
5554
|
+
const pnpmModulesPath = await findPnpmNodeModulesPath();
|
|
5555
|
+
if (!pnpmModulesPath) {
|
|
5556
|
+
return nodePath;
|
|
5557
|
+
}
|
|
5558
|
+
if (nodePath) {
|
|
5559
|
+
if (nodePath.includes(pnpmModulesPath)) {
|
|
5560
|
+
return nodePath;
|
|
5561
|
+
}
|
|
5562
|
+
return `${nodePath}:${pnpmModulesPath}`;
|
|
5563
|
+
}
|
|
5564
|
+
return pnpmModulesPath;
|
|
5565
|
+
}
|
|
5566
|
+
async function findPnpmNodeModulesPath() {
|
|
5567
|
+
return await findUp3(
|
|
5568
|
+
async (directory) => {
|
|
5569
|
+
const pnpmModules = join6(directory, "node_modules", ".pnpm", "node_modules");
|
|
5570
|
+
const hasPnpmNodeModules = await pathExists2(pnpmModules);
|
|
5571
|
+
if (hasPnpmNodeModules) {
|
|
5572
|
+
return pnpmModules;
|
|
5573
|
+
}
|
|
5574
|
+
},
|
|
5575
|
+
{ type: "directory" }
|
|
5576
|
+
);
|
|
5577
|
+
}
|
|
4974
5578
|
|
|
4975
5579
|
// src/commands/init.ts
|
|
4976
5580
|
import { intro as intro4, isCancel, log as log3, outro as outro4, select as select2, spinner as spinner5, text } from "@clack/prompts";
|
|
@@ -4979,11 +5583,11 @@ import {
|
|
|
4979
5583
|
flattenAttributes as flattenAttributes3,
|
|
4980
5584
|
recordSpanException as recordSpanException5
|
|
4981
5585
|
} from "@trigger.dev/core/v3";
|
|
4982
|
-
import
|
|
5586
|
+
import chalk6 from "chalk";
|
|
4983
5587
|
import { execa as execa3 } from "execa";
|
|
4984
5588
|
import { applyEdits, modify } from "jsonc-parser";
|
|
4985
5589
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
4986
|
-
import { join as
|
|
5590
|
+
import { join as join7, relative as relative4, resolve as resolve3 } from "node:path";
|
|
4987
5591
|
import terminalLink3 from "terminal-link";
|
|
4988
5592
|
import { z as z6 } from "zod";
|
|
4989
5593
|
|
|
@@ -5028,45 +5632,6 @@ function replaceAll(input, replacements) {
|
|
|
5028
5632
|
return output;
|
|
5029
5633
|
}
|
|
5030
5634
|
|
|
5031
|
-
// src/utilities/getUserPackageManager.ts
|
|
5032
|
-
import pathModule2 from "path";
|
|
5033
|
-
async function getUserPackageManager(path6) {
|
|
5034
|
-
try {
|
|
5035
|
-
return await detectPackageManagerFromArtifacts(path6);
|
|
5036
|
-
} catch (error) {
|
|
5037
|
-
return detectPackageManagerFromCurrentCommand();
|
|
5038
|
-
}
|
|
5039
|
-
}
|
|
5040
|
-
function detectPackageManagerFromCurrentCommand() {
|
|
5041
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
5042
|
-
if (userAgent) {
|
|
5043
|
-
if (userAgent.startsWith("yarn")) {
|
|
5044
|
-
return "yarn";
|
|
5045
|
-
} else if (userAgent.startsWith("pnpm")) {
|
|
5046
|
-
return "pnpm";
|
|
5047
|
-
} else {
|
|
5048
|
-
return "npm";
|
|
5049
|
-
}
|
|
5050
|
-
} else {
|
|
5051
|
-
return "npm";
|
|
5052
|
-
}
|
|
5053
|
-
}
|
|
5054
|
-
async function detectPackageManagerFromArtifacts(path6) {
|
|
5055
|
-
const packageFiles = [
|
|
5056
|
-
{ name: "yarn.lock", pm: "yarn" },
|
|
5057
|
-
{ name: "pnpm-lock.yaml", pm: "pnpm" },
|
|
5058
|
-
{ name: "package-lock.json", pm: "npm" },
|
|
5059
|
-
{ name: "npm-shrinkwrap.json", pm: "npm" }
|
|
5060
|
-
];
|
|
5061
|
-
for (const { name, pm } of packageFiles) {
|
|
5062
|
-
const exists = await pathExists(pathModule2.join(path6, name));
|
|
5063
|
-
if (exists) {
|
|
5064
|
-
return pm;
|
|
5065
|
-
}
|
|
5066
|
-
}
|
|
5067
|
-
throw new Error("Could not detect package manager from artifacts");
|
|
5068
|
-
}
|
|
5069
|
-
|
|
5070
5635
|
// src/utilities/resolveInternalFilePath.ts
|
|
5071
5636
|
import { resolve as importResolve3 } from "import-meta-resolve";
|
|
5072
5637
|
function resolveInternalFilePath(filePath) {
|
|
@@ -5162,7 +5727,7 @@ async function _initCommand(dir, options) {
|
|
|
5162
5727
|
log3.success("Successfully initialized project for Trigger.dev v3 \u{1FAE1}");
|
|
5163
5728
|
log3.info("Next steps:");
|
|
5164
5729
|
log3.info(
|
|
5165
|
-
` 1. To start developing, run ${
|
|
5730
|
+
` 1. To start developing, run ${chalk6.green(
|
|
5166
5731
|
`npx trigger.dev@${options.tag} dev`
|
|
5167
5732
|
)} in your project directory`
|
|
5168
5733
|
);
|
|
@@ -5177,7 +5742,7 @@ async function _initCommand(dir, options) {
|
|
|
5177
5742
|
` 4. Need help? Join our ${terminalLink3(
|
|
5178
5743
|
"Discord community",
|
|
5179
5744
|
"https://trigger.dev/discord"
|
|
5180
|
-
)} or email us at ${
|
|
5745
|
+
)} or email us at ${chalk6.cyan("help@trigger.dev")}`
|
|
5181
5746
|
);
|
|
5182
5747
|
outro4(`Project initialized successfully. Happy coding!`);
|
|
5183
5748
|
}
|
|
@@ -5219,19 +5784,19 @@ async function createTriggerDir(dir, options) {
|
|
|
5219
5784
|
"cli.example": example
|
|
5220
5785
|
});
|
|
5221
5786
|
if (example === "none") {
|
|
5222
|
-
await createFile(
|
|
5787
|
+
await createFile(join7(triggerDir, ".gitkeep"), "");
|
|
5223
5788
|
log3.step(`Created directory at ${location}`);
|
|
5224
5789
|
span.end();
|
|
5225
5790
|
return { location, isCustomValue: location !== defaultValue };
|
|
5226
5791
|
}
|
|
5227
5792
|
const exampleFile = resolveInternalFilePath(`./templates/examples/${example}.ts.template`);
|
|
5228
|
-
const outputPath =
|
|
5793
|
+
const outputPath = join7(triggerDir, "example.ts");
|
|
5229
5794
|
await createFileFromTemplate({
|
|
5230
5795
|
templatePath: exampleFile,
|
|
5231
5796
|
outputPath,
|
|
5232
5797
|
replacements: {}
|
|
5233
5798
|
});
|
|
5234
|
-
const relativeOutputPath =
|
|
5799
|
+
const relativeOutputPath = relative4(process.cwd(), outputPath);
|
|
5235
5800
|
log3.step(`Created example file at ${relativeOutputPath}`);
|
|
5236
5801
|
span.end();
|
|
5237
5802
|
return { location, isCustomValue: location !== defaultValue };
|
|
@@ -5248,7 +5813,7 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5248
5813
|
return await tracer.startActiveSpan("gitIgnoreDotTriggerDir", async (span) => {
|
|
5249
5814
|
try {
|
|
5250
5815
|
const projectDir = resolve3(process.cwd(), dir);
|
|
5251
|
-
const gitIgnorePath =
|
|
5816
|
+
const gitIgnorePath = join7(projectDir, ".gitignore");
|
|
5252
5817
|
span.setAttributes({
|
|
5253
5818
|
"cli.projectDir": projectDir,
|
|
5254
5819
|
"cli.gitIgnorePath": gitIgnorePath
|
|
@@ -5282,7 +5847,7 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5282
5847
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5283
5848
|
try {
|
|
5284
5849
|
const projectDir = resolve3(process.cwd(), dir);
|
|
5285
|
-
const tsconfigPath =
|
|
5850
|
+
const tsconfigPath = join7(projectDir, "tsconfig.json");
|
|
5286
5851
|
span.setAttributes({
|
|
5287
5852
|
"cli.projectDir": projectDir,
|
|
5288
5853
|
"cli.tsconfigPath": tsconfigPath
|
|
@@ -5369,7 +5934,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5369
5934
|
spnnr.start("Creating config file");
|
|
5370
5935
|
const projectDir = resolve3(process.cwd(), dir);
|
|
5371
5936
|
const templatePath = resolveInternalFilePath("./templates/trigger.config.ts.template");
|
|
5372
|
-
const outputPath =
|
|
5937
|
+
const outputPath = join7(projectDir, "trigger.config.ts");
|
|
5373
5938
|
span.setAttributes({
|
|
5374
5939
|
"cli.projectDir": projectDir,
|
|
5375
5940
|
"cli.templatePath": templatePath,
|
|
@@ -5385,7 +5950,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5385
5950
|
outputPath,
|
|
5386
5951
|
override: options.overrideConfig
|
|
5387
5952
|
});
|
|
5388
|
-
const relativePathToOutput =
|
|
5953
|
+
const relativePathToOutput = relative4(process.cwd(), outputPath);
|
|
5389
5954
|
spnnr.stop(
|
|
5390
5955
|
result.success ? `Config file created at ${relativePathToOutput}` : `Failed to create config file: ${result.error}`
|
|
5391
5956
|
);
|
|
@@ -5467,12 +6032,14 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5467
6032
|
// src/commands/logout.ts
|
|
5468
6033
|
var LogoutCommandOptions = CommonCommandOptions;
|
|
5469
6034
|
function configureLogoutCommand(program2) {
|
|
5470
|
-
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
5471
|
-
|
|
5472
|
-
await
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
6035
|
+
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
6036
|
+
async (options) => {
|
|
6037
|
+
await handleTelemetry(async () => {
|
|
6038
|
+
await printInitialBanner(false);
|
|
6039
|
+
await logoutCommand(options);
|
|
6040
|
+
});
|
|
6041
|
+
}
|
|
6042
|
+
);
|
|
5476
6043
|
}
|
|
5477
6044
|
async function logoutCommand(options) {
|
|
5478
6045
|
return await wrapCommandAction("logoutCommand", LogoutCommandOptions, options, async (opts) => {
|
|
@@ -5482,11 +6049,46 @@ async function logoutCommand(options) {
|
|
|
5482
6049
|
async function logout(options) {
|
|
5483
6050
|
const config = readAuthConfigProfile(options.profile);
|
|
5484
6051
|
if (!config?.accessToken) {
|
|
5485
|
-
logger.info(`You are already logged out [${options.profile
|
|
6052
|
+
logger.info(`You are already logged out [${options.profile}]`);
|
|
6053
|
+
return;
|
|
6054
|
+
}
|
|
6055
|
+
deleteAuthConfigProfile(options.profile);
|
|
6056
|
+
logger.info(`Logged out of Trigger.dev [${options.profile}]`);
|
|
6057
|
+
}
|
|
6058
|
+
|
|
6059
|
+
// src/commands/list-profiles.ts
|
|
6060
|
+
import { log as log4, outro as outro5 } from "@clack/prompts";
|
|
6061
|
+
var ListProfilesOptions = CommonCommandOptions;
|
|
6062
|
+
function configureListProfilesCommand(program2) {
|
|
6063
|
+
return program2.command("list-profiles").description("List all of your CLI profiles").option(
|
|
6064
|
+
"-l, --log-level <level>",
|
|
6065
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
6066
|
+
"log"
|
|
6067
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (options) => {
|
|
6068
|
+
await handleTelemetry(async () => {
|
|
6069
|
+
await printInitialBanner(true);
|
|
6070
|
+
await listProfilesCommand(options);
|
|
6071
|
+
});
|
|
6072
|
+
});
|
|
6073
|
+
}
|
|
6074
|
+
async function listProfilesCommand(options) {
|
|
6075
|
+
return await wrapCommandAction("listProfiles", ListProfilesOptions, options, async (opts) => {
|
|
6076
|
+
return await listProfiles(opts);
|
|
6077
|
+
});
|
|
6078
|
+
}
|
|
6079
|
+
async function listProfiles(options) {
|
|
6080
|
+
const authConfig = readAuthConfigFile();
|
|
6081
|
+
if (!authConfig) {
|
|
6082
|
+
logger.info("No profiles found");
|
|
5486
6083
|
return;
|
|
5487
6084
|
}
|
|
5488
|
-
|
|
5489
|
-
|
|
6085
|
+
const profiles = Object.keys(authConfig);
|
|
6086
|
+
log4.message("Profiles:");
|
|
6087
|
+
for (const profile of profiles) {
|
|
6088
|
+
const profileConfig = authConfig[profile];
|
|
6089
|
+
log4.info(`${profile}${profileConfig?.apiUrl ? ` - ${chalkGrey(profileConfig.apiUrl)}` : ""}`);
|
|
6090
|
+
}
|
|
6091
|
+
outro5("Retrieve account info by running whoami --profile <profile>");
|
|
5490
6092
|
}
|
|
5491
6093
|
|
|
5492
6094
|
// src/cli/index.ts
|
|
@@ -5498,6 +6100,7 @@ configureDevCommand(program);
|
|
|
5498
6100
|
configureDeployCommand(program);
|
|
5499
6101
|
configureWhoamiCommand(program);
|
|
5500
6102
|
configureLogoutCommand(program);
|
|
6103
|
+
configureListProfilesCommand(program);
|
|
5501
6104
|
|
|
5502
6105
|
// src/index.ts
|
|
5503
6106
|
var main = async () => {
|