trigger.dev 3.0.0-beta.3 → 3.0.0-beta.30
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 +17 -4
- package/dist/index.js +2008 -671
- package/dist/index.js.map +1 -1
- package/dist/templates/trigger.config.ts.template +2 -1
- package/dist/workers/dev/worker-facade.js +51 -54
- package/dist/workers/dev/worker-setup.js +8 -15
- package/dist/workers/prod/entry-point.js +177 -78
- package/dist/workers/prod/worker-facade.js +63 -55
- package/dist/workers/prod/worker-setup.js +5 -20
- package/package.json +9 -14
package/dist/index.js
CHANGED
|
@@ -57,7 +57,7 @@ var require_XDGAppPaths = __commonJS({
|
|
|
57
57
|
return typeof t;
|
|
58
58
|
}
|
|
59
59
|
function Adapt(adapter_) {
|
|
60
|
-
var meta = adapter_.meta,
|
|
60
|
+
var meta = adapter_.meta, path7 = adapter_.path, xdg = adapter_.xdg;
|
|
61
61
|
var XDGAppPaths_ = /* @__PURE__ */ function() {
|
|
62
62
|
function XDGAppPaths_2(options_) {
|
|
63
63
|
if (options_ === void 0) {
|
|
@@ -79,7 +79,7 @@ var require_XDGAppPaths = __commonJS({
|
|
|
79
79
|
meta.mainFilename()
|
|
80
80
|
];
|
|
81
81
|
var nameFallback = "$eval";
|
|
82
|
-
var name =
|
|
82
|
+
var name = path7.parse(((_c = namePriorityList.find(function(e) {
|
|
83
83
|
return isString(e);
|
|
84
84
|
})) !== null && _c !== void 0 ? _c : nameFallback) + suffix).name;
|
|
85
85
|
XDGAppPaths.$name = function $name() {
|
|
@@ -98,28 +98,28 @@ var require_XDGAppPaths = __commonJS({
|
|
|
98
98
|
return isIsolated(dirOptions) ? name : "";
|
|
99
99
|
}
|
|
100
100
|
XDGAppPaths.cache = function cache(dirOptions) {
|
|
101
|
-
return
|
|
101
|
+
return path7.join(xdg.cache(), finalPathSegment(dirOptions));
|
|
102
102
|
};
|
|
103
103
|
XDGAppPaths.config = function config(dirOptions) {
|
|
104
|
-
return
|
|
104
|
+
return path7.join(xdg.config(), finalPathSegment(dirOptions));
|
|
105
105
|
};
|
|
106
106
|
XDGAppPaths.data = function data(dirOptions) {
|
|
107
|
-
return
|
|
107
|
+
return path7.join(xdg.data(), finalPathSegment(dirOptions));
|
|
108
108
|
};
|
|
109
109
|
XDGAppPaths.runtime = function runtime(dirOptions) {
|
|
110
|
-
return xdg.runtime() ?
|
|
110
|
+
return xdg.runtime() ? path7.join(xdg.runtime(), finalPathSegment(dirOptions)) : void 0;
|
|
111
111
|
};
|
|
112
112
|
XDGAppPaths.state = function state(dirOptions) {
|
|
113
|
-
return
|
|
113
|
+
return path7.join(xdg.state(), finalPathSegment(dirOptions));
|
|
114
114
|
};
|
|
115
115
|
XDGAppPaths.configDirs = function configDirs(dirOptions) {
|
|
116
116
|
return xdg.configDirs().map(function(s) {
|
|
117
|
-
return
|
|
117
|
+
return path7.join(s, finalPathSegment(dirOptions));
|
|
118
118
|
});
|
|
119
119
|
};
|
|
120
120
|
XDGAppPaths.dataDirs = function dataDirs(dirOptions) {
|
|
121
121
|
return xdg.dataDirs().map(function(s) {
|
|
122
|
-
return
|
|
122
|
+
return path7.join(s, finalPathSegment(dirOptions));
|
|
123
123
|
});
|
|
124
124
|
};
|
|
125
125
|
return XDGAppPaths;
|
|
@@ -144,14 +144,14 @@ var require_XDG = __commonJS({
|
|
|
144
144
|
exports.__esModule = true;
|
|
145
145
|
exports.Adapt = void 0;
|
|
146
146
|
function Adapt(adapter_) {
|
|
147
|
-
var env = adapter_.env, osPaths = adapter_.osPaths,
|
|
147
|
+
var env = adapter_.env, osPaths = adapter_.osPaths, path7 = adapter_.path;
|
|
148
148
|
var isMacOS = /^darwin$/i.test(adapter_.process.platform);
|
|
149
149
|
var isWinOS = /^win/i.test(adapter_.process.platform);
|
|
150
150
|
function baseDir() {
|
|
151
151
|
return osPaths.home() || osPaths.temp();
|
|
152
152
|
}
|
|
153
153
|
function valOrPath(val, pathSegments) {
|
|
154
|
-
return val ||
|
|
154
|
+
return val || path7.join.apply(path7, pathSegments);
|
|
155
155
|
}
|
|
156
156
|
var linux = function() {
|
|
157
157
|
var cache = function() {
|
|
@@ -226,11 +226,11 @@ var require_XDG = __commonJS({
|
|
|
226
226
|
XDG.state = extension.state;
|
|
227
227
|
XDG.configDirs = function configDirs() {
|
|
228
228
|
var pathList = env.get("XDG_CONFIG_DIRS");
|
|
229
|
-
return __spreadArray([extension.config()], pathList ? pathList.split(
|
|
229
|
+
return __spreadArray([extension.config()], pathList ? pathList.split(path7.delimiter) : []);
|
|
230
230
|
};
|
|
231
231
|
XDG.dataDirs = function dataDirs() {
|
|
232
232
|
var pathList = env.get("XDG_DATA_DIRS");
|
|
233
|
-
return __spreadArray([extension.data()], pathList ? pathList.split(
|
|
233
|
+
return __spreadArray([extension.data()], pathList ? pathList.split(path7.delimiter) : []);
|
|
234
234
|
};
|
|
235
235
|
return XDG;
|
|
236
236
|
}
|
|
@@ -257,13 +257,13 @@ var require_OSPaths = __commonJS({
|
|
|
257
257
|
return !s;
|
|
258
258
|
}
|
|
259
259
|
function Adapt(adapter_) {
|
|
260
|
-
var env = adapter_.env, os2 = adapter_.os,
|
|
260
|
+
var env = adapter_.env, os2 = adapter_.os, path7 = adapter_.path;
|
|
261
261
|
var isWinOS = /^win/i.test(adapter_.process.platform);
|
|
262
262
|
function normalizePath(path_) {
|
|
263
263
|
return path_ ? adapter_.path.normalize(adapter_.path.join(path_, ".")) : void 0;
|
|
264
264
|
}
|
|
265
265
|
function home() {
|
|
266
|
-
var
|
|
266
|
+
var posix2 = function() {
|
|
267
267
|
return normalizePath((typeof os2.homedir === "function" ? os2.homedir() : void 0) || env.get("HOME"));
|
|
268
268
|
};
|
|
269
269
|
var windows = function() {
|
|
@@ -271,19 +271,19 @@ var require_OSPaths = __commonJS({
|
|
|
271
271
|
typeof os2.homedir === "function" ? os2.homedir() : void 0,
|
|
272
272
|
env.get("USERPROFILE"),
|
|
273
273
|
env.get("HOME"),
|
|
274
|
-
env.get("HOMEDRIVE") || env.get("HOMEPATH") ?
|
|
274
|
+
env.get("HOMEDRIVE") || env.get("HOMEPATH") ? path7.join(env.get("HOMEDRIVE") || "", env.get("HOMEPATH") || "") : void 0
|
|
275
275
|
];
|
|
276
276
|
return normalizePath(priorityList.find(function(v) {
|
|
277
277
|
return !isEmpty(v);
|
|
278
278
|
}));
|
|
279
279
|
};
|
|
280
|
-
return isWinOS ? windows() :
|
|
280
|
+
return isWinOS ? windows() : posix2();
|
|
281
281
|
}
|
|
282
282
|
function temp() {
|
|
283
283
|
function joinPathToBase(base, segments) {
|
|
284
|
-
return base ?
|
|
284
|
+
return base ? path7.join.apply(path7, __spreadArray([base], segments)) : void 0;
|
|
285
285
|
}
|
|
286
|
-
function
|
|
286
|
+
function posix2() {
|
|
287
287
|
var fallback = "/tmp";
|
|
288
288
|
var priorityList = [
|
|
289
289
|
typeof os2.tmpdir === "function" ? os2.tmpdir() : void 0,
|
|
@@ -331,7 +331,7 @@ var require_OSPaths = __commonJS({
|
|
|
331
331
|
});
|
|
332
332
|
return v && normalizePath(v()) || fallback;
|
|
333
333
|
}
|
|
334
|
-
return isWinOS ? windows() :
|
|
334
|
+
return isWinOS ? windows() : posix2();
|
|
335
335
|
}
|
|
336
336
|
var OSPaths_ = /* @__PURE__ */ function() {
|
|
337
337
|
function OSPaths_2() {
|
|
@@ -385,7 +385,7 @@ var require_node = __commonJS({
|
|
|
385
385
|
exports.__esModule = true;
|
|
386
386
|
exports.adapter = void 0;
|
|
387
387
|
var os2 = __importStar(__require("os"));
|
|
388
|
-
var
|
|
388
|
+
var path7 = __importStar(__require("path"));
|
|
389
389
|
exports.adapter = {
|
|
390
390
|
atImportPermissions: { env: true },
|
|
391
391
|
env: {
|
|
@@ -394,7 +394,7 @@ var require_node = __commonJS({
|
|
|
394
394
|
}
|
|
395
395
|
},
|
|
396
396
|
os: os2,
|
|
397
|
-
path:
|
|
397
|
+
path: path7,
|
|
398
398
|
process
|
|
399
399
|
};
|
|
400
400
|
}
|
|
@@ -447,7 +447,7 @@ var require_node2 = __commonJS({
|
|
|
447
447
|
};
|
|
448
448
|
exports.__esModule = true;
|
|
449
449
|
exports.adapter = void 0;
|
|
450
|
-
var
|
|
450
|
+
var path7 = __importStar(__require("path"));
|
|
451
451
|
var os_paths_1 = __importDefault(require_mod_cjs());
|
|
452
452
|
exports.adapter = {
|
|
453
453
|
atImportPermissions: { env: true },
|
|
@@ -457,7 +457,7 @@ var require_node2 = __commonJS({
|
|
|
457
457
|
}
|
|
458
458
|
},
|
|
459
459
|
osPaths: os_paths_1["default"],
|
|
460
|
-
path:
|
|
460
|
+
path: path7,
|
|
461
461
|
process
|
|
462
462
|
};
|
|
463
463
|
}
|
|
@@ -510,7 +510,7 @@ var require_node3 = __commonJS({
|
|
|
510
510
|
};
|
|
511
511
|
exports.__esModule = true;
|
|
512
512
|
exports.adapter = void 0;
|
|
513
|
-
var
|
|
513
|
+
var path7 = __importStar(__require("path"));
|
|
514
514
|
var xdg_portable_1 = __importDefault(require_mod_cjs2());
|
|
515
515
|
exports.adapter = {
|
|
516
516
|
atImportPermissions: { env: true, read: true },
|
|
@@ -525,7 +525,7 @@ var require_node3 = __commonJS({
|
|
|
525
525
|
return process.pkg ? process.execPath : void 0;
|
|
526
526
|
}
|
|
527
527
|
},
|
|
528
|
-
path:
|
|
528
|
+
path: path7,
|
|
529
529
|
process,
|
|
530
530
|
xdg: xdg_portable_1["default"]
|
|
531
531
|
};
|
|
@@ -777,31 +777,31 @@ var require_retry2 = __commonJS({
|
|
|
777
777
|
import { Command as Command2 } from "commander";
|
|
778
778
|
|
|
779
779
|
// src/commands/deploy.ts
|
|
780
|
-
import { intro as
|
|
780
|
+
import { intro as intro4, log as log5, outro as outro5 } from "@clack/prompts";
|
|
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
|
-
flattenAttributes as
|
|
786
|
-
recordSpanException as recordSpanException4
|
|
786
|
+
flattenAttributes as flattenAttributes3
|
|
787
787
|
} from "@trigger.dev/core/v3";
|
|
788
|
-
import
|
|
788
|
+
import { recordSpanException as recordSpanException5 } from "@trigger.dev/core/v3/workers";
|
|
789
789
|
import { Option as CommandOption } from "commander";
|
|
790
790
|
import { build as build2 } from "esbuild";
|
|
791
791
|
import { execa as execa2 } from "execa";
|
|
792
|
-
import { resolve as importResolve } from "import-meta-resolve";
|
|
793
792
|
import { createHash } from "node:crypto";
|
|
794
793
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
795
794
|
import { copyFile, mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
796
|
-
import { dirname, join as
|
|
795
|
+
import { dirname, join as join6, posix, relative as relative3 } from "node:path";
|
|
797
796
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
798
|
-
import
|
|
797
|
+
import terminalLink2 from "terminal-link";
|
|
799
798
|
import invariant from "tiny-invariant";
|
|
800
799
|
import { z as z4 } from "zod";
|
|
801
800
|
|
|
802
801
|
// package.json
|
|
803
|
-
var version = "3.0.0-beta.
|
|
802
|
+
var version = "3.0.0-beta.30";
|
|
804
803
|
var dependencies = {
|
|
804
|
+
"@anatine/esbuild-decorators": "^0.2.19",
|
|
805
805
|
"@clack/prompts": "^0.7.0",
|
|
806
806
|
"@depot/cli": "0.0.1-cli.2.55.0",
|
|
807
807
|
"@opentelemetry/api": "^1.8.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
|
|
819
|
+
"@trigger.dev/core": "workspace:3.0.0-beta.30",
|
|
820
820
|
"@types/degit": "^2.8.3",
|
|
821
821
|
chalk: "^5.2.0",
|
|
822
822
|
chokidar: "^3.5.3",
|
|
@@ -833,12 +833,10 @@ var dependencies = {
|
|
|
833
833
|
"import-meta-resolve": "^4.0.0",
|
|
834
834
|
ink: "^4.4.1",
|
|
835
835
|
"jsonc-parser": "^3.2.1",
|
|
836
|
-
jsonlines: "^0.1.1",
|
|
837
836
|
liquidjs: "^10.9.2",
|
|
838
837
|
"mock-fs": "^5.2.0",
|
|
839
838
|
nanoid: "^4.0.2",
|
|
840
839
|
"node-fetch": "^3.3.0",
|
|
841
|
-
"npm-check-updates": "^16.12.2",
|
|
842
840
|
"object-hash": "^3.0.0",
|
|
843
841
|
"p-debounce": "^4.0.0",
|
|
844
842
|
"p-throttle": "^6.1.0",
|
|
@@ -850,7 +848,6 @@ var dependencies = {
|
|
|
850
848
|
"simple-git": "^3.19.0",
|
|
851
849
|
"socket.io-client": "^4.7.4",
|
|
852
850
|
"source-map-support": "^0.5.21",
|
|
853
|
-
"supports-color": "^9.4.0",
|
|
854
851
|
"terminal-link": "^3.0.0",
|
|
855
852
|
"tiny-invariant": "^1.2.0",
|
|
856
853
|
"tsconfig-paths": "^4.2.0",
|
|
@@ -858,7 +855,8 @@ var dependencies = {
|
|
|
858
855
|
url: "^0.11.1",
|
|
859
856
|
ws: "^8.12.0",
|
|
860
857
|
zod: "3.22.3",
|
|
861
|
-
"zod-validation-error": "^1.5.0"
|
|
858
|
+
"zod-validation-error": "^1.5.0",
|
|
859
|
+
typescript: "^5.4.0"
|
|
862
860
|
};
|
|
863
861
|
var package_default = {
|
|
864
862
|
name: "trigger.dev",
|
|
@@ -894,13 +892,12 @@ var package_default = {
|
|
|
894
892
|
type: "module",
|
|
895
893
|
exports: "./dist/index.js",
|
|
896
894
|
bin: {
|
|
897
|
-
|
|
895
|
+
triggerdev: "./dist/index.js"
|
|
898
896
|
},
|
|
899
897
|
devDependencies: {
|
|
900
898
|
"@trigger.dev/core-apps": "workspace:*",
|
|
901
899
|
"@trigger.dev/tsconfig": "workspace:*",
|
|
902
900
|
"@types/gradient-string": "^1.1.2",
|
|
903
|
-
"@types/jsonlines": "^0.1.5",
|
|
904
901
|
"@types/mock-fs": "^4.13.1",
|
|
905
902
|
"@types/node": "18",
|
|
906
903
|
"@types/object-hash": "^3.0.6",
|
|
@@ -908,8 +905,8 @@ var package_default = {
|
|
|
908
905
|
"@types/semver": "^7.3.13",
|
|
909
906
|
"@types/ws": "^8.5.3",
|
|
910
907
|
"cpy-cli": "^5.0.0",
|
|
908
|
+
nodemon: "^3.0.1",
|
|
911
909
|
"npm-run-all": "^4.1.5",
|
|
912
|
-
"npm-watch": "^0.11.0",
|
|
913
910
|
open: "^10.0.3",
|
|
914
911
|
"p-retry": "^6.1.0",
|
|
915
912
|
rimraf: "^3.0.2",
|
|
@@ -919,9 +916,6 @@ var package_default = {
|
|
|
919
916
|
vitest: "^0.34.4",
|
|
920
917
|
"xdg-app-paths": "^8.3.0"
|
|
921
918
|
},
|
|
922
|
-
watch: {
|
|
923
|
-
"build:prod-containerfile": "src/Containerfile.prod"
|
|
924
|
-
},
|
|
925
919
|
scripts: {
|
|
926
920
|
typecheck: "tsc -p tsconfig.check.json",
|
|
927
921
|
build: "npm run clean && run-p build:**",
|
|
@@ -931,7 +925,7 @@ var package_default = {
|
|
|
931
925
|
dev: "npm run clean && run-p dev:**",
|
|
932
926
|
"dev:main": "tsup --watch",
|
|
933
927
|
"dev:workers": "tsup --config tsup.workers.config.ts --watch",
|
|
934
|
-
"dev:
|
|
928
|
+
"dev:test": "nodemon -w src/Containerfile.prod -x npm run build:prod-containerfile",
|
|
935
929
|
clean: "rimraf dist",
|
|
936
930
|
start: "node dist/index.js",
|
|
937
931
|
test: "vitest"
|
|
@@ -1147,7 +1141,8 @@ async function zodfetch(schema, url, requestInit) {
|
|
|
1147
1141
|
}
|
|
1148
1142
|
|
|
1149
1143
|
// src/cli/common.ts
|
|
1150
|
-
import { flattenAttributes
|
|
1144
|
+
import { flattenAttributes } from "@trigger.dev/core/v3";
|
|
1145
|
+
import { recordSpanException } from "@trigger.dev/core/v3/workers";
|
|
1151
1146
|
import { z } from "zod";
|
|
1152
1147
|
|
|
1153
1148
|
// src/telemetry/tracing.ts
|
|
@@ -1157,6 +1152,10 @@ import { Resource, detectResourcesSync, processDetectorSync } from "@opentelemet
|
|
|
1157
1152
|
import { NodeTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";
|
|
1158
1153
|
import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
|
|
1159
1154
|
import { DiagConsoleLogger, DiagLogLevel, diag, trace } from "@opentelemetry/api";
|
|
1155
|
+
import {
|
|
1156
|
+
SEMRESATTRS_SERVICE_NAME,
|
|
1157
|
+
SEMRESATTRS_SERVICE_VERSION
|
|
1158
|
+
} from "@opentelemetry/semantic-conventions";
|
|
1160
1159
|
function initializeTracing() {
|
|
1161
1160
|
if (process.argv.includes("--skip-telemetry") || process.env.TRIGGER_DEV_SKIP_TELEMETRY) {
|
|
1162
1161
|
return;
|
|
@@ -1168,7 +1167,8 @@ function initializeTracing() {
|
|
|
1168
1167
|
detectors: [processDetectorSync]
|
|
1169
1168
|
}).merge(
|
|
1170
1169
|
new Resource({
|
|
1171
|
-
|
|
1170
|
+
[SEMRESATTRS_SERVICE_NAME]: "trigger.dev cli v3",
|
|
1171
|
+
[SEMRESATTRS_SERVICE_VERSION]: version
|
|
1172
1172
|
})
|
|
1173
1173
|
);
|
|
1174
1174
|
const traceProvider = new NodeTracerProvider({
|
|
@@ -1185,10 +1185,9 @@ function initializeTracing() {
|
|
|
1185
1185
|
});
|
|
1186
1186
|
const spanExporter = new OTLPTraceExporter({
|
|
1187
1187
|
url: "https://otel.baselime.io/v1",
|
|
1188
|
-
timeoutMillis:
|
|
1188
|
+
timeoutMillis: 5e3,
|
|
1189
1189
|
headers: {
|
|
1190
|
-
"x-api-key": "
|
|
1191
|
-
// this is a joke
|
|
1190
|
+
"x-api-key": "b6e0fbbaf8dc2524773d2152ae2e9eb5c7fbaa52"
|
|
1192
1191
|
}
|
|
1193
1192
|
});
|
|
1194
1193
|
const spanProcessor = new SimpleSpanProcessor(spanExporter);
|
|
@@ -1201,7 +1200,7 @@ function initializeTracing() {
|
|
|
1201
1200
|
}
|
|
1202
1201
|
var provider = initializeTracing();
|
|
1203
1202
|
function getTracer() {
|
|
1204
|
-
return trace.getTracer("trigger.dev cli", version);
|
|
1203
|
+
return trace.getTracer("trigger.dev cli v3", version);
|
|
1205
1204
|
}
|
|
1206
1205
|
|
|
1207
1206
|
// src/cli/common.ts
|
|
@@ -1307,7 +1306,7 @@ var Logger = class {
|
|
|
1307
1306
|
const kind = LOGGER_LEVEL_FORMAT_TYPE_MAP[level];
|
|
1308
1307
|
if (kind) {
|
|
1309
1308
|
const [firstLine, ...otherLines] = message.split("\n");
|
|
1310
|
-
const notes = otherLines.length > 0 ? otherLines.map((
|
|
1309
|
+
const notes = otherLines.length > 0 ? otherLines.map((text3) => ({ text: text3 })) : void 0;
|
|
1311
1310
|
return formatMessagesSync([{ text: firstLine, notes }], {
|
|
1312
1311
|
color: true,
|
|
1313
1312
|
kind,
|
|
@@ -1322,6 +1321,83 @@ var logger = new Logger();
|
|
|
1322
1321
|
|
|
1323
1322
|
// src/cli/common.ts
|
|
1324
1323
|
import { outro } from "@clack/prompts";
|
|
1324
|
+
|
|
1325
|
+
// src/utilities/cliOutput.ts
|
|
1326
|
+
import { log } from "@clack/prompts";
|
|
1327
|
+
import chalk2 from "chalk";
|
|
1328
|
+
var green = "#4FFF54";
|
|
1329
|
+
var purple = "#735BF3";
|
|
1330
|
+
function chalkGreen(text3) {
|
|
1331
|
+
return chalk2.hex(green)(text3);
|
|
1332
|
+
}
|
|
1333
|
+
function chalkPurple(text3) {
|
|
1334
|
+
return chalk2.hex(purple)(text3);
|
|
1335
|
+
}
|
|
1336
|
+
function chalkGrey(text3) {
|
|
1337
|
+
return chalk2.hex("#878C99")(text3);
|
|
1338
|
+
}
|
|
1339
|
+
function chalkError(text3) {
|
|
1340
|
+
return chalk2.hex("#E11D48")(text3);
|
|
1341
|
+
}
|
|
1342
|
+
function chalkWarning(text3) {
|
|
1343
|
+
return chalk2.yellow(text3);
|
|
1344
|
+
}
|
|
1345
|
+
function chalkSuccess(text3) {
|
|
1346
|
+
return chalk2.hex("#28BF5C")(text3);
|
|
1347
|
+
}
|
|
1348
|
+
function chalkLink(text3) {
|
|
1349
|
+
return chalk2.underline.hex("#D7D9DD")(text3);
|
|
1350
|
+
}
|
|
1351
|
+
function chalkWorker(text3) {
|
|
1352
|
+
return chalk2.hex("#FFFF89")(text3);
|
|
1353
|
+
}
|
|
1354
|
+
function chalkTask(text3) {
|
|
1355
|
+
return chalk2.hex("#60A5FA")(text3);
|
|
1356
|
+
}
|
|
1357
|
+
function chalkRun(text3) {
|
|
1358
|
+
return chalk2.hex("#A78BFA")(text3);
|
|
1359
|
+
}
|
|
1360
|
+
function logo() {
|
|
1361
|
+
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1362
|
+
}
|
|
1363
|
+
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1364
|
+
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1365
|
+
month: "short",
|
|
1366
|
+
day: "2-digit",
|
|
1367
|
+
hour: "2-digit",
|
|
1368
|
+
minute: "2-digit",
|
|
1369
|
+
second: "2-digit",
|
|
1370
|
+
hour12: false
|
|
1371
|
+
}).format(date);
|
|
1372
|
+
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1373
|
+
return formattedDate;
|
|
1374
|
+
}
|
|
1375
|
+
function prettyError(header, body, footer) {
|
|
1376
|
+
const prefix = "Error: ";
|
|
1377
|
+
const indent = Array(prefix.length).fill(" ").join("");
|
|
1378
|
+
const spacing = "\n\n";
|
|
1379
|
+
const prettyPrefix = chalkError(prefix);
|
|
1380
|
+
const withIndents = (text3) => text3?.split("\n").map((line) => `${indent}${line}`).join("\n");
|
|
1381
|
+
const prettyBody = withIndents(body);
|
|
1382
|
+
const prettyFooter = withIndents(footer);
|
|
1383
|
+
log.error(
|
|
1384
|
+
`${prettyPrefix}${header}${prettyBody ? `${spacing}${prettyBody}` : ""}${prettyFooter ? `${spacing}${prettyFooter}` : ""}`
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
function prettyWarning(header, body, footer) {
|
|
1388
|
+
const prefix = "Warning: ";
|
|
1389
|
+
const indent = Array(prefix.length).fill(" ").join("");
|
|
1390
|
+
const spacing = "\n\n";
|
|
1391
|
+
const prettyPrefix = chalkWarning(prefix);
|
|
1392
|
+
const withIndents = (text3) => text3?.split("\n").map((line) => `${indent}${line}`).join("\n");
|
|
1393
|
+
const prettyBody = withIndents(body);
|
|
1394
|
+
const prettyFooter = withIndents(footer);
|
|
1395
|
+
log.warn(
|
|
1396
|
+
`${prettyPrefix}${header}${prettyBody ? `${spacing}${prettyBody}` : ""}${prettyFooter ? `${spacing}${prettyFooter}` : ""}`
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// src/cli/common.ts
|
|
1325
1401
|
var CommonCommandOptions = z.object({
|
|
1326
1402
|
apiUrl: z.string().optional(),
|
|
1327
1403
|
logLevel: z.enum(["debug", "info", "log", "warn", "error", "none"]).default("log"),
|
|
@@ -1331,7 +1407,7 @@ var CommonCommandOptions = z.object({
|
|
|
1331
1407
|
function commonOptions(command) {
|
|
1332
1408
|
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
1409
|
"-l, --log-level <level>",
|
|
1334
|
-
"The log level to use (debug, info, log, warn, error, none)",
|
|
1410
|
+
"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
1411
|
"log"
|
|
1336
1412
|
).option("--skip-telemetry", "Opt-out of sending telemetry");
|
|
1337
1413
|
}
|
|
@@ -1377,7 +1453,7 @@ async function wrapCommandAction(name, schema, options, action) {
|
|
|
1377
1453
|
} else if (e instanceof SkipCommandError) {
|
|
1378
1454
|
} else {
|
|
1379
1455
|
recordSpanException(span, e);
|
|
1380
|
-
logger.
|
|
1456
|
+
logger.log(`${chalkError("X Error:")} ${e instanceof Error ? e.message : String(e)}`);
|
|
1381
1457
|
}
|
|
1382
1458
|
span.end();
|
|
1383
1459
|
throw e;
|
|
@@ -1420,31 +1496,34 @@ import fsModule, { writeFile } from "fs/promises";
|
|
|
1420
1496
|
import fs from "node:fs";
|
|
1421
1497
|
import { tmpdir } from "node:os";
|
|
1422
1498
|
import pathModule from "node:path";
|
|
1423
|
-
async function createFile(
|
|
1424
|
-
await fsModule.mkdir(pathModule.dirname(
|
|
1425
|
-
await fsModule.writeFile(
|
|
1426
|
-
return
|
|
1499
|
+
async function createFile(path7, contents) {
|
|
1500
|
+
await fsModule.mkdir(pathModule.dirname(path7), { recursive: true });
|
|
1501
|
+
await fsModule.writeFile(path7, contents);
|
|
1502
|
+
return path7;
|
|
1427
1503
|
}
|
|
1428
|
-
async function pathExists(
|
|
1429
|
-
return fsSync.existsSync(
|
|
1504
|
+
async function pathExists(path7) {
|
|
1505
|
+
return fsSync.existsSync(path7);
|
|
1430
1506
|
}
|
|
1431
|
-
async function
|
|
1432
|
-
|
|
1507
|
+
async function removeFile(path7) {
|
|
1508
|
+
await fsModule.unlink(path7);
|
|
1433
1509
|
}
|
|
1434
|
-
async function
|
|
1435
|
-
|
|
1510
|
+
async function readFile(path7) {
|
|
1511
|
+
return await fsModule.readFile(path7, "utf8");
|
|
1512
|
+
}
|
|
1513
|
+
async function readJSONFile(path7) {
|
|
1514
|
+
const fileContents = await fsModule.readFile(path7, "utf8");
|
|
1436
1515
|
return JSON.parse(fileContents);
|
|
1437
1516
|
}
|
|
1438
|
-
async function writeJSONFile(
|
|
1439
|
-
await writeFile(
|
|
1517
|
+
async function writeJSONFile(path7, json, pretty = false) {
|
|
1518
|
+
await writeFile(path7, JSON.stringify(json, void 0, pretty ? 2 : void 0), "utf8");
|
|
1440
1519
|
}
|
|
1441
|
-
function readJSONFileSync(
|
|
1442
|
-
const fileContents = fsSync.readFileSync(
|
|
1520
|
+
function readJSONFileSync(path7) {
|
|
1521
|
+
const fileContents = fsSync.readFileSync(path7, "utf8");
|
|
1443
1522
|
return JSON.parse(fileContents);
|
|
1444
1523
|
}
|
|
1445
|
-
function safeDeleteFileSync(
|
|
1524
|
+
function safeDeleteFileSync(path7) {
|
|
1446
1525
|
try {
|
|
1447
|
-
fs.unlinkSync(
|
|
1526
|
+
fs.unlinkSync(path7);
|
|
1448
1527
|
} catch (error) {
|
|
1449
1528
|
}
|
|
1450
1529
|
}
|
|
@@ -1467,16 +1546,26 @@ function createTaskFileImports(taskFiles) {
|
|
|
1467
1546
|
async function gatherTaskFiles(config) {
|
|
1468
1547
|
const taskFiles = [];
|
|
1469
1548
|
for (const triggerDir of config.triggerDirectories) {
|
|
1470
|
-
const files = await
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1549
|
+
const files = await gatherTaskFilesFromDir(triggerDir, triggerDir, config);
|
|
1550
|
+
taskFiles.push(...files);
|
|
1551
|
+
}
|
|
1552
|
+
return taskFiles;
|
|
1553
|
+
}
|
|
1554
|
+
async function gatherTaskFilesFromDir(dirPath, triggerDir, config) {
|
|
1555
|
+
const taskFiles = [];
|
|
1556
|
+
const files = await fs2.promises.readdir(dirPath, { withFileTypes: true });
|
|
1557
|
+
for (const file of files) {
|
|
1558
|
+
if (!file.isFile()) {
|
|
1559
|
+
const fullPath = join(dirPath, file.name);
|
|
1560
|
+
taskFiles.push(...await gatherTaskFilesFromDir(fullPath, triggerDir, config));
|
|
1561
|
+
} else {
|
|
1562
|
+
if (!file.name.endsWith(".js") && !file.name.endsWith(".ts") && !file.name.endsWith(".jsx") && !file.name.endsWith(".tsx")) {
|
|
1475
1563
|
continue;
|
|
1476
|
-
|
|
1564
|
+
}
|
|
1565
|
+
const fullPath = join(dirPath, file.name);
|
|
1477
1566
|
const filePath = relative(config.projectDir, fullPath);
|
|
1478
|
-
const
|
|
1479
|
-
const
|
|
1567
|
+
const importName = filePath.replace(/\..+$/, "").replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1568
|
+
const importPath = filePath.replace(/\\/g, "/");
|
|
1480
1569
|
taskFiles.push({ triggerDir, importPath, importName, filePath });
|
|
1481
1570
|
}
|
|
1482
1571
|
}
|
|
@@ -1493,9 +1582,12 @@ async function getTriggerDirectories(dirPath) {
|
|
|
1493
1582
|
const entries = await fs2.promises.readdir(dirPath, { withFileTypes: true });
|
|
1494
1583
|
const triggerDirectories = [];
|
|
1495
1584
|
for (const entry of entries) {
|
|
1496
|
-
if (!entry.isDirectory() || IGNORED_DIRS.includes(entry.name))
|
|
1585
|
+
if (!entry.isDirectory() || IGNORED_DIRS.includes(entry.name) || entry.name.startsWith("."))
|
|
1497
1586
|
continue;
|
|
1498
1587
|
const fullPath = join(dirPath, entry.name);
|
|
1588
|
+
if (fullPath.endsWith("app/api/trigger")) {
|
|
1589
|
+
continue;
|
|
1590
|
+
}
|
|
1499
1591
|
if (entry.name === "trigger") {
|
|
1500
1592
|
triggerDirectories.push(fullPath);
|
|
1501
1593
|
}
|
|
@@ -1506,6 +1598,7 @@ async function getTriggerDirectories(dirPath) {
|
|
|
1506
1598
|
|
|
1507
1599
|
// src/utilities/configFiles.ts
|
|
1508
1600
|
import { build } from "esbuild";
|
|
1601
|
+
import { esbuildDecorators } from "@anatine/esbuild-decorators";
|
|
1509
1602
|
function getGlobalConfigFolderPath() {
|
|
1510
1603
|
const configDir = mod_esm_default("trigger").config();
|
|
1511
1604
|
return configDir;
|
|
@@ -1535,6 +1628,11 @@ function readAuthConfigProfile(profile = "default") {
|
|
|
1535
1628
|
return void 0;
|
|
1536
1629
|
}
|
|
1537
1630
|
}
|
|
1631
|
+
function deleteAuthConfigProfile(profile = "default") {
|
|
1632
|
+
const existingConfig = readAuthConfigFile() || {};
|
|
1633
|
+
delete existingConfig[profile];
|
|
1634
|
+
writeAuthConfigFile(existingConfig);
|
|
1635
|
+
}
|
|
1538
1636
|
function readAuthConfigFile() {
|
|
1539
1637
|
try {
|
|
1540
1638
|
const authConfigFilePath = getAuthConfigFilePath();
|
|
@@ -1564,16 +1662,25 @@ async function getConfigPath(dir, fileName) {
|
|
|
1564
1662
|
});
|
|
1565
1663
|
return await findUp(fileName ? [fileName] : CONFIG_FILES, { cwd: dir });
|
|
1566
1664
|
}
|
|
1665
|
+
async function findFilePath(dir, fileName) {
|
|
1666
|
+
const result = await findUp([fileName], { cwd: dir });
|
|
1667
|
+
logger.debug("Searched for the file", {
|
|
1668
|
+
dir,
|
|
1669
|
+
fileName,
|
|
1670
|
+
result
|
|
1671
|
+
});
|
|
1672
|
+
return result;
|
|
1673
|
+
}
|
|
1567
1674
|
async function readConfig(dir, options) {
|
|
1568
1675
|
const absoluteDir = path2.resolve(process.cwd(), dir);
|
|
1569
1676
|
const configPath = await getConfigPath(dir, options?.configFile);
|
|
1570
1677
|
if (!configPath) {
|
|
1571
1678
|
if (options?.projectRef) {
|
|
1572
|
-
const
|
|
1573
|
-
const
|
|
1679
|
+
const rawConfig = await normalizeConfig({ project: options.projectRef });
|
|
1680
|
+
const config = Config.parse(rawConfig);
|
|
1574
1681
|
return {
|
|
1575
1682
|
status: "in-memory",
|
|
1576
|
-
config: await resolveConfig(absoluteDir,
|
|
1683
|
+
config: await resolveConfig(absoluteDir, config)
|
|
1577
1684
|
};
|
|
1578
1685
|
} else {
|
|
1579
1686
|
throw new Error(`Config file not found in ${absoluteDir} or any parent directory.`);
|
|
@@ -1597,92 +1704,64 @@ async function readConfig(dir, options) {
|
|
|
1597
1704
|
platform: "node",
|
|
1598
1705
|
target: ["es2018", "node18"],
|
|
1599
1706
|
outfile: builtConfigFilePath,
|
|
1600
|
-
logLevel: "silent"
|
|
1707
|
+
logLevel: "silent",
|
|
1708
|
+
plugins: [
|
|
1709
|
+
esbuildDecorators({
|
|
1710
|
+
cwd: absoluteDir,
|
|
1711
|
+
tsx: false,
|
|
1712
|
+
force: false
|
|
1713
|
+
})
|
|
1714
|
+
]
|
|
1601
1715
|
});
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1716
|
+
try {
|
|
1717
|
+
const userConfigModule = await import(builtConfigFileHref);
|
|
1718
|
+
const rawConfig = await normalizeConfig(
|
|
1719
|
+
userConfigModule?.config,
|
|
1720
|
+
options?.projectRef ? { project: options?.projectRef } : void 0
|
|
1721
|
+
);
|
|
1722
|
+
const config = Config.parse(rawConfig);
|
|
1723
|
+
return {
|
|
1724
|
+
status: "file",
|
|
1725
|
+
config: await resolveConfig(absoluteDir, config),
|
|
1726
|
+
path: configPath
|
|
1727
|
+
};
|
|
1728
|
+
} catch (error) {
|
|
1729
|
+
return {
|
|
1730
|
+
status: "error",
|
|
1731
|
+
error
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1612
1734
|
}
|
|
1613
|
-
async function resolveConfig(
|
|
1735
|
+
async function resolveConfig(path7, config) {
|
|
1614
1736
|
if (!config.triggerDirectories) {
|
|
1615
|
-
config.triggerDirectories = await findTriggerDirectories(
|
|
1737
|
+
config.triggerDirectories = await findTriggerDirectories(path7);
|
|
1616
1738
|
}
|
|
1617
1739
|
config.triggerDirectories = resolveTriggerDirectories(config.triggerDirectories);
|
|
1740
|
+
logger.debug("Resolved trigger directories", { triggerDirectories: config.triggerDirectories });
|
|
1618
1741
|
if (!config.triggerUrl) {
|
|
1619
1742
|
config.triggerUrl = CLOUD_API_URL;
|
|
1620
1743
|
}
|
|
1621
1744
|
if (!config.projectDir) {
|
|
1622
|
-
config.projectDir =
|
|
1745
|
+
config.projectDir = path7;
|
|
1623
1746
|
}
|
|
1624
1747
|
if (!config.tsconfigPath) {
|
|
1625
|
-
config.tsconfigPath = await
|
|
1748
|
+
config.tsconfigPath = await findFilePath(path7, "tsconfig.json");
|
|
1626
1749
|
}
|
|
1627
1750
|
return config;
|
|
1628
1751
|
}
|
|
1629
|
-
async function normalizeConfig(config) {
|
|
1752
|
+
async function normalizeConfig(config, overrides) {
|
|
1753
|
+
let normalized = config;
|
|
1630
1754
|
if (typeof config === "function") {
|
|
1631
|
-
|
|
1755
|
+
normalized = await config();
|
|
1632
1756
|
}
|
|
1633
|
-
|
|
1757
|
+
normalized = { ...normalized, ...overrides };
|
|
1758
|
+
return normalized;
|
|
1634
1759
|
}
|
|
1635
1760
|
|
|
1636
1761
|
// src/utilities/initialBanner.ts
|
|
1637
|
-
import { spinner } from "@clack/prompts";
|
|
1638
1762
|
import chalk3 from "chalk";
|
|
1639
|
-
import supportsColor from "supports-color";
|
|
1640
1763
|
import checkForUpdate from "update-check";
|
|
1641
1764
|
|
|
1642
|
-
// src/utilities/cliOutput.ts
|
|
1643
|
-
import chalk2 from "chalk";
|
|
1644
|
-
var green = "#4FFF54";
|
|
1645
|
-
var purple = "#735BF3";
|
|
1646
|
-
function chalkGrey(text2) {
|
|
1647
|
-
return chalk2.hex("#878C99")(text2);
|
|
1648
|
-
}
|
|
1649
|
-
function chalkError(text2) {
|
|
1650
|
-
return chalk2.hex("#E11D48")(text2);
|
|
1651
|
-
}
|
|
1652
|
-
function chalkWarning(text2) {
|
|
1653
|
-
return chalk2.yellow(text2);
|
|
1654
|
-
}
|
|
1655
|
-
function chalkSuccess(text2) {
|
|
1656
|
-
return chalk2.hex("#28BF5C")(text2);
|
|
1657
|
-
}
|
|
1658
|
-
function chalkLink(text2) {
|
|
1659
|
-
return chalk2.underline.hex("#D7D9DD")(text2);
|
|
1660
|
-
}
|
|
1661
|
-
function chalkWorker(text2) {
|
|
1662
|
-
return chalk2.hex("#FFFF89")(text2);
|
|
1663
|
-
}
|
|
1664
|
-
function chalkTask(text2) {
|
|
1665
|
-
return chalk2.hex("#60A5FA")(text2);
|
|
1666
|
-
}
|
|
1667
|
-
function chalkRun(text2) {
|
|
1668
|
-
return chalk2.hex("#A78BFA")(text2);
|
|
1669
|
-
}
|
|
1670
|
-
function logo() {
|
|
1671
|
-
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1672
|
-
}
|
|
1673
|
-
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1674
|
-
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1675
|
-
month: "short",
|
|
1676
|
-
day: "2-digit",
|
|
1677
|
-
hour: "2-digit",
|
|
1678
|
-
minute: "2-digit",
|
|
1679
|
-
second: "2-digit",
|
|
1680
|
-
hour12: false
|
|
1681
|
-
}).format(date);
|
|
1682
|
-
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1683
|
-
return formattedDate;
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
1765
|
// src/utilities/getVersion.ts
|
|
1687
1766
|
import path3 from "path";
|
|
1688
1767
|
function getVersion() {
|
|
@@ -1691,13 +1770,32 @@ function getVersion() {
|
|
|
1691
1770
|
return packageJsonContent.version ?? "1.0.0";
|
|
1692
1771
|
}
|
|
1693
1772
|
|
|
1773
|
+
// src/utilities/windows.ts
|
|
1774
|
+
import { log as log2, spinner as clackSpinner } from "@clack/prompts";
|
|
1775
|
+
var isWindows = process.platform === "win32";
|
|
1776
|
+
function escapeImportPath(path7) {
|
|
1777
|
+
return isWindows ? path7.replaceAll("\\", "\\\\") : path7;
|
|
1778
|
+
}
|
|
1779
|
+
var ballmerSpinner = () => ({
|
|
1780
|
+
start: (msg) => {
|
|
1781
|
+
log2.step(msg ?? "");
|
|
1782
|
+
},
|
|
1783
|
+
stop: (msg, code) => {
|
|
1784
|
+
log2.message(msg ?? "");
|
|
1785
|
+
},
|
|
1786
|
+
message: (msg) => {
|
|
1787
|
+
log2.message(msg ?? "");
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
var spinner = () => isWindows ? ballmerSpinner() : clackSpinner();
|
|
1791
|
+
|
|
1694
1792
|
// src/utilities/initialBanner.ts
|
|
1695
1793
|
async function printInitialBanner(performUpdateCheck = true) {
|
|
1696
|
-
const
|
|
1697
|
-
const
|
|
1698
|
-
${logo()} ${chalkGrey(`(${
|
|
1794
|
+
const cliVersion = getVersion();
|
|
1795
|
+
const text3 = `
|
|
1796
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}
|
|
1699
1797
|
`;
|
|
1700
|
-
logger.info(
|
|
1798
|
+
logger.info(text3);
|
|
1701
1799
|
let maybeNewVersion;
|
|
1702
1800
|
if (performUpdateCheck) {
|
|
1703
1801
|
const loadingSpinner = spinner();
|
|
@@ -1705,7 +1803,7 @@ ${logo()} ${chalkGrey(`(${packageVersion})`)}
|
|
|
1705
1803
|
maybeNewVersion = await updateCheck();
|
|
1706
1804
|
if (maybeNewVersion !== void 0) {
|
|
1707
1805
|
loadingSpinner.stop(`Update available ${chalk3.green(maybeNewVersion)}`);
|
|
1708
|
-
const currentMajor = parseInt(
|
|
1806
|
+
const currentMajor = parseInt(cliVersion.split(".")[0]);
|
|
1709
1807
|
const newMajor = parseInt(maybeNewVersion.split(".")[0]);
|
|
1710
1808
|
if (newMajor > currentMajor) {
|
|
1711
1809
|
logger.warn(
|
|
@@ -1720,18 +1818,26 @@ After installation, run Trigger.dev with \`npx trigger.dev\`.`
|
|
|
1720
1818
|
}
|
|
1721
1819
|
}
|
|
1722
1820
|
async function printStandloneInitialBanner(performUpdateCheck = true) {
|
|
1723
|
-
const
|
|
1724
|
-
let text2 = `
|
|
1725
|
-
${logo()} ${chalkGrey("(v3 Developer Preview)")}`;
|
|
1821
|
+
const cliVersion = getVersion();
|
|
1726
1822
|
if (performUpdateCheck) {
|
|
1727
1823
|
const maybeNewVersion = await updateCheck();
|
|
1728
1824
|
if (maybeNewVersion !== void 0) {
|
|
1729
|
-
|
|
1825
|
+
logger.log(`
|
|
1826
|
+
${logo()} ${chalkGrey(`(${cliVersion} -> ${chalk3.green(maybeNewVersion)})`)}`);
|
|
1827
|
+
} else {
|
|
1828
|
+
logger.log(`
|
|
1829
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}`);
|
|
1730
1830
|
}
|
|
1831
|
+
} else {
|
|
1832
|
+
logger.log(`
|
|
1833
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}`);
|
|
1731
1834
|
}
|
|
1732
|
-
logger.log(
|
|
1835
|
+
logger.log(`${chalkGrey("-".repeat(54))}`);
|
|
1733
1836
|
}
|
|
1734
|
-
function printDevBanner() {
|
|
1837
|
+
function printDevBanner(printTopBorder = true) {
|
|
1838
|
+
if (printTopBorder) {
|
|
1839
|
+
logger.log(chalkGrey("-".repeat(54)));
|
|
1840
|
+
}
|
|
1735
1841
|
logger.log(
|
|
1736
1842
|
`${chalkGrey("Key:")} ${chalkWorker("Version")} ${chalkGrey("|")} ${chalkTask(
|
|
1737
1843
|
"Task"
|
|
@@ -1743,7 +1849,7 @@ async function doUpdateCheck() {
|
|
|
1743
1849
|
let update = null;
|
|
1744
1850
|
try {
|
|
1745
1851
|
update = await checkForUpdate(package_default, {
|
|
1746
|
-
distTag: package_default.version.startsWith("
|
|
1852
|
+
distTag: package_default.version.startsWith("3.0.0-beta") ? "beta" : "latest"
|
|
1747
1853
|
});
|
|
1748
1854
|
} catch (err) {
|
|
1749
1855
|
}
|
|
@@ -1761,26 +1867,20 @@ async function installPackages(packages, options) {
|
|
|
1761
1867
|
const cwd = options?.cwd ?? process.cwd();
|
|
1762
1868
|
logger.debug("Installing packages", { packages });
|
|
1763
1869
|
await setPackageJsonDeps(join3(cwd, "package.json"), packages);
|
|
1764
|
-
|
|
1870
|
+
await execa(
|
|
1765
1871
|
"npm",
|
|
1766
1872
|
["install", "--install-strategy", "nested", "--ignore-scripts", "--no-audit", "--no-fund"],
|
|
1767
1873
|
{
|
|
1768
1874
|
cwd,
|
|
1769
|
-
stderr: "
|
|
1875
|
+
stderr: "pipe"
|
|
1770
1876
|
}
|
|
1771
1877
|
);
|
|
1772
|
-
await new Promise((res, rej) => {
|
|
1773
|
-
childProcess2.on("error", (e) => rej(e));
|
|
1774
|
-
childProcess2.on("close", () => res());
|
|
1775
|
-
});
|
|
1776
|
-
await childProcess2;
|
|
1777
|
-
return;
|
|
1778
1878
|
}
|
|
1779
|
-
function detectPackageNameFromImportPath(
|
|
1780
|
-
if (
|
|
1781
|
-
return
|
|
1879
|
+
function detectPackageNameFromImportPath(path7) {
|
|
1880
|
+
if (path7.startsWith("@")) {
|
|
1881
|
+
return path7.split("/").slice(0, 2).join("/");
|
|
1782
1882
|
} else {
|
|
1783
|
-
return
|
|
1883
|
+
return path7.split("/")[0];
|
|
1784
1884
|
}
|
|
1785
1885
|
}
|
|
1786
1886
|
function stripWorkspaceFromVersion(version2) {
|
|
@@ -1796,16 +1896,16 @@ function parsePackageName(packageSpecifier) {
|
|
|
1796
1896
|
}
|
|
1797
1897
|
return { name: packageSpecifier };
|
|
1798
1898
|
}
|
|
1799
|
-
async function setPackageJsonDeps(
|
|
1899
|
+
async function setPackageJsonDeps(path7, deps) {
|
|
1800
1900
|
try {
|
|
1801
|
-
const existingPackageJson = await readJSONFile(
|
|
1901
|
+
const existingPackageJson = await readJSONFile(path7);
|
|
1802
1902
|
const newPackageJson = {
|
|
1803
1903
|
...existingPackageJson,
|
|
1804
1904
|
dependencies: {
|
|
1805
1905
|
...deps
|
|
1806
1906
|
}
|
|
1807
1907
|
};
|
|
1808
|
-
await writeJSONFile(
|
|
1908
|
+
await writeJSONFile(path7, newPackageJson);
|
|
1809
1909
|
} catch (error) {
|
|
1810
1910
|
const defaultPackageJson = {
|
|
1811
1911
|
name: "temp",
|
|
@@ -1813,13 +1913,13 @@ async function setPackageJsonDeps(path6, deps) {
|
|
|
1813
1913
|
description: "",
|
|
1814
1914
|
dependencies: deps
|
|
1815
1915
|
};
|
|
1816
|
-
await writeJSONFile(
|
|
1916
|
+
await writeJSONFile(path7, defaultPackageJson);
|
|
1817
1917
|
}
|
|
1818
1918
|
}
|
|
1819
1919
|
|
|
1820
1920
|
// src/commands/login.ts
|
|
1821
|
-
import { intro as intro2, log, outro as
|
|
1822
|
-
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3";
|
|
1921
|
+
import { intro as intro2, log as log3, outro as outro3, select } from "@clack/prompts";
|
|
1922
|
+
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3/workers";
|
|
1823
1923
|
|
|
1824
1924
|
// ../../node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
|
|
1825
1925
|
import process6 from "node:process";
|
|
@@ -2189,14 +2289,14 @@ var baseOpen = async (options) => {
|
|
|
2189
2289
|
}
|
|
2190
2290
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
2191
2291
|
if (options.wait) {
|
|
2192
|
-
return new Promise((
|
|
2292
|
+
return new Promise((resolve5, reject) => {
|
|
2193
2293
|
subprocess.once("error", reject);
|
|
2194
2294
|
subprocess.once("close", (exitCode) => {
|
|
2195
2295
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
2196
2296
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
2197
2297
|
return;
|
|
2198
2298
|
}
|
|
2199
|
-
|
|
2299
|
+
resolve5(subprocess);
|
|
2200
2300
|
});
|
|
2201
2301
|
});
|
|
2202
2302
|
}
|
|
@@ -2313,7 +2413,7 @@ var decorateErrorWithCounts = (error, attemptNumber, options) => {
|
|
|
2313
2413
|
return error;
|
|
2314
2414
|
};
|
|
2315
2415
|
async function pRetry(input, options) {
|
|
2316
|
-
return new Promise((
|
|
2416
|
+
return new Promise((resolve5, reject) => {
|
|
2317
2417
|
options = {
|
|
2318
2418
|
onFailedAttempt() {
|
|
2319
2419
|
},
|
|
@@ -2336,7 +2436,7 @@ async function pRetry(input, options) {
|
|
|
2336
2436
|
try {
|
|
2337
2437
|
const result = await input(attemptNumber);
|
|
2338
2438
|
cleanUp();
|
|
2339
|
-
|
|
2439
|
+
resolve5(result);
|
|
2340
2440
|
} catch (error) {
|
|
2341
2441
|
try {
|
|
2342
2442
|
if (!(error instanceof Error)) {
|
|
@@ -2366,10 +2466,10 @@ async function pRetry(input, options) {
|
|
|
2366
2466
|
import { z as z3 } from "zod";
|
|
2367
2467
|
|
|
2368
2468
|
// src/commands/whoami.ts
|
|
2369
|
-
import { intro, note,
|
|
2469
|
+
import { intro, note, outro as outro2 } from "@clack/prompts";
|
|
2370
2470
|
|
|
2371
2471
|
// src/utilities/session.ts
|
|
2372
|
-
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3";
|
|
2472
|
+
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3/workers";
|
|
2373
2473
|
var tracer2 = getTracer();
|
|
2374
2474
|
async function isLoggedIn(profile = "default") {
|
|
2375
2475
|
return await tracer2.startActiveSpan("isLoggedIn", async (span) => {
|
|
@@ -2444,16 +2544,23 @@ async function whoAmI(options, embedded = false) {
|
|
|
2444
2544
|
if (!embedded) {
|
|
2445
2545
|
intro(`Displaying your account details [${options?.profile ?? "default"}]`);
|
|
2446
2546
|
}
|
|
2447
|
-
const loadingSpinner =
|
|
2547
|
+
const loadingSpinner = spinner();
|
|
2448
2548
|
loadingSpinner.start("Checking your account details");
|
|
2449
2549
|
const authentication = await isLoggedIn(options?.profile);
|
|
2450
2550
|
if (!authentication.ok) {
|
|
2451
2551
|
if (authentication.error === "fetch failed") {
|
|
2452
2552
|
loadingSpinner.stop("Fetch failed. Platform down?");
|
|
2453
2553
|
} else {
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2554
|
+
if (embedded) {
|
|
2555
|
+
loadingSpinner.stop(
|
|
2556
|
+
`Failed to check account details. You may want to run \`trigger.dev logout --profile ${options?.profile ?? "default"}\` and try again.`
|
|
2557
|
+
);
|
|
2558
|
+
} else {
|
|
2559
|
+
loadingSpinner.stop(
|
|
2560
|
+
`You must login first. Use \`trigger.dev login --profile ${options?.profile ?? "default"}\` to login.`
|
|
2561
|
+
);
|
|
2562
|
+
outro2("Whoami failed");
|
|
2563
|
+
}
|
|
2457
2564
|
}
|
|
2458
2565
|
return {
|
|
2459
2566
|
success: false,
|
|
@@ -2518,6 +2625,29 @@ async function login(options) {
|
|
|
2518
2625
|
if (!opts.embedded) {
|
|
2519
2626
|
intro2("Logging in to Trigger.dev");
|
|
2520
2627
|
}
|
|
2628
|
+
const accessTokenFromEnv = process.env.TRIGGER_ACCESS_TOKEN;
|
|
2629
|
+
if (accessTokenFromEnv) {
|
|
2630
|
+
const auth = {
|
|
2631
|
+
accessToken: accessTokenFromEnv,
|
|
2632
|
+
apiUrl: process.env.TRIGGER_API_URL ?? "https://api.trigger.dev"
|
|
2633
|
+
};
|
|
2634
|
+
const apiClient3 = new CliApiClient(auth.apiUrl, auth.accessToken);
|
|
2635
|
+
const userData = await apiClient3.whoAmI();
|
|
2636
|
+
if (!userData.success) {
|
|
2637
|
+
throw new Error(userData.error);
|
|
2638
|
+
}
|
|
2639
|
+
return {
|
|
2640
|
+
ok: true,
|
|
2641
|
+
profile: options?.profile ?? "default",
|
|
2642
|
+
userId: userData.data.userId,
|
|
2643
|
+
email: userData.data.email,
|
|
2644
|
+
dashboardUrl: userData.data.dashboardUrl,
|
|
2645
|
+
auth: {
|
|
2646
|
+
accessToken: auth.accessToken,
|
|
2647
|
+
apiUrl: auth.apiUrl
|
|
2648
|
+
}
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2521
2651
|
const authConfig = readAuthConfigProfile(options?.profile);
|
|
2522
2652
|
if (authConfig && authConfig.accessToken) {
|
|
2523
2653
|
const whoAmIResult = await whoAmI(
|
|
@@ -2526,10 +2656,18 @@ async function login(options) {
|
|
|
2526
2656
|
skipTelemetry: !span.isRecording(),
|
|
2527
2657
|
logLevel: logger.loggerLevel
|
|
2528
2658
|
},
|
|
2529
|
-
|
|
2659
|
+
true
|
|
2530
2660
|
);
|
|
2531
2661
|
if (!whoAmIResult.success) {
|
|
2532
|
-
|
|
2662
|
+
prettyError("Unable to validate existing personal access token", whoAmIResult.error);
|
|
2663
|
+
if (!opts.embedded) {
|
|
2664
|
+
outro3(
|
|
2665
|
+
`Login failed using stored token. To fix, first logout using \`trigger.dev logout${options?.profile ? ` --profile ${options.profile}` : ""}\` and then try again.`
|
|
2666
|
+
);
|
|
2667
|
+
throw new SkipLoggingError(whoAmIResult.error);
|
|
2668
|
+
} else {
|
|
2669
|
+
throw new Error(whoAmIResult.error);
|
|
2670
|
+
}
|
|
2533
2671
|
} else {
|
|
2534
2672
|
if (!opts.embedded) {
|
|
2535
2673
|
const continueOption = await select({
|
|
@@ -2547,7 +2685,7 @@ async function login(options) {
|
|
|
2547
2685
|
initialValue: false
|
|
2548
2686
|
});
|
|
2549
2687
|
if (continueOption !== true) {
|
|
2550
|
-
|
|
2688
|
+
outro3("Already logged in");
|
|
2551
2689
|
span.setAttributes({
|
|
2552
2690
|
"cli.userId": whoAmIResult.data.userId,
|
|
2553
2691
|
"cli.email": whoAmIResult.data.email,
|
|
@@ -2588,16 +2726,16 @@ async function login(options) {
|
|
|
2588
2726
|
}
|
|
2589
2727
|
}
|
|
2590
2728
|
if (opts.embedded) {
|
|
2591
|
-
|
|
2729
|
+
log3.step("You must login to continue.");
|
|
2592
2730
|
}
|
|
2593
2731
|
const apiClient2 = new CliApiClient(authConfig?.apiUrl ?? opts.defaultApiUrl);
|
|
2594
2732
|
const authorizationCodeResult = await createAuthorizationCode(apiClient2);
|
|
2595
|
-
|
|
2733
|
+
log3.step(
|
|
2596
2734
|
`Please visit the following URL to login:
|
|
2597
2735
|
${chalkLink(authorizationCodeResult.url)}`
|
|
2598
2736
|
);
|
|
2599
2737
|
await open_default(authorizationCodeResult.url);
|
|
2600
|
-
const getPersonalAccessTokenSpinner =
|
|
2738
|
+
const getPersonalAccessTokenSpinner = spinner();
|
|
2601
2739
|
getPersonalAccessTokenSpinner.start("Waiting for you to login");
|
|
2602
2740
|
try {
|
|
2603
2741
|
const indexResult = await pRetry(
|
|
@@ -2626,9 +2764,9 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2626
2764
|
throw new Error(whoAmIResult.error);
|
|
2627
2765
|
}
|
|
2628
2766
|
if (opts.embedded) {
|
|
2629
|
-
|
|
2767
|
+
log3.step("Logged in successfully");
|
|
2630
2768
|
} else {
|
|
2631
|
-
|
|
2769
|
+
outro3("Logged in successfully");
|
|
2632
2770
|
}
|
|
2633
2771
|
span.end();
|
|
2634
2772
|
return {
|
|
@@ -2645,7 +2783,7 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2645
2783
|
} catch (e) {
|
|
2646
2784
|
getPersonalAccessTokenSpinner.stop(`Failed to get access token`);
|
|
2647
2785
|
if (e instanceof AbortError) {
|
|
2648
|
-
|
|
2786
|
+
log3.error(e.message);
|
|
2649
2787
|
}
|
|
2650
2788
|
recordSpanException3(span, e);
|
|
2651
2789
|
span.end();
|
|
@@ -2694,7 +2832,7 @@ async function getPersonalAccessToken(apiClient2, authorizationCode) {
|
|
|
2694
2832
|
async function createAuthorizationCode(apiClient2) {
|
|
2695
2833
|
return await tracer.startActiveSpan("createAuthorizationCode", async (span) => {
|
|
2696
2834
|
try {
|
|
2697
|
-
const createAuthCodeSpinner =
|
|
2835
|
+
const createAuthCodeSpinner = spinner();
|
|
2698
2836
|
createAuthCodeSpinner.start("Creating authorition code");
|
|
2699
2837
|
const authorizationCodeResult = await apiClient2.createAuthorizationCode();
|
|
2700
2838
|
if (!authorizationCodeResult.success) {
|
|
@@ -2718,10 +2856,69 @@ ${authorizationCodeResult.error}`
|
|
|
2718
2856
|
});
|
|
2719
2857
|
}
|
|
2720
2858
|
|
|
2859
|
+
// src/commands/deploy.ts
|
|
2860
|
+
import { esbuildDecorators as esbuildDecorators2 } from "@anatine/esbuild-decorators";
|
|
2861
|
+
import { Glob } from "glob";
|
|
2862
|
+
|
|
2721
2863
|
// src/utilities/build.ts
|
|
2722
2864
|
import { readFileSync } from "node:fs";
|
|
2723
2865
|
import { extname, isAbsolute } from "node:path";
|
|
2724
2866
|
import tsConfigPaths from "tsconfig-paths";
|
|
2867
|
+
function mockServerOnlyPlugin() {
|
|
2868
|
+
return {
|
|
2869
|
+
name: "trigger-mock-server-only",
|
|
2870
|
+
setup(build3) {
|
|
2871
|
+
build3.onResolve({ filter: /server-only/ }, (args) => {
|
|
2872
|
+
if (args.path !== "server-only") {
|
|
2873
|
+
return void 0;
|
|
2874
|
+
}
|
|
2875
|
+
logger.debug(`[trigger-mock-server-only] Bundling ${args.path}`, {
|
|
2876
|
+
...args
|
|
2877
|
+
});
|
|
2878
|
+
return {
|
|
2879
|
+
path: args.path,
|
|
2880
|
+
external: false,
|
|
2881
|
+
namespace: "server-only-mock"
|
|
2882
|
+
};
|
|
2883
|
+
});
|
|
2884
|
+
build3.onLoad({ filter: /server-only/, namespace: "server-only-mock" }, (args) => {
|
|
2885
|
+
return {
|
|
2886
|
+
contents: `export default true;`,
|
|
2887
|
+
loader: "js"
|
|
2888
|
+
};
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
};
|
|
2892
|
+
}
|
|
2893
|
+
function bundleTriggerDevCore(buildIdentifier, tsconfigPath) {
|
|
2894
|
+
return {
|
|
2895
|
+
name: "trigger-bundle-core",
|
|
2896
|
+
setup(build3) {
|
|
2897
|
+
build3.onResolve({ filter: /.*/ }, (args) => {
|
|
2898
|
+
if (!args.path.startsWith("@trigger.dev/core/v3")) {
|
|
2899
|
+
return void 0;
|
|
2900
|
+
}
|
|
2901
|
+
const triggerSdkPath = __require.resolve("@trigger.dev/sdk/v3", { paths: [process.cwd()] });
|
|
2902
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Resolved @trigger.dev/sdk/v3`, {
|
|
2903
|
+
...args,
|
|
2904
|
+
triggerSdkPath
|
|
2905
|
+
});
|
|
2906
|
+
const resolvedPath = __require.resolve(args.path, {
|
|
2907
|
+
paths: [triggerSdkPath]
|
|
2908
|
+
});
|
|
2909
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Externalizing ${args.path}`, {
|
|
2910
|
+
...args,
|
|
2911
|
+
triggerSdkPath,
|
|
2912
|
+
resolvedPath
|
|
2913
|
+
});
|
|
2914
|
+
return {
|
|
2915
|
+
path: resolvedPath,
|
|
2916
|
+
external: false
|
|
2917
|
+
};
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2725
2922
|
function workerSetupImportConfigPlugin(configPath) {
|
|
2726
2923
|
return {
|
|
2727
2924
|
name: "trigger-worker-setup",
|
|
@@ -2733,7 +2930,9 @@ function workerSetupImportConfigPlugin(configPath) {
|
|
|
2733
2930
|
let workerSetupContents = readFileSync(args.path, "utf-8");
|
|
2734
2931
|
workerSetupContents = workerSetupContents.replace(
|
|
2735
2932
|
"__SETUP_IMPORTED_PROJECT_CONFIG__",
|
|
2736
|
-
`import * as setupImportedConfigExports from "${
|
|
2933
|
+
`import * as setupImportedConfigExports from "${escapeImportPath(
|
|
2934
|
+
configPath
|
|
2935
|
+
)}"; const setupImportedConfig = setupImportedConfigExports.config;`
|
|
2737
2936
|
);
|
|
2738
2937
|
logger.debug("Loading worker setup", {
|
|
2739
2938
|
args,
|
|
@@ -2780,7 +2979,7 @@ function bundleDependenciesPlugin(buildIdentifier, dependenciesToBundle, tsconfi
|
|
|
2780
2979
|
return void 0;
|
|
2781
2980
|
}
|
|
2782
2981
|
}
|
|
2783
|
-
logger.
|
|
2982
|
+
logger.debug(`[${buildIdentifier}] Externalizing ${args.path}`, {
|
|
2784
2983
|
...args
|
|
2785
2984
|
});
|
|
2786
2985
|
return {
|
|
@@ -2868,12 +3067,728 @@ function getLoaderForFile(file) {
|
|
|
2868
3067
|
throw new Error(`Cannot get loader for file ${file}`);
|
|
2869
3068
|
}
|
|
2870
3069
|
|
|
3070
|
+
// src/utilities/deployErrors.ts
|
|
3071
|
+
import chalk4 from "chalk";
|
|
3072
|
+
import { relative as relative2 } from "node:path";
|
|
3073
|
+
import { groupTaskMetadataIssuesByTask } from "@trigger.dev/core/v3";
|
|
3074
|
+
import terminalLink from "terminal-link";
|
|
3075
|
+
|
|
3076
|
+
// src/utilities/links.ts
|
|
3077
|
+
var docs = {
|
|
3078
|
+
config: {
|
|
3079
|
+
home: "https://trigger.dev/docs/v3/trigger-config",
|
|
3080
|
+
esm: "https://trigger.dev/docs/v3/trigger-config#esm-only-packages",
|
|
3081
|
+
prisma: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators",
|
|
3082
|
+
additionalPackages: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators"
|
|
3083
|
+
}
|
|
3084
|
+
};
|
|
3085
|
+
var getInTouch = "https://trigger.dev/contact";
|
|
3086
|
+
|
|
3087
|
+
// src/utilities/deployErrors.ts
|
|
3088
|
+
function errorIsErrorLike(error) {
|
|
3089
|
+
return error instanceof Error || typeof error === "object" && error !== null && "message" in error;
|
|
3090
|
+
}
|
|
3091
|
+
function parseBuildErrorStack(error) {
|
|
3092
|
+
if (typeof error === "string") {
|
|
3093
|
+
return error;
|
|
3094
|
+
}
|
|
3095
|
+
if (errorIsErrorLike(error)) {
|
|
3096
|
+
if (typeof error.stack === "string") {
|
|
3097
|
+
const isErrRequireEsm = error.stack.includes("ERR_REQUIRE_ESM");
|
|
3098
|
+
let moduleName = null;
|
|
3099
|
+
if (isErrRequireEsm) {
|
|
3100
|
+
const moduleRegex = /node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)\/[^\/]+\s/;
|
|
3101
|
+
const match = moduleRegex.exec(error.stack);
|
|
3102
|
+
if (match) {
|
|
3103
|
+
moduleName = match[1];
|
|
3104
|
+
return {
|
|
3105
|
+
type: "esm-require-error",
|
|
3106
|
+
moduleName
|
|
3107
|
+
};
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
} else {
|
|
3111
|
+
return error.message;
|
|
3112
|
+
}
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
function logESMRequireError(parsedError, resolvedConfig) {
|
|
3116
|
+
logger.log(
|
|
3117
|
+
`
|
|
3118
|
+
${chalkError("X Error:")} The ${chalkPurple(
|
|
3119
|
+
parsedError.moduleName
|
|
3120
|
+
)} module is being required even though it's ESM only, and builds only support CommonJS. There are two ${chalk4.underline(
|
|
3121
|
+
"possible"
|
|
3122
|
+
)} ways to fix this:`
|
|
3123
|
+
);
|
|
3124
|
+
logger.log(
|
|
3125
|
+
`
|
|
3126
|
+
${chalkGrey("\u25CB")} Dynamically import the module in your code: ${chalkGrey(
|
|
3127
|
+
`const myModule = await import("${parsedError.moduleName}");`
|
|
3128
|
+
)}`
|
|
3129
|
+
);
|
|
3130
|
+
if (resolvedConfig.status === "file") {
|
|
3131
|
+
const relativePath = relative2(resolvedConfig.config.projectDir, resolvedConfig.path).replace(
|
|
3132
|
+
/\\/g,
|
|
3133
|
+
"/"
|
|
3134
|
+
);
|
|
3135
|
+
logger.log(
|
|
3136
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3137
|
+
parsedError.moduleName
|
|
3138
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3139
|
+
`(${relativePath})`
|
|
3140
|
+
)}. This will bundle the module with your code.
|
|
3141
|
+
`
|
|
3142
|
+
);
|
|
3143
|
+
} else {
|
|
3144
|
+
logger.log(
|
|
3145
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3146
|
+
parsedError.moduleName
|
|
3147
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3148
|
+
"(you'll need to create one)"
|
|
3149
|
+
)}. This will bundle the module with your code.
|
|
3150
|
+
`
|
|
3151
|
+
);
|
|
3152
|
+
}
|
|
3153
|
+
logger.log(
|
|
3154
|
+
`${chalkGrey("\u25CB")} For more info see the ${terminalLink("relevant docs", docs.config.esm)}.
|
|
3155
|
+
`
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
3158
|
+
function parseNpmInstallError(error) {
|
|
3159
|
+
if (typeof error === "string") {
|
|
3160
|
+
return error;
|
|
3161
|
+
}
|
|
3162
|
+
if (error instanceof Error) {
|
|
3163
|
+
if (typeof error.stack === "string") {
|
|
3164
|
+
const isPackageNotFoundError = error.stack.includes("ERR! 404 Not Found") && error.stack.includes("is not in this registry");
|
|
3165
|
+
let packageName = null;
|
|
3166
|
+
if (isPackageNotFoundError) {
|
|
3167
|
+
const packageNameRegex = /'([^']+)' is not in this registry/;
|
|
3168
|
+
const match = packageNameRegex.exec(error.stack);
|
|
3169
|
+
if (match) {
|
|
3170
|
+
packageName = match[1];
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
if (packageName) {
|
|
3174
|
+
return {
|
|
3175
|
+
type: "package-not-found-error",
|
|
3176
|
+
packageName
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
const noMatchingVersionRegex = /No matching version found for ([^\s]+)\s/;
|
|
3180
|
+
const noMatchingVersionMatch = noMatchingVersionRegex.exec(error.stack);
|
|
3181
|
+
if (noMatchingVersionMatch) {
|
|
3182
|
+
return {
|
|
3183
|
+
type: "no-matching-version-error",
|
|
3184
|
+
packageName: noMatchingVersionMatch[1].replace(/.$/, "")
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
return error.message;
|
|
3188
|
+
} else {
|
|
3189
|
+
return error.message;
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
return "Unknown error";
|
|
3193
|
+
}
|
|
3194
|
+
function logTaskMetadataParseError(zodIssues, tasks) {
|
|
3195
|
+
logger.log(
|
|
3196
|
+
`
|
|
3197
|
+
${chalkError("X Error:")} Failed to start. The following ${zodIssues.length === 1 ? "task issue was" : "task issues were"} found:`
|
|
3198
|
+
);
|
|
3199
|
+
const groupedIssues = groupTaskMetadataIssuesByTask(tasks, zodIssues);
|
|
3200
|
+
for (const key in groupedIssues) {
|
|
3201
|
+
const taskWithIssues = groupedIssues[key];
|
|
3202
|
+
if (!taskWithIssues) {
|
|
3203
|
+
continue;
|
|
3204
|
+
}
|
|
3205
|
+
logger.log(
|
|
3206
|
+
`
|
|
3207
|
+
${chalkWarning("\u276F")} ${taskWithIssues.exportName} ${chalkGrey("in")} ${taskWithIssues.filePath}`
|
|
3208
|
+
);
|
|
3209
|
+
for (const issue of taskWithIssues.issues) {
|
|
3210
|
+
if (issue.path) {
|
|
3211
|
+
logger.log(` ${chalkError("x")} ${issue.path} ${chalkGrey(issue.message)}`);
|
|
3212
|
+
} else {
|
|
3213
|
+
logger.log(` ${chalkError("x")} ${chalkGrey(issue.message)}`);
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3219
|
+
// src/utilities/javascriptProject.ts
|
|
3220
|
+
import { $ } from "execa";
|
|
3221
|
+
import { join as join4 } from "node:path";
|
|
3222
|
+
|
|
3223
|
+
// src/utilities/getUserPackageManager.ts
|
|
3224
|
+
import { findUp as findUp2 } from "find-up";
|
|
3225
|
+
import { basename } from "path";
|
|
3226
|
+
async function getUserPackageManager(path7) {
|
|
3227
|
+
const packageManager = await detectPackageManager(path7);
|
|
3228
|
+
logger.debug("Detected package manager", { packageManager });
|
|
3229
|
+
return packageManager;
|
|
3230
|
+
}
|
|
3231
|
+
async function detectPackageManager(path7) {
|
|
3232
|
+
try {
|
|
3233
|
+
return await detectPackageManagerFromArtifacts(path7);
|
|
3234
|
+
} catch (error) {
|
|
3235
|
+
return detectPackageManagerFromCurrentCommand();
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
function detectPackageManagerFromCurrentCommand() {
|
|
3239
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
3240
|
+
if (userAgent) {
|
|
3241
|
+
if (userAgent.startsWith("yarn")) {
|
|
3242
|
+
return "yarn";
|
|
3243
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
3244
|
+
return "pnpm";
|
|
3245
|
+
} else {
|
|
3246
|
+
return "npm";
|
|
3247
|
+
}
|
|
3248
|
+
} else {
|
|
3249
|
+
return "npm";
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
async function detectPackageManagerFromArtifacts(path7) {
|
|
3253
|
+
const artifacts = {
|
|
3254
|
+
yarn: "yarn.lock",
|
|
3255
|
+
pnpm: "pnpm-lock.yaml",
|
|
3256
|
+
npm: "package-lock.json",
|
|
3257
|
+
npmShrinkwrap: "npm-shrinkwrap.json"
|
|
3258
|
+
};
|
|
3259
|
+
const foundPath = await findUp2(Object.values(artifacts), { cwd: path7 });
|
|
3260
|
+
if (!foundPath) {
|
|
3261
|
+
throw new Error("Could not detect package manager from artifacts");
|
|
3262
|
+
}
|
|
3263
|
+
logger.debug("Found path from package manager artifacts", { foundPath });
|
|
3264
|
+
switch (basename(foundPath)) {
|
|
3265
|
+
case artifacts.yarn:
|
|
3266
|
+
return "yarn";
|
|
3267
|
+
case artifacts.pnpm:
|
|
3268
|
+
return "pnpm";
|
|
3269
|
+
case artifacts.npm:
|
|
3270
|
+
case artifacts.npmShrinkwrap:
|
|
3271
|
+
return "npm";
|
|
3272
|
+
default:
|
|
3273
|
+
throw new Error(`Unhandled package manager detection path: ${foundPath}`);
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3277
|
+
// src/utilities/assertExhaustive.ts
|
|
3278
|
+
function assertExhaustive(x) {
|
|
3279
|
+
throw new Error("Unexpected object: " + x);
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
// src/utilities/javascriptProject.ts
|
|
3283
|
+
import { builtinModules } from "node:module";
|
|
3284
|
+
import { recordSpanException as recordSpanException4 } from "@trigger.dev/core/v3/otel";
|
|
3285
|
+
import { flattenAttributes as flattenAttributes2 } from "@trigger.dev/core/v3";
|
|
3286
|
+
var JavascriptProject = class {
|
|
3287
|
+
constructor(projectPath) {
|
|
3288
|
+
this.projectPath = projectPath;
|
|
3289
|
+
}
|
|
3290
|
+
_packageJson;
|
|
3291
|
+
_packageManager;
|
|
3292
|
+
get packageJson() {
|
|
3293
|
+
if (!this._packageJson) {
|
|
3294
|
+
this._packageJson = readJSONFileSync(join4(this.projectPath, "package.json"));
|
|
3295
|
+
}
|
|
3296
|
+
return this._packageJson;
|
|
3297
|
+
}
|
|
3298
|
+
get scripts() {
|
|
3299
|
+
return {
|
|
3300
|
+
postinstall: this.packageJson.scripts?.postinstall ?? ""
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
3303
|
+
async install() {
|
|
3304
|
+
const command = await this.#getCommand();
|
|
3305
|
+
try {
|
|
3306
|
+
await command.installDependencies({
|
|
3307
|
+
cwd: this.projectPath
|
|
3308
|
+
});
|
|
3309
|
+
} catch (error) {
|
|
3310
|
+
logger.debug(`Failed to install dependencies using ${command.name}`, {
|
|
3311
|
+
error
|
|
3312
|
+
});
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
async resolveAll(packageNames, options) {
|
|
3316
|
+
return tracer.startActiveSpan("JavascriptProject.resolveAll", async (span) => {
|
|
3317
|
+
const externalPackages = packageNames.filter((packageName) => !isBuiltInModule(packageName));
|
|
3318
|
+
const opts = { allowDev: false, ...options };
|
|
3319
|
+
const command = await this.#getCommand();
|
|
3320
|
+
span.setAttributes({
|
|
3321
|
+
externalPackages,
|
|
3322
|
+
packageManager: command.name
|
|
3323
|
+
});
|
|
3324
|
+
try {
|
|
3325
|
+
const versions = await command.resolveDependencyVersions(externalPackages, {
|
|
3326
|
+
cwd: this.projectPath
|
|
3327
|
+
});
|
|
3328
|
+
if (versions) {
|
|
3329
|
+
logger.debug(`Resolved [${externalPackages.join(", ")}] version using ${command.name}`, {
|
|
3330
|
+
versions
|
|
3331
|
+
});
|
|
3332
|
+
span.setAttributes({
|
|
3333
|
+
...flattenAttributes2(versions, "versions")
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3336
|
+
const missingPackages = externalPackages.filter((packageName) => !versions[packageName]);
|
|
3337
|
+
const missingPackageVersions = {};
|
|
3338
|
+
for (const packageName of missingPackages) {
|
|
3339
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3340
|
+
if (typeof packageJsonVersion === "string") {
|
|
3341
|
+
logger.debug(`Resolved ${packageName} version using package.json`, {
|
|
3342
|
+
packageJsonVersion
|
|
3343
|
+
});
|
|
3344
|
+
missingPackageVersions[packageName] = packageJsonVersion;
|
|
3345
|
+
}
|
|
3346
|
+
if (opts.allowDev) {
|
|
3347
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3348
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3349
|
+
logger.debug(`Resolved ${packageName} version using devDependencies`, {
|
|
3350
|
+
devPackageJsonVersion
|
|
3351
|
+
});
|
|
3352
|
+
missingPackageVersions[packageName] = devPackageJsonVersion;
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
span.setAttributes({
|
|
3357
|
+
...flattenAttributes2(missingPackageVersions, "missingPackageVersions"),
|
|
3358
|
+
missingPackages
|
|
3359
|
+
});
|
|
3360
|
+
span.end();
|
|
3361
|
+
return { ...versions, ...missingPackageVersions };
|
|
3362
|
+
} catch (error) {
|
|
3363
|
+
recordSpanException4(span, error);
|
|
3364
|
+
span.end();
|
|
3365
|
+
logger.debug(`Failed to resolve dependency versions using ${command.name}`, {
|
|
3366
|
+
packageNames,
|
|
3367
|
+
error
|
|
3368
|
+
});
|
|
3369
|
+
return {};
|
|
3370
|
+
}
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3373
|
+
async resolve(packageName, options) {
|
|
3374
|
+
if (isBuiltInModule(packageName)) {
|
|
3375
|
+
return void 0;
|
|
3376
|
+
}
|
|
3377
|
+
const opts = { allowDev: false, ...options };
|
|
3378
|
+
const command = await this.#getCommand();
|
|
3379
|
+
try {
|
|
3380
|
+
const version2 = await command.resolveDependencyVersion(packageName, {
|
|
3381
|
+
cwd: this.projectPath
|
|
3382
|
+
});
|
|
3383
|
+
if (version2) {
|
|
3384
|
+
logger.debug(`Resolved ${packageName} version using ${command.name}`, { version: version2 });
|
|
3385
|
+
return version2;
|
|
3386
|
+
}
|
|
3387
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3388
|
+
if (typeof packageJsonVersion === "string") {
|
|
3389
|
+
logger.debug(`Resolved ${packageName} version using package.json`, { packageJsonVersion });
|
|
3390
|
+
return packageJsonVersion;
|
|
3391
|
+
}
|
|
3392
|
+
if (opts.allowDev) {
|
|
3393
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3394
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3395
|
+
logger.debug(`Resolved ${packageName} version using devDependencies`, {
|
|
3396
|
+
devPackageJsonVersion
|
|
3397
|
+
});
|
|
3398
|
+
return devPackageJsonVersion;
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
} catch (error) {
|
|
3402
|
+
logger.debug(`Failed to resolve dependency version using ${command.name}`, {
|
|
3403
|
+
packageName,
|
|
3404
|
+
error
|
|
3405
|
+
});
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
async #getCommand() {
|
|
3409
|
+
const packageManager = await this.getPackageManager();
|
|
3410
|
+
switch (packageManager) {
|
|
3411
|
+
case "npm":
|
|
3412
|
+
return new NPMCommands();
|
|
3413
|
+
case "pnpm":
|
|
3414
|
+
return new PNPMCommands();
|
|
3415
|
+
case "yarn":
|
|
3416
|
+
return new YarnCommands();
|
|
3417
|
+
default:
|
|
3418
|
+
assertExhaustive(packageManager);
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
async getPackageManager() {
|
|
3422
|
+
if (!this._packageManager) {
|
|
3423
|
+
this._packageManager = await getUserPackageManager(this.projectPath);
|
|
3424
|
+
}
|
|
3425
|
+
return this._packageManager;
|
|
3426
|
+
}
|
|
3427
|
+
};
|
|
3428
|
+
var PNPMCommands = class {
|
|
3429
|
+
get name() {
|
|
3430
|
+
return "pnpm";
|
|
3431
|
+
}
|
|
3432
|
+
get cmd() {
|
|
3433
|
+
return process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
3434
|
+
}
|
|
3435
|
+
async installDependencies(options) {
|
|
3436
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3437
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3438
|
+
}
|
|
3439
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3440
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} -r --json`;
|
|
3441
|
+
const result = JSON.parse(stdout);
|
|
3442
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`);
|
|
3443
|
+
for (const dep of result) {
|
|
3444
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3445
|
+
if (dependency) {
|
|
3446
|
+
return dependency.version;
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3451
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageNames} -r --json`;
|
|
3452
|
+
const result = JSON.parse(stdout);
|
|
3453
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`);
|
|
3454
|
+
const results = {};
|
|
3455
|
+
for (const dep of result) {
|
|
3456
|
+
for (const packageName of packageNames) {
|
|
3457
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3458
|
+
if (dependency) {
|
|
3459
|
+
results[packageName] = dependency.version;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
return results;
|
|
3464
|
+
}
|
|
3465
|
+
};
|
|
3466
|
+
var NPMCommands = class {
|
|
3467
|
+
get name() {
|
|
3468
|
+
return "npm";
|
|
3469
|
+
}
|
|
3470
|
+
get cmd() {
|
|
3471
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
3472
|
+
}
|
|
3473
|
+
async installDependencies(options) {
|
|
3474
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3475
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3476
|
+
}
|
|
3477
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3478
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} --json`;
|
|
3479
|
+
const output = JSON.parse(stdout);
|
|
3480
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`, { output });
|
|
3481
|
+
return this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3482
|
+
}
|
|
3483
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3484
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageNames} --json`;
|
|
3485
|
+
const output = JSON.parse(stdout);
|
|
3486
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`, { output });
|
|
3487
|
+
const results = {};
|
|
3488
|
+
for (const packageName of packageNames) {
|
|
3489
|
+
const version2 = this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3490
|
+
if (version2) {
|
|
3491
|
+
results[packageName] = version2;
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
return results;
|
|
3495
|
+
}
|
|
3496
|
+
#recursivelySearchDependencies(dependencies2, packageName) {
|
|
3497
|
+
for (const [name, dependency] of Object.entries(dependencies2)) {
|
|
3498
|
+
if (name === packageName) {
|
|
3499
|
+
return dependency.version;
|
|
3500
|
+
}
|
|
3501
|
+
if (dependency.dependencies) {
|
|
3502
|
+
const result = this.#recursivelySearchDependencies(dependency.dependencies, packageName);
|
|
3503
|
+
if (result) {
|
|
3504
|
+
return result;
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
};
|
|
3510
|
+
var YarnCommands = class {
|
|
3511
|
+
get name() {
|
|
3512
|
+
return "yarn";
|
|
3513
|
+
}
|
|
3514
|
+
get cmd() {
|
|
3515
|
+
return process.platform === "win32" ? "yarn.cmd" : "yarn";
|
|
3516
|
+
}
|
|
3517
|
+
async installDependencies(options) {
|
|
3518
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3519
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3520
|
+
}
|
|
3521
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3522
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} info ${packageName} --json`;
|
|
3523
|
+
const lines = stdout.split("\n");
|
|
3524
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`);
|
|
3525
|
+
for (const line of lines) {
|
|
3526
|
+
const json = JSON.parse(line);
|
|
3527
|
+
if (json.value === packageName) {
|
|
3528
|
+
return json.children.Version;
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3533
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} info ${packageNames} --json`;
|
|
3534
|
+
const lines = stdout.split("\n");
|
|
3535
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`);
|
|
3536
|
+
const results = {};
|
|
3537
|
+
for (const line of lines) {
|
|
3538
|
+
const json = JSON.parse(line);
|
|
3539
|
+
const packageName = this.#parseYarnValueIntoPackageName(json.value);
|
|
3540
|
+
if (packageNames.includes(packageName)) {
|
|
3541
|
+
results[packageName] = json.children.Version;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
return results;
|
|
3545
|
+
}
|
|
3546
|
+
// The "value" when doing yarn info is formatted like this:
|
|
3547
|
+
// "package-name@npm:version" or "package-name@workspace:version"
|
|
3548
|
+
// This function will parse the value into just the package name.
|
|
3549
|
+
// This correctly handles scoped packages as well e.g. @scope/package-name@npm:version
|
|
3550
|
+
#parseYarnValueIntoPackageName(value) {
|
|
3551
|
+
const parts = value.split("@");
|
|
3552
|
+
if (parts.length === 3) {
|
|
3553
|
+
return parts[1];
|
|
3554
|
+
}
|
|
3555
|
+
return parts[0];
|
|
3556
|
+
}
|
|
3557
|
+
};
|
|
3558
|
+
function isBuiltInModule(module) {
|
|
3559
|
+
if (module.startsWith("node:")) {
|
|
3560
|
+
return true;
|
|
3561
|
+
}
|
|
3562
|
+
return builtinModules.includes(module);
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
// src/utilities/resolveInternalFilePath.ts
|
|
3566
|
+
import path5 from "path";
|
|
3567
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3568
|
+
function cliRootPath() {
|
|
3569
|
+
const __filename2 = fileURLToPath3(import.meta.url);
|
|
3570
|
+
const __dirname2 = path5.dirname(__filename2);
|
|
3571
|
+
return __dirname2;
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
// src/utilities/safeJsonParse.ts
|
|
3575
|
+
function safeJsonParse(json) {
|
|
3576
|
+
if (!json) {
|
|
3577
|
+
return void 0;
|
|
3578
|
+
}
|
|
3579
|
+
try {
|
|
3580
|
+
return JSON.parse(json);
|
|
3581
|
+
} catch {
|
|
3582
|
+
return void 0;
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
// src/commands/update.ts
|
|
3587
|
+
import { confirm, intro as intro3, isCancel, log as log4, outro as outro4 } from "@clack/prompts";
|
|
3588
|
+
import { join as join5, resolve as resolve2 } from "path";
|
|
3589
|
+
var UpdateCommandOptions = CommonCommandOptions.pick({
|
|
3590
|
+
logLevel: true,
|
|
3591
|
+
skipTelemetry: true
|
|
3592
|
+
});
|
|
3593
|
+
function configureUpdateCommand(program2) {
|
|
3594
|
+
return program2.command("update").description("Updates all @trigger.dev/* packages to match the CLI version").argument("[path]", "The path to the directory that contains the package.json file", ".").option(
|
|
3595
|
+
"-l, --log-level <level>",
|
|
3596
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
3597
|
+
"log"
|
|
3598
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (path7, options) => {
|
|
3599
|
+
wrapCommandAction("dev", UpdateCommandOptions, options, async (opts) => {
|
|
3600
|
+
await printStandloneInitialBanner(true);
|
|
3601
|
+
await updateCommand(path7, opts);
|
|
3602
|
+
});
|
|
3603
|
+
});
|
|
3604
|
+
}
|
|
3605
|
+
var triggerPackageFilter = /^@trigger\.dev/;
|
|
3606
|
+
async function updateCommand(dir, options) {
|
|
3607
|
+
await updateTriggerPackages(dir, options);
|
|
3608
|
+
}
|
|
3609
|
+
async function updateTriggerPackages(dir, options, embedded, requireUpdate) {
|
|
3610
|
+
let hasOutput = false;
|
|
3611
|
+
if (!embedded) {
|
|
3612
|
+
intro3("Updating packages");
|
|
3613
|
+
}
|
|
3614
|
+
const projectPath = resolve2(process.cwd(), dir);
|
|
3615
|
+
const { packageJson, readonlyPackageJson, packageJsonPath } = await getPackageJson(projectPath);
|
|
3616
|
+
if (!packageJson) {
|
|
3617
|
+
log4.error("Failed to load package.json. Try to re-run with `-l debug` to see what's going on.");
|
|
3618
|
+
return false;
|
|
3619
|
+
}
|
|
3620
|
+
const cliVersion = getVersion();
|
|
3621
|
+
const newCliVersion = await updateCheck();
|
|
3622
|
+
if (newCliVersion) {
|
|
3623
|
+
prettyWarning(
|
|
3624
|
+
"You're not running the latest CLI version, please consider updating ASAP",
|
|
3625
|
+
`Current: ${cliVersion}
|
|
3626
|
+
Latest: ${newCliVersion}`,
|
|
3627
|
+
"Run latest: npx trigger.dev@beta"
|
|
3628
|
+
);
|
|
3629
|
+
hasOutput = true;
|
|
3630
|
+
}
|
|
3631
|
+
const triggerDependencies = getTriggerDependencies(packageJson);
|
|
3632
|
+
function getVersionMismatches(deps, targetVersion) {
|
|
3633
|
+
const mismatches = [];
|
|
3634
|
+
for (const dep of deps) {
|
|
3635
|
+
if (dep.version === targetVersion) {
|
|
3636
|
+
continue;
|
|
3637
|
+
}
|
|
3638
|
+
mismatches.push(dep);
|
|
3639
|
+
}
|
|
3640
|
+
return mismatches;
|
|
3641
|
+
}
|
|
3642
|
+
const versionMismatches = getVersionMismatches(triggerDependencies, cliVersion);
|
|
3643
|
+
if (versionMismatches.length === 0) {
|
|
3644
|
+
if (!embedded) {
|
|
3645
|
+
outro4(`Nothing to do${newCliVersion ? " ..but you should really update your CLI!" : ""}`);
|
|
3646
|
+
return hasOutput;
|
|
3647
|
+
}
|
|
3648
|
+
return hasOutput;
|
|
3649
|
+
}
|
|
3650
|
+
prettyWarning(
|
|
3651
|
+
"Mismatch between your CLI version and installed packages",
|
|
3652
|
+
"We recommend pinned versions for guaranteed compatibility"
|
|
3653
|
+
);
|
|
3654
|
+
if (!process.stdout.isTTY) {
|
|
3655
|
+
outro4("Deploy failed");
|
|
3656
|
+
console.log(
|
|
3657
|
+
`ERROR: Version mismatch detected while running in CI. This won't end well. Aborting.
|
|
3658
|
+
|
|
3659
|
+
Please run the dev command locally and check that your CLI version matches the one printed below. Additionally, all \`@trigger.dev/*\` packages also need to match this version.
|
|
3660
|
+
|
|
3661
|
+
If your local CLI version doesn't match the one below, you may want to pin the CLI version in this CI step. To do that, just replace \`trigger.dev@beta\` with \`trigger.dev@<FULL_VERSION>\`, for example: \`npx trigger.dev@3.0.0-beta.17 deploy\`
|
|
3662
|
+
|
|
3663
|
+
CLI version: ${cliVersion}
|
|
3664
|
+
|
|
3665
|
+
Current package versions that don't match the CLI:
|
|
3666
|
+
${versionMismatches.map((dep) => `- ${dep.name}@${dep.version}`).join("\n")}
|
|
3667
|
+
`
|
|
3668
|
+
);
|
|
3669
|
+
process.exit(1);
|
|
3670
|
+
}
|
|
3671
|
+
log4.message("");
|
|
3672
|
+
const userWantsToUpdate = await updateConfirmation(versionMismatches, cliVersion);
|
|
3673
|
+
if (isCancel(userWantsToUpdate)) {
|
|
3674
|
+
throw new OutroCommandError();
|
|
3675
|
+
}
|
|
3676
|
+
if (!userWantsToUpdate) {
|
|
3677
|
+
if (requireUpdate) {
|
|
3678
|
+
outro4("You shall not pass!");
|
|
3679
|
+
logger.log(
|
|
3680
|
+
`${chalkError(
|
|
3681
|
+
"X Error:"
|
|
3682
|
+
)} Update required: Version mismatches are a common source of bugs and errors. Please update or use \`--skip-update-check\` at your own risk.
|
|
3683
|
+
`
|
|
3684
|
+
);
|
|
3685
|
+
process.exit(1);
|
|
3686
|
+
}
|
|
3687
|
+
if (!embedded) {
|
|
3688
|
+
outro4("You've been warned!");
|
|
3689
|
+
}
|
|
3690
|
+
return hasOutput;
|
|
3691
|
+
}
|
|
3692
|
+
const installSpinner = spinner();
|
|
3693
|
+
installSpinner.start("Writing new package.json file");
|
|
3694
|
+
const packageJsonBackupPath = `${packageJsonPath}.bak`;
|
|
3695
|
+
await writeJSONFile(packageJsonBackupPath, readonlyPackageJson, true);
|
|
3696
|
+
const exitHandler = async (sig) => {
|
|
3697
|
+
log4.warn(
|
|
3698
|
+
`You may have to manually roll back any package.json changes. Backup written to ${packageJsonBackupPath}`
|
|
3699
|
+
);
|
|
3700
|
+
};
|
|
3701
|
+
process.prependOnceListener("exit", exitHandler);
|
|
3702
|
+
mutatePackageJsonWithUpdatedPackages(packageJson, versionMismatches, cliVersion);
|
|
3703
|
+
await writeJSONFile(packageJsonPath, packageJson, true);
|
|
3704
|
+
async function revertPackageJsonChanges() {
|
|
3705
|
+
await writeJSONFile(packageJsonPath, readonlyPackageJson, true);
|
|
3706
|
+
await removeFile(packageJsonBackupPath);
|
|
3707
|
+
}
|
|
3708
|
+
installSpinner.message("Installing new package versions");
|
|
3709
|
+
const jsProject = new JavascriptProject(projectPath);
|
|
3710
|
+
let packageManager;
|
|
3711
|
+
try {
|
|
3712
|
+
packageManager = await jsProject.getPackageManager();
|
|
3713
|
+
installSpinner.message(`Installing new package versions with ${packageManager}`);
|
|
3714
|
+
await jsProject.install();
|
|
3715
|
+
} catch (error) {
|
|
3716
|
+
installSpinner.stop(
|
|
3717
|
+
`Failed to install new package versions${packageManager ? ` with ${packageManager}` : ""}`
|
|
3718
|
+
);
|
|
3719
|
+
process.removeListener("exit", exitHandler);
|
|
3720
|
+
await revertPackageJsonChanges();
|
|
3721
|
+
throw error;
|
|
3722
|
+
}
|
|
3723
|
+
installSpinner.stop("Installed new package versions");
|
|
3724
|
+
process.removeListener("exit", exitHandler);
|
|
3725
|
+
await removeFile(packageJsonBackupPath);
|
|
3726
|
+
if (!embedded) {
|
|
3727
|
+
outro4(
|
|
3728
|
+
`Packages updated${newCliVersion ? " ..but you should really update your CLI too!" : ""}`
|
|
3729
|
+
);
|
|
3730
|
+
}
|
|
3731
|
+
return hasOutput;
|
|
3732
|
+
}
|
|
3733
|
+
function getTriggerDependencies(packageJson) {
|
|
3734
|
+
const deps = [];
|
|
3735
|
+
for (const type of ["dependencies", "devDependencies"]) {
|
|
3736
|
+
for (const [name, version2] of Object.entries(packageJson[type] ?? {})) {
|
|
3737
|
+
if (!version2) {
|
|
3738
|
+
continue;
|
|
3739
|
+
}
|
|
3740
|
+
if (version2.startsWith("workspace")) {
|
|
3741
|
+
continue;
|
|
3742
|
+
}
|
|
3743
|
+
if (!triggerPackageFilter.test(name)) {
|
|
3744
|
+
continue;
|
|
3745
|
+
}
|
|
3746
|
+
const ignoredPackages = ["@trigger.dev/companyicons"];
|
|
3747
|
+
if (ignoredPackages.includes(name)) {
|
|
3748
|
+
continue;
|
|
3749
|
+
}
|
|
3750
|
+
deps.push({ type, name, version: version2 });
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
return deps;
|
|
3754
|
+
}
|
|
3755
|
+
function mutatePackageJsonWithUpdatedPackages(packageJson, depsToUpdate, targetVersion) {
|
|
3756
|
+
for (const { type, name, version: version2 } of depsToUpdate) {
|
|
3757
|
+
if (!packageJson[type]) {
|
|
3758
|
+
throw new Error(
|
|
3759
|
+
`No ${type} entry found in package.json. Please try to upgrade manually instead.`
|
|
3760
|
+
);
|
|
3761
|
+
}
|
|
3762
|
+
packageJson[type][name] = targetVersion;
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
function printUpdateTable(depsToUpdate, targetVersion) {
|
|
3766
|
+
log4.message("Suggested updates");
|
|
3767
|
+
const tableData = depsToUpdate.map((dep) => ({
|
|
3768
|
+
package: dep.name,
|
|
3769
|
+
old: dep.version,
|
|
3770
|
+
new: targetVersion
|
|
3771
|
+
}));
|
|
3772
|
+
logger.table(tableData);
|
|
3773
|
+
}
|
|
3774
|
+
async function updateConfirmation(depsToUpdate, targetVersion) {
|
|
3775
|
+
printUpdateTable(depsToUpdate, targetVersion);
|
|
3776
|
+
let confirmMessage = "Would you like to apply those updates?";
|
|
3777
|
+
return await confirm({
|
|
3778
|
+
message: confirmMessage
|
|
3779
|
+
});
|
|
3780
|
+
}
|
|
3781
|
+
async function getPackageJson(absoluteProjectPath) {
|
|
3782
|
+
const packageJsonPath = join5(absoluteProjectPath, "package.json");
|
|
3783
|
+
const readonlyPackageJson = Object.freeze(await readJSONFile(packageJsonPath));
|
|
3784
|
+
const packageJson = structuredClone(readonlyPackageJson);
|
|
3785
|
+
return { packageJson, readonlyPackageJson, packageJsonPath };
|
|
3786
|
+
}
|
|
3787
|
+
|
|
2871
3788
|
// src/commands/deploy.ts
|
|
2872
|
-
import { Glob } from "glob";
|
|
2873
3789
|
var DeployCommandOptions = CommonCommandOptions.extend({
|
|
2874
3790
|
skipTypecheck: z4.boolean().default(false),
|
|
2875
3791
|
skipDeploy: z4.boolean().default(false),
|
|
2876
|
-
ignoreEnvVarCheck: z4.boolean().default(false),
|
|
2877
3792
|
env: z4.enum(["prod", "staging"]),
|
|
2878
3793
|
loadImage: z4.boolean().default(false),
|
|
2879
3794
|
buildPlatform: z4.enum(["linux/amd64", "linux/arm64"]).default("linux/amd64"),
|
|
@@ -2883,7 +3798,10 @@ var DeployCommandOptions = CommonCommandOptions.extend({
|
|
|
2883
3798
|
config: z4.string().optional(),
|
|
2884
3799
|
projectRef: z4.string().optional(),
|
|
2885
3800
|
outputMetafile: z4.string().optional(),
|
|
2886
|
-
apiUrl: z4.string().optional()
|
|
3801
|
+
apiUrl: z4.string().optional(),
|
|
3802
|
+
saveLogs: z4.boolean().default(false),
|
|
3803
|
+
skipUpdateCheck: z4.boolean().default(false),
|
|
3804
|
+
noCache: z4.boolean().default(false)
|
|
2887
3805
|
});
|
|
2888
3806
|
function configureDeployCommand(program2) {
|
|
2889
3807
|
return commonOptions(
|
|
@@ -2891,18 +3809,20 @@ function configureDeployCommand(program2) {
|
|
|
2891
3809
|
"-e, --env <env>",
|
|
2892
3810
|
"Deploy to a specific environment (currently only prod and staging are supported)",
|
|
2893
3811
|
"prod"
|
|
2894
|
-
).option("--skip-typecheck", "Whether to skip the pre-build typecheck").option(
|
|
2895
|
-
"--ignore-env-var-check",
|
|
2896
|
-
"Detected missing environment variables won't block deployment"
|
|
2897
|
-
).option("-c, --config <config file>", "The name of the config file, found at [path]").option(
|
|
3812
|
+
).option("--skip-typecheck", "Whether to skip the pre-build typecheck").option("--skip-update-check", "Skip checking for @trigger.dev package updates").option("-c, --config <config file>", "The name of the config file, found at [path]").option(
|
|
2898
3813
|
"-p, --project-ref <project ref>",
|
|
2899
|
-
"The project ref. Required if there is no config file."
|
|
3814
|
+
"The project ref. Required if there is no config file. This will override the project specified in the config file."
|
|
2900
3815
|
)
|
|
2901
3816
|
).addOption(
|
|
2902
3817
|
new CommandOption(
|
|
2903
3818
|
"--self-hosted",
|
|
2904
3819
|
"Build and load the image using your local Docker. Use the --registry option to specify the registry to push the image to when using --self-hosted, or just use --push-image to push to the default registry."
|
|
2905
3820
|
).hideHelp()
|
|
3821
|
+
).addOption(
|
|
3822
|
+
new CommandOption(
|
|
3823
|
+
"--no-cache",
|
|
3824
|
+
"Do not use the cache when building the image. This will slow down the build process but can be useful if you are experiencing issues with the cache."
|
|
3825
|
+
).hideHelp()
|
|
2906
3826
|
).addOption(
|
|
2907
3827
|
new CommandOption(
|
|
2908
3828
|
"--push",
|
|
@@ -2918,6 +3838,11 @@ function configureDeployCommand(program2) {
|
|
|
2918
3838
|
"--tag <tag>",
|
|
2919
3839
|
"(Coming soon) Specify the tag to use when pushing the image to the registry"
|
|
2920
3840
|
).hideHelp()
|
|
3841
|
+
).addOption(
|
|
3842
|
+
new CommandOption(
|
|
3843
|
+
"--ignore-env-var-check",
|
|
3844
|
+
"(deprecated) Detected missing environment variables won't block deployment"
|
|
3845
|
+
).hideHelp()
|
|
2921
3846
|
).addOption(new CommandOption("-D, --skip-deploy", "Skip deploying the image").hideHelp()).addOption(
|
|
2922
3847
|
new CommandOption("--load-image", "Load the built image into your local docker").hideHelp()
|
|
2923
3848
|
).addOption(
|
|
@@ -2930,10 +3855,15 @@ function configureDeployCommand(program2) {
|
|
|
2930
3855
|
"--output-metafile <path>",
|
|
2931
3856
|
"If provided, will save the esbuild metafile for the build to the specified path"
|
|
2932
3857
|
).hideHelp()
|
|
2933
|
-
).
|
|
3858
|
+
).addOption(
|
|
3859
|
+
new CommandOption(
|
|
3860
|
+
"--save-logs",
|
|
3861
|
+
"If provided, will save logs even for successful builds"
|
|
3862
|
+
).hideHelp()
|
|
3863
|
+
).action(async (path7, options) => {
|
|
2934
3864
|
await handleTelemetry(async () => {
|
|
2935
3865
|
await printStandloneInitialBanner(true);
|
|
2936
|
-
await deployCommand(
|
|
3866
|
+
await deployCommand(path7, options);
|
|
2937
3867
|
});
|
|
2938
3868
|
});
|
|
2939
3869
|
}
|
|
@@ -2944,7 +3874,10 @@ async function deployCommand(dir, options) {
|
|
|
2944
3874
|
}
|
|
2945
3875
|
async function _deployCommand(dir, options) {
|
|
2946
3876
|
const span = trace2.getSpan(context.active());
|
|
2947
|
-
|
|
3877
|
+
intro4("Deploying project");
|
|
3878
|
+
if (!options.skipUpdateCheck) {
|
|
3879
|
+
await updateTriggerPackages(dir, { ...options }, true, true);
|
|
3880
|
+
}
|
|
2948
3881
|
const authorization = await login({
|
|
2949
3882
|
embedded: true,
|
|
2950
3883
|
defaultApiUrl: options.apiUrl,
|
|
@@ -2968,6 +3901,11 @@ async function _deployCommand(dir, options) {
|
|
|
2968
3901
|
configFile: options.config,
|
|
2969
3902
|
projectRef: options.projectRef
|
|
2970
3903
|
});
|
|
3904
|
+
if (resolvedConfig.status === "error") {
|
|
3905
|
+
logger.error("Failed to read config:", resolvedConfig.error);
|
|
3906
|
+
span && recordSpanException5(span, resolvedConfig.error);
|
|
3907
|
+
throw new SkipLoggingError("Failed to read config");
|
|
3908
|
+
}
|
|
2971
3909
|
logger.debug("Resolved config", { resolvedConfig });
|
|
2972
3910
|
span?.setAttributes({
|
|
2973
3911
|
"resolvedConfig.status": resolvedConfig.status,
|
|
@@ -2976,7 +3914,7 @@ async function _deployCommand(dir, options) {
|
|
|
2976
3914
|
"resolvedConfig.config.projectDir": resolvedConfig.config.projectDir,
|
|
2977
3915
|
"resolvedConfig.config.triggerUrl": resolvedConfig.config.triggerUrl,
|
|
2978
3916
|
"resolvedConfig.config.triggerDirectories": resolvedConfig.config.triggerDirectories,
|
|
2979
|
-
...
|
|
3917
|
+
...flattenAttributes3(resolvedConfig.config.retries, "resolvedConfig.config.retries")
|
|
2980
3918
|
});
|
|
2981
3919
|
const apiClient2 = new CliApiClient(authorization.auth.apiUrl, authorization.auth.accessToken);
|
|
2982
3920
|
const deploymentEnv = await apiClient2.getProjectEnv({
|
|
@@ -2987,7 +3925,7 @@ async function _deployCommand(dir, options) {
|
|
|
2987
3925
|
throw new Error(deploymentEnv.error);
|
|
2988
3926
|
}
|
|
2989
3927
|
const environmentClient = new CliApiClient(authorization.auth.apiUrl, deploymentEnv.data.apiKey);
|
|
2990
|
-
|
|
3928
|
+
log5.step(
|
|
2991
3929
|
`Preparing to deploy "${deploymentEnv.data.name}" (${resolvedConfig.config.project}) to ${options.env}`
|
|
2992
3930
|
);
|
|
2993
3931
|
const compilation = await compileProject(
|
|
@@ -2996,15 +3934,6 @@ async function _deployCommand(dir, options) {
|
|
|
2996
3934
|
resolvedConfig.status === "file" ? resolvedConfig.path : void 0
|
|
2997
3935
|
);
|
|
2998
3936
|
logger.debug("Compilation result", { compilation });
|
|
2999
|
-
if (compilation.envVars.length > 0) {
|
|
3000
|
-
await checkEnvVars(
|
|
3001
|
-
compilation.envVars ?? [],
|
|
3002
|
-
resolvedConfig.config,
|
|
3003
|
-
options,
|
|
3004
|
-
environmentClient,
|
|
3005
|
-
authorization.dashboardUrl
|
|
3006
|
-
);
|
|
3007
|
-
}
|
|
3008
3937
|
const deploymentResponse = await environmentClient.initializeDeployment({
|
|
3009
3938
|
contentHash: compilation.contentHash,
|
|
3010
3939
|
userId: authorization.userId
|
|
@@ -3018,7 +3947,7 @@ async function _deployCommand(dir, options) {
|
|
|
3018
3947
|
);
|
|
3019
3948
|
}
|
|
3020
3949
|
const version2 = deploymentResponse.data.version;
|
|
3021
|
-
const deploymentSpinner =
|
|
3950
|
+
const deploymentSpinner = spinner();
|
|
3022
3951
|
deploymentSpinner.start(`Deploying version ${version2}`);
|
|
3023
3952
|
const selfHostedRegistryHost = deploymentResponse.data.registryHost ?? options.registry;
|
|
3024
3953
|
const registryHost = selfHostedRegistryHost ?? "registry.trigger.dev";
|
|
@@ -3035,7 +3964,8 @@ async function _deployCommand(dir, options) {
|
|
|
3035
3964
|
projectRef: resolvedConfig.config.project,
|
|
3036
3965
|
buildPlatform: options.buildPlatform,
|
|
3037
3966
|
pushImage: options.push,
|
|
3038
|
-
selfHostedRegistry: !!options.registry
|
|
3967
|
+
selfHostedRegistry: !!options.registry,
|
|
3968
|
+
noCache: options.noCache
|
|
3039
3969
|
});
|
|
3040
3970
|
}
|
|
3041
3971
|
if (!deploymentResponse.data.externalBuildData) {
|
|
@@ -3043,28 +3973,57 @@ async function _deployCommand(dir, options) {
|
|
|
3043
3973
|
"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."
|
|
3044
3974
|
);
|
|
3045
3975
|
}
|
|
3046
|
-
return buildAndPushImage(
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3976
|
+
return buildAndPushImage(
|
|
3977
|
+
{
|
|
3978
|
+
registryHost,
|
|
3979
|
+
auth: authorization.auth.accessToken,
|
|
3980
|
+
imageTag: deploymentResponse.data.imageTag,
|
|
3981
|
+
buildId: deploymentResponse.data.externalBuildData.buildId,
|
|
3982
|
+
buildToken: deploymentResponse.data.externalBuildData.buildToken,
|
|
3983
|
+
buildProjectId: deploymentResponse.data.externalBuildData.projectId,
|
|
3984
|
+
cwd: compilation.path,
|
|
3985
|
+
projectId: resolvedConfig.config.project,
|
|
3986
|
+
deploymentId: deploymentResponse.data.id,
|
|
3987
|
+
deploymentVersion: deploymentResponse.data.version,
|
|
3988
|
+
contentHash: deploymentResponse.data.contentHash,
|
|
3989
|
+
projectRef: resolvedConfig.config.project,
|
|
3990
|
+
loadImage: options.loadImage,
|
|
3991
|
+
buildPlatform: options.buildPlatform,
|
|
3992
|
+
noCache: options.noCache
|
|
3993
|
+
},
|
|
3994
|
+
deploymentSpinner
|
|
3995
|
+
);
|
|
3062
3996
|
};
|
|
3063
3997
|
const image = await buildImage();
|
|
3998
|
+
const warnings = checkLogsForWarnings(image.logs);
|
|
3999
|
+
if (!warnings.ok) {
|
|
4000
|
+
await failDeploy(
|
|
4001
|
+
deploymentResponse.data.shortCode,
|
|
4002
|
+
warnings.summary,
|
|
4003
|
+
image.logs,
|
|
4004
|
+
deploymentSpinner,
|
|
4005
|
+
warnings.warnings,
|
|
4006
|
+
warnings.errors
|
|
4007
|
+
);
|
|
4008
|
+
throw new SkipLoggingError(`Failed to build project image: ${warnings.summary}`);
|
|
4009
|
+
}
|
|
3064
4010
|
if (!image.ok) {
|
|
3065
|
-
|
|
4011
|
+
await failDeploy(
|
|
4012
|
+
deploymentResponse.data.shortCode,
|
|
4013
|
+
image.error,
|
|
4014
|
+
image.logs,
|
|
4015
|
+
deploymentSpinner,
|
|
4016
|
+
warnings.warnings
|
|
4017
|
+
);
|
|
3066
4018
|
throw new SkipLoggingError(`Failed to build project image: ${image.error}`);
|
|
3067
4019
|
}
|
|
4020
|
+
const preExitTasks = async () => {
|
|
4021
|
+
printWarnings(warnings.warnings);
|
|
4022
|
+
if (options.saveLogs) {
|
|
4023
|
+
const logPath = await saveLogs(deploymentResponse.data.shortCode, image.logs);
|
|
4024
|
+
log5.info(`Build logs have been saved to ${logPath}`);
|
|
4025
|
+
}
|
|
4026
|
+
};
|
|
3068
4027
|
const imageReference = options.selfHosted ? `${selfHostedRegistryHost ? `${selfHostedRegistryHost}/` : ""}${image.image}${image.digest ? `@${image.digest}` : ""}` : `${registryHost}/${image.image}${image.digest ? `@${image.digest}` : ""}`;
|
|
3069
4028
|
span?.setAttributes({
|
|
3070
4029
|
"image.reference": imageReference
|
|
@@ -3073,6 +4032,7 @@ async function _deployCommand(dir, options) {
|
|
|
3073
4032
|
deploymentSpinner.stop(
|
|
3074
4033
|
`Project image built: ${imageReference}. Skipping deployment as requested`
|
|
3075
4034
|
);
|
|
4035
|
+
await preExitTasks();
|
|
3076
4036
|
throw new SkipCommandError("Skipping deployment as requested");
|
|
3077
4037
|
}
|
|
3078
4038
|
deploymentSpinner.message(
|
|
@@ -3082,11 +4042,13 @@ async function _deployCommand(dir, options) {
|
|
|
3082
4042
|
const startIndexingResponse = await environmentClient.startDeploymentIndexing(
|
|
3083
4043
|
deploymentResponse.data.id,
|
|
3084
4044
|
{
|
|
3085
|
-
imageReference
|
|
4045
|
+
imageReference,
|
|
4046
|
+
selfHosted: options.selfHosted
|
|
3086
4047
|
}
|
|
3087
4048
|
);
|
|
3088
4049
|
if (!startIndexingResponse.success) {
|
|
3089
4050
|
deploymentSpinner.stop(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
4051
|
+
await preExitTasks();
|
|
3090
4052
|
throw new SkipLoggingError(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
3091
4053
|
}
|
|
3092
4054
|
const finishedDeployment = await waitForDeploymentToFinish(
|
|
@@ -3095,26 +4057,33 @@ async function _deployCommand(dir, options) {
|
|
|
3095
4057
|
);
|
|
3096
4058
|
if (!finishedDeployment) {
|
|
3097
4059
|
deploymentSpinner.stop(`Deployment failed to complete`);
|
|
4060
|
+
await preExitTasks();
|
|
3098
4061
|
throw new SkipLoggingError("Deployment failed to complete: unknown issue");
|
|
3099
4062
|
}
|
|
3100
4063
|
if (typeof finishedDeployment === "string") {
|
|
3101
4064
|
deploymentSpinner.stop(`Deployment failed to complete: ${finishedDeployment}`);
|
|
4065
|
+
await preExitTasks();
|
|
3102
4066
|
throw new SkipLoggingError(`Deployment failed to complete: ${finishedDeployment}`);
|
|
3103
4067
|
}
|
|
3104
|
-
const deploymentLink =
|
|
4068
|
+
const deploymentLink = terminalLink2(
|
|
3105
4069
|
"View deployment",
|
|
3106
4070
|
`${authorization.dashboardUrl}/projects/v3/${resolvedConfig.config.project}/deployments/${finishedDeployment.shortCode}`
|
|
3107
4071
|
);
|
|
3108
4072
|
switch (finishedDeployment.status) {
|
|
3109
4073
|
case "DEPLOYED": {
|
|
3110
|
-
|
|
4074
|
+
if (warnings.warnings.length > 0) {
|
|
4075
|
+
deploymentSpinner.stop("Deployment completed with warnings");
|
|
4076
|
+
} else {
|
|
4077
|
+
deploymentSpinner.stop("Deployment completed");
|
|
4078
|
+
}
|
|
4079
|
+
await preExitTasks();
|
|
3111
4080
|
const taskCount = finishedDeployment.worker?.tasks.length ?? 0;
|
|
3112
4081
|
if (taskCount === 0) {
|
|
3113
|
-
|
|
4082
|
+
outro5(
|
|
3114
4083
|
`Version ${version2} deployed with no detected tasks. Please make sure you are exporting tasks in your project. ${deploymentLink}`
|
|
3115
4084
|
);
|
|
3116
4085
|
} else {
|
|
3117
|
-
|
|
4086
|
+
outro5(
|
|
3118
4087
|
`Version ${version2} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${deploymentLink}`
|
|
3119
4088
|
);
|
|
3120
4089
|
}
|
|
@@ -3122,10 +4091,29 @@ async function _deployCommand(dir, options) {
|
|
|
3122
4091
|
}
|
|
3123
4092
|
case "FAILED": {
|
|
3124
4093
|
if (finishedDeployment.errorData) {
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
4094
|
+
if (finishedDeployment.errorData.name === "TaskMetadataParseError") {
|
|
4095
|
+
const errorJson = safeJsonParse(finishedDeployment.errorData.stack);
|
|
4096
|
+
if (errorJson) {
|
|
4097
|
+
const parsedError2 = TaskMetadataFailedToParseData.safeParse(errorJson);
|
|
4098
|
+
if (parsedError2.success) {
|
|
4099
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4100
|
+
logTaskMetadataParseError(parsedError2.data.zodIssues, parsedError2.data.tasks);
|
|
4101
|
+
await preExitTasks();
|
|
4102
|
+
throw new SkipLoggingError(
|
|
4103
|
+
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
4104
|
+
);
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
const parsedError = finishedDeployment.errorData.stack ? parseBuildErrorStack(finishedDeployment.errorData) ?? finishedDeployment.errorData.message : finishedDeployment.errorData.message;
|
|
4109
|
+
if (typeof parsedError === "string") {
|
|
4110
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4111
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
4112
|
+
} else {
|
|
4113
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4114
|
+
logESMRequireError(parsedError, resolvedConfig);
|
|
4115
|
+
}
|
|
4116
|
+
await preExitTasks();
|
|
3129
4117
|
throw new SkipLoggingError(
|
|
3130
4118
|
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3131
4119
|
);
|
|
@@ -3133,62 +4121,132 @@ async function _deployCommand(dir, options) {
|
|
|
3133
4121
|
deploymentSpinner.stop(
|
|
3134
4122
|
`Deployment failed with an unknown error. Please contact eric@trigger.dev for help. ${deploymentLink}`
|
|
3135
4123
|
);
|
|
4124
|
+
await preExitTasks();
|
|
3136
4125
|
throw new SkipLoggingError("Deployment failed with an unknown error");
|
|
3137
4126
|
}
|
|
3138
4127
|
}
|
|
3139
4128
|
case "CANCELED": {
|
|
3140
4129
|
deploymentSpinner.stop(`Deployment was canceled. ${deploymentLink}`);
|
|
4130
|
+
await preExitTasks();
|
|
3141
4131
|
throw new SkipLoggingError("Deployment was canceled");
|
|
3142
4132
|
}
|
|
3143
|
-
case "TIMED_OUT": {
|
|
3144
|
-
deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
|
|
3145
|
-
|
|
4133
|
+
case "TIMED_OUT": {
|
|
4134
|
+
deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
|
|
4135
|
+
await preExitTasks();
|
|
4136
|
+
throw new SkipLoggingError("Deployment timed out");
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
function printErrors(errors) {
|
|
4141
|
+
for (const error of errors ?? []) {
|
|
4142
|
+
log5.error(`${chalkError("Error:")} ${error}`);
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
function printWarnings(warnings) {
|
|
4146
|
+
for (const warning of warnings ?? []) {
|
|
4147
|
+
log5.warn(`${chalkWarning("Warning:")} ${warning}`);
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
function checkLogsForWarnings(logs) {
|
|
4151
|
+
const warnings = [
|
|
4152
|
+
{
|
|
4153
|
+
regex: /prisma:warn We could not find your Prisma schema/,
|
|
4154
|
+
message: `Prisma generate failed to find the default schema. Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4155
|
+
"Config docs",
|
|
4156
|
+
docs.config.prisma
|
|
4157
|
+
)}
|
|
4158
|
+
Custom schema paths require a postinstall script like this: \`prisma generate --schema=./custom/path/to/schema.prisma\``,
|
|
4159
|
+
shouldFail: true
|
|
4160
|
+
}
|
|
4161
|
+
];
|
|
4162
|
+
const errorMessages2 = [];
|
|
4163
|
+
const warningMessages = [];
|
|
4164
|
+
let shouldFail = false;
|
|
4165
|
+
for (const warning of warnings) {
|
|
4166
|
+
const matches = logs.match(warning.regex);
|
|
4167
|
+
if (!matches) {
|
|
4168
|
+
continue;
|
|
4169
|
+
}
|
|
4170
|
+
const message = getMessageFromTemplate(warning.message, matches.groups);
|
|
4171
|
+
if (warning.shouldFail) {
|
|
4172
|
+
shouldFail = true;
|
|
4173
|
+
errorMessages2.push(message);
|
|
4174
|
+
} else {
|
|
4175
|
+
warningMessages.push(message);
|
|
4176
|
+
}
|
|
4177
|
+
}
|
|
4178
|
+
if (shouldFail) {
|
|
4179
|
+
return {
|
|
4180
|
+
ok: false,
|
|
4181
|
+
summary: "Build succeeded with critical warnings. Will not proceed",
|
|
4182
|
+
warnings: warningMessages,
|
|
4183
|
+
errors: errorMessages2
|
|
4184
|
+
};
|
|
4185
|
+
}
|
|
4186
|
+
return {
|
|
4187
|
+
ok: true,
|
|
4188
|
+
warnings: warningMessages
|
|
4189
|
+
};
|
|
4190
|
+
}
|
|
4191
|
+
function checkLogsForErrors(logs) {
|
|
4192
|
+
const errors = [
|
|
4193
|
+
{
|
|
4194
|
+
regex: /Error: Provided --schema at (?<schema>.*) doesn't exist/,
|
|
4195
|
+
message: `Prisma generate failed to find the specified schema at "$schema".
|
|
4196
|
+
Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4197
|
+
"Config docs",
|
|
4198
|
+
docs.config.prisma
|
|
4199
|
+
)}`
|
|
4200
|
+
},
|
|
4201
|
+
{
|
|
4202
|
+
regex: /sh: 1: (?<packageOrBinary>.*): not found/,
|
|
4203
|
+
message: `$packageOrBinary not found
|
|
4204
|
+
|
|
4205
|
+
If it's a package: Include it in ${terminalLink2(
|
|
4206
|
+
"config.additionalPackages",
|
|
4207
|
+
docs.config.prisma
|
|
4208
|
+
)}
|
|
4209
|
+
If it's a binary: Please ${terminalLink2(
|
|
4210
|
+
"get in touch",
|
|
4211
|
+
getInTouch
|
|
4212
|
+
)} and we'll see what we can do!`
|
|
4213
|
+
}
|
|
4214
|
+
];
|
|
4215
|
+
for (const error of errors) {
|
|
4216
|
+
const matches = logs.match(error.regex);
|
|
4217
|
+
if (!matches) {
|
|
4218
|
+
continue;
|
|
3146
4219
|
}
|
|
4220
|
+
const message = getMessageFromTemplate(error.message, matches.groups);
|
|
4221
|
+
log5.error(`${chalkError("Error:")} ${message}`);
|
|
4222
|
+
break;
|
|
3147
4223
|
}
|
|
3148
4224
|
}
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
environmentVariablesSpinner.start("Checking environment variables");
|
|
3155
|
-
const environmentVariables = await environmentClient.getEnvironmentVariables(config.project);
|
|
3156
|
-
if (!environmentVariables.success) {
|
|
3157
|
-
environmentVariablesSpinner.stop(`Failed to fetch environment variables, skipping check`);
|
|
3158
|
-
} else {
|
|
3159
|
-
const missingEnvironmentVariables = envVars.filter(
|
|
3160
|
-
(envVar) => environmentVariables.data.variables[envVar] === void 0
|
|
3161
|
-
);
|
|
3162
|
-
if (missingEnvironmentVariables.length > 0) {
|
|
3163
|
-
environmentVariablesSpinner.stop(
|
|
3164
|
-
`Found missing env vars in ${options.env}: ${arrayToSentence(
|
|
3165
|
-
missingEnvironmentVariables
|
|
3166
|
-
)}. ${options.ignoreEnvVarCheck ? "Continuing deployment because of --ignore-env-var-check. " : "Aborting deployment. "}${chalk4.bgBlueBright(
|
|
3167
|
-
terminalLink(
|
|
3168
|
-
"Manage env vars",
|
|
3169
|
-
`${apiUrl}/projects/v3/${config.project}/environment-variables`
|
|
3170
|
-
)
|
|
3171
|
-
)}`
|
|
3172
|
-
);
|
|
3173
|
-
span.setAttributes({
|
|
3174
|
-
"envVars.missing": missingEnvironmentVariables
|
|
3175
|
-
});
|
|
3176
|
-
if (!options.ignoreEnvVarCheck) {
|
|
3177
|
-
throw new SkipLoggingError("Found missing environment variables");
|
|
3178
|
-
} else {
|
|
3179
|
-
span.end();
|
|
3180
|
-
return;
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
environmentVariablesSpinner.stop(`Environment variable check passed`);
|
|
3184
|
-
}
|
|
3185
|
-
span.end();
|
|
3186
|
-
} catch (e) {
|
|
3187
|
-
recordSpanException4(span, e);
|
|
3188
|
-
span.end();
|
|
3189
|
-
throw e;
|
|
4225
|
+
function getMessageFromTemplate(template, replacer) {
|
|
4226
|
+
let message = template;
|
|
4227
|
+
if (replacer) {
|
|
4228
|
+
for (const [key, value] of Object.entries(replacer)) {
|
|
4229
|
+
message = message.replaceAll(`$${key}`, value);
|
|
3190
4230
|
}
|
|
3191
|
-
}
|
|
4231
|
+
}
|
|
4232
|
+
return message;
|
|
4233
|
+
}
|
|
4234
|
+
async function saveLogs(shortCode, logs) {
|
|
4235
|
+
const logPath = join6(await createTempDir(), `build-${shortCode}.log`);
|
|
4236
|
+
await writeFile2(logPath, logs);
|
|
4237
|
+
return logPath;
|
|
4238
|
+
}
|
|
4239
|
+
async function failDeploy(shortCode, errorSummary, logs, deploymentSpinner, warnings, errors) {
|
|
4240
|
+
deploymentSpinner.stop(`Failed to deploy project`);
|
|
4241
|
+
if (logs.trim() !== "") {
|
|
4242
|
+
const logPath = await saveLogs(shortCode, logs);
|
|
4243
|
+
printWarnings(warnings);
|
|
4244
|
+
printErrors(errors);
|
|
4245
|
+
checkLogsForErrors(logs);
|
|
4246
|
+
outro5(`${chalkError("Error:")} ${errorSummary}. Full build logs have been saved to ${logPath}`);
|
|
4247
|
+
} else {
|
|
4248
|
+
outro5(`${chalkError("Error:")} ${errorSummary}.`);
|
|
4249
|
+
}
|
|
3192
4250
|
}
|
|
3193
4251
|
async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds = 60) {
|
|
3194
4252
|
return tracer.startActiveSpan("waitForDeploymentToFinish", async (span) => {
|
|
@@ -3218,13 +4276,13 @@ async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds
|
|
|
3218
4276
|
await setTimeout2(1e3);
|
|
3219
4277
|
}
|
|
3220
4278
|
} catch (error) {
|
|
3221
|
-
|
|
4279
|
+
recordSpanException5(span, error);
|
|
3222
4280
|
span.end();
|
|
3223
4281
|
return error instanceof Error ? error.message : JSON.stringify(error);
|
|
3224
4282
|
}
|
|
3225
4283
|
});
|
|
3226
4284
|
}
|
|
3227
|
-
async function buildAndPushImage(options) {
|
|
4285
|
+
async function buildAndPushImage(options, updater) {
|
|
3228
4286
|
return tracer.startActiveSpan("buildAndPushImage", async (span) => {
|
|
3229
4287
|
span.setAttributes({
|
|
3230
4288
|
"options.registryHost": options.registryHost,
|
|
@@ -3245,6 +4303,7 @@ async function buildAndPushImage(options) {
|
|
|
3245
4303
|
"build",
|
|
3246
4304
|
"-f",
|
|
3247
4305
|
"Containerfile",
|
|
4306
|
+
options.noCache ? "--no-cache" : void 0,
|
|
3248
4307
|
"--platform",
|
|
3249
4308
|
options.buildPlatform,
|
|
3250
4309
|
"--provenance",
|
|
@@ -3280,15 +4339,24 @@ async function buildAndPushImage(options) {
|
|
|
3280
4339
|
});
|
|
3281
4340
|
const errors = [];
|
|
3282
4341
|
try {
|
|
3283
|
-
await new Promise((res, rej) => {
|
|
4342
|
+
const processCode = await new Promise((res, rej) => {
|
|
3284
4343
|
childProcess2.stderr?.on("data", (data) => {
|
|
3285
|
-
const
|
|
3286
|
-
|
|
3287
|
-
|
|
4344
|
+
const text3 = data.toString();
|
|
4345
|
+
const lines = text3.split("\n").filter(Boolean);
|
|
4346
|
+
errors.push(...lines);
|
|
4347
|
+
logger.debug(text3);
|
|
3288
4348
|
});
|
|
3289
4349
|
childProcess2.on("error", (e) => rej(e));
|
|
3290
|
-
childProcess2.on("close", () => res());
|
|
4350
|
+
childProcess2.on("close", (code) => res(code));
|
|
3291
4351
|
});
|
|
4352
|
+
const logs = extractLogs(errors);
|
|
4353
|
+
if (processCode !== 0) {
|
|
4354
|
+
return {
|
|
4355
|
+
ok: false,
|
|
4356
|
+
error: `Error building image`,
|
|
4357
|
+
logs
|
|
4358
|
+
};
|
|
4359
|
+
}
|
|
3292
4360
|
const digest = extractImageDigest(errors);
|
|
3293
4361
|
span.setAttributes({
|
|
3294
4362
|
"image.digest": digest
|
|
@@ -3297,14 +4365,16 @@ async function buildAndPushImage(options) {
|
|
|
3297
4365
|
return {
|
|
3298
4366
|
ok: true,
|
|
3299
4367
|
image: options.imageTag,
|
|
4368
|
+
logs,
|
|
3300
4369
|
digest
|
|
3301
4370
|
};
|
|
3302
4371
|
} catch (e) {
|
|
3303
|
-
|
|
4372
|
+
recordSpanException5(span, e);
|
|
3304
4373
|
span.end();
|
|
3305
4374
|
return {
|
|
3306
4375
|
ok: false,
|
|
3307
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4376
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4377
|
+
logs: extractLogs(errors)
|
|
3308
4378
|
};
|
|
3309
4379
|
}
|
|
3310
4380
|
});
|
|
@@ -3325,6 +4395,7 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3325
4395
|
"build",
|
|
3326
4396
|
"-f",
|
|
3327
4397
|
"Containerfile",
|
|
4398
|
+
options.noCache ? "--no-cache" : void 0,
|
|
3328
4399
|
"--platform",
|
|
3329
4400
|
options.buildPlatform,
|
|
3330
4401
|
"--build-arg",
|
|
@@ -3342,7 +4413,9 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3342
4413
|
"."
|
|
3343
4414
|
// The build context
|
|
3344
4415
|
].filter(Boolean);
|
|
3345
|
-
logger.debug(`docker ${buildArgs.join(" ")}
|
|
4416
|
+
logger.debug(`docker ${buildArgs.join(" ")}`, {
|
|
4417
|
+
cwd: options.cwd
|
|
4418
|
+
});
|
|
3346
4419
|
span.setAttribute("docker.command.build", `docker ${buildArgs.join(" ")}`);
|
|
3347
4420
|
const buildProcess = execa2("docker", buildArgs, {
|
|
3348
4421
|
cwd: options.cwd
|
|
@@ -3350,25 +4423,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3350
4423
|
const errors = [];
|
|
3351
4424
|
let digest;
|
|
3352
4425
|
try {
|
|
3353
|
-
await new Promise((res, rej) => {
|
|
4426
|
+
const processCode = await new Promise((res, rej) => {
|
|
3354
4427
|
buildProcess.stderr?.on("data", (data) => {
|
|
3355
|
-
const
|
|
3356
|
-
errors.push(
|
|
3357
|
-
logger.debug(
|
|
4428
|
+
const text3 = data.toString();
|
|
4429
|
+
errors.push(text3);
|
|
4430
|
+
logger.debug(text3);
|
|
3358
4431
|
});
|
|
3359
4432
|
buildProcess.on("error", (e) => rej(e));
|
|
3360
|
-
buildProcess.on("close", () => res());
|
|
4433
|
+
buildProcess.on("close", (code) => res(code));
|
|
3361
4434
|
});
|
|
4435
|
+
if (processCode !== 0) {
|
|
4436
|
+
return {
|
|
4437
|
+
ok: false,
|
|
4438
|
+
error: "Error building image",
|
|
4439
|
+
logs: extractLogs(errors)
|
|
4440
|
+
};
|
|
4441
|
+
}
|
|
3362
4442
|
digest = extractImageDigest(errors);
|
|
3363
4443
|
span.setAttributes({
|
|
3364
4444
|
"image.digest": digest
|
|
3365
4445
|
});
|
|
3366
4446
|
} catch (e) {
|
|
3367
|
-
|
|
4447
|
+
recordSpanException5(span, e);
|
|
3368
4448
|
span.end();
|
|
3369
4449
|
return {
|
|
3370
4450
|
ok: false,
|
|
3371
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4451
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4452
|
+
logs: extractLogs(errors)
|
|
3372
4453
|
};
|
|
3373
4454
|
}
|
|
3374
4455
|
const pushArgs = ["push", imageRef].filter(Boolean);
|
|
@@ -3379,25 +4460,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3379
4460
|
cwd: options.cwd
|
|
3380
4461
|
});
|
|
3381
4462
|
try {
|
|
3382
|
-
await new Promise((res, rej) => {
|
|
4463
|
+
const processCode = await new Promise((res, rej) => {
|
|
3383
4464
|
pushProcess.stdout?.on("data", (data) => {
|
|
3384
|
-
const
|
|
3385
|
-
logger.debug(
|
|
4465
|
+
const text3 = data.toString();
|
|
4466
|
+
logger.debug(text3);
|
|
3386
4467
|
});
|
|
3387
4468
|
pushProcess.stderr?.on("data", (data) => {
|
|
3388
|
-
const
|
|
3389
|
-
logger.debug(
|
|
4469
|
+
const text3 = data.toString();
|
|
4470
|
+
logger.debug(text3);
|
|
3390
4471
|
});
|
|
3391
4472
|
pushProcess.on("error", (e) => rej(e));
|
|
3392
|
-
pushProcess.on("close", () => res());
|
|
4473
|
+
pushProcess.on("close", (code) => res(code));
|
|
3393
4474
|
});
|
|
4475
|
+
if (processCode !== 0) {
|
|
4476
|
+
return {
|
|
4477
|
+
ok: false,
|
|
4478
|
+
error: "Error pushing image",
|
|
4479
|
+
logs: extractLogs(errors)
|
|
4480
|
+
};
|
|
4481
|
+
}
|
|
3394
4482
|
span.end();
|
|
3395
4483
|
} catch (e) {
|
|
3396
|
-
|
|
4484
|
+
recordSpanException5(span, e);
|
|
3397
4485
|
span.end();
|
|
3398
4486
|
return {
|
|
3399
4487
|
ok: false,
|
|
3400
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4488
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4489
|
+
logs: extractLogs(errors)
|
|
3401
4490
|
};
|
|
3402
4491
|
}
|
|
3403
4492
|
}
|
|
@@ -3405,21 +4494,25 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3405
4494
|
return {
|
|
3406
4495
|
ok: true,
|
|
3407
4496
|
image: options.imageTag,
|
|
3408
|
-
digest
|
|
4497
|
+
digest,
|
|
4498
|
+
logs: extractLogs(errors)
|
|
3409
4499
|
};
|
|
3410
4500
|
});
|
|
3411
4501
|
}
|
|
3412
4502
|
function extractImageDigest(outputs) {
|
|
3413
|
-
const imageDigestRegex = /sha256:[a-f0-9]{64}/;
|
|
4503
|
+
const imageDigestRegex = /pushing manifest for .+(?<digest>sha256:[a-f0-9]{64})/;
|
|
3414
4504
|
for (const line of outputs) {
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
}
|
|
4505
|
+
const imageDigestMatch = line.match(imageDigestRegex);
|
|
4506
|
+
const digest = imageDigestMatch?.groups?.digest;
|
|
4507
|
+
if (digest) {
|
|
4508
|
+
return digest;
|
|
3420
4509
|
}
|
|
3421
4510
|
}
|
|
3422
4511
|
}
|
|
4512
|
+
function extractLogs(outputs) {
|
|
4513
|
+
const cleanedOutputs = outputs.map((line) => line.trim()).filter((line) => line !== "");
|
|
4514
|
+
return cleanedOutputs.map((line) => line.trim()).join("\n");
|
|
4515
|
+
}
|
|
3423
4516
|
async function compileProject(config, options, configPath) {
|
|
3424
4517
|
return await tracer.startActiveSpan("compileProject", async (span) => {
|
|
3425
4518
|
try {
|
|
@@ -3429,25 +4522,25 @@ async function compileProject(config, options, configPath) {
|
|
|
3429
4522
|
throw new Error("Typecheck failed, aborting deployment");
|
|
3430
4523
|
}
|
|
3431
4524
|
}
|
|
3432
|
-
const compileSpinner =
|
|
4525
|
+
const compileSpinner = spinner();
|
|
3433
4526
|
compileSpinner.start(`Building project in ${config.projectDir}`);
|
|
3434
4527
|
const taskFiles = await gatherTaskFiles(config);
|
|
3435
4528
|
const workerFacade = readFileSync2(
|
|
3436
|
-
|
|
3437
|
-
"file://",
|
|
3438
|
-
""
|
|
3439
|
-
),
|
|
4529
|
+
join6(cliRootPath(), "workers", "prod", "worker-facade.js"),
|
|
3440
4530
|
"utf-8"
|
|
3441
4531
|
);
|
|
3442
|
-
const workerSetupPath =
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
4532
|
+
const workerSetupPath = join6(cliRootPath(), "workers", "prod", "worker-setup.js");
|
|
4533
|
+
let workerContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
4534
|
+
"__WORKER_SETUP__",
|
|
4535
|
+
`import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
|
|
4536
|
+
);
|
|
3446
4537
|
if (configPath) {
|
|
3447
4538
|
logger.debug("Importing project config from", { configPath });
|
|
3448
4539
|
workerContents = workerContents.replace(
|
|
3449
4540
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
3450
|
-
`import * as importedConfigExports from "${
|
|
4541
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
4542
|
+
configPath
|
|
4543
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
3451
4544
|
);
|
|
3452
4545
|
} else {
|
|
3453
4546
|
workerContents = workerContents.replace(
|
|
@@ -3473,17 +4566,26 @@ async function compileProject(config, options, configPath) {
|
|
|
3473
4566
|
// This is needed to support opentelemetry instrumentation that uses module patching
|
|
3474
4567
|
target: ["node18", "es2020"],
|
|
3475
4568
|
outdir: "out",
|
|
4569
|
+
banner: {
|
|
4570
|
+
js: `process.on("uncaughtException", function(error, origin) { if (error instanceof Error) { process.send && process.send({ type: "EVENT", message: { type: "UNCAUGHT_EXCEPTION", payload: { error: { name: error.name, message: error.message, stack: error.stack }, origin }, version: "v1" } }); } else { process.send && process.send({ type: "EVENT", message: { type: "UNCAUGHT_EXCEPTION", payload: { error: { name: "Error", message: typeof error === "string" ? error : JSON.stringify(error) }, origin }, version: "v1" } }); } });`
|
|
4571
|
+
},
|
|
3476
4572
|
define: {
|
|
3477
4573
|
TRIGGER_API_URL: `"${config.triggerUrl}"`,
|
|
3478
4574
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
3479
4575
|
},
|
|
3480
4576
|
plugins: [
|
|
4577
|
+
mockServerOnlyPlugin(),
|
|
3481
4578
|
bundleDependenciesPlugin(
|
|
3482
4579
|
"workerFacade",
|
|
3483
4580
|
config.dependenciesToBundle,
|
|
3484
4581
|
config.tsconfigPath
|
|
3485
4582
|
),
|
|
3486
|
-
workerSetupImportConfigPlugin(configPath)
|
|
4583
|
+
workerSetupImportConfigPlugin(configPath),
|
|
4584
|
+
esbuildDecorators2({
|
|
4585
|
+
tsconfig: config.tsconfigPath,
|
|
4586
|
+
tsx: true,
|
|
4587
|
+
force: false
|
|
4588
|
+
})
|
|
3487
4589
|
]
|
|
3488
4590
|
});
|
|
3489
4591
|
if (result.errors.length > 0) {
|
|
@@ -3496,13 +4598,10 @@ async function compileProject(config, options, configPath) {
|
|
|
3496
4598
|
throw new Error("Build failed, aborting deployment");
|
|
3497
4599
|
}
|
|
3498
4600
|
if (options.outputMetafile) {
|
|
3499
|
-
await writeJSONFile(
|
|
4601
|
+
await writeJSONFile(join6(options.outputMetafile, "worker.json"), result.metafile);
|
|
3500
4602
|
}
|
|
3501
4603
|
const entryPointContents = readFileSync2(
|
|
3502
|
-
|
|
3503
|
-
"file://",
|
|
3504
|
-
""
|
|
3505
|
-
),
|
|
4604
|
+
join6(cliRootPath(), "workers", "prod", "entry-point.js"),
|
|
3506
4605
|
"utf-8"
|
|
3507
4606
|
);
|
|
3508
4607
|
const entryPointResult = await build2({
|
|
@@ -3545,58 +4644,72 @@ async function compileProject(config, options, configPath) {
|
|
|
3545
4644
|
}
|
|
3546
4645
|
if (options.outputMetafile) {
|
|
3547
4646
|
await writeJSONFile(
|
|
3548
|
-
|
|
4647
|
+
join6(options.outputMetafile, "entry-point.json"),
|
|
3549
4648
|
entryPointResult.metafile
|
|
3550
4649
|
);
|
|
3551
4650
|
}
|
|
3552
4651
|
const tempDir = await createTempDir();
|
|
3553
4652
|
logger.debug(`Writing compiled files to ${tempDir}`);
|
|
3554
|
-
const metaOutput = result.metafile.outputs[
|
|
4653
|
+
const metaOutput = result.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3555
4654
|
invariant(metaOutput, "Meta output for the result build is missing");
|
|
3556
|
-
const entryPointMetaOutput = entryPointResult.metafile.outputs[
|
|
4655
|
+
const entryPointMetaOutput = entryPointResult.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3557
4656
|
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
|
|
3558
4657
|
const workerOutputFile = result.outputFiles.find(
|
|
3559
|
-
(file) => file.path ===
|
|
4658
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3560
4659
|
);
|
|
3561
4660
|
invariant(workerOutputFile, "Output file for the result build is missing");
|
|
3562
4661
|
const workerSourcemapFile = result.outputFiles.find(
|
|
3563
|
-
(file) => file.path ===
|
|
4662
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js.map")
|
|
3564
4663
|
);
|
|
3565
4664
|
invariant(workerSourcemapFile, "Sourcemap file for the result build is missing");
|
|
3566
4665
|
const entryPointOutputFile = entryPointResult.outputFiles.find(
|
|
3567
|
-
(file) => file.path ===
|
|
4666
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3568
4667
|
);
|
|
3569
4668
|
invariant(entryPointOutputFile, "Output file for the entryPoint build is missing");
|
|
3570
4669
|
await writeFile2(
|
|
3571
|
-
|
|
4670
|
+
join6(tempDir, "worker.js"),
|
|
3572
4671
|
`${workerOutputFile.text}
|
|
3573
4672
|
//# sourceMappingURL=worker.js.map`
|
|
3574
4673
|
);
|
|
3575
|
-
await writeFile2(
|
|
3576
|
-
await writeFile2(
|
|
4674
|
+
await writeFile2(join6(tempDir, "worker.js.map"), workerSourcemapFile.text);
|
|
4675
|
+
await writeFile2(join6(tempDir, "index.js"), entryPointOutputFile.text);
|
|
3577
4676
|
logger.debug("Getting the imports for the worker and entryPoint builds", {
|
|
3578
4677
|
workerImports: metaOutput.imports,
|
|
3579
4678
|
entryPointImports: entryPointMetaOutput.imports
|
|
3580
4679
|
});
|
|
3581
4680
|
const allImports = [...metaOutput.imports, ...entryPointMetaOutput.imports];
|
|
3582
|
-
const
|
|
3583
|
-
const dependencies2 = await
|
|
3584
|
-
|
|
3585
|
-
config,
|
|
3586
|
-
externalPackageJson
|
|
3587
|
-
);
|
|
4681
|
+
const javascriptProject = new JavascriptProject(config.projectDir);
|
|
4682
|
+
const dependencies2 = await resolveRequiredDependencies(allImports, config, javascriptProject);
|
|
4683
|
+
logger.debug("gatherRequiredDependencies()", { dependencies: dependencies2 });
|
|
3588
4684
|
const packageJsonContents = {
|
|
3589
4685
|
name: "trigger-worker",
|
|
3590
4686
|
version: "0.0.0",
|
|
3591
4687
|
description: "",
|
|
3592
4688
|
dependencies: dependencies2,
|
|
3593
4689
|
scripts: {
|
|
3594
|
-
|
|
4690
|
+
...javascriptProject.scripts
|
|
3595
4691
|
}
|
|
3596
4692
|
};
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
4693
|
+
span.setAttributes({
|
|
4694
|
+
...flattenAttributes3(packageJsonContents, "packageJson.contents")
|
|
4695
|
+
});
|
|
4696
|
+
await writeJSONFile(join6(tempDir, "package.json"), packageJsonContents);
|
|
4697
|
+
const copyResult = await copyAdditionalFiles(config, tempDir);
|
|
4698
|
+
if (!copyResult.ok) {
|
|
4699
|
+
compileSpinner.stop("Project built with warnings");
|
|
4700
|
+
log5.warn(
|
|
4701
|
+
`No additionalFiles matches for:
|
|
4702
|
+
|
|
4703
|
+
${copyResult.noMatches.map((glob) => `- "${glob}"`).join("\n")}
|
|
4704
|
+
|
|
4705
|
+
If this is unexpected you should check your ${terminalLink2(
|
|
4706
|
+
"glob patterns",
|
|
4707
|
+
"https://github.com/isaacs/node-glob?tab=readme-ov-file#glob-primer"
|
|
4708
|
+
)} are valid.`
|
|
4709
|
+
);
|
|
4710
|
+
} else {
|
|
4711
|
+
compileSpinner.stop("Project built successfully");
|
|
4712
|
+
}
|
|
3600
4713
|
const resolvingDependenciesResult = await resolveDependencies(
|
|
3601
4714
|
tempDir,
|
|
3602
4715
|
packageJsonContents,
|
|
@@ -3604,31 +4717,31 @@ async function compileProject(config, options, configPath) {
|
|
|
3604
4717
|
options
|
|
3605
4718
|
);
|
|
3606
4719
|
if (!resolvingDependenciesResult) {
|
|
3607
|
-
throw new
|
|
4720
|
+
throw new SkipLoggingError("Failed to resolve dependencies");
|
|
4721
|
+
}
|
|
4722
|
+
const containerFilePath = join6(cliRootPath(), "Containerfile.prod");
|
|
4723
|
+
let containerFileContents = readFileSync2(containerFilePath, "utf-8");
|
|
4724
|
+
if (config.postInstall) {
|
|
4725
|
+
containerFileContents = containerFileContents.replace(
|
|
4726
|
+
"__POST_INSTALL__",
|
|
4727
|
+
`RUN ${config.postInstall}`
|
|
4728
|
+
);
|
|
4729
|
+
} else {
|
|
4730
|
+
containerFileContents = containerFileContents.replace("__POST_INSTALL__", "");
|
|
3608
4731
|
}
|
|
3609
|
-
|
|
3610
|
-
importResolve("./Containerfile.prod", import.meta.url)
|
|
3611
|
-
).href.replace("file://", "");
|
|
3612
|
-
await copyFile(containerFilePath, join4(tempDir, "Containerfile"));
|
|
4732
|
+
await writeFile2(join6(tempDir, "Containerfile"), containerFileContents);
|
|
3613
4733
|
const contentHasher = createHash("sha256");
|
|
3614
4734
|
contentHasher.update(Buffer.from(entryPointOutputFile.text));
|
|
3615
4735
|
contentHasher.update(Buffer.from(workerOutputFile.text));
|
|
3616
4736
|
contentHasher.update(Buffer.from(JSON.stringify(dependencies2)));
|
|
3617
4737
|
const contentHash = contentHasher.digest("hex");
|
|
3618
|
-
const workerSetupEnvVars = await findAllEnvironmentVariableReferencesInFile(workerSetupPath);
|
|
3619
|
-
const workerFacadeEnvVars = findAllEnvironmentVariableReferences(workerContents);
|
|
3620
|
-
const envVars = findAllEnvironmentVariableReferences(workerOutputFile.text);
|
|
3621
|
-
const finalEnvVars = envVars.filter(
|
|
3622
|
-
(envVar) => !workerFacadeEnvVars.includes(envVar) && !workerSetupEnvVars.includes(envVar)
|
|
3623
|
-
);
|
|
3624
4738
|
span.setAttributes({
|
|
3625
|
-
contentHash
|
|
3626
|
-
envVars: finalEnvVars
|
|
4739
|
+
contentHash
|
|
3627
4740
|
});
|
|
3628
4741
|
span.end();
|
|
3629
|
-
return { path: tempDir, contentHash
|
|
4742
|
+
return { path: tempDir, contentHash };
|
|
3630
4743
|
} catch (e) {
|
|
3631
|
-
|
|
4744
|
+
recordSpanException5(span, e);
|
|
3632
4745
|
span.end();
|
|
3633
4746
|
throw e;
|
|
3634
4747
|
}
|
|
@@ -3636,22 +4749,22 @@ async function compileProject(config, options, configPath) {
|
|
|
3636
4749
|
}
|
|
3637
4750
|
async function resolveDependencies(projectDir, packageJsonContents, config, options) {
|
|
3638
4751
|
return await tracer.startActiveSpan("resolveDependencies", async (span) => {
|
|
3639
|
-
const resolvingDepsSpinner =
|
|
4752
|
+
const resolvingDepsSpinner = spinner();
|
|
3640
4753
|
resolvingDepsSpinner.start("Resolving dependencies");
|
|
3641
4754
|
const hasher = createHash("sha256");
|
|
3642
4755
|
hasher.update(JSON.stringify(packageJsonContents));
|
|
3643
4756
|
const digest = hasher.digest("hex").slice(0, 16);
|
|
3644
|
-
const cacheDir =
|
|
3645
|
-
const cachePath =
|
|
4757
|
+
const cacheDir = join6(config.projectDir, ".trigger", "cache");
|
|
4758
|
+
const cachePath = join6(cacheDir, `${digest}.json`);
|
|
3646
4759
|
span.setAttributes({
|
|
3647
4760
|
"packageJson.digest": digest,
|
|
3648
4761
|
"cache.path": cachePath,
|
|
3649
|
-
...
|
|
4762
|
+
...flattenAttributes3(packageJsonContents, "packageJson.contents")
|
|
3650
4763
|
});
|
|
3651
4764
|
try {
|
|
3652
4765
|
const cachedPackageLock = await readFile2(cachePath, "utf-8");
|
|
3653
4766
|
logger.debug(`Using cached package-lock.json for ${digest}`);
|
|
3654
|
-
await writeFile2(
|
|
4767
|
+
await writeFile2(join6(projectDir, "package-lock.json"), cachedPackageLock);
|
|
3655
4768
|
span.setAttributes({
|
|
3656
4769
|
"cache.hit": true
|
|
3657
4770
|
});
|
|
@@ -3674,21 +4787,44 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3674
4787
|
cwd: projectDir,
|
|
3675
4788
|
stdio: logger.loggerLevel === "debug" ? "inherit" : "pipe"
|
|
3676
4789
|
});
|
|
3677
|
-
const packageLockContents = await readFile2(
|
|
4790
|
+
const packageLockContents = await readFile2(join6(projectDir, "package-lock.json"), "utf-8");
|
|
3678
4791
|
logger.debug(`Writing package-lock.json to cache for ${digest}`);
|
|
3679
4792
|
await mkdir(cacheDir, { recursive: true });
|
|
3680
4793
|
await writeFile2(cachePath, packageLockContents);
|
|
3681
|
-
await writeFile2(
|
|
4794
|
+
await writeFile2(join6(projectDir, "package-lock.json"), packageLockContents);
|
|
3682
4795
|
span.end();
|
|
3683
4796
|
resolvingDepsSpinner.stop("Dependencies resolved");
|
|
3684
4797
|
return true;
|
|
3685
4798
|
} catch (installError) {
|
|
3686
|
-
|
|
3687
|
-
recordSpanException4(span, installError);
|
|
4799
|
+
recordSpanException5(span, installError);
|
|
3688
4800
|
span.end();
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
4801
|
+
const parsedError = parseNpmInstallError(installError);
|
|
4802
|
+
if (typeof parsedError === "string") {
|
|
4803
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies: ${parsedError}`);
|
|
4804
|
+
} else {
|
|
4805
|
+
switch (parsedError.type) {
|
|
4806
|
+
case "package-not-found-error": {
|
|
4807
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4808
|
+
logger.log(
|
|
4809
|
+
`
|
|
4810
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4811
|
+
parsedError.packageName
|
|
4812
|
+
)} could not be found in the npm registry.`
|
|
4813
|
+
);
|
|
4814
|
+
break;
|
|
4815
|
+
}
|
|
4816
|
+
case "no-matching-version-error": {
|
|
4817
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4818
|
+
logger.log(
|
|
4819
|
+
`
|
|
4820
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4821
|
+
parsedError.packageName
|
|
4822
|
+
)} could not resolve because the version doesn't exist`
|
|
4823
|
+
);
|
|
4824
|
+
break;
|
|
4825
|
+
}
|
|
4826
|
+
}
|
|
4827
|
+
}
|
|
3692
4828
|
return false;
|
|
3693
4829
|
}
|
|
3694
4830
|
}
|
|
@@ -3697,7 +4833,7 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3697
4833
|
async function typecheckProject(config, options) {
|
|
3698
4834
|
return await tracer.startActiveSpan("typecheckProject", async (span) => {
|
|
3699
4835
|
try {
|
|
3700
|
-
const typecheckSpinner =
|
|
4836
|
+
const typecheckSpinner = spinner();
|
|
3701
4837
|
typecheckSpinner.start("Typechecking project");
|
|
3702
4838
|
const tscTypecheck = execa2("npm", ["exec", "tsc", "--", "--noEmit"], {
|
|
3703
4839
|
cwd: config.projectDir
|
|
@@ -3707,8 +4843,8 @@ async function typecheckProject(config, options) {
|
|
|
3707
4843
|
tscTypecheck.stdout?.on("data", (chunk) => stdouts.push(chunk.toString()));
|
|
3708
4844
|
tscTypecheck.stderr?.on("data", (chunk) => stderrs.push(chunk.toString()));
|
|
3709
4845
|
try {
|
|
3710
|
-
await new Promise((
|
|
3711
|
-
tscTypecheck.addListener("exit", (code) => code === 0 ?
|
|
4846
|
+
await new Promise((resolve5, reject) => {
|
|
4847
|
+
tscTypecheck.addListener("exit", (code) => code === 0 ? resolve5(code) : reject(code));
|
|
3712
4848
|
});
|
|
3713
4849
|
} catch (error) {
|
|
3714
4850
|
typecheckSpinner.stop(
|
|
@@ -3726,63 +4862,100 @@ async function typecheckProject(config, options) {
|
|
|
3726
4862
|
span.end();
|
|
3727
4863
|
return true;
|
|
3728
4864
|
} catch (e) {
|
|
3729
|
-
|
|
4865
|
+
recordSpanException5(span, e);
|
|
3730
4866
|
span.end();
|
|
3731
4867
|
return false;
|
|
3732
4868
|
}
|
|
3733
4869
|
});
|
|
3734
4870
|
}
|
|
3735
|
-
async function
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
}
|
|
3741
|
-
const packageName = detectPackageNameFromImportPath(file.path);
|
|
3742
|
-
if (dependencies2[packageName]) {
|
|
3743
|
-
continue;
|
|
3744
|
-
}
|
|
3745
|
-
const externalDependencyVersion = (projectPackageJson?.dependencies ?? {})[packageName];
|
|
3746
|
-
if (externalDependencyVersion) {
|
|
3747
|
-
dependencies2[packageName] = stripWorkspaceFromVersion(externalDependencyVersion);
|
|
3748
|
-
continue;
|
|
3749
|
-
}
|
|
3750
|
-
const internalDependencyVersion = dependencies[packageName] ?? detectDependencyVersion(packageName);
|
|
3751
|
-
if (internalDependencyVersion) {
|
|
3752
|
-
dependencies2[packageName] = stripWorkspaceFromVersion(internalDependencyVersion);
|
|
3753
|
-
}
|
|
3754
|
-
}
|
|
3755
|
-
if (config.additionalPackages) {
|
|
3756
|
-
for (const packageName of config.additionalPackages) {
|
|
3757
|
-
if (dependencies2[packageName]) {
|
|
4871
|
+
async function resolveRequiredDependencies(imports, config, project) {
|
|
4872
|
+
return await tracer.startActiveSpan("resolveRequiredDependencies", async (span) => {
|
|
4873
|
+
const resolvablePackageNames = /* @__PURE__ */ new Set();
|
|
4874
|
+
for (const file of imports) {
|
|
4875
|
+
if (file.kind !== "require-call" && file.kind !== "dynamic-import" || !file.external) {
|
|
3758
4876
|
continue;
|
|
3759
4877
|
}
|
|
3760
|
-
const
|
|
3761
|
-
if (
|
|
3762
|
-
dependencies2[packageParts.name] = packageParts.version;
|
|
4878
|
+
const packageName = detectPackageNameFromImportPath(file.path);
|
|
4879
|
+
if (!packageName) {
|
|
3763
4880
|
continue;
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
4881
|
+
}
|
|
4882
|
+
resolvablePackageNames.add(packageName);
|
|
4883
|
+
}
|
|
4884
|
+
span.setAttribute("resolvablePackageNames", Array.from(resolvablePackageNames));
|
|
4885
|
+
const resolvedPackageVersions = await project.resolveAll(Array.from(resolvablePackageNames));
|
|
4886
|
+
const missingPackages = Array.from(resolvablePackageNames).filter(
|
|
4887
|
+
(packageName) => !resolvedPackageVersions[packageName]
|
|
4888
|
+
);
|
|
4889
|
+
span.setAttributes({
|
|
4890
|
+
...flattenAttributes3(resolvedPackageVersions, "resolvedPackageVersions")
|
|
4891
|
+
});
|
|
4892
|
+
span.setAttribute("missingPackages", missingPackages);
|
|
4893
|
+
const dependencies2 = {};
|
|
4894
|
+
for (const missingPackage of missingPackages) {
|
|
4895
|
+
const internalDependencyVersion = dependencies[missingPackage] ?? detectDependencyVersion(missingPackage);
|
|
4896
|
+
if (internalDependencyVersion) {
|
|
4897
|
+
dependencies2[missingPackage] = stripWorkspaceFromVersion(internalDependencyVersion);
|
|
4898
|
+
}
|
|
4899
|
+
}
|
|
4900
|
+
for (const [packageName, version2] of Object.entries(resolvedPackageVersions)) {
|
|
4901
|
+
dependencies2[packageName] = version2;
|
|
4902
|
+
}
|
|
4903
|
+
if (config.additionalPackages) {
|
|
4904
|
+
span.setAttribute("additionalPackages", config.additionalPackages);
|
|
4905
|
+
for (const packageName of config.additionalPackages) {
|
|
4906
|
+
if (dependencies2[packageName]) {
|
|
4907
|
+
continue;
|
|
4908
|
+
}
|
|
4909
|
+
const packageParts = parsePackageName(packageName);
|
|
4910
|
+
if (packageParts.version) {
|
|
4911
|
+
dependencies2[packageParts.name] = packageParts.version;
|
|
3771
4912
|
continue;
|
|
3772
4913
|
} else {
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
);
|
|
4914
|
+
const externalDependencyVersion = await project.resolve(packageParts.name, {
|
|
4915
|
+
allowDev: true
|
|
4916
|
+
});
|
|
4917
|
+
if (externalDependencyVersion) {
|
|
4918
|
+
dependencies2[packageParts.name] = externalDependencyVersion;
|
|
4919
|
+
continue;
|
|
4920
|
+
} else {
|
|
4921
|
+
logger.log(
|
|
4922
|
+
`${chalkWarning("X Warning:")} Could not find version for package ${chalkPurple(
|
|
4923
|
+
packageName
|
|
4924
|
+
)}, add a version specifier to the package name (e.g. ${packageParts.name}@latest) or add it to your project's package.json`
|
|
4925
|
+
);
|
|
4926
|
+
}
|
|
3776
4927
|
}
|
|
3777
4928
|
}
|
|
3778
4929
|
}
|
|
3779
|
-
|
|
3780
|
-
|
|
4930
|
+
if (!dependencies2["@trigger.dev/sdk"]) {
|
|
4931
|
+
logger.debug("Adding missing @trigger.dev/sdk dependency", {
|
|
4932
|
+
version
|
|
4933
|
+
});
|
|
4934
|
+
span.setAttribute("addingMissingSDK", version);
|
|
4935
|
+
dependencies2["@trigger.dev/sdk"] = version;
|
|
4936
|
+
}
|
|
4937
|
+
if (!dependencies2["@trigger.dev/core"]) {
|
|
4938
|
+
logger.debug("Adding missing @trigger.dev/core dependency", {
|
|
4939
|
+
version
|
|
4940
|
+
});
|
|
4941
|
+
span.setAttribute("addingMissingCore", version);
|
|
4942
|
+
dependencies2["@trigger.dev/core"] = version;
|
|
4943
|
+
}
|
|
4944
|
+
const result = Object.fromEntries(
|
|
4945
|
+
Object.entries(dependencies2).sort(([a], [b]) => a.localeCompare(b))
|
|
4946
|
+
);
|
|
4947
|
+
span.setAttributes({
|
|
4948
|
+
...flattenAttributes3(result, "dependencies")
|
|
4949
|
+
});
|
|
4950
|
+
span.end();
|
|
4951
|
+
return result;
|
|
4952
|
+
});
|
|
3781
4953
|
}
|
|
3782
4954
|
async function copyAdditionalFiles(config, tempDir) {
|
|
3783
4955
|
const additionalFiles = config.additionalFiles ?? [];
|
|
4956
|
+
const noMatches = [];
|
|
3784
4957
|
if (additionalFiles.length === 0) {
|
|
3785
|
-
return;
|
|
4958
|
+
return { ok: true };
|
|
3786
4959
|
}
|
|
3787
4960
|
return await tracer.startActiveSpan(
|
|
3788
4961
|
"copyAdditionalFiles",
|
|
@@ -3796,24 +4969,57 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3796
4969
|
logger.debug(`Copying files to ${tempDir}`, {
|
|
3797
4970
|
additionalFiles
|
|
3798
4971
|
});
|
|
3799
|
-
const
|
|
4972
|
+
const globOptions = {
|
|
3800
4973
|
withFileTypes: true,
|
|
3801
4974
|
ignore: ["node_modules"],
|
|
3802
4975
|
cwd: config.projectDir,
|
|
3803
4976
|
nodir: true
|
|
3804
|
-
}
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
)
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
4977
|
+
};
|
|
4978
|
+
const globs = [];
|
|
4979
|
+
let i = 0;
|
|
4980
|
+
for (const additionalFile of additionalFiles) {
|
|
4981
|
+
let glob;
|
|
4982
|
+
if (i === 0) {
|
|
4983
|
+
glob = new Glob(additionalFile, globOptions);
|
|
4984
|
+
} else {
|
|
4985
|
+
const previousGlob = globs[i - 1];
|
|
4986
|
+
if (!previousGlob) {
|
|
4987
|
+
logger.error("No previous glob, this shouldn't happen", { i, additionalFiles });
|
|
4988
|
+
continue;
|
|
4989
|
+
}
|
|
4990
|
+
glob = new Glob(additionalFile, previousGlob);
|
|
4991
|
+
}
|
|
4992
|
+
if (!(Symbol.asyncIterator in glob)) {
|
|
4993
|
+
logger.error("Glob should be an async iterator", { glob });
|
|
4994
|
+
throw new Error("Unrecoverable error while copying additional files");
|
|
4995
|
+
}
|
|
4996
|
+
let matches = 0;
|
|
4997
|
+
for await (const file of glob) {
|
|
4998
|
+
matches++;
|
|
4999
|
+
const pathInsideTempDir = relative3(config.projectDir, file.fullpath()).split(posix.sep).filter((p) => p !== "..").join(posix.sep);
|
|
5000
|
+
const relativeDestinationPath = join6(tempDir, pathInsideTempDir);
|
|
5001
|
+
logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
|
|
5002
|
+
await mkdir(dirname(relativeDestinationPath), { recursive: true });
|
|
5003
|
+
await copyFile(file.fullpath(), relativeDestinationPath);
|
|
5004
|
+
}
|
|
5005
|
+
if (matches === 0) {
|
|
5006
|
+
noMatches.push(additionalFile);
|
|
5007
|
+
}
|
|
5008
|
+
globs[i] = glob;
|
|
5009
|
+
i++;
|
|
3813
5010
|
}
|
|
3814
5011
|
span.end();
|
|
5012
|
+
if (noMatches.length > 0) {
|
|
5013
|
+
return {
|
|
5014
|
+
ok: false,
|
|
5015
|
+
noMatches
|
|
5016
|
+
};
|
|
5017
|
+
}
|
|
5018
|
+
return {
|
|
5019
|
+
ok: true
|
|
5020
|
+
};
|
|
3815
5021
|
} catch (error) {
|
|
3816
|
-
|
|
5022
|
+
recordSpanException5(span, error);
|
|
3817
5023
|
span.end();
|
|
3818
5024
|
throw error;
|
|
3819
5025
|
}
|
|
@@ -3822,7 +5028,7 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3822
5028
|
}
|
|
3823
5029
|
async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
3824
5030
|
const tmpDir = await createTempDir();
|
|
3825
|
-
const dockerConfigPath =
|
|
5031
|
+
const dockerConfigPath = join6(tmpDir, "config.json");
|
|
3826
5032
|
await writeJSONFile(dockerConfigPath, {
|
|
3827
5033
|
auths: {
|
|
3828
5034
|
[registryHost]: {
|
|
@@ -3833,43 +5039,20 @@ async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
|
3833
5039
|
logger.debug(`Writing docker config to ${dockerConfigPath}`);
|
|
3834
5040
|
return tmpDir;
|
|
3835
5041
|
}
|
|
3836
|
-
async function findAllEnvironmentVariableReferencesInFile(filePath) {
|
|
3837
|
-
const fileContents = await readFile2(filePath, "utf-8");
|
|
3838
|
-
return findAllEnvironmentVariableReferences(fileContents);
|
|
3839
|
-
}
|
|
3840
|
-
var IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH", "DEBUG"];
|
|
3841
|
-
function findAllEnvironmentVariableReferences(code) {
|
|
3842
|
-
const regex = /\bprocess\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
|
|
3843
|
-
const matches = code.matchAll(regex);
|
|
3844
|
-
const matchesArray = Array.from(matches, (match) => match[1]).filter(Boolean);
|
|
3845
|
-
const filteredMatches = matchesArray.filter((match) => !IGNORED_ENV_VARS.includes(match));
|
|
3846
|
-
return Array.from(new Set(filteredMatches));
|
|
3847
|
-
}
|
|
3848
|
-
function arrayToSentence(items) {
|
|
3849
|
-
if (items.length === 1 && typeof items[0] === "string") {
|
|
3850
|
-
return items[0];
|
|
3851
|
-
}
|
|
3852
|
-
if (items.length === 2) {
|
|
3853
|
-
return `${items[0]} and ${items[1]}`;
|
|
3854
|
-
}
|
|
3855
|
-
return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
3856
|
-
}
|
|
3857
5042
|
|
|
3858
5043
|
// src/commands/dev.tsx
|
|
3859
5044
|
import {
|
|
3860
|
-
ZodMessageHandler as ZodMessageHandler2,
|
|
3861
|
-
ZodMessageSender as ZodMessageSender2,
|
|
3862
5045
|
clientWebsocketMessages,
|
|
3863
5046
|
detectDependencyVersion as detectDependencyVersion2,
|
|
3864
5047
|
serverWebsocketMessages
|
|
3865
5048
|
} from "@trigger.dev/core/v3";
|
|
5049
|
+
import { ZodMessageHandler as ZodMessageHandler2, ZodMessageSender as ZodMessageSender2 } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3866
5050
|
import { watch } from "chokidar";
|
|
3867
5051
|
import { context as context2 } from "esbuild";
|
|
3868
|
-
import { resolve as importResolve2 } from "import-meta-resolve";
|
|
3869
5052
|
import { render, useInput } from "ink";
|
|
3870
5053
|
import { createHash as createHash2 } from "node:crypto";
|
|
3871
5054
|
import fs7, { readFileSync as readFileSync3 } from "node:fs";
|
|
3872
|
-
import { basename, dirname as dirname3, join as
|
|
5055
|
+
import { basename as basename2, dirname as dirname3, join as join7, normalize } from "node:path";
|
|
3873
5056
|
import pDebounce from "p-debounce";
|
|
3874
5057
|
import { WebSocket } from "partysocket";
|
|
3875
5058
|
import React, { Suspense, useEffect } from "react";
|
|
@@ -3885,23 +5068,30 @@ var UncaughtExceptionError = class extends Error {
|
|
|
3885
5068
|
this.name = "UncaughtExceptionError";
|
|
3886
5069
|
}
|
|
3887
5070
|
};
|
|
5071
|
+
var TaskMetadataParseError = class extends Error {
|
|
5072
|
+
constructor(zodIssues, tasks) {
|
|
5073
|
+
super(`Failed to parse task metadata`);
|
|
5074
|
+
this.zodIssues = zodIssues;
|
|
5075
|
+
this.tasks = tasks;
|
|
5076
|
+
this.name = "TaskMetadataParseError";
|
|
5077
|
+
}
|
|
5078
|
+
};
|
|
3888
5079
|
|
|
3889
5080
|
// src/workers/dev/backgroundWorker.ts
|
|
3890
5081
|
import {
|
|
3891
5082
|
SemanticInternalAttributes,
|
|
3892
5083
|
TaskRunErrorCodes,
|
|
3893
|
-
ZodMessageHandler,
|
|
3894
|
-
ZodMessageSender,
|
|
3895
5084
|
childToWorkerMessages,
|
|
3896
5085
|
correctErrorStackTrace,
|
|
3897
5086
|
formatDurationMilliseconds,
|
|
3898
5087
|
workerToChildMessages
|
|
3899
5088
|
} from "@trigger.dev/core/v3";
|
|
5089
|
+
import { ZodMessageHandler, ZodMessageSender } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3900
5090
|
import dotenv from "dotenv";
|
|
3901
5091
|
import { Evt } from "evt";
|
|
3902
5092
|
import { fork } from "node:child_process";
|
|
3903
|
-
import { dirname as dirname2, resolve as
|
|
3904
|
-
import
|
|
5093
|
+
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
5094
|
+
import terminalLink3 from "terminal-link";
|
|
3905
5095
|
var BackgroundWorkerCoordinator = class {
|
|
3906
5096
|
constructor(baseURL) {
|
|
3907
5097
|
this.baseURL = baseURL;
|
|
@@ -3986,7 +5176,7 @@ var BackgroundWorkerCoordinator = class {
|
|
|
3986
5176
|
const logsUrl = `${this.baseURL}/runs/${execution.run.id}`;
|
|
3987
5177
|
const pipe = chalkGrey("|");
|
|
3988
5178
|
const bullet = chalkGrey("\u25CB");
|
|
3989
|
-
const link = chalkLink(
|
|
5179
|
+
const link = chalkLink(terminalLink3("View logs", logsUrl));
|
|
3990
5180
|
let timestampPrefix = chalkGrey(prettyPrintDate(payload.execution.attempt.startedAt));
|
|
3991
5181
|
const workerPrefix = chalkWorker(record.version);
|
|
3992
5182
|
const taskPrefix = chalkTask(execution.task.id);
|
|
@@ -4059,8 +5249,8 @@ var CancelledProcessError = class extends Error {
|
|
|
4059
5249
|
}
|
|
4060
5250
|
};
|
|
4061
5251
|
var BackgroundWorker = class {
|
|
4062
|
-
constructor(
|
|
4063
|
-
this.path =
|
|
5252
|
+
constructor(path7, params) {
|
|
5253
|
+
this.path = path7;
|
|
4064
5254
|
this.params = params;
|
|
4065
5255
|
}
|
|
4066
5256
|
_initialized = false;
|
|
@@ -4094,7 +5284,13 @@ var BackgroundWorker = class {
|
|
|
4094
5284
|
await installPackages(this.params.dependencies, { cwd: dirname2(this.path) });
|
|
4095
5285
|
}
|
|
4096
5286
|
let resolved = false;
|
|
4097
|
-
|
|
5287
|
+
const cwd = dirname2(this.path);
|
|
5288
|
+
const fullEnv = {
|
|
5289
|
+
...this.params.env,
|
|
5290
|
+
...this.#readEnvVars()
|
|
5291
|
+
};
|
|
5292
|
+
logger.debug("Initializing worker", { path: this.path, cwd, fullEnv });
|
|
5293
|
+
this.tasks = await new Promise((resolve5, reject) => {
|
|
4098
5294
|
const child = fork(this.path, {
|
|
4099
5295
|
stdio: [
|
|
4100
5296
|
/*stdin*/
|
|
@@ -4105,10 +5301,8 @@ var BackgroundWorker = class {
|
|
|
4105
5301
|
"pipe",
|
|
4106
5302
|
"ipc"
|
|
4107
5303
|
],
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
...this.#readEnvVars()
|
|
4111
|
-
}
|
|
5304
|
+
cwd,
|
|
5305
|
+
env: fullEnv
|
|
4112
5306
|
});
|
|
4113
5307
|
const timeout = setTimeout(() => {
|
|
4114
5308
|
if (resolved) {
|
|
@@ -4123,13 +5317,18 @@ var BackgroundWorker = class {
|
|
|
4123
5317
|
if (message.type === "TASKS_READY" && !resolved) {
|
|
4124
5318
|
clearTimeout(timeout);
|
|
4125
5319
|
resolved = true;
|
|
4126
|
-
|
|
5320
|
+
resolve5(message.payload.tasks);
|
|
4127
5321
|
child.kill();
|
|
4128
5322
|
} else if (message.type === "UNCAUGHT_EXCEPTION") {
|
|
4129
5323
|
clearTimeout(timeout);
|
|
4130
5324
|
resolved = true;
|
|
4131
5325
|
reject(new UncaughtExceptionError(message.payload.error, message.payload.origin));
|
|
4132
5326
|
child.kill();
|
|
5327
|
+
} else if (message.type === "TASKS_FAILED_TO_PARSE") {
|
|
5328
|
+
clearTimeout(timeout);
|
|
5329
|
+
resolved = true;
|
|
5330
|
+
reject(new TaskMetadataParseError(message.payload.zodIssues, message.payload.tasks));
|
|
5331
|
+
child.kill();
|
|
4133
5332
|
}
|
|
4134
5333
|
});
|
|
4135
5334
|
child.on("exit", (code) => {
|
|
@@ -4139,6 +5338,9 @@ var BackgroundWorker = class {
|
|
|
4139
5338
|
reject(new Error(`Worker exited with code ${code}`));
|
|
4140
5339
|
}
|
|
4141
5340
|
});
|
|
5341
|
+
child.stdout?.on("data", (data) => {
|
|
5342
|
+
logger.log(data.toString());
|
|
5343
|
+
});
|
|
4142
5344
|
});
|
|
4143
5345
|
this._initialized = true;
|
|
4144
5346
|
}
|
|
@@ -4155,7 +5357,7 @@ var BackgroundWorker = class {
|
|
|
4155
5357
|
}
|
|
4156
5358
|
if (!this._taskRunProcesses.has(payload.execution.run.id)) {
|
|
4157
5359
|
const taskRunProcess = new TaskRunProcess(
|
|
4158
|
-
payload.execution
|
|
5360
|
+
payload.execution,
|
|
4159
5361
|
this.path,
|
|
4160
5362
|
{
|
|
4161
5363
|
...this.params.env,
|
|
@@ -4250,7 +5452,7 @@ var BackgroundWorker = class {
|
|
|
4250
5452
|
const result = {};
|
|
4251
5453
|
dotenv.config({
|
|
4252
5454
|
processEnv: result,
|
|
4253
|
-
path: [".env", ".env.local", ".env.development.local"].map((p) =>
|
|
5455
|
+
path: [".env", ".env.local", ".env.development.local"].map((p) => resolve3(process.cwd(), p))
|
|
4254
5456
|
});
|
|
4255
5457
|
process.env.TRIGGER_API_URL && (result.TRIGGER_API_URL = process.env.TRIGGER_API_URL);
|
|
4256
5458
|
delete result.TRIGGER_API_URL;
|
|
@@ -4265,9 +5467,9 @@ var BackgroundWorker = class {
|
|
|
4265
5467
|
}
|
|
4266
5468
|
};
|
|
4267
5469
|
var TaskRunProcess = class {
|
|
4268
|
-
constructor(
|
|
4269
|
-
this.
|
|
4270
|
-
this.path =
|
|
5470
|
+
constructor(execution, path7, env, metadata, worker) {
|
|
5471
|
+
this.execution = execution;
|
|
5472
|
+
this.path = path7;
|
|
4271
5473
|
this.env = env;
|
|
4272
5474
|
this.metadata = metadata;
|
|
4273
5475
|
this.worker = worker;
|
|
@@ -4297,9 +5499,20 @@ var TaskRunProcess = class {
|
|
|
4297
5499
|
await this.cleanup(true);
|
|
4298
5500
|
}
|
|
4299
5501
|
async initialize() {
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
5502
|
+
const fullEnv = {
|
|
5503
|
+
...this.execution.run.isTest ? { TRIGGER_LOG_LEVEL: "debug" } : {},
|
|
5504
|
+
...this.env,
|
|
5505
|
+
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
5506
|
+
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
5507
|
+
}),
|
|
5508
|
+
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
5509
|
+
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
5510
|
+
};
|
|
5511
|
+
const cwd = dirname2(this.path);
|
|
5512
|
+
logger.debug(`[${this.execution.run.id}] initializing task run process`, {
|
|
5513
|
+
env: fullEnv,
|
|
5514
|
+
path: this.path,
|
|
5515
|
+
cwd
|
|
4303
5516
|
});
|
|
4304
5517
|
this._child = fork(this.path, {
|
|
4305
5518
|
stdio: [
|
|
@@ -4311,15 +5524,8 @@ var TaskRunProcess = class {
|
|
|
4311
5524
|
"pipe",
|
|
4312
5525
|
"ipc"
|
|
4313
5526
|
],
|
|
4314
|
-
cwd
|
|
4315
|
-
env:
|
|
4316
|
-
...this.env,
|
|
4317
|
-
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
4318
|
-
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
4319
|
-
}),
|
|
4320
|
-
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
4321
|
-
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
4322
|
-
},
|
|
5527
|
+
cwd,
|
|
5528
|
+
env: fullEnv,
|
|
4323
5529
|
execArgv: this.worker.debuggerOn ? ["--inspect-brk", "--trace-uncaught", "--no-warnings=ExperimentalWarning"] : ["--trace-uncaught", "--no-warnings=ExperimentalWarning"]
|
|
4324
5530
|
});
|
|
4325
5531
|
this._child.on("message", this.#handleMessage.bind(this));
|
|
@@ -4331,18 +5537,24 @@ var TaskRunProcess = class {
|
|
|
4331
5537
|
if (kill && this._isBeingKilled) {
|
|
4332
5538
|
return;
|
|
4333
5539
|
}
|
|
4334
|
-
logger.debug(`[${this.
|
|
5540
|
+
logger.debug(`[${this.execution.run.id}] cleaning up task run process`, { kill });
|
|
4335
5541
|
await this._sender.send("CLEANUP", {
|
|
4336
5542
|
flush: true,
|
|
4337
5543
|
kill
|
|
4338
5544
|
});
|
|
4339
5545
|
this._isBeingKilled = kill;
|
|
5546
|
+
setTimeout(() => {
|
|
5547
|
+
if (this._child && !this._child.killed) {
|
|
5548
|
+
logger.debug(`[${this.execution.run.id}] killing task run process after timeout`);
|
|
5549
|
+
this._child.kill();
|
|
5550
|
+
}
|
|
5551
|
+
}, 5e3);
|
|
4340
5552
|
}
|
|
4341
5553
|
async executeTaskRun(payload) {
|
|
4342
5554
|
let resolver;
|
|
4343
5555
|
let rejecter;
|
|
4344
|
-
const promise = new Promise((
|
|
4345
|
-
resolver =
|
|
5556
|
+
const promise = new Promise((resolve5, reject) => {
|
|
5557
|
+
resolver = resolve5;
|
|
4346
5558
|
rejecter = reject;
|
|
4347
5559
|
});
|
|
4348
5560
|
this._attemptStatuses.set(payload.execution.attempt.id, "PENDING");
|
|
@@ -4362,10 +5574,13 @@ var TaskRunProcess = class {
|
|
|
4362
5574
|
if (!completion.ok && typeof completion.retry !== "undefined") {
|
|
4363
5575
|
return;
|
|
4364
5576
|
}
|
|
4365
|
-
if (execution.run.id === this.
|
|
5577
|
+
if (execution.run.id === this.execution.run.id) {
|
|
4366
5578
|
return;
|
|
4367
5579
|
}
|
|
4368
|
-
logger.debug(`[${this.
|
|
5580
|
+
logger.debug(`[${this.execution.run.id}] task run completed notification`, {
|
|
5581
|
+
completion,
|
|
5582
|
+
execution
|
|
5583
|
+
});
|
|
4369
5584
|
this._sender.send("TASK_RUN_COMPLETED_NOTIFICATION", {
|
|
4370
5585
|
completion,
|
|
4371
5586
|
execution
|
|
@@ -4390,6 +5605,7 @@ var TaskRunProcess = class {
|
|
|
4390
5605
|
break;
|
|
4391
5606
|
}
|
|
4392
5607
|
case "READY_TO_DISPOSE": {
|
|
5608
|
+
logger.debug(`[${this.execution.run.id}] task run process is ready to dispose`);
|
|
4393
5609
|
this.#kill();
|
|
4394
5610
|
break;
|
|
4395
5611
|
}
|
|
@@ -4403,7 +5619,7 @@ var TaskRunProcess = class {
|
|
|
4403
5619
|
}
|
|
4404
5620
|
}
|
|
4405
5621
|
async #handleExit(code) {
|
|
4406
|
-
logger.debug(`[${this.
|
|
5622
|
+
logger.debug(`[${this.execution.run.id}] task run process exiting`, { code });
|
|
4407
5623
|
for (const [id, status] of this._attemptStatuses.entries()) {
|
|
4408
5624
|
if (status === "PENDING") {
|
|
4409
5625
|
this._attemptStatuses.set(id, "REJECTED");
|
|
@@ -4425,10 +5641,14 @@ var TaskRunProcess = class {
|
|
|
4425
5641
|
}
|
|
4426
5642
|
#handleLog(data) {
|
|
4427
5643
|
if (!this._currentExecution) {
|
|
5644
|
+
logger.log(`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4428
5645
|
return;
|
|
4429
5646
|
}
|
|
5647
|
+
const runId = chalkRun(
|
|
5648
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5649
|
+
);
|
|
4430
5650
|
logger.log(
|
|
4431
|
-
|
|
5651
|
+
`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4432
5652
|
);
|
|
4433
5653
|
}
|
|
4434
5654
|
#handleStdErr(data) {
|
|
@@ -4436,41 +5656,76 @@ var TaskRunProcess = class {
|
|
|
4436
5656
|
return;
|
|
4437
5657
|
}
|
|
4438
5658
|
if (!this._currentExecution) {
|
|
4439
|
-
logger.
|
|
5659
|
+
logger.log(`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4440
5660
|
return;
|
|
4441
5661
|
}
|
|
4442
|
-
|
|
4443
|
-
|
|
5662
|
+
const runId = chalkRun(
|
|
5663
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5664
|
+
);
|
|
5665
|
+
logger.log(
|
|
5666
|
+
`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4444
5667
|
);
|
|
4445
5668
|
}
|
|
4446
5669
|
#kill() {
|
|
4447
5670
|
if (this._child && !this._child.killed) {
|
|
5671
|
+
logger.debug(`[${this.execution.run.id}] killing task run process`);
|
|
4448
5672
|
this._child?.kill();
|
|
4449
5673
|
}
|
|
4450
5674
|
}
|
|
4451
5675
|
};
|
|
4452
5676
|
|
|
5677
|
+
// src/utilities/runtimeCheck.ts
|
|
5678
|
+
function runtimeCheck(minimumMajor, minimumMinor) {
|
|
5679
|
+
if (typeof process === "undefined") {
|
|
5680
|
+
throw "The dev CLI can only be run in a Node.js compatible environment";
|
|
5681
|
+
}
|
|
5682
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
5683
|
+
const isBun = typeof process.versions.bun === "string";
|
|
5684
|
+
if (major < minimumMajor || major === minimumMajor && minor < minimumMinor) {
|
|
5685
|
+
if (isBun) {
|
|
5686
|
+
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}`;
|
|
5687
|
+
} else {
|
|
5688
|
+
throw `The dev CLI requires at least Node.js ${minimumMajor}.${minimumMinor}. You are running Node.js ${process.versions.node}`;
|
|
5689
|
+
}
|
|
5690
|
+
}
|
|
5691
|
+
logger.debug(
|
|
5692
|
+
`Node.js version: ${process.versions.node}${isBun ? ` (Bun ${process.versions.bun})` : ""}`
|
|
5693
|
+
);
|
|
5694
|
+
}
|
|
5695
|
+
|
|
4453
5696
|
// src/commands/dev.tsx
|
|
5697
|
+
import { findUp as findUp3, pathExists as pathExists2 } from "find-up";
|
|
5698
|
+
import { esbuildDecorators as esbuildDecorators3 } from "@anatine/esbuild-decorators";
|
|
4454
5699
|
var apiClient;
|
|
4455
5700
|
var DevCommandOptions = CommonCommandOptions.extend({
|
|
4456
5701
|
debugger: z5.boolean().default(false),
|
|
4457
5702
|
debugOtel: z5.boolean().default(false),
|
|
4458
5703
|
config: z5.string().optional(),
|
|
4459
|
-
projectRef: z5.string().optional()
|
|
5704
|
+
projectRef: z5.string().optional(),
|
|
5705
|
+
skipUpdateCheck: z5.boolean().default(false)
|
|
4460
5706
|
});
|
|
4461
5707
|
function configureDevCommand(program2) {
|
|
4462
5708
|
return commonOptions(
|
|
4463
|
-
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(
|
|
5709
|
+
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(
|
|
4464
5710
|
"-p, --project-ref <project ref>",
|
|
4465
5711
|
"The project ref. Required if there is no config file."
|
|
4466
|
-
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging")
|
|
4467
|
-
).action(async (
|
|
5712
|
+
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging").option("--skip-update-check", "Skip checking for @trigger.dev package updates")
|
|
5713
|
+
).action(async (path7, options) => {
|
|
4468
5714
|
wrapCommandAction("dev", DevCommandOptions, options, async (opts) => {
|
|
4469
|
-
await devCommand(
|
|
5715
|
+
await devCommand(path7, opts);
|
|
4470
5716
|
});
|
|
4471
5717
|
});
|
|
4472
5718
|
}
|
|
5719
|
+
var MINIMUM_NODE_MAJOR = 18;
|
|
5720
|
+
var MINIMUM_NODE_MINOR = 16;
|
|
4473
5721
|
async function devCommand(dir, options) {
|
|
5722
|
+
try {
|
|
5723
|
+
runtimeCheck(MINIMUM_NODE_MAJOR, MINIMUM_NODE_MINOR);
|
|
5724
|
+
} catch (e) {
|
|
5725
|
+
logger.log(`${chalkError("X Error:")} ${e}`);
|
|
5726
|
+
process.exitCode = 1;
|
|
5727
|
+
return;
|
|
5728
|
+
}
|
|
4474
5729
|
const authorization = await isLoggedIn(options.profile);
|
|
4475
5730
|
if (!authorization.ok) {
|
|
4476
5731
|
if (authorization.error === "fetch failed") {
|
|
@@ -4485,40 +5740,48 @@ async function devCommand(dir, options) {
|
|
|
4485
5740
|
process.exitCode = 1;
|
|
4486
5741
|
return;
|
|
4487
5742
|
}
|
|
4488
|
-
const devInstance = await startDev(dir, options, authorization.auth);
|
|
5743
|
+
const devInstance = await startDev(dir, options, authorization.auth, authorization.dashboardUrl);
|
|
4489
5744
|
const { waitUntilExit } = devInstance.devReactElement;
|
|
4490
5745
|
await waitUntilExit();
|
|
4491
5746
|
}
|
|
4492
|
-
async function startDev(dir, options, authorization) {
|
|
5747
|
+
async function startDev(dir, options, authorization, dashboardUrl) {
|
|
4493
5748
|
let rerender;
|
|
4494
5749
|
try {
|
|
4495
5750
|
if (options.logLevel) {
|
|
4496
5751
|
logger.loggerLevel = options.logLevel;
|
|
4497
5752
|
}
|
|
4498
5753
|
await printStandloneInitialBanner(true);
|
|
4499
|
-
|
|
5754
|
+
let displayedUpdateMessage = false;
|
|
5755
|
+
if (!options.skipUpdateCheck) {
|
|
5756
|
+
displayedUpdateMessage = await updateTriggerPackages(dir, { ...options }, true, true);
|
|
5757
|
+
}
|
|
5758
|
+
printDevBanner(displayedUpdateMessage);
|
|
4500
5759
|
logger.debug("Starting dev session", { dir, options, authorization });
|
|
4501
5760
|
let config = await readConfig(dir, {
|
|
4502
5761
|
projectRef: options.projectRef,
|
|
4503
5762
|
configFile: options.config
|
|
4504
5763
|
});
|
|
4505
5764
|
logger.debug("Initial config", { config });
|
|
5765
|
+
if (config.status === "error") {
|
|
5766
|
+
logger.error("Failed to read config", config.error);
|
|
5767
|
+
process.exit(1);
|
|
5768
|
+
}
|
|
4506
5769
|
async function getDevReactElement(configParam, authorization2, configPath) {
|
|
4507
5770
|
const accessToken = authorization2.accessToken;
|
|
4508
5771
|
const apiUrl = authorization2.apiUrl;
|
|
4509
5772
|
apiClient = new CliApiClient(apiUrl, accessToken);
|
|
4510
5773
|
const devEnv = await apiClient.getProjectEnv({
|
|
4511
|
-
projectRef:
|
|
5774
|
+
projectRef: configParam.project,
|
|
4512
5775
|
env: "dev"
|
|
4513
5776
|
});
|
|
4514
5777
|
if (!devEnv.success) {
|
|
4515
5778
|
if (devEnv.error === "Project not found") {
|
|
4516
5779
|
logger.error(
|
|
4517
|
-
`Project not found: ${
|
|
5780
|
+
`Project not found: ${configParam.project}. Ensure you are using the correct project ref and CLI profile (use --profile). Currently using the "${options.profile}" profile, which points to ${authorization2.apiUrl}`
|
|
4518
5781
|
);
|
|
4519
5782
|
} else {
|
|
4520
5783
|
logger.error(
|
|
4521
|
-
`Failed to initialize dev environment: ${devEnv.error}. Using project ref ${
|
|
5784
|
+
`Failed to initialize dev environment: ${devEnv.error}. Using project ref ${configParam.project}`
|
|
4522
5785
|
);
|
|
4523
5786
|
}
|
|
4524
5787
|
process.exit(1);
|
|
@@ -4527,6 +5790,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4527
5790
|
return /* @__PURE__ */ React.createElement(
|
|
4528
5791
|
DevUI,
|
|
4529
5792
|
{
|
|
5793
|
+
dashboardUrl,
|
|
4530
5794
|
config: configParam,
|
|
4531
5795
|
apiUrl,
|
|
4532
5796
|
apiKey: devEnv.data.apiKey,
|
|
@@ -4558,6 +5822,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4558
5822
|
}
|
|
4559
5823
|
function useDev({
|
|
4560
5824
|
config,
|
|
5825
|
+
dashboardUrl,
|
|
4561
5826
|
apiUrl,
|
|
4562
5827
|
apiKey,
|
|
4563
5828
|
environmentClient,
|
|
@@ -4587,7 +5852,7 @@ function useDev({
|
|
|
4587
5852
|
}
|
|
4588
5853
|
});
|
|
4589
5854
|
const backgroundWorkerCoordinator = new BackgroundWorkerCoordinator(
|
|
4590
|
-
`${
|
|
5855
|
+
`${dashboardUrl}/projects/v3/${config.project}`
|
|
4591
5856
|
);
|
|
4592
5857
|
websocket.addEventListener("open", async (event) => {
|
|
4593
5858
|
});
|
|
@@ -4659,22 +5924,21 @@ function useDev({
|
|
|
4659
5924
|
}
|
|
4660
5925
|
let latestWorkerContentHash;
|
|
4661
5926
|
const taskFiles = await gatherTaskFiles(config);
|
|
4662
|
-
const
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
"
|
|
5927
|
+
const workerFacadePath = join7(cliRootPath(), "workers", "dev", "worker-facade.js");
|
|
5928
|
+
const workerFacade = readFileSync3(workerFacadePath, "utf-8");
|
|
5929
|
+
const workerSetupPath = join7(cliRootPath(), "workers", "dev", "worker-setup.js");
|
|
5930
|
+
let entryPointContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
5931
|
+
"__WORKER_SETUP__",
|
|
5932
|
+
`import { tracingSDK, sender } from "${escapeImportPath(workerSetupPath)}";`
|
|
4668
5933
|
);
|
|
4669
|
-
const workerSetupPath = new URL(
|
|
4670
|
-
importResolve2("./workers/dev/worker-setup.js", import.meta.url)
|
|
4671
|
-
).href.replace("file://", "");
|
|
4672
|
-
let entryPointContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace("__WORKER_SETUP__", `import { tracingSDK, sender } from "${workerSetupPath}";`);
|
|
4673
5934
|
if (configPath) {
|
|
5935
|
+
configPath = normalize(configPath);
|
|
4674
5936
|
logger.debug("Importing project config from", { configPath });
|
|
4675
5937
|
entryPointContents = entryPointContents.replace(
|
|
4676
5938
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
4677
|
-
`import * as importedConfigExports from "${
|
|
5939
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
5940
|
+
configPath
|
|
5941
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
4678
5942
|
);
|
|
4679
5943
|
} else {
|
|
4680
5944
|
entryPointContents = entryPointContents.replace(
|
|
@@ -4690,6 +5954,9 @@ function useDev({
|
|
|
4690
5954
|
resolveDir: process.cwd(),
|
|
4691
5955
|
sourcefile: "__entryPoint.ts"
|
|
4692
5956
|
},
|
|
5957
|
+
banner: {
|
|
5958
|
+
js: `process.on("uncaughtException", function(error, origin) { if (error instanceof Error) { process.send && process.send({ type: "UNCAUGHT_EXCEPTION", payload: { error: { name: error.name, message: error.message, stack: error.stack }, origin }, version: "v1" }); } else { process.send && process.send({ type: "UNCAUGHT_EXCEPTION", payload: { error: { name: "Error", message: typeof error === "string" ? error : JSON.stringify(error) }, origin }, version: "v1" }); } });`
|
|
5959
|
+
},
|
|
4693
5960
|
bundle: true,
|
|
4694
5961
|
metafile: true,
|
|
4695
5962
|
write: false,
|
|
@@ -4707,12 +5974,19 @@ function useDev({
|
|
|
4707
5974
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
4708
5975
|
},
|
|
4709
5976
|
plugins: [
|
|
5977
|
+
mockServerOnlyPlugin(),
|
|
5978
|
+
bundleTriggerDevCore("workerFacade", config.tsconfigPath),
|
|
4710
5979
|
bundleDependenciesPlugin(
|
|
4711
5980
|
"workerFacade",
|
|
4712
5981
|
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
|
|
4713
5982
|
config.tsconfigPath
|
|
4714
5983
|
),
|
|
4715
5984
|
workerSetupImportConfigPlugin(configPath),
|
|
5985
|
+
esbuildDecorators3({
|
|
5986
|
+
tsconfig: config.tsconfigPath,
|
|
5987
|
+
tsx: true,
|
|
5988
|
+
force: false
|
|
5989
|
+
}),
|
|
4716
5990
|
{
|
|
4717
5991
|
name: "trigger.dev v3",
|
|
4718
5992
|
setup(build3) {
|
|
@@ -4726,19 +6000,19 @@ function useDev({
|
|
|
4726
6000
|
if (!firstBuild) {
|
|
4727
6001
|
logger.log(chalkGrey("\u25CB Building background worker\u2026"));
|
|
4728
6002
|
}
|
|
4729
|
-
const metaOutputKey =
|
|
6003
|
+
const metaOutputKey = join7("out", `stdin.js`).replace(/\\/g, "/");
|
|
4730
6004
|
const metaOutput = result.metafile.outputs[metaOutputKey];
|
|
4731
6005
|
if (!metaOutput) {
|
|
4732
6006
|
throw new Error(`Could not find metafile`);
|
|
4733
6007
|
}
|
|
4734
|
-
const outputFileKey =
|
|
6008
|
+
const outputFileKey = join7(config.projectDir, metaOutputKey);
|
|
4735
6009
|
const outputFile = result.outputFiles.find((file) => file.path === outputFileKey);
|
|
4736
6010
|
if (!outputFile) {
|
|
4737
6011
|
throw new Error(
|
|
4738
6012
|
`Could not find output file for entry point ${metaOutput.entryPoint}`
|
|
4739
6013
|
);
|
|
4740
6014
|
}
|
|
4741
|
-
const sourceMapFileKey =
|
|
6015
|
+
const sourceMapFileKey = join7(config.projectDir, `${metaOutputKey}.map`);
|
|
4742
6016
|
const sourceMapFile = result.outputFiles.find(
|
|
4743
6017
|
(file) => file.path === sourceMapFileKey
|
|
4744
6018
|
);
|
|
@@ -4749,20 +6023,20 @@ function useDev({
|
|
|
4749
6023
|
logger.log(chalkGrey("\u25CB No changes detected, skipping build\u2026"));
|
|
4750
6024
|
return;
|
|
4751
6025
|
}
|
|
4752
|
-
const fullPath =
|
|
6026
|
+
const fullPath = join7(config.projectDir, ".trigger", `${contentHash}.js`);
|
|
4753
6027
|
const sourceMapPath = `${fullPath}.map`;
|
|
4754
6028
|
const outputFileWithSourceMap = `${outputFile.text}
|
|
4755
|
-
//# sourceMappingURL=${
|
|
6029
|
+
//# sourceMappingURL=${basename2(sourceMapPath)}`;
|
|
4756
6030
|
await fs7.promises.mkdir(dirname3(fullPath), { recursive: true });
|
|
4757
6031
|
await fs7.promises.writeFile(fullPath, outputFileWithSourceMap);
|
|
4758
6032
|
logger.debug(`Wrote background worker to ${fullPath}`);
|
|
4759
|
-
const dependencies2 = await
|
|
6033
|
+
const dependencies2 = await gatherRequiredDependencies(metaOutput, config);
|
|
4760
6034
|
if (sourceMapFile) {
|
|
4761
6035
|
const sourceMapPath2 = `${fullPath}.map`;
|
|
4762
6036
|
await fs7.promises.writeFile(sourceMapPath2, sourceMapFile.text);
|
|
4763
6037
|
}
|
|
4764
6038
|
const environmentVariablesResponse = await environmentClient.getEnvironmentVariables(config.project);
|
|
4765
|
-
const processEnv = gatherProcessEnv();
|
|
6039
|
+
const processEnv = await gatherProcessEnv();
|
|
4766
6040
|
const backgroundWorker = new BackgroundWorker(fullPath, {
|
|
4767
6041
|
projectConfig: config,
|
|
4768
6042
|
dependencies: dependencies2,
|
|
@@ -4780,8 +6054,15 @@ function useDev({
|
|
|
4780
6054
|
latestWorkerContentHash = contentHash;
|
|
4781
6055
|
let packageVersion;
|
|
4782
6056
|
const taskResources = [];
|
|
4783
|
-
if (!backgroundWorker.tasks) {
|
|
4784
|
-
|
|
6057
|
+
if (!backgroundWorker.tasks || backgroundWorker.tasks.length === 0) {
|
|
6058
|
+
logger.log(
|
|
6059
|
+
`${chalkError(
|
|
6060
|
+
"X Error:"
|
|
6061
|
+
)} Worker failed to build: no tasks found. Searched in ${config.triggerDirectories.join(
|
|
6062
|
+
", "
|
|
6063
|
+
)}`
|
|
6064
|
+
);
|
|
6065
|
+
return;
|
|
4785
6066
|
}
|
|
4786
6067
|
for (const task of backgroundWorker.tasks) {
|
|
4787
6068
|
taskResources.push(task);
|
|
@@ -4800,6 +6081,9 @@ function useDev({
|
|
|
4800
6081
|
);
|
|
4801
6082
|
return;
|
|
4802
6083
|
}
|
|
6084
|
+
logger.debug("Creating background worker with tasks", {
|
|
6085
|
+
tasks: taskResources
|
|
6086
|
+
});
|
|
4803
6087
|
const backgroundWorkerBody = {
|
|
4804
6088
|
localOnly: true,
|
|
4805
6089
|
metadata: {
|
|
@@ -4830,17 +6114,52 @@ function useDev({
|
|
|
4830
6114
|
backgroundWorker
|
|
4831
6115
|
);
|
|
4832
6116
|
} catch (e) {
|
|
4833
|
-
if (e instanceof
|
|
4834
|
-
|
|
4835
|
-
|
|
6117
|
+
if (e instanceof TaskMetadataParseError) {
|
|
6118
|
+
logTaskMetadataParseError(e.zodIssues, e.tasks);
|
|
6119
|
+
return;
|
|
6120
|
+
} else if (e instanceof UncaughtExceptionError) {
|
|
6121
|
+
const parsedBuildError = parseBuildErrorStack(e.originalError);
|
|
6122
|
+
if (parsedBuildError && typeof parsedBuildError !== "string") {
|
|
6123
|
+
logESMRequireError(
|
|
6124
|
+
parsedBuildError,
|
|
6125
|
+
configPath ? { status: "file", path: configPath, config } : { status: "in-memory", config }
|
|
6126
|
+
);
|
|
6127
|
+
return;
|
|
6128
|
+
} else {
|
|
6129
|
+
}
|
|
6130
|
+
if (e.originalError.message || e.originalError.stack) {
|
|
6131
|
+
logger.log(
|
|
6132
|
+
`${chalkError("X Error:")} Worker failed to start`,
|
|
6133
|
+
e.originalError.stack ?? e.originalError.message
|
|
6134
|
+
);
|
|
4836
6135
|
}
|
|
4837
6136
|
return;
|
|
4838
6137
|
}
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
6138
|
+
const parsedError = parseNpmInstallError(e);
|
|
6139
|
+
if (typeof parsedError === "string") {
|
|
6140
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
6141
|
+
} else {
|
|
6142
|
+
switch (parsedError.type) {
|
|
6143
|
+
case "package-not-found-error": {
|
|
6144
|
+
logger.log(
|
|
6145
|
+
`
|
|
6146
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
6147
|
+
parsedError.packageName
|
|
6148
|
+
)} could not be found in the npm registry.`
|
|
6149
|
+
);
|
|
6150
|
+
break;
|
|
6151
|
+
}
|
|
6152
|
+
case "no-matching-version-error": {
|
|
6153
|
+
logger.log(
|
|
6154
|
+
`
|
|
6155
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
6156
|
+
parsedError.packageName
|
|
6157
|
+
)} could not resolve because the version doesn't exist`
|
|
6158
|
+
);
|
|
6159
|
+
break;
|
|
6160
|
+
}
|
|
6161
|
+
}
|
|
4842
6162
|
}
|
|
4843
|
-
logger.error(`Background worker failed to start: ${e}`);
|
|
4844
6163
|
}
|
|
4845
6164
|
});
|
|
4846
6165
|
}
|
|
@@ -4851,17 +6170,17 @@ function useDev({
|
|
|
4851
6170
|
}
|
|
4852
6171
|
const throttledRebuild = pDebounce(runBuild, 250, { before: true });
|
|
4853
6172
|
const taskFileWatcher = watch(
|
|
4854
|
-
config.triggerDirectories.map((triggerDir) => `${triggerDir}
|
|
6173
|
+
config.triggerDirectories.map((triggerDir) => `${triggerDir}/**/*.ts`),
|
|
4855
6174
|
{
|
|
4856
6175
|
ignoreInitial: true
|
|
4857
6176
|
}
|
|
4858
6177
|
);
|
|
4859
|
-
taskFileWatcher.on("add", async (
|
|
6178
|
+
taskFileWatcher.on("add", async (path7) => {
|
|
4860
6179
|
throttledRebuild().catch((error) => {
|
|
4861
6180
|
logger.error(error);
|
|
4862
6181
|
});
|
|
4863
6182
|
});
|
|
4864
|
-
taskFileWatcher.on("unlink", async (
|
|
6183
|
+
taskFileWatcher.on("unlink", async (path7) => {
|
|
4865
6184
|
throttledRebuild().catch((error) => {
|
|
4866
6185
|
logger.error(error);
|
|
4867
6186
|
});
|
|
@@ -4902,7 +6221,7 @@ function WebsocketFactory(apiKey) {
|
|
|
4902
6221
|
}
|
|
4903
6222
|
};
|
|
4904
6223
|
}
|
|
4905
|
-
async function
|
|
6224
|
+
async function gatherRequiredDependencies(outputMeta, config) {
|
|
4906
6225
|
const dependencies2 = {};
|
|
4907
6226
|
logger.debug("Gathering required dependencies from imports", {
|
|
4908
6227
|
imports: outputMeta.imports
|
|
@@ -4921,7 +6240,7 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4921
6240
|
}
|
|
4922
6241
|
}
|
|
4923
6242
|
if (config.additionalPackages) {
|
|
4924
|
-
const projectPackageJson = await readJSONFile(
|
|
6243
|
+
const projectPackageJson = await readJSONFile(join7(config.projectDir, "package.json"));
|
|
4925
6244
|
for (const packageName of config.additionalPackages) {
|
|
4926
6245
|
if (dependencies2[packageName]) {
|
|
4927
6246
|
continue;
|
|
@@ -4958,7 +6277,7 @@ ${task.filePath} -> ${task.exportName}`).join("")}`;
|
|
|
4958
6277
|
}).join("");
|
|
4959
6278
|
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
|
|
4960
6279
|
}
|
|
4961
|
-
function gatherProcessEnv() {
|
|
6280
|
+
async function gatherProcessEnv() {
|
|
4962
6281
|
const env = {
|
|
4963
6282
|
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
4964
6283
|
PATH: process.env.PATH,
|
|
@@ -4969,31 +6288,54 @@ function gatherProcessEnv() {
|
|
|
4969
6288
|
NVM_BIN: process.env.NVM_BIN,
|
|
4970
6289
|
LANG: process.env.LANG,
|
|
4971
6290
|
TERM: process.env.TERM,
|
|
4972
|
-
NODE_PATH: process.env.NODE_PATH,
|
|
6291
|
+
NODE_PATH: await amendNodePathWithPnpmNodeModules(process.env.NODE_PATH),
|
|
4973
6292
|
HOME: process.env.HOME,
|
|
4974
6293
|
BUN_INSTALL: process.env.BUN_INSTALL
|
|
4975
6294
|
};
|
|
4976
6295
|
return Object.fromEntries(Object.entries(env).filter(([key, value]) => value !== void 0));
|
|
4977
6296
|
}
|
|
6297
|
+
async function amendNodePathWithPnpmNodeModules(nodePath) {
|
|
6298
|
+
const pnpmModulesPath = await findPnpmNodeModulesPath();
|
|
6299
|
+
if (!pnpmModulesPath) {
|
|
6300
|
+
return nodePath;
|
|
6301
|
+
}
|
|
6302
|
+
if (nodePath) {
|
|
6303
|
+
if (nodePath.includes(pnpmModulesPath)) {
|
|
6304
|
+
return nodePath;
|
|
6305
|
+
}
|
|
6306
|
+
return `${nodePath}:${pnpmModulesPath}`;
|
|
6307
|
+
}
|
|
6308
|
+
return pnpmModulesPath;
|
|
6309
|
+
}
|
|
6310
|
+
async function findPnpmNodeModulesPath() {
|
|
6311
|
+
return await findUp3(
|
|
6312
|
+
async (directory) => {
|
|
6313
|
+
const pnpmModules = join7(directory, "node_modules", ".pnpm", "node_modules");
|
|
6314
|
+
const hasPnpmNodeModules = await pathExists2(pnpmModules);
|
|
6315
|
+
if (hasPnpmNodeModules) {
|
|
6316
|
+
return pnpmModules;
|
|
6317
|
+
}
|
|
6318
|
+
},
|
|
6319
|
+
{ type: "directory" }
|
|
6320
|
+
);
|
|
6321
|
+
}
|
|
4978
6322
|
|
|
4979
6323
|
// src/commands/init.ts
|
|
4980
|
-
import { intro as
|
|
6324
|
+
import { intro as intro5, isCancel as isCancel2, log as log6, outro as outro6, select as select2, text } from "@clack/prompts";
|
|
4981
6325
|
import { context as context3, trace as trace3 } from "@opentelemetry/api";
|
|
4982
|
-
import {
|
|
4983
|
-
|
|
4984
|
-
recordSpanException as recordSpanException5
|
|
4985
|
-
} from "@trigger.dev/core/v3";
|
|
6326
|
+
import { flattenAttributes as flattenAttributes4 } from "@trigger.dev/core/v3";
|
|
6327
|
+
import { recordSpanException as recordSpanException6 } from "@trigger.dev/core/v3/workers";
|
|
4986
6328
|
import chalk5 from "chalk";
|
|
4987
6329
|
import { execa as execa3 } from "execa";
|
|
4988
6330
|
import { applyEdits, modify } from "jsonc-parser";
|
|
4989
6331
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
4990
|
-
import { join as
|
|
4991
|
-
import
|
|
6332
|
+
import { join as join8, relative as relative4, resolve as resolve4 } from "node:path";
|
|
6333
|
+
import terminalLink4 from "terminal-link";
|
|
4992
6334
|
import { z as z6 } from "zod";
|
|
4993
6335
|
|
|
4994
6336
|
// src/utilities/createFileFromTemplate.ts
|
|
4995
6337
|
import fs8 from "fs/promises";
|
|
4996
|
-
import
|
|
6338
|
+
import path6 from "path";
|
|
4997
6339
|
async function createFileFromTemplate(params) {
|
|
4998
6340
|
let template = await readFile(params.templatePath);
|
|
4999
6341
|
if (await pathExists(params.outputPath) && !params.override) {
|
|
@@ -5004,7 +6346,7 @@ async function createFileFromTemplate(params) {
|
|
|
5004
6346
|
}
|
|
5005
6347
|
try {
|
|
5006
6348
|
const output = replaceAll(template, params.replacements);
|
|
5007
|
-
const directoryName =
|
|
6349
|
+
const directoryName = path6.dirname(params.outputPath);
|
|
5008
6350
|
await fs8.mkdir(directoryName, { recursive: true });
|
|
5009
6351
|
await fs8.writeFile(params.outputPath, output);
|
|
5010
6352
|
return {
|
|
@@ -5032,51 +6374,6 @@ function replaceAll(input, replacements) {
|
|
|
5032
6374
|
return output;
|
|
5033
6375
|
}
|
|
5034
6376
|
|
|
5035
|
-
// src/utilities/getUserPackageManager.ts
|
|
5036
|
-
import pathModule2 from "path";
|
|
5037
|
-
async function getUserPackageManager(path6) {
|
|
5038
|
-
try {
|
|
5039
|
-
return await detectPackageManagerFromArtifacts(path6);
|
|
5040
|
-
} catch (error) {
|
|
5041
|
-
return detectPackageManagerFromCurrentCommand();
|
|
5042
|
-
}
|
|
5043
|
-
}
|
|
5044
|
-
function detectPackageManagerFromCurrentCommand() {
|
|
5045
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
5046
|
-
if (userAgent) {
|
|
5047
|
-
if (userAgent.startsWith("yarn")) {
|
|
5048
|
-
return "yarn";
|
|
5049
|
-
} else if (userAgent.startsWith("pnpm")) {
|
|
5050
|
-
return "pnpm";
|
|
5051
|
-
} else {
|
|
5052
|
-
return "npm";
|
|
5053
|
-
}
|
|
5054
|
-
} else {
|
|
5055
|
-
return "npm";
|
|
5056
|
-
}
|
|
5057
|
-
}
|
|
5058
|
-
async function detectPackageManagerFromArtifacts(path6) {
|
|
5059
|
-
const packageFiles = [
|
|
5060
|
-
{ name: "yarn.lock", pm: "yarn" },
|
|
5061
|
-
{ name: "pnpm-lock.yaml", pm: "pnpm" },
|
|
5062
|
-
{ name: "package-lock.json", pm: "npm" },
|
|
5063
|
-
{ name: "npm-shrinkwrap.json", pm: "npm" }
|
|
5064
|
-
];
|
|
5065
|
-
for (const { name, pm } of packageFiles) {
|
|
5066
|
-
const exists = await pathExists(pathModule2.join(path6, name));
|
|
5067
|
-
if (exists) {
|
|
5068
|
-
return pm;
|
|
5069
|
-
}
|
|
5070
|
-
}
|
|
5071
|
-
throw new Error("Could not detect package manager from artifacts");
|
|
5072
|
-
}
|
|
5073
|
-
|
|
5074
|
-
// src/utilities/resolveInternalFilePath.ts
|
|
5075
|
-
import { resolve as importResolve3 } from "import-meta-resolve";
|
|
5076
|
-
function resolveInternalFilePath(filePath) {
|
|
5077
|
-
return new URL(importResolve3(filePath, import.meta.url)).href.replace("file://", "");
|
|
5078
|
-
}
|
|
5079
|
-
|
|
5080
6377
|
// src/commands/init.ts
|
|
5081
6378
|
var InitCommandOptions = CommonCommandOptions.extend({
|
|
5082
6379
|
projectRef: z6.string().optional(),
|
|
@@ -5094,10 +6391,10 @@ function configureInitCommand(program2) {
|
|
|
5094
6391
|
"The version of the @trigger.dev/sdk package to install",
|
|
5095
6392
|
"beta"
|
|
5096
6393
|
).option("--skip-package-install", "Skip installing the @trigger.dev/sdk package").option("--override-config", "Override the existing config file if it exists")
|
|
5097
|
-
).action(async (
|
|
6394
|
+
).action(async (path7, options) => {
|
|
5098
6395
|
await handleTelemetry(async () => {
|
|
5099
6396
|
await printStandloneInitialBanner(true);
|
|
5100
|
-
await initCommand(
|
|
6397
|
+
await initCommand(path7, options);
|
|
5101
6398
|
});
|
|
5102
6399
|
});
|
|
5103
6400
|
}
|
|
@@ -5108,7 +6405,7 @@ async function initCommand(dir, options) {
|
|
|
5108
6405
|
}
|
|
5109
6406
|
async function _initCommand(dir, options) {
|
|
5110
6407
|
const span = trace3.getSpan(context3.active());
|
|
5111
|
-
|
|
6408
|
+
intro5("Initializing project");
|
|
5112
6409
|
const authorization = await login({
|
|
5113
6410
|
embedded: true,
|
|
5114
6411
|
defaultApiUrl: options.apiUrl,
|
|
@@ -5132,7 +6429,7 @@ async function _initCommand(dir, options) {
|
|
|
5132
6429
|
if (!options.overrideConfig) {
|
|
5133
6430
|
try {
|
|
5134
6431
|
const result = await readConfig(dir);
|
|
5135
|
-
|
|
6432
|
+
outro6(
|
|
5136
6433
|
result.status === "file" ? `Project already initialized: Found config file at ${result.path}. Pass --override-config to override` : "Project already initialized"
|
|
5137
6434
|
);
|
|
5138
6435
|
return;
|
|
@@ -5146,58 +6443,59 @@ async function _initCommand(dir, options) {
|
|
|
5146
6443
|
options.projectRef
|
|
5147
6444
|
);
|
|
5148
6445
|
span?.setAttributes({
|
|
5149
|
-
...
|
|
6446
|
+
...flattenAttributes4(selectedProject, "cli.project")
|
|
5150
6447
|
});
|
|
5151
6448
|
logger.debug("Selected project", selectedProject);
|
|
5152
|
-
|
|
6449
|
+
log6.step(`Configuring project "${selectedProject.name}" (${selectedProject.externalRef})`);
|
|
5153
6450
|
if (!options.skipPackageInstall) {
|
|
5154
6451
|
await installPackages2(dir, options);
|
|
5155
6452
|
} else {
|
|
5156
|
-
|
|
6453
|
+
log6.info("Skipping package installation");
|
|
5157
6454
|
}
|
|
5158
6455
|
const triggerDir = await createTriggerDir(dir, options);
|
|
5159
6456
|
await writeConfigFile(dir, selectedProject, options, triggerDir);
|
|
5160
6457
|
await addConfigFileToTsConfig(dir, options);
|
|
5161
6458
|
await gitIgnoreDotTriggerDir(dir, options);
|
|
5162
|
-
const projectDashboard =
|
|
6459
|
+
const projectDashboard = terminalLink4(
|
|
5163
6460
|
"project dashboard",
|
|
5164
6461
|
`${authorization.dashboardUrl}/projects/v3/${selectedProject.externalRef}`
|
|
5165
6462
|
);
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
6463
|
+
log6.success("Successfully initialized project for Trigger.dev v3 \u{1FAE1}");
|
|
6464
|
+
log6.info("Next steps:");
|
|
6465
|
+
log6.info(
|
|
5169
6466
|
` 1. To start developing, run ${chalk5.green(
|
|
5170
6467
|
`npx trigger.dev@${options.tag} dev`
|
|
5171
6468
|
)} in your project directory`
|
|
5172
6469
|
);
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
` 3. Head over to our ${
|
|
6470
|
+
log6.info(` 2. Visit your ${projectDashboard} to view your newly created tasks.`);
|
|
6471
|
+
log6.info(
|
|
6472
|
+
` 3. Head over to our ${terminalLink4(
|
|
5176
6473
|
"v3 docs",
|
|
5177
6474
|
"https://trigger.dev/docs/v3"
|
|
5178
6475
|
)} to learn more.`
|
|
5179
6476
|
);
|
|
5180
|
-
|
|
5181
|
-
` 4. Need help? Join our ${
|
|
6477
|
+
log6.info(
|
|
6478
|
+
` 4. Need help? Join our ${terminalLink4(
|
|
5182
6479
|
"Discord community",
|
|
5183
6480
|
"https://trigger.dev/discord"
|
|
5184
6481
|
)} or email us at ${chalk5.cyan("help@trigger.dev")}`
|
|
5185
6482
|
);
|
|
5186
|
-
|
|
6483
|
+
outro6(`Project initialized successfully. Happy coding!`);
|
|
5187
6484
|
}
|
|
5188
6485
|
async function createTriggerDir(dir, options) {
|
|
5189
6486
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5190
6487
|
try {
|
|
5191
|
-
const defaultValue =
|
|
6488
|
+
const defaultValue = join8(dir, "src", "trigger");
|
|
5192
6489
|
const location = await text({
|
|
5193
6490
|
message: "Where would you like to create the Trigger.dev directory?",
|
|
5194
6491
|
defaultValue,
|
|
5195
6492
|
placeholder: defaultValue
|
|
5196
6493
|
});
|
|
5197
|
-
if (
|
|
6494
|
+
if (isCancel2(location)) {
|
|
5198
6495
|
throw new OutroCommandError();
|
|
5199
6496
|
}
|
|
5200
|
-
const triggerDir =
|
|
6497
|
+
const triggerDir = resolve4(process.cwd(), location);
|
|
6498
|
+
logger.debug({ triggerDir });
|
|
5201
6499
|
span.setAttributes({
|
|
5202
6500
|
"cli.triggerDir": triggerDir
|
|
5203
6501
|
});
|
|
@@ -5215,7 +6513,7 @@ async function createTriggerDir(dir, options) {
|
|
|
5215
6513
|
}
|
|
5216
6514
|
]
|
|
5217
6515
|
});
|
|
5218
|
-
if (
|
|
6516
|
+
if (isCancel2(exampleSelection)) {
|
|
5219
6517
|
throw new OutroCommandError();
|
|
5220
6518
|
}
|
|
5221
6519
|
const example = exampleSelection;
|
|
@@ -5223,25 +6521,25 @@ async function createTriggerDir(dir, options) {
|
|
|
5223
6521
|
"cli.example": example
|
|
5224
6522
|
});
|
|
5225
6523
|
if (example === "none") {
|
|
5226
|
-
await createFile(
|
|
5227
|
-
|
|
6524
|
+
await createFile(join8(triggerDir, ".gitkeep"), "");
|
|
6525
|
+
log6.step(`Created directory at ${location}`);
|
|
5228
6526
|
span.end();
|
|
5229
6527
|
return { location, isCustomValue: location !== defaultValue };
|
|
5230
6528
|
}
|
|
5231
|
-
const
|
|
5232
|
-
const outputPath =
|
|
6529
|
+
const templatePath = join8(cliRootPath(), "templates", "examples", `${example}.ts.template`);
|
|
6530
|
+
const outputPath = join8(triggerDir, "example.ts");
|
|
5233
6531
|
await createFileFromTemplate({
|
|
5234
|
-
templatePath
|
|
6532
|
+
templatePath,
|
|
5235
6533
|
outputPath,
|
|
5236
6534
|
replacements: {}
|
|
5237
6535
|
});
|
|
5238
|
-
const relativeOutputPath =
|
|
5239
|
-
|
|
6536
|
+
const relativeOutputPath = relative4(process.cwd(), outputPath);
|
|
6537
|
+
log6.step(`Created example file at ${relativeOutputPath}`);
|
|
5240
6538
|
span.end();
|
|
5241
6539
|
return { location, isCustomValue: location !== defaultValue };
|
|
5242
6540
|
} catch (e) {
|
|
5243
6541
|
if (!(e instanceof SkipCommandError)) {
|
|
5244
|
-
|
|
6542
|
+
recordSpanException6(span, e);
|
|
5245
6543
|
}
|
|
5246
6544
|
span.end();
|
|
5247
6545
|
throw e;
|
|
@@ -5251,15 +6549,15 @@ async function createTriggerDir(dir, options) {
|
|
|
5251
6549
|
async function gitIgnoreDotTriggerDir(dir, options) {
|
|
5252
6550
|
return await tracer.startActiveSpan("gitIgnoreDotTriggerDir", async (span) => {
|
|
5253
6551
|
try {
|
|
5254
|
-
const projectDir =
|
|
5255
|
-
const gitIgnorePath =
|
|
6552
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6553
|
+
const gitIgnorePath = join8(projectDir, ".gitignore");
|
|
5256
6554
|
span.setAttributes({
|
|
5257
6555
|
"cli.projectDir": projectDir,
|
|
5258
6556
|
"cli.gitIgnorePath": gitIgnorePath
|
|
5259
6557
|
});
|
|
5260
6558
|
if (!await pathExists(gitIgnorePath)) {
|
|
5261
6559
|
await createFile(gitIgnorePath, ".trigger");
|
|
5262
|
-
|
|
6560
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5263
6561
|
span.end();
|
|
5264
6562
|
return;
|
|
5265
6563
|
}
|
|
@@ -5271,11 +6569,11 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5271
6569
|
const newGitIgnoreContent = `${gitIgnoreContent}
|
|
5272
6570
|
.trigger`;
|
|
5273
6571
|
await writeFile3(gitIgnorePath, newGitIgnoreContent, "utf-8");
|
|
5274
|
-
|
|
6572
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5275
6573
|
span.end();
|
|
5276
6574
|
} catch (e) {
|
|
5277
6575
|
if (!(e instanceof SkipCommandError)) {
|
|
5278
|
-
|
|
6576
|
+
recordSpanException6(span, e);
|
|
5279
6577
|
}
|
|
5280
6578
|
span.end();
|
|
5281
6579
|
throw e;
|
|
@@ -5285,8 +6583,8 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5285
6583
|
async function addConfigFileToTsConfig(dir, options) {
|
|
5286
6584
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5287
6585
|
try {
|
|
5288
|
-
const projectDir =
|
|
5289
|
-
const tsconfigPath =
|
|
6586
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6587
|
+
const tsconfigPath = join8(projectDir, "tsconfig.json");
|
|
5290
6588
|
span.setAttributes({
|
|
5291
6589
|
"cli.projectDir": projectDir,
|
|
5292
6590
|
"cli.tsconfigPath": tsconfigPath
|
|
@@ -5304,11 +6602,11 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5304
6602
|
const newTsconfigContent = applyEdits(tsconfigContent, edits);
|
|
5305
6603
|
logger.debug("new tsconfig.json content", { newTsconfigContent });
|
|
5306
6604
|
await writeFile3(tsconfigPath, newTsconfigContent, "utf-8");
|
|
5307
|
-
|
|
6605
|
+
log6.step(`Added trigger.config.ts to tsconfig.json`);
|
|
5308
6606
|
span.end();
|
|
5309
6607
|
} catch (e) {
|
|
5310
6608
|
if (!(e instanceof SkipCommandError)) {
|
|
5311
|
-
|
|
6609
|
+
recordSpanException6(span, e);
|
|
5312
6610
|
}
|
|
5313
6611
|
span.end();
|
|
5314
6612
|
throw e;
|
|
@@ -5317,9 +6615,9 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5317
6615
|
}
|
|
5318
6616
|
async function installPackages2(dir, options) {
|
|
5319
6617
|
return await tracer.startActiveSpan("installPackages", async (span) => {
|
|
5320
|
-
const installSpinner =
|
|
6618
|
+
const installSpinner = spinner();
|
|
5321
6619
|
try {
|
|
5322
|
-
const projectDir =
|
|
6620
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
5323
6621
|
const pkgManager = await getUserPackageManager(projectDir);
|
|
5324
6622
|
span.setAttributes({
|
|
5325
6623
|
"cli.projectDir": projectDir,
|
|
@@ -5359,7 +6657,7 @@ async function installPackages2(dir, options) {
|
|
|
5359
6657
|
`Failed to install @trigger.dev/sdk@${options.tag}. Rerun command with --log-level debug for more details.`
|
|
5360
6658
|
);
|
|
5361
6659
|
if (!(e instanceof SkipCommandError)) {
|
|
5362
|
-
|
|
6660
|
+
recordSpanException6(span, e);
|
|
5363
6661
|
}
|
|
5364
6662
|
span.end();
|
|
5365
6663
|
throw e;
|
|
@@ -5369,11 +6667,11 @@ async function installPackages2(dir, options) {
|
|
|
5369
6667
|
async function writeConfigFile(dir, project, options, triggerDir) {
|
|
5370
6668
|
return await tracer.startActiveSpan("writeConfigFile", async (span) => {
|
|
5371
6669
|
try {
|
|
5372
|
-
const spnnr =
|
|
6670
|
+
const spnnr = spinner();
|
|
5373
6671
|
spnnr.start("Creating config file");
|
|
5374
|
-
const projectDir =
|
|
5375
|
-
const templatePath =
|
|
5376
|
-
const outputPath =
|
|
6672
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6673
|
+
const templatePath = join8(cliRootPath(), "templates", "trigger.config.ts.template");
|
|
6674
|
+
const outputPath = join8(projectDir, "trigger.config.ts");
|
|
5377
6675
|
span.setAttributes({
|
|
5378
6676
|
"cli.projectDir": projectDir,
|
|
5379
6677
|
"cli.templatePath": templatePath,
|
|
@@ -5389,7 +6687,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5389
6687
|
outputPath,
|
|
5390
6688
|
override: options.overrideConfig
|
|
5391
6689
|
});
|
|
5392
|
-
const relativePathToOutput =
|
|
6690
|
+
const relativePathToOutput = relative4(process.cwd(), outputPath);
|
|
5393
6691
|
spnnr.stop(
|
|
5394
6692
|
result.success ? `Config file created at ${relativePathToOutput}` : `Failed to create config file: ${result.error}`
|
|
5395
6693
|
);
|
|
@@ -5400,7 +6698,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5400
6698
|
return result.success;
|
|
5401
6699
|
} catch (e) {
|
|
5402
6700
|
if (!(e instanceof SkipCommandError)) {
|
|
5403
|
-
|
|
6701
|
+
recordSpanException6(span, e);
|
|
5404
6702
|
}
|
|
5405
6703
|
span.end();
|
|
5406
6704
|
throw e;
|
|
@@ -5413,13 +6711,13 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5413
6711
|
if (projectRef) {
|
|
5414
6712
|
const projectResponse = await apiClient2.getProject(projectRef);
|
|
5415
6713
|
if (!projectResponse.success) {
|
|
5416
|
-
|
|
6714
|
+
log6.error(
|
|
5417
6715
|
`--project-ref ${projectRef} is not a valid project ref. Request to fetch data resulted in: ${projectResponse.error}`
|
|
5418
6716
|
);
|
|
5419
6717
|
throw new SkipCommandError(projectResponse.error);
|
|
5420
6718
|
}
|
|
5421
6719
|
span.setAttributes({
|
|
5422
|
-
...
|
|
6720
|
+
...flattenAttributes4(projectResponse.data, "cli.project")
|
|
5423
6721
|
});
|
|
5424
6722
|
span.end();
|
|
5425
6723
|
return projectResponse.data;
|
|
@@ -5429,11 +6727,11 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5429
6727
|
throw new Error(`Failed to get projects: ${projectsResponse.error}`);
|
|
5430
6728
|
}
|
|
5431
6729
|
if (projectsResponse.data.length === 0) {
|
|
5432
|
-
const newProjectLink =
|
|
6730
|
+
const newProjectLink = terminalLink4(
|
|
5433
6731
|
"Create new project",
|
|
5434
6732
|
`${dashboardUrl}/projects/new?version=v3`
|
|
5435
6733
|
);
|
|
5436
|
-
|
|
6734
|
+
outro6(`You don't have any projects yet. ${newProjectLink}`);
|
|
5437
6735
|
throw new SkipCommandError();
|
|
5438
6736
|
}
|
|
5439
6737
|
const selectedProject = await select2({
|
|
@@ -5444,7 +6742,7 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5444
6742
|
hint: project.organization.title
|
|
5445
6743
|
}))
|
|
5446
6744
|
});
|
|
5447
|
-
if (
|
|
6745
|
+
if (isCancel2(selectedProject)) {
|
|
5448
6746
|
throw new OutroCommandError();
|
|
5449
6747
|
}
|
|
5450
6748
|
const projectData = projectsResponse.data.find(
|
|
@@ -5454,13 +6752,13 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5454
6752
|
throw new Error("Invalid project ref");
|
|
5455
6753
|
}
|
|
5456
6754
|
span.setAttributes({
|
|
5457
|
-
...
|
|
6755
|
+
...flattenAttributes4(projectData, "cli.project")
|
|
5458
6756
|
});
|
|
5459
6757
|
span.end();
|
|
5460
6758
|
return projectData;
|
|
5461
6759
|
} catch (e) {
|
|
5462
6760
|
if (!(e instanceof SkipCommandError)) {
|
|
5463
|
-
|
|
6761
|
+
recordSpanException6(span, e);
|
|
5464
6762
|
}
|
|
5465
6763
|
span.end();
|
|
5466
6764
|
throw e;
|
|
@@ -5471,12 +6769,14 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5471
6769
|
// src/commands/logout.ts
|
|
5472
6770
|
var LogoutCommandOptions = CommonCommandOptions;
|
|
5473
6771
|
function configureLogoutCommand(program2) {
|
|
5474
|
-
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
5475
|
-
|
|
5476
|
-
await
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
6772
|
+
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
6773
|
+
async (options) => {
|
|
6774
|
+
await handleTelemetry(async () => {
|
|
6775
|
+
await printInitialBanner(false);
|
|
6776
|
+
await logoutCommand(options);
|
|
6777
|
+
});
|
|
6778
|
+
}
|
|
6779
|
+
);
|
|
5480
6780
|
}
|
|
5481
6781
|
async function logoutCommand(options) {
|
|
5482
6782
|
return await wrapCommandAction("logoutCommand", LogoutCommandOptions, options, async (opts) => {
|
|
@@ -5486,11 +6786,46 @@ async function logoutCommand(options) {
|
|
|
5486
6786
|
async function logout(options) {
|
|
5487
6787
|
const config = readAuthConfigProfile(options.profile);
|
|
5488
6788
|
if (!config?.accessToken) {
|
|
5489
|
-
logger.info(`You are already logged out [${options.profile
|
|
6789
|
+
logger.info(`You are already logged out [${options.profile}]`);
|
|
6790
|
+
return;
|
|
6791
|
+
}
|
|
6792
|
+
deleteAuthConfigProfile(options.profile);
|
|
6793
|
+
logger.info(`Logged out of Trigger.dev [${options.profile}]`);
|
|
6794
|
+
}
|
|
6795
|
+
|
|
6796
|
+
// src/commands/list-profiles.ts
|
|
6797
|
+
import { log as log7, outro as outro7 } from "@clack/prompts";
|
|
6798
|
+
var ListProfilesOptions = CommonCommandOptions;
|
|
6799
|
+
function configureListProfilesCommand(program2) {
|
|
6800
|
+
return program2.command("list-profiles").description("List all of your CLI profiles").option(
|
|
6801
|
+
"-l, --log-level <level>",
|
|
6802
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
6803
|
+
"log"
|
|
6804
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (options) => {
|
|
6805
|
+
await handleTelemetry(async () => {
|
|
6806
|
+
await printInitialBanner(true);
|
|
6807
|
+
await listProfilesCommand(options);
|
|
6808
|
+
});
|
|
6809
|
+
});
|
|
6810
|
+
}
|
|
6811
|
+
async function listProfilesCommand(options) {
|
|
6812
|
+
return await wrapCommandAction("listProfiles", ListProfilesOptions, options, async (opts) => {
|
|
6813
|
+
return await listProfiles(opts);
|
|
6814
|
+
});
|
|
6815
|
+
}
|
|
6816
|
+
async function listProfiles(options) {
|
|
6817
|
+
const authConfig = readAuthConfigFile();
|
|
6818
|
+
if (!authConfig) {
|
|
6819
|
+
logger.info("No profiles found");
|
|
5490
6820
|
return;
|
|
5491
6821
|
}
|
|
5492
|
-
|
|
5493
|
-
|
|
6822
|
+
const profiles = Object.keys(authConfig);
|
|
6823
|
+
log7.message("Profiles:");
|
|
6824
|
+
for (const profile of profiles) {
|
|
6825
|
+
const profileConfig = authConfig[profile];
|
|
6826
|
+
log7.info(`${profile}${profileConfig?.apiUrl ? ` - ${chalkGrey(profileConfig.apiUrl)}` : ""}`);
|
|
6827
|
+
}
|
|
6828
|
+
outro7("Retrieve account info by running whoami --profile <profile>");
|
|
5494
6829
|
}
|
|
5495
6830
|
|
|
5496
6831
|
// src/cli/index.ts
|
|
@@ -5502,6 +6837,8 @@ configureDevCommand(program);
|
|
|
5502
6837
|
configureDeployCommand(program);
|
|
5503
6838
|
configureWhoamiCommand(program);
|
|
5504
6839
|
configureLogoutCommand(program);
|
|
6840
|
+
configureListProfilesCommand(program);
|
|
6841
|
+
configureUpdateCommand(program);
|
|
5505
6842
|
|
|
5506
6843
|
// src/index.ts
|
|
5507
6844
|
var main = async () => {
|