trigger.dev 3.0.0-beta.3 → 3.0.0-beta.31
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 +2027 -677
- 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.31";
|
|
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.31",
|
|
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,51 +1867,58 @@ 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) {
|
|
1787
1887
|
return version2.replace(/^workspace:/, "");
|
|
1788
1888
|
}
|
|
1789
1889
|
function parsePackageName(packageSpecifier) {
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1890
|
+
let name;
|
|
1891
|
+
let version2;
|
|
1892
|
+
if (packageSpecifier.startsWith("@")) {
|
|
1893
|
+
const atIndex = packageSpecifier.indexOf("@", 1);
|
|
1894
|
+
if (atIndex !== -1) {
|
|
1895
|
+
name = packageSpecifier.slice(0, atIndex);
|
|
1896
|
+
version2 = packageSpecifier.slice(atIndex + 1);
|
|
1897
|
+
} else {
|
|
1898
|
+
name = packageSpecifier;
|
|
1899
|
+
}
|
|
1900
|
+
} else {
|
|
1901
|
+
const [packageName, packageVersion] = packageSpecifier.split("@");
|
|
1902
|
+
if (typeof packageName === "string") {
|
|
1903
|
+
name = packageName;
|
|
1904
|
+
}
|
|
1905
|
+
version2 = packageVersion;
|
|
1793
1906
|
}
|
|
1794
|
-
if (
|
|
1795
|
-
return { name:
|
|
1907
|
+
if (!name) {
|
|
1908
|
+
return { name: packageSpecifier };
|
|
1796
1909
|
}
|
|
1797
|
-
return { name:
|
|
1910
|
+
return { name, version: version2 };
|
|
1798
1911
|
}
|
|
1799
|
-
async function setPackageJsonDeps(
|
|
1912
|
+
async function setPackageJsonDeps(path7, deps) {
|
|
1800
1913
|
try {
|
|
1801
|
-
const existingPackageJson = await readJSONFile(
|
|
1914
|
+
const existingPackageJson = await readJSONFile(path7);
|
|
1802
1915
|
const newPackageJson = {
|
|
1803
1916
|
...existingPackageJson,
|
|
1804
1917
|
dependencies: {
|
|
1805
1918
|
...deps
|
|
1806
1919
|
}
|
|
1807
1920
|
};
|
|
1808
|
-
await writeJSONFile(
|
|
1921
|
+
await writeJSONFile(path7, newPackageJson);
|
|
1809
1922
|
} catch (error) {
|
|
1810
1923
|
const defaultPackageJson = {
|
|
1811
1924
|
name: "temp",
|
|
@@ -1813,13 +1926,13 @@ async function setPackageJsonDeps(path6, deps) {
|
|
|
1813
1926
|
description: "",
|
|
1814
1927
|
dependencies: deps
|
|
1815
1928
|
};
|
|
1816
|
-
await writeJSONFile(
|
|
1929
|
+
await writeJSONFile(path7, defaultPackageJson);
|
|
1817
1930
|
}
|
|
1818
1931
|
}
|
|
1819
1932
|
|
|
1820
1933
|
// src/commands/login.ts
|
|
1821
|
-
import { intro as intro2, log, outro as
|
|
1822
|
-
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3";
|
|
1934
|
+
import { intro as intro2, log as log3, outro as outro3, select } from "@clack/prompts";
|
|
1935
|
+
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3/workers";
|
|
1823
1936
|
|
|
1824
1937
|
// ../../node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
|
|
1825
1938
|
import process6 from "node:process";
|
|
@@ -2189,14 +2302,14 @@ var baseOpen = async (options) => {
|
|
|
2189
2302
|
}
|
|
2190
2303
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
2191
2304
|
if (options.wait) {
|
|
2192
|
-
return new Promise((
|
|
2305
|
+
return new Promise((resolve5, reject) => {
|
|
2193
2306
|
subprocess.once("error", reject);
|
|
2194
2307
|
subprocess.once("close", (exitCode) => {
|
|
2195
2308
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
2196
2309
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
2197
2310
|
return;
|
|
2198
2311
|
}
|
|
2199
|
-
|
|
2312
|
+
resolve5(subprocess);
|
|
2200
2313
|
});
|
|
2201
2314
|
});
|
|
2202
2315
|
}
|
|
@@ -2313,7 +2426,7 @@ var decorateErrorWithCounts = (error, attemptNumber, options) => {
|
|
|
2313
2426
|
return error;
|
|
2314
2427
|
};
|
|
2315
2428
|
async function pRetry(input, options) {
|
|
2316
|
-
return new Promise((
|
|
2429
|
+
return new Promise((resolve5, reject) => {
|
|
2317
2430
|
options = {
|
|
2318
2431
|
onFailedAttempt() {
|
|
2319
2432
|
},
|
|
@@ -2336,7 +2449,7 @@ async function pRetry(input, options) {
|
|
|
2336
2449
|
try {
|
|
2337
2450
|
const result = await input(attemptNumber);
|
|
2338
2451
|
cleanUp();
|
|
2339
|
-
|
|
2452
|
+
resolve5(result);
|
|
2340
2453
|
} catch (error) {
|
|
2341
2454
|
try {
|
|
2342
2455
|
if (!(error instanceof Error)) {
|
|
@@ -2366,10 +2479,10 @@ async function pRetry(input, options) {
|
|
|
2366
2479
|
import { z as z3 } from "zod";
|
|
2367
2480
|
|
|
2368
2481
|
// src/commands/whoami.ts
|
|
2369
|
-
import { intro, note,
|
|
2482
|
+
import { intro, note, outro as outro2 } from "@clack/prompts";
|
|
2370
2483
|
|
|
2371
2484
|
// src/utilities/session.ts
|
|
2372
|
-
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3";
|
|
2485
|
+
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3/workers";
|
|
2373
2486
|
var tracer2 = getTracer();
|
|
2374
2487
|
async function isLoggedIn(profile = "default") {
|
|
2375
2488
|
return await tracer2.startActiveSpan("isLoggedIn", async (span) => {
|
|
@@ -2444,16 +2557,23 @@ async function whoAmI(options, embedded = false) {
|
|
|
2444
2557
|
if (!embedded) {
|
|
2445
2558
|
intro(`Displaying your account details [${options?.profile ?? "default"}]`);
|
|
2446
2559
|
}
|
|
2447
|
-
const loadingSpinner =
|
|
2560
|
+
const loadingSpinner = spinner();
|
|
2448
2561
|
loadingSpinner.start("Checking your account details");
|
|
2449
2562
|
const authentication = await isLoggedIn(options?.profile);
|
|
2450
2563
|
if (!authentication.ok) {
|
|
2451
2564
|
if (authentication.error === "fetch failed") {
|
|
2452
2565
|
loadingSpinner.stop("Fetch failed. Platform down?");
|
|
2453
2566
|
} else {
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2567
|
+
if (embedded) {
|
|
2568
|
+
loadingSpinner.stop(
|
|
2569
|
+
`Failed to check account details. You may want to run \`trigger.dev logout --profile ${options?.profile ?? "default"}\` and try again.`
|
|
2570
|
+
);
|
|
2571
|
+
} else {
|
|
2572
|
+
loadingSpinner.stop(
|
|
2573
|
+
`You must login first. Use \`trigger.dev login --profile ${options?.profile ?? "default"}\` to login.`
|
|
2574
|
+
);
|
|
2575
|
+
outro2("Whoami failed");
|
|
2576
|
+
}
|
|
2457
2577
|
}
|
|
2458
2578
|
return {
|
|
2459
2579
|
success: false,
|
|
@@ -2518,6 +2638,29 @@ async function login(options) {
|
|
|
2518
2638
|
if (!opts.embedded) {
|
|
2519
2639
|
intro2("Logging in to Trigger.dev");
|
|
2520
2640
|
}
|
|
2641
|
+
const accessTokenFromEnv = process.env.TRIGGER_ACCESS_TOKEN;
|
|
2642
|
+
if (accessTokenFromEnv) {
|
|
2643
|
+
const auth = {
|
|
2644
|
+
accessToken: accessTokenFromEnv,
|
|
2645
|
+
apiUrl: process.env.TRIGGER_API_URL ?? "https://api.trigger.dev"
|
|
2646
|
+
};
|
|
2647
|
+
const apiClient3 = new CliApiClient(auth.apiUrl, auth.accessToken);
|
|
2648
|
+
const userData = await apiClient3.whoAmI();
|
|
2649
|
+
if (!userData.success) {
|
|
2650
|
+
throw new Error(userData.error);
|
|
2651
|
+
}
|
|
2652
|
+
return {
|
|
2653
|
+
ok: true,
|
|
2654
|
+
profile: options?.profile ?? "default",
|
|
2655
|
+
userId: userData.data.userId,
|
|
2656
|
+
email: userData.data.email,
|
|
2657
|
+
dashboardUrl: userData.data.dashboardUrl,
|
|
2658
|
+
auth: {
|
|
2659
|
+
accessToken: auth.accessToken,
|
|
2660
|
+
apiUrl: auth.apiUrl
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2521
2664
|
const authConfig = readAuthConfigProfile(options?.profile);
|
|
2522
2665
|
if (authConfig && authConfig.accessToken) {
|
|
2523
2666
|
const whoAmIResult = await whoAmI(
|
|
@@ -2526,10 +2669,18 @@ async function login(options) {
|
|
|
2526
2669
|
skipTelemetry: !span.isRecording(),
|
|
2527
2670
|
logLevel: logger.loggerLevel
|
|
2528
2671
|
},
|
|
2529
|
-
|
|
2672
|
+
true
|
|
2530
2673
|
);
|
|
2531
2674
|
if (!whoAmIResult.success) {
|
|
2532
|
-
|
|
2675
|
+
prettyError("Unable to validate existing personal access token", whoAmIResult.error);
|
|
2676
|
+
if (!opts.embedded) {
|
|
2677
|
+
outro3(
|
|
2678
|
+
`Login failed using stored token. To fix, first logout using \`trigger.dev logout${options?.profile ? ` --profile ${options.profile}` : ""}\` and then try again.`
|
|
2679
|
+
);
|
|
2680
|
+
throw new SkipLoggingError(whoAmIResult.error);
|
|
2681
|
+
} else {
|
|
2682
|
+
throw new Error(whoAmIResult.error);
|
|
2683
|
+
}
|
|
2533
2684
|
} else {
|
|
2534
2685
|
if (!opts.embedded) {
|
|
2535
2686
|
const continueOption = await select({
|
|
@@ -2547,7 +2698,7 @@ async function login(options) {
|
|
|
2547
2698
|
initialValue: false
|
|
2548
2699
|
});
|
|
2549
2700
|
if (continueOption !== true) {
|
|
2550
|
-
|
|
2701
|
+
outro3("Already logged in");
|
|
2551
2702
|
span.setAttributes({
|
|
2552
2703
|
"cli.userId": whoAmIResult.data.userId,
|
|
2553
2704
|
"cli.email": whoAmIResult.data.email,
|
|
@@ -2588,16 +2739,16 @@ async function login(options) {
|
|
|
2588
2739
|
}
|
|
2589
2740
|
}
|
|
2590
2741
|
if (opts.embedded) {
|
|
2591
|
-
|
|
2742
|
+
log3.step("You must login to continue.");
|
|
2592
2743
|
}
|
|
2593
2744
|
const apiClient2 = new CliApiClient(authConfig?.apiUrl ?? opts.defaultApiUrl);
|
|
2594
2745
|
const authorizationCodeResult = await createAuthorizationCode(apiClient2);
|
|
2595
|
-
|
|
2746
|
+
log3.step(
|
|
2596
2747
|
`Please visit the following URL to login:
|
|
2597
2748
|
${chalkLink(authorizationCodeResult.url)}`
|
|
2598
2749
|
);
|
|
2599
2750
|
await open_default(authorizationCodeResult.url);
|
|
2600
|
-
const getPersonalAccessTokenSpinner =
|
|
2751
|
+
const getPersonalAccessTokenSpinner = spinner();
|
|
2601
2752
|
getPersonalAccessTokenSpinner.start("Waiting for you to login");
|
|
2602
2753
|
try {
|
|
2603
2754
|
const indexResult = await pRetry(
|
|
@@ -2626,9 +2777,9 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2626
2777
|
throw new Error(whoAmIResult.error);
|
|
2627
2778
|
}
|
|
2628
2779
|
if (opts.embedded) {
|
|
2629
|
-
|
|
2780
|
+
log3.step("Logged in successfully");
|
|
2630
2781
|
} else {
|
|
2631
|
-
|
|
2782
|
+
outro3("Logged in successfully");
|
|
2632
2783
|
}
|
|
2633
2784
|
span.end();
|
|
2634
2785
|
return {
|
|
@@ -2645,7 +2796,7 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2645
2796
|
} catch (e) {
|
|
2646
2797
|
getPersonalAccessTokenSpinner.stop(`Failed to get access token`);
|
|
2647
2798
|
if (e instanceof AbortError) {
|
|
2648
|
-
|
|
2799
|
+
log3.error(e.message);
|
|
2649
2800
|
}
|
|
2650
2801
|
recordSpanException3(span, e);
|
|
2651
2802
|
span.end();
|
|
@@ -2694,7 +2845,7 @@ async function getPersonalAccessToken(apiClient2, authorizationCode) {
|
|
|
2694
2845
|
async function createAuthorizationCode(apiClient2) {
|
|
2695
2846
|
return await tracer.startActiveSpan("createAuthorizationCode", async (span) => {
|
|
2696
2847
|
try {
|
|
2697
|
-
const createAuthCodeSpinner =
|
|
2848
|
+
const createAuthCodeSpinner = spinner();
|
|
2698
2849
|
createAuthCodeSpinner.start("Creating authorition code");
|
|
2699
2850
|
const authorizationCodeResult = await apiClient2.createAuthorizationCode();
|
|
2700
2851
|
if (!authorizationCodeResult.success) {
|
|
@@ -2718,10 +2869,69 @@ ${authorizationCodeResult.error}`
|
|
|
2718
2869
|
});
|
|
2719
2870
|
}
|
|
2720
2871
|
|
|
2872
|
+
// src/commands/deploy.ts
|
|
2873
|
+
import { esbuildDecorators as esbuildDecorators2 } from "@anatine/esbuild-decorators";
|
|
2874
|
+
import { Glob } from "glob";
|
|
2875
|
+
|
|
2721
2876
|
// src/utilities/build.ts
|
|
2722
2877
|
import { readFileSync } from "node:fs";
|
|
2723
2878
|
import { extname, isAbsolute } from "node:path";
|
|
2724
2879
|
import tsConfigPaths from "tsconfig-paths";
|
|
2880
|
+
function mockServerOnlyPlugin() {
|
|
2881
|
+
return {
|
|
2882
|
+
name: "trigger-mock-server-only",
|
|
2883
|
+
setup(build3) {
|
|
2884
|
+
build3.onResolve({ filter: /server-only/ }, (args) => {
|
|
2885
|
+
if (args.path !== "server-only") {
|
|
2886
|
+
return void 0;
|
|
2887
|
+
}
|
|
2888
|
+
logger.debug(`[trigger-mock-server-only] Bundling ${args.path}`, {
|
|
2889
|
+
...args
|
|
2890
|
+
});
|
|
2891
|
+
return {
|
|
2892
|
+
path: args.path,
|
|
2893
|
+
external: false,
|
|
2894
|
+
namespace: "server-only-mock"
|
|
2895
|
+
};
|
|
2896
|
+
});
|
|
2897
|
+
build3.onLoad({ filter: /server-only/, namespace: "server-only-mock" }, (args) => {
|
|
2898
|
+
return {
|
|
2899
|
+
contents: `export default true;`,
|
|
2900
|
+
loader: "js"
|
|
2901
|
+
};
|
|
2902
|
+
});
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
function bundleTriggerDevCore(buildIdentifier, tsconfigPath) {
|
|
2907
|
+
return {
|
|
2908
|
+
name: "trigger-bundle-core",
|
|
2909
|
+
setup(build3) {
|
|
2910
|
+
build3.onResolve({ filter: /.*/ }, (args) => {
|
|
2911
|
+
if (!args.path.startsWith("@trigger.dev/core/v3")) {
|
|
2912
|
+
return void 0;
|
|
2913
|
+
}
|
|
2914
|
+
const triggerSdkPath = __require.resolve("@trigger.dev/sdk/v3", { paths: [process.cwd()] });
|
|
2915
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Resolved @trigger.dev/sdk/v3`, {
|
|
2916
|
+
...args,
|
|
2917
|
+
triggerSdkPath
|
|
2918
|
+
});
|
|
2919
|
+
const resolvedPath = __require.resolve(args.path, {
|
|
2920
|
+
paths: [triggerSdkPath]
|
|
2921
|
+
});
|
|
2922
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Externalizing ${args.path}`, {
|
|
2923
|
+
...args,
|
|
2924
|
+
triggerSdkPath,
|
|
2925
|
+
resolvedPath
|
|
2926
|
+
});
|
|
2927
|
+
return {
|
|
2928
|
+
path: resolvedPath,
|
|
2929
|
+
external: false
|
|
2930
|
+
};
|
|
2931
|
+
});
|
|
2932
|
+
}
|
|
2933
|
+
};
|
|
2934
|
+
}
|
|
2725
2935
|
function workerSetupImportConfigPlugin(configPath) {
|
|
2726
2936
|
return {
|
|
2727
2937
|
name: "trigger-worker-setup",
|
|
@@ -2733,7 +2943,9 @@ function workerSetupImportConfigPlugin(configPath) {
|
|
|
2733
2943
|
let workerSetupContents = readFileSync(args.path, "utf-8");
|
|
2734
2944
|
workerSetupContents = workerSetupContents.replace(
|
|
2735
2945
|
"__SETUP_IMPORTED_PROJECT_CONFIG__",
|
|
2736
|
-
`import * as setupImportedConfigExports from "${
|
|
2946
|
+
`import * as setupImportedConfigExports from "${escapeImportPath(
|
|
2947
|
+
configPath
|
|
2948
|
+
)}"; const setupImportedConfig = setupImportedConfigExports.config;`
|
|
2737
2949
|
);
|
|
2738
2950
|
logger.debug("Loading worker setup", {
|
|
2739
2951
|
args,
|
|
@@ -2780,7 +2992,7 @@ function bundleDependenciesPlugin(buildIdentifier, dependenciesToBundle, tsconfi
|
|
|
2780
2992
|
return void 0;
|
|
2781
2993
|
}
|
|
2782
2994
|
}
|
|
2783
|
-
logger.
|
|
2995
|
+
logger.debug(`[${buildIdentifier}] Externalizing ${args.path}`, {
|
|
2784
2996
|
...args
|
|
2785
2997
|
});
|
|
2786
2998
|
return {
|
|
@@ -2868,12 +3080,728 @@ function getLoaderForFile(file) {
|
|
|
2868
3080
|
throw new Error(`Cannot get loader for file ${file}`);
|
|
2869
3081
|
}
|
|
2870
3082
|
|
|
3083
|
+
// src/utilities/deployErrors.ts
|
|
3084
|
+
import chalk4 from "chalk";
|
|
3085
|
+
import { relative as relative2 } from "node:path";
|
|
3086
|
+
import { groupTaskMetadataIssuesByTask } from "@trigger.dev/core/v3";
|
|
3087
|
+
import terminalLink from "terminal-link";
|
|
3088
|
+
|
|
3089
|
+
// src/utilities/links.ts
|
|
3090
|
+
var docs = {
|
|
3091
|
+
config: {
|
|
3092
|
+
home: "https://trigger.dev/docs/v3/trigger-config",
|
|
3093
|
+
esm: "https://trigger.dev/docs/v3/trigger-config#esm-only-packages",
|
|
3094
|
+
prisma: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators",
|
|
3095
|
+
additionalPackages: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators"
|
|
3096
|
+
}
|
|
3097
|
+
};
|
|
3098
|
+
var getInTouch = "https://trigger.dev/contact";
|
|
3099
|
+
|
|
3100
|
+
// src/utilities/deployErrors.ts
|
|
3101
|
+
function errorIsErrorLike(error) {
|
|
3102
|
+
return error instanceof Error || typeof error === "object" && error !== null && "message" in error;
|
|
3103
|
+
}
|
|
3104
|
+
function parseBuildErrorStack(error) {
|
|
3105
|
+
if (typeof error === "string") {
|
|
3106
|
+
return error;
|
|
3107
|
+
}
|
|
3108
|
+
if (errorIsErrorLike(error)) {
|
|
3109
|
+
if (typeof error.stack === "string") {
|
|
3110
|
+
const isErrRequireEsm = error.stack.includes("ERR_REQUIRE_ESM");
|
|
3111
|
+
let moduleName = null;
|
|
3112
|
+
if (isErrRequireEsm) {
|
|
3113
|
+
const moduleRegex = /node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)\/[^\/]+\s/;
|
|
3114
|
+
const match = moduleRegex.exec(error.stack);
|
|
3115
|
+
if (match) {
|
|
3116
|
+
moduleName = match[1];
|
|
3117
|
+
return {
|
|
3118
|
+
type: "esm-require-error",
|
|
3119
|
+
moduleName
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
} else {
|
|
3124
|
+
return error.message;
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
function logESMRequireError(parsedError, resolvedConfig) {
|
|
3129
|
+
logger.log(
|
|
3130
|
+
`
|
|
3131
|
+
${chalkError("X Error:")} The ${chalkPurple(
|
|
3132
|
+
parsedError.moduleName
|
|
3133
|
+
)} module is being required even though it's ESM only, and builds only support CommonJS. There are two ${chalk4.underline(
|
|
3134
|
+
"possible"
|
|
3135
|
+
)} ways to fix this:`
|
|
3136
|
+
);
|
|
3137
|
+
logger.log(
|
|
3138
|
+
`
|
|
3139
|
+
${chalkGrey("\u25CB")} Dynamically import the module in your code: ${chalkGrey(
|
|
3140
|
+
`const myModule = await import("${parsedError.moduleName}");`
|
|
3141
|
+
)}`
|
|
3142
|
+
);
|
|
3143
|
+
if (resolvedConfig.status === "file") {
|
|
3144
|
+
const relativePath = relative2(resolvedConfig.config.projectDir, resolvedConfig.path).replace(
|
|
3145
|
+
/\\/g,
|
|
3146
|
+
"/"
|
|
3147
|
+
);
|
|
3148
|
+
logger.log(
|
|
3149
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3150
|
+
parsedError.moduleName
|
|
3151
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3152
|
+
`(${relativePath})`
|
|
3153
|
+
)}. This will bundle the module with your code.
|
|
3154
|
+
`
|
|
3155
|
+
);
|
|
3156
|
+
} else {
|
|
3157
|
+
logger.log(
|
|
3158
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3159
|
+
parsedError.moduleName
|
|
3160
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3161
|
+
"(you'll need to create one)"
|
|
3162
|
+
)}. This will bundle the module with your code.
|
|
3163
|
+
`
|
|
3164
|
+
);
|
|
3165
|
+
}
|
|
3166
|
+
logger.log(
|
|
3167
|
+
`${chalkGrey("\u25CB")} For more info see the ${terminalLink("relevant docs", docs.config.esm)}.
|
|
3168
|
+
`
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
function parseNpmInstallError(error) {
|
|
3172
|
+
if (typeof error === "string") {
|
|
3173
|
+
return error;
|
|
3174
|
+
}
|
|
3175
|
+
if (error instanceof Error) {
|
|
3176
|
+
if (typeof error.stack === "string") {
|
|
3177
|
+
const isPackageNotFoundError = error.stack.includes("ERR! 404 Not Found") && error.stack.includes("is not in this registry");
|
|
3178
|
+
let packageName = null;
|
|
3179
|
+
if (isPackageNotFoundError) {
|
|
3180
|
+
const packageNameRegex = /'([^']+)' is not in this registry/;
|
|
3181
|
+
const match = packageNameRegex.exec(error.stack);
|
|
3182
|
+
if (match) {
|
|
3183
|
+
packageName = match[1];
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
if (packageName) {
|
|
3187
|
+
return {
|
|
3188
|
+
type: "package-not-found-error",
|
|
3189
|
+
packageName
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
const noMatchingVersionRegex = /No matching version found for ([^\s]+)\s/;
|
|
3193
|
+
const noMatchingVersionMatch = noMatchingVersionRegex.exec(error.stack);
|
|
3194
|
+
if (noMatchingVersionMatch) {
|
|
3195
|
+
return {
|
|
3196
|
+
type: "no-matching-version-error",
|
|
3197
|
+
packageName: noMatchingVersionMatch[1].replace(/.$/, "")
|
|
3198
|
+
};
|
|
3199
|
+
}
|
|
3200
|
+
return error.message;
|
|
3201
|
+
} else {
|
|
3202
|
+
return error.message;
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
return "Unknown error";
|
|
3206
|
+
}
|
|
3207
|
+
function logTaskMetadataParseError(zodIssues, tasks) {
|
|
3208
|
+
logger.log(
|
|
3209
|
+
`
|
|
3210
|
+
${chalkError("X Error:")} Failed to start. The following ${zodIssues.length === 1 ? "task issue was" : "task issues were"} found:`
|
|
3211
|
+
);
|
|
3212
|
+
const groupedIssues = groupTaskMetadataIssuesByTask(tasks, zodIssues);
|
|
3213
|
+
for (const key in groupedIssues) {
|
|
3214
|
+
const taskWithIssues = groupedIssues[key];
|
|
3215
|
+
if (!taskWithIssues) {
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3218
|
+
logger.log(
|
|
3219
|
+
`
|
|
3220
|
+
${chalkWarning("\u276F")} ${taskWithIssues.exportName} ${chalkGrey("in")} ${taskWithIssues.filePath}`
|
|
3221
|
+
);
|
|
3222
|
+
for (const issue of taskWithIssues.issues) {
|
|
3223
|
+
if (issue.path) {
|
|
3224
|
+
logger.log(` ${chalkError("x")} ${issue.path} ${chalkGrey(issue.message)}`);
|
|
3225
|
+
} else {
|
|
3226
|
+
logger.log(` ${chalkError("x")} ${chalkGrey(issue.message)}`);
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
// src/utilities/javascriptProject.ts
|
|
3233
|
+
import { $ } from "execa";
|
|
3234
|
+
import { join as join4 } from "node:path";
|
|
3235
|
+
|
|
3236
|
+
// src/utilities/getUserPackageManager.ts
|
|
3237
|
+
import { findUp as findUp2 } from "find-up";
|
|
3238
|
+
import { basename } from "path";
|
|
3239
|
+
async function getUserPackageManager(path7) {
|
|
3240
|
+
const packageManager = await detectPackageManager(path7);
|
|
3241
|
+
logger.debug("Detected package manager", { packageManager });
|
|
3242
|
+
return packageManager;
|
|
3243
|
+
}
|
|
3244
|
+
async function detectPackageManager(path7) {
|
|
3245
|
+
try {
|
|
3246
|
+
return await detectPackageManagerFromArtifacts(path7);
|
|
3247
|
+
} catch (error) {
|
|
3248
|
+
return detectPackageManagerFromCurrentCommand();
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
function detectPackageManagerFromCurrentCommand() {
|
|
3252
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
3253
|
+
if (userAgent) {
|
|
3254
|
+
if (userAgent.startsWith("yarn")) {
|
|
3255
|
+
return "yarn";
|
|
3256
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
3257
|
+
return "pnpm";
|
|
3258
|
+
} else {
|
|
3259
|
+
return "npm";
|
|
3260
|
+
}
|
|
3261
|
+
} else {
|
|
3262
|
+
return "npm";
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
async function detectPackageManagerFromArtifacts(path7) {
|
|
3266
|
+
const artifacts = {
|
|
3267
|
+
yarn: "yarn.lock",
|
|
3268
|
+
pnpm: "pnpm-lock.yaml",
|
|
3269
|
+
npm: "package-lock.json",
|
|
3270
|
+
npmShrinkwrap: "npm-shrinkwrap.json"
|
|
3271
|
+
};
|
|
3272
|
+
const foundPath = await findUp2(Object.values(artifacts), { cwd: path7 });
|
|
3273
|
+
if (!foundPath) {
|
|
3274
|
+
throw new Error("Could not detect package manager from artifacts");
|
|
3275
|
+
}
|
|
3276
|
+
logger.debug("Found path from package manager artifacts", { foundPath });
|
|
3277
|
+
switch (basename(foundPath)) {
|
|
3278
|
+
case artifacts.yarn:
|
|
3279
|
+
return "yarn";
|
|
3280
|
+
case artifacts.pnpm:
|
|
3281
|
+
return "pnpm";
|
|
3282
|
+
case artifacts.npm:
|
|
3283
|
+
case artifacts.npmShrinkwrap:
|
|
3284
|
+
return "npm";
|
|
3285
|
+
default:
|
|
3286
|
+
throw new Error(`Unhandled package manager detection path: ${foundPath}`);
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
// src/utilities/assertExhaustive.ts
|
|
3291
|
+
function assertExhaustive(x) {
|
|
3292
|
+
throw new Error("Unexpected object: " + x);
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
// src/utilities/javascriptProject.ts
|
|
3296
|
+
import { builtinModules } from "node:module";
|
|
3297
|
+
import { recordSpanException as recordSpanException4 } from "@trigger.dev/core/v3/otel";
|
|
3298
|
+
import { flattenAttributes as flattenAttributes2 } from "@trigger.dev/core/v3";
|
|
3299
|
+
var JavascriptProject = class {
|
|
3300
|
+
constructor(projectPath) {
|
|
3301
|
+
this.projectPath = projectPath;
|
|
3302
|
+
}
|
|
3303
|
+
_packageJson;
|
|
3304
|
+
_packageManager;
|
|
3305
|
+
get packageJson() {
|
|
3306
|
+
if (!this._packageJson) {
|
|
3307
|
+
this._packageJson = readJSONFileSync(join4(this.projectPath, "package.json"));
|
|
3308
|
+
}
|
|
3309
|
+
return this._packageJson;
|
|
3310
|
+
}
|
|
3311
|
+
get scripts() {
|
|
3312
|
+
return {
|
|
3313
|
+
postinstall: this.packageJson.scripts?.postinstall ?? ""
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
async install() {
|
|
3317
|
+
const command = await this.#getCommand();
|
|
3318
|
+
try {
|
|
3319
|
+
await command.installDependencies({
|
|
3320
|
+
cwd: this.projectPath
|
|
3321
|
+
});
|
|
3322
|
+
} catch (error) {
|
|
3323
|
+
logger.debug(`Failed to install dependencies using ${command.name}`, {
|
|
3324
|
+
error
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
async resolveAll(packageNames, options) {
|
|
3329
|
+
return tracer.startActiveSpan("JavascriptProject.resolveAll", async (span) => {
|
|
3330
|
+
const externalPackages = packageNames.filter((packageName) => !isBuiltInModule(packageName));
|
|
3331
|
+
const opts = { allowDev: false, ...options };
|
|
3332
|
+
const command = await this.#getCommand();
|
|
3333
|
+
span.setAttributes({
|
|
3334
|
+
externalPackages,
|
|
3335
|
+
packageManager: command.name
|
|
3336
|
+
});
|
|
3337
|
+
try {
|
|
3338
|
+
const versions = await command.resolveDependencyVersions(externalPackages, {
|
|
3339
|
+
cwd: this.projectPath
|
|
3340
|
+
});
|
|
3341
|
+
if (versions) {
|
|
3342
|
+
logger.debug(`Resolved [${externalPackages.join(", ")}] version using ${command.name}`, {
|
|
3343
|
+
versions
|
|
3344
|
+
});
|
|
3345
|
+
span.setAttributes({
|
|
3346
|
+
...flattenAttributes2(versions, "versions")
|
|
3347
|
+
});
|
|
3348
|
+
}
|
|
3349
|
+
const missingPackages = externalPackages.filter((packageName) => !versions[packageName]);
|
|
3350
|
+
const missingPackageVersions = {};
|
|
3351
|
+
for (const packageName of missingPackages) {
|
|
3352
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3353
|
+
if (typeof packageJsonVersion === "string") {
|
|
3354
|
+
logger.debug(`Resolved ${packageName} version using package.json`, {
|
|
3355
|
+
packageJsonVersion
|
|
3356
|
+
});
|
|
3357
|
+
missingPackageVersions[packageName] = packageJsonVersion;
|
|
3358
|
+
}
|
|
3359
|
+
if (opts.allowDev) {
|
|
3360
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3361
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3362
|
+
logger.debug(`Resolved ${packageName} version using devDependencies`, {
|
|
3363
|
+
devPackageJsonVersion
|
|
3364
|
+
});
|
|
3365
|
+
missingPackageVersions[packageName] = devPackageJsonVersion;
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
span.setAttributes({
|
|
3370
|
+
...flattenAttributes2(missingPackageVersions, "missingPackageVersions"),
|
|
3371
|
+
missingPackages
|
|
3372
|
+
});
|
|
3373
|
+
span.end();
|
|
3374
|
+
return { ...versions, ...missingPackageVersions };
|
|
3375
|
+
} catch (error) {
|
|
3376
|
+
recordSpanException4(span, error);
|
|
3377
|
+
span.end();
|
|
3378
|
+
logger.debug(`Failed to resolve dependency versions using ${command.name}`, {
|
|
3379
|
+
packageNames,
|
|
3380
|
+
error
|
|
3381
|
+
});
|
|
3382
|
+
return {};
|
|
3383
|
+
}
|
|
3384
|
+
});
|
|
3385
|
+
}
|
|
3386
|
+
async resolve(packageName, options) {
|
|
3387
|
+
if (isBuiltInModule(packageName)) {
|
|
3388
|
+
return void 0;
|
|
3389
|
+
}
|
|
3390
|
+
const opts = { allowDev: false, ...options };
|
|
3391
|
+
const command = await this.#getCommand();
|
|
3392
|
+
try {
|
|
3393
|
+
const version2 = await command.resolveDependencyVersion(packageName, {
|
|
3394
|
+
cwd: this.projectPath
|
|
3395
|
+
});
|
|
3396
|
+
if (version2) {
|
|
3397
|
+
logger.debug(`Resolved ${packageName} version using ${command.name}`, { version: version2 });
|
|
3398
|
+
return version2;
|
|
3399
|
+
}
|
|
3400
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3401
|
+
if (typeof packageJsonVersion === "string") {
|
|
3402
|
+
logger.debug(`Resolved ${packageName} version using package.json`, { packageJsonVersion });
|
|
3403
|
+
return packageJsonVersion;
|
|
3404
|
+
}
|
|
3405
|
+
if (opts.allowDev) {
|
|
3406
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3407
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3408
|
+
logger.debug(`Resolved ${packageName} version using devDependencies`, {
|
|
3409
|
+
devPackageJsonVersion
|
|
3410
|
+
});
|
|
3411
|
+
return devPackageJsonVersion;
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
} catch (error) {
|
|
3415
|
+
logger.debug(`Failed to resolve dependency version using ${command.name}`, {
|
|
3416
|
+
packageName,
|
|
3417
|
+
error
|
|
3418
|
+
});
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
async #getCommand() {
|
|
3422
|
+
const packageManager = await this.getPackageManager();
|
|
3423
|
+
switch (packageManager) {
|
|
3424
|
+
case "npm":
|
|
3425
|
+
return new NPMCommands();
|
|
3426
|
+
case "pnpm":
|
|
3427
|
+
return new PNPMCommands();
|
|
3428
|
+
case "yarn":
|
|
3429
|
+
return new YarnCommands();
|
|
3430
|
+
default:
|
|
3431
|
+
assertExhaustive(packageManager);
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
async getPackageManager() {
|
|
3435
|
+
if (!this._packageManager) {
|
|
3436
|
+
this._packageManager = await getUserPackageManager(this.projectPath);
|
|
3437
|
+
}
|
|
3438
|
+
return this._packageManager;
|
|
3439
|
+
}
|
|
3440
|
+
};
|
|
3441
|
+
var PNPMCommands = class {
|
|
3442
|
+
get name() {
|
|
3443
|
+
return "pnpm";
|
|
3444
|
+
}
|
|
3445
|
+
get cmd() {
|
|
3446
|
+
return process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
3447
|
+
}
|
|
3448
|
+
async installDependencies(options) {
|
|
3449
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3450
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3451
|
+
}
|
|
3452
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3453
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} -r --json`;
|
|
3454
|
+
const result = JSON.parse(stdout);
|
|
3455
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`);
|
|
3456
|
+
for (const dep of result) {
|
|
3457
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3458
|
+
if (dependency) {
|
|
3459
|
+
return dependency.version;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3464
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageNames} -r --json`;
|
|
3465
|
+
const result = JSON.parse(stdout);
|
|
3466
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`);
|
|
3467
|
+
const results = {};
|
|
3468
|
+
for (const dep of result) {
|
|
3469
|
+
for (const packageName of packageNames) {
|
|
3470
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3471
|
+
if (dependency) {
|
|
3472
|
+
results[packageName] = dependency.version;
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
return results;
|
|
3477
|
+
}
|
|
3478
|
+
};
|
|
3479
|
+
var NPMCommands = class {
|
|
3480
|
+
get name() {
|
|
3481
|
+
return "npm";
|
|
3482
|
+
}
|
|
3483
|
+
get cmd() {
|
|
3484
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
3485
|
+
}
|
|
3486
|
+
async installDependencies(options) {
|
|
3487
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3488
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3489
|
+
}
|
|
3490
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3491
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} --json`;
|
|
3492
|
+
const output = JSON.parse(stdout);
|
|
3493
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`, { output });
|
|
3494
|
+
return this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3495
|
+
}
|
|
3496
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3497
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageNames} --json`;
|
|
3498
|
+
const output = JSON.parse(stdout);
|
|
3499
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`, { output });
|
|
3500
|
+
const results = {};
|
|
3501
|
+
for (const packageName of packageNames) {
|
|
3502
|
+
const version2 = this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3503
|
+
if (version2) {
|
|
3504
|
+
results[packageName] = version2;
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
return results;
|
|
3508
|
+
}
|
|
3509
|
+
#recursivelySearchDependencies(dependencies2, packageName) {
|
|
3510
|
+
for (const [name, dependency] of Object.entries(dependencies2)) {
|
|
3511
|
+
if (name === packageName) {
|
|
3512
|
+
return dependency.version;
|
|
3513
|
+
}
|
|
3514
|
+
if (dependency.dependencies) {
|
|
3515
|
+
const result = this.#recursivelySearchDependencies(dependency.dependencies, packageName);
|
|
3516
|
+
if (result) {
|
|
3517
|
+
return result;
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
};
|
|
3523
|
+
var YarnCommands = class {
|
|
3524
|
+
get name() {
|
|
3525
|
+
return "yarn";
|
|
3526
|
+
}
|
|
3527
|
+
get cmd() {
|
|
3528
|
+
return process.platform === "win32" ? "yarn.cmd" : "yarn";
|
|
3529
|
+
}
|
|
3530
|
+
async installDependencies(options) {
|
|
3531
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3532
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3533
|
+
}
|
|
3534
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3535
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} info ${packageName} --json`;
|
|
3536
|
+
const lines = stdout.split("\n");
|
|
3537
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`);
|
|
3538
|
+
for (const line of lines) {
|
|
3539
|
+
const json = JSON.parse(line);
|
|
3540
|
+
if (json.value === packageName) {
|
|
3541
|
+
return json.children.Version;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
async resolveDependencyVersions(packageNames, options) {
|
|
3546
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} info ${packageNames} --json`;
|
|
3547
|
+
const lines = stdout.split("\n");
|
|
3548
|
+
logger.debug(`Resolving ${packageNames.join(" ")} version using ${this.name}`);
|
|
3549
|
+
const results = {};
|
|
3550
|
+
for (const line of lines) {
|
|
3551
|
+
const json = JSON.parse(line);
|
|
3552
|
+
const packageName = this.#parseYarnValueIntoPackageName(json.value);
|
|
3553
|
+
if (packageNames.includes(packageName)) {
|
|
3554
|
+
results[packageName] = json.children.Version;
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
return results;
|
|
3558
|
+
}
|
|
3559
|
+
// The "value" when doing yarn info is formatted like this:
|
|
3560
|
+
// "package-name@npm:version" or "package-name@workspace:version"
|
|
3561
|
+
// This function will parse the value into just the package name.
|
|
3562
|
+
// This correctly handles scoped packages as well e.g. @scope/package-name@npm:version
|
|
3563
|
+
#parseYarnValueIntoPackageName(value) {
|
|
3564
|
+
const parts = value.split("@");
|
|
3565
|
+
if (parts.length === 3) {
|
|
3566
|
+
return parts[1];
|
|
3567
|
+
}
|
|
3568
|
+
return parts[0];
|
|
3569
|
+
}
|
|
3570
|
+
};
|
|
3571
|
+
function isBuiltInModule(module) {
|
|
3572
|
+
if (module.startsWith("node:")) {
|
|
3573
|
+
return true;
|
|
3574
|
+
}
|
|
3575
|
+
return builtinModules.includes(module);
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
// src/utilities/resolveInternalFilePath.ts
|
|
3579
|
+
import path5 from "path";
|
|
3580
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3581
|
+
function cliRootPath() {
|
|
3582
|
+
const __filename2 = fileURLToPath3(import.meta.url);
|
|
3583
|
+
const __dirname2 = path5.dirname(__filename2);
|
|
3584
|
+
return __dirname2;
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
// src/utilities/safeJsonParse.ts
|
|
3588
|
+
function safeJsonParse(json) {
|
|
3589
|
+
if (!json) {
|
|
3590
|
+
return void 0;
|
|
3591
|
+
}
|
|
3592
|
+
try {
|
|
3593
|
+
return JSON.parse(json);
|
|
3594
|
+
} catch {
|
|
3595
|
+
return void 0;
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
// src/commands/update.ts
|
|
3600
|
+
import { confirm, intro as intro3, isCancel, log as log4, outro as outro4 } from "@clack/prompts";
|
|
3601
|
+
import { join as join5, resolve as resolve2 } from "path";
|
|
3602
|
+
var UpdateCommandOptions = CommonCommandOptions.pick({
|
|
3603
|
+
logLevel: true,
|
|
3604
|
+
skipTelemetry: true
|
|
3605
|
+
});
|
|
3606
|
+
function configureUpdateCommand(program2) {
|
|
3607
|
+
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(
|
|
3608
|
+
"-l, --log-level <level>",
|
|
3609
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
3610
|
+
"log"
|
|
3611
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (path7, options) => {
|
|
3612
|
+
wrapCommandAction("dev", UpdateCommandOptions, options, async (opts) => {
|
|
3613
|
+
await printStandloneInitialBanner(true);
|
|
3614
|
+
await updateCommand(path7, opts);
|
|
3615
|
+
});
|
|
3616
|
+
});
|
|
3617
|
+
}
|
|
3618
|
+
var triggerPackageFilter = /^@trigger\.dev/;
|
|
3619
|
+
async function updateCommand(dir, options) {
|
|
3620
|
+
await updateTriggerPackages(dir, options);
|
|
3621
|
+
}
|
|
3622
|
+
async function updateTriggerPackages(dir, options, embedded, requireUpdate) {
|
|
3623
|
+
let hasOutput = false;
|
|
3624
|
+
if (!embedded) {
|
|
3625
|
+
intro3("Updating packages");
|
|
3626
|
+
}
|
|
3627
|
+
const projectPath = resolve2(process.cwd(), dir);
|
|
3628
|
+
const { packageJson, readonlyPackageJson, packageJsonPath } = await getPackageJson(projectPath);
|
|
3629
|
+
if (!packageJson) {
|
|
3630
|
+
log4.error("Failed to load package.json. Try to re-run with `-l debug` to see what's going on.");
|
|
3631
|
+
return false;
|
|
3632
|
+
}
|
|
3633
|
+
const cliVersion = getVersion();
|
|
3634
|
+
const newCliVersion = await updateCheck();
|
|
3635
|
+
if (newCliVersion) {
|
|
3636
|
+
prettyWarning(
|
|
3637
|
+
"You're not running the latest CLI version, please consider updating ASAP",
|
|
3638
|
+
`Current: ${cliVersion}
|
|
3639
|
+
Latest: ${newCliVersion}`,
|
|
3640
|
+
"Run latest: npx trigger.dev@beta"
|
|
3641
|
+
);
|
|
3642
|
+
hasOutput = true;
|
|
3643
|
+
}
|
|
3644
|
+
const triggerDependencies = getTriggerDependencies(packageJson);
|
|
3645
|
+
function getVersionMismatches(deps, targetVersion) {
|
|
3646
|
+
const mismatches = [];
|
|
3647
|
+
for (const dep of deps) {
|
|
3648
|
+
if (dep.version === targetVersion) {
|
|
3649
|
+
continue;
|
|
3650
|
+
}
|
|
3651
|
+
mismatches.push(dep);
|
|
3652
|
+
}
|
|
3653
|
+
return mismatches;
|
|
3654
|
+
}
|
|
3655
|
+
const versionMismatches = getVersionMismatches(triggerDependencies, cliVersion);
|
|
3656
|
+
if (versionMismatches.length === 0) {
|
|
3657
|
+
if (!embedded) {
|
|
3658
|
+
outro4(`Nothing to do${newCliVersion ? " ..but you should really update your CLI!" : ""}`);
|
|
3659
|
+
return hasOutput;
|
|
3660
|
+
}
|
|
3661
|
+
return hasOutput;
|
|
3662
|
+
}
|
|
3663
|
+
prettyWarning(
|
|
3664
|
+
"Mismatch between your CLI version and installed packages",
|
|
3665
|
+
"We recommend pinned versions for guaranteed compatibility"
|
|
3666
|
+
);
|
|
3667
|
+
if (!process.stdout.isTTY) {
|
|
3668
|
+
outro4("Deploy failed");
|
|
3669
|
+
console.log(
|
|
3670
|
+
`ERROR: Version mismatch detected while running in CI. This won't end well. Aborting.
|
|
3671
|
+
|
|
3672
|
+
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.
|
|
3673
|
+
|
|
3674
|
+
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\`
|
|
3675
|
+
|
|
3676
|
+
CLI version: ${cliVersion}
|
|
3677
|
+
|
|
3678
|
+
Current package versions that don't match the CLI:
|
|
3679
|
+
${versionMismatches.map((dep) => `- ${dep.name}@${dep.version}`).join("\n")}
|
|
3680
|
+
`
|
|
3681
|
+
);
|
|
3682
|
+
process.exit(1);
|
|
3683
|
+
}
|
|
3684
|
+
log4.message("");
|
|
3685
|
+
const userWantsToUpdate = await updateConfirmation(versionMismatches, cliVersion);
|
|
3686
|
+
if (isCancel(userWantsToUpdate)) {
|
|
3687
|
+
throw new OutroCommandError();
|
|
3688
|
+
}
|
|
3689
|
+
if (!userWantsToUpdate) {
|
|
3690
|
+
if (requireUpdate) {
|
|
3691
|
+
outro4("You shall not pass!");
|
|
3692
|
+
logger.log(
|
|
3693
|
+
`${chalkError(
|
|
3694
|
+
"X Error:"
|
|
3695
|
+
)} Update required: Version mismatches are a common source of bugs and errors. Please update or use \`--skip-update-check\` at your own risk.
|
|
3696
|
+
`
|
|
3697
|
+
);
|
|
3698
|
+
process.exit(1);
|
|
3699
|
+
}
|
|
3700
|
+
if (!embedded) {
|
|
3701
|
+
outro4("You've been warned!");
|
|
3702
|
+
}
|
|
3703
|
+
return hasOutput;
|
|
3704
|
+
}
|
|
3705
|
+
const installSpinner = spinner();
|
|
3706
|
+
installSpinner.start("Writing new package.json file");
|
|
3707
|
+
const packageJsonBackupPath = `${packageJsonPath}.bak`;
|
|
3708
|
+
await writeJSONFile(packageJsonBackupPath, readonlyPackageJson, true);
|
|
3709
|
+
const exitHandler = async (sig) => {
|
|
3710
|
+
log4.warn(
|
|
3711
|
+
`You may have to manually roll back any package.json changes. Backup written to ${packageJsonBackupPath}`
|
|
3712
|
+
);
|
|
3713
|
+
};
|
|
3714
|
+
process.prependOnceListener("exit", exitHandler);
|
|
3715
|
+
mutatePackageJsonWithUpdatedPackages(packageJson, versionMismatches, cliVersion);
|
|
3716
|
+
await writeJSONFile(packageJsonPath, packageJson, true);
|
|
3717
|
+
async function revertPackageJsonChanges() {
|
|
3718
|
+
await writeJSONFile(packageJsonPath, readonlyPackageJson, true);
|
|
3719
|
+
await removeFile(packageJsonBackupPath);
|
|
3720
|
+
}
|
|
3721
|
+
installSpinner.message("Installing new package versions");
|
|
3722
|
+
const jsProject = new JavascriptProject(projectPath);
|
|
3723
|
+
let packageManager;
|
|
3724
|
+
try {
|
|
3725
|
+
packageManager = await jsProject.getPackageManager();
|
|
3726
|
+
installSpinner.message(`Installing new package versions with ${packageManager}`);
|
|
3727
|
+
await jsProject.install();
|
|
3728
|
+
} catch (error) {
|
|
3729
|
+
installSpinner.stop(
|
|
3730
|
+
`Failed to install new package versions${packageManager ? ` with ${packageManager}` : ""}`
|
|
3731
|
+
);
|
|
3732
|
+
process.removeListener("exit", exitHandler);
|
|
3733
|
+
await revertPackageJsonChanges();
|
|
3734
|
+
throw error;
|
|
3735
|
+
}
|
|
3736
|
+
installSpinner.stop("Installed new package versions");
|
|
3737
|
+
process.removeListener("exit", exitHandler);
|
|
3738
|
+
await removeFile(packageJsonBackupPath);
|
|
3739
|
+
if (!embedded) {
|
|
3740
|
+
outro4(
|
|
3741
|
+
`Packages updated${newCliVersion ? " ..but you should really update your CLI too!" : ""}`
|
|
3742
|
+
);
|
|
3743
|
+
}
|
|
3744
|
+
return hasOutput;
|
|
3745
|
+
}
|
|
3746
|
+
function getTriggerDependencies(packageJson) {
|
|
3747
|
+
const deps = [];
|
|
3748
|
+
for (const type of ["dependencies", "devDependencies"]) {
|
|
3749
|
+
for (const [name, version2] of Object.entries(packageJson[type] ?? {})) {
|
|
3750
|
+
if (!version2) {
|
|
3751
|
+
continue;
|
|
3752
|
+
}
|
|
3753
|
+
if (version2.startsWith("workspace")) {
|
|
3754
|
+
continue;
|
|
3755
|
+
}
|
|
3756
|
+
if (!triggerPackageFilter.test(name)) {
|
|
3757
|
+
continue;
|
|
3758
|
+
}
|
|
3759
|
+
const ignoredPackages = ["@trigger.dev/companyicons"];
|
|
3760
|
+
if (ignoredPackages.includes(name)) {
|
|
3761
|
+
continue;
|
|
3762
|
+
}
|
|
3763
|
+
deps.push({ type, name, version: version2 });
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
return deps;
|
|
3767
|
+
}
|
|
3768
|
+
function mutatePackageJsonWithUpdatedPackages(packageJson, depsToUpdate, targetVersion) {
|
|
3769
|
+
for (const { type, name, version: version2 } of depsToUpdate) {
|
|
3770
|
+
if (!packageJson[type]) {
|
|
3771
|
+
throw new Error(
|
|
3772
|
+
`No ${type} entry found in package.json. Please try to upgrade manually instead.`
|
|
3773
|
+
);
|
|
3774
|
+
}
|
|
3775
|
+
packageJson[type][name] = targetVersion;
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
function printUpdateTable(depsToUpdate, targetVersion) {
|
|
3779
|
+
log4.message("Suggested updates");
|
|
3780
|
+
const tableData = depsToUpdate.map((dep) => ({
|
|
3781
|
+
package: dep.name,
|
|
3782
|
+
old: dep.version,
|
|
3783
|
+
new: targetVersion
|
|
3784
|
+
}));
|
|
3785
|
+
logger.table(tableData);
|
|
3786
|
+
}
|
|
3787
|
+
async function updateConfirmation(depsToUpdate, targetVersion) {
|
|
3788
|
+
printUpdateTable(depsToUpdate, targetVersion);
|
|
3789
|
+
let confirmMessage = "Would you like to apply those updates?";
|
|
3790
|
+
return await confirm({
|
|
3791
|
+
message: confirmMessage
|
|
3792
|
+
});
|
|
3793
|
+
}
|
|
3794
|
+
async function getPackageJson(absoluteProjectPath) {
|
|
3795
|
+
const packageJsonPath = join5(absoluteProjectPath, "package.json");
|
|
3796
|
+
const readonlyPackageJson = Object.freeze(await readJSONFile(packageJsonPath));
|
|
3797
|
+
const packageJson = structuredClone(readonlyPackageJson);
|
|
3798
|
+
return { packageJson, readonlyPackageJson, packageJsonPath };
|
|
3799
|
+
}
|
|
3800
|
+
|
|
2871
3801
|
// src/commands/deploy.ts
|
|
2872
|
-
import { Glob } from "glob";
|
|
2873
3802
|
var DeployCommandOptions = CommonCommandOptions.extend({
|
|
2874
3803
|
skipTypecheck: z4.boolean().default(false),
|
|
2875
3804
|
skipDeploy: z4.boolean().default(false),
|
|
2876
|
-
ignoreEnvVarCheck: z4.boolean().default(false),
|
|
2877
3805
|
env: z4.enum(["prod", "staging"]),
|
|
2878
3806
|
loadImage: z4.boolean().default(false),
|
|
2879
3807
|
buildPlatform: z4.enum(["linux/amd64", "linux/arm64"]).default("linux/amd64"),
|
|
@@ -2883,7 +3811,10 @@ var DeployCommandOptions = CommonCommandOptions.extend({
|
|
|
2883
3811
|
config: z4.string().optional(),
|
|
2884
3812
|
projectRef: z4.string().optional(),
|
|
2885
3813
|
outputMetafile: z4.string().optional(),
|
|
2886
|
-
apiUrl: z4.string().optional()
|
|
3814
|
+
apiUrl: z4.string().optional(),
|
|
3815
|
+
saveLogs: z4.boolean().default(false),
|
|
3816
|
+
skipUpdateCheck: z4.boolean().default(false),
|
|
3817
|
+
noCache: z4.boolean().default(false)
|
|
2887
3818
|
});
|
|
2888
3819
|
function configureDeployCommand(program2) {
|
|
2889
3820
|
return commonOptions(
|
|
@@ -2891,18 +3822,20 @@ function configureDeployCommand(program2) {
|
|
|
2891
3822
|
"-e, --env <env>",
|
|
2892
3823
|
"Deploy to a specific environment (currently only prod and staging are supported)",
|
|
2893
3824
|
"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(
|
|
3825
|
+
).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
3826
|
"-p, --project-ref <project ref>",
|
|
2899
|
-
"The project ref. Required if there is no config file."
|
|
3827
|
+
"The project ref. Required if there is no config file. This will override the project specified in the config file."
|
|
2900
3828
|
)
|
|
2901
3829
|
).addOption(
|
|
2902
3830
|
new CommandOption(
|
|
2903
3831
|
"--self-hosted",
|
|
2904
3832
|
"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
3833
|
).hideHelp()
|
|
3834
|
+
).addOption(
|
|
3835
|
+
new CommandOption(
|
|
3836
|
+
"--no-cache",
|
|
3837
|
+
"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."
|
|
3838
|
+
).hideHelp()
|
|
2906
3839
|
).addOption(
|
|
2907
3840
|
new CommandOption(
|
|
2908
3841
|
"--push",
|
|
@@ -2918,6 +3851,11 @@ function configureDeployCommand(program2) {
|
|
|
2918
3851
|
"--tag <tag>",
|
|
2919
3852
|
"(Coming soon) Specify the tag to use when pushing the image to the registry"
|
|
2920
3853
|
).hideHelp()
|
|
3854
|
+
).addOption(
|
|
3855
|
+
new CommandOption(
|
|
3856
|
+
"--ignore-env-var-check",
|
|
3857
|
+
"(deprecated) Detected missing environment variables won't block deployment"
|
|
3858
|
+
).hideHelp()
|
|
2921
3859
|
).addOption(new CommandOption("-D, --skip-deploy", "Skip deploying the image").hideHelp()).addOption(
|
|
2922
3860
|
new CommandOption("--load-image", "Load the built image into your local docker").hideHelp()
|
|
2923
3861
|
).addOption(
|
|
@@ -2930,10 +3868,15 @@ function configureDeployCommand(program2) {
|
|
|
2930
3868
|
"--output-metafile <path>",
|
|
2931
3869
|
"If provided, will save the esbuild metafile for the build to the specified path"
|
|
2932
3870
|
).hideHelp()
|
|
2933
|
-
).
|
|
3871
|
+
).addOption(
|
|
3872
|
+
new CommandOption(
|
|
3873
|
+
"--save-logs",
|
|
3874
|
+
"If provided, will save logs even for successful builds"
|
|
3875
|
+
).hideHelp()
|
|
3876
|
+
).action(async (path7, options) => {
|
|
2934
3877
|
await handleTelemetry(async () => {
|
|
2935
3878
|
await printStandloneInitialBanner(true);
|
|
2936
|
-
await deployCommand(
|
|
3879
|
+
await deployCommand(path7, options);
|
|
2937
3880
|
});
|
|
2938
3881
|
});
|
|
2939
3882
|
}
|
|
@@ -2944,7 +3887,10 @@ async function deployCommand(dir, options) {
|
|
|
2944
3887
|
}
|
|
2945
3888
|
async function _deployCommand(dir, options) {
|
|
2946
3889
|
const span = trace2.getSpan(context.active());
|
|
2947
|
-
|
|
3890
|
+
intro4("Deploying project");
|
|
3891
|
+
if (!options.skipUpdateCheck) {
|
|
3892
|
+
await updateTriggerPackages(dir, { ...options }, true, true);
|
|
3893
|
+
}
|
|
2948
3894
|
const authorization = await login({
|
|
2949
3895
|
embedded: true,
|
|
2950
3896
|
defaultApiUrl: options.apiUrl,
|
|
@@ -2968,6 +3914,11 @@ async function _deployCommand(dir, options) {
|
|
|
2968
3914
|
configFile: options.config,
|
|
2969
3915
|
projectRef: options.projectRef
|
|
2970
3916
|
});
|
|
3917
|
+
if (resolvedConfig.status === "error") {
|
|
3918
|
+
logger.error("Failed to read config:", resolvedConfig.error);
|
|
3919
|
+
span && recordSpanException5(span, resolvedConfig.error);
|
|
3920
|
+
throw new SkipLoggingError("Failed to read config");
|
|
3921
|
+
}
|
|
2971
3922
|
logger.debug("Resolved config", { resolvedConfig });
|
|
2972
3923
|
span?.setAttributes({
|
|
2973
3924
|
"resolvedConfig.status": resolvedConfig.status,
|
|
@@ -2976,7 +3927,7 @@ async function _deployCommand(dir, options) {
|
|
|
2976
3927
|
"resolvedConfig.config.projectDir": resolvedConfig.config.projectDir,
|
|
2977
3928
|
"resolvedConfig.config.triggerUrl": resolvedConfig.config.triggerUrl,
|
|
2978
3929
|
"resolvedConfig.config.triggerDirectories": resolvedConfig.config.triggerDirectories,
|
|
2979
|
-
...
|
|
3930
|
+
...flattenAttributes3(resolvedConfig.config.retries, "resolvedConfig.config.retries")
|
|
2980
3931
|
});
|
|
2981
3932
|
const apiClient2 = new CliApiClient(authorization.auth.apiUrl, authorization.auth.accessToken);
|
|
2982
3933
|
const deploymentEnv = await apiClient2.getProjectEnv({
|
|
@@ -2987,7 +3938,7 @@ async function _deployCommand(dir, options) {
|
|
|
2987
3938
|
throw new Error(deploymentEnv.error);
|
|
2988
3939
|
}
|
|
2989
3940
|
const environmentClient = new CliApiClient(authorization.auth.apiUrl, deploymentEnv.data.apiKey);
|
|
2990
|
-
|
|
3941
|
+
log5.step(
|
|
2991
3942
|
`Preparing to deploy "${deploymentEnv.data.name}" (${resolvedConfig.config.project}) to ${options.env}`
|
|
2992
3943
|
);
|
|
2993
3944
|
const compilation = await compileProject(
|
|
@@ -2996,15 +3947,6 @@ async function _deployCommand(dir, options) {
|
|
|
2996
3947
|
resolvedConfig.status === "file" ? resolvedConfig.path : void 0
|
|
2997
3948
|
);
|
|
2998
3949
|
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
3950
|
const deploymentResponse = await environmentClient.initializeDeployment({
|
|
3009
3951
|
contentHash: compilation.contentHash,
|
|
3010
3952
|
userId: authorization.userId
|
|
@@ -3018,7 +3960,7 @@ async function _deployCommand(dir, options) {
|
|
|
3018
3960
|
);
|
|
3019
3961
|
}
|
|
3020
3962
|
const version2 = deploymentResponse.data.version;
|
|
3021
|
-
const deploymentSpinner =
|
|
3963
|
+
const deploymentSpinner = spinner();
|
|
3022
3964
|
deploymentSpinner.start(`Deploying version ${version2}`);
|
|
3023
3965
|
const selfHostedRegistryHost = deploymentResponse.data.registryHost ?? options.registry;
|
|
3024
3966
|
const registryHost = selfHostedRegistryHost ?? "registry.trigger.dev";
|
|
@@ -3035,7 +3977,8 @@ async function _deployCommand(dir, options) {
|
|
|
3035
3977
|
projectRef: resolvedConfig.config.project,
|
|
3036
3978
|
buildPlatform: options.buildPlatform,
|
|
3037
3979
|
pushImage: options.push,
|
|
3038
|
-
selfHostedRegistry: !!options.registry
|
|
3980
|
+
selfHostedRegistry: !!options.registry,
|
|
3981
|
+
noCache: options.noCache
|
|
3039
3982
|
});
|
|
3040
3983
|
}
|
|
3041
3984
|
if (!deploymentResponse.data.externalBuildData) {
|
|
@@ -3043,28 +3986,57 @@ async function _deployCommand(dir, options) {
|
|
|
3043
3986
|
"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
3987
|
);
|
|
3045
3988
|
}
|
|
3046
|
-
return buildAndPushImage(
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3989
|
+
return buildAndPushImage(
|
|
3990
|
+
{
|
|
3991
|
+
registryHost,
|
|
3992
|
+
auth: authorization.auth.accessToken,
|
|
3993
|
+
imageTag: deploymentResponse.data.imageTag,
|
|
3994
|
+
buildId: deploymentResponse.data.externalBuildData.buildId,
|
|
3995
|
+
buildToken: deploymentResponse.data.externalBuildData.buildToken,
|
|
3996
|
+
buildProjectId: deploymentResponse.data.externalBuildData.projectId,
|
|
3997
|
+
cwd: compilation.path,
|
|
3998
|
+
projectId: resolvedConfig.config.project,
|
|
3999
|
+
deploymentId: deploymentResponse.data.id,
|
|
4000
|
+
deploymentVersion: deploymentResponse.data.version,
|
|
4001
|
+
contentHash: deploymentResponse.data.contentHash,
|
|
4002
|
+
projectRef: resolvedConfig.config.project,
|
|
4003
|
+
loadImage: options.loadImage,
|
|
4004
|
+
buildPlatform: options.buildPlatform,
|
|
4005
|
+
noCache: options.noCache
|
|
4006
|
+
},
|
|
4007
|
+
deploymentSpinner
|
|
4008
|
+
);
|
|
3062
4009
|
};
|
|
3063
4010
|
const image = await buildImage();
|
|
4011
|
+
const warnings = checkLogsForWarnings(image.logs);
|
|
4012
|
+
if (!warnings.ok) {
|
|
4013
|
+
await failDeploy(
|
|
4014
|
+
deploymentResponse.data.shortCode,
|
|
4015
|
+
warnings.summary,
|
|
4016
|
+
image.logs,
|
|
4017
|
+
deploymentSpinner,
|
|
4018
|
+
warnings.warnings,
|
|
4019
|
+
warnings.errors
|
|
4020
|
+
);
|
|
4021
|
+
throw new SkipLoggingError(`Failed to build project image: ${warnings.summary}`);
|
|
4022
|
+
}
|
|
3064
4023
|
if (!image.ok) {
|
|
3065
|
-
|
|
4024
|
+
await failDeploy(
|
|
4025
|
+
deploymentResponse.data.shortCode,
|
|
4026
|
+
image.error,
|
|
4027
|
+
image.logs,
|
|
4028
|
+
deploymentSpinner,
|
|
4029
|
+
warnings.warnings
|
|
4030
|
+
);
|
|
3066
4031
|
throw new SkipLoggingError(`Failed to build project image: ${image.error}`);
|
|
3067
4032
|
}
|
|
4033
|
+
const preExitTasks = async () => {
|
|
4034
|
+
printWarnings(warnings.warnings);
|
|
4035
|
+
if (options.saveLogs) {
|
|
4036
|
+
const logPath = await saveLogs(deploymentResponse.data.shortCode, image.logs);
|
|
4037
|
+
log5.info(`Build logs have been saved to ${logPath}`);
|
|
4038
|
+
}
|
|
4039
|
+
};
|
|
3068
4040
|
const imageReference = options.selfHosted ? `${selfHostedRegistryHost ? `${selfHostedRegistryHost}/` : ""}${image.image}${image.digest ? `@${image.digest}` : ""}` : `${registryHost}/${image.image}${image.digest ? `@${image.digest}` : ""}`;
|
|
3069
4041
|
span?.setAttributes({
|
|
3070
4042
|
"image.reference": imageReference
|
|
@@ -3073,6 +4045,7 @@ async function _deployCommand(dir, options) {
|
|
|
3073
4045
|
deploymentSpinner.stop(
|
|
3074
4046
|
`Project image built: ${imageReference}. Skipping deployment as requested`
|
|
3075
4047
|
);
|
|
4048
|
+
await preExitTasks();
|
|
3076
4049
|
throw new SkipCommandError("Skipping deployment as requested");
|
|
3077
4050
|
}
|
|
3078
4051
|
deploymentSpinner.message(
|
|
@@ -3082,11 +4055,13 @@ async function _deployCommand(dir, options) {
|
|
|
3082
4055
|
const startIndexingResponse = await environmentClient.startDeploymentIndexing(
|
|
3083
4056
|
deploymentResponse.data.id,
|
|
3084
4057
|
{
|
|
3085
|
-
imageReference
|
|
4058
|
+
imageReference,
|
|
4059
|
+
selfHosted: options.selfHosted
|
|
3086
4060
|
}
|
|
3087
4061
|
);
|
|
3088
4062
|
if (!startIndexingResponse.success) {
|
|
3089
4063
|
deploymentSpinner.stop(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
4064
|
+
await preExitTasks();
|
|
3090
4065
|
throw new SkipLoggingError(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
3091
4066
|
}
|
|
3092
4067
|
const finishedDeployment = await waitForDeploymentToFinish(
|
|
@@ -3095,26 +4070,33 @@ async function _deployCommand(dir, options) {
|
|
|
3095
4070
|
);
|
|
3096
4071
|
if (!finishedDeployment) {
|
|
3097
4072
|
deploymentSpinner.stop(`Deployment failed to complete`);
|
|
4073
|
+
await preExitTasks();
|
|
3098
4074
|
throw new SkipLoggingError("Deployment failed to complete: unknown issue");
|
|
3099
4075
|
}
|
|
3100
4076
|
if (typeof finishedDeployment === "string") {
|
|
3101
4077
|
deploymentSpinner.stop(`Deployment failed to complete: ${finishedDeployment}`);
|
|
4078
|
+
await preExitTasks();
|
|
3102
4079
|
throw new SkipLoggingError(`Deployment failed to complete: ${finishedDeployment}`);
|
|
3103
4080
|
}
|
|
3104
|
-
const deploymentLink =
|
|
4081
|
+
const deploymentLink = terminalLink2(
|
|
3105
4082
|
"View deployment",
|
|
3106
4083
|
`${authorization.dashboardUrl}/projects/v3/${resolvedConfig.config.project}/deployments/${finishedDeployment.shortCode}`
|
|
3107
4084
|
);
|
|
3108
4085
|
switch (finishedDeployment.status) {
|
|
3109
4086
|
case "DEPLOYED": {
|
|
3110
|
-
|
|
4087
|
+
if (warnings.warnings.length > 0) {
|
|
4088
|
+
deploymentSpinner.stop("Deployment completed with warnings");
|
|
4089
|
+
} else {
|
|
4090
|
+
deploymentSpinner.stop("Deployment completed");
|
|
4091
|
+
}
|
|
4092
|
+
await preExitTasks();
|
|
3111
4093
|
const taskCount = finishedDeployment.worker?.tasks.length ?? 0;
|
|
3112
4094
|
if (taskCount === 0) {
|
|
3113
|
-
|
|
4095
|
+
outro5(
|
|
3114
4096
|
`Version ${version2} deployed with no detected tasks. Please make sure you are exporting tasks in your project. ${deploymentLink}`
|
|
3115
4097
|
);
|
|
3116
4098
|
} else {
|
|
3117
|
-
|
|
4099
|
+
outro5(
|
|
3118
4100
|
`Version ${version2} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${deploymentLink}`
|
|
3119
4101
|
);
|
|
3120
4102
|
}
|
|
@@ -3122,10 +4104,29 @@ async function _deployCommand(dir, options) {
|
|
|
3122
4104
|
}
|
|
3123
4105
|
case "FAILED": {
|
|
3124
4106
|
if (finishedDeployment.errorData) {
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
4107
|
+
if (finishedDeployment.errorData.name === "TaskMetadataParseError") {
|
|
4108
|
+
const errorJson = safeJsonParse(finishedDeployment.errorData.stack);
|
|
4109
|
+
if (errorJson) {
|
|
4110
|
+
const parsedError2 = TaskMetadataFailedToParseData.safeParse(errorJson);
|
|
4111
|
+
if (parsedError2.success) {
|
|
4112
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4113
|
+
logTaskMetadataParseError(parsedError2.data.zodIssues, parsedError2.data.tasks);
|
|
4114
|
+
await preExitTasks();
|
|
4115
|
+
throw new SkipLoggingError(
|
|
4116
|
+
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
4117
|
+
);
|
|
4118
|
+
}
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
const parsedError = finishedDeployment.errorData.stack ? parseBuildErrorStack(finishedDeployment.errorData) ?? finishedDeployment.errorData.message : finishedDeployment.errorData.message;
|
|
4122
|
+
if (typeof parsedError === "string") {
|
|
4123
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4124
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
4125
|
+
} else {
|
|
4126
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
4127
|
+
logESMRequireError(parsedError, resolvedConfig);
|
|
4128
|
+
}
|
|
4129
|
+
await preExitTasks();
|
|
3129
4130
|
throw new SkipLoggingError(
|
|
3130
4131
|
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3131
4132
|
);
|
|
@@ -3133,62 +4134,132 @@ async function _deployCommand(dir, options) {
|
|
|
3133
4134
|
deploymentSpinner.stop(
|
|
3134
4135
|
`Deployment failed with an unknown error. Please contact eric@trigger.dev for help. ${deploymentLink}`
|
|
3135
4136
|
);
|
|
4137
|
+
await preExitTasks();
|
|
3136
4138
|
throw new SkipLoggingError("Deployment failed with an unknown error");
|
|
3137
4139
|
}
|
|
3138
4140
|
}
|
|
3139
4141
|
case "CANCELED": {
|
|
3140
4142
|
deploymentSpinner.stop(`Deployment was canceled. ${deploymentLink}`);
|
|
4143
|
+
await preExitTasks();
|
|
3141
4144
|
throw new SkipLoggingError("Deployment was canceled");
|
|
3142
4145
|
}
|
|
3143
|
-
case "TIMED_OUT": {
|
|
3144
|
-
deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
|
|
3145
|
-
|
|
4146
|
+
case "TIMED_OUT": {
|
|
4147
|
+
deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
|
|
4148
|
+
await preExitTasks();
|
|
4149
|
+
throw new SkipLoggingError("Deployment timed out");
|
|
4150
|
+
}
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
function printErrors(errors) {
|
|
4154
|
+
for (const error of errors ?? []) {
|
|
4155
|
+
log5.error(`${chalkError("Error:")} ${error}`);
|
|
4156
|
+
}
|
|
4157
|
+
}
|
|
4158
|
+
function printWarnings(warnings) {
|
|
4159
|
+
for (const warning of warnings ?? []) {
|
|
4160
|
+
log5.warn(`${chalkWarning("Warning:")} ${warning}`);
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
function checkLogsForWarnings(logs) {
|
|
4164
|
+
const warnings = [
|
|
4165
|
+
{
|
|
4166
|
+
regex: /prisma:warn We could not find your Prisma schema/,
|
|
4167
|
+
message: `Prisma generate failed to find the default schema. Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4168
|
+
"Config docs",
|
|
4169
|
+
docs.config.prisma
|
|
4170
|
+
)}
|
|
4171
|
+
Custom schema paths require a postinstall script like this: \`prisma generate --schema=./custom/path/to/schema.prisma\``,
|
|
4172
|
+
shouldFail: true
|
|
4173
|
+
}
|
|
4174
|
+
];
|
|
4175
|
+
const errorMessages2 = [];
|
|
4176
|
+
const warningMessages = [];
|
|
4177
|
+
let shouldFail = false;
|
|
4178
|
+
for (const warning of warnings) {
|
|
4179
|
+
const matches = logs.match(warning.regex);
|
|
4180
|
+
if (!matches) {
|
|
4181
|
+
continue;
|
|
4182
|
+
}
|
|
4183
|
+
const message = getMessageFromTemplate(warning.message, matches.groups);
|
|
4184
|
+
if (warning.shouldFail) {
|
|
4185
|
+
shouldFail = true;
|
|
4186
|
+
errorMessages2.push(message);
|
|
4187
|
+
} else {
|
|
4188
|
+
warningMessages.push(message);
|
|
4189
|
+
}
|
|
4190
|
+
}
|
|
4191
|
+
if (shouldFail) {
|
|
4192
|
+
return {
|
|
4193
|
+
ok: false,
|
|
4194
|
+
summary: "Build succeeded with critical warnings. Will not proceed",
|
|
4195
|
+
warnings: warningMessages,
|
|
4196
|
+
errors: errorMessages2
|
|
4197
|
+
};
|
|
4198
|
+
}
|
|
4199
|
+
return {
|
|
4200
|
+
ok: true,
|
|
4201
|
+
warnings: warningMessages
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
function checkLogsForErrors(logs) {
|
|
4205
|
+
const errors = [
|
|
4206
|
+
{
|
|
4207
|
+
regex: /Error: Provided --schema at (?<schema>.*) doesn't exist/,
|
|
4208
|
+
message: `Prisma generate failed to find the specified schema at "$schema".
|
|
4209
|
+
Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4210
|
+
"Config docs",
|
|
4211
|
+
docs.config.prisma
|
|
4212
|
+
)}`
|
|
4213
|
+
},
|
|
4214
|
+
{
|
|
4215
|
+
regex: /sh: 1: (?<packageOrBinary>.*): not found/,
|
|
4216
|
+
message: `$packageOrBinary not found
|
|
4217
|
+
|
|
4218
|
+
If it's a package: Include it in ${terminalLink2(
|
|
4219
|
+
"config.additionalPackages",
|
|
4220
|
+
docs.config.prisma
|
|
4221
|
+
)}
|
|
4222
|
+
If it's a binary: Please ${terminalLink2(
|
|
4223
|
+
"get in touch",
|
|
4224
|
+
getInTouch
|
|
4225
|
+
)} and we'll see what we can do!`
|
|
4226
|
+
}
|
|
4227
|
+
];
|
|
4228
|
+
for (const error of errors) {
|
|
4229
|
+
const matches = logs.match(error.regex);
|
|
4230
|
+
if (!matches) {
|
|
4231
|
+
continue;
|
|
3146
4232
|
}
|
|
4233
|
+
const message = getMessageFromTemplate(error.message, matches.groups);
|
|
4234
|
+
log5.error(`${chalkError("Error:")} ${message}`);
|
|
4235
|
+
break;
|
|
3147
4236
|
}
|
|
3148
4237
|
}
|
|
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;
|
|
4238
|
+
function getMessageFromTemplate(template, replacer) {
|
|
4239
|
+
let message = template;
|
|
4240
|
+
if (replacer) {
|
|
4241
|
+
for (const [key, value] of Object.entries(replacer)) {
|
|
4242
|
+
message = message.replaceAll(`$${key}`, value);
|
|
3190
4243
|
}
|
|
3191
|
-
}
|
|
4244
|
+
}
|
|
4245
|
+
return message;
|
|
4246
|
+
}
|
|
4247
|
+
async function saveLogs(shortCode, logs) {
|
|
4248
|
+
const logPath = join6(await createTempDir(), `build-${shortCode}.log`);
|
|
4249
|
+
await writeFile2(logPath, logs);
|
|
4250
|
+
return logPath;
|
|
4251
|
+
}
|
|
4252
|
+
async function failDeploy(shortCode, errorSummary, logs, deploymentSpinner, warnings, errors) {
|
|
4253
|
+
deploymentSpinner.stop(`Failed to deploy project`);
|
|
4254
|
+
if (logs.trim() !== "") {
|
|
4255
|
+
const logPath = await saveLogs(shortCode, logs);
|
|
4256
|
+
printWarnings(warnings);
|
|
4257
|
+
printErrors(errors);
|
|
4258
|
+
checkLogsForErrors(logs);
|
|
4259
|
+
outro5(`${chalkError("Error:")} ${errorSummary}. Full build logs have been saved to ${logPath}`);
|
|
4260
|
+
} else {
|
|
4261
|
+
outro5(`${chalkError("Error:")} ${errorSummary}.`);
|
|
4262
|
+
}
|
|
3192
4263
|
}
|
|
3193
4264
|
async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds = 60) {
|
|
3194
4265
|
return tracer.startActiveSpan("waitForDeploymentToFinish", async (span) => {
|
|
@@ -3218,13 +4289,13 @@ async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds
|
|
|
3218
4289
|
await setTimeout2(1e3);
|
|
3219
4290
|
}
|
|
3220
4291
|
} catch (error) {
|
|
3221
|
-
|
|
4292
|
+
recordSpanException5(span, error);
|
|
3222
4293
|
span.end();
|
|
3223
4294
|
return error instanceof Error ? error.message : JSON.stringify(error);
|
|
3224
4295
|
}
|
|
3225
4296
|
});
|
|
3226
4297
|
}
|
|
3227
|
-
async function buildAndPushImage(options) {
|
|
4298
|
+
async function buildAndPushImage(options, updater) {
|
|
3228
4299
|
return tracer.startActiveSpan("buildAndPushImage", async (span) => {
|
|
3229
4300
|
span.setAttributes({
|
|
3230
4301
|
"options.registryHost": options.registryHost,
|
|
@@ -3245,6 +4316,7 @@ async function buildAndPushImage(options) {
|
|
|
3245
4316
|
"build",
|
|
3246
4317
|
"-f",
|
|
3247
4318
|
"Containerfile",
|
|
4319
|
+
options.noCache ? "--no-cache" : void 0,
|
|
3248
4320
|
"--platform",
|
|
3249
4321
|
options.buildPlatform,
|
|
3250
4322
|
"--provenance",
|
|
@@ -3280,15 +4352,24 @@ async function buildAndPushImage(options) {
|
|
|
3280
4352
|
});
|
|
3281
4353
|
const errors = [];
|
|
3282
4354
|
try {
|
|
3283
|
-
await new Promise((res, rej) => {
|
|
4355
|
+
const processCode = await new Promise((res, rej) => {
|
|
3284
4356
|
childProcess2.stderr?.on("data", (data) => {
|
|
3285
|
-
const
|
|
3286
|
-
|
|
3287
|
-
|
|
4357
|
+
const text3 = data.toString();
|
|
4358
|
+
const lines = text3.split("\n").filter(Boolean);
|
|
4359
|
+
errors.push(...lines);
|
|
4360
|
+
logger.debug(text3);
|
|
3288
4361
|
});
|
|
3289
4362
|
childProcess2.on("error", (e) => rej(e));
|
|
3290
|
-
childProcess2.on("close", () => res());
|
|
4363
|
+
childProcess2.on("close", (code) => res(code));
|
|
3291
4364
|
});
|
|
4365
|
+
const logs = extractLogs(errors);
|
|
4366
|
+
if (processCode !== 0) {
|
|
4367
|
+
return {
|
|
4368
|
+
ok: false,
|
|
4369
|
+
error: `Error building image`,
|
|
4370
|
+
logs
|
|
4371
|
+
};
|
|
4372
|
+
}
|
|
3292
4373
|
const digest = extractImageDigest(errors);
|
|
3293
4374
|
span.setAttributes({
|
|
3294
4375
|
"image.digest": digest
|
|
@@ -3297,14 +4378,16 @@ async function buildAndPushImage(options) {
|
|
|
3297
4378
|
return {
|
|
3298
4379
|
ok: true,
|
|
3299
4380
|
image: options.imageTag,
|
|
4381
|
+
logs,
|
|
3300
4382
|
digest
|
|
3301
4383
|
};
|
|
3302
4384
|
} catch (e) {
|
|
3303
|
-
|
|
4385
|
+
recordSpanException5(span, e);
|
|
3304
4386
|
span.end();
|
|
3305
4387
|
return {
|
|
3306
4388
|
ok: false,
|
|
3307
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4389
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4390
|
+
logs: extractLogs(errors)
|
|
3308
4391
|
};
|
|
3309
4392
|
}
|
|
3310
4393
|
});
|
|
@@ -3325,6 +4408,7 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3325
4408
|
"build",
|
|
3326
4409
|
"-f",
|
|
3327
4410
|
"Containerfile",
|
|
4411
|
+
options.noCache ? "--no-cache" : void 0,
|
|
3328
4412
|
"--platform",
|
|
3329
4413
|
options.buildPlatform,
|
|
3330
4414
|
"--build-arg",
|
|
@@ -3342,7 +4426,9 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3342
4426
|
"."
|
|
3343
4427
|
// The build context
|
|
3344
4428
|
].filter(Boolean);
|
|
3345
|
-
logger.debug(`docker ${buildArgs.join(" ")}
|
|
4429
|
+
logger.debug(`docker ${buildArgs.join(" ")}`, {
|
|
4430
|
+
cwd: options.cwd
|
|
4431
|
+
});
|
|
3346
4432
|
span.setAttribute("docker.command.build", `docker ${buildArgs.join(" ")}`);
|
|
3347
4433
|
const buildProcess = execa2("docker", buildArgs, {
|
|
3348
4434
|
cwd: options.cwd
|
|
@@ -3350,25 +4436,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3350
4436
|
const errors = [];
|
|
3351
4437
|
let digest;
|
|
3352
4438
|
try {
|
|
3353
|
-
await new Promise((res, rej) => {
|
|
4439
|
+
const processCode = await new Promise((res, rej) => {
|
|
3354
4440
|
buildProcess.stderr?.on("data", (data) => {
|
|
3355
|
-
const
|
|
3356
|
-
errors.push(
|
|
3357
|
-
logger.debug(
|
|
4441
|
+
const text3 = data.toString();
|
|
4442
|
+
errors.push(text3);
|
|
4443
|
+
logger.debug(text3);
|
|
3358
4444
|
});
|
|
3359
4445
|
buildProcess.on("error", (e) => rej(e));
|
|
3360
|
-
buildProcess.on("close", () => res());
|
|
4446
|
+
buildProcess.on("close", (code) => res(code));
|
|
3361
4447
|
});
|
|
4448
|
+
if (processCode !== 0) {
|
|
4449
|
+
return {
|
|
4450
|
+
ok: false,
|
|
4451
|
+
error: "Error building image",
|
|
4452
|
+
logs: extractLogs(errors)
|
|
4453
|
+
};
|
|
4454
|
+
}
|
|
3362
4455
|
digest = extractImageDigest(errors);
|
|
3363
4456
|
span.setAttributes({
|
|
3364
4457
|
"image.digest": digest
|
|
3365
4458
|
});
|
|
3366
4459
|
} catch (e) {
|
|
3367
|
-
|
|
4460
|
+
recordSpanException5(span, e);
|
|
3368
4461
|
span.end();
|
|
3369
4462
|
return {
|
|
3370
4463
|
ok: false,
|
|
3371
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4464
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4465
|
+
logs: extractLogs(errors)
|
|
3372
4466
|
};
|
|
3373
4467
|
}
|
|
3374
4468
|
const pushArgs = ["push", imageRef].filter(Boolean);
|
|
@@ -3379,25 +4473,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3379
4473
|
cwd: options.cwd
|
|
3380
4474
|
});
|
|
3381
4475
|
try {
|
|
3382
|
-
await new Promise((res, rej) => {
|
|
4476
|
+
const processCode = await new Promise((res, rej) => {
|
|
3383
4477
|
pushProcess.stdout?.on("data", (data) => {
|
|
3384
|
-
const
|
|
3385
|
-
logger.debug(
|
|
4478
|
+
const text3 = data.toString();
|
|
4479
|
+
logger.debug(text3);
|
|
3386
4480
|
});
|
|
3387
4481
|
pushProcess.stderr?.on("data", (data) => {
|
|
3388
|
-
const
|
|
3389
|
-
logger.debug(
|
|
4482
|
+
const text3 = data.toString();
|
|
4483
|
+
logger.debug(text3);
|
|
3390
4484
|
});
|
|
3391
4485
|
pushProcess.on("error", (e) => rej(e));
|
|
3392
|
-
pushProcess.on("close", () => res());
|
|
4486
|
+
pushProcess.on("close", (code) => res(code));
|
|
3393
4487
|
});
|
|
4488
|
+
if (processCode !== 0) {
|
|
4489
|
+
return {
|
|
4490
|
+
ok: false,
|
|
4491
|
+
error: "Error pushing image",
|
|
4492
|
+
logs: extractLogs(errors)
|
|
4493
|
+
};
|
|
4494
|
+
}
|
|
3394
4495
|
span.end();
|
|
3395
4496
|
} catch (e) {
|
|
3396
|
-
|
|
4497
|
+
recordSpanException5(span, e);
|
|
3397
4498
|
span.end();
|
|
3398
4499
|
return {
|
|
3399
4500
|
ok: false,
|
|
3400
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4501
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4502
|
+
logs: extractLogs(errors)
|
|
3401
4503
|
};
|
|
3402
4504
|
}
|
|
3403
4505
|
}
|
|
@@ -3405,21 +4507,25 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3405
4507
|
return {
|
|
3406
4508
|
ok: true,
|
|
3407
4509
|
image: options.imageTag,
|
|
3408
|
-
digest
|
|
4510
|
+
digest,
|
|
4511
|
+
logs: extractLogs(errors)
|
|
3409
4512
|
};
|
|
3410
4513
|
});
|
|
3411
4514
|
}
|
|
3412
4515
|
function extractImageDigest(outputs) {
|
|
3413
|
-
const imageDigestRegex = /sha256:[a-f0-9]{64}/;
|
|
4516
|
+
const imageDigestRegex = /pushing manifest for .+(?<digest>sha256:[a-f0-9]{64})/;
|
|
3414
4517
|
for (const line of outputs) {
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
}
|
|
4518
|
+
const imageDigestMatch = line.match(imageDigestRegex);
|
|
4519
|
+
const digest = imageDigestMatch?.groups?.digest;
|
|
4520
|
+
if (digest) {
|
|
4521
|
+
return digest;
|
|
3420
4522
|
}
|
|
3421
4523
|
}
|
|
3422
4524
|
}
|
|
4525
|
+
function extractLogs(outputs) {
|
|
4526
|
+
const cleanedOutputs = outputs.map((line) => line.trim()).filter((line) => line !== "");
|
|
4527
|
+
return cleanedOutputs.map((line) => line.trim()).join("\n");
|
|
4528
|
+
}
|
|
3423
4529
|
async function compileProject(config, options, configPath) {
|
|
3424
4530
|
return await tracer.startActiveSpan("compileProject", async (span) => {
|
|
3425
4531
|
try {
|
|
@@ -3429,25 +4535,25 @@ async function compileProject(config, options, configPath) {
|
|
|
3429
4535
|
throw new Error("Typecheck failed, aborting deployment");
|
|
3430
4536
|
}
|
|
3431
4537
|
}
|
|
3432
|
-
const compileSpinner =
|
|
4538
|
+
const compileSpinner = spinner();
|
|
3433
4539
|
compileSpinner.start(`Building project in ${config.projectDir}`);
|
|
3434
4540
|
const taskFiles = await gatherTaskFiles(config);
|
|
3435
4541
|
const workerFacade = readFileSync2(
|
|
3436
|
-
|
|
3437
|
-
"file://",
|
|
3438
|
-
""
|
|
3439
|
-
),
|
|
4542
|
+
join6(cliRootPath(), "workers", "prod", "worker-facade.js"),
|
|
3440
4543
|
"utf-8"
|
|
3441
4544
|
);
|
|
3442
|
-
const workerSetupPath =
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
4545
|
+
const workerSetupPath = join6(cliRootPath(), "workers", "prod", "worker-setup.js");
|
|
4546
|
+
let workerContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
4547
|
+
"__WORKER_SETUP__",
|
|
4548
|
+
`import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
|
|
4549
|
+
);
|
|
3446
4550
|
if (configPath) {
|
|
3447
4551
|
logger.debug("Importing project config from", { configPath });
|
|
3448
4552
|
workerContents = workerContents.replace(
|
|
3449
4553
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
3450
|
-
`import * as importedConfigExports from "${
|
|
4554
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
4555
|
+
configPath
|
|
4556
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
3451
4557
|
);
|
|
3452
4558
|
} else {
|
|
3453
4559
|
workerContents = workerContents.replace(
|
|
@@ -3473,17 +4579,26 @@ async function compileProject(config, options, configPath) {
|
|
|
3473
4579
|
// This is needed to support opentelemetry instrumentation that uses module patching
|
|
3474
4580
|
target: ["node18", "es2020"],
|
|
3475
4581
|
outdir: "out",
|
|
4582
|
+
banner: {
|
|
4583
|
+
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" } }); } });`
|
|
4584
|
+
},
|
|
3476
4585
|
define: {
|
|
3477
4586
|
TRIGGER_API_URL: `"${config.triggerUrl}"`,
|
|
3478
4587
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
3479
4588
|
},
|
|
3480
4589
|
plugins: [
|
|
4590
|
+
mockServerOnlyPlugin(),
|
|
3481
4591
|
bundleDependenciesPlugin(
|
|
3482
4592
|
"workerFacade",
|
|
3483
4593
|
config.dependenciesToBundle,
|
|
3484
4594
|
config.tsconfigPath
|
|
3485
4595
|
),
|
|
3486
|
-
workerSetupImportConfigPlugin(configPath)
|
|
4596
|
+
workerSetupImportConfigPlugin(configPath),
|
|
4597
|
+
esbuildDecorators2({
|
|
4598
|
+
tsconfig: config.tsconfigPath,
|
|
4599
|
+
tsx: true,
|
|
4600
|
+
force: false
|
|
4601
|
+
})
|
|
3487
4602
|
]
|
|
3488
4603
|
});
|
|
3489
4604
|
if (result.errors.length > 0) {
|
|
@@ -3496,13 +4611,10 @@ async function compileProject(config, options, configPath) {
|
|
|
3496
4611
|
throw new Error("Build failed, aborting deployment");
|
|
3497
4612
|
}
|
|
3498
4613
|
if (options.outputMetafile) {
|
|
3499
|
-
await writeJSONFile(
|
|
4614
|
+
await writeJSONFile(join6(options.outputMetafile, "worker.json"), result.metafile);
|
|
3500
4615
|
}
|
|
3501
4616
|
const entryPointContents = readFileSync2(
|
|
3502
|
-
|
|
3503
|
-
"file://",
|
|
3504
|
-
""
|
|
3505
|
-
),
|
|
4617
|
+
join6(cliRootPath(), "workers", "prod", "entry-point.js"),
|
|
3506
4618
|
"utf-8"
|
|
3507
4619
|
);
|
|
3508
4620
|
const entryPointResult = await build2({
|
|
@@ -3545,58 +4657,72 @@ async function compileProject(config, options, configPath) {
|
|
|
3545
4657
|
}
|
|
3546
4658
|
if (options.outputMetafile) {
|
|
3547
4659
|
await writeJSONFile(
|
|
3548
|
-
|
|
4660
|
+
join6(options.outputMetafile, "entry-point.json"),
|
|
3549
4661
|
entryPointResult.metafile
|
|
3550
4662
|
);
|
|
3551
4663
|
}
|
|
3552
4664
|
const tempDir = await createTempDir();
|
|
3553
4665
|
logger.debug(`Writing compiled files to ${tempDir}`);
|
|
3554
|
-
const metaOutput = result.metafile.outputs[
|
|
4666
|
+
const metaOutput = result.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3555
4667
|
invariant(metaOutput, "Meta output for the result build is missing");
|
|
3556
|
-
const entryPointMetaOutput = entryPointResult.metafile.outputs[
|
|
4668
|
+
const entryPointMetaOutput = entryPointResult.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3557
4669
|
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
|
|
3558
4670
|
const workerOutputFile = result.outputFiles.find(
|
|
3559
|
-
(file) => file.path ===
|
|
4671
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3560
4672
|
);
|
|
3561
4673
|
invariant(workerOutputFile, "Output file for the result build is missing");
|
|
3562
4674
|
const workerSourcemapFile = result.outputFiles.find(
|
|
3563
|
-
(file) => file.path ===
|
|
4675
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js.map")
|
|
3564
4676
|
);
|
|
3565
4677
|
invariant(workerSourcemapFile, "Sourcemap file for the result build is missing");
|
|
3566
4678
|
const entryPointOutputFile = entryPointResult.outputFiles.find(
|
|
3567
|
-
(file) => file.path ===
|
|
4679
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3568
4680
|
);
|
|
3569
4681
|
invariant(entryPointOutputFile, "Output file for the entryPoint build is missing");
|
|
3570
4682
|
await writeFile2(
|
|
3571
|
-
|
|
4683
|
+
join6(tempDir, "worker.js"),
|
|
3572
4684
|
`${workerOutputFile.text}
|
|
3573
4685
|
//# sourceMappingURL=worker.js.map`
|
|
3574
4686
|
);
|
|
3575
|
-
await writeFile2(
|
|
3576
|
-
await writeFile2(
|
|
4687
|
+
await writeFile2(join6(tempDir, "worker.js.map"), workerSourcemapFile.text);
|
|
4688
|
+
await writeFile2(join6(tempDir, "index.js"), entryPointOutputFile.text);
|
|
3577
4689
|
logger.debug("Getting the imports for the worker and entryPoint builds", {
|
|
3578
4690
|
workerImports: metaOutput.imports,
|
|
3579
4691
|
entryPointImports: entryPointMetaOutput.imports
|
|
3580
4692
|
});
|
|
3581
4693
|
const allImports = [...metaOutput.imports, ...entryPointMetaOutput.imports];
|
|
3582
|
-
const
|
|
3583
|
-
const dependencies2 = await
|
|
3584
|
-
|
|
3585
|
-
config,
|
|
3586
|
-
externalPackageJson
|
|
3587
|
-
);
|
|
4694
|
+
const javascriptProject = new JavascriptProject(config.projectDir);
|
|
4695
|
+
const dependencies2 = await resolveRequiredDependencies(allImports, config, javascriptProject);
|
|
4696
|
+
logger.debug("gatherRequiredDependencies()", { dependencies: dependencies2 });
|
|
3588
4697
|
const packageJsonContents = {
|
|
3589
4698
|
name: "trigger-worker",
|
|
3590
4699
|
version: "0.0.0",
|
|
3591
4700
|
description: "",
|
|
3592
4701
|
dependencies: dependencies2,
|
|
3593
4702
|
scripts: {
|
|
3594
|
-
|
|
4703
|
+
...javascriptProject.scripts
|
|
3595
4704
|
}
|
|
3596
4705
|
};
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
4706
|
+
span.setAttributes({
|
|
4707
|
+
...flattenAttributes3(packageJsonContents, "packageJson.contents")
|
|
4708
|
+
});
|
|
4709
|
+
await writeJSONFile(join6(tempDir, "package.json"), packageJsonContents);
|
|
4710
|
+
const copyResult = await copyAdditionalFiles(config, tempDir);
|
|
4711
|
+
if (!copyResult.ok) {
|
|
4712
|
+
compileSpinner.stop("Project built with warnings");
|
|
4713
|
+
log5.warn(
|
|
4714
|
+
`No additionalFiles matches for:
|
|
4715
|
+
|
|
4716
|
+
${copyResult.noMatches.map((glob) => `- "${glob}"`).join("\n")}
|
|
4717
|
+
|
|
4718
|
+
If this is unexpected you should check your ${terminalLink2(
|
|
4719
|
+
"glob patterns",
|
|
4720
|
+
"https://github.com/isaacs/node-glob?tab=readme-ov-file#glob-primer"
|
|
4721
|
+
)} are valid.`
|
|
4722
|
+
);
|
|
4723
|
+
} else {
|
|
4724
|
+
compileSpinner.stop("Project built successfully");
|
|
4725
|
+
}
|
|
3600
4726
|
const resolvingDependenciesResult = await resolveDependencies(
|
|
3601
4727
|
tempDir,
|
|
3602
4728
|
packageJsonContents,
|
|
@@ -3604,31 +4730,31 @@ async function compileProject(config, options, configPath) {
|
|
|
3604
4730
|
options
|
|
3605
4731
|
);
|
|
3606
4732
|
if (!resolvingDependenciesResult) {
|
|
3607
|
-
throw new
|
|
4733
|
+
throw new SkipLoggingError("Failed to resolve dependencies");
|
|
4734
|
+
}
|
|
4735
|
+
const containerFilePath = join6(cliRootPath(), "Containerfile.prod");
|
|
4736
|
+
let containerFileContents = readFileSync2(containerFilePath, "utf-8");
|
|
4737
|
+
if (config.postInstall) {
|
|
4738
|
+
containerFileContents = containerFileContents.replace(
|
|
4739
|
+
"__POST_INSTALL__",
|
|
4740
|
+
`RUN ${config.postInstall}`
|
|
4741
|
+
);
|
|
4742
|
+
} else {
|
|
4743
|
+
containerFileContents = containerFileContents.replace("__POST_INSTALL__", "");
|
|
3608
4744
|
}
|
|
3609
|
-
|
|
3610
|
-
importResolve("./Containerfile.prod", import.meta.url)
|
|
3611
|
-
).href.replace("file://", "");
|
|
3612
|
-
await copyFile(containerFilePath, join4(tempDir, "Containerfile"));
|
|
4745
|
+
await writeFile2(join6(tempDir, "Containerfile"), containerFileContents);
|
|
3613
4746
|
const contentHasher = createHash("sha256");
|
|
3614
4747
|
contentHasher.update(Buffer.from(entryPointOutputFile.text));
|
|
3615
4748
|
contentHasher.update(Buffer.from(workerOutputFile.text));
|
|
3616
4749
|
contentHasher.update(Buffer.from(JSON.stringify(dependencies2)));
|
|
3617
4750
|
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
4751
|
span.setAttributes({
|
|
3625
|
-
contentHash
|
|
3626
|
-
envVars: finalEnvVars
|
|
4752
|
+
contentHash
|
|
3627
4753
|
});
|
|
3628
4754
|
span.end();
|
|
3629
|
-
return { path: tempDir, contentHash
|
|
4755
|
+
return { path: tempDir, contentHash };
|
|
3630
4756
|
} catch (e) {
|
|
3631
|
-
|
|
4757
|
+
recordSpanException5(span, e);
|
|
3632
4758
|
span.end();
|
|
3633
4759
|
throw e;
|
|
3634
4760
|
}
|
|
@@ -3636,22 +4762,22 @@ async function compileProject(config, options, configPath) {
|
|
|
3636
4762
|
}
|
|
3637
4763
|
async function resolveDependencies(projectDir, packageJsonContents, config, options) {
|
|
3638
4764
|
return await tracer.startActiveSpan("resolveDependencies", async (span) => {
|
|
3639
|
-
const resolvingDepsSpinner =
|
|
4765
|
+
const resolvingDepsSpinner = spinner();
|
|
3640
4766
|
resolvingDepsSpinner.start("Resolving dependencies");
|
|
3641
4767
|
const hasher = createHash("sha256");
|
|
3642
4768
|
hasher.update(JSON.stringify(packageJsonContents));
|
|
3643
4769
|
const digest = hasher.digest("hex").slice(0, 16);
|
|
3644
|
-
const cacheDir =
|
|
3645
|
-
const cachePath =
|
|
4770
|
+
const cacheDir = join6(config.projectDir, ".trigger", "cache");
|
|
4771
|
+
const cachePath = join6(cacheDir, `${digest}.json`);
|
|
3646
4772
|
span.setAttributes({
|
|
3647
4773
|
"packageJson.digest": digest,
|
|
3648
4774
|
"cache.path": cachePath,
|
|
3649
|
-
...
|
|
4775
|
+
...flattenAttributes3(packageJsonContents, "packageJson.contents")
|
|
3650
4776
|
});
|
|
3651
4777
|
try {
|
|
3652
4778
|
const cachedPackageLock = await readFile2(cachePath, "utf-8");
|
|
3653
4779
|
logger.debug(`Using cached package-lock.json for ${digest}`);
|
|
3654
|
-
await writeFile2(
|
|
4780
|
+
await writeFile2(join6(projectDir, "package-lock.json"), cachedPackageLock);
|
|
3655
4781
|
span.setAttributes({
|
|
3656
4782
|
"cache.hit": true
|
|
3657
4783
|
});
|
|
@@ -3674,21 +4800,44 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3674
4800
|
cwd: projectDir,
|
|
3675
4801
|
stdio: logger.loggerLevel === "debug" ? "inherit" : "pipe"
|
|
3676
4802
|
});
|
|
3677
|
-
const packageLockContents = await readFile2(
|
|
4803
|
+
const packageLockContents = await readFile2(join6(projectDir, "package-lock.json"), "utf-8");
|
|
3678
4804
|
logger.debug(`Writing package-lock.json to cache for ${digest}`);
|
|
3679
4805
|
await mkdir(cacheDir, { recursive: true });
|
|
3680
4806
|
await writeFile2(cachePath, packageLockContents);
|
|
3681
|
-
await writeFile2(
|
|
4807
|
+
await writeFile2(join6(projectDir, "package-lock.json"), packageLockContents);
|
|
3682
4808
|
span.end();
|
|
3683
4809
|
resolvingDepsSpinner.stop("Dependencies resolved");
|
|
3684
4810
|
return true;
|
|
3685
4811
|
} catch (installError) {
|
|
3686
|
-
|
|
3687
|
-
recordSpanException4(span, installError);
|
|
4812
|
+
recordSpanException5(span, installError);
|
|
3688
4813
|
span.end();
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
4814
|
+
const parsedError = parseNpmInstallError(installError);
|
|
4815
|
+
if (typeof parsedError === "string") {
|
|
4816
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies: ${parsedError}`);
|
|
4817
|
+
} else {
|
|
4818
|
+
switch (parsedError.type) {
|
|
4819
|
+
case "package-not-found-error": {
|
|
4820
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4821
|
+
logger.log(
|
|
4822
|
+
`
|
|
4823
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4824
|
+
parsedError.packageName
|
|
4825
|
+
)} could not be found in the npm registry.`
|
|
4826
|
+
);
|
|
4827
|
+
break;
|
|
4828
|
+
}
|
|
4829
|
+
case "no-matching-version-error": {
|
|
4830
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4831
|
+
logger.log(
|
|
4832
|
+
`
|
|
4833
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4834
|
+
parsedError.packageName
|
|
4835
|
+
)} could not resolve because the version doesn't exist`
|
|
4836
|
+
);
|
|
4837
|
+
break;
|
|
4838
|
+
}
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
3692
4841
|
return false;
|
|
3693
4842
|
}
|
|
3694
4843
|
}
|
|
@@ -3697,7 +4846,7 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3697
4846
|
async function typecheckProject(config, options) {
|
|
3698
4847
|
return await tracer.startActiveSpan("typecheckProject", async (span) => {
|
|
3699
4848
|
try {
|
|
3700
|
-
const typecheckSpinner =
|
|
4849
|
+
const typecheckSpinner = spinner();
|
|
3701
4850
|
typecheckSpinner.start("Typechecking project");
|
|
3702
4851
|
const tscTypecheck = execa2("npm", ["exec", "tsc", "--", "--noEmit"], {
|
|
3703
4852
|
cwd: config.projectDir
|
|
@@ -3707,8 +4856,8 @@ async function typecheckProject(config, options) {
|
|
|
3707
4856
|
tscTypecheck.stdout?.on("data", (chunk) => stdouts.push(chunk.toString()));
|
|
3708
4857
|
tscTypecheck.stderr?.on("data", (chunk) => stderrs.push(chunk.toString()));
|
|
3709
4858
|
try {
|
|
3710
|
-
await new Promise((
|
|
3711
|
-
tscTypecheck.addListener("exit", (code) => code === 0 ?
|
|
4859
|
+
await new Promise((resolve5, reject) => {
|
|
4860
|
+
tscTypecheck.addListener("exit", (code) => code === 0 ? resolve5(code) : reject(code));
|
|
3712
4861
|
});
|
|
3713
4862
|
} catch (error) {
|
|
3714
4863
|
typecheckSpinner.stop(
|
|
@@ -3726,63 +4875,100 @@ async function typecheckProject(config, options) {
|
|
|
3726
4875
|
span.end();
|
|
3727
4876
|
return true;
|
|
3728
4877
|
} catch (e) {
|
|
3729
|
-
|
|
4878
|
+
recordSpanException5(span, e);
|
|
3730
4879
|
span.end();
|
|
3731
4880
|
return false;
|
|
3732
4881
|
}
|
|
3733
4882
|
});
|
|
3734
4883
|
}
|
|
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]) {
|
|
4884
|
+
async function resolveRequiredDependencies(imports, config, project) {
|
|
4885
|
+
return await tracer.startActiveSpan("resolveRequiredDependencies", async (span) => {
|
|
4886
|
+
const resolvablePackageNames = /* @__PURE__ */ new Set();
|
|
4887
|
+
for (const file of imports) {
|
|
4888
|
+
if (file.kind !== "require-call" && file.kind !== "dynamic-import" || !file.external) {
|
|
3758
4889
|
continue;
|
|
3759
4890
|
}
|
|
3760
|
-
const
|
|
3761
|
-
if (
|
|
3762
|
-
dependencies2[packageParts.name] = packageParts.version;
|
|
4891
|
+
const packageName = detectPackageNameFromImportPath(file.path);
|
|
4892
|
+
if (!packageName) {
|
|
3763
4893
|
continue;
|
|
3764
|
-
}
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
4894
|
+
}
|
|
4895
|
+
resolvablePackageNames.add(packageName);
|
|
4896
|
+
}
|
|
4897
|
+
span.setAttribute("resolvablePackageNames", Array.from(resolvablePackageNames));
|
|
4898
|
+
const resolvedPackageVersions = await project.resolveAll(Array.from(resolvablePackageNames));
|
|
4899
|
+
const missingPackages = Array.from(resolvablePackageNames).filter(
|
|
4900
|
+
(packageName) => !resolvedPackageVersions[packageName]
|
|
4901
|
+
);
|
|
4902
|
+
span.setAttributes({
|
|
4903
|
+
...flattenAttributes3(resolvedPackageVersions, "resolvedPackageVersions")
|
|
4904
|
+
});
|
|
4905
|
+
span.setAttribute("missingPackages", missingPackages);
|
|
4906
|
+
const dependencies2 = {};
|
|
4907
|
+
for (const missingPackage of missingPackages) {
|
|
4908
|
+
const internalDependencyVersion = dependencies[missingPackage] ?? detectDependencyVersion(missingPackage);
|
|
4909
|
+
if (internalDependencyVersion) {
|
|
4910
|
+
dependencies2[missingPackage] = stripWorkspaceFromVersion(internalDependencyVersion);
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
for (const [packageName, version2] of Object.entries(resolvedPackageVersions)) {
|
|
4914
|
+
dependencies2[packageName] = version2;
|
|
4915
|
+
}
|
|
4916
|
+
if (config.additionalPackages) {
|
|
4917
|
+
span.setAttribute("additionalPackages", config.additionalPackages);
|
|
4918
|
+
for (const packageName of config.additionalPackages) {
|
|
4919
|
+
if (dependencies2[packageName]) {
|
|
4920
|
+
continue;
|
|
4921
|
+
}
|
|
4922
|
+
const packageParts = parsePackageName(packageName);
|
|
4923
|
+
if (packageParts.version) {
|
|
4924
|
+
dependencies2[packageParts.name] = packageParts.version;
|
|
3771
4925
|
continue;
|
|
3772
4926
|
} else {
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
);
|
|
4927
|
+
const externalDependencyVersion = await project.resolve(packageParts.name, {
|
|
4928
|
+
allowDev: true
|
|
4929
|
+
});
|
|
4930
|
+
if (externalDependencyVersion) {
|
|
4931
|
+
dependencies2[packageParts.name] = externalDependencyVersion;
|
|
4932
|
+
continue;
|
|
4933
|
+
} else {
|
|
4934
|
+
logger.log(
|
|
4935
|
+
`${chalkWarning("X Warning:")} Could not find version for package ${chalkPurple(
|
|
4936
|
+
packageName
|
|
4937
|
+
)}, add a version specifier to the package name (e.g. ${packageParts.name}@latest) or add it to your project's package.json`
|
|
4938
|
+
);
|
|
4939
|
+
}
|
|
3776
4940
|
}
|
|
3777
4941
|
}
|
|
3778
4942
|
}
|
|
3779
|
-
|
|
3780
|
-
|
|
4943
|
+
if (!dependencies2["@trigger.dev/sdk"]) {
|
|
4944
|
+
logger.debug("Adding missing @trigger.dev/sdk dependency", {
|
|
4945
|
+
version
|
|
4946
|
+
});
|
|
4947
|
+
span.setAttribute("addingMissingSDK", version);
|
|
4948
|
+
dependencies2["@trigger.dev/sdk"] = version;
|
|
4949
|
+
}
|
|
4950
|
+
if (!dependencies2["@trigger.dev/core"]) {
|
|
4951
|
+
logger.debug("Adding missing @trigger.dev/core dependency", {
|
|
4952
|
+
version
|
|
4953
|
+
});
|
|
4954
|
+
span.setAttribute("addingMissingCore", version);
|
|
4955
|
+
dependencies2["@trigger.dev/core"] = version;
|
|
4956
|
+
}
|
|
4957
|
+
const result = Object.fromEntries(
|
|
4958
|
+
Object.entries(dependencies2).sort(([a], [b]) => a.localeCompare(b))
|
|
4959
|
+
);
|
|
4960
|
+
span.setAttributes({
|
|
4961
|
+
...flattenAttributes3(result, "dependencies")
|
|
4962
|
+
});
|
|
4963
|
+
span.end();
|
|
4964
|
+
return result;
|
|
4965
|
+
});
|
|
3781
4966
|
}
|
|
3782
4967
|
async function copyAdditionalFiles(config, tempDir) {
|
|
3783
4968
|
const additionalFiles = config.additionalFiles ?? [];
|
|
4969
|
+
const noMatches = [];
|
|
3784
4970
|
if (additionalFiles.length === 0) {
|
|
3785
|
-
return;
|
|
4971
|
+
return { ok: true };
|
|
3786
4972
|
}
|
|
3787
4973
|
return await tracer.startActiveSpan(
|
|
3788
4974
|
"copyAdditionalFiles",
|
|
@@ -3796,24 +4982,57 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3796
4982
|
logger.debug(`Copying files to ${tempDir}`, {
|
|
3797
4983
|
additionalFiles
|
|
3798
4984
|
});
|
|
3799
|
-
const
|
|
4985
|
+
const globOptions = {
|
|
3800
4986
|
withFileTypes: true,
|
|
3801
4987
|
ignore: ["node_modules"],
|
|
3802
4988
|
cwd: config.projectDir,
|
|
3803
4989
|
nodir: true
|
|
3804
|
-
}
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
)
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
4990
|
+
};
|
|
4991
|
+
const globs = [];
|
|
4992
|
+
let i = 0;
|
|
4993
|
+
for (const additionalFile of additionalFiles) {
|
|
4994
|
+
let glob;
|
|
4995
|
+
if (i === 0) {
|
|
4996
|
+
glob = new Glob(additionalFile, globOptions);
|
|
4997
|
+
} else {
|
|
4998
|
+
const previousGlob = globs[i - 1];
|
|
4999
|
+
if (!previousGlob) {
|
|
5000
|
+
logger.error("No previous glob, this shouldn't happen", { i, additionalFiles });
|
|
5001
|
+
continue;
|
|
5002
|
+
}
|
|
5003
|
+
glob = new Glob(additionalFile, previousGlob);
|
|
5004
|
+
}
|
|
5005
|
+
if (!(Symbol.asyncIterator in glob)) {
|
|
5006
|
+
logger.error("Glob should be an async iterator", { glob });
|
|
5007
|
+
throw new Error("Unrecoverable error while copying additional files");
|
|
5008
|
+
}
|
|
5009
|
+
let matches = 0;
|
|
5010
|
+
for await (const file of glob) {
|
|
5011
|
+
matches++;
|
|
5012
|
+
const pathInsideTempDir = relative3(config.projectDir, file.fullpath()).split(posix.sep).filter((p) => p !== "..").join(posix.sep);
|
|
5013
|
+
const relativeDestinationPath = join6(tempDir, pathInsideTempDir);
|
|
5014
|
+
logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
|
|
5015
|
+
await mkdir(dirname(relativeDestinationPath), { recursive: true });
|
|
5016
|
+
await copyFile(file.fullpath(), relativeDestinationPath);
|
|
5017
|
+
}
|
|
5018
|
+
if (matches === 0) {
|
|
5019
|
+
noMatches.push(additionalFile);
|
|
5020
|
+
}
|
|
5021
|
+
globs[i] = glob;
|
|
5022
|
+
i++;
|
|
3813
5023
|
}
|
|
3814
5024
|
span.end();
|
|
5025
|
+
if (noMatches.length > 0) {
|
|
5026
|
+
return {
|
|
5027
|
+
ok: false,
|
|
5028
|
+
noMatches
|
|
5029
|
+
};
|
|
5030
|
+
}
|
|
5031
|
+
return {
|
|
5032
|
+
ok: true
|
|
5033
|
+
};
|
|
3815
5034
|
} catch (error) {
|
|
3816
|
-
|
|
5035
|
+
recordSpanException5(span, error);
|
|
3817
5036
|
span.end();
|
|
3818
5037
|
throw error;
|
|
3819
5038
|
}
|
|
@@ -3822,7 +5041,7 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3822
5041
|
}
|
|
3823
5042
|
async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
3824
5043
|
const tmpDir = await createTempDir();
|
|
3825
|
-
const dockerConfigPath =
|
|
5044
|
+
const dockerConfigPath = join6(tmpDir, "config.json");
|
|
3826
5045
|
await writeJSONFile(dockerConfigPath, {
|
|
3827
5046
|
auths: {
|
|
3828
5047
|
[registryHost]: {
|
|
@@ -3833,43 +5052,20 @@ async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
|
3833
5052
|
logger.debug(`Writing docker config to ${dockerConfigPath}`);
|
|
3834
5053
|
return tmpDir;
|
|
3835
5054
|
}
|
|
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
5055
|
|
|
3858
5056
|
// src/commands/dev.tsx
|
|
3859
5057
|
import {
|
|
3860
|
-
ZodMessageHandler as ZodMessageHandler2,
|
|
3861
|
-
ZodMessageSender as ZodMessageSender2,
|
|
3862
5058
|
clientWebsocketMessages,
|
|
3863
5059
|
detectDependencyVersion as detectDependencyVersion2,
|
|
3864
5060
|
serverWebsocketMessages
|
|
3865
5061
|
} from "@trigger.dev/core/v3";
|
|
5062
|
+
import { ZodMessageHandler as ZodMessageHandler2, ZodMessageSender as ZodMessageSender2 } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3866
5063
|
import { watch } from "chokidar";
|
|
3867
5064
|
import { context as context2 } from "esbuild";
|
|
3868
|
-
import { resolve as importResolve2 } from "import-meta-resolve";
|
|
3869
5065
|
import { render, useInput } from "ink";
|
|
3870
5066
|
import { createHash as createHash2 } from "node:crypto";
|
|
3871
5067
|
import fs7, { readFileSync as readFileSync3 } from "node:fs";
|
|
3872
|
-
import { basename, dirname as dirname3, join as
|
|
5068
|
+
import { basename as basename2, dirname as dirname3, join as join7, normalize } from "node:path";
|
|
3873
5069
|
import pDebounce from "p-debounce";
|
|
3874
5070
|
import { WebSocket } from "partysocket";
|
|
3875
5071
|
import React, { Suspense, useEffect } from "react";
|
|
@@ -3885,23 +5081,30 @@ var UncaughtExceptionError = class extends Error {
|
|
|
3885
5081
|
this.name = "UncaughtExceptionError";
|
|
3886
5082
|
}
|
|
3887
5083
|
};
|
|
5084
|
+
var TaskMetadataParseError = class extends Error {
|
|
5085
|
+
constructor(zodIssues, tasks) {
|
|
5086
|
+
super(`Failed to parse task metadata`);
|
|
5087
|
+
this.zodIssues = zodIssues;
|
|
5088
|
+
this.tasks = tasks;
|
|
5089
|
+
this.name = "TaskMetadataParseError";
|
|
5090
|
+
}
|
|
5091
|
+
};
|
|
3888
5092
|
|
|
3889
5093
|
// src/workers/dev/backgroundWorker.ts
|
|
3890
5094
|
import {
|
|
3891
5095
|
SemanticInternalAttributes,
|
|
3892
5096
|
TaskRunErrorCodes,
|
|
3893
|
-
ZodMessageHandler,
|
|
3894
|
-
ZodMessageSender,
|
|
3895
5097
|
childToWorkerMessages,
|
|
3896
5098
|
correctErrorStackTrace,
|
|
3897
5099
|
formatDurationMilliseconds,
|
|
3898
5100
|
workerToChildMessages
|
|
3899
5101
|
} from "@trigger.dev/core/v3";
|
|
5102
|
+
import { ZodMessageHandler, ZodMessageSender } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3900
5103
|
import dotenv from "dotenv";
|
|
3901
5104
|
import { Evt } from "evt";
|
|
3902
5105
|
import { fork } from "node:child_process";
|
|
3903
|
-
import { dirname as dirname2, resolve as
|
|
3904
|
-
import
|
|
5106
|
+
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
5107
|
+
import terminalLink3 from "terminal-link";
|
|
3905
5108
|
var BackgroundWorkerCoordinator = class {
|
|
3906
5109
|
constructor(baseURL) {
|
|
3907
5110
|
this.baseURL = baseURL;
|
|
@@ -3986,7 +5189,7 @@ var BackgroundWorkerCoordinator = class {
|
|
|
3986
5189
|
const logsUrl = `${this.baseURL}/runs/${execution.run.id}`;
|
|
3987
5190
|
const pipe = chalkGrey("|");
|
|
3988
5191
|
const bullet = chalkGrey("\u25CB");
|
|
3989
|
-
const link = chalkLink(
|
|
5192
|
+
const link = chalkLink(terminalLink3("View logs", logsUrl));
|
|
3990
5193
|
let timestampPrefix = chalkGrey(prettyPrintDate(payload.execution.attempt.startedAt));
|
|
3991
5194
|
const workerPrefix = chalkWorker(record.version);
|
|
3992
5195
|
const taskPrefix = chalkTask(execution.task.id);
|
|
@@ -4059,8 +5262,8 @@ var CancelledProcessError = class extends Error {
|
|
|
4059
5262
|
}
|
|
4060
5263
|
};
|
|
4061
5264
|
var BackgroundWorker = class {
|
|
4062
|
-
constructor(
|
|
4063
|
-
this.path =
|
|
5265
|
+
constructor(path7, params) {
|
|
5266
|
+
this.path = path7;
|
|
4064
5267
|
this.params = params;
|
|
4065
5268
|
}
|
|
4066
5269
|
_initialized = false;
|
|
@@ -4094,7 +5297,13 @@ var BackgroundWorker = class {
|
|
|
4094
5297
|
await installPackages(this.params.dependencies, { cwd: dirname2(this.path) });
|
|
4095
5298
|
}
|
|
4096
5299
|
let resolved = false;
|
|
4097
|
-
|
|
5300
|
+
const cwd = dirname2(this.path);
|
|
5301
|
+
const fullEnv = {
|
|
5302
|
+
...this.params.env,
|
|
5303
|
+
...this.#readEnvVars()
|
|
5304
|
+
};
|
|
5305
|
+
logger.debug("Initializing worker", { path: this.path, cwd, fullEnv });
|
|
5306
|
+
this.tasks = await new Promise((resolve5, reject) => {
|
|
4098
5307
|
const child = fork(this.path, {
|
|
4099
5308
|
stdio: [
|
|
4100
5309
|
/*stdin*/
|
|
@@ -4105,10 +5314,8 @@ var BackgroundWorker = class {
|
|
|
4105
5314
|
"pipe",
|
|
4106
5315
|
"ipc"
|
|
4107
5316
|
],
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
...this.#readEnvVars()
|
|
4111
|
-
}
|
|
5317
|
+
cwd,
|
|
5318
|
+
env: fullEnv
|
|
4112
5319
|
});
|
|
4113
5320
|
const timeout = setTimeout(() => {
|
|
4114
5321
|
if (resolved) {
|
|
@@ -4123,13 +5330,18 @@ var BackgroundWorker = class {
|
|
|
4123
5330
|
if (message.type === "TASKS_READY" && !resolved) {
|
|
4124
5331
|
clearTimeout(timeout);
|
|
4125
5332
|
resolved = true;
|
|
4126
|
-
|
|
5333
|
+
resolve5(message.payload.tasks);
|
|
4127
5334
|
child.kill();
|
|
4128
5335
|
} else if (message.type === "UNCAUGHT_EXCEPTION") {
|
|
4129
5336
|
clearTimeout(timeout);
|
|
4130
5337
|
resolved = true;
|
|
4131
5338
|
reject(new UncaughtExceptionError(message.payload.error, message.payload.origin));
|
|
4132
5339
|
child.kill();
|
|
5340
|
+
} else if (message.type === "TASKS_FAILED_TO_PARSE") {
|
|
5341
|
+
clearTimeout(timeout);
|
|
5342
|
+
resolved = true;
|
|
5343
|
+
reject(new TaskMetadataParseError(message.payload.zodIssues, message.payload.tasks));
|
|
5344
|
+
child.kill();
|
|
4133
5345
|
}
|
|
4134
5346
|
});
|
|
4135
5347
|
child.on("exit", (code) => {
|
|
@@ -4139,6 +5351,9 @@ var BackgroundWorker = class {
|
|
|
4139
5351
|
reject(new Error(`Worker exited with code ${code}`));
|
|
4140
5352
|
}
|
|
4141
5353
|
});
|
|
5354
|
+
child.stdout?.on("data", (data) => {
|
|
5355
|
+
logger.log(data.toString());
|
|
5356
|
+
});
|
|
4142
5357
|
});
|
|
4143
5358
|
this._initialized = true;
|
|
4144
5359
|
}
|
|
@@ -4155,7 +5370,7 @@ var BackgroundWorker = class {
|
|
|
4155
5370
|
}
|
|
4156
5371
|
if (!this._taskRunProcesses.has(payload.execution.run.id)) {
|
|
4157
5372
|
const taskRunProcess = new TaskRunProcess(
|
|
4158
|
-
payload.execution
|
|
5373
|
+
payload.execution,
|
|
4159
5374
|
this.path,
|
|
4160
5375
|
{
|
|
4161
5376
|
...this.params.env,
|
|
@@ -4250,7 +5465,7 @@ var BackgroundWorker = class {
|
|
|
4250
5465
|
const result = {};
|
|
4251
5466
|
dotenv.config({
|
|
4252
5467
|
processEnv: result,
|
|
4253
|
-
path: [".env", ".env.local", ".env.development.local"].map((p) =>
|
|
5468
|
+
path: [".env", ".env.local", ".env.development.local"].map((p) => resolve3(process.cwd(), p))
|
|
4254
5469
|
});
|
|
4255
5470
|
process.env.TRIGGER_API_URL && (result.TRIGGER_API_URL = process.env.TRIGGER_API_URL);
|
|
4256
5471
|
delete result.TRIGGER_API_URL;
|
|
@@ -4265,9 +5480,9 @@ var BackgroundWorker = class {
|
|
|
4265
5480
|
}
|
|
4266
5481
|
};
|
|
4267
5482
|
var TaskRunProcess = class {
|
|
4268
|
-
constructor(
|
|
4269
|
-
this.
|
|
4270
|
-
this.path =
|
|
5483
|
+
constructor(execution, path7, env, metadata, worker) {
|
|
5484
|
+
this.execution = execution;
|
|
5485
|
+
this.path = path7;
|
|
4271
5486
|
this.env = env;
|
|
4272
5487
|
this.metadata = metadata;
|
|
4273
5488
|
this.worker = worker;
|
|
@@ -4297,9 +5512,20 @@ var TaskRunProcess = class {
|
|
|
4297
5512
|
await this.cleanup(true);
|
|
4298
5513
|
}
|
|
4299
5514
|
async initialize() {
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
5515
|
+
const fullEnv = {
|
|
5516
|
+
...this.execution.run.isTest ? { TRIGGER_LOG_LEVEL: "debug" } : {},
|
|
5517
|
+
...this.env,
|
|
5518
|
+
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
5519
|
+
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
5520
|
+
}),
|
|
5521
|
+
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
5522
|
+
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
5523
|
+
};
|
|
5524
|
+
const cwd = dirname2(this.path);
|
|
5525
|
+
logger.debug(`[${this.execution.run.id}] initializing task run process`, {
|
|
5526
|
+
env: fullEnv,
|
|
5527
|
+
path: this.path,
|
|
5528
|
+
cwd
|
|
4303
5529
|
});
|
|
4304
5530
|
this._child = fork(this.path, {
|
|
4305
5531
|
stdio: [
|
|
@@ -4311,15 +5537,8 @@ var TaskRunProcess = class {
|
|
|
4311
5537
|
"pipe",
|
|
4312
5538
|
"ipc"
|
|
4313
5539
|
],
|
|
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
|
-
},
|
|
5540
|
+
cwd,
|
|
5541
|
+
env: fullEnv,
|
|
4323
5542
|
execArgv: this.worker.debuggerOn ? ["--inspect-brk", "--trace-uncaught", "--no-warnings=ExperimentalWarning"] : ["--trace-uncaught", "--no-warnings=ExperimentalWarning"]
|
|
4324
5543
|
});
|
|
4325
5544
|
this._child.on("message", this.#handleMessage.bind(this));
|
|
@@ -4331,18 +5550,24 @@ var TaskRunProcess = class {
|
|
|
4331
5550
|
if (kill && this._isBeingKilled) {
|
|
4332
5551
|
return;
|
|
4333
5552
|
}
|
|
4334
|
-
logger.debug(`[${this.
|
|
5553
|
+
logger.debug(`[${this.execution.run.id}] cleaning up task run process`, { kill });
|
|
4335
5554
|
await this._sender.send("CLEANUP", {
|
|
4336
5555
|
flush: true,
|
|
4337
5556
|
kill
|
|
4338
5557
|
});
|
|
4339
5558
|
this._isBeingKilled = kill;
|
|
5559
|
+
setTimeout(() => {
|
|
5560
|
+
if (this._child && !this._child.killed) {
|
|
5561
|
+
logger.debug(`[${this.execution.run.id}] killing task run process after timeout`);
|
|
5562
|
+
this._child.kill();
|
|
5563
|
+
}
|
|
5564
|
+
}, 5e3);
|
|
4340
5565
|
}
|
|
4341
5566
|
async executeTaskRun(payload) {
|
|
4342
5567
|
let resolver;
|
|
4343
5568
|
let rejecter;
|
|
4344
|
-
const promise = new Promise((
|
|
4345
|
-
resolver =
|
|
5569
|
+
const promise = new Promise((resolve5, reject) => {
|
|
5570
|
+
resolver = resolve5;
|
|
4346
5571
|
rejecter = reject;
|
|
4347
5572
|
});
|
|
4348
5573
|
this._attemptStatuses.set(payload.execution.attempt.id, "PENDING");
|
|
@@ -4362,10 +5587,13 @@ var TaskRunProcess = class {
|
|
|
4362
5587
|
if (!completion.ok && typeof completion.retry !== "undefined") {
|
|
4363
5588
|
return;
|
|
4364
5589
|
}
|
|
4365
|
-
if (execution.run.id === this.
|
|
5590
|
+
if (execution.run.id === this.execution.run.id) {
|
|
4366
5591
|
return;
|
|
4367
5592
|
}
|
|
4368
|
-
logger.debug(`[${this.
|
|
5593
|
+
logger.debug(`[${this.execution.run.id}] task run completed notification`, {
|
|
5594
|
+
completion,
|
|
5595
|
+
execution
|
|
5596
|
+
});
|
|
4369
5597
|
this._sender.send("TASK_RUN_COMPLETED_NOTIFICATION", {
|
|
4370
5598
|
completion,
|
|
4371
5599
|
execution
|
|
@@ -4390,6 +5618,7 @@ var TaskRunProcess = class {
|
|
|
4390
5618
|
break;
|
|
4391
5619
|
}
|
|
4392
5620
|
case "READY_TO_DISPOSE": {
|
|
5621
|
+
logger.debug(`[${this.execution.run.id}] task run process is ready to dispose`);
|
|
4393
5622
|
this.#kill();
|
|
4394
5623
|
break;
|
|
4395
5624
|
}
|
|
@@ -4403,7 +5632,7 @@ var TaskRunProcess = class {
|
|
|
4403
5632
|
}
|
|
4404
5633
|
}
|
|
4405
5634
|
async #handleExit(code) {
|
|
4406
|
-
logger.debug(`[${this.
|
|
5635
|
+
logger.debug(`[${this.execution.run.id}] task run process exiting`, { code });
|
|
4407
5636
|
for (const [id, status] of this._attemptStatuses.entries()) {
|
|
4408
5637
|
if (status === "PENDING") {
|
|
4409
5638
|
this._attemptStatuses.set(id, "REJECTED");
|
|
@@ -4425,10 +5654,14 @@ var TaskRunProcess = class {
|
|
|
4425
5654
|
}
|
|
4426
5655
|
#handleLog(data) {
|
|
4427
5656
|
if (!this._currentExecution) {
|
|
5657
|
+
logger.log(`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4428
5658
|
return;
|
|
4429
5659
|
}
|
|
5660
|
+
const runId = chalkRun(
|
|
5661
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5662
|
+
);
|
|
4430
5663
|
logger.log(
|
|
4431
|
-
|
|
5664
|
+
`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4432
5665
|
);
|
|
4433
5666
|
}
|
|
4434
5667
|
#handleStdErr(data) {
|
|
@@ -4436,41 +5669,76 @@ var TaskRunProcess = class {
|
|
|
4436
5669
|
return;
|
|
4437
5670
|
}
|
|
4438
5671
|
if (!this._currentExecution) {
|
|
4439
|
-
logger.
|
|
5672
|
+
logger.log(`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4440
5673
|
return;
|
|
4441
5674
|
}
|
|
4442
|
-
|
|
4443
|
-
|
|
5675
|
+
const runId = chalkRun(
|
|
5676
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5677
|
+
);
|
|
5678
|
+
logger.log(
|
|
5679
|
+
`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4444
5680
|
);
|
|
4445
5681
|
}
|
|
4446
5682
|
#kill() {
|
|
4447
5683
|
if (this._child && !this._child.killed) {
|
|
5684
|
+
logger.debug(`[${this.execution.run.id}] killing task run process`);
|
|
4448
5685
|
this._child?.kill();
|
|
4449
5686
|
}
|
|
4450
5687
|
}
|
|
4451
5688
|
};
|
|
4452
5689
|
|
|
5690
|
+
// src/utilities/runtimeCheck.ts
|
|
5691
|
+
function runtimeCheck(minimumMajor, minimumMinor) {
|
|
5692
|
+
if (typeof process === "undefined") {
|
|
5693
|
+
throw "The dev CLI can only be run in a Node.js compatible environment";
|
|
5694
|
+
}
|
|
5695
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
5696
|
+
const isBun = typeof process.versions.bun === "string";
|
|
5697
|
+
if (major < minimumMajor || major === minimumMajor && minor < minimumMinor) {
|
|
5698
|
+
if (isBun) {
|
|
5699
|
+
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}`;
|
|
5700
|
+
} else {
|
|
5701
|
+
throw `The dev CLI requires at least Node.js ${minimumMajor}.${minimumMinor}. You are running Node.js ${process.versions.node}`;
|
|
5702
|
+
}
|
|
5703
|
+
}
|
|
5704
|
+
logger.debug(
|
|
5705
|
+
`Node.js version: ${process.versions.node}${isBun ? ` (Bun ${process.versions.bun})` : ""}`
|
|
5706
|
+
);
|
|
5707
|
+
}
|
|
5708
|
+
|
|
4453
5709
|
// src/commands/dev.tsx
|
|
5710
|
+
import { findUp as findUp3, pathExists as pathExists2 } from "find-up";
|
|
5711
|
+
import { esbuildDecorators as esbuildDecorators3 } from "@anatine/esbuild-decorators";
|
|
4454
5712
|
var apiClient;
|
|
4455
5713
|
var DevCommandOptions = CommonCommandOptions.extend({
|
|
4456
5714
|
debugger: z5.boolean().default(false),
|
|
4457
5715
|
debugOtel: z5.boolean().default(false),
|
|
4458
5716
|
config: z5.string().optional(),
|
|
4459
|
-
projectRef: z5.string().optional()
|
|
5717
|
+
projectRef: z5.string().optional(),
|
|
5718
|
+
skipUpdateCheck: z5.boolean().default(false)
|
|
4460
5719
|
});
|
|
4461
5720
|
function configureDevCommand(program2) {
|
|
4462
5721
|
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(
|
|
5722
|
+
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
5723
|
"-p, --project-ref <project ref>",
|
|
4465
5724
|
"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 (
|
|
5725
|
+
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging").option("--skip-update-check", "Skip checking for @trigger.dev package updates")
|
|
5726
|
+
).action(async (path7, options) => {
|
|
4468
5727
|
wrapCommandAction("dev", DevCommandOptions, options, async (opts) => {
|
|
4469
|
-
await devCommand(
|
|
5728
|
+
await devCommand(path7, opts);
|
|
4470
5729
|
});
|
|
4471
5730
|
});
|
|
4472
5731
|
}
|
|
5732
|
+
var MINIMUM_NODE_MAJOR = 18;
|
|
5733
|
+
var MINIMUM_NODE_MINOR = 16;
|
|
4473
5734
|
async function devCommand(dir, options) {
|
|
5735
|
+
try {
|
|
5736
|
+
runtimeCheck(MINIMUM_NODE_MAJOR, MINIMUM_NODE_MINOR);
|
|
5737
|
+
} catch (e) {
|
|
5738
|
+
logger.log(`${chalkError("X Error:")} ${e}`);
|
|
5739
|
+
process.exitCode = 1;
|
|
5740
|
+
return;
|
|
5741
|
+
}
|
|
4474
5742
|
const authorization = await isLoggedIn(options.profile);
|
|
4475
5743
|
if (!authorization.ok) {
|
|
4476
5744
|
if (authorization.error === "fetch failed") {
|
|
@@ -4485,40 +5753,48 @@ async function devCommand(dir, options) {
|
|
|
4485
5753
|
process.exitCode = 1;
|
|
4486
5754
|
return;
|
|
4487
5755
|
}
|
|
4488
|
-
const devInstance = await startDev(dir, options, authorization.auth);
|
|
5756
|
+
const devInstance = await startDev(dir, options, authorization.auth, authorization.dashboardUrl);
|
|
4489
5757
|
const { waitUntilExit } = devInstance.devReactElement;
|
|
4490
5758
|
await waitUntilExit();
|
|
4491
5759
|
}
|
|
4492
|
-
async function startDev(dir, options, authorization) {
|
|
5760
|
+
async function startDev(dir, options, authorization, dashboardUrl) {
|
|
4493
5761
|
let rerender;
|
|
4494
5762
|
try {
|
|
4495
5763
|
if (options.logLevel) {
|
|
4496
5764
|
logger.loggerLevel = options.logLevel;
|
|
4497
5765
|
}
|
|
4498
5766
|
await printStandloneInitialBanner(true);
|
|
4499
|
-
|
|
5767
|
+
let displayedUpdateMessage = false;
|
|
5768
|
+
if (!options.skipUpdateCheck) {
|
|
5769
|
+
displayedUpdateMessage = await updateTriggerPackages(dir, { ...options }, true, true);
|
|
5770
|
+
}
|
|
5771
|
+
printDevBanner(displayedUpdateMessage);
|
|
4500
5772
|
logger.debug("Starting dev session", { dir, options, authorization });
|
|
4501
5773
|
let config = await readConfig(dir, {
|
|
4502
5774
|
projectRef: options.projectRef,
|
|
4503
5775
|
configFile: options.config
|
|
4504
5776
|
});
|
|
4505
5777
|
logger.debug("Initial config", { config });
|
|
5778
|
+
if (config.status === "error") {
|
|
5779
|
+
logger.error("Failed to read config", config.error);
|
|
5780
|
+
process.exit(1);
|
|
5781
|
+
}
|
|
4506
5782
|
async function getDevReactElement(configParam, authorization2, configPath) {
|
|
4507
5783
|
const accessToken = authorization2.accessToken;
|
|
4508
5784
|
const apiUrl = authorization2.apiUrl;
|
|
4509
5785
|
apiClient = new CliApiClient(apiUrl, accessToken);
|
|
4510
5786
|
const devEnv = await apiClient.getProjectEnv({
|
|
4511
|
-
projectRef:
|
|
5787
|
+
projectRef: configParam.project,
|
|
4512
5788
|
env: "dev"
|
|
4513
5789
|
});
|
|
4514
5790
|
if (!devEnv.success) {
|
|
4515
5791
|
if (devEnv.error === "Project not found") {
|
|
4516
5792
|
logger.error(
|
|
4517
|
-
`Project not found: ${
|
|
5793
|
+
`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
5794
|
);
|
|
4519
5795
|
} else {
|
|
4520
5796
|
logger.error(
|
|
4521
|
-
`Failed to initialize dev environment: ${devEnv.error}. Using project ref ${
|
|
5797
|
+
`Failed to initialize dev environment: ${devEnv.error}. Using project ref ${configParam.project}`
|
|
4522
5798
|
);
|
|
4523
5799
|
}
|
|
4524
5800
|
process.exit(1);
|
|
@@ -4527,6 +5803,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4527
5803
|
return /* @__PURE__ */ React.createElement(
|
|
4528
5804
|
DevUI,
|
|
4529
5805
|
{
|
|
5806
|
+
dashboardUrl,
|
|
4530
5807
|
config: configParam,
|
|
4531
5808
|
apiUrl,
|
|
4532
5809
|
apiKey: devEnv.data.apiKey,
|
|
@@ -4558,6 +5835,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4558
5835
|
}
|
|
4559
5836
|
function useDev({
|
|
4560
5837
|
config,
|
|
5838
|
+
dashboardUrl,
|
|
4561
5839
|
apiUrl,
|
|
4562
5840
|
apiKey,
|
|
4563
5841
|
environmentClient,
|
|
@@ -4587,7 +5865,7 @@ function useDev({
|
|
|
4587
5865
|
}
|
|
4588
5866
|
});
|
|
4589
5867
|
const backgroundWorkerCoordinator = new BackgroundWorkerCoordinator(
|
|
4590
|
-
`${
|
|
5868
|
+
`${dashboardUrl}/projects/v3/${config.project}`
|
|
4591
5869
|
);
|
|
4592
5870
|
websocket.addEventListener("open", async (event) => {
|
|
4593
5871
|
});
|
|
@@ -4659,22 +5937,21 @@ function useDev({
|
|
|
4659
5937
|
}
|
|
4660
5938
|
let latestWorkerContentHash;
|
|
4661
5939
|
const taskFiles = await gatherTaskFiles(config);
|
|
4662
|
-
const
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
"
|
|
5940
|
+
const workerFacadePath = join7(cliRootPath(), "workers", "dev", "worker-facade.js");
|
|
5941
|
+
const workerFacade = readFileSync3(workerFacadePath, "utf-8");
|
|
5942
|
+
const workerSetupPath = join7(cliRootPath(), "workers", "dev", "worker-setup.js");
|
|
5943
|
+
let entryPointContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
5944
|
+
"__WORKER_SETUP__",
|
|
5945
|
+
`import { tracingSDK, sender } from "${escapeImportPath(workerSetupPath)}";`
|
|
4668
5946
|
);
|
|
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
5947
|
if (configPath) {
|
|
5948
|
+
configPath = normalize(configPath);
|
|
4674
5949
|
logger.debug("Importing project config from", { configPath });
|
|
4675
5950
|
entryPointContents = entryPointContents.replace(
|
|
4676
5951
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
4677
|
-
`import * as importedConfigExports from "${
|
|
5952
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
5953
|
+
configPath
|
|
5954
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
4678
5955
|
);
|
|
4679
5956
|
} else {
|
|
4680
5957
|
entryPointContents = entryPointContents.replace(
|
|
@@ -4690,6 +5967,9 @@ function useDev({
|
|
|
4690
5967
|
resolveDir: process.cwd(),
|
|
4691
5968
|
sourcefile: "__entryPoint.ts"
|
|
4692
5969
|
},
|
|
5970
|
+
banner: {
|
|
5971
|
+
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" }); } });`
|
|
5972
|
+
},
|
|
4693
5973
|
bundle: true,
|
|
4694
5974
|
metafile: true,
|
|
4695
5975
|
write: false,
|
|
@@ -4707,12 +5987,19 @@ function useDev({
|
|
|
4707
5987
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
4708
5988
|
},
|
|
4709
5989
|
plugins: [
|
|
5990
|
+
mockServerOnlyPlugin(),
|
|
5991
|
+
bundleTriggerDevCore("workerFacade", config.tsconfigPath),
|
|
4710
5992
|
bundleDependenciesPlugin(
|
|
4711
5993
|
"workerFacade",
|
|
4712
5994
|
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
|
|
4713
5995
|
config.tsconfigPath
|
|
4714
5996
|
),
|
|
4715
5997
|
workerSetupImportConfigPlugin(configPath),
|
|
5998
|
+
esbuildDecorators3({
|
|
5999
|
+
tsconfig: config.tsconfigPath,
|
|
6000
|
+
tsx: true,
|
|
6001
|
+
force: false
|
|
6002
|
+
}),
|
|
4716
6003
|
{
|
|
4717
6004
|
name: "trigger.dev v3",
|
|
4718
6005
|
setup(build3) {
|
|
@@ -4726,19 +6013,19 @@ function useDev({
|
|
|
4726
6013
|
if (!firstBuild) {
|
|
4727
6014
|
logger.log(chalkGrey("\u25CB Building background worker\u2026"));
|
|
4728
6015
|
}
|
|
4729
|
-
const metaOutputKey =
|
|
6016
|
+
const metaOutputKey = join7("out", `stdin.js`).replace(/\\/g, "/");
|
|
4730
6017
|
const metaOutput = result.metafile.outputs[metaOutputKey];
|
|
4731
6018
|
if (!metaOutput) {
|
|
4732
6019
|
throw new Error(`Could not find metafile`);
|
|
4733
6020
|
}
|
|
4734
|
-
const outputFileKey =
|
|
6021
|
+
const outputFileKey = join7(config.projectDir, metaOutputKey);
|
|
4735
6022
|
const outputFile = result.outputFiles.find((file) => file.path === outputFileKey);
|
|
4736
6023
|
if (!outputFile) {
|
|
4737
6024
|
throw new Error(
|
|
4738
6025
|
`Could not find output file for entry point ${metaOutput.entryPoint}`
|
|
4739
6026
|
);
|
|
4740
6027
|
}
|
|
4741
|
-
const sourceMapFileKey =
|
|
6028
|
+
const sourceMapFileKey = join7(config.projectDir, `${metaOutputKey}.map`);
|
|
4742
6029
|
const sourceMapFile = result.outputFiles.find(
|
|
4743
6030
|
(file) => file.path === sourceMapFileKey
|
|
4744
6031
|
);
|
|
@@ -4749,20 +6036,20 @@ function useDev({
|
|
|
4749
6036
|
logger.log(chalkGrey("\u25CB No changes detected, skipping build\u2026"));
|
|
4750
6037
|
return;
|
|
4751
6038
|
}
|
|
4752
|
-
const fullPath =
|
|
6039
|
+
const fullPath = join7(config.projectDir, ".trigger", `${contentHash}.js`);
|
|
4753
6040
|
const sourceMapPath = `${fullPath}.map`;
|
|
4754
6041
|
const outputFileWithSourceMap = `${outputFile.text}
|
|
4755
|
-
//# sourceMappingURL=${
|
|
6042
|
+
//# sourceMappingURL=${basename2(sourceMapPath)}`;
|
|
4756
6043
|
await fs7.promises.mkdir(dirname3(fullPath), { recursive: true });
|
|
4757
6044
|
await fs7.promises.writeFile(fullPath, outputFileWithSourceMap);
|
|
4758
6045
|
logger.debug(`Wrote background worker to ${fullPath}`);
|
|
4759
|
-
const dependencies2 = await
|
|
6046
|
+
const dependencies2 = await gatherRequiredDependencies(metaOutput, config);
|
|
4760
6047
|
if (sourceMapFile) {
|
|
4761
6048
|
const sourceMapPath2 = `${fullPath}.map`;
|
|
4762
6049
|
await fs7.promises.writeFile(sourceMapPath2, sourceMapFile.text);
|
|
4763
6050
|
}
|
|
4764
6051
|
const environmentVariablesResponse = await environmentClient.getEnvironmentVariables(config.project);
|
|
4765
|
-
const processEnv = gatherProcessEnv();
|
|
6052
|
+
const processEnv = await gatherProcessEnv();
|
|
4766
6053
|
const backgroundWorker = new BackgroundWorker(fullPath, {
|
|
4767
6054
|
projectConfig: config,
|
|
4768
6055
|
dependencies: dependencies2,
|
|
@@ -4780,8 +6067,15 @@ function useDev({
|
|
|
4780
6067
|
latestWorkerContentHash = contentHash;
|
|
4781
6068
|
let packageVersion;
|
|
4782
6069
|
const taskResources = [];
|
|
4783
|
-
if (!backgroundWorker.tasks) {
|
|
4784
|
-
|
|
6070
|
+
if (!backgroundWorker.tasks || backgroundWorker.tasks.length === 0) {
|
|
6071
|
+
logger.log(
|
|
6072
|
+
`${chalkError(
|
|
6073
|
+
"X Error:"
|
|
6074
|
+
)} Worker failed to build: no tasks found. Searched in ${config.triggerDirectories.join(
|
|
6075
|
+
", "
|
|
6076
|
+
)}`
|
|
6077
|
+
);
|
|
6078
|
+
return;
|
|
4785
6079
|
}
|
|
4786
6080
|
for (const task of backgroundWorker.tasks) {
|
|
4787
6081
|
taskResources.push(task);
|
|
@@ -4800,6 +6094,9 @@ function useDev({
|
|
|
4800
6094
|
);
|
|
4801
6095
|
return;
|
|
4802
6096
|
}
|
|
6097
|
+
logger.debug("Creating background worker with tasks", {
|
|
6098
|
+
tasks: taskResources
|
|
6099
|
+
});
|
|
4803
6100
|
const backgroundWorkerBody = {
|
|
4804
6101
|
localOnly: true,
|
|
4805
6102
|
metadata: {
|
|
@@ -4830,17 +6127,52 @@ function useDev({
|
|
|
4830
6127
|
backgroundWorker
|
|
4831
6128
|
);
|
|
4832
6129
|
} catch (e) {
|
|
4833
|
-
if (e instanceof
|
|
4834
|
-
|
|
4835
|
-
|
|
6130
|
+
if (e instanceof TaskMetadataParseError) {
|
|
6131
|
+
logTaskMetadataParseError(e.zodIssues, e.tasks);
|
|
6132
|
+
return;
|
|
6133
|
+
} else if (e instanceof UncaughtExceptionError) {
|
|
6134
|
+
const parsedBuildError = parseBuildErrorStack(e.originalError);
|
|
6135
|
+
if (parsedBuildError && typeof parsedBuildError !== "string") {
|
|
6136
|
+
logESMRequireError(
|
|
6137
|
+
parsedBuildError,
|
|
6138
|
+
configPath ? { status: "file", path: configPath, config } : { status: "in-memory", config }
|
|
6139
|
+
);
|
|
6140
|
+
return;
|
|
6141
|
+
} else {
|
|
6142
|
+
}
|
|
6143
|
+
if (e.originalError.message || e.originalError.stack) {
|
|
6144
|
+
logger.log(
|
|
6145
|
+
`${chalkError("X Error:")} Worker failed to start`,
|
|
6146
|
+
e.originalError.stack ?? e.originalError.message
|
|
6147
|
+
);
|
|
4836
6148
|
}
|
|
4837
6149
|
return;
|
|
4838
6150
|
}
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
6151
|
+
const parsedError = parseNpmInstallError(e);
|
|
6152
|
+
if (typeof parsedError === "string") {
|
|
6153
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
6154
|
+
} else {
|
|
6155
|
+
switch (parsedError.type) {
|
|
6156
|
+
case "package-not-found-error": {
|
|
6157
|
+
logger.log(
|
|
6158
|
+
`
|
|
6159
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
6160
|
+
parsedError.packageName
|
|
6161
|
+
)} could not be found in the npm registry.`
|
|
6162
|
+
);
|
|
6163
|
+
break;
|
|
6164
|
+
}
|
|
6165
|
+
case "no-matching-version-error": {
|
|
6166
|
+
logger.log(
|
|
6167
|
+
`
|
|
6168
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
6169
|
+
parsedError.packageName
|
|
6170
|
+
)} could not resolve because the version doesn't exist`
|
|
6171
|
+
);
|
|
6172
|
+
break;
|
|
6173
|
+
}
|
|
6174
|
+
}
|
|
4842
6175
|
}
|
|
4843
|
-
logger.error(`Background worker failed to start: ${e}`);
|
|
4844
6176
|
}
|
|
4845
6177
|
});
|
|
4846
6178
|
}
|
|
@@ -4851,17 +6183,17 @@ function useDev({
|
|
|
4851
6183
|
}
|
|
4852
6184
|
const throttledRebuild = pDebounce(runBuild, 250, { before: true });
|
|
4853
6185
|
const taskFileWatcher = watch(
|
|
4854
|
-
config.triggerDirectories.map((triggerDir) => `${triggerDir}
|
|
6186
|
+
config.triggerDirectories.map((triggerDir) => `${triggerDir}/**/*.ts`),
|
|
4855
6187
|
{
|
|
4856
6188
|
ignoreInitial: true
|
|
4857
6189
|
}
|
|
4858
6190
|
);
|
|
4859
|
-
taskFileWatcher.on("add", async (
|
|
6191
|
+
taskFileWatcher.on("add", async (path7) => {
|
|
4860
6192
|
throttledRebuild().catch((error) => {
|
|
4861
6193
|
logger.error(error);
|
|
4862
6194
|
});
|
|
4863
6195
|
});
|
|
4864
|
-
taskFileWatcher.on("unlink", async (
|
|
6196
|
+
taskFileWatcher.on("unlink", async (path7) => {
|
|
4865
6197
|
throttledRebuild().catch((error) => {
|
|
4866
6198
|
logger.error(error);
|
|
4867
6199
|
});
|
|
@@ -4902,7 +6234,7 @@ function WebsocketFactory(apiKey) {
|
|
|
4902
6234
|
}
|
|
4903
6235
|
};
|
|
4904
6236
|
}
|
|
4905
|
-
async function
|
|
6237
|
+
async function gatherRequiredDependencies(outputMeta, config) {
|
|
4906
6238
|
const dependencies2 = {};
|
|
4907
6239
|
logger.debug("Gathering required dependencies from imports", {
|
|
4908
6240
|
imports: outputMeta.imports
|
|
@@ -4921,7 +6253,7 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4921
6253
|
}
|
|
4922
6254
|
}
|
|
4923
6255
|
if (config.additionalPackages) {
|
|
4924
|
-
const projectPackageJson = await readJSONFile(
|
|
6256
|
+
const projectPackageJson = await readJSONFile(join7(config.projectDir, "package.json"));
|
|
4925
6257
|
for (const packageName of config.additionalPackages) {
|
|
4926
6258
|
if (dependencies2[packageName]) {
|
|
4927
6259
|
continue;
|
|
@@ -4958,7 +6290,7 @@ ${task.filePath} -> ${task.exportName}`).join("")}`;
|
|
|
4958
6290
|
}).join("");
|
|
4959
6291
|
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
|
|
4960
6292
|
}
|
|
4961
|
-
function gatherProcessEnv() {
|
|
6293
|
+
async function gatherProcessEnv() {
|
|
4962
6294
|
const env = {
|
|
4963
6295
|
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
4964
6296
|
PATH: process.env.PATH,
|
|
@@ -4969,31 +6301,54 @@ function gatherProcessEnv() {
|
|
|
4969
6301
|
NVM_BIN: process.env.NVM_BIN,
|
|
4970
6302
|
LANG: process.env.LANG,
|
|
4971
6303
|
TERM: process.env.TERM,
|
|
4972
|
-
NODE_PATH: process.env.NODE_PATH,
|
|
6304
|
+
NODE_PATH: await amendNodePathWithPnpmNodeModules(process.env.NODE_PATH),
|
|
4973
6305
|
HOME: process.env.HOME,
|
|
4974
6306
|
BUN_INSTALL: process.env.BUN_INSTALL
|
|
4975
6307
|
};
|
|
4976
6308
|
return Object.fromEntries(Object.entries(env).filter(([key, value]) => value !== void 0));
|
|
4977
6309
|
}
|
|
6310
|
+
async function amendNodePathWithPnpmNodeModules(nodePath) {
|
|
6311
|
+
const pnpmModulesPath = await findPnpmNodeModulesPath();
|
|
6312
|
+
if (!pnpmModulesPath) {
|
|
6313
|
+
return nodePath;
|
|
6314
|
+
}
|
|
6315
|
+
if (nodePath) {
|
|
6316
|
+
if (nodePath.includes(pnpmModulesPath)) {
|
|
6317
|
+
return nodePath;
|
|
6318
|
+
}
|
|
6319
|
+
return `${nodePath}:${pnpmModulesPath}`;
|
|
6320
|
+
}
|
|
6321
|
+
return pnpmModulesPath;
|
|
6322
|
+
}
|
|
6323
|
+
async function findPnpmNodeModulesPath() {
|
|
6324
|
+
return await findUp3(
|
|
6325
|
+
async (directory) => {
|
|
6326
|
+
const pnpmModules = join7(directory, "node_modules", ".pnpm", "node_modules");
|
|
6327
|
+
const hasPnpmNodeModules = await pathExists2(pnpmModules);
|
|
6328
|
+
if (hasPnpmNodeModules) {
|
|
6329
|
+
return pnpmModules;
|
|
6330
|
+
}
|
|
6331
|
+
},
|
|
6332
|
+
{ type: "directory" }
|
|
6333
|
+
);
|
|
6334
|
+
}
|
|
4978
6335
|
|
|
4979
6336
|
// src/commands/init.ts
|
|
4980
|
-
import { intro as
|
|
6337
|
+
import { intro as intro5, isCancel as isCancel2, log as log6, outro as outro6, select as select2, text } from "@clack/prompts";
|
|
4981
6338
|
import { context as context3, trace as trace3 } from "@opentelemetry/api";
|
|
4982
|
-
import {
|
|
4983
|
-
|
|
4984
|
-
recordSpanException as recordSpanException5
|
|
4985
|
-
} from "@trigger.dev/core/v3";
|
|
6339
|
+
import { flattenAttributes as flattenAttributes4 } from "@trigger.dev/core/v3";
|
|
6340
|
+
import { recordSpanException as recordSpanException6 } from "@trigger.dev/core/v3/workers";
|
|
4986
6341
|
import chalk5 from "chalk";
|
|
4987
6342
|
import { execa as execa3 } from "execa";
|
|
4988
6343
|
import { applyEdits, modify } from "jsonc-parser";
|
|
4989
6344
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
4990
|
-
import { join as
|
|
4991
|
-
import
|
|
6345
|
+
import { join as join8, relative as relative4, resolve as resolve4 } from "node:path";
|
|
6346
|
+
import terminalLink4 from "terminal-link";
|
|
4992
6347
|
import { z as z6 } from "zod";
|
|
4993
6348
|
|
|
4994
6349
|
// src/utilities/createFileFromTemplate.ts
|
|
4995
6350
|
import fs8 from "fs/promises";
|
|
4996
|
-
import
|
|
6351
|
+
import path6 from "path";
|
|
4997
6352
|
async function createFileFromTemplate(params) {
|
|
4998
6353
|
let template = await readFile(params.templatePath);
|
|
4999
6354
|
if (await pathExists(params.outputPath) && !params.override) {
|
|
@@ -5004,7 +6359,7 @@ async function createFileFromTemplate(params) {
|
|
|
5004
6359
|
}
|
|
5005
6360
|
try {
|
|
5006
6361
|
const output = replaceAll(template, params.replacements);
|
|
5007
|
-
const directoryName =
|
|
6362
|
+
const directoryName = path6.dirname(params.outputPath);
|
|
5008
6363
|
await fs8.mkdir(directoryName, { recursive: true });
|
|
5009
6364
|
await fs8.writeFile(params.outputPath, output);
|
|
5010
6365
|
return {
|
|
@@ -5032,51 +6387,6 @@ function replaceAll(input, replacements) {
|
|
|
5032
6387
|
return output;
|
|
5033
6388
|
}
|
|
5034
6389
|
|
|
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
6390
|
// src/commands/init.ts
|
|
5081
6391
|
var InitCommandOptions = CommonCommandOptions.extend({
|
|
5082
6392
|
projectRef: z6.string().optional(),
|
|
@@ -5094,10 +6404,10 @@ function configureInitCommand(program2) {
|
|
|
5094
6404
|
"The version of the @trigger.dev/sdk package to install",
|
|
5095
6405
|
"beta"
|
|
5096
6406
|
).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 (
|
|
6407
|
+
).action(async (path7, options) => {
|
|
5098
6408
|
await handleTelemetry(async () => {
|
|
5099
6409
|
await printStandloneInitialBanner(true);
|
|
5100
|
-
await initCommand(
|
|
6410
|
+
await initCommand(path7, options);
|
|
5101
6411
|
});
|
|
5102
6412
|
});
|
|
5103
6413
|
}
|
|
@@ -5108,7 +6418,7 @@ async function initCommand(dir, options) {
|
|
|
5108
6418
|
}
|
|
5109
6419
|
async function _initCommand(dir, options) {
|
|
5110
6420
|
const span = trace3.getSpan(context3.active());
|
|
5111
|
-
|
|
6421
|
+
intro5("Initializing project");
|
|
5112
6422
|
const authorization = await login({
|
|
5113
6423
|
embedded: true,
|
|
5114
6424
|
defaultApiUrl: options.apiUrl,
|
|
@@ -5132,7 +6442,7 @@ async function _initCommand(dir, options) {
|
|
|
5132
6442
|
if (!options.overrideConfig) {
|
|
5133
6443
|
try {
|
|
5134
6444
|
const result = await readConfig(dir);
|
|
5135
|
-
|
|
6445
|
+
outro6(
|
|
5136
6446
|
result.status === "file" ? `Project already initialized: Found config file at ${result.path}. Pass --override-config to override` : "Project already initialized"
|
|
5137
6447
|
);
|
|
5138
6448
|
return;
|
|
@@ -5146,58 +6456,59 @@ async function _initCommand(dir, options) {
|
|
|
5146
6456
|
options.projectRef
|
|
5147
6457
|
);
|
|
5148
6458
|
span?.setAttributes({
|
|
5149
|
-
...
|
|
6459
|
+
...flattenAttributes4(selectedProject, "cli.project")
|
|
5150
6460
|
});
|
|
5151
6461
|
logger.debug("Selected project", selectedProject);
|
|
5152
|
-
|
|
6462
|
+
log6.step(`Configuring project "${selectedProject.name}" (${selectedProject.externalRef})`);
|
|
5153
6463
|
if (!options.skipPackageInstall) {
|
|
5154
6464
|
await installPackages2(dir, options);
|
|
5155
6465
|
} else {
|
|
5156
|
-
|
|
6466
|
+
log6.info("Skipping package installation");
|
|
5157
6467
|
}
|
|
5158
6468
|
const triggerDir = await createTriggerDir(dir, options);
|
|
5159
6469
|
await writeConfigFile(dir, selectedProject, options, triggerDir);
|
|
5160
6470
|
await addConfigFileToTsConfig(dir, options);
|
|
5161
6471
|
await gitIgnoreDotTriggerDir(dir, options);
|
|
5162
|
-
const projectDashboard =
|
|
6472
|
+
const projectDashboard = terminalLink4(
|
|
5163
6473
|
"project dashboard",
|
|
5164
6474
|
`${authorization.dashboardUrl}/projects/v3/${selectedProject.externalRef}`
|
|
5165
6475
|
);
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
6476
|
+
log6.success("Successfully initialized project for Trigger.dev v3 \u{1FAE1}");
|
|
6477
|
+
log6.info("Next steps:");
|
|
6478
|
+
log6.info(
|
|
5169
6479
|
` 1. To start developing, run ${chalk5.green(
|
|
5170
6480
|
`npx trigger.dev@${options.tag} dev`
|
|
5171
6481
|
)} in your project directory`
|
|
5172
6482
|
);
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
` 3. Head over to our ${
|
|
6483
|
+
log6.info(` 2. Visit your ${projectDashboard} to view your newly created tasks.`);
|
|
6484
|
+
log6.info(
|
|
6485
|
+
` 3. Head over to our ${terminalLink4(
|
|
5176
6486
|
"v3 docs",
|
|
5177
6487
|
"https://trigger.dev/docs/v3"
|
|
5178
6488
|
)} to learn more.`
|
|
5179
6489
|
);
|
|
5180
|
-
|
|
5181
|
-
` 4. Need help? Join our ${
|
|
6490
|
+
log6.info(
|
|
6491
|
+
` 4. Need help? Join our ${terminalLink4(
|
|
5182
6492
|
"Discord community",
|
|
5183
6493
|
"https://trigger.dev/discord"
|
|
5184
6494
|
)} or email us at ${chalk5.cyan("help@trigger.dev")}`
|
|
5185
6495
|
);
|
|
5186
|
-
|
|
6496
|
+
outro6(`Project initialized successfully. Happy coding!`);
|
|
5187
6497
|
}
|
|
5188
6498
|
async function createTriggerDir(dir, options) {
|
|
5189
6499
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5190
6500
|
try {
|
|
5191
|
-
const defaultValue =
|
|
6501
|
+
const defaultValue = join8(dir, "src", "trigger");
|
|
5192
6502
|
const location = await text({
|
|
5193
6503
|
message: "Where would you like to create the Trigger.dev directory?",
|
|
5194
6504
|
defaultValue,
|
|
5195
6505
|
placeholder: defaultValue
|
|
5196
6506
|
});
|
|
5197
|
-
if (
|
|
6507
|
+
if (isCancel2(location)) {
|
|
5198
6508
|
throw new OutroCommandError();
|
|
5199
6509
|
}
|
|
5200
|
-
const triggerDir =
|
|
6510
|
+
const triggerDir = resolve4(process.cwd(), location);
|
|
6511
|
+
logger.debug({ triggerDir });
|
|
5201
6512
|
span.setAttributes({
|
|
5202
6513
|
"cli.triggerDir": triggerDir
|
|
5203
6514
|
});
|
|
@@ -5215,7 +6526,7 @@ async function createTriggerDir(dir, options) {
|
|
|
5215
6526
|
}
|
|
5216
6527
|
]
|
|
5217
6528
|
});
|
|
5218
|
-
if (
|
|
6529
|
+
if (isCancel2(exampleSelection)) {
|
|
5219
6530
|
throw new OutroCommandError();
|
|
5220
6531
|
}
|
|
5221
6532
|
const example = exampleSelection;
|
|
@@ -5223,25 +6534,25 @@ async function createTriggerDir(dir, options) {
|
|
|
5223
6534
|
"cli.example": example
|
|
5224
6535
|
});
|
|
5225
6536
|
if (example === "none") {
|
|
5226
|
-
await createFile(
|
|
5227
|
-
|
|
6537
|
+
await createFile(join8(triggerDir, ".gitkeep"), "");
|
|
6538
|
+
log6.step(`Created directory at ${location}`);
|
|
5228
6539
|
span.end();
|
|
5229
6540
|
return { location, isCustomValue: location !== defaultValue };
|
|
5230
6541
|
}
|
|
5231
|
-
const
|
|
5232
|
-
const outputPath =
|
|
6542
|
+
const templatePath = join8(cliRootPath(), "templates", "examples", `${example}.ts.template`);
|
|
6543
|
+
const outputPath = join8(triggerDir, "example.ts");
|
|
5233
6544
|
await createFileFromTemplate({
|
|
5234
|
-
templatePath
|
|
6545
|
+
templatePath,
|
|
5235
6546
|
outputPath,
|
|
5236
6547
|
replacements: {}
|
|
5237
6548
|
});
|
|
5238
|
-
const relativeOutputPath =
|
|
5239
|
-
|
|
6549
|
+
const relativeOutputPath = relative4(process.cwd(), outputPath);
|
|
6550
|
+
log6.step(`Created example file at ${relativeOutputPath}`);
|
|
5240
6551
|
span.end();
|
|
5241
6552
|
return { location, isCustomValue: location !== defaultValue };
|
|
5242
6553
|
} catch (e) {
|
|
5243
6554
|
if (!(e instanceof SkipCommandError)) {
|
|
5244
|
-
|
|
6555
|
+
recordSpanException6(span, e);
|
|
5245
6556
|
}
|
|
5246
6557
|
span.end();
|
|
5247
6558
|
throw e;
|
|
@@ -5251,15 +6562,15 @@ async function createTriggerDir(dir, options) {
|
|
|
5251
6562
|
async function gitIgnoreDotTriggerDir(dir, options) {
|
|
5252
6563
|
return await tracer.startActiveSpan("gitIgnoreDotTriggerDir", async (span) => {
|
|
5253
6564
|
try {
|
|
5254
|
-
const projectDir =
|
|
5255
|
-
const gitIgnorePath =
|
|
6565
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6566
|
+
const gitIgnorePath = join8(projectDir, ".gitignore");
|
|
5256
6567
|
span.setAttributes({
|
|
5257
6568
|
"cli.projectDir": projectDir,
|
|
5258
6569
|
"cli.gitIgnorePath": gitIgnorePath
|
|
5259
6570
|
});
|
|
5260
6571
|
if (!await pathExists(gitIgnorePath)) {
|
|
5261
6572
|
await createFile(gitIgnorePath, ".trigger");
|
|
5262
|
-
|
|
6573
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5263
6574
|
span.end();
|
|
5264
6575
|
return;
|
|
5265
6576
|
}
|
|
@@ -5271,11 +6582,11 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5271
6582
|
const newGitIgnoreContent = `${gitIgnoreContent}
|
|
5272
6583
|
.trigger`;
|
|
5273
6584
|
await writeFile3(gitIgnorePath, newGitIgnoreContent, "utf-8");
|
|
5274
|
-
|
|
6585
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5275
6586
|
span.end();
|
|
5276
6587
|
} catch (e) {
|
|
5277
6588
|
if (!(e instanceof SkipCommandError)) {
|
|
5278
|
-
|
|
6589
|
+
recordSpanException6(span, e);
|
|
5279
6590
|
}
|
|
5280
6591
|
span.end();
|
|
5281
6592
|
throw e;
|
|
@@ -5285,8 +6596,8 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5285
6596
|
async function addConfigFileToTsConfig(dir, options) {
|
|
5286
6597
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5287
6598
|
try {
|
|
5288
|
-
const projectDir =
|
|
5289
|
-
const tsconfigPath =
|
|
6599
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6600
|
+
const tsconfigPath = join8(projectDir, "tsconfig.json");
|
|
5290
6601
|
span.setAttributes({
|
|
5291
6602
|
"cli.projectDir": projectDir,
|
|
5292
6603
|
"cli.tsconfigPath": tsconfigPath
|
|
@@ -5304,11 +6615,11 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5304
6615
|
const newTsconfigContent = applyEdits(tsconfigContent, edits);
|
|
5305
6616
|
logger.debug("new tsconfig.json content", { newTsconfigContent });
|
|
5306
6617
|
await writeFile3(tsconfigPath, newTsconfigContent, "utf-8");
|
|
5307
|
-
|
|
6618
|
+
log6.step(`Added trigger.config.ts to tsconfig.json`);
|
|
5308
6619
|
span.end();
|
|
5309
6620
|
} catch (e) {
|
|
5310
6621
|
if (!(e instanceof SkipCommandError)) {
|
|
5311
|
-
|
|
6622
|
+
recordSpanException6(span, e);
|
|
5312
6623
|
}
|
|
5313
6624
|
span.end();
|
|
5314
6625
|
throw e;
|
|
@@ -5317,9 +6628,9 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5317
6628
|
}
|
|
5318
6629
|
async function installPackages2(dir, options) {
|
|
5319
6630
|
return await tracer.startActiveSpan("installPackages", async (span) => {
|
|
5320
|
-
const installSpinner =
|
|
6631
|
+
const installSpinner = spinner();
|
|
5321
6632
|
try {
|
|
5322
|
-
const projectDir =
|
|
6633
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
5323
6634
|
const pkgManager = await getUserPackageManager(projectDir);
|
|
5324
6635
|
span.setAttributes({
|
|
5325
6636
|
"cli.projectDir": projectDir,
|
|
@@ -5359,7 +6670,7 @@ async function installPackages2(dir, options) {
|
|
|
5359
6670
|
`Failed to install @trigger.dev/sdk@${options.tag}. Rerun command with --log-level debug for more details.`
|
|
5360
6671
|
);
|
|
5361
6672
|
if (!(e instanceof SkipCommandError)) {
|
|
5362
|
-
|
|
6673
|
+
recordSpanException6(span, e);
|
|
5363
6674
|
}
|
|
5364
6675
|
span.end();
|
|
5365
6676
|
throw e;
|
|
@@ -5369,11 +6680,11 @@ async function installPackages2(dir, options) {
|
|
|
5369
6680
|
async function writeConfigFile(dir, project, options, triggerDir) {
|
|
5370
6681
|
return await tracer.startActiveSpan("writeConfigFile", async (span) => {
|
|
5371
6682
|
try {
|
|
5372
|
-
const spnnr =
|
|
6683
|
+
const spnnr = spinner();
|
|
5373
6684
|
spnnr.start("Creating config file");
|
|
5374
|
-
const projectDir =
|
|
5375
|
-
const templatePath =
|
|
5376
|
-
const outputPath =
|
|
6685
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6686
|
+
const templatePath = join8(cliRootPath(), "templates", "trigger.config.ts.template");
|
|
6687
|
+
const outputPath = join8(projectDir, "trigger.config.ts");
|
|
5377
6688
|
span.setAttributes({
|
|
5378
6689
|
"cli.projectDir": projectDir,
|
|
5379
6690
|
"cli.templatePath": templatePath,
|
|
@@ -5389,7 +6700,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5389
6700
|
outputPath,
|
|
5390
6701
|
override: options.overrideConfig
|
|
5391
6702
|
});
|
|
5392
|
-
const relativePathToOutput =
|
|
6703
|
+
const relativePathToOutput = relative4(process.cwd(), outputPath);
|
|
5393
6704
|
spnnr.stop(
|
|
5394
6705
|
result.success ? `Config file created at ${relativePathToOutput}` : `Failed to create config file: ${result.error}`
|
|
5395
6706
|
);
|
|
@@ -5400,7 +6711,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5400
6711
|
return result.success;
|
|
5401
6712
|
} catch (e) {
|
|
5402
6713
|
if (!(e instanceof SkipCommandError)) {
|
|
5403
|
-
|
|
6714
|
+
recordSpanException6(span, e);
|
|
5404
6715
|
}
|
|
5405
6716
|
span.end();
|
|
5406
6717
|
throw e;
|
|
@@ -5413,13 +6724,13 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5413
6724
|
if (projectRef) {
|
|
5414
6725
|
const projectResponse = await apiClient2.getProject(projectRef);
|
|
5415
6726
|
if (!projectResponse.success) {
|
|
5416
|
-
|
|
6727
|
+
log6.error(
|
|
5417
6728
|
`--project-ref ${projectRef} is not a valid project ref. Request to fetch data resulted in: ${projectResponse.error}`
|
|
5418
6729
|
);
|
|
5419
6730
|
throw new SkipCommandError(projectResponse.error);
|
|
5420
6731
|
}
|
|
5421
6732
|
span.setAttributes({
|
|
5422
|
-
...
|
|
6733
|
+
...flattenAttributes4(projectResponse.data, "cli.project")
|
|
5423
6734
|
});
|
|
5424
6735
|
span.end();
|
|
5425
6736
|
return projectResponse.data;
|
|
@@ -5429,11 +6740,11 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5429
6740
|
throw new Error(`Failed to get projects: ${projectsResponse.error}`);
|
|
5430
6741
|
}
|
|
5431
6742
|
if (projectsResponse.data.length === 0) {
|
|
5432
|
-
const newProjectLink =
|
|
6743
|
+
const newProjectLink = terminalLink4(
|
|
5433
6744
|
"Create new project",
|
|
5434
6745
|
`${dashboardUrl}/projects/new?version=v3`
|
|
5435
6746
|
);
|
|
5436
|
-
|
|
6747
|
+
outro6(`You don't have any projects yet. ${newProjectLink}`);
|
|
5437
6748
|
throw new SkipCommandError();
|
|
5438
6749
|
}
|
|
5439
6750
|
const selectedProject = await select2({
|
|
@@ -5444,7 +6755,7 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5444
6755
|
hint: project.organization.title
|
|
5445
6756
|
}))
|
|
5446
6757
|
});
|
|
5447
|
-
if (
|
|
6758
|
+
if (isCancel2(selectedProject)) {
|
|
5448
6759
|
throw new OutroCommandError();
|
|
5449
6760
|
}
|
|
5450
6761
|
const projectData = projectsResponse.data.find(
|
|
@@ -5454,13 +6765,13 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5454
6765
|
throw new Error("Invalid project ref");
|
|
5455
6766
|
}
|
|
5456
6767
|
span.setAttributes({
|
|
5457
|
-
...
|
|
6768
|
+
...flattenAttributes4(projectData, "cli.project")
|
|
5458
6769
|
});
|
|
5459
6770
|
span.end();
|
|
5460
6771
|
return projectData;
|
|
5461
6772
|
} catch (e) {
|
|
5462
6773
|
if (!(e instanceof SkipCommandError)) {
|
|
5463
|
-
|
|
6774
|
+
recordSpanException6(span, e);
|
|
5464
6775
|
}
|
|
5465
6776
|
span.end();
|
|
5466
6777
|
throw e;
|
|
@@ -5471,12 +6782,14 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5471
6782
|
// src/commands/logout.ts
|
|
5472
6783
|
var LogoutCommandOptions = CommonCommandOptions;
|
|
5473
6784
|
function configureLogoutCommand(program2) {
|
|
5474
|
-
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
5475
|
-
|
|
5476
|
-
await
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
6785
|
+
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
6786
|
+
async (options) => {
|
|
6787
|
+
await handleTelemetry(async () => {
|
|
6788
|
+
await printInitialBanner(false);
|
|
6789
|
+
await logoutCommand(options);
|
|
6790
|
+
});
|
|
6791
|
+
}
|
|
6792
|
+
);
|
|
5480
6793
|
}
|
|
5481
6794
|
async function logoutCommand(options) {
|
|
5482
6795
|
return await wrapCommandAction("logoutCommand", LogoutCommandOptions, options, async (opts) => {
|
|
@@ -5486,11 +6799,46 @@ async function logoutCommand(options) {
|
|
|
5486
6799
|
async function logout(options) {
|
|
5487
6800
|
const config = readAuthConfigProfile(options.profile);
|
|
5488
6801
|
if (!config?.accessToken) {
|
|
5489
|
-
logger.info(`You are already logged out [${options.profile
|
|
6802
|
+
logger.info(`You are already logged out [${options.profile}]`);
|
|
6803
|
+
return;
|
|
6804
|
+
}
|
|
6805
|
+
deleteAuthConfigProfile(options.profile);
|
|
6806
|
+
logger.info(`Logged out of Trigger.dev [${options.profile}]`);
|
|
6807
|
+
}
|
|
6808
|
+
|
|
6809
|
+
// src/commands/list-profiles.ts
|
|
6810
|
+
import { log as log7, outro as outro7 } from "@clack/prompts";
|
|
6811
|
+
var ListProfilesOptions = CommonCommandOptions;
|
|
6812
|
+
function configureListProfilesCommand(program2) {
|
|
6813
|
+
return program2.command("list-profiles").description("List all of your CLI profiles").option(
|
|
6814
|
+
"-l, --log-level <level>",
|
|
6815
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
6816
|
+
"log"
|
|
6817
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (options) => {
|
|
6818
|
+
await handleTelemetry(async () => {
|
|
6819
|
+
await printInitialBanner(true);
|
|
6820
|
+
await listProfilesCommand(options);
|
|
6821
|
+
});
|
|
6822
|
+
});
|
|
6823
|
+
}
|
|
6824
|
+
async function listProfilesCommand(options) {
|
|
6825
|
+
return await wrapCommandAction("listProfiles", ListProfilesOptions, options, async (opts) => {
|
|
6826
|
+
return await listProfiles(opts);
|
|
6827
|
+
});
|
|
6828
|
+
}
|
|
6829
|
+
async function listProfiles(options) {
|
|
6830
|
+
const authConfig = readAuthConfigFile();
|
|
6831
|
+
if (!authConfig) {
|
|
6832
|
+
logger.info("No profiles found");
|
|
5490
6833
|
return;
|
|
5491
6834
|
}
|
|
5492
|
-
|
|
5493
|
-
|
|
6835
|
+
const profiles = Object.keys(authConfig);
|
|
6836
|
+
log7.message("Profiles:");
|
|
6837
|
+
for (const profile of profiles) {
|
|
6838
|
+
const profileConfig = authConfig[profile];
|
|
6839
|
+
log7.info(`${profile}${profileConfig?.apiUrl ? ` - ${chalkGrey(profileConfig.apiUrl)}` : ""}`);
|
|
6840
|
+
}
|
|
6841
|
+
outro7("Retrieve account info by running whoami --profile <profile>");
|
|
5494
6842
|
}
|
|
5495
6843
|
|
|
5496
6844
|
// src/cli/index.ts
|
|
@@ -5502,6 +6850,8 @@ configureDevCommand(program);
|
|
|
5502
6850
|
configureDeployCommand(program);
|
|
5503
6851
|
configureWhoamiCommand(program);
|
|
5504
6852
|
configureLogoutCommand(program);
|
|
6853
|
+
configureListProfilesCommand(program);
|
|
6854
|
+
configureUpdateCommand(program);
|
|
5505
6855
|
|
|
5506
6856
|
// src/index.ts
|
|
5507
6857
|
var main = async () => {
|