trigger.dev 3.0.0-beta.2 → 3.0.0-beta.20
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 +15 -4
- package/dist/index.js +1725 -606
- 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 -3
- package/dist/workers/prod/entry-point.js +99 -43
- package/dist/workers/prod/worker-facade.js +62 -54
- package/dist/workers/prod/worker-setup.js +5 -3
- package/package.json +6 -13
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,30 +777,29 @@ 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 flattenAttributes2
|
|
786
|
-
recordSpanException as recordSpanException4
|
|
786
|
+
flattenAttributes as flattenAttributes2
|
|
787
787
|
} from "@trigger.dev/core/v3";
|
|
788
|
-
import
|
|
788
|
+
import { recordSpanException as recordSpanException4 } 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, relative as relative3, posix } 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.20";
|
|
804
803
|
var dependencies = {
|
|
805
804
|
"@clack/prompts": "^0.7.0",
|
|
806
805
|
"@depot/cli": "0.0.1-cli.2.55.0",
|
|
@@ -816,7 +815,7 @@ var dependencies = {
|
|
|
816
815
|
"@opentelemetry/sdk-trace-base": "^1.22.0",
|
|
817
816
|
"@opentelemetry/sdk-trace-node": "^1.22.0",
|
|
818
817
|
"@opentelemetry/semantic-conventions": "^1.22.0",
|
|
819
|
-
"@trigger.dev/core": "workspace
|
|
818
|
+
"@trigger.dev/core": "workspace:3.0.0-beta.20",
|
|
820
819
|
"@types/degit": "^2.8.3",
|
|
821
820
|
chalk: "^5.2.0",
|
|
822
821
|
chokidar: "^3.5.3",
|
|
@@ -833,12 +832,10 @@ var dependencies = {
|
|
|
833
832
|
"import-meta-resolve": "^4.0.0",
|
|
834
833
|
ink: "^4.4.1",
|
|
835
834
|
"jsonc-parser": "^3.2.1",
|
|
836
|
-
jsonlines: "^0.1.1",
|
|
837
835
|
liquidjs: "^10.9.2",
|
|
838
836
|
"mock-fs": "^5.2.0",
|
|
839
837
|
nanoid: "^4.0.2",
|
|
840
838
|
"node-fetch": "^3.3.0",
|
|
841
|
-
"npm-check-updates": "^16.12.2",
|
|
842
839
|
"object-hash": "^3.0.0",
|
|
843
840
|
"p-debounce": "^4.0.0",
|
|
844
841
|
"p-throttle": "^6.1.0",
|
|
@@ -850,7 +847,6 @@ var dependencies = {
|
|
|
850
847
|
"simple-git": "^3.19.0",
|
|
851
848
|
"socket.io-client": "^4.7.4",
|
|
852
849
|
"source-map-support": "^0.5.21",
|
|
853
|
-
"supports-color": "^9.4.0",
|
|
854
850
|
"terminal-link": "^3.0.0",
|
|
855
851
|
"tiny-invariant": "^1.2.0",
|
|
856
852
|
"tsconfig-paths": "^4.2.0",
|
|
@@ -894,13 +890,12 @@ var package_default = {
|
|
|
894
890
|
type: "module",
|
|
895
891
|
exports: "./dist/index.js",
|
|
896
892
|
bin: {
|
|
897
|
-
|
|
893
|
+
triggerdev: "./dist/index.js"
|
|
898
894
|
},
|
|
899
895
|
devDependencies: {
|
|
900
896
|
"@trigger.dev/core-apps": "workspace:*",
|
|
901
897
|
"@trigger.dev/tsconfig": "workspace:*",
|
|
902
898
|
"@types/gradient-string": "^1.1.2",
|
|
903
|
-
"@types/jsonlines": "^0.1.5",
|
|
904
899
|
"@types/mock-fs": "^4.13.1",
|
|
905
900
|
"@types/node": "18",
|
|
906
901
|
"@types/object-hash": "^3.0.6",
|
|
@@ -908,8 +903,8 @@ var package_default = {
|
|
|
908
903
|
"@types/semver": "^7.3.13",
|
|
909
904
|
"@types/ws": "^8.5.3",
|
|
910
905
|
"cpy-cli": "^5.0.0",
|
|
906
|
+
nodemon: "^3.0.1",
|
|
911
907
|
"npm-run-all": "^4.1.5",
|
|
912
|
-
"npm-watch": "^0.11.0",
|
|
913
908
|
open: "^10.0.3",
|
|
914
909
|
"p-retry": "^6.1.0",
|
|
915
910
|
rimraf: "^3.0.2",
|
|
@@ -919,9 +914,6 @@ var package_default = {
|
|
|
919
914
|
vitest: "^0.34.4",
|
|
920
915
|
"xdg-app-paths": "^8.3.0"
|
|
921
916
|
},
|
|
922
|
-
watch: {
|
|
923
|
-
"build:prod-containerfile": "src/Containerfile.prod"
|
|
924
|
-
},
|
|
925
917
|
scripts: {
|
|
926
918
|
typecheck: "tsc -p tsconfig.check.json",
|
|
927
919
|
build: "npm run clean && run-p build:**",
|
|
@@ -931,7 +923,7 @@ var package_default = {
|
|
|
931
923
|
dev: "npm run clean && run-p dev:**",
|
|
932
924
|
"dev:main": "tsup --watch",
|
|
933
925
|
"dev:workers": "tsup --config tsup.workers.config.ts --watch",
|
|
934
|
-
"dev:
|
|
926
|
+
"dev:test": "nodemon -w src/Containerfile.prod -x npm run build:prod-containerfile",
|
|
935
927
|
clean: "rimraf dist",
|
|
936
928
|
start: "node dist/index.js",
|
|
937
929
|
test: "vitest"
|
|
@@ -1147,7 +1139,8 @@ async function zodfetch(schema, url, requestInit) {
|
|
|
1147
1139
|
}
|
|
1148
1140
|
|
|
1149
1141
|
// src/cli/common.ts
|
|
1150
|
-
import { flattenAttributes
|
|
1142
|
+
import { flattenAttributes } from "@trigger.dev/core/v3";
|
|
1143
|
+
import { recordSpanException } from "@trigger.dev/core/v3/workers";
|
|
1151
1144
|
import { z } from "zod";
|
|
1152
1145
|
|
|
1153
1146
|
// src/telemetry/tracing.ts
|
|
@@ -1157,6 +1150,10 @@ import { Resource, detectResourcesSync, processDetectorSync } from "@opentelemet
|
|
|
1157
1150
|
import { NodeTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";
|
|
1158
1151
|
import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
|
|
1159
1152
|
import { DiagConsoleLogger, DiagLogLevel, diag, trace } from "@opentelemetry/api";
|
|
1153
|
+
import {
|
|
1154
|
+
SEMRESATTRS_SERVICE_NAME,
|
|
1155
|
+
SEMRESATTRS_SERVICE_VERSION
|
|
1156
|
+
} from "@opentelemetry/semantic-conventions";
|
|
1160
1157
|
function initializeTracing() {
|
|
1161
1158
|
if (process.argv.includes("--skip-telemetry") || process.env.TRIGGER_DEV_SKIP_TELEMETRY) {
|
|
1162
1159
|
return;
|
|
@@ -1168,7 +1165,8 @@ function initializeTracing() {
|
|
|
1168
1165
|
detectors: [processDetectorSync]
|
|
1169
1166
|
}).merge(
|
|
1170
1167
|
new Resource({
|
|
1171
|
-
|
|
1168
|
+
[SEMRESATTRS_SERVICE_NAME]: "trigger.dev cli v3",
|
|
1169
|
+
[SEMRESATTRS_SERVICE_VERSION]: version
|
|
1172
1170
|
})
|
|
1173
1171
|
);
|
|
1174
1172
|
const traceProvider = new NodeTracerProvider({
|
|
@@ -1185,10 +1183,9 @@ function initializeTracing() {
|
|
|
1185
1183
|
});
|
|
1186
1184
|
const spanExporter = new OTLPTraceExporter({
|
|
1187
1185
|
url: "https://otel.baselime.io/v1",
|
|
1188
|
-
timeoutMillis:
|
|
1186
|
+
timeoutMillis: 5e3,
|
|
1189
1187
|
headers: {
|
|
1190
|
-
"x-api-key": "
|
|
1191
|
-
// this is a joke
|
|
1188
|
+
"x-api-key": "b6e0fbbaf8dc2524773d2152ae2e9eb5c7fbaa52"
|
|
1192
1189
|
}
|
|
1193
1190
|
});
|
|
1194
1191
|
const spanProcessor = new SimpleSpanProcessor(spanExporter);
|
|
@@ -1201,7 +1198,7 @@ function initializeTracing() {
|
|
|
1201
1198
|
}
|
|
1202
1199
|
var provider = initializeTracing();
|
|
1203
1200
|
function getTracer() {
|
|
1204
|
-
return trace.getTracer("trigger.dev cli", version);
|
|
1201
|
+
return trace.getTracer("trigger.dev cli v3", version);
|
|
1205
1202
|
}
|
|
1206
1203
|
|
|
1207
1204
|
// src/cli/common.ts
|
|
@@ -1307,7 +1304,7 @@ var Logger = class {
|
|
|
1307
1304
|
const kind = LOGGER_LEVEL_FORMAT_TYPE_MAP[level];
|
|
1308
1305
|
if (kind) {
|
|
1309
1306
|
const [firstLine, ...otherLines] = message.split("\n");
|
|
1310
|
-
const notes = otherLines.length > 0 ? otherLines.map((
|
|
1307
|
+
const notes = otherLines.length > 0 ? otherLines.map((text3) => ({ text: text3 })) : void 0;
|
|
1311
1308
|
return formatMessagesSync([{ text: firstLine, notes }], {
|
|
1312
1309
|
color: true,
|
|
1313
1310
|
kind,
|
|
@@ -1322,6 +1319,83 @@ var logger = new Logger();
|
|
|
1322
1319
|
|
|
1323
1320
|
// src/cli/common.ts
|
|
1324
1321
|
import { outro } from "@clack/prompts";
|
|
1322
|
+
|
|
1323
|
+
// src/utilities/cliOutput.ts
|
|
1324
|
+
import { log } from "@clack/prompts";
|
|
1325
|
+
import chalk2 from "chalk";
|
|
1326
|
+
var green = "#4FFF54";
|
|
1327
|
+
var purple = "#735BF3";
|
|
1328
|
+
function chalkGreen(text3) {
|
|
1329
|
+
return chalk2.hex(green)(text3);
|
|
1330
|
+
}
|
|
1331
|
+
function chalkPurple(text3) {
|
|
1332
|
+
return chalk2.hex(purple)(text3);
|
|
1333
|
+
}
|
|
1334
|
+
function chalkGrey(text3) {
|
|
1335
|
+
return chalk2.hex("#878C99")(text3);
|
|
1336
|
+
}
|
|
1337
|
+
function chalkError(text3) {
|
|
1338
|
+
return chalk2.hex("#E11D48")(text3);
|
|
1339
|
+
}
|
|
1340
|
+
function chalkWarning(text3) {
|
|
1341
|
+
return chalk2.yellow(text3);
|
|
1342
|
+
}
|
|
1343
|
+
function chalkSuccess(text3) {
|
|
1344
|
+
return chalk2.hex("#28BF5C")(text3);
|
|
1345
|
+
}
|
|
1346
|
+
function chalkLink(text3) {
|
|
1347
|
+
return chalk2.underline.hex("#D7D9DD")(text3);
|
|
1348
|
+
}
|
|
1349
|
+
function chalkWorker(text3) {
|
|
1350
|
+
return chalk2.hex("#FFFF89")(text3);
|
|
1351
|
+
}
|
|
1352
|
+
function chalkTask(text3) {
|
|
1353
|
+
return chalk2.hex("#60A5FA")(text3);
|
|
1354
|
+
}
|
|
1355
|
+
function chalkRun(text3) {
|
|
1356
|
+
return chalk2.hex("#A78BFA")(text3);
|
|
1357
|
+
}
|
|
1358
|
+
function logo() {
|
|
1359
|
+
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1360
|
+
}
|
|
1361
|
+
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1362
|
+
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1363
|
+
month: "short",
|
|
1364
|
+
day: "2-digit",
|
|
1365
|
+
hour: "2-digit",
|
|
1366
|
+
minute: "2-digit",
|
|
1367
|
+
second: "2-digit",
|
|
1368
|
+
hour12: false
|
|
1369
|
+
}).format(date);
|
|
1370
|
+
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1371
|
+
return formattedDate;
|
|
1372
|
+
}
|
|
1373
|
+
function prettyError(header, body, footer) {
|
|
1374
|
+
const prefix = "Error: ";
|
|
1375
|
+
const indent = Array(prefix.length).fill(" ").join("");
|
|
1376
|
+
const spacing = "\n\n";
|
|
1377
|
+
const prettyPrefix = chalkError(prefix);
|
|
1378
|
+
const withIndents = (text3) => text3?.split("\n").map((line) => `${indent}${line}`).join("\n");
|
|
1379
|
+
const prettyBody = withIndents(body);
|
|
1380
|
+
const prettyFooter = withIndents(footer);
|
|
1381
|
+
log.error(
|
|
1382
|
+
`${prettyPrefix}${header}${prettyBody ? `${spacing}${prettyBody}` : ""}${prettyFooter ? `${spacing}${prettyFooter}` : ""}`
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1385
|
+
function prettyWarning(header, body, footer) {
|
|
1386
|
+
const prefix = "Warning: ";
|
|
1387
|
+
const indent = Array(prefix.length).fill(" ").join("");
|
|
1388
|
+
const spacing = "\n\n";
|
|
1389
|
+
const prettyPrefix = chalkWarning(prefix);
|
|
1390
|
+
const withIndents = (text3) => text3?.split("\n").map((line) => `${indent}${line}`).join("\n");
|
|
1391
|
+
const prettyBody = withIndents(body);
|
|
1392
|
+
const prettyFooter = withIndents(footer);
|
|
1393
|
+
log.warn(
|
|
1394
|
+
`${prettyPrefix}${header}${prettyBody ? `${spacing}${prettyBody}` : ""}${prettyFooter ? `${spacing}${prettyFooter}` : ""}`
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// src/cli/common.ts
|
|
1325
1399
|
var CommonCommandOptions = z.object({
|
|
1326
1400
|
apiUrl: z.string().optional(),
|
|
1327
1401
|
logLevel: z.enum(["debug", "info", "log", "warn", "error", "none"]).default("log"),
|
|
@@ -1331,7 +1405,7 @@ var CommonCommandOptions = z.object({
|
|
|
1331
1405
|
function commonOptions(command) {
|
|
1332
1406
|
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
1407
|
"-l, --log-level <level>",
|
|
1334
|
-
"The log level to use (debug, info, log, warn, error, none)",
|
|
1408
|
+
"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
1409
|
"log"
|
|
1336
1410
|
).option("--skip-telemetry", "Opt-out of sending telemetry");
|
|
1337
1411
|
}
|
|
@@ -1377,7 +1451,7 @@ async function wrapCommandAction(name, schema, options, action) {
|
|
|
1377
1451
|
} else if (e instanceof SkipCommandError) {
|
|
1378
1452
|
} else {
|
|
1379
1453
|
recordSpanException(span, e);
|
|
1380
|
-
logger.
|
|
1454
|
+
logger.log(`${chalkError("X Error:")} ${e instanceof Error ? e.message : String(e)}`);
|
|
1381
1455
|
}
|
|
1382
1456
|
span.end();
|
|
1383
1457
|
throw e;
|
|
@@ -1420,31 +1494,34 @@ import fsModule, { writeFile } from "fs/promises";
|
|
|
1420
1494
|
import fs from "node:fs";
|
|
1421
1495
|
import { tmpdir } from "node:os";
|
|
1422
1496
|
import pathModule from "node:path";
|
|
1423
|
-
async function createFile(
|
|
1424
|
-
await fsModule.mkdir(pathModule.dirname(
|
|
1425
|
-
await fsModule.writeFile(
|
|
1426
|
-
return
|
|
1497
|
+
async function createFile(path7, contents) {
|
|
1498
|
+
await fsModule.mkdir(pathModule.dirname(path7), { recursive: true });
|
|
1499
|
+
await fsModule.writeFile(path7, contents);
|
|
1500
|
+
return path7;
|
|
1501
|
+
}
|
|
1502
|
+
async function pathExists(path7) {
|
|
1503
|
+
return fsSync.existsSync(path7);
|
|
1427
1504
|
}
|
|
1428
|
-
async function
|
|
1429
|
-
|
|
1505
|
+
async function removeFile(path7) {
|
|
1506
|
+
await fsModule.unlink(path7);
|
|
1430
1507
|
}
|
|
1431
|
-
async function readFile(
|
|
1432
|
-
return await fsModule.readFile(
|
|
1508
|
+
async function readFile(path7) {
|
|
1509
|
+
return await fsModule.readFile(path7, "utf8");
|
|
1433
1510
|
}
|
|
1434
|
-
async function readJSONFile(
|
|
1435
|
-
const fileContents = await fsModule.readFile(
|
|
1511
|
+
async function readJSONFile(path7) {
|
|
1512
|
+
const fileContents = await fsModule.readFile(path7, "utf8");
|
|
1436
1513
|
return JSON.parse(fileContents);
|
|
1437
1514
|
}
|
|
1438
|
-
async function writeJSONFile(
|
|
1439
|
-
await writeFile(
|
|
1515
|
+
async function writeJSONFile(path7, json, pretty = false) {
|
|
1516
|
+
await writeFile(path7, JSON.stringify(json, void 0, pretty ? 2 : void 0), "utf8");
|
|
1440
1517
|
}
|
|
1441
|
-
function readJSONFileSync(
|
|
1442
|
-
const fileContents = fsSync.readFileSync(
|
|
1518
|
+
function readJSONFileSync(path7) {
|
|
1519
|
+
const fileContents = fsSync.readFileSync(path7, "utf8");
|
|
1443
1520
|
return JSON.parse(fileContents);
|
|
1444
1521
|
}
|
|
1445
|
-
function safeDeleteFileSync(
|
|
1522
|
+
function safeDeleteFileSync(path7) {
|
|
1446
1523
|
try {
|
|
1447
|
-
fs.unlinkSync(
|
|
1524
|
+
fs.unlinkSync(path7);
|
|
1448
1525
|
} catch (error) {
|
|
1449
1526
|
}
|
|
1450
1527
|
}
|
|
@@ -1467,16 +1544,26 @@ function createTaskFileImports(taskFiles) {
|
|
|
1467
1544
|
async function gatherTaskFiles(config) {
|
|
1468
1545
|
const taskFiles = [];
|
|
1469
1546
|
for (const triggerDir of config.triggerDirectories) {
|
|
1470
|
-
const files = await
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1547
|
+
const files = await gatherTaskFilesFromDir(triggerDir, triggerDir, config);
|
|
1548
|
+
taskFiles.push(...files);
|
|
1549
|
+
}
|
|
1550
|
+
return taskFiles;
|
|
1551
|
+
}
|
|
1552
|
+
async function gatherTaskFilesFromDir(dirPath, triggerDir, config) {
|
|
1553
|
+
const taskFiles = [];
|
|
1554
|
+
const files = await fs2.promises.readdir(dirPath, { withFileTypes: true });
|
|
1555
|
+
for (const file of files) {
|
|
1556
|
+
if (!file.isFile()) {
|
|
1557
|
+
const fullPath = join(dirPath, file.name);
|
|
1558
|
+
taskFiles.push(...await gatherTaskFilesFromDir(fullPath, triggerDir, config));
|
|
1559
|
+
} else {
|
|
1560
|
+
if (!file.name.endsWith(".js") && !file.name.endsWith(".ts") && !file.name.endsWith(".jsx") && !file.name.endsWith(".tsx")) {
|
|
1475
1561
|
continue;
|
|
1476
|
-
|
|
1562
|
+
}
|
|
1563
|
+
const fullPath = join(dirPath, file.name);
|
|
1477
1564
|
const filePath = relative(config.projectDir, fullPath);
|
|
1478
|
-
const
|
|
1479
|
-
const
|
|
1565
|
+
const importName = filePath.replace(/\..+$/, "").replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1566
|
+
const importPath = filePath.replace(/\\/g, "/");
|
|
1480
1567
|
taskFiles.push({ triggerDir, importPath, importName, filePath });
|
|
1481
1568
|
}
|
|
1482
1569
|
}
|
|
@@ -1493,9 +1580,12 @@ async function getTriggerDirectories(dirPath) {
|
|
|
1493
1580
|
const entries = await fs2.promises.readdir(dirPath, { withFileTypes: true });
|
|
1494
1581
|
const triggerDirectories = [];
|
|
1495
1582
|
for (const entry of entries) {
|
|
1496
|
-
if (!entry.isDirectory() || IGNORED_DIRS.includes(entry.name))
|
|
1583
|
+
if (!entry.isDirectory() || IGNORED_DIRS.includes(entry.name) || entry.name.startsWith("."))
|
|
1497
1584
|
continue;
|
|
1498
1585
|
const fullPath = join(dirPath, entry.name);
|
|
1586
|
+
if (fullPath.endsWith("app/api/trigger")) {
|
|
1587
|
+
continue;
|
|
1588
|
+
}
|
|
1499
1589
|
if (entry.name === "trigger") {
|
|
1500
1590
|
triggerDirectories.push(fullPath);
|
|
1501
1591
|
}
|
|
@@ -1535,6 +1625,11 @@ function readAuthConfigProfile(profile = "default") {
|
|
|
1535
1625
|
return void 0;
|
|
1536
1626
|
}
|
|
1537
1627
|
}
|
|
1628
|
+
function deleteAuthConfigProfile(profile = "default") {
|
|
1629
|
+
const existingConfig = readAuthConfigFile() || {};
|
|
1630
|
+
delete existingConfig[profile];
|
|
1631
|
+
writeAuthConfigFile(existingConfig);
|
|
1632
|
+
}
|
|
1538
1633
|
function readAuthConfigFile() {
|
|
1539
1634
|
try {
|
|
1540
1635
|
const authConfigFilePath = getAuthConfigFilePath();
|
|
@@ -1564,6 +1659,15 @@ async function getConfigPath(dir, fileName) {
|
|
|
1564
1659
|
});
|
|
1565
1660
|
return await findUp(fileName ? [fileName] : CONFIG_FILES, { cwd: dir });
|
|
1566
1661
|
}
|
|
1662
|
+
async function findFilePath(dir, fileName) {
|
|
1663
|
+
const result = await findUp([fileName], { cwd: dir });
|
|
1664
|
+
logger.debug("Searched for the file", {
|
|
1665
|
+
dir,
|
|
1666
|
+
fileName,
|
|
1667
|
+
result
|
|
1668
|
+
});
|
|
1669
|
+
return result;
|
|
1670
|
+
}
|
|
1567
1671
|
async function readConfig(dir, options) {
|
|
1568
1672
|
const absoluteDir = path2.resolve(process.cwd(), dir);
|
|
1569
1673
|
const configPath = await getConfigPath(dir, options?.configFile);
|
|
@@ -1601,7 +1705,8 @@ async function readConfig(dir, options) {
|
|
|
1601
1705
|
});
|
|
1602
1706
|
const userConfigModule = await import(builtConfigFileHref);
|
|
1603
1707
|
const rawConfig = await normalizeConfig(
|
|
1604
|
-
userConfigModule
|
|
1708
|
+
userConfigModule?.config,
|
|
1709
|
+
options?.projectRef ? { project: options?.projectRef } : void 0
|
|
1605
1710
|
);
|
|
1606
1711
|
const config = Config.parse(rawConfig);
|
|
1607
1712
|
return {
|
|
@@ -1610,82 +1715,36 @@ async function readConfig(dir, options) {
|
|
|
1610
1715
|
path: configPath
|
|
1611
1716
|
};
|
|
1612
1717
|
}
|
|
1613
|
-
async function resolveConfig(
|
|
1718
|
+
async function resolveConfig(path7, config) {
|
|
1614
1719
|
if (!config.triggerDirectories) {
|
|
1615
|
-
config.triggerDirectories = await findTriggerDirectories(
|
|
1720
|
+
config.triggerDirectories = await findTriggerDirectories(path7);
|
|
1616
1721
|
}
|
|
1617
1722
|
config.triggerDirectories = resolveTriggerDirectories(config.triggerDirectories);
|
|
1723
|
+
logger.debug("Resolved trigger directories", { triggerDirectories: config.triggerDirectories });
|
|
1618
1724
|
if (!config.triggerUrl) {
|
|
1619
1725
|
config.triggerUrl = CLOUD_API_URL;
|
|
1620
1726
|
}
|
|
1621
1727
|
if (!config.projectDir) {
|
|
1622
|
-
config.projectDir =
|
|
1728
|
+
config.projectDir = path7;
|
|
1623
1729
|
}
|
|
1624
1730
|
if (!config.tsconfigPath) {
|
|
1625
|
-
config.tsconfigPath = await
|
|
1731
|
+
config.tsconfigPath = await findFilePath(path7, "tsconfig.json");
|
|
1626
1732
|
}
|
|
1627
1733
|
return config;
|
|
1628
1734
|
}
|
|
1629
|
-
async function normalizeConfig(config) {
|
|
1735
|
+
async function normalizeConfig(config, overrides) {
|
|
1736
|
+
let normalized = config;
|
|
1630
1737
|
if (typeof config === "function") {
|
|
1631
|
-
|
|
1738
|
+
normalized = await config();
|
|
1632
1739
|
}
|
|
1633
|
-
|
|
1740
|
+
normalized = { ...normalized, ...overrides };
|
|
1741
|
+
return normalized;
|
|
1634
1742
|
}
|
|
1635
1743
|
|
|
1636
1744
|
// src/utilities/initialBanner.ts
|
|
1637
|
-
import { spinner } from "@clack/prompts";
|
|
1638
1745
|
import chalk3 from "chalk";
|
|
1639
|
-
import supportsColor from "supports-color";
|
|
1640
1746
|
import checkForUpdate from "update-check";
|
|
1641
1747
|
|
|
1642
|
-
// src/utilities/cliOutput.ts
|
|
1643
|
-
import chalk2 from "chalk";
|
|
1644
|
-
var green = "#4FFF54";
|
|
1645
|
-
var purple = "#735BF3";
|
|
1646
|
-
function chalkPurple(text2) {
|
|
1647
|
-
return chalk2.hex(purple)(text2);
|
|
1648
|
-
}
|
|
1649
|
-
function chalkGrey(text2) {
|
|
1650
|
-
return chalk2.hex("#878C99")(text2);
|
|
1651
|
-
}
|
|
1652
|
-
function chalkError(text2) {
|
|
1653
|
-
return chalk2.hex("#E11D48")(text2);
|
|
1654
|
-
}
|
|
1655
|
-
function chalkWarning(text2) {
|
|
1656
|
-
return chalk2.yellow(text2);
|
|
1657
|
-
}
|
|
1658
|
-
function chalkSuccess(text2) {
|
|
1659
|
-
return chalk2.hex("#28BF5C")(text2);
|
|
1660
|
-
}
|
|
1661
|
-
function chalkLink(text2) {
|
|
1662
|
-
return chalk2.underline.hex("#D7D9DD")(text2);
|
|
1663
|
-
}
|
|
1664
|
-
function chalkWorker(text2) {
|
|
1665
|
-
return chalk2.hex("#FFFF89")(text2);
|
|
1666
|
-
}
|
|
1667
|
-
function chalkTask(text2) {
|
|
1668
|
-
return chalk2.hex("#60A5FA")(text2);
|
|
1669
|
-
}
|
|
1670
|
-
function chalkRun(text2) {
|
|
1671
|
-
return chalk2.hex("#A78BFA")(text2);
|
|
1672
|
-
}
|
|
1673
|
-
function logo() {
|
|
1674
|
-
return `${chalk2.hex(green).bold("Trigger")}${chalk2.hex(purple).bold(".dev")}`;
|
|
1675
|
-
}
|
|
1676
|
-
function prettyPrintDate(date = /* @__PURE__ */ new Date()) {
|
|
1677
|
-
let formattedDate = new Intl.DateTimeFormat("en-US", {
|
|
1678
|
-
month: "short",
|
|
1679
|
-
day: "2-digit",
|
|
1680
|
-
hour: "2-digit",
|
|
1681
|
-
minute: "2-digit",
|
|
1682
|
-
second: "2-digit",
|
|
1683
|
-
hour12: false
|
|
1684
|
-
}).format(date);
|
|
1685
|
-
formattedDate += "." + ("00" + date.getMilliseconds()).slice(-3);
|
|
1686
|
-
return formattedDate;
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
1748
|
// src/utilities/getVersion.ts
|
|
1690
1749
|
import path3 from "path";
|
|
1691
1750
|
function getVersion() {
|
|
@@ -1694,13 +1753,32 @@ function getVersion() {
|
|
|
1694
1753
|
return packageJsonContent.version ?? "1.0.0";
|
|
1695
1754
|
}
|
|
1696
1755
|
|
|
1756
|
+
// src/utilities/windows.ts
|
|
1757
|
+
import { log as log2, spinner as clackSpinner } from "@clack/prompts";
|
|
1758
|
+
var isWindows = process.platform === "win32";
|
|
1759
|
+
function escapeImportPath(path7) {
|
|
1760
|
+
return isWindows ? path7.replaceAll("\\", "\\\\") : path7;
|
|
1761
|
+
}
|
|
1762
|
+
var ballmerSpinner = () => ({
|
|
1763
|
+
start: (msg) => {
|
|
1764
|
+
log2.step(msg ?? "");
|
|
1765
|
+
},
|
|
1766
|
+
stop: (msg, code) => {
|
|
1767
|
+
log2.message(msg ?? "");
|
|
1768
|
+
},
|
|
1769
|
+
message: (msg) => {
|
|
1770
|
+
log2.message(msg ?? "");
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
var spinner = () => isWindows ? ballmerSpinner() : clackSpinner();
|
|
1774
|
+
|
|
1697
1775
|
// src/utilities/initialBanner.ts
|
|
1698
1776
|
async function printInitialBanner(performUpdateCheck = true) {
|
|
1699
|
-
const
|
|
1700
|
-
const
|
|
1701
|
-
${logo()} ${chalkGrey(`(${
|
|
1777
|
+
const cliVersion = getVersion();
|
|
1778
|
+
const text3 = `
|
|
1779
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}
|
|
1702
1780
|
`;
|
|
1703
|
-
logger.info(
|
|
1781
|
+
logger.info(text3);
|
|
1704
1782
|
let maybeNewVersion;
|
|
1705
1783
|
if (performUpdateCheck) {
|
|
1706
1784
|
const loadingSpinner = spinner();
|
|
@@ -1708,7 +1786,7 @@ ${logo()} ${chalkGrey(`(${packageVersion})`)}
|
|
|
1708
1786
|
maybeNewVersion = await updateCheck();
|
|
1709
1787
|
if (maybeNewVersion !== void 0) {
|
|
1710
1788
|
loadingSpinner.stop(`Update available ${chalk3.green(maybeNewVersion)}`);
|
|
1711
|
-
const currentMajor = parseInt(
|
|
1789
|
+
const currentMajor = parseInt(cliVersion.split(".")[0]);
|
|
1712
1790
|
const newMajor = parseInt(maybeNewVersion.split(".")[0]);
|
|
1713
1791
|
if (newMajor > currentMajor) {
|
|
1714
1792
|
logger.warn(
|
|
@@ -1723,18 +1801,26 @@ After installation, run Trigger.dev with \`npx trigger.dev\`.`
|
|
|
1723
1801
|
}
|
|
1724
1802
|
}
|
|
1725
1803
|
async function printStandloneInitialBanner(performUpdateCheck = true) {
|
|
1726
|
-
const
|
|
1727
|
-
let text2 = `
|
|
1728
|
-
${logo()} ${chalkGrey("(v3 Developer Preview)")}`;
|
|
1804
|
+
const cliVersion = getVersion();
|
|
1729
1805
|
if (performUpdateCheck) {
|
|
1730
1806
|
const maybeNewVersion = await updateCheck();
|
|
1731
1807
|
if (maybeNewVersion !== void 0) {
|
|
1732
|
-
|
|
1808
|
+
logger.log(`
|
|
1809
|
+
${logo()} ${chalkGrey(`(${cliVersion} -> ${chalk3.green(maybeNewVersion)})`)}`);
|
|
1810
|
+
} else {
|
|
1811
|
+
logger.log(`
|
|
1812
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}`);
|
|
1733
1813
|
}
|
|
1814
|
+
} else {
|
|
1815
|
+
logger.log(`
|
|
1816
|
+
${logo()} ${chalkGrey(`(${cliVersion})`)}`);
|
|
1734
1817
|
}
|
|
1735
|
-
logger.log(
|
|
1818
|
+
logger.log(`${chalkGrey("-".repeat(54))}`);
|
|
1736
1819
|
}
|
|
1737
|
-
function printDevBanner() {
|
|
1820
|
+
function printDevBanner(printTopBorder = true) {
|
|
1821
|
+
if (printTopBorder) {
|
|
1822
|
+
logger.log(chalkGrey("-".repeat(54)));
|
|
1823
|
+
}
|
|
1738
1824
|
logger.log(
|
|
1739
1825
|
`${chalkGrey("Key:")} ${chalkWorker("Version")} ${chalkGrey("|")} ${chalkTask(
|
|
1740
1826
|
"Task"
|
|
@@ -1746,7 +1832,7 @@ async function doUpdateCheck() {
|
|
|
1746
1832
|
let update = null;
|
|
1747
1833
|
try {
|
|
1748
1834
|
update = await checkForUpdate(package_default, {
|
|
1749
|
-
distTag: package_default.version.startsWith("
|
|
1835
|
+
distTag: package_default.version.startsWith("3.0.0-beta") ? "beta" : "latest"
|
|
1750
1836
|
});
|
|
1751
1837
|
} catch (err) {
|
|
1752
1838
|
}
|
|
@@ -1764,26 +1850,20 @@ async function installPackages(packages, options) {
|
|
|
1764
1850
|
const cwd = options?.cwd ?? process.cwd();
|
|
1765
1851
|
logger.debug("Installing packages", { packages });
|
|
1766
1852
|
await setPackageJsonDeps(join3(cwd, "package.json"), packages);
|
|
1767
|
-
|
|
1853
|
+
await execa(
|
|
1768
1854
|
"npm",
|
|
1769
1855
|
["install", "--install-strategy", "nested", "--ignore-scripts", "--no-audit", "--no-fund"],
|
|
1770
1856
|
{
|
|
1771
1857
|
cwd,
|
|
1772
|
-
stderr: "
|
|
1858
|
+
stderr: "pipe"
|
|
1773
1859
|
}
|
|
1774
1860
|
);
|
|
1775
|
-
await new Promise((res, rej) => {
|
|
1776
|
-
childProcess2.on("error", (e) => rej(e));
|
|
1777
|
-
childProcess2.on("close", () => res());
|
|
1778
|
-
});
|
|
1779
|
-
await childProcess2;
|
|
1780
|
-
return;
|
|
1781
1861
|
}
|
|
1782
|
-
function detectPackageNameFromImportPath(
|
|
1783
|
-
if (
|
|
1784
|
-
return
|
|
1862
|
+
function detectPackageNameFromImportPath(path7) {
|
|
1863
|
+
if (path7.startsWith("@")) {
|
|
1864
|
+
return path7.split("/").slice(0, 2).join("/");
|
|
1785
1865
|
} else {
|
|
1786
|
-
return
|
|
1866
|
+
return path7.split("/")[0];
|
|
1787
1867
|
}
|
|
1788
1868
|
}
|
|
1789
1869
|
function stripWorkspaceFromVersion(version2) {
|
|
@@ -1799,16 +1879,16 @@ function parsePackageName(packageSpecifier) {
|
|
|
1799
1879
|
}
|
|
1800
1880
|
return { name: packageSpecifier };
|
|
1801
1881
|
}
|
|
1802
|
-
async function setPackageJsonDeps(
|
|
1882
|
+
async function setPackageJsonDeps(path7, deps) {
|
|
1803
1883
|
try {
|
|
1804
|
-
const existingPackageJson = await readJSONFile(
|
|
1884
|
+
const existingPackageJson = await readJSONFile(path7);
|
|
1805
1885
|
const newPackageJson = {
|
|
1806
1886
|
...existingPackageJson,
|
|
1807
1887
|
dependencies: {
|
|
1808
1888
|
...deps
|
|
1809
1889
|
}
|
|
1810
1890
|
};
|
|
1811
|
-
await writeJSONFile(
|
|
1891
|
+
await writeJSONFile(path7, newPackageJson);
|
|
1812
1892
|
} catch (error) {
|
|
1813
1893
|
const defaultPackageJson = {
|
|
1814
1894
|
name: "temp",
|
|
@@ -1816,13 +1896,13 @@ async function setPackageJsonDeps(path6, deps) {
|
|
|
1816
1896
|
description: "",
|
|
1817
1897
|
dependencies: deps
|
|
1818
1898
|
};
|
|
1819
|
-
await writeJSONFile(
|
|
1899
|
+
await writeJSONFile(path7, defaultPackageJson);
|
|
1820
1900
|
}
|
|
1821
1901
|
}
|
|
1822
1902
|
|
|
1823
1903
|
// src/commands/login.ts
|
|
1824
|
-
import { intro as intro2, log, outro as
|
|
1825
|
-
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3";
|
|
1904
|
+
import { intro as intro2, log as log3, outro as outro3, select } from "@clack/prompts";
|
|
1905
|
+
import { recordSpanException as recordSpanException3 } from "@trigger.dev/core/v3/workers";
|
|
1826
1906
|
|
|
1827
1907
|
// ../../node_modules/.pnpm/open@10.0.3/node_modules/open/index.js
|
|
1828
1908
|
import process6 from "node:process";
|
|
@@ -2192,14 +2272,14 @@ var baseOpen = async (options) => {
|
|
|
2192
2272
|
}
|
|
2193
2273
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
2194
2274
|
if (options.wait) {
|
|
2195
|
-
return new Promise((
|
|
2275
|
+
return new Promise((resolve5, reject) => {
|
|
2196
2276
|
subprocess.once("error", reject);
|
|
2197
2277
|
subprocess.once("close", (exitCode) => {
|
|
2198
2278
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
2199
2279
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
2200
2280
|
return;
|
|
2201
2281
|
}
|
|
2202
|
-
|
|
2282
|
+
resolve5(subprocess);
|
|
2203
2283
|
});
|
|
2204
2284
|
});
|
|
2205
2285
|
}
|
|
@@ -2316,7 +2396,7 @@ var decorateErrorWithCounts = (error, attemptNumber, options) => {
|
|
|
2316
2396
|
return error;
|
|
2317
2397
|
};
|
|
2318
2398
|
async function pRetry(input, options) {
|
|
2319
|
-
return new Promise((
|
|
2399
|
+
return new Promise((resolve5, reject) => {
|
|
2320
2400
|
options = {
|
|
2321
2401
|
onFailedAttempt() {
|
|
2322
2402
|
},
|
|
@@ -2339,7 +2419,7 @@ async function pRetry(input, options) {
|
|
|
2339
2419
|
try {
|
|
2340
2420
|
const result = await input(attemptNumber);
|
|
2341
2421
|
cleanUp();
|
|
2342
|
-
|
|
2422
|
+
resolve5(result);
|
|
2343
2423
|
} catch (error) {
|
|
2344
2424
|
try {
|
|
2345
2425
|
if (!(error instanceof Error)) {
|
|
@@ -2369,10 +2449,10 @@ async function pRetry(input, options) {
|
|
|
2369
2449
|
import { z as z3 } from "zod";
|
|
2370
2450
|
|
|
2371
2451
|
// src/commands/whoami.ts
|
|
2372
|
-
import { intro, note,
|
|
2452
|
+
import { intro, note, outro as outro2 } from "@clack/prompts";
|
|
2373
2453
|
|
|
2374
2454
|
// src/utilities/session.ts
|
|
2375
|
-
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3";
|
|
2455
|
+
import { recordSpanException as recordSpanException2 } from "@trigger.dev/core/v3/workers";
|
|
2376
2456
|
var tracer2 = getTracer();
|
|
2377
2457
|
async function isLoggedIn(profile = "default") {
|
|
2378
2458
|
return await tracer2.startActiveSpan("isLoggedIn", async (span) => {
|
|
@@ -2447,16 +2527,23 @@ async function whoAmI(options, embedded = false) {
|
|
|
2447
2527
|
if (!embedded) {
|
|
2448
2528
|
intro(`Displaying your account details [${options?.profile ?? "default"}]`);
|
|
2449
2529
|
}
|
|
2450
|
-
const loadingSpinner =
|
|
2530
|
+
const loadingSpinner = spinner();
|
|
2451
2531
|
loadingSpinner.start("Checking your account details");
|
|
2452
2532
|
const authentication = await isLoggedIn(options?.profile);
|
|
2453
2533
|
if (!authentication.ok) {
|
|
2454
2534
|
if (authentication.error === "fetch failed") {
|
|
2455
2535
|
loadingSpinner.stop("Fetch failed. Platform down?");
|
|
2456
2536
|
} else {
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2537
|
+
if (embedded) {
|
|
2538
|
+
loadingSpinner.stop(
|
|
2539
|
+
`Failed to check account details. You may want to run \`trigger.dev logout --profile ${options?.profile ?? "default"}\` and try again.`
|
|
2540
|
+
);
|
|
2541
|
+
} else {
|
|
2542
|
+
loadingSpinner.stop(
|
|
2543
|
+
`You must login first. Use \`trigger.dev login --profile ${options?.profile ?? "default"}\` to login.`
|
|
2544
|
+
);
|
|
2545
|
+
outro2("Whoami failed");
|
|
2546
|
+
}
|
|
2460
2547
|
}
|
|
2461
2548
|
return {
|
|
2462
2549
|
success: false,
|
|
@@ -2521,6 +2608,29 @@ async function login(options) {
|
|
|
2521
2608
|
if (!opts.embedded) {
|
|
2522
2609
|
intro2("Logging in to Trigger.dev");
|
|
2523
2610
|
}
|
|
2611
|
+
const accessTokenFromEnv = process.env.TRIGGER_ACCESS_TOKEN;
|
|
2612
|
+
if (accessTokenFromEnv) {
|
|
2613
|
+
const auth = {
|
|
2614
|
+
accessToken: accessTokenFromEnv,
|
|
2615
|
+
apiUrl: process.env.TRIGGER_API_URL ?? "https://api.trigger.dev"
|
|
2616
|
+
};
|
|
2617
|
+
const apiClient3 = new CliApiClient(auth.apiUrl, auth.accessToken);
|
|
2618
|
+
const userData = await apiClient3.whoAmI();
|
|
2619
|
+
if (!userData.success) {
|
|
2620
|
+
throw new Error(userData.error);
|
|
2621
|
+
}
|
|
2622
|
+
return {
|
|
2623
|
+
ok: true,
|
|
2624
|
+
profile: options?.profile ?? "default",
|
|
2625
|
+
userId: userData.data.userId,
|
|
2626
|
+
email: userData.data.email,
|
|
2627
|
+
dashboardUrl: userData.data.dashboardUrl,
|
|
2628
|
+
auth: {
|
|
2629
|
+
accessToken: auth.accessToken,
|
|
2630
|
+
apiUrl: auth.apiUrl
|
|
2631
|
+
}
|
|
2632
|
+
};
|
|
2633
|
+
}
|
|
2524
2634
|
const authConfig = readAuthConfigProfile(options?.profile);
|
|
2525
2635
|
if (authConfig && authConfig.accessToken) {
|
|
2526
2636
|
const whoAmIResult = await whoAmI(
|
|
@@ -2529,10 +2639,18 @@ async function login(options) {
|
|
|
2529
2639
|
skipTelemetry: !span.isRecording(),
|
|
2530
2640
|
logLevel: logger.loggerLevel
|
|
2531
2641
|
},
|
|
2532
|
-
|
|
2642
|
+
true
|
|
2533
2643
|
);
|
|
2534
2644
|
if (!whoAmIResult.success) {
|
|
2535
|
-
|
|
2645
|
+
prettyError("Unable to validate existing personal access token", whoAmIResult.error);
|
|
2646
|
+
if (!opts.embedded) {
|
|
2647
|
+
outro3(
|
|
2648
|
+
`Login failed using stored token. To fix, first logout using \`trigger.dev logout${options?.profile ? ` --profile ${options.profile}` : ""}\` and then try again.`
|
|
2649
|
+
);
|
|
2650
|
+
throw new SkipLoggingError(whoAmIResult.error);
|
|
2651
|
+
} else {
|
|
2652
|
+
throw new Error(whoAmIResult.error);
|
|
2653
|
+
}
|
|
2536
2654
|
} else {
|
|
2537
2655
|
if (!opts.embedded) {
|
|
2538
2656
|
const continueOption = await select({
|
|
@@ -2550,7 +2668,7 @@ async function login(options) {
|
|
|
2550
2668
|
initialValue: false
|
|
2551
2669
|
});
|
|
2552
2670
|
if (continueOption !== true) {
|
|
2553
|
-
|
|
2671
|
+
outro3("Already logged in");
|
|
2554
2672
|
span.setAttributes({
|
|
2555
2673
|
"cli.userId": whoAmIResult.data.userId,
|
|
2556
2674
|
"cli.email": whoAmIResult.data.email,
|
|
@@ -2591,16 +2709,16 @@ async function login(options) {
|
|
|
2591
2709
|
}
|
|
2592
2710
|
}
|
|
2593
2711
|
if (opts.embedded) {
|
|
2594
|
-
|
|
2712
|
+
log3.step("You must login to continue.");
|
|
2595
2713
|
}
|
|
2596
2714
|
const apiClient2 = new CliApiClient(authConfig?.apiUrl ?? opts.defaultApiUrl);
|
|
2597
2715
|
const authorizationCodeResult = await createAuthorizationCode(apiClient2);
|
|
2598
|
-
|
|
2716
|
+
log3.step(
|
|
2599
2717
|
`Please visit the following URL to login:
|
|
2600
2718
|
${chalkLink(authorizationCodeResult.url)}`
|
|
2601
2719
|
);
|
|
2602
2720
|
await open_default(authorizationCodeResult.url);
|
|
2603
|
-
const getPersonalAccessTokenSpinner =
|
|
2721
|
+
const getPersonalAccessTokenSpinner = spinner();
|
|
2604
2722
|
getPersonalAccessTokenSpinner.start("Waiting for you to login");
|
|
2605
2723
|
try {
|
|
2606
2724
|
const indexResult = await pRetry(
|
|
@@ -2629,9 +2747,9 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2629
2747
|
throw new Error(whoAmIResult.error);
|
|
2630
2748
|
}
|
|
2631
2749
|
if (opts.embedded) {
|
|
2632
|
-
|
|
2750
|
+
log3.step("Logged in successfully");
|
|
2633
2751
|
} else {
|
|
2634
|
-
|
|
2752
|
+
outro3("Logged in successfully");
|
|
2635
2753
|
}
|
|
2636
2754
|
span.end();
|
|
2637
2755
|
return {
|
|
@@ -2648,7 +2766,7 @@ ${chalkLink(authorizationCodeResult.url)}`
|
|
|
2648
2766
|
} catch (e) {
|
|
2649
2767
|
getPersonalAccessTokenSpinner.stop(`Failed to get access token`);
|
|
2650
2768
|
if (e instanceof AbortError) {
|
|
2651
|
-
|
|
2769
|
+
log3.error(e.message);
|
|
2652
2770
|
}
|
|
2653
2771
|
recordSpanException3(span, e);
|
|
2654
2772
|
span.end();
|
|
@@ -2697,7 +2815,7 @@ async function getPersonalAccessToken(apiClient2, authorizationCode) {
|
|
|
2697
2815
|
async function createAuthorizationCode(apiClient2) {
|
|
2698
2816
|
return await tracer.startActiveSpan("createAuthorizationCode", async (span) => {
|
|
2699
2817
|
try {
|
|
2700
|
-
const createAuthCodeSpinner =
|
|
2818
|
+
const createAuthCodeSpinner = spinner();
|
|
2701
2819
|
createAuthCodeSpinner.start("Creating authorition code");
|
|
2702
2820
|
const authorizationCodeResult = await apiClient2.createAuthorizationCode();
|
|
2703
2821
|
if (!authorizationCodeResult.success) {
|
|
@@ -2721,10 +2839,42 @@ ${authorizationCodeResult.error}`
|
|
|
2721
2839
|
});
|
|
2722
2840
|
}
|
|
2723
2841
|
|
|
2842
|
+
// src/commands/deploy.ts
|
|
2843
|
+
import { Glob } from "glob";
|
|
2844
|
+
|
|
2724
2845
|
// src/utilities/build.ts
|
|
2725
2846
|
import { readFileSync } from "node:fs";
|
|
2726
2847
|
import { extname, isAbsolute } from "node:path";
|
|
2727
2848
|
import tsConfigPaths from "tsconfig-paths";
|
|
2849
|
+
function bundleTriggerDevCore(buildIdentifier, tsconfigPath) {
|
|
2850
|
+
return {
|
|
2851
|
+
name: "trigger-bundle-core",
|
|
2852
|
+
setup(build3) {
|
|
2853
|
+
build3.onResolve({ filter: /.*/ }, (args) => {
|
|
2854
|
+
if (!args.path.startsWith("@trigger.dev/core/v3")) {
|
|
2855
|
+
return void 0;
|
|
2856
|
+
}
|
|
2857
|
+
const triggerSdkPath = __require.resolve("@trigger.dev/sdk/v3", { paths: [process.cwd()] });
|
|
2858
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Resolved @trigger.dev/sdk/v3`, {
|
|
2859
|
+
...args,
|
|
2860
|
+
triggerSdkPath
|
|
2861
|
+
});
|
|
2862
|
+
const resolvedPath = __require.resolve(args.path, {
|
|
2863
|
+
paths: [triggerSdkPath]
|
|
2864
|
+
});
|
|
2865
|
+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Externalizing ${args.path}`, {
|
|
2866
|
+
...args,
|
|
2867
|
+
triggerSdkPath,
|
|
2868
|
+
resolvedPath
|
|
2869
|
+
});
|
|
2870
|
+
return {
|
|
2871
|
+
path: resolvedPath,
|
|
2872
|
+
external: false
|
|
2873
|
+
};
|
|
2874
|
+
});
|
|
2875
|
+
}
|
|
2876
|
+
};
|
|
2877
|
+
}
|
|
2728
2878
|
function workerSetupImportConfigPlugin(configPath) {
|
|
2729
2879
|
return {
|
|
2730
2880
|
name: "trigger-worker-setup",
|
|
@@ -2736,7 +2886,9 @@ function workerSetupImportConfigPlugin(configPath) {
|
|
|
2736
2886
|
let workerSetupContents = readFileSync(args.path, "utf-8");
|
|
2737
2887
|
workerSetupContents = workerSetupContents.replace(
|
|
2738
2888
|
"__SETUP_IMPORTED_PROJECT_CONFIG__",
|
|
2739
|
-
`import * as setupImportedConfigExports from "${
|
|
2889
|
+
`import * as setupImportedConfigExports from "${escapeImportPath(
|
|
2890
|
+
configPath
|
|
2891
|
+
)}"; const setupImportedConfig = setupImportedConfigExports.config;`
|
|
2740
2892
|
);
|
|
2741
2893
|
logger.debug("Loading worker setup", {
|
|
2742
2894
|
args,
|
|
@@ -2871,12 +3023,644 @@ function getLoaderForFile(file) {
|
|
|
2871
3023
|
throw new Error(`Cannot get loader for file ${file}`);
|
|
2872
3024
|
}
|
|
2873
3025
|
|
|
3026
|
+
// src/utilities/deployErrors.ts
|
|
3027
|
+
import chalk4 from "chalk";
|
|
3028
|
+
import { relative as relative2 } from "node:path";
|
|
3029
|
+
import { groupTaskMetadataIssuesByTask } from "@trigger.dev/core/v3";
|
|
3030
|
+
import terminalLink from "terminal-link";
|
|
3031
|
+
|
|
3032
|
+
// src/utilities/links.ts
|
|
3033
|
+
var docs = {
|
|
3034
|
+
config: {
|
|
3035
|
+
home: "https://trigger.dev/docs/v3/trigger-config",
|
|
3036
|
+
esm: "https://trigger.dev/docs/v3/trigger-config#esm-only-packages",
|
|
3037
|
+
prisma: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators",
|
|
3038
|
+
additionalPackages: "https://trigger.dev/docs/v3/trigger-config#prisma-and-other-generators"
|
|
3039
|
+
}
|
|
3040
|
+
};
|
|
3041
|
+
var getInTouch = "https://trigger.dev/contact";
|
|
3042
|
+
|
|
3043
|
+
// src/utilities/deployErrors.ts
|
|
3044
|
+
function errorIsErrorLike(error) {
|
|
3045
|
+
return error instanceof Error || typeof error === "object" && error !== null && "message" in error;
|
|
3046
|
+
}
|
|
3047
|
+
function parseBuildErrorStack(error) {
|
|
3048
|
+
if (typeof error === "string") {
|
|
3049
|
+
return error;
|
|
3050
|
+
}
|
|
3051
|
+
if (errorIsErrorLike(error)) {
|
|
3052
|
+
if (typeof error.stack === "string") {
|
|
3053
|
+
const isErrRequireEsm = error.stack.includes("ERR_REQUIRE_ESM");
|
|
3054
|
+
let moduleName = null;
|
|
3055
|
+
if (isErrRequireEsm) {
|
|
3056
|
+
const moduleRegex = /node_modules\/(@[^\/]+\/[^\/]+|[^\/]+)\/[^\/]+\s/;
|
|
3057
|
+
const match = moduleRegex.exec(error.stack);
|
|
3058
|
+
if (match) {
|
|
3059
|
+
moduleName = match[1];
|
|
3060
|
+
return {
|
|
3061
|
+
type: "esm-require-error",
|
|
3062
|
+
moduleName
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
} else {
|
|
3067
|
+
return error.message;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
function logESMRequireError(parsedError, resolvedConfig) {
|
|
3072
|
+
logger.log(
|
|
3073
|
+
`
|
|
3074
|
+
${chalkError("X Error:")} The ${chalkPurple(
|
|
3075
|
+
parsedError.moduleName
|
|
3076
|
+
)} module is being required even though it's ESM only, and builds only support CommonJS. There are two ${chalk4.underline(
|
|
3077
|
+
"possible"
|
|
3078
|
+
)} ways to fix this:`
|
|
3079
|
+
);
|
|
3080
|
+
logger.log(
|
|
3081
|
+
`
|
|
3082
|
+
${chalkGrey("\u25CB")} Dynamically import the module in your code: ${chalkGrey(
|
|
3083
|
+
`const myModule = await import("${parsedError.moduleName}");`
|
|
3084
|
+
)}`
|
|
3085
|
+
);
|
|
3086
|
+
if (resolvedConfig.status === "file") {
|
|
3087
|
+
const relativePath = relative2(resolvedConfig.config.projectDir, resolvedConfig.path).replace(
|
|
3088
|
+
/\\/g,
|
|
3089
|
+
"/"
|
|
3090
|
+
);
|
|
3091
|
+
logger.log(
|
|
3092
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3093
|
+
parsedError.moduleName
|
|
3094
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3095
|
+
`(${relativePath})`
|
|
3096
|
+
)}. This will bundle the module with your code.
|
|
3097
|
+
`
|
|
3098
|
+
);
|
|
3099
|
+
} else {
|
|
3100
|
+
logger.log(
|
|
3101
|
+
`${chalkGrey("\u25CB")} ${chalk4.underline("Or")} add ${chalkPurple(
|
|
3102
|
+
parsedError.moduleName
|
|
3103
|
+
)} to the ${chalkGreen("dependenciesToBundle")} array in your config file ${chalkGrey(
|
|
3104
|
+
"(you'll need to create one)"
|
|
3105
|
+
)}. This will bundle the module with your code.
|
|
3106
|
+
`
|
|
3107
|
+
);
|
|
3108
|
+
}
|
|
3109
|
+
logger.log(
|
|
3110
|
+
`${chalkGrey("\u25CB")} For more info see the ${terminalLink("relevant docs", docs.config.esm)}.
|
|
3111
|
+
`
|
|
3112
|
+
);
|
|
3113
|
+
}
|
|
3114
|
+
function parseNpmInstallError(error) {
|
|
3115
|
+
if (typeof error === "string") {
|
|
3116
|
+
return error;
|
|
3117
|
+
}
|
|
3118
|
+
if (error instanceof Error) {
|
|
3119
|
+
if (typeof error.stack === "string") {
|
|
3120
|
+
const isPackageNotFoundError = error.stack.includes("ERR! 404 Not Found") && error.stack.includes("is not in this registry");
|
|
3121
|
+
let packageName = null;
|
|
3122
|
+
if (isPackageNotFoundError) {
|
|
3123
|
+
const packageNameRegex = /'([^']+)' is not in this registry/;
|
|
3124
|
+
const match = packageNameRegex.exec(error.stack);
|
|
3125
|
+
if (match) {
|
|
3126
|
+
packageName = match[1];
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
if (packageName) {
|
|
3130
|
+
return {
|
|
3131
|
+
type: "package-not-found-error",
|
|
3132
|
+
packageName
|
|
3133
|
+
};
|
|
3134
|
+
}
|
|
3135
|
+
const noMatchingVersionRegex = /No matching version found for ([^\s]+)\s/;
|
|
3136
|
+
const noMatchingVersionMatch = noMatchingVersionRegex.exec(error.stack);
|
|
3137
|
+
if (noMatchingVersionMatch) {
|
|
3138
|
+
return {
|
|
3139
|
+
type: "no-matching-version-error",
|
|
3140
|
+
packageName: noMatchingVersionMatch[1].replace(/.$/, "")
|
|
3141
|
+
};
|
|
3142
|
+
}
|
|
3143
|
+
return error.message;
|
|
3144
|
+
} else {
|
|
3145
|
+
return error.message;
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
return "Unknown error";
|
|
3149
|
+
}
|
|
3150
|
+
function logTaskMetadataParseError(zodIssues, tasks) {
|
|
3151
|
+
logger.log(
|
|
3152
|
+
`
|
|
3153
|
+
${chalkError("X Error:")} Failed to start. The following ${zodIssues.length === 1 ? "task issue was" : "task issues were"} found:`
|
|
3154
|
+
);
|
|
3155
|
+
const groupedIssues = groupTaskMetadataIssuesByTask(tasks, zodIssues);
|
|
3156
|
+
for (const key in groupedIssues) {
|
|
3157
|
+
const taskWithIssues = groupedIssues[key];
|
|
3158
|
+
if (!taskWithIssues) {
|
|
3159
|
+
continue;
|
|
3160
|
+
}
|
|
3161
|
+
logger.log(
|
|
3162
|
+
`
|
|
3163
|
+
${chalkWarning("\u276F")} ${taskWithIssues.exportName} ${chalkGrey("in")} ${taskWithIssues.filePath}`
|
|
3164
|
+
);
|
|
3165
|
+
for (const issue of taskWithIssues.issues) {
|
|
3166
|
+
if (issue.path) {
|
|
3167
|
+
logger.log(` ${chalkError("x")} ${issue.path} ${chalkGrey(issue.message)}`);
|
|
3168
|
+
} else {
|
|
3169
|
+
logger.log(` ${chalkError("x")} ${chalkGrey(issue.message)}`);
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
// src/utilities/safeJsonParse.ts
|
|
3176
|
+
function safeJsonParse(json) {
|
|
3177
|
+
if (!json) {
|
|
3178
|
+
return void 0;
|
|
3179
|
+
}
|
|
3180
|
+
try {
|
|
3181
|
+
return JSON.parse(json);
|
|
3182
|
+
} catch {
|
|
3183
|
+
return void 0;
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
|
|
3187
|
+
// src/utilities/javascriptProject.ts
|
|
3188
|
+
import { $ } from "execa";
|
|
3189
|
+
import { join as join4 } from "node:path";
|
|
3190
|
+
|
|
3191
|
+
// src/utilities/getUserPackageManager.ts
|
|
3192
|
+
import { findUp as findUp2 } from "find-up";
|
|
3193
|
+
import { basename } from "path";
|
|
3194
|
+
async function getUserPackageManager(path7) {
|
|
3195
|
+
const packageManager = await detectPackageManager(path7);
|
|
3196
|
+
logger.debug("Detected package manager", { packageManager });
|
|
3197
|
+
return packageManager;
|
|
3198
|
+
}
|
|
3199
|
+
async function detectPackageManager(path7) {
|
|
3200
|
+
try {
|
|
3201
|
+
return await detectPackageManagerFromArtifacts(path7);
|
|
3202
|
+
} catch (error) {
|
|
3203
|
+
return detectPackageManagerFromCurrentCommand();
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
function detectPackageManagerFromCurrentCommand() {
|
|
3207
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
3208
|
+
if (userAgent) {
|
|
3209
|
+
if (userAgent.startsWith("yarn")) {
|
|
3210
|
+
return "yarn";
|
|
3211
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
3212
|
+
return "pnpm";
|
|
3213
|
+
} else {
|
|
3214
|
+
return "npm";
|
|
3215
|
+
}
|
|
3216
|
+
} else {
|
|
3217
|
+
return "npm";
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
async function detectPackageManagerFromArtifacts(path7) {
|
|
3221
|
+
const artifacts = {
|
|
3222
|
+
yarn: "yarn.lock",
|
|
3223
|
+
pnpm: "pnpm-lock.yaml",
|
|
3224
|
+
npm: "package-lock.json",
|
|
3225
|
+
npmShrinkwrap: "npm-shrinkwrap.json"
|
|
3226
|
+
};
|
|
3227
|
+
const foundPath = await findUp2(Object.values(artifacts), { cwd: path7 });
|
|
3228
|
+
if (!foundPath) {
|
|
3229
|
+
throw new Error("Could not detect package manager from artifacts");
|
|
3230
|
+
}
|
|
3231
|
+
logger.debug("Found path from package manager artifacts", { foundPath });
|
|
3232
|
+
switch (basename(foundPath)) {
|
|
3233
|
+
case artifacts.yarn:
|
|
3234
|
+
return "yarn";
|
|
3235
|
+
case artifacts.pnpm:
|
|
3236
|
+
return "pnpm";
|
|
3237
|
+
case artifacts.npm:
|
|
3238
|
+
case artifacts.npmShrinkwrap:
|
|
3239
|
+
return "npm";
|
|
3240
|
+
default:
|
|
3241
|
+
throw new Error(`Unhandled package manager detection path: ${foundPath}`);
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
|
|
3245
|
+
// src/utilities/assertExhaustive.ts
|
|
3246
|
+
function assertExhaustive(x) {
|
|
3247
|
+
throw new Error("Unexpected object: " + x);
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
// src/utilities/javascriptProject.ts
|
|
3251
|
+
var BuiltInModules = /* @__PURE__ */ new Set([
|
|
3252
|
+
"assert",
|
|
3253
|
+
"async_hooks",
|
|
3254
|
+
"buffer",
|
|
3255
|
+
"child_process",
|
|
3256
|
+
"cluster",
|
|
3257
|
+
"console",
|
|
3258
|
+
"constants",
|
|
3259
|
+
"crypto",
|
|
3260
|
+
"dgram",
|
|
3261
|
+
"dns",
|
|
3262
|
+
"domain",
|
|
3263
|
+
"events",
|
|
3264
|
+
"fs",
|
|
3265
|
+
"http",
|
|
3266
|
+
"http2",
|
|
3267
|
+
"https",
|
|
3268
|
+
"inspector",
|
|
3269
|
+
"module",
|
|
3270
|
+
"net",
|
|
3271
|
+
"os",
|
|
3272
|
+
"path",
|
|
3273
|
+
"perf_hooks",
|
|
3274
|
+
"process",
|
|
3275
|
+
"punycode",
|
|
3276
|
+
"querystring",
|
|
3277
|
+
"readline",
|
|
3278
|
+
"repl",
|
|
3279
|
+
"stream",
|
|
3280
|
+
"string_decoder",
|
|
3281
|
+
"timers",
|
|
3282
|
+
"tls",
|
|
3283
|
+
"trace_events",
|
|
3284
|
+
"tty",
|
|
3285
|
+
"url",
|
|
3286
|
+
"util",
|
|
3287
|
+
"v8",
|
|
3288
|
+
"vm",
|
|
3289
|
+
"worker_threads",
|
|
3290
|
+
"zlib"
|
|
3291
|
+
]);
|
|
3292
|
+
var JavascriptProject = class {
|
|
3293
|
+
constructor(projectPath) {
|
|
3294
|
+
this.projectPath = projectPath;
|
|
3295
|
+
}
|
|
3296
|
+
_packageJson;
|
|
3297
|
+
_packageManager;
|
|
3298
|
+
get packageJson() {
|
|
3299
|
+
if (!this._packageJson) {
|
|
3300
|
+
this._packageJson = readJSONFileSync(join4(this.projectPath, "package.json"));
|
|
3301
|
+
}
|
|
3302
|
+
return this._packageJson;
|
|
3303
|
+
}
|
|
3304
|
+
get scripts() {
|
|
3305
|
+
return {
|
|
3306
|
+
postinstall: this.packageJson.scripts?.postinstall ?? ""
|
|
3307
|
+
};
|
|
3308
|
+
}
|
|
3309
|
+
async install() {
|
|
3310
|
+
const command = await this.#getCommand();
|
|
3311
|
+
try {
|
|
3312
|
+
await command.installDependencies({
|
|
3313
|
+
cwd: this.projectPath
|
|
3314
|
+
});
|
|
3315
|
+
} catch (error) {
|
|
3316
|
+
logger.debug(`Failed to install dependencies using ${command.name}`, {
|
|
3317
|
+
error
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
async resolve(packageName, options) {
|
|
3322
|
+
if (BuiltInModules.has(packageName)) {
|
|
3323
|
+
return void 0;
|
|
3324
|
+
}
|
|
3325
|
+
const opts = { allowDev: false, ...options };
|
|
3326
|
+
const packageJsonVersion = this.packageJson.dependencies?.[packageName];
|
|
3327
|
+
if (typeof packageJsonVersion === "string") {
|
|
3328
|
+
return packageJsonVersion;
|
|
3329
|
+
}
|
|
3330
|
+
if (opts.allowDev) {
|
|
3331
|
+
const devPackageJsonVersion = this.packageJson.devDependencies?.[packageName];
|
|
3332
|
+
if (typeof devPackageJsonVersion === "string") {
|
|
3333
|
+
return devPackageJsonVersion;
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
const command = await this.#getCommand();
|
|
3337
|
+
try {
|
|
3338
|
+
const version2 = await command.resolveDependencyVersion(packageName, {
|
|
3339
|
+
cwd: this.projectPath
|
|
3340
|
+
});
|
|
3341
|
+
if (version2) {
|
|
3342
|
+
return version2;
|
|
3343
|
+
}
|
|
3344
|
+
} catch (error) {
|
|
3345
|
+
logger.debug(`Failed to resolve dependency version using ${command.name}`, {
|
|
3346
|
+
packageName,
|
|
3347
|
+
error
|
|
3348
|
+
});
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
async #getCommand() {
|
|
3352
|
+
const packageManager = await this.getPackageManager();
|
|
3353
|
+
switch (packageManager) {
|
|
3354
|
+
case "npm":
|
|
3355
|
+
return new NPMCommands();
|
|
3356
|
+
case "pnpm":
|
|
3357
|
+
return new PNPMCommands();
|
|
3358
|
+
case "yarn":
|
|
3359
|
+
return new YarnCommands();
|
|
3360
|
+
default:
|
|
3361
|
+
assertExhaustive(packageManager);
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
async getPackageManager() {
|
|
3365
|
+
if (!this._packageManager) {
|
|
3366
|
+
this._packageManager = await getUserPackageManager(this.projectPath);
|
|
3367
|
+
}
|
|
3368
|
+
return this._packageManager;
|
|
3369
|
+
}
|
|
3370
|
+
};
|
|
3371
|
+
var PNPMCommands = class {
|
|
3372
|
+
get name() {
|
|
3373
|
+
return "pnpm";
|
|
3374
|
+
}
|
|
3375
|
+
get cmd() {
|
|
3376
|
+
return process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
3377
|
+
}
|
|
3378
|
+
async installDependencies(options) {
|
|
3379
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3380
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3381
|
+
}
|
|
3382
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3383
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} -r --json`;
|
|
3384
|
+
const result = JSON.parse(stdout);
|
|
3385
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`, { result });
|
|
3386
|
+
for (const dep of result) {
|
|
3387
|
+
const dependency = dep.dependencies?.[packageName];
|
|
3388
|
+
if (dependency) {
|
|
3389
|
+
return dependency.version;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
};
|
|
3394
|
+
var NPMCommands = class {
|
|
3395
|
+
get name() {
|
|
3396
|
+
return "npm";
|
|
3397
|
+
}
|
|
3398
|
+
get cmd() {
|
|
3399
|
+
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
3400
|
+
}
|
|
3401
|
+
async installDependencies(options) {
|
|
3402
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3403
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3404
|
+
}
|
|
3405
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3406
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} list ${packageName} --json`;
|
|
3407
|
+
const output = JSON.parse(stdout);
|
|
3408
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`, { output });
|
|
3409
|
+
return this.#recursivelySearchDependencies(output.dependencies, packageName);
|
|
3410
|
+
}
|
|
3411
|
+
#recursivelySearchDependencies(dependencies2, packageName) {
|
|
3412
|
+
for (const [name, dependency] of Object.entries(dependencies2)) {
|
|
3413
|
+
if (name === packageName) {
|
|
3414
|
+
return dependency.version;
|
|
3415
|
+
}
|
|
3416
|
+
if (dependency.dependencies) {
|
|
3417
|
+
const result = this.#recursivelySearchDependencies(dependency.dependencies, packageName);
|
|
3418
|
+
if (result) {
|
|
3419
|
+
return result;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
};
|
|
3425
|
+
var YarnCommands = class {
|
|
3426
|
+
get name() {
|
|
3427
|
+
return "yarn";
|
|
3428
|
+
}
|
|
3429
|
+
get cmd() {
|
|
3430
|
+
return process.platform === "win32" ? "yarn.cmd" : "yarn";
|
|
3431
|
+
}
|
|
3432
|
+
async installDependencies(options) {
|
|
3433
|
+
const { stdout, stderr } = await $({ cwd: options.cwd })`${this.cmd} install`;
|
|
3434
|
+
logger.debug(`Installing dependencies using ${this.name}`, { stdout, stderr });
|
|
3435
|
+
}
|
|
3436
|
+
async resolveDependencyVersion(packageName, options) {
|
|
3437
|
+
const { stdout } = await $({ cwd: options.cwd })`${this.cmd} info ${packageName} --json`;
|
|
3438
|
+
const lines = stdout.split("\n");
|
|
3439
|
+
logger.debug(`Resolving ${packageName} version using ${this.name}`, { lines });
|
|
3440
|
+
for (const line of lines) {
|
|
3441
|
+
const json = JSON.parse(line);
|
|
3442
|
+
if (json.value === packageName) {
|
|
3443
|
+
return json.children.Version;
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
};
|
|
3448
|
+
|
|
3449
|
+
// src/utilities/resolveInternalFilePath.ts
|
|
3450
|
+
import path5 from "path";
|
|
3451
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3452
|
+
function cliRootPath() {
|
|
3453
|
+
const __filename2 = fileURLToPath3(import.meta.url);
|
|
3454
|
+
const __dirname2 = path5.dirname(__filename2);
|
|
3455
|
+
return __dirname2;
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3458
|
+
// src/commands/update.ts
|
|
3459
|
+
import { confirm, intro as intro3, isCancel, log as log4, outro as outro4 } from "@clack/prompts";
|
|
3460
|
+
import { join as join5, resolve as resolve2 } from "path";
|
|
3461
|
+
var UpdateCommandOptions = CommonCommandOptions.pick({
|
|
3462
|
+
logLevel: true,
|
|
3463
|
+
skipTelemetry: true
|
|
3464
|
+
});
|
|
3465
|
+
function configureUpdateCommand(program2) {
|
|
3466
|
+
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(
|
|
3467
|
+
"-l, --log-level <level>",
|
|
3468
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
3469
|
+
"log"
|
|
3470
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (path7, options) => {
|
|
3471
|
+
wrapCommandAction("dev", UpdateCommandOptions, options, async (opts) => {
|
|
3472
|
+
await printStandloneInitialBanner(true);
|
|
3473
|
+
await updateCommand(path7, opts);
|
|
3474
|
+
});
|
|
3475
|
+
});
|
|
3476
|
+
}
|
|
3477
|
+
var triggerPackageFilter = /^@trigger\.dev/;
|
|
3478
|
+
async function updateCommand(dir, options) {
|
|
3479
|
+
await updateTriggerPackages(dir, options);
|
|
3480
|
+
}
|
|
3481
|
+
async function updateTriggerPackages(dir, options, embedded, requireUpdate) {
|
|
3482
|
+
let hasOutput = false;
|
|
3483
|
+
if (!embedded) {
|
|
3484
|
+
intro3("Updating packages");
|
|
3485
|
+
}
|
|
3486
|
+
const projectPath = resolve2(process.cwd(), dir);
|
|
3487
|
+
const { packageJson, readonlyPackageJson, packageJsonPath } = await getPackageJson(projectPath);
|
|
3488
|
+
if (!packageJson) {
|
|
3489
|
+
log4.error("Failed to load package.json. Try to re-run with `-l debug` to see what's going on.");
|
|
3490
|
+
return false;
|
|
3491
|
+
}
|
|
3492
|
+
const cliVersion = getVersion();
|
|
3493
|
+
const newCliVersion = await updateCheck();
|
|
3494
|
+
if (newCliVersion) {
|
|
3495
|
+
prettyWarning(
|
|
3496
|
+
"You're not running the latest CLI version, please consider updating ASAP",
|
|
3497
|
+
`Current: ${cliVersion}
|
|
3498
|
+
Latest: ${newCliVersion}`,
|
|
3499
|
+
"Run latest: npx trigger.dev@beta"
|
|
3500
|
+
);
|
|
3501
|
+
hasOutput = true;
|
|
3502
|
+
}
|
|
3503
|
+
const triggerDependencies = getTriggerDependencies(packageJson);
|
|
3504
|
+
function getVersionMismatches(deps, targetVersion) {
|
|
3505
|
+
const mismatches = [];
|
|
3506
|
+
for (const dep of deps) {
|
|
3507
|
+
if (dep.version === targetVersion) {
|
|
3508
|
+
continue;
|
|
3509
|
+
}
|
|
3510
|
+
mismatches.push(dep);
|
|
3511
|
+
}
|
|
3512
|
+
return mismatches;
|
|
3513
|
+
}
|
|
3514
|
+
const versionMismatches = getVersionMismatches(triggerDependencies, cliVersion);
|
|
3515
|
+
if (versionMismatches.length === 0) {
|
|
3516
|
+
if (!embedded) {
|
|
3517
|
+
outro4(`Nothing to do${newCliVersion ? " ..but you should really update your CLI!" : ""}`);
|
|
3518
|
+
return hasOutput;
|
|
3519
|
+
}
|
|
3520
|
+
return hasOutput;
|
|
3521
|
+
}
|
|
3522
|
+
prettyWarning(
|
|
3523
|
+
"Mismatch between your CLI version and installed packages",
|
|
3524
|
+
"We recommend pinned versions for guaranteed compatibility"
|
|
3525
|
+
);
|
|
3526
|
+
if (!process.stdout.isTTY) {
|
|
3527
|
+
outro4("Deploy failed");
|
|
3528
|
+
console.log(
|
|
3529
|
+
`ERROR: Version mismatch detected while running in CI. This won't end well. Aborting.
|
|
3530
|
+
|
|
3531
|
+
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.
|
|
3532
|
+
|
|
3533
|
+
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\`
|
|
3534
|
+
|
|
3535
|
+
CLI version: ${cliVersion}
|
|
3536
|
+
|
|
3537
|
+
Current package versions that don't match the CLI:
|
|
3538
|
+
${versionMismatches.map((dep) => `- ${dep.name}@${dep.version}`).join("\n")}
|
|
3539
|
+
`
|
|
3540
|
+
);
|
|
3541
|
+
process.exit(1);
|
|
3542
|
+
}
|
|
3543
|
+
log4.message("");
|
|
3544
|
+
const userWantsToUpdate = await updateConfirmation(versionMismatches, cliVersion);
|
|
3545
|
+
if (isCancel(userWantsToUpdate)) {
|
|
3546
|
+
throw new OutroCommandError();
|
|
3547
|
+
}
|
|
3548
|
+
if (!userWantsToUpdate) {
|
|
3549
|
+
if (requireUpdate) {
|
|
3550
|
+
outro4("You shall not pass!");
|
|
3551
|
+
logger.log(
|
|
3552
|
+
`${chalkError(
|
|
3553
|
+
"X Error:"
|
|
3554
|
+
)} Update required: Version mismatches are a common source of bugs and errors. Please update or use \`--skip-update-check\` at your own risk.
|
|
3555
|
+
`
|
|
3556
|
+
);
|
|
3557
|
+
process.exit(1);
|
|
3558
|
+
}
|
|
3559
|
+
if (!embedded) {
|
|
3560
|
+
outro4("You've been warned!");
|
|
3561
|
+
}
|
|
3562
|
+
return hasOutput;
|
|
3563
|
+
}
|
|
3564
|
+
const installSpinner = spinner();
|
|
3565
|
+
installSpinner.start("Writing new package.json file");
|
|
3566
|
+
const packageJsonBackupPath = `${packageJsonPath}.bak`;
|
|
3567
|
+
await writeJSONFile(packageJsonBackupPath, readonlyPackageJson, true);
|
|
3568
|
+
const exitHandler = async (sig) => {
|
|
3569
|
+
log4.warn(
|
|
3570
|
+
`You may have to manually roll back any package.json changes. Backup written to ${packageJsonBackupPath}`
|
|
3571
|
+
);
|
|
3572
|
+
};
|
|
3573
|
+
process.prependOnceListener("exit", exitHandler);
|
|
3574
|
+
mutatePackageJsonWithUpdatedPackages(packageJson, versionMismatches, cliVersion);
|
|
3575
|
+
await writeJSONFile(packageJsonPath, packageJson, true);
|
|
3576
|
+
async function revertPackageJsonChanges() {
|
|
3577
|
+
await writeJSONFile(packageJsonPath, readonlyPackageJson, true);
|
|
3578
|
+
await removeFile(packageJsonBackupPath);
|
|
3579
|
+
}
|
|
3580
|
+
installSpinner.message("Installing new package versions");
|
|
3581
|
+
const jsProject = new JavascriptProject(projectPath);
|
|
3582
|
+
let packageManager;
|
|
3583
|
+
try {
|
|
3584
|
+
packageManager = await jsProject.getPackageManager();
|
|
3585
|
+
installSpinner.message(`Installing new package versions with ${packageManager}`);
|
|
3586
|
+
await jsProject.install();
|
|
3587
|
+
} catch (error) {
|
|
3588
|
+
installSpinner.stop(
|
|
3589
|
+
`Failed to install new package versions${packageManager ? ` with ${packageManager}` : ""}`
|
|
3590
|
+
);
|
|
3591
|
+
process.removeListener("exit", exitHandler);
|
|
3592
|
+
await revertPackageJsonChanges();
|
|
3593
|
+
throw error;
|
|
3594
|
+
}
|
|
3595
|
+
installSpinner.stop("Installed new package versions");
|
|
3596
|
+
process.removeListener("exit", exitHandler);
|
|
3597
|
+
await removeFile(packageJsonBackupPath);
|
|
3598
|
+
if (!embedded) {
|
|
3599
|
+
outro4(
|
|
3600
|
+
`Packages updated${newCliVersion ? " ..but you should really update your CLI too!" : ""}`
|
|
3601
|
+
);
|
|
3602
|
+
}
|
|
3603
|
+
return hasOutput;
|
|
3604
|
+
}
|
|
3605
|
+
function getTriggerDependencies(packageJson) {
|
|
3606
|
+
const deps = [];
|
|
3607
|
+
for (const type of ["dependencies", "devDependencies"]) {
|
|
3608
|
+
for (const [name, version2] of Object.entries(packageJson[type] ?? {})) {
|
|
3609
|
+
if (!version2) {
|
|
3610
|
+
continue;
|
|
3611
|
+
}
|
|
3612
|
+
if (version2.startsWith("workspace")) {
|
|
3613
|
+
continue;
|
|
3614
|
+
}
|
|
3615
|
+
if (!triggerPackageFilter.test(name)) {
|
|
3616
|
+
continue;
|
|
3617
|
+
}
|
|
3618
|
+
const ignoredPackages = ["@trigger.dev/companyicons"];
|
|
3619
|
+
if (ignoredPackages.includes(name)) {
|
|
3620
|
+
continue;
|
|
3621
|
+
}
|
|
3622
|
+
deps.push({ type, name, version: version2 });
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
return deps;
|
|
3626
|
+
}
|
|
3627
|
+
function mutatePackageJsonWithUpdatedPackages(packageJson, depsToUpdate, targetVersion) {
|
|
3628
|
+
for (const { type, name, version: version2 } of depsToUpdate) {
|
|
3629
|
+
if (!packageJson[type]) {
|
|
3630
|
+
throw new Error(
|
|
3631
|
+
`No ${type} entry found in package.json. Please try to upgrade manually instead.`
|
|
3632
|
+
);
|
|
3633
|
+
}
|
|
3634
|
+
packageJson[type][name] = targetVersion;
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
function printUpdateTable(depsToUpdate, targetVersion) {
|
|
3638
|
+
log4.message("Suggested updates");
|
|
3639
|
+
const tableData = depsToUpdate.map((dep) => ({
|
|
3640
|
+
package: dep.name,
|
|
3641
|
+
old: dep.version,
|
|
3642
|
+
new: targetVersion
|
|
3643
|
+
}));
|
|
3644
|
+
logger.table(tableData);
|
|
3645
|
+
}
|
|
3646
|
+
async function updateConfirmation(depsToUpdate, targetVersion) {
|
|
3647
|
+
printUpdateTable(depsToUpdate, targetVersion);
|
|
3648
|
+
let confirmMessage = "Would you like to apply those updates?";
|
|
3649
|
+
return await confirm({
|
|
3650
|
+
message: confirmMessage
|
|
3651
|
+
});
|
|
3652
|
+
}
|
|
3653
|
+
async function getPackageJson(absoluteProjectPath) {
|
|
3654
|
+
const packageJsonPath = join5(absoluteProjectPath, "package.json");
|
|
3655
|
+
const readonlyPackageJson = Object.freeze(await readJSONFile(packageJsonPath));
|
|
3656
|
+
const packageJson = structuredClone(readonlyPackageJson);
|
|
3657
|
+
return { packageJson, readonlyPackageJson, packageJsonPath };
|
|
3658
|
+
}
|
|
3659
|
+
|
|
2874
3660
|
// src/commands/deploy.ts
|
|
2875
|
-
import { Glob } from "glob";
|
|
2876
3661
|
var DeployCommandOptions = CommonCommandOptions.extend({
|
|
2877
3662
|
skipTypecheck: z4.boolean().default(false),
|
|
2878
3663
|
skipDeploy: z4.boolean().default(false),
|
|
2879
|
-
ignoreEnvVarCheck: z4.boolean().default(false),
|
|
2880
3664
|
env: z4.enum(["prod", "staging"]),
|
|
2881
3665
|
loadImage: z4.boolean().default(false),
|
|
2882
3666
|
buildPlatform: z4.enum(["linux/amd64", "linux/arm64"]).default("linux/amd64"),
|
|
@@ -2886,7 +3670,9 @@ var DeployCommandOptions = CommonCommandOptions.extend({
|
|
|
2886
3670
|
config: z4.string().optional(),
|
|
2887
3671
|
projectRef: z4.string().optional(),
|
|
2888
3672
|
outputMetafile: z4.string().optional(),
|
|
2889
|
-
apiUrl: z4.string().optional()
|
|
3673
|
+
apiUrl: z4.string().optional(),
|
|
3674
|
+
saveLogs: z4.boolean().default(false),
|
|
3675
|
+
skipUpdateCheck: z4.boolean().default(false)
|
|
2890
3676
|
});
|
|
2891
3677
|
function configureDeployCommand(program2) {
|
|
2892
3678
|
return commonOptions(
|
|
@@ -2894,12 +3680,9 @@ function configureDeployCommand(program2) {
|
|
|
2894
3680
|
"-e, --env <env>",
|
|
2895
3681
|
"Deploy to a specific environment (currently only prod and staging are supported)",
|
|
2896
3682
|
"prod"
|
|
2897
|
-
).option("--skip-typecheck", "Whether to skip the pre-build typecheck").option(
|
|
2898
|
-
"--ignore-env-var-check",
|
|
2899
|
-
"Detected missing environment variables won't block deployment"
|
|
2900
|
-
).option("-c, --config <config file>", "The name of the config file, found at [path]").option(
|
|
3683
|
+
).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(
|
|
2901
3684
|
"-p, --project-ref <project ref>",
|
|
2902
|
-
"The project ref. Required if there is no config file."
|
|
3685
|
+
"The project ref. Required if there is no config file. This will override the project specified in the config file."
|
|
2903
3686
|
)
|
|
2904
3687
|
).addOption(
|
|
2905
3688
|
new CommandOption(
|
|
@@ -2921,6 +3704,11 @@ function configureDeployCommand(program2) {
|
|
|
2921
3704
|
"--tag <tag>",
|
|
2922
3705
|
"(Coming soon) Specify the tag to use when pushing the image to the registry"
|
|
2923
3706
|
).hideHelp()
|
|
3707
|
+
).addOption(
|
|
3708
|
+
new CommandOption(
|
|
3709
|
+
"--ignore-env-var-check",
|
|
3710
|
+
"(deprecated) Detected missing environment variables won't block deployment"
|
|
3711
|
+
).hideHelp()
|
|
2924
3712
|
).addOption(new CommandOption("-D, --skip-deploy", "Skip deploying the image").hideHelp()).addOption(
|
|
2925
3713
|
new CommandOption("--load-image", "Load the built image into your local docker").hideHelp()
|
|
2926
3714
|
).addOption(
|
|
@@ -2933,10 +3721,15 @@ function configureDeployCommand(program2) {
|
|
|
2933
3721
|
"--output-metafile <path>",
|
|
2934
3722
|
"If provided, will save the esbuild metafile for the build to the specified path"
|
|
2935
3723
|
).hideHelp()
|
|
2936
|
-
).
|
|
3724
|
+
).addOption(
|
|
3725
|
+
new CommandOption(
|
|
3726
|
+
"--save-logs",
|
|
3727
|
+
"If provided, will save logs even for successful builds"
|
|
3728
|
+
).hideHelp()
|
|
3729
|
+
).action(async (path7, options) => {
|
|
2937
3730
|
await handleTelemetry(async () => {
|
|
2938
3731
|
await printStandloneInitialBanner(true);
|
|
2939
|
-
await deployCommand(
|
|
3732
|
+
await deployCommand(path7, options);
|
|
2940
3733
|
});
|
|
2941
3734
|
});
|
|
2942
3735
|
}
|
|
@@ -2947,7 +3740,10 @@ async function deployCommand(dir, options) {
|
|
|
2947
3740
|
}
|
|
2948
3741
|
async function _deployCommand(dir, options) {
|
|
2949
3742
|
const span = trace2.getSpan(context.active());
|
|
2950
|
-
|
|
3743
|
+
intro4("Deploying project");
|
|
3744
|
+
if (!options.skipUpdateCheck) {
|
|
3745
|
+
await updateTriggerPackages(dir, { ...options }, true, true);
|
|
3746
|
+
}
|
|
2951
3747
|
const authorization = await login({
|
|
2952
3748
|
embedded: true,
|
|
2953
3749
|
defaultApiUrl: options.apiUrl,
|
|
@@ -2990,7 +3786,7 @@ async function _deployCommand(dir, options) {
|
|
|
2990
3786
|
throw new Error(deploymentEnv.error);
|
|
2991
3787
|
}
|
|
2992
3788
|
const environmentClient = new CliApiClient(authorization.auth.apiUrl, deploymentEnv.data.apiKey);
|
|
2993
|
-
|
|
3789
|
+
log5.step(
|
|
2994
3790
|
`Preparing to deploy "${deploymentEnv.data.name}" (${resolvedConfig.config.project}) to ${options.env}`
|
|
2995
3791
|
);
|
|
2996
3792
|
const compilation = await compileProject(
|
|
@@ -2999,15 +3795,6 @@ async function _deployCommand(dir, options) {
|
|
|
2999
3795
|
resolvedConfig.status === "file" ? resolvedConfig.path : void 0
|
|
3000
3796
|
);
|
|
3001
3797
|
logger.debug("Compilation result", { compilation });
|
|
3002
|
-
if (compilation.envVars.length > 0) {
|
|
3003
|
-
await checkEnvVars(
|
|
3004
|
-
compilation.envVars ?? [],
|
|
3005
|
-
resolvedConfig.config,
|
|
3006
|
-
options,
|
|
3007
|
-
environmentClient,
|
|
3008
|
-
authorization.dashboardUrl
|
|
3009
|
-
);
|
|
3010
|
-
}
|
|
3011
3798
|
const deploymentResponse = await environmentClient.initializeDeployment({
|
|
3012
3799
|
contentHash: compilation.contentHash,
|
|
3013
3800
|
userId: authorization.userId
|
|
@@ -3021,7 +3808,7 @@ async function _deployCommand(dir, options) {
|
|
|
3021
3808
|
);
|
|
3022
3809
|
}
|
|
3023
3810
|
const version2 = deploymentResponse.data.version;
|
|
3024
|
-
const deploymentSpinner =
|
|
3811
|
+
const deploymentSpinner = spinner();
|
|
3025
3812
|
deploymentSpinner.start(`Deploying version ${version2}`);
|
|
3026
3813
|
const selfHostedRegistryHost = deploymentResponse.data.registryHost ?? options.registry;
|
|
3027
3814
|
const registryHost = selfHostedRegistryHost ?? "registry.trigger.dev";
|
|
@@ -3046,28 +3833,56 @@ async function _deployCommand(dir, options) {
|
|
|
3046
3833
|
"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."
|
|
3047
3834
|
);
|
|
3048
3835
|
}
|
|
3049
|
-
return buildAndPushImage(
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3836
|
+
return buildAndPushImage(
|
|
3837
|
+
{
|
|
3838
|
+
registryHost,
|
|
3839
|
+
auth: authorization.auth.accessToken,
|
|
3840
|
+
imageTag: deploymentResponse.data.imageTag,
|
|
3841
|
+
buildId: deploymentResponse.data.externalBuildData.buildId,
|
|
3842
|
+
buildToken: deploymentResponse.data.externalBuildData.buildToken,
|
|
3843
|
+
buildProjectId: deploymentResponse.data.externalBuildData.projectId,
|
|
3844
|
+
cwd: compilation.path,
|
|
3845
|
+
projectId: resolvedConfig.config.project,
|
|
3846
|
+
deploymentId: deploymentResponse.data.id,
|
|
3847
|
+
deploymentVersion: deploymentResponse.data.version,
|
|
3848
|
+
contentHash: deploymentResponse.data.contentHash,
|
|
3849
|
+
projectRef: resolvedConfig.config.project,
|
|
3850
|
+
loadImage: options.loadImage,
|
|
3851
|
+
buildPlatform: options.buildPlatform
|
|
3852
|
+
},
|
|
3853
|
+
deploymentSpinner
|
|
3854
|
+
);
|
|
3065
3855
|
};
|
|
3066
3856
|
const image = await buildImage();
|
|
3857
|
+
const warnings = checkLogsForWarnings(image.logs);
|
|
3858
|
+
if (!warnings.ok) {
|
|
3859
|
+
await failDeploy(
|
|
3860
|
+
deploymentResponse.data.shortCode,
|
|
3861
|
+
warnings.summary,
|
|
3862
|
+
image.logs,
|
|
3863
|
+
deploymentSpinner,
|
|
3864
|
+
warnings.warnings,
|
|
3865
|
+
warnings.errors
|
|
3866
|
+
);
|
|
3867
|
+
throw new SkipLoggingError(`Failed to build project image: ${warnings.summary}`);
|
|
3868
|
+
}
|
|
3067
3869
|
if (!image.ok) {
|
|
3068
|
-
|
|
3870
|
+
await failDeploy(
|
|
3871
|
+
deploymentResponse.data.shortCode,
|
|
3872
|
+
image.error,
|
|
3873
|
+
image.logs,
|
|
3874
|
+
deploymentSpinner,
|
|
3875
|
+
warnings.warnings
|
|
3876
|
+
);
|
|
3069
3877
|
throw new SkipLoggingError(`Failed to build project image: ${image.error}`);
|
|
3070
3878
|
}
|
|
3879
|
+
const preExitTasks = async () => {
|
|
3880
|
+
printWarnings(warnings.warnings);
|
|
3881
|
+
if (options.saveLogs) {
|
|
3882
|
+
const logPath = await saveLogs(deploymentResponse.data.shortCode, image.logs);
|
|
3883
|
+
log5.info(`Build logs have been saved to ${logPath}`);
|
|
3884
|
+
}
|
|
3885
|
+
};
|
|
3071
3886
|
const imageReference = options.selfHosted ? `${selfHostedRegistryHost ? `${selfHostedRegistryHost}/` : ""}${image.image}${image.digest ? `@${image.digest}` : ""}` : `${registryHost}/${image.image}${image.digest ? `@${image.digest}` : ""}`;
|
|
3072
3887
|
span?.setAttributes({
|
|
3073
3888
|
"image.reference": imageReference
|
|
@@ -3076,6 +3891,7 @@ async function _deployCommand(dir, options) {
|
|
|
3076
3891
|
deploymentSpinner.stop(
|
|
3077
3892
|
`Project image built: ${imageReference}. Skipping deployment as requested`
|
|
3078
3893
|
);
|
|
3894
|
+
await preExitTasks();
|
|
3079
3895
|
throw new SkipCommandError("Skipping deployment as requested");
|
|
3080
3896
|
}
|
|
3081
3897
|
deploymentSpinner.message(
|
|
@@ -3090,6 +3906,7 @@ async function _deployCommand(dir, options) {
|
|
|
3090
3906
|
);
|
|
3091
3907
|
if (!startIndexingResponse.success) {
|
|
3092
3908
|
deploymentSpinner.stop(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
3909
|
+
await preExitTasks();
|
|
3093
3910
|
throw new SkipLoggingError(`Failed to start indexing: ${startIndexingResponse.error}`);
|
|
3094
3911
|
}
|
|
3095
3912
|
const finishedDeployment = await waitForDeploymentToFinish(
|
|
@@ -3098,26 +3915,33 @@ async function _deployCommand(dir, options) {
|
|
|
3098
3915
|
);
|
|
3099
3916
|
if (!finishedDeployment) {
|
|
3100
3917
|
deploymentSpinner.stop(`Deployment failed to complete`);
|
|
3918
|
+
await preExitTasks();
|
|
3101
3919
|
throw new SkipLoggingError("Deployment failed to complete: unknown issue");
|
|
3102
3920
|
}
|
|
3103
3921
|
if (typeof finishedDeployment === "string") {
|
|
3104
3922
|
deploymentSpinner.stop(`Deployment failed to complete: ${finishedDeployment}`);
|
|
3923
|
+
await preExitTasks();
|
|
3105
3924
|
throw new SkipLoggingError(`Deployment failed to complete: ${finishedDeployment}`);
|
|
3106
3925
|
}
|
|
3107
|
-
const deploymentLink =
|
|
3926
|
+
const deploymentLink = terminalLink2(
|
|
3108
3927
|
"View deployment",
|
|
3109
3928
|
`${authorization.dashboardUrl}/projects/v3/${resolvedConfig.config.project}/deployments/${finishedDeployment.shortCode}`
|
|
3110
3929
|
);
|
|
3111
3930
|
switch (finishedDeployment.status) {
|
|
3112
3931
|
case "DEPLOYED": {
|
|
3113
|
-
|
|
3932
|
+
if (warnings.warnings.length > 0) {
|
|
3933
|
+
deploymentSpinner.stop("Deployment completed with warnings");
|
|
3934
|
+
} else {
|
|
3935
|
+
deploymentSpinner.stop("Deployment completed");
|
|
3936
|
+
}
|
|
3937
|
+
await preExitTasks();
|
|
3114
3938
|
const taskCount = finishedDeployment.worker?.tasks.length ?? 0;
|
|
3115
3939
|
if (taskCount === 0) {
|
|
3116
|
-
|
|
3940
|
+
outro5(
|
|
3117
3941
|
`Version ${version2} deployed with no detected tasks. Please make sure you are exporting tasks in your project. ${deploymentLink}`
|
|
3118
3942
|
);
|
|
3119
3943
|
} else {
|
|
3120
|
-
|
|
3944
|
+
outro5(
|
|
3121
3945
|
`Version ${version2} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${deploymentLink}`
|
|
3122
3946
|
);
|
|
3123
3947
|
}
|
|
@@ -3125,10 +3949,29 @@ async function _deployCommand(dir, options) {
|
|
|
3125
3949
|
}
|
|
3126
3950
|
case "FAILED": {
|
|
3127
3951
|
if (finishedDeployment.errorData) {
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3952
|
+
if (finishedDeployment.errorData.name === "TaskMetadataParseError") {
|
|
3953
|
+
const errorJson = safeJsonParse(finishedDeployment.errorData.stack);
|
|
3954
|
+
if (errorJson) {
|
|
3955
|
+
const parsedError2 = TaskMetadataFailedToParseData.safeParse(errorJson);
|
|
3956
|
+
if (parsedError2.success) {
|
|
3957
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3958
|
+
logTaskMetadataParseError(parsedError2.data.zodIssues, parsedError2.data.tasks);
|
|
3959
|
+
await preExitTasks();
|
|
3960
|
+
throw new SkipLoggingError(
|
|
3961
|
+
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3962
|
+
);
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
const parsedError = finishedDeployment.errorData.stack ? parseBuildErrorStack(finishedDeployment.errorData) ?? finishedDeployment.errorData.message : finishedDeployment.errorData.message;
|
|
3967
|
+
if (typeof parsedError === "string") {
|
|
3968
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3969
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
3970
|
+
} else {
|
|
3971
|
+
deploymentSpinner.stop(`Deployment encountered an error. ${deploymentLink}`);
|
|
3972
|
+
logESMRequireError(parsedError, resolvedConfig);
|
|
3973
|
+
}
|
|
3974
|
+
await preExitTasks();
|
|
3132
3975
|
throw new SkipLoggingError(
|
|
3133
3976
|
`Deployment encountered an error: ${finishedDeployment.errorData.name}`
|
|
3134
3977
|
);
|
|
@@ -3136,62 +3979,132 @@ async function _deployCommand(dir, options) {
|
|
|
3136
3979
|
deploymentSpinner.stop(
|
|
3137
3980
|
`Deployment failed with an unknown error. Please contact eric@trigger.dev for help. ${deploymentLink}`
|
|
3138
3981
|
);
|
|
3982
|
+
await preExitTasks();
|
|
3139
3983
|
throw new SkipLoggingError("Deployment failed with an unknown error");
|
|
3140
3984
|
}
|
|
3141
3985
|
}
|
|
3142
3986
|
case "CANCELED": {
|
|
3143
3987
|
deploymentSpinner.stop(`Deployment was canceled. ${deploymentLink}`);
|
|
3988
|
+
await preExitTasks();
|
|
3144
3989
|
throw new SkipLoggingError("Deployment was canceled");
|
|
3145
3990
|
}
|
|
3146
3991
|
case "TIMED_OUT": {
|
|
3147
3992
|
deploymentSpinner.stop(`Deployment timed out. ${deploymentLink}`);
|
|
3993
|
+
await preExitTasks();
|
|
3148
3994
|
throw new SkipLoggingError("Deployment timed out");
|
|
3149
3995
|
}
|
|
3150
3996
|
}
|
|
3151
3997
|
}
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
`${apiUrl}/projects/v3/${config.project}/environment-variables`
|
|
3173
|
-
)
|
|
3174
|
-
)}`
|
|
3175
|
-
);
|
|
3176
|
-
span.setAttributes({
|
|
3177
|
-
"envVars.missing": missingEnvironmentVariables
|
|
3178
|
-
});
|
|
3179
|
-
if (!options.ignoreEnvVarCheck) {
|
|
3180
|
-
throw new SkipLoggingError("Found missing environment variables");
|
|
3181
|
-
} else {
|
|
3182
|
-
span.end();
|
|
3183
|
-
return;
|
|
3184
|
-
}
|
|
3185
|
-
}
|
|
3186
|
-
environmentVariablesSpinner.stop(`Environment variable check passed`);
|
|
3187
|
-
}
|
|
3188
|
-
span.end();
|
|
3189
|
-
} catch (e) {
|
|
3190
|
-
recordSpanException4(span, e);
|
|
3191
|
-
span.end();
|
|
3192
|
-
throw e;
|
|
3998
|
+
function printErrors(errors) {
|
|
3999
|
+
for (const error of errors ?? []) {
|
|
4000
|
+
log5.error(`${chalkError("Error:")} ${error}`);
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
function printWarnings(warnings) {
|
|
4004
|
+
for (const warning of warnings ?? []) {
|
|
4005
|
+
log5.warn(`${chalkWarning("Warning:")} ${warning}`);
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
function checkLogsForWarnings(logs) {
|
|
4009
|
+
const warnings = [
|
|
4010
|
+
{
|
|
4011
|
+
regex: /prisma:warn We could not find your Prisma schema/,
|
|
4012
|
+
message: `Prisma generate failed to find the default schema. Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4013
|
+
"Config docs",
|
|
4014
|
+
docs.config.prisma
|
|
4015
|
+
)}
|
|
4016
|
+
Custom schema paths require a postinstall script like this: \`prisma generate --schema=./custom/path/to/schema.prisma\``,
|
|
4017
|
+
shouldFail: true
|
|
3193
4018
|
}
|
|
3194
|
-
|
|
4019
|
+
];
|
|
4020
|
+
const errorMessages2 = [];
|
|
4021
|
+
const warningMessages = [];
|
|
4022
|
+
let shouldFail = false;
|
|
4023
|
+
for (const warning of warnings) {
|
|
4024
|
+
const matches = logs.match(warning.regex);
|
|
4025
|
+
if (!matches) {
|
|
4026
|
+
continue;
|
|
4027
|
+
}
|
|
4028
|
+
const message = getMessageFromTemplate(warning.message, matches.groups);
|
|
4029
|
+
if (warning.shouldFail) {
|
|
4030
|
+
shouldFail = true;
|
|
4031
|
+
errorMessages2.push(message);
|
|
4032
|
+
} else {
|
|
4033
|
+
warningMessages.push(message);
|
|
4034
|
+
}
|
|
4035
|
+
}
|
|
4036
|
+
if (shouldFail) {
|
|
4037
|
+
return {
|
|
4038
|
+
ok: false,
|
|
4039
|
+
summary: "Build succeeded with critical warnings. Will not proceed",
|
|
4040
|
+
warnings: warningMessages,
|
|
4041
|
+
errors: errorMessages2
|
|
4042
|
+
};
|
|
4043
|
+
}
|
|
4044
|
+
return {
|
|
4045
|
+
ok: true,
|
|
4046
|
+
warnings: warningMessages
|
|
4047
|
+
};
|
|
4048
|
+
}
|
|
4049
|
+
function checkLogsForErrors(logs) {
|
|
4050
|
+
const errors = [
|
|
4051
|
+
{
|
|
4052
|
+
regex: /Error: Provided --schema at (?<schema>.*) doesn't exist/,
|
|
4053
|
+
message: `Prisma generate failed to find the specified schema at "$schema".
|
|
4054
|
+
Did you include it in config.additionalFiles? ${terminalLink2(
|
|
4055
|
+
"Config docs",
|
|
4056
|
+
docs.config.prisma
|
|
4057
|
+
)}`
|
|
4058
|
+
},
|
|
4059
|
+
{
|
|
4060
|
+
regex: /sh: 1: (?<packageOrBinary>.*): not found/,
|
|
4061
|
+
message: `$packageOrBinary not found
|
|
4062
|
+
|
|
4063
|
+
If it's a package: Include it in ${terminalLink2(
|
|
4064
|
+
"config.additionalPackages",
|
|
4065
|
+
docs.config.prisma
|
|
4066
|
+
)}
|
|
4067
|
+
If it's a binary: Please ${terminalLink2(
|
|
4068
|
+
"get in touch",
|
|
4069
|
+
getInTouch
|
|
4070
|
+
)} and we'll see what we can do!`
|
|
4071
|
+
}
|
|
4072
|
+
];
|
|
4073
|
+
for (const error of errors) {
|
|
4074
|
+
const matches = logs.match(error.regex);
|
|
4075
|
+
if (!matches) {
|
|
4076
|
+
continue;
|
|
4077
|
+
}
|
|
4078
|
+
const message = getMessageFromTemplate(error.message, matches.groups);
|
|
4079
|
+
log5.error(`${chalkError("Error:")} ${message}`);
|
|
4080
|
+
break;
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
function getMessageFromTemplate(template, replacer) {
|
|
4084
|
+
let message = template;
|
|
4085
|
+
if (replacer) {
|
|
4086
|
+
for (const [key, value] of Object.entries(replacer)) {
|
|
4087
|
+
message = message.replaceAll(`$${key}`, value);
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
return message;
|
|
4091
|
+
}
|
|
4092
|
+
async function saveLogs(shortCode, logs) {
|
|
4093
|
+
const logPath = join6(await createTempDir(), `build-${shortCode}.log`);
|
|
4094
|
+
await writeFile2(logPath, logs);
|
|
4095
|
+
return logPath;
|
|
4096
|
+
}
|
|
4097
|
+
async function failDeploy(shortCode, errorSummary, logs, deploymentSpinner, warnings, errors) {
|
|
4098
|
+
deploymentSpinner.stop(`Failed to deploy project`);
|
|
4099
|
+
if (logs.trim() !== "") {
|
|
4100
|
+
const logPath = await saveLogs(shortCode, logs);
|
|
4101
|
+
printWarnings(warnings);
|
|
4102
|
+
printErrors(errors);
|
|
4103
|
+
checkLogsForErrors(logs);
|
|
4104
|
+
outro5(`${chalkError("Error:")} ${errorSummary}. Full build logs have been saved to ${logPath}`);
|
|
4105
|
+
} else {
|
|
4106
|
+
outro5(`${chalkError("Error:")} ${errorSummary}.`);
|
|
4107
|
+
}
|
|
3195
4108
|
}
|
|
3196
4109
|
async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds = 60) {
|
|
3197
4110
|
return tracer.startActiveSpan("waitForDeploymentToFinish", async (span) => {
|
|
@@ -3227,7 +4140,7 @@ async function waitForDeploymentToFinish(deploymentId, client, timeoutInSeconds
|
|
|
3227
4140
|
}
|
|
3228
4141
|
});
|
|
3229
4142
|
}
|
|
3230
|
-
async function buildAndPushImage(options) {
|
|
4143
|
+
async function buildAndPushImage(options, updater) {
|
|
3231
4144
|
return tracer.startActiveSpan("buildAndPushImage", async (span) => {
|
|
3232
4145
|
span.setAttributes({
|
|
3233
4146
|
"options.registryHost": options.registryHost,
|
|
@@ -3283,15 +4196,24 @@ async function buildAndPushImage(options) {
|
|
|
3283
4196
|
});
|
|
3284
4197
|
const errors = [];
|
|
3285
4198
|
try {
|
|
3286
|
-
await new Promise((res, rej) => {
|
|
4199
|
+
const processCode = await new Promise((res, rej) => {
|
|
3287
4200
|
childProcess2.stderr?.on("data", (data) => {
|
|
3288
|
-
const
|
|
3289
|
-
|
|
3290
|
-
|
|
4201
|
+
const text3 = data.toString();
|
|
4202
|
+
const lines = text3.split("\n").filter(Boolean);
|
|
4203
|
+
errors.push(...lines);
|
|
4204
|
+
logger.debug(text3);
|
|
3291
4205
|
});
|
|
3292
4206
|
childProcess2.on("error", (e) => rej(e));
|
|
3293
|
-
childProcess2.on("close", () => res());
|
|
4207
|
+
childProcess2.on("close", (code) => res(code));
|
|
3294
4208
|
});
|
|
4209
|
+
const logs = extractLogs(errors);
|
|
4210
|
+
if (processCode !== 0) {
|
|
4211
|
+
return {
|
|
4212
|
+
ok: false,
|
|
4213
|
+
error: `Error building image`,
|
|
4214
|
+
logs
|
|
4215
|
+
};
|
|
4216
|
+
}
|
|
3295
4217
|
const digest = extractImageDigest(errors);
|
|
3296
4218
|
span.setAttributes({
|
|
3297
4219
|
"image.digest": digest
|
|
@@ -3300,6 +4222,7 @@ async function buildAndPushImage(options) {
|
|
|
3300
4222
|
return {
|
|
3301
4223
|
ok: true,
|
|
3302
4224
|
image: options.imageTag,
|
|
4225
|
+
logs,
|
|
3303
4226
|
digest
|
|
3304
4227
|
};
|
|
3305
4228
|
} catch (e) {
|
|
@@ -3307,7 +4230,8 @@ async function buildAndPushImage(options) {
|
|
|
3307
4230
|
span.end();
|
|
3308
4231
|
return {
|
|
3309
4232
|
ok: false,
|
|
3310
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4233
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4234
|
+
logs: extractLogs(errors)
|
|
3311
4235
|
};
|
|
3312
4236
|
}
|
|
3313
4237
|
});
|
|
@@ -3353,15 +4277,22 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3353
4277
|
const errors = [];
|
|
3354
4278
|
let digest;
|
|
3355
4279
|
try {
|
|
3356
|
-
await new Promise((res, rej) => {
|
|
4280
|
+
const processCode = await new Promise((res, rej) => {
|
|
3357
4281
|
buildProcess.stderr?.on("data", (data) => {
|
|
3358
|
-
const
|
|
3359
|
-
errors.push(
|
|
3360
|
-
logger.debug(
|
|
4282
|
+
const text3 = data.toString();
|
|
4283
|
+
errors.push(text3);
|
|
4284
|
+
logger.debug(text3);
|
|
3361
4285
|
});
|
|
3362
4286
|
buildProcess.on("error", (e) => rej(e));
|
|
3363
|
-
buildProcess.on("close", () => res());
|
|
4287
|
+
buildProcess.on("close", (code) => res(code));
|
|
3364
4288
|
});
|
|
4289
|
+
if (processCode !== 0) {
|
|
4290
|
+
return {
|
|
4291
|
+
ok: false,
|
|
4292
|
+
error: "Error building image",
|
|
4293
|
+
logs: extractLogs(errors)
|
|
4294
|
+
};
|
|
4295
|
+
}
|
|
3365
4296
|
digest = extractImageDigest(errors);
|
|
3366
4297
|
span.setAttributes({
|
|
3367
4298
|
"image.digest": digest
|
|
@@ -3371,7 +4302,8 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3371
4302
|
span.end();
|
|
3372
4303
|
return {
|
|
3373
4304
|
ok: false,
|
|
3374
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4305
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4306
|
+
logs: extractLogs(errors)
|
|
3375
4307
|
};
|
|
3376
4308
|
}
|
|
3377
4309
|
const pushArgs = ["push", imageRef].filter(Boolean);
|
|
@@ -3382,25 +4314,33 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3382
4314
|
cwd: options.cwd
|
|
3383
4315
|
});
|
|
3384
4316
|
try {
|
|
3385
|
-
await new Promise((res, rej) => {
|
|
4317
|
+
const processCode = await new Promise((res, rej) => {
|
|
3386
4318
|
pushProcess.stdout?.on("data", (data) => {
|
|
3387
|
-
const
|
|
3388
|
-
logger.debug(
|
|
4319
|
+
const text3 = data.toString();
|
|
4320
|
+
logger.debug(text3);
|
|
3389
4321
|
});
|
|
3390
4322
|
pushProcess.stderr?.on("data", (data) => {
|
|
3391
|
-
const
|
|
3392
|
-
logger.debug(
|
|
4323
|
+
const text3 = data.toString();
|
|
4324
|
+
logger.debug(text3);
|
|
3393
4325
|
});
|
|
3394
4326
|
pushProcess.on("error", (e) => rej(e));
|
|
3395
|
-
pushProcess.on("close", () => res());
|
|
4327
|
+
pushProcess.on("close", (code) => res(code));
|
|
3396
4328
|
});
|
|
4329
|
+
if (processCode !== 0) {
|
|
4330
|
+
return {
|
|
4331
|
+
ok: false,
|
|
4332
|
+
error: "Error pushing image",
|
|
4333
|
+
logs: extractLogs(errors)
|
|
4334
|
+
};
|
|
4335
|
+
}
|
|
3397
4336
|
span.end();
|
|
3398
4337
|
} catch (e) {
|
|
3399
4338
|
recordSpanException4(span, e);
|
|
3400
4339
|
span.end();
|
|
3401
4340
|
return {
|
|
3402
4341
|
ok: false,
|
|
3403
|
-
error: e instanceof Error ? e.message : JSON.stringify(e)
|
|
4342
|
+
error: e instanceof Error ? e.message : JSON.stringify(e),
|
|
4343
|
+
logs: extractLogs(errors)
|
|
3404
4344
|
};
|
|
3405
4345
|
}
|
|
3406
4346
|
}
|
|
@@ -3408,21 +4348,25 @@ async function buildAndPushSelfHostedImage(options) {
|
|
|
3408
4348
|
return {
|
|
3409
4349
|
ok: true,
|
|
3410
4350
|
image: options.imageTag,
|
|
3411
|
-
digest
|
|
4351
|
+
digest,
|
|
4352
|
+
logs: extractLogs(errors)
|
|
3412
4353
|
};
|
|
3413
4354
|
});
|
|
3414
4355
|
}
|
|
3415
4356
|
function extractImageDigest(outputs) {
|
|
3416
|
-
const imageDigestRegex = /sha256:[a-f0-9]{64}/;
|
|
4357
|
+
const imageDigestRegex = /pushing manifest for .+(?<digest>sha256:[a-f0-9]{64})/;
|
|
3417
4358
|
for (const line of outputs) {
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
}
|
|
4359
|
+
const imageDigestMatch = line.match(imageDigestRegex);
|
|
4360
|
+
const digest = imageDigestMatch?.groups?.digest;
|
|
4361
|
+
if (digest) {
|
|
4362
|
+
return digest;
|
|
3423
4363
|
}
|
|
3424
4364
|
}
|
|
3425
4365
|
}
|
|
4366
|
+
function extractLogs(outputs) {
|
|
4367
|
+
const cleanedOutputs = outputs.map((line) => line.trim()).filter((line) => line !== "");
|
|
4368
|
+
return cleanedOutputs.map((line) => line.trim()).join("\n");
|
|
4369
|
+
}
|
|
3426
4370
|
async function compileProject(config, options, configPath) {
|
|
3427
4371
|
return await tracer.startActiveSpan("compileProject", async (span) => {
|
|
3428
4372
|
try {
|
|
@@ -3432,25 +4376,25 @@ async function compileProject(config, options, configPath) {
|
|
|
3432
4376
|
throw new Error("Typecheck failed, aborting deployment");
|
|
3433
4377
|
}
|
|
3434
4378
|
}
|
|
3435
|
-
const compileSpinner =
|
|
4379
|
+
const compileSpinner = spinner();
|
|
3436
4380
|
compileSpinner.start(`Building project in ${config.projectDir}`);
|
|
3437
4381
|
const taskFiles = await gatherTaskFiles(config);
|
|
3438
4382
|
const workerFacade = readFileSync2(
|
|
3439
|
-
|
|
3440
|
-
"file://",
|
|
3441
|
-
""
|
|
3442
|
-
),
|
|
4383
|
+
join6(cliRootPath(), "workers", "prod", "worker-facade.js"),
|
|
3443
4384
|
"utf-8"
|
|
3444
4385
|
);
|
|
3445
|
-
const workerSetupPath =
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
4386
|
+
const workerSetupPath = join6(cliRootPath(), "workers", "prod", "worker-setup.js");
|
|
4387
|
+
let workerContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
4388
|
+
"__WORKER_SETUP__",
|
|
4389
|
+
`import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
|
|
4390
|
+
);
|
|
3449
4391
|
if (configPath) {
|
|
3450
4392
|
logger.debug("Importing project config from", { configPath });
|
|
3451
4393
|
workerContents = workerContents.replace(
|
|
3452
4394
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
3453
|
-
`import * as importedConfigExports from "${
|
|
4395
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
4396
|
+
configPath
|
|
4397
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
3454
4398
|
);
|
|
3455
4399
|
} else {
|
|
3456
4400
|
workerContents = workerContents.replace(
|
|
@@ -3499,13 +4443,10 @@ async function compileProject(config, options, configPath) {
|
|
|
3499
4443
|
throw new Error("Build failed, aborting deployment");
|
|
3500
4444
|
}
|
|
3501
4445
|
if (options.outputMetafile) {
|
|
3502
|
-
await writeJSONFile(
|
|
4446
|
+
await writeJSONFile(join6(options.outputMetafile, "worker.json"), result.metafile);
|
|
3503
4447
|
}
|
|
3504
4448
|
const entryPointContents = readFileSync2(
|
|
3505
|
-
|
|
3506
|
-
"file://",
|
|
3507
|
-
""
|
|
3508
|
-
),
|
|
4449
|
+
join6(cliRootPath(), "workers", "prod", "entry-point.js"),
|
|
3509
4450
|
"utf-8"
|
|
3510
4451
|
);
|
|
3511
4452
|
const entryPointResult = await build2({
|
|
@@ -3548,58 +4489,68 @@ async function compileProject(config, options, configPath) {
|
|
|
3548
4489
|
}
|
|
3549
4490
|
if (options.outputMetafile) {
|
|
3550
4491
|
await writeJSONFile(
|
|
3551
|
-
|
|
4492
|
+
join6(options.outputMetafile, "entry-point.json"),
|
|
3552
4493
|
entryPointResult.metafile
|
|
3553
4494
|
);
|
|
3554
4495
|
}
|
|
3555
4496
|
const tempDir = await createTempDir();
|
|
3556
4497
|
logger.debug(`Writing compiled files to ${tempDir}`);
|
|
3557
|
-
const metaOutput = result.metafile.outputs[
|
|
4498
|
+
const metaOutput = result.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3558
4499
|
invariant(metaOutput, "Meta output for the result build is missing");
|
|
3559
|
-
const entryPointMetaOutput = entryPointResult.metafile.outputs[
|
|
4500
|
+
const entryPointMetaOutput = entryPointResult.metafile.outputs[posix.join("out", "stdin.js")];
|
|
3560
4501
|
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
|
|
3561
4502
|
const workerOutputFile = result.outputFiles.find(
|
|
3562
|
-
(file) => file.path ===
|
|
4503
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3563
4504
|
);
|
|
3564
4505
|
invariant(workerOutputFile, "Output file for the result build is missing");
|
|
3565
4506
|
const workerSourcemapFile = result.outputFiles.find(
|
|
3566
|
-
(file) => file.path ===
|
|
4507
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js.map")
|
|
3567
4508
|
);
|
|
3568
4509
|
invariant(workerSourcemapFile, "Sourcemap file for the result build is missing");
|
|
3569
4510
|
const entryPointOutputFile = entryPointResult.outputFiles.find(
|
|
3570
|
-
(file) => file.path ===
|
|
4511
|
+
(file) => file.path === join6(config.projectDir, "out", "stdin.js")
|
|
3571
4512
|
);
|
|
3572
4513
|
invariant(entryPointOutputFile, "Output file for the entryPoint build is missing");
|
|
3573
4514
|
await writeFile2(
|
|
3574
|
-
|
|
4515
|
+
join6(tempDir, "worker.js"),
|
|
3575
4516
|
`${workerOutputFile.text}
|
|
3576
4517
|
//# sourceMappingURL=worker.js.map`
|
|
3577
4518
|
);
|
|
3578
|
-
await writeFile2(
|
|
3579
|
-
await writeFile2(
|
|
4519
|
+
await writeFile2(join6(tempDir, "worker.js.map"), workerSourcemapFile.text);
|
|
4520
|
+
await writeFile2(join6(tempDir, "index.js"), entryPointOutputFile.text);
|
|
3580
4521
|
logger.debug("Getting the imports for the worker and entryPoint builds", {
|
|
3581
4522
|
workerImports: metaOutput.imports,
|
|
3582
4523
|
entryPointImports: entryPointMetaOutput.imports
|
|
3583
4524
|
});
|
|
3584
4525
|
const allImports = [...metaOutput.imports, ...entryPointMetaOutput.imports];
|
|
3585
|
-
const
|
|
3586
|
-
const dependencies2 = await gatherRequiredDependencies(
|
|
3587
|
-
allImports,
|
|
3588
|
-
config,
|
|
3589
|
-
externalPackageJson
|
|
3590
|
-
);
|
|
4526
|
+
const javascriptProject = new JavascriptProject(config.projectDir);
|
|
4527
|
+
const dependencies2 = await gatherRequiredDependencies(allImports, config, javascriptProject);
|
|
3591
4528
|
const packageJsonContents = {
|
|
3592
4529
|
name: "trigger-worker",
|
|
3593
4530
|
version: "0.0.0",
|
|
3594
4531
|
description: "",
|
|
3595
4532
|
dependencies: dependencies2,
|
|
3596
4533
|
scripts: {
|
|
3597
|
-
|
|
4534
|
+
...javascriptProject.scripts
|
|
3598
4535
|
}
|
|
3599
4536
|
};
|
|
3600
|
-
await writeJSONFile(
|
|
3601
|
-
await copyAdditionalFiles(config, tempDir);
|
|
3602
|
-
|
|
4537
|
+
await writeJSONFile(join6(tempDir, "package.json"), packageJsonContents);
|
|
4538
|
+
const copyResult = await copyAdditionalFiles(config, tempDir);
|
|
4539
|
+
if (!copyResult.ok) {
|
|
4540
|
+
compileSpinner.stop("Project built with warnings");
|
|
4541
|
+
log5.warn(
|
|
4542
|
+
`No additionalFiles matches for:
|
|
4543
|
+
|
|
4544
|
+
${copyResult.noMatches.map((glob) => `- "${glob}"`).join("\n")}
|
|
4545
|
+
|
|
4546
|
+
If this is unexpected you should check your ${terminalLink2(
|
|
4547
|
+
"glob patterns",
|
|
4548
|
+
"https://github.com/isaacs/node-glob?tab=readme-ov-file#glob-primer"
|
|
4549
|
+
)} are valid.`
|
|
4550
|
+
);
|
|
4551
|
+
} else {
|
|
4552
|
+
compileSpinner.stop("Project built successfully");
|
|
4553
|
+
}
|
|
3603
4554
|
const resolvingDependenciesResult = await resolveDependencies(
|
|
3604
4555
|
tempDir,
|
|
3605
4556
|
packageJsonContents,
|
|
@@ -3607,29 +4558,20 @@ async function compileProject(config, options, configPath) {
|
|
|
3607
4558
|
options
|
|
3608
4559
|
);
|
|
3609
4560
|
if (!resolvingDependenciesResult) {
|
|
3610
|
-
throw new
|
|
4561
|
+
throw new SkipLoggingError("Failed to resolve dependencies");
|
|
3611
4562
|
}
|
|
3612
|
-
const containerFilePath =
|
|
3613
|
-
|
|
3614
|
-
).href.replace("file://", "");
|
|
3615
|
-
await copyFile(containerFilePath, join4(tempDir, "Containerfile"));
|
|
4563
|
+
const containerFilePath = join6(cliRootPath(), "Containerfile.prod");
|
|
4564
|
+
await copyFile(containerFilePath, join6(tempDir, "Containerfile"));
|
|
3616
4565
|
const contentHasher = createHash("sha256");
|
|
3617
4566
|
contentHasher.update(Buffer.from(entryPointOutputFile.text));
|
|
3618
4567
|
contentHasher.update(Buffer.from(workerOutputFile.text));
|
|
3619
4568
|
contentHasher.update(Buffer.from(JSON.stringify(dependencies2)));
|
|
3620
4569
|
const contentHash = contentHasher.digest("hex");
|
|
3621
|
-
const workerSetupEnvVars = await findAllEnvironmentVariableReferencesInFile(workerSetupPath);
|
|
3622
|
-
const workerFacadeEnvVars = findAllEnvironmentVariableReferences(workerContents);
|
|
3623
|
-
const envVars = findAllEnvironmentVariableReferences(workerOutputFile.text);
|
|
3624
|
-
const finalEnvVars = envVars.filter(
|
|
3625
|
-
(envVar) => !workerFacadeEnvVars.includes(envVar) && !workerSetupEnvVars.includes(envVar)
|
|
3626
|
-
);
|
|
3627
4570
|
span.setAttributes({
|
|
3628
|
-
contentHash
|
|
3629
|
-
envVars: finalEnvVars
|
|
4571
|
+
contentHash
|
|
3630
4572
|
});
|
|
3631
4573
|
span.end();
|
|
3632
|
-
return { path: tempDir, contentHash
|
|
4574
|
+
return { path: tempDir, contentHash };
|
|
3633
4575
|
} catch (e) {
|
|
3634
4576
|
recordSpanException4(span, e);
|
|
3635
4577
|
span.end();
|
|
@@ -3639,13 +4581,13 @@ async function compileProject(config, options, configPath) {
|
|
|
3639
4581
|
}
|
|
3640
4582
|
async function resolveDependencies(projectDir, packageJsonContents, config, options) {
|
|
3641
4583
|
return await tracer.startActiveSpan("resolveDependencies", async (span) => {
|
|
3642
|
-
const resolvingDepsSpinner =
|
|
4584
|
+
const resolvingDepsSpinner = spinner();
|
|
3643
4585
|
resolvingDepsSpinner.start("Resolving dependencies");
|
|
3644
4586
|
const hasher = createHash("sha256");
|
|
3645
4587
|
hasher.update(JSON.stringify(packageJsonContents));
|
|
3646
4588
|
const digest = hasher.digest("hex").slice(0, 16);
|
|
3647
|
-
const cacheDir =
|
|
3648
|
-
const cachePath =
|
|
4589
|
+
const cacheDir = join6(config.projectDir, ".trigger", "cache");
|
|
4590
|
+
const cachePath = join6(cacheDir, `${digest}.json`);
|
|
3649
4591
|
span.setAttributes({
|
|
3650
4592
|
"packageJson.digest": digest,
|
|
3651
4593
|
"cache.path": cachePath,
|
|
@@ -3654,7 +4596,7 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3654
4596
|
try {
|
|
3655
4597
|
const cachedPackageLock = await readFile2(cachePath, "utf-8");
|
|
3656
4598
|
logger.debug(`Using cached package-lock.json for ${digest}`);
|
|
3657
|
-
await writeFile2(
|
|
4599
|
+
await writeFile2(join6(projectDir, "package-lock.json"), cachedPackageLock);
|
|
3658
4600
|
span.setAttributes({
|
|
3659
4601
|
"cache.hit": true
|
|
3660
4602
|
});
|
|
@@ -3677,21 +4619,44 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3677
4619
|
cwd: projectDir,
|
|
3678
4620
|
stdio: logger.loggerLevel === "debug" ? "inherit" : "pipe"
|
|
3679
4621
|
});
|
|
3680
|
-
const packageLockContents = await readFile2(
|
|
4622
|
+
const packageLockContents = await readFile2(join6(projectDir, "package-lock.json"), "utf-8");
|
|
3681
4623
|
logger.debug(`Writing package-lock.json to cache for ${digest}`);
|
|
3682
4624
|
await mkdir(cacheDir, { recursive: true });
|
|
3683
4625
|
await writeFile2(cachePath, packageLockContents);
|
|
3684
|
-
await writeFile2(
|
|
4626
|
+
await writeFile2(join6(projectDir, "package-lock.json"), packageLockContents);
|
|
3685
4627
|
span.end();
|
|
3686
4628
|
resolvingDepsSpinner.stop("Dependencies resolved");
|
|
3687
4629
|
return true;
|
|
3688
4630
|
} catch (installError) {
|
|
3689
|
-
logger.debug(`Failed to resolve dependencies: ${JSON.stringify(installError)}`);
|
|
3690
4631
|
recordSpanException4(span, installError);
|
|
3691
4632
|
span.end();
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
4633
|
+
const parsedError = parseNpmInstallError(installError);
|
|
4634
|
+
if (typeof parsedError === "string") {
|
|
4635
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies: ${parsedError}`);
|
|
4636
|
+
} else {
|
|
4637
|
+
switch (parsedError.type) {
|
|
4638
|
+
case "package-not-found-error": {
|
|
4639
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4640
|
+
logger.log(
|
|
4641
|
+
`
|
|
4642
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4643
|
+
parsedError.packageName
|
|
4644
|
+
)} could not be found in the npm registry.`
|
|
4645
|
+
);
|
|
4646
|
+
break;
|
|
4647
|
+
}
|
|
4648
|
+
case "no-matching-version-error": {
|
|
4649
|
+
resolvingDepsSpinner.stop(`Failed to resolve dependencies`);
|
|
4650
|
+
logger.log(
|
|
4651
|
+
`
|
|
4652
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
4653
|
+
parsedError.packageName
|
|
4654
|
+
)} could not resolve because the version doesn't exist`
|
|
4655
|
+
);
|
|
4656
|
+
break;
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
3695
4660
|
return false;
|
|
3696
4661
|
}
|
|
3697
4662
|
}
|
|
@@ -3700,7 +4665,7 @@ async function resolveDependencies(projectDir, packageJsonContents, config, opti
|
|
|
3700
4665
|
async function typecheckProject(config, options) {
|
|
3701
4666
|
return await tracer.startActiveSpan("typecheckProject", async (span) => {
|
|
3702
4667
|
try {
|
|
3703
|
-
const typecheckSpinner =
|
|
4668
|
+
const typecheckSpinner = spinner();
|
|
3704
4669
|
typecheckSpinner.start("Typechecking project");
|
|
3705
4670
|
const tscTypecheck = execa2("npm", ["exec", "tsc", "--", "--noEmit"], {
|
|
3706
4671
|
cwd: config.projectDir
|
|
@@ -3710,8 +4675,8 @@ async function typecheckProject(config, options) {
|
|
|
3710
4675
|
tscTypecheck.stdout?.on("data", (chunk) => stdouts.push(chunk.toString()));
|
|
3711
4676
|
tscTypecheck.stderr?.on("data", (chunk) => stderrs.push(chunk.toString()));
|
|
3712
4677
|
try {
|
|
3713
|
-
await new Promise((
|
|
3714
|
-
tscTypecheck.addListener("exit", (code) => code === 0 ?
|
|
4678
|
+
await new Promise((resolve5, reject) => {
|
|
4679
|
+
tscTypecheck.addListener("exit", (code) => code === 0 ? resolve5(code) : reject(code));
|
|
3715
4680
|
});
|
|
3716
4681
|
} catch (error) {
|
|
3717
4682
|
typecheckSpinner.stop(
|
|
@@ -3735,7 +4700,7 @@ async function typecheckProject(config, options) {
|
|
|
3735
4700
|
}
|
|
3736
4701
|
});
|
|
3737
4702
|
}
|
|
3738
|
-
async function gatherRequiredDependencies(imports, config,
|
|
4703
|
+
async function gatherRequiredDependencies(imports, config, project) {
|
|
3739
4704
|
const dependencies2 = {};
|
|
3740
4705
|
for (const file of imports) {
|
|
3741
4706
|
if (file.kind !== "require-call" && file.kind !== "dynamic-import" || !file.external) {
|
|
@@ -3745,7 +4710,7 @@ async function gatherRequiredDependencies(imports, config, projectPackageJson) {
|
|
|
3745
4710
|
if (dependencies2[packageName]) {
|
|
3746
4711
|
continue;
|
|
3747
4712
|
}
|
|
3748
|
-
const externalDependencyVersion = (
|
|
4713
|
+
const externalDependencyVersion = await project.resolve(packageName);
|
|
3749
4714
|
if (externalDependencyVersion) {
|
|
3750
4715
|
dependencies2[packageName] = stripWorkspaceFromVersion(externalDependencyVersion);
|
|
3751
4716
|
continue;
|
|
@@ -3765,16 +4730,17 @@ async function gatherRequiredDependencies(imports, config, projectPackageJson) {
|
|
|
3765
4730
|
dependencies2[packageParts.name] = packageParts.version;
|
|
3766
4731
|
continue;
|
|
3767
4732
|
} else {
|
|
3768
|
-
const externalDependencyVersion = {
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
}[packageName];
|
|
4733
|
+
const externalDependencyVersion = await project.resolve(packageParts.name, {
|
|
4734
|
+
allowDev: true
|
|
4735
|
+
});
|
|
3772
4736
|
if (externalDependencyVersion) {
|
|
3773
4737
|
dependencies2[packageParts.name] = externalDependencyVersion;
|
|
3774
4738
|
continue;
|
|
3775
4739
|
} else {
|
|
3776
|
-
logger.
|
|
3777
|
-
|
|
4740
|
+
logger.log(
|
|
4741
|
+
`${chalkWarning("X Warning:")} Could not find version for package ${chalkPurple(
|
|
4742
|
+
packageName
|
|
4743
|
+
)}, add a version specifier to the package name (e.g. ${packageParts.name}@latest) or add it to your project's package.json`
|
|
3778
4744
|
);
|
|
3779
4745
|
}
|
|
3780
4746
|
}
|
|
@@ -3784,8 +4750,9 @@ async function gatherRequiredDependencies(imports, config, projectPackageJson) {
|
|
|
3784
4750
|
}
|
|
3785
4751
|
async function copyAdditionalFiles(config, tempDir) {
|
|
3786
4752
|
const additionalFiles = config.additionalFiles ?? [];
|
|
4753
|
+
const noMatches = [];
|
|
3787
4754
|
if (additionalFiles.length === 0) {
|
|
3788
|
-
return;
|
|
4755
|
+
return { ok: true };
|
|
3789
4756
|
}
|
|
3790
4757
|
return await tracer.startActiveSpan(
|
|
3791
4758
|
"copyAdditionalFiles",
|
|
@@ -3799,22 +4766,55 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3799
4766
|
logger.debug(`Copying files to ${tempDir}`, {
|
|
3800
4767
|
additionalFiles
|
|
3801
4768
|
});
|
|
3802
|
-
const
|
|
4769
|
+
const globOptions = {
|
|
3803
4770
|
withFileTypes: true,
|
|
3804
4771
|
ignore: ["node_modules"],
|
|
3805
4772
|
cwd: config.projectDir,
|
|
3806
4773
|
nodir: true
|
|
3807
|
-
}
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
)
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
4774
|
+
};
|
|
4775
|
+
const globs = [];
|
|
4776
|
+
let i = 0;
|
|
4777
|
+
for (const additionalFile of additionalFiles) {
|
|
4778
|
+
let glob;
|
|
4779
|
+
if (i === 0) {
|
|
4780
|
+
glob = new Glob(additionalFile, globOptions);
|
|
4781
|
+
} else {
|
|
4782
|
+
const previousGlob = globs[i - 1];
|
|
4783
|
+
if (!previousGlob) {
|
|
4784
|
+
logger.error("No previous glob, this shouldn't happen", { i, additionalFiles });
|
|
4785
|
+
continue;
|
|
4786
|
+
}
|
|
4787
|
+
glob = new Glob(additionalFile, previousGlob);
|
|
4788
|
+
}
|
|
4789
|
+
if (!(Symbol.asyncIterator in glob)) {
|
|
4790
|
+
logger.error("Glob should be an async iterator", { glob });
|
|
4791
|
+
throw new Error("Unrecoverable error while copying additional files");
|
|
4792
|
+
}
|
|
4793
|
+
let matches = 0;
|
|
4794
|
+
for await (const file of glob) {
|
|
4795
|
+
matches++;
|
|
4796
|
+
const pathInsideTempDir = relative3(config.projectDir, file.fullpath()).split(posix.sep).filter((p) => p !== "..").join(posix.sep);
|
|
4797
|
+
const relativeDestinationPath = join6(tempDir, pathInsideTempDir);
|
|
4798
|
+
logger.debug(`Copying file ${file.fullpath()} to ${relativeDestinationPath}`);
|
|
4799
|
+
await mkdir(dirname(relativeDestinationPath), { recursive: true });
|
|
4800
|
+
await copyFile(file.fullpath(), relativeDestinationPath);
|
|
4801
|
+
}
|
|
4802
|
+
if (matches === 0) {
|
|
4803
|
+
noMatches.push(additionalFile);
|
|
4804
|
+
}
|
|
4805
|
+
globs[i] = glob;
|
|
4806
|
+
i++;
|
|
3816
4807
|
}
|
|
3817
4808
|
span.end();
|
|
4809
|
+
if (noMatches.length > 0) {
|
|
4810
|
+
return {
|
|
4811
|
+
ok: false,
|
|
4812
|
+
noMatches
|
|
4813
|
+
};
|
|
4814
|
+
}
|
|
4815
|
+
return {
|
|
4816
|
+
ok: true
|
|
4817
|
+
};
|
|
3818
4818
|
} catch (error) {
|
|
3819
4819
|
recordSpanException4(span, error);
|
|
3820
4820
|
span.end();
|
|
@@ -3825,7 +4825,7 @@ async function copyAdditionalFiles(config, tempDir) {
|
|
|
3825
4825
|
}
|
|
3826
4826
|
async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
3827
4827
|
const tmpDir = await createTempDir();
|
|
3828
|
-
const dockerConfigPath =
|
|
4828
|
+
const dockerConfigPath = join6(tmpDir, "config.json");
|
|
3829
4829
|
await writeJSONFile(dockerConfigPath, {
|
|
3830
4830
|
auths: {
|
|
3831
4831
|
[registryHost]: {
|
|
@@ -3836,43 +4836,20 @@ async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
|
|
|
3836
4836
|
logger.debug(`Writing docker config to ${dockerConfigPath}`);
|
|
3837
4837
|
return tmpDir;
|
|
3838
4838
|
}
|
|
3839
|
-
async function findAllEnvironmentVariableReferencesInFile(filePath) {
|
|
3840
|
-
const fileContents = await readFile2(filePath, "utf-8");
|
|
3841
|
-
return findAllEnvironmentVariableReferences(fileContents);
|
|
3842
|
-
}
|
|
3843
|
-
var IGNORED_ENV_VARS = ["NODE_ENV", "SHELL", "HOME", "PWD", "LOGNAME", "USER", "PATH", "DEBUG"];
|
|
3844
|
-
function findAllEnvironmentVariableReferences(code) {
|
|
3845
|
-
const regex = /\bprocess\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
|
|
3846
|
-
const matches = code.matchAll(regex);
|
|
3847
|
-
const matchesArray = Array.from(matches, (match) => match[1]).filter(Boolean);
|
|
3848
|
-
const filteredMatches = matchesArray.filter((match) => !IGNORED_ENV_VARS.includes(match));
|
|
3849
|
-
return Array.from(new Set(filteredMatches));
|
|
3850
|
-
}
|
|
3851
|
-
function arrayToSentence(items) {
|
|
3852
|
-
if (items.length === 1 && typeof items[0] === "string") {
|
|
3853
|
-
return items[0];
|
|
3854
|
-
}
|
|
3855
|
-
if (items.length === 2) {
|
|
3856
|
-
return `${items[0]} and ${items[1]}`;
|
|
3857
|
-
}
|
|
3858
|
-
return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
3859
|
-
}
|
|
3860
4839
|
|
|
3861
4840
|
// src/commands/dev.tsx
|
|
3862
4841
|
import {
|
|
3863
|
-
ZodMessageHandler as ZodMessageHandler2,
|
|
3864
|
-
ZodMessageSender as ZodMessageSender2,
|
|
3865
4842
|
clientWebsocketMessages,
|
|
3866
4843
|
detectDependencyVersion as detectDependencyVersion2,
|
|
3867
4844
|
serverWebsocketMessages
|
|
3868
4845
|
} from "@trigger.dev/core/v3";
|
|
4846
|
+
import { ZodMessageHandler as ZodMessageHandler2, ZodMessageSender as ZodMessageSender2 } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3869
4847
|
import { watch } from "chokidar";
|
|
3870
4848
|
import { context as context2 } from "esbuild";
|
|
3871
|
-
import { resolve as importResolve2 } from "import-meta-resolve";
|
|
3872
4849
|
import { render, useInput } from "ink";
|
|
3873
4850
|
import { createHash as createHash2 } from "node:crypto";
|
|
3874
4851
|
import fs7, { readFileSync as readFileSync3 } from "node:fs";
|
|
3875
|
-
import { basename, dirname as dirname3, join as
|
|
4852
|
+
import { basename as basename2, dirname as dirname3, join as join7, normalize } from "node:path";
|
|
3876
4853
|
import pDebounce from "p-debounce";
|
|
3877
4854
|
import { WebSocket } from "partysocket";
|
|
3878
4855
|
import React, { Suspense, useEffect } from "react";
|
|
@@ -3888,23 +4865,30 @@ var UncaughtExceptionError = class extends Error {
|
|
|
3888
4865
|
this.name = "UncaughtExceptionError";
|
|
3889
4866
|
}
|
|
3890
4867
|
};
|
|
4868
|
+
var TaskMetadataParseError = class extends Error {
|
|
4869
|
+
constructor(zodIssues, tasks) {
|
|
4870
|
+
super(`Failed to parse task metadata`);
|
|
4871
|
+
this.zodIssues = zodIssues;
|
|
4872
|
+
this.tasks = tasks;
|
|
4873
|
+
this.name = "TaskMetadataParseError";
|
|
4874
|
+
}
|
|
4875
|
+
};
|
|
3891
4876
|
|
|
3892
4877
|
// src/workers/dev/backgroundWorker.ts
|
|
3893
4878
|
import {
|
|
3894
4879
|
SemanticInternalAttributes,
|
|
3895
4880
|
TaskRunErrorCodes,
|
|
3896
|
-
ZodMessageHandler,
|
|
3897
|
-
ZodMessageSender,
|
|
3898
4881
|
childToWorkerMessages,
|
|
3899
4882
|
correctErrorStackTrace,
|
|
3900
4883
|
formatDurationMilliseconds,
|
|
3901
4884
|
workerToChildMessages
|
|
3902
4885
|
} from "@trigger.dev/core/v3";
|
|
4886
|
+
import { ZodMessageHandler, ZodMessageSender } from "@trigger.dev/core/v3/zodMessageHandler";
|
|
3903
4887
|
import dotenv from "dotenv";
|
|
3904
4888
|
import { Evt } from "evt";
|
|
3905
4889
|
import { fork } from "node:child_process";
|
|
3906
|
-
import { dirname as dirname2, resolve as
|
|
3907
|
-
import
|
|
4890
|
+
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
4891
|
+
import terminalLink3 from "terminal-link";
|
|
3908
4892
|
var BackgroundWorkerCoordinator = class {
|
|
3909
4893
|
constructor(baseURL) {
|
|
3910
4894
|
this.baseURL = baseURL;
|
|
@@ -3989,7 +4973,7 @@ var BackgroundWorkerCoordinator = class {
|
|
|
3989
4973
|
const logsUrl = `${this.baseURL}/runs/${execution.run.id}`;
|
|
3990
4974
|
const pipe = chalkGrey("|");
|
|
3991
4975
|
const bullet = chalkGrey("\u25CB");
|
|
3992
|
-
const link = chalkLink(
|
|
4976
|
+
const link = chalkLink(terminalLink3("View logs", logsUrl));
|
|
3993
4977
|
let timestampPrefix = chalkGrey(prettyPrintDate(payload.execution.attempt.startedAt));
|
|
3994
4978
|
const workerPrefix = chalkWorker(record.version);
|
|
3995
4979
|
const taskPrefix = chalkTask(execution.task.id);
|
|
@@ -4062,8 +5046,8 @@ var CancelledProcessError = class extends Error {
|
|
|
4062
5046
|
}
|
|
4063
5047
|
};
|
|
4064
5048
|
var BackgroundWorker = class {
|
|
4065
|
-
constructor(
|
|
4066
|
-
this.path =
|
|
5049
|
+
constructor(path7, params) {
|
|
5050
|
+
this.path = path7;
|
|
4067
5051
|
this.params = params;
|
|
4068
5052
|
}
|
|
4069
5053
|
_initialized = false;
|
|
@@ -4097,7 +5081,13 @@ var BackgroundWorker = class {
|
|
|
4097
5081
|
await installPackages(this.params.dependencies, { cwd: dirname2(this.path) });
|
|
4098
5082
|
}
|
|
4099
5083
|
let resolved = false;
|
|
4100
|
-
|
|
5084
|
+
const cwd = dirname2(this.path);
|
|
5085
|
+
const fullEnv = {
|
|
5086
|
+
...this.params.env,
|
|
5087
|
+
...this.#readEnvVars()
|
|
5088
|
+
};
|
|
5089
|
+
logger.debug("Initializing worker", { path: this.path, cwd, fullEnv });
|
|
5090
|
+
this.tasks = await new Promise((resolve5, reject) => {
|
|
4101
5091
|
const child = fork(this.path, {
|
|
4102
5092
|
stdio: [
|
|
4103
5093
|
/*stdin*/
|
|
@@ -4108,10 +5098,8 @@ var BackgroundWorker = class {
|
|
|
4108
5098
|
"pipe",
|
|
4109
5099
|
"ipc"
|
|
4110
5100
|
],
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
...this.#readEnvVars()
|
|
4114
|
-
}
|
|
5101
|
+
cwd,
|
|
5102
|
+
env: fullEnv
|
|
4115
5103
|
});
|
|
4116
5104
|
const timeout = setTimeout(() => {
|
|
4117
5105
|
if (resolved) {
|
|
@@ -4126,13 +5114,18 @@ var BackgroundWorker = class {
|
|
|
4126
5114
|
if (message.type === "TASKS_READY" && !resolved) {
|
|
4127
5115
|
clearTimeout(timeout);
|
|
4128
5116
|
resolved = true;
|
|
4129
|
-
|
|
5117
|
+
resolve5(message.payload.tasks);
|
|
4130
5118
|
child.kill();
|
|
4131
5119
|
} else if (message.type === "UNCAUGHT_EXCEPTION") {
|
|
4132
5120
|
clearTimeout(timeout);
|
|
4133
5121
|
resolved = true;
|
|
4134
5122
|
reject(new UncaughtExceptionError(message.payload.error, message.payload.origin));
|
|
4135
5123
|
child.kill();
|
|
5124
|
+
} else if (message.type === "TASKS_FAILED_TO_PARSE") {
|
|
5125
|
+
clearTimeout(timeout);
|
|
5126
|
+
resolved = true;
|
|
5127
|
+
reject(new TaskMetadataParseError(message.payload.zodIssues, message.payload.tasks));
|
|
5128
|
+
child.kill();
|
|
4136
5129
|
}
|
|
4137
5130
|
});
|
|
4138
5131
|
child.on("exit", (code) => {
|
|
@@ -4142,6 +5135,9 @@ var BackgroundWorker = class {
|
|
|
4142
5135
|
reject(new Error(`Worker exited with code ${code}`));
|
|
4143
5136
|
}
|
|
4144
5137
|
});
|
|
5138
|
+
child.stdout?.on("data", (data) => {
|
|
5139
|
+
logger.log(data.toString());
|
|
5140
|
+
});
|
|
4145
5141
|
});
|
|
4146
5142
|
this._initialized = true;
|
|
4147
5143
|
}
|
|
@@ -4158,7 +5154,7 @@ var BackgroundWorker = class {
|
|
|
4158
5154
|
}
|
|
4159
5155
|
if (!this._taskRunProcesses.has(payload.execution.run.id)) {
|
|
4160
5156
|
const taskRunProcess = new TaskRunProcess(
|
|
4161
|
-
payload.execution
|
|
5157
|
+
payload.execution,
|
|
4162
5158
|
this.path,
|
|
4163
5159
|
{
|
|
4164
5160
|
...this.params.env,
|
|
@@ -4253,7 +5249,7 @@ var BackgroundWorker = class {
|
|
|
4253
5249
|
const result = {};
|
|
4254
5250
|
dotenv.config({
|
|
4255
5251
|
processEnv: result,
|
|
4256
|
-
path: [".env", ".env.local", ".env.development.local"].map((p) =>
|
|
5252
|
+
path: [".env", ".env.local", ".env.development.local"].map((p) => resolve3(process.cwd(), p))
|
|
4257
5253
|
});
|
|
4258
5254
|
process.env.TRIGGER_API_URL && (result.TRIGGER_API_URL = process.env.TRIGGER_API_URL);
|
|
4259
5255
|
delete result.TRIGGER_API_URL;
|
|
@@ -4268,9 +5264,9 @@ var BackgroundWorker = class {
|
|
|
4268
5264
|
}
|
|
4269
5265
|
};
|
|
4270
5266
|
var TaskRunProcess = class {
|
|
4271
|
-
constructor(
|
|
4272
|
-
this.
|
|
4273
|
-
this.path =
|
|
5267
|
+
constructor(execution, path7, env, metadata, worker) {
|
|
5268
|
+
this.execution = execution;
|
|
5269
|
+
this.path = path7;
|
|
4274
5270
|
this.env = env;
|
|
4275
5271
|
this.metadata = metadata;
|
|
4276
5272
|
this.worker = worker;
|
|
@@ -4300,9 +5296,20 @@ var TaskRunProcess = class {
|
|
|
4300
5296
|
await this.cleanup(true);
|
|
4301
5297
|
}
|
|
4302
5298
|
async initialize() {
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
5299
|
+
const fullEnv = {
|
|
5300
|
+
...this.execution.run.isTest ? { TRIGGER_LOG_LEVEL: "debug" } : {},
|
|
5301
|
+
...this.env,
|
|
5302
|
+
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
5303
|
+
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
5304
|
+
}),
|
|
5305
|
+
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
5306
|
+
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
5307
|
+
};
|
|
5308
|
+
const cwd = dirname2(this.path);
|
|
5309
|
+
logger.debug(`[${this.execution.run.id}] initializing task run process`, {
|
|
5310
|
+
env: fullEnv,
|
|
5311
|
+
path: this.path,
|
|
5312
|
+
cwd
|
|
4306
5313
|
});
|
|
4307
5314
|
this._child = fork(this.path, {
|
|
4308
5315
|
stdio: [
|
|
@@ -4314,15 +5321,8 @@ var TaskRunProcess = class {
|
|
|
4314
5321
|
"pipe",
|
|
4315
5322
|
"ipc"
|
|
4316
5323
|
],
|
|
4317
|
-
cwd
|
|
4318
|
-
env:
|
|
4319
|
-
...this.env,
|
|
4320
|
-
OTEL_RESOURCE_ATTRIBUTES: JSON.stringify({
|
|
4321
|
-
[SemanticInternalAttributes.PROJECT_DIR]: this.worker.projectConfig.projectDir
|
|
4322
|
-
}),
|
|
4323
|
-
OTEL_EXPORTER_OTLP_COMPRESSION: "none",
|
|
4324
|
-
...this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}
|
|
4325
|
-
},
|
|
5324
|
+
cwd,
|
|
5325
|
+
env: fullEnv,
|
|
4326
5326
|
execArgv: this.worker.debuggerOn ? ["--inspect-brk", "--trace-uncaught", "--no-warnings=ExperimentalWarning"] : ["--trace-uncaught", "--no-warnings=ExperimentalWarning"]
|
|
4327
5327
|
});
|
|
4328
5328
|
this._child.on("message", this.#handleMessage.bind(this));
|
|
@@ -4334,18 +5334,24 @@ var TaskRunProcess = class {
|
|
|
4334
5334
|
if (kill && this._isBeingKilled) {
|
|
4335
5335
|
return;
|
|
4336
5336
|
}
|
|
4337
|
-
logger.debug(`[${this.
|
|
5337
|
+
logger.debug(`[${this.execution.run.id}] cleaning up task run process`, { kill });
|
|
4338
5338
|
await this._sender.send("CLEANUP", {
|
|
4339
5339
|
flush: true,
|
|
4340
5340
|
kill
|
|
4341
5341
|
});
|
|
4342
5342
|
this._isBeingKilled = kill;
|
|
5343
|
+
setTimeout(() => {
|
|
5344
|
+
if (this._child && !this._child.killed) {
|
|
5345
|
+
logger.debug(`[${this.execution.run.id}] killing task run process after timeout`);
|
|
5346
|
+
this._child.kill();
|
|
5347
|
+
}
|
|
5348
|
+
}, 5e3);
|
|
4343
5349
|
}
|
|
4344
5350
|
async executeTaskRun(payload) {
|
|
4345
5351
|
let resolver;
|
|
4346
5352
|
let rejecter;
|
|
4347
|
-
const promise = new Promise((
|
|
4348
|
-
resolver =
|
|
5353
|
+
const promise = new Promise((resolve5, reject) => {
|
|
5354
|
+
resolver = resolve5;
|
|
4349
5355
|
rejecter = reject;
|
|
4350
5356
|
});
|
|
4351
5357
|
this._attemptStatuses.set(payload.execution.attempt.id, "PENDING");
|
|
@@ -4365,10 +5371,13 @@ var TaskRunProcess = class {
|
|
|
4365
5371
|
if (!completion.ok && typeof completion.retry !== "undefined") {
|
|
4366
5372
|
return;
|
|
4367
5373
|
}
|
|
4368
|
-
if (execution.run.id === this.
|
|
5374
|
+
if (execution.run.id === this.execution.run.id) {
|
|
4369
5375
|
return;
|
|
4370
5376
|
}
|
|
4371
|
-
logger.debug(`[${this.
|
|
5377
|
+
logger.debug(`[${this.execution.run.id}] task run completed notification`, {
|
|
5378
|
+
completion,
|
|
5379
|
+
execution
|
|
5380
|
+
});
|
|
4372
5381
|
this._sender.send("TASK_RUN_COMPLETED_NOTIFICATION", {
|
|
4373
5382
|
completion,
|
|
4374
5383
|
execution
|
|
@@ -4393,6 +5402,7 @@ var TaskRunProcess = class {
|
|
|
4393
5402
|
break;
|
|
4394
5403
|
}
|
|
4395
5404
|
case "READY_TO_DISPOSE": {
|
|
5405
|
+
logger.debug(`[${this.execution.run.id}] task run process is ready to dispose`);
|
|
4396
5406
|
this.#kill();
|
|
4397
5407
|
break;
|
|
4398
5408
|
}
|
|
@@ -4406,7 +5416,7 @@ var TaskRunProcess = class {
|
|
|
4406
5416
|
}
|
|
4407
5417
|
}
|
|
4408
5418
|
async #handleExit(code) {
|
|
4409
|
-
logger.debug(`[${this.
|
|
5419
|
+
logger.debug(`[${this.execution.run.id}] task run process exiting`, { code });
|
|
4410
5420
|
for (const [id, status] of this._attemptStatuses.entries()) {
|
|
4411
5421
|
if (status === "PENDING") {
|
|
4412
5422
|
this._attemptStatuses.set(id, "REJECTED");
|
|
@@ -4428,10 +5438,14 @@ var TaskRunProcess = class {
|
|
|
4428
5438
|
}
|
|
4429
5439
|
#handleLog(data) {
|
|
4430
5440
|
if (!this._currentExecution) {
|
|
5441
|
+
logger.log(`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4431
5442
|
return;
|
|
4432
5443
|
}
|
|
5444
|
+
const runId = chalkRun(
|
|
5445
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5446
|
+
);
|
|
4433
5447
|
logger.log(
|
|
4434
|
-
|
|
5448
|
+
`${chalkGrey("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4435
5449
|
);
|
|
4436
5450
|
}
|
|
4437
5451
|
#handleStdErr(data) {
|
|
@@ -4439,63 +5453,105 @@ var TaskRunProcess = class {
|
|
|
4439
5453
|
return;
|
|
4440
5454
|
}
|
|
4441
5455
|
if (!this._currentExecution) {
|
|
4442
|
-
logger.
|
|
5456
|
+
logger.log(`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${data.toString()}`);
|
|
4443
5457
|
return;
|
|
4444
5458
|
}
|
|
4445
|
-
|
|
4446
|
-
|
|
5459
|
+
const runId = chalkRun(
|
|
5460
|
+
`${this._currentExecution.run.id}.${this._currentExecution.attempt.number}`
|
|
5461
|
+
);
|
|
5462
|
+
logger.log(
|
|
5463
|
+
`${chalkError("\u25CB")} ${chalkGrey(prettyPrintDate(/* @__PURE__ */ new Date()))} ${runId} ${data.toString()}`
|
|
4447
5464
|
);
|
|
4448
5465
|
}
|
|
4449
5466
|
#kill() {
|
|
4450
5467
|
if (this._child && !this._child.killed) {
|
|
5468
|
+
logger.debug(`[${this.execution.run.id}] killing task run process`);
|
|
4451
5469
|
this._child?.kill();
|
|
4452
5470
|
}
|
|
4453
5471
|
}
|
|
4454
5472
|
};
|
|
4455
5473
|
|
|
5474
|
+
// src/utilities/runtimeCheck.ts
|
|
5475
|
+
function runtimeCheck(minimumMajor, minimumMinor) {
|
|
5476
|
+
if (typeof process === "undefined") {
|
|
5477
|
+
throw "The dev CLI can only be run in a Node.js compatible environment";
|
|
5478
|
+
}
|
|
5479
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
5480
|
+
const isBun = typeof process.versions.bun === "string";
|
|
5481
|
+
if (major < minimumMajor || major === minimumMajor && minor < minimumMinor) {
|
|
5482
|
+
if (isBun) {
|
|
5483
|
+
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}`;
|
|
5484
|
+
} else {
|
|
5485
|
+
throw `The dev CLI requires at least Node.js ${minimumMajor}.${minimumMinor}. You are running Node.js ${process.versions.node}`;
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
logger.debug(
|
|
5489
|
+
`Node.js version: ${process.versions.node}${isBun ? ` (Bun ${process.versions.bun})` : ""}`
|
|
5490
|
+
);
|
|
5491
|
+
}
|
|
5492
|
+
|
|
4456
5493
|
// src/commands/dev.tsx
|
|
5494
|
+
import { findUp as findUp3, pathExists as pathExists2 } from "find-up";
|
|
4457
5495
|
var apiClient;
|
|
4458
5496
|
var DevCommandOptions = CommonCommandOptions.extend({
|
|
4459
5497
|
debugger: z5.boolean().default(false),
|
|
4460
5498
|
debugOtel: z5.boolean().default(false),
|
|
4461
5499
|
config: z5.string().optional(),
|
|
4462
|
-
projectRef: z5.string().optional()
|
|
5500
|
+
projectRef: z5.string().optional(),
|
|
5501
|
+
skipUpdateCheck: z5.boolean().default(false)
|
|
4463
5502
|
});
|
|
4464
5503
|
function configureDevCommand(program2) {
|
|
4465
5504
|
return commonOptions(
|
|
4466
|
-
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(
|
|
5505
|
+
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(
|
|
4467
5506
|
"-p, --project-ref <project ref>",
|
|
4468
5507
|
"The project ref. Required if there is no config file."
|
|
4469
|
-
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging")
|
|
4470
|
-
).action(async (
|
|
5508
|
+
).option("--debugger", "Enable the debugger").option("--debug-otel", "Enable OpenTelemetry debugging").option("--skip-update-check", "Skip checking for @trigger.dev package updates")
|
|
5509
|
+
).action(async (path7, options) => {
|
|
4471
5510
|
wrapCommandAction("dev", DevCommandOptions, options, async (opts) => {
|
|
4472
|
-
await devCommand(
|
|
5511
|
+
await devCommand(path7, opts);
|
|
4473
5512
|
});
|
|
4474
5513
|
});
|
|
4475
5514
|
}
|
|
5515
|
+
var MINIMUM_NODE_MAJOR = 18;
|
|
5516
|
+
var MINIMUM_NODE_MINOR = 16;
|
|
4476
5517
|
async function devCommand(dir, options) {
|
|
5518
|
+
try {
|
|
5519
|
+
runtimeCheck(MINIMUM_NODE_MAJOR, MINIMUM_NODE_MINOR);
|
|
5520
|
+
} catch (e) {
|
|
5521
|
+
logger.log(`${chalkError("X Error:")} ${e}`);
|
|
5522
|
+
process.exitCode = 1;
|
|
5523
|
+
return;
|
|
5524
|
+
}
|
|
4477
5525
|
const authorization = await isLoggedIn(options.profile);
|
|
4478
5526
|
if (!authorization.ok) {
|
|
4479
5527
|
if (authorization.error === "fetch failed") {
|
|
4480
|
-
logger.
|
|
5528
|
+
logger.log(
|
|
5529
|
+
`${chalkError(
|
|
5530
|
+
"X Error:"
|
|
5531
|
+
)} Connecting to the server failed. Please check your internet connection or contact eric@trigger.dev for help.`
|
|
5532
|
+
);
|
|
4481
5533
|
} else {
|
|
4482
|
-
logger.
|
|
5534
|
+
logger.log(`${chalkError("X Error:")} You must login first. Use the \`login\` CLI command.`);
|
|
4483
5535
|
}
|
|
4484
5536
|
process.exitCode = 1;
|
|
4485
5537
|
return;
|
|
4486
5538
|
}
|
|
4487
|
-
const devInstance = await startDev(dir, options, authorization.auth);
|
|
5539
|
+
const devInstance = await startDev(dir, options, authorization.auth, authorization.dashboardUrl);
|
|
4488
5540
|
const { waitUntilExit } = devInstance.devReactElement;
|
|
4489
5541
|
await waitUntilExit();
|
|
4490
5542
|
}
|
|
4491
|
-
async function startDev(dir, options, authorization) {
|
|
5543
|
+
async function startDev(dir, options, authorization, dashboardUrl) {
|
|
4492
5544
|
let rerender;
|
|
4493
5545
|
try {
|
|
4494
5546
|
if (options.logLevel) {
|
|
4495
5547
|
logger.loggerLevel = options.logLevel;
|
|
4496
5548
|
}
|
|
4497
5549
|
await printStandloneInitialBanner(true);
|
|
4498
|
-
|
|
5550
|
+
let displayedUpdateMessage = false;
|
|
5551
|
+
if (!options.skipUpdateCheck) {
|
|
5552
|
+
displayedUpdateMessage = await updateTriggerPackages(dir, { ...options }, true, true);
|
|
5553
|
+
}
|
|
5554
|
+
printDevBanner(displayedUpdateMessage);
|
|
4499
5555
|
logger.debug("Starting dev session", { dir, options, authorization });
|
|
4500
5556
|
let config = await readConfig(dir, {
|
|
4501
5557
|
projectRef: options.projectRef,
|
|
@@ -4526,6 +5582,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4526
5582
|
return /* @__PURE__ */ React.createElement(
|
|
4527
5583
|
DevUI,
|
|
4528
5584
|
{
|
|
5585
|
+
dashboardUrl,
|
|
4529
5586
|
config: configParam,
|
|
4530
5587
|
apiUrl,
|
|
4531
5588
|
apiKey: devEnv.data.apiKey,
|
|
@@ -4557,6 +5614,7 @@ async function startDev(dir, options, authorization) {
|
|
|
4557
5614
|
}
|
|
4558
5615
|
function useDev({
|
|
4559
5616
|
config,
|
|
5617
|
+
dashboardUrl,
|
|
4560
5618
|
apiUrl,
|
|
4561
5619
|
apiKey,
|
|
4562
5620
|
environmentClient,
|
|
@@ -4586,7 +5644,7 @@ function useDev({
|
|
|
4586
5644
|
}
|
|
4587
5645
|
});
|
|
4588
5646
|
const backgroundWorkerCoordinator = new BackgroundWorkerCoordinator(
|
|
4589
|
-
`${
|
|
5647
|
+
`${dashboardUrl}/projects/v3/${config.project}`
|
|
4590
5648
|
);
|
|
4591
5649
|
websocket.addEventListener("open", async (event) => {
|
|
4592
5650
|
});
|
|
@@ -4658,22 +5716,21 @@ function useDev({
|
|
|
4658
5716
|
}
|
|
4659
5717
|
let latestWorkerContentHash;
|
|
4660
5718
|
const taskFiles = await gatherTaskFiles(config);
|
|
4661
|
-
const
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
"
|
|
5719
|
+
const workerFacadePath = join7(cliRootPath(), "workers", "dev", "worker-facade.js");
|
|
5720
|
+
const workerFacade = readFileSync3(workerFacadePath, "utf-8");
|
|
5721
|
+
const workerSetupPath = join7(cliRootPath(), "workers", "dev", "worker-setup.js");
|
|
5722
|
+
let entryPointContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace(
|
|
5723
|
+
"__WORKER_SETUP__",
|
|
5724
|
+
`import { tracingSDK, sender } from "${escapeImportPath(workerSetupPath)}";`
|
|
4667
5725
|
);
|
|
4668
|
-
const workerSetupPath = new URL(
|
|
4669
|
-
importResolve2("./workers/dev/worker-setup.js", import.meta.url)
|
|
4670
|
-
).href.replace("file://", "");
|
|
4671
|
-
let entryPointContents = workerFacade.replace("__TASKS__", createTaskFileImports(taskFiles)).replace("__WORKER_SETUP__", `import { tracingSDK, sender } from "${workerSetupPath}";`);
|
|
4672
5726
|
if (configPath) {
|
|
5727
|
+
configPath = normalize(configPath);
|
|
4673
5728
|
logger.debug("Importing project config from", { configPath });
|
|
4674
5729
|
entryPointContents = entryPointContents.replace(
|
|
4675
5730
|
"__IMPORTED_PROJECT_CONFIG__",
|
|
4676
|
-
`import * as importedConfigExports from "${
|
|
5731
|
+
`import * as importedConfigExports from "${escapeImportPath(
|
|
5732
|
+
configPath
|
|
5733
|
+
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
|
|
4677
5734
|
);
|
|
4678
5735
|
} else {
|
|
4679
5736
|
entryPointContents = entryPointContents.replace(
|
|
@@ -4706,6 +5763,7 @@ function useDev({
|
|
|
4706
5763
|
__PROJECT_CONFIG__: JSON.stringify(config)
|
|
4707
5764
|
},
|
|
4708
5765
|
plugins: [
|
|
5766
|
+
bundleTriggerDevCore("workerFacade", config.tsconfigPath),
|
|
4709
5767
|
bundleDependenciesPlugin(
|
|
4710
5768
|
"workerFacade",
|
|
4711
5769
|
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
|
|
@@ -4725,19 +5783,19 @@ function useDev({
|
|
|
4725
5783
|
if (!firstBuild) {
|
|
4726
5784
|
logger.log(chalkGrey("\u25CB Building background worker\u2026"));
|
|
4727
5785
|
}
|
|
4728
|
-
const metaOutputKey =
|
|
5786
|
+
const metaOutputKey = join7("out", `stdin.js`).replace(/\\/g, "/");
|
|
4729
5787
|
const metaOutput = result.metafile.outputs[metaOutputKey];
|
|
4730
5788
|
if (!metaOutput) {
|
|
4731
5789
|
throw new Error(`Could not find metafile`);
|
|
4732
5790
|
}
|
|
4733
|
-
const outputFileKey =
|
|
5791
|
+
const outputFileKey = join7(config.projectDir, metaOutputKey);
|
|
4734
5792
|
const outputFile = result.outputFiles.find((file) => file.path === outputFileKey);
|
|
4735
5793
|
if (!outputFile) {
|
|
4736
5794
|
throw new Error(
|
|
4737
5795
|
`Could not find output file for entry point ${metaOutput.entryPoint}`
|
|
4738
5796
|
);
|
|
4739
5797
|
}
|
|
4740
|
-
const sourceMapFileKey =
|
|
5798
|
+
const sourceMapFileKey = join7(config.projectDir, `${metaOutputKey}.map`);
|
|
4741
5799
|
const sourceMapFile = result.outputFiles.find(
|
|
4742
5800
|
(file) => file.path === sourceMapFileKey
|
|
4743
5801
|
);
|
|
@@ -4748,10 +5806,10 @@ function useDev({
|
|
|
4748
5806
|
logger.log(chalkGrey("\u25CB No changes detected, skipping build\u2026"));
|
|
4749
5807
|
return;
|
|
4750
5808
|
}
|
|
4751
|
-
const fullPath =
|
|
5809
|
+
const fullPath = join7(config.projectDir, ".trigger", `${contentHash}.js`);
|
|
4752
5810
|
const sourceMapPath = `${fullPath}.map`;
|
|
4753
5811
|
const outputFileWithSourceMap = `${outputFile.text}
|
|
4754
|
-
//# sourceMappingURL=${
|
|
5812
|
+
//# sourceMappingURL=${basename2(sourceMapPath)}`;
|
|
4755
5813
|
await fs7.promises.mkdir(dirname3(fullPath), { recursive: true });
|
|
4756
5814
|
await fs7.promises.writeFile(fullPath, outputFileWithSourceMap);
|
|
4757
5815
|
logger.debug(`Wrote background worker to ${fullPath}`);
|
|
@@ -4761,7 +5819,7 @@ function useDev({
|
|
|
4761
5819
|
await fs7.promises.writeFile(sourceMapPath2, sourceMapFile.text);
|
|
4762
5820
|
}
|
|
4763
5821
|
const environmentVariablesResponse = await environmentClient.getEnvironmentVariables(config.project);
|
|
4764
|
-
const processEnv = gatherProcessEnv();
|
|
5822
|
+
const processEnv = await gatherProcessEnv();
|
|
4765
5823
|
const backgroundWorker = new BackgroundWorker(fullPath, {
|
|
4766
5824
|
projectConfig: config,
|
|
4767
5825
|
dependencies: dependencies2,
|
|
@@ -4779,8 +5837,15 @@ function useDev({
|
|
|
4779
5837
|
latestWorkerContentHash = contentHash;
|
|
4780
5838
|
let packageVersion;
|
|
4781
5839
|
const taskResources = [];
|
|
4782
|
-
if (!backgroundWorker.tasks) {
|
|
4783
|
-
|
|
5840
|
+
if (!backgroundWorker.tasks || backgroundWorker.tasks.length === 0) {
|
|
5841
|
+
logger.log(
|
|
5842
|
+
`${chalkError(
|
|
5843
|
+
"X Error:"
|
|
5844
|
+
)} Worker failed to build: no tasks found. Searched in ${config.triggerDirectories.join(
|
|
5845
|
+
", "
|
|
5846
|
+
)}`
|
|
5847
|
+
);
|
|
5848
|
+
return;
|
|
4784
5849
|
}
|
|
4785
5850
|
for (const task of backgroundWorker.tasks) {
|
|
4786
5851
|
taskResources.push(task);
|
|
@@ -4799,6 +5864,9 @@ function useDev({
|
|
|
4799
5864
|
);
|
|
4800
5865
|
return;
|
|
4801
5866
|
}
|
|
5867
|
+
logger.debug("Creating background worker with tasks", {
|
|
5868
|
+
tasks: taskResources
|
|
5869
|
+
});
|
|
4802
5870
|
const backgroundWorkerBody = {
|
|
4803
5871
|
localOnly: true,
|
|
4804
5872
|
metadata: {
|
|
@@ -4829,17 +5897,52 @@ function useDev({
|
|
|
4829
5897
|
backgroundWorker
|
|
4830
5898
|
);
|
|
4831
5899
|
} catch (e) {
|
|
4832
|
-
if (e instanceof
|
|
5900
|
+
if (e instanceof TaskMetadataParseError) {
|
|
5901
|
+
logTaskMetadataParseError(e.zodIssues, e.tasks);
|
|
5902
|
+
return;
|
|
5903
|
+
} else if (e instanceof UncaughtExceptionError) {
|
|
5904
|
+
const parsedBuildError = parseBuildErrorStack(e.originalError);
|
|
5905
|
+
if (parsedBuildError && typeof parsedBuildError !== "string") {
|
|
5906
|
+
logESMRequireError(
|
|
5907
|
+
parsedBuildError,
|
|
5908
|
+
configPath ? { status: "file", path: configPath, config } : { status: "in-memory", config }
|
|
5909
|
+
);
|
|
5910
|
+
return;
|
|
5911
|
+
} else {
|
|
5912
|
+
}
|
|
4833
5913
|
if (e.originalError.stack) {
|
|
4834
|
-
logger.
|
|
5914
|
+
logger.log(
|
|
5915
|
+
`${chalkError("X Error:")} Worker failed to start`,
|
|
5916
|
+
e.originalError.stack
|
|
5917
|
+
);
|
|
4835
5918
|
}
|
|
4836
5919
|
return;
|
|
4837
5920
|
}
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
5921
|
+
const parsedError = parseNpmInstallError(e);
|
|
5922
|
+
if (typeof parsedError === "string") {
|
|
5923
|
+
logger.log(`${chalkError("X Error:")} ${parsedError}`);
|
|
5924
|
+
} else {
|
|
5925
|
+
switch (parsedError.type) {
|
|
5926
|
+
case "package-not-found-error": {
|
|
5927
|
+
logger.log(
|
|
5928
|
+
`
|
|
5929
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
5930
|
+
parsedError.packageName
|
|
5931
|
+
)} could not be found in the npm registry.`
|
|
5932
|
+
);
|
|
5933
|
+
break;
|
|
5934
|
+
}
|
|
5935
|
+
case "no-matching-version-error": {
|
|
5936
|
+
logger.log(
|
|
5937
|
+
`
|
|
5938
|
+
${chalkError("X Error:")} The package ${chalkPurple(
|
|
5939
|
+
parsedError.packageName
|
|
5940
|
+
)} could not resolve because the version doesn't exist`
|
|
5941
|
+
);
|
|
5942
|
+
break;
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
4841
5945
|
}
|
|
4842
|
-
logger.error(`Background worker failed to start: ${e}`);
|
|
4843
5946
|
}
|
|
4844
5947
|
});
|
|
4845
5948
|
}
|
|
@@ -4850,17 +5953,17 @@ function useDev({
|
|
|
4850
5953
|
}
|
|
4851
5954
|
const throttledRebuild = pDebounce(runBuild, 250, { before: true });
|
|
4852
5955
|
const taskFileWatcher = watch(
|
|
4853
|
-
config.triggerDirectories.map((triggerDir) => `${triggerDir}
|
|
5956
|
+
config.triggerDirectories.map((triggerDir) => `${triggerDir}/**/*.ts`),
|
|
4854
5957
|
{
|
|
4855
5958
|
ignoreInitial: true
|
|
4856
5959
|
}
|
|
4857
5960
|
);
|
|
4858
|
-
taskFileWatcher.on("add", async (
|
|
5961
|
+
taskFileWatcher.on("add", async (path7) => {
|
|
4859
5962
|
throttledRebuild().catch((error) => {
|
|
4860
5963
|
logger.error(error);
|
|
4861
5964
|
});
|
|
4862
5965
|
});
|
|
4863
|
-
taskFileWatcher.on("unlink", async (
|
|
5966
|
+
taskFileWatcher.on("unlink", async (path7) => {
|
|
4864
5967
|
throttledRebuild().catch((error) => {
|
|
4865
5968
|
logger.error(error);
|
|
4866
5969
|
});
|
|
@@ -4920,7 +6023,7 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4920
6023
|
}
|
|
4921
6024
|
}
|
|
4922
6025
|
if (config.additionalPackages) {
|
|
4923
|
-
const projectPackageJson = await readJSONFile(
|
|
6026
|
+
const projectPackageJson = await readJSONFile(join7(config.projectDir, "package.json"));
|
|
4924
6027
|
for (const packageName of config.additionalPackages) {
|
|
4925
6028
|
if (dependencies2[packageName]) {
|
|
4926
6029
|
continue;
|
|
@@ -4950,16 +6053,14 @@ async function gatherRequiredDependencies2(outputMeta, config) {
|
|
|
4950
6053
|
function createDuplicateTaskIdOutputErrorMessage(duplicateTaskIds, taskResources) {
|
|
4951
6054
|
const duplicateTable = duplicateTaskIds.map((id) => {
|
|
4952
6055
|
const tasks = taskResources.filter((task) => task.id === id);
|
|
4953
|
-
return `
|
|
4954
|
-
${tasks.map((task) => `${task.filePath} -> ${task.exportName}`).join("\n")}`;
|
|
4955
|
-
}).join("\n\n");
|
|
4956
|
-
return `Duplicate task ids detected:
|
|
4957
|
-
|
|
4958
|
-
${duplicateTable}
|
|
6056
|
+
return `
|
|
4959
6057
|
|
|
4960
|
-
|
|
6058
|
+
${chalkTask(id)} was found in:${tasks.map((task) => `
|
|
6059
|
+
${task.filePath} -> ${task.exportName}`).join("")}`;
|
|
6060
|
+
}).join("");
|
|
6061
|
+
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
|
|
4961
6062
|
}
|
|
4962
|
-
function gatherProcessEnv() {
|
|
6063
|
+
async function gatherProcessEnv() {
|
|
4963
6064
|
const env = {
|
|
4964
6065
|
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
4965
6066
|
PATH: process.env.PATH,
|
|
@@ -4970,31 +6071,54 @@ function gatherProcessEnv() {
|
|
|
4970
6071
|
NVM_BIN: process.env.NVM_BIN,
|
|
4971
6072
|
LANG: process.env.LANG,
|
|
4972
6073
|
TERM: process.env.TERM,
|
|
4973
|
-
NODE_PATH: process.env.NODE_PATH,
|
|
6074
|
+
NODE_PATH: await amendNodePathWithPnpmNodeModules(process.env.NODE_PATH),
|
|
4974
6075
|
HOME: process.env.HOME,
|
|
4975
6076
|
BUN_INSTALL: process.env.BUN_INSTALL
|
|
4976
6077
|
};
|
|
4977
6078
|
return Object.fromEntries(Object.entries(env).filter(([key, value]) => value !== void 0));
|
|
4978
6079
|
}
|
|
6080
|
+
async function amendNodePathWithPnpmNodeModules(nodePath) {
|
|
6081
|
+
const pnpmModulesPath = await findPnpmNodeModulesPath();
|
|
6082
|
+
if (!pnpmModulesPath) {
|
|
6083
|
+
return nodePath;
|
|
6084
|
+
}
|
|
6085
|
+
if (nodePath) {
|
|
6086
|
+
if (nodePath.includes(pnpmModulesPath)) {
|
|
6087
|
+
return nodePath;
|
|
6088
|
+
}
|
|
6089
|
+
return `${nodePath}:${pnpmModulesPath}`;
|
|
6090
|
+
}
|
|
6091
|
+
return pnpmModulesPath;
|
|
6092
|
+
}
|
|
6093
|
+
async function findPnpmNodeModulesPath() {
|
|
6094
|
+
return await findUp3(
|
|
6095
|
+
async (directory) => {
|
|
6096
|
+
const pnpmModules = join7(directory, "node_modules", ".pnpm", "node_modules");
|
|
6097
|
+
const hasPnpmNodeModules = await pathExists2(pnpmModules);
|
|
6098
|
+
if (hasPnpmNodeModules) {
|
|
6099
|
+
return pnpmModules;
|
|
6100
|
+
}
|
|
6101
|
+
},
|
|
6102
|
+
{ type: "directory" }
|
|
6103
|
+
);
|
|
6104
|
+
}
|
|
4979
6105
|
|
|
4980
6106
|
// src/commands/init.ts
|
|
4981
|
-
import { intro as
|
|
6107
|
+
import { intro as intro5, isCancel as isCancel2, log as log6, outro as outro6, select as select2, text } from "@clack/prompts";
|
|
4982
6108
|
import { context as context3, trace as trace3 } from "@opentelemetry/api";
|
|
4983
|
-
import {
|
|
4984
|
-
|
|
4985
|
-
recordSpanException as recordSpanException5
|
|
4986
|
-
} from "@trigger.dev/core/v3";
|
|
6109
|
+
import { flattenAttributes as flattenAttributes3 } from "@trigger.dev/core/v3";
|
|
6110
|
+
import { recordSpanException as recordSpanException5 } from "@trigger.dev/core/v3/workers";
|
|
4987
6111
|
import chalk5 from "chalk";
|
|
4988
6112
|
import { execa as execa3 } from "execa";
|
|
4989
6113
|
import { applyEdits, modify } from "jsonc-parser";
|
|
4990
6114
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
4991
|
-
import { join as
|
|
4992
|
-
import
|
|
6115
|
+
import { join as join8, relative as relative4, resolve as resolve4 } from "node:path";
|
|
6116
|
+
import terminalLink4 from "terminal-link";
|
|
4993
6117
|
import { z as z6 } from "zod";
|
|
4994
6118
|
|
|
4995
6119
|
// src/utilities/createFileFromTemplate.ts
|
|
4996
6120
|
import fs8 from "fs/promises";
|
|
4997
|
-
import
|
|
6121
|
+
import path6 from "path";
|
|
4998
6122
|
async function createFileFromTemplate(params) {
|
|
4999
6123
|
let template = await readFile(params.templatePath);
|
|
5000
6124
|
if (await pathExists(params.outputPath) && !params.override) {
|
|
@@ -5005,7 +6129,7 @@ async function createFileFromTemplate(params) {
|
|
|
5005
6129
|
}
|
|
5006
6130
|
try {
|
|
5007
6131
|
const output = replaceAll(template, params.replacements);
|
|
5008
|
-
const directoryName =
|
|
6132
|
+
const directoryName = path6.dirname(params.outputPath);
|
|
5009
6133
|
await fs8.mkdir(directoryName, { recursive: true });
|
|
5010
6134
|
await fs8.writeFile(params.outputPath, output);
|
|
5011
6135
|
return {
|
|
@@ -5033,51 +6157,6 @@ function replaceAll(input, replacements) {
|
|
|
5033
6157
|
return output;
|
|
5034
6158
|
}
|
|
5035
6159
|
|
|
5036
|
-
// src/utilities/getUserPackageManager.ts
|
|
5037
|
-
import pathModule2 from "path";
|
|
5038
|
-
async function getUserPackageManager(path6) {
|
|
5039
|
-
try {
|
|
5040
|
-
return await detectPackageManagerFromArtifacts(path6);
|
|
5041
|
-
} catch (error) {
|
|
5042
|
-
return detectPackageManagerFromCurrentCommand();
|
|
5043
|
-
}
|
|
5044
|
-
}
|
|
5045
|
-
function detectPackageManagerFromCurrentCommand() {
|
|
5046
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
5047
|
-
if (userAgent) {
|
|
5048
|
-
if (userAgent.startsWith("yarn")) {
|
|
5049
|
-
return "yarn";
|
|
5050
|
-
} else if (userAgent.startsWith("pnpm")) {
|
|
5051
|
-
return "pnpm";
|
|
5052
|
-
} else {
|
|
5053
|
-
return "npm";
|
|
5054
|
-
}
|
|
5055
|
-
} else {
|
|
5056
|
-
return "npm";
|
|
5057
|
-
}
|
|
5058
|
-
}
|
|
5059
|
-
async function detectPackageManagerFromArtifacts(path6) {
|
|
5060
|
-
const packageFiles = [
|
|
5061
|
-
{ name: "yarn.lock", pm: "yarn" },
|
|
5062
|
-
{ name: "pnpm-lock.yaml", pm: "pnpm" },
|
|
5063
|
-
{ name: "package-lock.json", pm: "npm" },
|
|
5064
|
-
{ name: "npm-shrinkwrap.json", pm: "npm" }
|
|
5065
|
-
];
|
|
5066
|
-
for (const { name, pm } of packageFiles) {
|
|
5067
|
-
const exists = await pathExists(pathModule2.join(path6, name));
|
|
5068
|
-
if (exists) {
|
|
5069
|
-
return pm;
|
|
5070
|
-
}
|
|
5071
|
-
}
|
|
5072
|
-
throw new Error("Could not detect package manager from artifacts");
|
|
5073
|
-
}
|
|
5074
|
-
|
|
5075
|
-
// src/utilities/resolveInternalFilePath.ts
|
|
5076
|
-
import { resolve as importResolve3 } from "import-meta-resolve";
|
|
5077
|
-
function resolveInternalFilePath(filePath) {
|
|
5078
|
-
return new URL(importResolve3(filePath, import.meta.url)).href.replace("file://", "");
|
|
5079
|
-
}
|
|
5080
|
-
|
|
5081
6160
|
// src/commands/init.ts
|
|
5082
6161
|
var InitCommandOptions = CommonCommandOptions.extend({
|
|
5083
6162
|
projectRef: z6.string().optional(),
|
|
@@ -5095,10 +6174,10 @@ function configureInitCommand(program2) {
|
|
|
5095
6174
|
"The version of the @trigger.dev/sdk package to install",
|
|
5096
6175
|
"beta"
|
|
5097
6176
|
).option("--skip-package-install", "Skip installing the @trigger.dev/sdk package").option("--override-config", "Override the existing config file if it exists")
|
|
5098
|
-
).action(async (
|
|
6177
|
+
).action(async (path7, options) => {
|
|
5099
6178
|
await handleTelemetry(async () => {
|
|
5100
6179
|
await printStandloneInitialBanner(true);
|
|
5101
|
-
await initCommand(
|
|
6180
|
+
await initCommand(path7, options);
|
|
5102
6181
|
});
|
|
5103
6182
|
});
|
|
5104
6183
|
}
|
|
@@ -5109,7 +6188,7 @@ async function initCommand(dir, options) {
|
|
|
5109
6188
|
}
|
|
5110
6189
|
async function _initCommand(dir, options) {
|
|
5111
6190
|
const span = trace3.getSpan(context3.active());
|
|
5112
|
-
|
|
6191
|
+
intro5("Initializing project");
|
|
5113
6192
|
const authorization = await login({
|
|
5114
6193
|
embedded: true,
|
|
5115
6194
|
defaultApiUrl: options.apiUrl,
|
|
@@ -5133,7 +6212,7 @@ async function _initCommand(dir, options) {
|
|
|
5133
6212
|
if (!options.overrideConfig) {
|
|
5134
6213
|
try {
|
|
5135
6214
|
const result = await readConfig(dir);
|
|
5136
|
-
|
|
6215
|
+
outro6(
|
|
5137
6216
|
result.status === "file" ? `Project already initialized: Found config file at ${result.path}. Pass --override-config to override` : "Project already initialized"
|
|
5138
6217
|
);
|
|
5139
6218
|
return;
|
|
@@ -5150,55 +6229,56 @@ async function _initCommand(dir, options) {
|
|
|
5150
6229
|
...flattenAttributes3(selectedProject, "cli.project")
|
|
5151
6230
|
});
|
|
5152
6231
|
logger.debug("Selected project", selectedProject);
|
|
5153
|
-
|
|
6232
|
+
log6.step(`Configuring project "${selectedProject.name}" (${selectedProject.externalRef})`);
|
|
5154
6233
|
if (!options.skipPackageInstall) {
|
|
5155
6234
|
await installPackages2(dir, options);
|
|
5156
6235
|
} else {
|
|
5157
|
-
|
|
6236
|
+
log6.info("Skipping package installation");
|
|
5158
6237
|
}
|
|
5159
6238
|
const triggerDir = await createTriggerDir(dir, options);
|
|
5160
6239
|
await writeConfigFile(dir, selectedProject, options, triggerDir);
|
|
5161
6240
|
await addConfigFileToTsConfig(dir, options);
|
|
5162
6241
|
await gitIgnoreDotTriggerDir(dir, options);
|
|
5163
|
-
const projectDashboard =
|
|
6242
|
+
const projectDashboard = terminalLink4(
|
|
5164
6243
|
"project dashboard",
|
|
5165
6244
|
`${authorization.dashboardUrl}/projects/v3/${selectedProject.externalRef}`
|
|
5166
6245
|
);
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
6246
|
+
log6.success("Successfully initialized project for Trigger.dev v3 \u{1FAE1}");
|
|
6247
|
+
log6.info("Next steps:");
|
|
6248
|
+
log6.info(
|
|
5170
6249
|
` 1. To start developing, run ${chalk5.green(
|
|
5171
6250
|
`npx trigger.dev@${options.tag} dev`
|
|
5172
6251
|
)} in your project directory`
|
|
5173
6252
|
);
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
` 3. Head over to our ${
|
|
6253
|
+
log6.info(` 2. Visit your ${projectDashboard} to view your newly created tasks.`);
|
|
6254
|
+
log6.info(
|
|
6255
|
+
` 3. Head over to our ${terminalLink4(
|
|
5177
6256
|
"v3 docs",
|
|
5178
6257
|
"https://trigger.dev/docs/v3"
|
|
5179
6258
|
)} to learn more.`
|
|
5180
6259
|
);
|
|
5181
|
-
|
|
5182
|
-
` 4. Need help? Join our ${
|
|
6260
|
+
log6.info(
|
|
6261
|
+
` 4. Need help? Join our ${terminalLink4(
|
|
5183
6262
|
"Discord community",
|
|
5184
6263
|
"https://trigger.dev/discord"
|
|
5185
6264
|
)} or email us at ${chalk5.cyan("help@trigger.dev")}`
|
|
5186
6265
|
);
|
|
5187
|
-
|
|
6266
|
+
outro6(`Project initialized successfully. Happy coding!`);
|
|
5188
6267
|
}
|
|
5189
6268
|
async function createTriggerDir(dir, options) {
|
|
5190
6269
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5191
6270
|
try {
|
|
5192
|
-
const defaultValue =
|
|
6271
|
+
const defaultValue = join8(dir, "src", "trigger");
|
|
5193
6272
|
const location = await text({
|
|
5194
6273
|
message: "Where would you like to create the Trigger.dev directory?",
|
|
5195
6274
|
defaultValue,
|
|
5196
6275
|
placeholder: defaultValue
|
|
5197
6276
|
});
|
|
5198
|
-
if (
|
|
6277
|
+
if (isCancel2(location)) {
|
|
5199
6278
|
throw new OutroCommandError();
|
|
5200
6279
|
}
|
|
5201
|
-
const triggerDir =
|
|
6280
|
+
const triggerDir = resolve4(process.cwd(), location);
|
|
6281
|
+
logger.debug({ triggerDir });
|
|
5202
6282
|
span.setAttributes({
|
|
5203
6283
|
"cli.triggerDir": triggerDir
|
|
5204
6284
|
});
|
|
@@ -5216,7 +6296,7 @@ async function createTriggerDir(dir, options) {
|
|
|
5216
6296
|
}
|
|
5217
6297
|
]
|
|
5218
6298
|
});
|
|
5219
|
-
if (
|
|
6299
|
+
if (isCancel2(exampleSelection)) {
|
|
5220
6300
|
throw new OutroCommandError();
|
|
5221
6301
|
}
|
|
5222
6302
|
const example = exampleSelection;
|
|
@@ -5224,20 +6304,20 @@ async function createTriggerDir(dir, options) {
|
|
|
5224
6304
|
"cli.example": example
|
|
5225
6305
|
});
|
|
5226
6306
|
if (example === "none") {
|
|
5227
|
-
await createFile(
|
|
5228
|
-
|
|
6307
|
+
await createFile(join8(triggerDir, ".gitkeep"), "");
|
|
6308
|
+
log6.step(`Created directory at ${location}`);
|
|
5229
6309
|
span.end();
|
|
5230
6310
|
return { location, isCustomValue: location !== defaultValue };
|
|
5231
6311
|
}
|
|
5232
|
-
const
|
|
5233
|
-
const outputPath =
|
|
6312
|
+
const templatePath = join8(cliRootPath(), "templates", "examples", `${example}.ts.template`);
|
|
6313
|
+
const outputPath = join8(triggerDir, "example.ts");
|
|
5234
6314
|
await createFileFromTemplate({
|
|
5235
|
-
templatePath
|
|
6315
|
+
templatePath,
|
|
5236
6316
|
outputPath,
|
|
5237
6317
|
replacements: {}
|
|
5238
6318
|
});
|
|
5239
|
-
const relativeOutputPath =
|
|
5240
|
-
|
|
6319
|
+
const relativeOutputPath = relative4(process.cwd(), outputPath);
|
|
6320
|
+
log6.step(`Created example file at ${relativeOutputPath}`);
|
|
5241
6321
|
span.end();
|
|
5242
6322
|
return { location, isCustomValue: location !== defaultValue };
|
|
5243
6323
|
} catch (e) {
|
|
@@ -5252,15 +6332,15 @@ async function createTriggerDir(dir, options) {
|
|
|
5252
6332
|
async function gitIgnoreDotTriggerDir(dir, options) {
|
|
5253
6333
|
return await tracer.startActiveSpan("gitIgnoreDotTriggerDir", async (span) => {
|
|
5254
6334
|
try {
|
|
5255
|
-
const projectDir =
|
|
5256
|
-
const gitIgnorePath =
|
|
6335
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6336
|
+
const gitIgnorePath = join8(projectDir, ".gitignore");
|
|
5257
6337
|
span.setAttributes({
|
|
5258
6338
|
"cli.projectDir": projectDir,
|
|
5259
6339
|
"cli.gitIgnorePath": gitIgnorePath
|
|
5260
6340
|
});
|
|
5261
6341
|
if (!await pathExists(gitIgnorePath)) {
|
|
5262
6342
|
await createFile(gitIgnorePath, ".trigger");
|
|
5263
|
-
|
|
6343
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5264
6344
|
span.end();
|
|
5265
6345
|
return;
|
|
5266
6346
|
}
|
|
@@ -5272,7 +6352,7 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5272
6352
|
const newGitIgnoreContent = `${gitIgnoreContent}
|
|
5273
6353
|
.trigger`;
|
|
5274
6354
|
await writeFile3(gitIgnorePath, newGitIgnoreContent, "utf-8");
|
|
5275
|
-
|
|
6355
|
+
log6.step(`Added .trigger to .gitignore`);
|
|
5276
6356
|
span.end();
|
|
5277
6357
|
} catch (e) {
|
|
5278
6358
|
if (!(e instanceof SkipCommandError)) {
|
|
@@ -5286,8 +6366,8 @@ async function gitIgnoreDotTriggerDir(dir, options) {
|
|
|
5286
6366
|
async function addConfigFileToTsConfig(dir, options) {
|
|
5287
6367
|
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
|
|
5288
6368
|
try {
|
|
5289
|
-
const projectDir =
|
|
5290
|
-
const tsconfigPath =
|
|
6369
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6370
|
+
const tsconfigPath = join8(projectDir, "tsconfig.json");
|
|
5291
6371
|
span.setAttributes({
|
|
5292
6372
|
"cli.projectDir": projectDir,
|
|
5293
6373
|
"cli.tsconfigPath": tsconfigPath
|
|
@@ -5305,7 +6385,7 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5305
6385
|
const newTsconfigContent = applyEdits(tsconfigContent, edits);
|
|
5306
6386
|
logger.debug("new tsconfig.json content", { newTsconfigContent });
|
|
5307
6387
|
await writeFile3(tsconfigPath, newTsconfigContent, "utf-8");
|
|
5308
|
-
|
|
6388
|
+
log6.step(`Added trigger.config.ts to tsconfig.json`);
|
|
5309
6389
|
span.end();
|
|
5310
6390
|
} catch (e) {
|
|
5311
6391
|
if (!(e instanceof SkipCommandError)) {
|
|
@@ -5318,9 +6398,9 @@ async function addConfigFileToTsConfig(dir, options) {
|
|
|
5318
6398
|
}
|
|
5319
6399
|
async function installPackages2(dir, options) {
|
|
5320
6400
|
return await tracer.startActiveSpan("installPackages", async (span) => {
|
|
5321
|
-
const installSpinner =
|
|
6401
|
+
const installSpinner = spinner();
|
|
5322
6402
|
try {
|
|
5323
|
-
const projectDir =
|
|
6403
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
5324
6404
|
const pkgManager = await getUserPackageManager(projectDir);
|
|
5325
6405
|
span.setAttributes({
|
|
5326
6406
|
"cli.projectDir": projectDir,
|
|
@@ -5370,11 +6450,11 @@ async function installPackages2(dir, options) {
|
|
|
5370
6450
|
async function writeConfigFile(dir, project, options, triggerDir) {
|
|
5371
6451
|
return await tracer.startActiveSpan("writeConfigFile", async (span) => {
|
|
5372
6452
|
try {
|
|
5373
|
-
const spnnr =
|
|
6453
|
+
const spnnr = spinner();
|
|
5374
6454
|
spnnr.start("Creating config file");
|
|
5375
|
-
const projectDir =
|
|
5376
|
-
const templatePath =
|
|
5377
|
-
const outputPath =
|
|
6455
|
+
const projectDir = resolve4(process.cwd(), dir);
|
|
6456
|
+
const templatePath = join8(cliRootPath(), "templates", "trigger.config.ts.template");
|
|
6457
|
+
const outputPath = join8(projectDir, "trigger.config.ts");
|
|
5378
6458
|
span.setAttributes({
|
|
5379
6459
|
"cli.projectDir": projectDir,
|
|
5380
6460
|
"cli.templatePath": templatePath,
|
|
@@ -5390,7 +6470,7 @@ async function writeConfigFile(dir, project, options, triggerDir) {
|
|
|
5390
6470
|
outputPath,
|
|
5391
6471
|
override: options.overrideConfig
|
|
5392
6472
|
});
|
|
5393
|
-
const relativePathToOutput =
|
|
6473
|
+
const relativePathToOutput = relative4(process.cwd(), outputPath);
|
|
5394
6474
|
spnnr.stop(
|
|
5395
6475
|
result.success ? `Config file created at ${relativePathToOutput}` : `Failed to create config file: ${result.error}`
|
|
5396
6476
|
);
|
|
@@ -5414,7 +6494,7 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5414
6494
|
if (projectRef) {
|
|
5415
6495
|
const projectResponse = await apiClient2.getProject(projectRef);
|
|
5416
6496
|
if (!projectResponse.success) {
|
|
5417
|
-
|
|
6497
|
+
log6.error(
|
|
5418
6498
|
`--project-ref ${projectRef} is not a valid project ref. Request to fetch data resulted in: ${projectResponse.error}`
|
|
5419
6499
|
);
|
|
5420
6500
|
throw new SkipCommandError(projectResponse.error);
|
|
@@ -5430,11 +6510,11 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5430
6510
|
throw new Error(`Failed to get projects: ${projectsResponse.error}`);
|
|
5431
6511
|
}
|
|
5432
6512
|
if (projectsResponse.data.length === 0) {
|
|
5433
|
-
const newProjectLink =
|
|
6513
|
+
const newProjectLink = terminalLink4(
|
|
5434
6514
|
"Create new project",
|
|
5435
6515
|
`${dashboardUrl}/projects/new?version=v3`
|
|
5436
6516
|
);
|
|
5437
|
-
|
|
6517
|
+
outro6(`You don't have any projects yet. ${newProjectLink}`);
|
|
5438
6518
|
throw new SkipCommandError();
|
|
5439
6519
|
}
|
|
5440
6520
|
const selectedProject = await select2({
|
|
@@ -5445,7 +6525,7 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5445
6525
|
hint: project.organization.title
|
|
5446
6526
|
}))
|
|
5447
6527
|
});
|
|
5448
|
-
if (
|
|
6528
|
+
if (isCancel2(selectedProject)) {
|
|
5449
6529
|
throw new OutroCommandError();
|
|
5450
6530
|
}
|
|
5451
6531
|
const projectData = projectsResponse.data.find(
|
|
@@ -5472,12 +6552,14 @@ async function selectProject(apiClient2, dashboardUrl, projectRef) {
|
|
|
5472
6552
|
// src/commands/logout.ts
|
|
5473
6553
|
var LogoutCommandOptions = CommonCommandOptions;
|
|
5474
6554
|
function configureLogoutCommand(program2) {
|
|
5475
|
-
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
5476
|
-
|
|
5477
|
-
await
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
6555
|
+
return commonOptions(program2.command("logout").description("Logout of Trigger.dev")).action(
|
|
6556
|
+
async (options) => {
|
|
6557
|
+
await handleTelemetry(async () => {
|
|
6558
|
+
await printInitialBanner(false);
|
|
6559
|
+
await logoutCommand(options);
|
|
6560
|
+
});
|
|
6561
|
+
}
|
|
6562
|
+
);
|
|
5481
6563
|
}
|
|
5482
6564
|
async function logoutCommand(options) {
|
|
5483
6565
|
return await wrapCommandAction("logoutCommand", LogoutCommandOptions, options, async (opts) => {
|
|
@@ -5487,11 +6569,46 @@ async function logoutCommand(options) {
|
|
|
5487
6569
|
async function logout(options) {
|
|
5488
6570
|
const config = readAuthConfigProfile(options.profile);
|
|
5489
6571
|
if (!config?.accessToken) {
|
|
5490
|
-
logger.info(`You are already logged out [${options.profile
|
|
6572
|
+
logger.info(`You are already logged out [${options.profile}]`);
|
|
6573
|
+
return;
|
|
6574
|
+
}
|
|
6575
|
+
deleteAuthConfigProfile(options.profile);
|
|
6576
|
+
logger.info(`Logged out of Trigger.dev [${options.profile}]`);
|
|
6577
|
+
}
|
|
6578
|
+
|
|
6579
|
+
// src/commands/list-profiles.ts
|
|
6580
|
+
import { log as log7, outro as outro7 } from "@clack/prompts";
|
|
6581
|
+
var ListProfilesOptions = CommonCommandOptions;
|
|
6582
|
+
function configureListProfilesCommand(program2) {
|
|
6583
|
+
return program2.command("list-profiles").description("List all of your CLI profiles").option(
|
|
6584
|
+
"-l, --log-level <level>",
|
|
6585
|
+
"The CLI log level to use (debug, info, log, warn, error, none). This does not effect the log level of your trigger.dev tasks.",
|
|
6586
|
+
"log"
|
|
6587
|
+
).option("--skip-telemetry", "Opt-out of sending telemetry").action(async (options) => {
|
|
6588
|
+
await handleTelemetry(async () => {
|
|
6589
|
+
await printInitialBanner(true);
|
|
6590
|
+
await listProfilesCommand(options);
|
|
6591
|
+
});
|
|
6592
|
+
});
|
|
6593
|
+
}
|
|
6594
|
+
async function listProfilesCommand(options) {
|
|
6595
|
+
return await wrapCommandAction("listProfiles", ListProfilesOptions, options, async (opts) => {
|
|
6596
|
+
return await listProfiles(opts);
|
|
6597
|
+
});
|
|
6598
|
+
}
|
|
6599
|
+
async function listProfiles(options) {
|
|
6600
|
+
const authConfig = readAuthConfigFile();
|
|
6601
|
+
if (!authConfig) {
|
|
6602
|
+
logger.info("No profiles found");
|
|
5491
6603
|
return;
|
|
5492
6604
|
}
|
|
5493
|
-
|
|
5494
|
-
|
|
6605
|
+
const profiles = Object.keys(authConfig);
|
|
6606
|
+
log7.message("Profiles:");
|
|
6607
|
+
for (const profile of profiles) {
|
|
6608
|
+
const profileConfig = authConfig[profile];
|
|
6609
|
+
log7.info(`${profile}${profileConfig?.apiUrl ? ` - ${chalkGrey(profileConfig.apiUrl)}` : ""}`);
|
|
6610
|
+
}
|
|
6611
|
+
outro7("Retrieve account info by running whoami --profile <profile>");
|
|
5495
6612
|
}
|
|
5496
6613
|
|
|
5497
6614
|
// src/cli/index.ts
|
|
@@ -5503,6 +6620,8 @@ configureDevCommand(program);
|
|
|
5503
6620
|
configureDeployCommand(program);
|
|
5504
6621
|
configureWhoamiCommand(program);
|
|
5505
6622
|
configureLogoutCommand(program);
|
|
6623
|
+
configureListProfilesCommand(program);
|
|
6624
|
+
configureUpdateCommand(program);
|
|
5506
6625
|
|
|
5507
6626
|
// src/index.ts
|
|
5508
6627
|
var main = async () => {
|