@freecodecamp/universe-cli 0.6.0 → 0.7.0
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/index.cjs +305 -164
- package/dist/index.js +270 -204
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { cac } from "cac";
|
|
|
6
6
|
// src/commands/deploy.ts
|
|
7
7
|
import { readFile as readFile2 } from "fs/promises";
|
|
8
8
|
import { resolve as resolve2 } from "path";
|
|
9
|
-
import { log } from "@clack/prompts";
|
|
9
|
+
import { log as log2, spinner } from "@clack/prompts";
|
|
10
10
|
|
|
11
11
|
// src/output/exit-codes.ts
|
|
12
12
|
var EXIT_USAGE = 10;
|
|
@@ -429,6 +429,14 @@ function suggest(target, candidates, threshold = 2) {
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
// src/lib/proxy-client.ts
|
|
432
|
+
var DEFAULT_FETCH_TIMEOUT_MS = 3e4;
|
|
433
|
+
function parseFetchTimeoutMs(env) {
|
|
434
|
+
const raw = env["UNIVERSE_FETCH_TIMEOUT_MS"];
|
|
435
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
436
|
+
const n = Number(raw);
|
|
437
|
+
if (!Number.isFinite(n) || n < 0) return void 0;
|
|
438
|
+
return Math.floor(n);
|
|
439
|
+
}
|
|
432
440
|
var ProxyError = class extends CliError {
|
|
433
441
|
exitCode;
|
|
434
442
|
status;
|
|
@@ -506,6 +514,24 @@ function stripTrailingSlash(url) {
|
|
|
506
514
|
function createProxyClient(cfg) {
|
|
507
515
|
const base = stripTrailingSlash(cfg.baseUrl);
|
|
508
516
|
const fetchImpl = cfg.fetch ?? globalThis.fetch.bind(globalThis);
|
|
517
|
+
const timeoutMs = cfg.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
|
|
518
|
+
function withTimeoutSignal(init) {
|
|
519
|
+
if (timeoutMs <= 0) return init;
|
|
520
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
521
|
+
const merged = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
522
|
+
return { ...init, signal: merged };
|
|
523
|
+
}
|
|
524
|
+
function translateFetchError(err) {
|
|
525
|
+
if (err instanceof DOMException && (err.name === "TimeoutError" || err.name === "AbortError")) {
|
|
526
|
+
throw new ProxyError(
|
|
527
|
+
0,
|
|
528
|
+
"timeout",
|
|
529
|
+
`proxy timed out after ${timeoutMs}ms`
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
533
|
+
throw new ProxyError(0, "network_error", `proxy unreachable: ${message}`);
|
|
534
|
+
}
|
|
509
535
|
async function userBearer() {
|
|
510
536
|
const tok = await cfg.getAuthToken();
|
|
511
537
|
return `Bearer ${tok}`;
|
|
@@ -513,10 +539,9 @@ function createProxyClient(cfg) {
|
|
|
513
539
|
async function call(url, init) {
|
|
514
540
|
let response;
|
|
515
541
|
try {
|
|
516
|
-
response = await fetchImpl(url, init);
|
|
542
|
+
response = await fetchImpl(url, withTimeoutSignal(init));
|
|
517
543
|
} catch (err) {
|
|
518
|
-
|
|
519
|
-
throw new ProxyError(0, "network_error", `proxy unreachable: ${message}`);
|
|
544
|
+
translateFetchError(err);
|
|
520
545
|
}
|
|
521
546
|
if (!response.ok) {
|
|
522
547
|
const env = await readErrorEnvelope(response);
|
|
@@ -588,20 +613,18 @@ function createProxyClient(cfg) {
|
|
|
588
613
|
const url = `${base}/api/site/${encodeURIComponent(req.site)}/alias/${encodeURIComponent(req.mode)}`;
|
|
589
614
|
let response;
|
|
590
615
|
try {
|
|
591
|
-
response = await fetchImpl(
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
throw new ProxyError(
|
|
601
|
-
0,
|
|
602
|
-
"network_error",
|
|
603
|
-
`proxy unreachable: ${message}`
|
|
616
|
+
response = await fetchImpl(
|
|
617
|
+
url,
|
|
618
|
+
withTimeoutSignal({
|
|
619
|
+
method: "GET",
|
|
620
|
+
headers: {
|
|
621
|
+
Authorization: await userBearer(),
|
|
622
|
+
Accept: "application/json"
|
|
623
|
+
}
|
|
624
|
+
})
|
|
604
625
|
);
|
|
626
|
+
} catch (err) {
|
|
627
|
+
translateFetchError(err);
|
|
605
628
|
}
|
|
606
629
|
if (response.status === 404) return null;
|
|
607
630
|
if (!response.ok) {
|
|
@@ -845,6 +868,106 @@ function buildErrorEnvelope(command, code, message, issues) {
|
|
|
845
868
|
};
|
|
846
869
|
}
|
|
847
870
|
|
|
871
|
+
// src/output/format.ts
|
|
872
|
+
import { log } from "@clack/prompts";
|
|
873
|
+
|
|
874
|
+
// src/output/redact.ts
|
|
875
|
+
var AWS_KEY_PREFIX_PATTERN = /(?:AKIA|ASIA|AROA|AIDA|ACCA|ANPA|ABIA|AGPA)[A-Z0-9]{12,}/g;
|
|
876
|
+
var URL_CREDS_PATTERN = /https?:\/\/[^@\s]+@/g;
|
|
877
|
+
var CREDENTIAL_CONTEXT_PATTERN = /(?:access_key_id|secret_access_key|accessKeyId|secretAccessKey|secret|password|token|key|credential|auth)\s*[=:]\s*([A-Za-z0-9/+=]{21,})/gi;
|
|
878
|
+
var HEX_CREDENTIAL_CONTEXT_PATTERN = /(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key)\s*[=:]\s*([a-f0-9]{32,})/gi;
|
|
879
|
+
var JSON_CREDENTIAL_PATTERN = /"(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key|accessKeyId|secretAccessKey)"\s*:\s*"[^"]+"/gi;
|
|
880
|
+
var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
|
|
881
|
+
var CREDENTIAL_KEY_PATTERN = /(?:secret|password|token|key|credential|auth)/i;
|
|
882
|
+
var EXACT_CREDENTIAL_KEYS = /* @__PURE__ */ new Set([
|
|
883
|
+
"accesskeyid",
|
|
884
|
+
"secretaccesskey",
|
|
885
|
+
"access_key_id",
|
|
886
|
+
"secret_access_key"
|
|
887
|
+
]);
|
|
888
|
+
var STANDALONE_LONG_SECRET = /^[A-Za-z0-9/+=]{21,}$/;
|
|
889
|
+
function maskAwsKey(match) {
|
|
890
|
+
return match.slice(0, 4) + "****" + match.slice(-4);
|
|
891
|
+
}
|
|
892
|
+
function maskUrlCreds(match) {
|
|
893
|
+
const atIndex = match.lastIndexOf("@");
|
|
894
|
+
const protocolEnd = match.indexOf("://") + 3;
|
|
895
|
+
return match.slice(0, protocolEnd) + "****:****@" + match.slice(atIndex + 1);
|
|
896
|
+
}
|
|
897
|
+
function redact(value) {
|
|
898
|
+
let result = value;
|
|
899
|
+
result = result.replace(URL_CREDS_PATTERN, maskUrlCreds);
|
|
900
|
+
result = result.replace(AWS_KEY_PREFIX_PATTERN, maskAwsKey);
|
|
901
|
+
result = result.replace(BEARER_PATTERN, "Bearer ****");
|
|
902
|
+
result = result.replace(JSON_CREDENTIAL_PATTERN, (match) => {
|
|
903
|
+
const colonIndex = match.indexOf(":");
|
|
904
|
+
return match.slice(0, colonIndex + 1) + '"****"';
|
|
905
|
+
});
|
|
906
|
+
result = result.replace(
|
|
907
|
+
CREDENTIAL_CONTEXT_PATTERN,
|
|
908
|
+
(_match, _secret, _offset, _full) => {
|
|
909
|
+
const eqIndex = _match.indexOf("=");
|
|
910
|
+
const colonIndex = _match.indexOf(":");
|
|
911
|
+
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
912
|
+
const prefix = _match.slice(0, sepIndex + 1);
|
|
913
|
+
return prefix + "****";
|
|
914
|
+
}
|
|
915
|
+
);
|
|
916
|
+
result = result.replace(HEX_CREDENTIAL_CONTEXT_PATTERN, (_match, _secret) => {
|
|
917
|
+
const eqIndex = _match.indexOf("=");
|
|
918
|
+
const colonIndex = _match.indexOf(":");
|
|
919
|
+
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
920
|
+
const prefix = _match.slice(0, sepIndex + 1);
|
|
921
|
+
return prefix + "****";
|
|
922
|
+
});
|
|
923
|
+
return result;
|
|
924
|
+
}
|
|
925
|
+
function redactValue(value, keyName) {
|
|
926
|
+
if (typeof value === "string") {
|
|
927
|
+
if (keyName && EXACT_CREDENTIAL_KEYS.has(keyName.toLowerCase())) {
|
|
928
|
+
return "****";
|
|
929
|
+
}
|
|
930
|
+
const redacted = redact(value);
|
|
931
|
+
if (redacted === value && keyName && CREDENTIAL_KEY_PATTERN.test(keyName) && STANDALONE_LONG_SECRET.test(value)) {
|
|
932
|
+
return "****";
|
|
933
|
+
}
|
|
934
|
+
return redacted;
|
|
935
|
+
}
|
|
936
|
+
if (Array.isArray(value)) {
|
|
937
|
+
return value.map((v) => redactValue(v, keyName));
|
|
938
|
+
}
|
|
939
|
+
if (value !== null && typeof value === "object") {
|
|
940
|
+
return redactObject(value);
|
|
941
|
+
}
|
|
942
|
+
return value;
|
|
943
|
+
}
|
|
944
|
+
function redactObject(obj) {
|
|
945
|
+
const result = {};
|
|
946
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
947
|
+
result[key] = redactValue(value, key);
|
|
948
|
+
}
|
|
949
|
+
return result;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/output/format.ts
|
|
953
|
+
function outputError(ctx, code, message, optsOrIssues) {
|
|
954
|
+
const opts = Array.isArray(optsOrIssues) ? { issues: optsOrIssues } : optsOrIssues ?? {};
|
|
955
|
+
const redactedMessage = redact(message);
|
|
956
|
+
const redactedIssues = opts.issues?.map(redact);
|
|
957
|
+
if (ctx.json) {
|
|
958
|
+
const envelope = buildErrorEnvelope(
|
|
959
|
+
ctx.command,
|
|
960
|
+
code,
|
|
961
|
+
redactedMessage,
|
|
962
|
+
redactedIssues
|
|
963
|
+
);
|
|
964
|
+
const payload = opts.extras ? { ...envelope, ...redactObject(opts.extras) } : envelope;
|
|
965
|
+
process.stdout.write(JSON.stringify(payload) + "\n");
|
|
966
|
+
} else {
|
|
967
|
+
(opts.logError ?? ((m) => log.error(m)))(redactedMessage);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
848
971
|
// src/commands/deploy.ts
|
|
849
972
|
var defaultReadPlatformYaml = async (cwd) => {
|
|
850
973
|
return readFile2(resolve2(cwd, "platform.yaml"), "utf-8");
|
|
@@ -938,10 +1061,11 @@ async function deploy(options, deps = {}) {
|
|
|
938
1061
|
const build = deps.runBuild ?? runBuild;
|
|
939
1062
|
const walk = deps.walkFiles ?? walkFiles;
|
|
940
1063
|
const upload = deps.uploadFiles ?? uploadFiles;
|
|
941
|
-
const
|
|
942
|
-
const
|
|
943
|
-
const
|
|
944
|
-
const
|
|
1064
|
+
const mkSpinner = deps.createSpinner ?? (() => spinner());
|
|
1065
|
+
const success = deps.logSuccess ?? ((s) => log2.success(s));
|
|
1066
|
+
const info = deps.logInfo ?? ((s) => log2.info(s));
|
|
1067
|
+
const warn = deps.logWarn ?? ((s) => log2.warn(s));
|
|
1068
|
+
const error = deps.logError ?? ((s) => log2.error(s));
|
|
945
1069
|
const exit = deps.exit ?? exitWithCode;
|
|
946
1070
|
try {
|
|
947
1071
|
const identity = await resolveId({ env });
|
|
@@ -954,7 +1078,8 @@ async function deploy(options, deps = {}) {
|
|
|
954
1078
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
955
1079
|
const client = mkClient({
|
|
956
1080
|
baseUrl,
|
|
957
|
-
getAuthToken: () => identity.token
|
|
1081
|
+
getAuthToken: () => identity.token,
|
|
1082
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
958
1083
|
});
|
|
959
1084
|
let me;
|
|
960
1085
|
try {
|
|
@@ -1005,17 +1130,22 @@ async function deploy(options, deps = {}) {
|
|
|
1005
1130
|
} catch (err) {
|
|
1006
1131
|
rethrowProxy("deploy init failed", err);
|
|
1007
1132
|
}
|
|
1133
|
+
const spin = options.json ? null : mkSpinner();
|
|
1134
|
+
spin?.start(`Uploading 0/${filtered.length} files`);
|
|
1008
1135
|
const uploadResult = await upload({
|
|
1009
1136
|
client,
|
|
1010
1137
|
deployId: initResult.deployId,
|
|
1011
1138
|
jwt: initResult.jwt,
|
|
1012
|
-
files: filtered
|
|
1139
|
+
files: filtered,
|
|
1140
|
+
onProgress: spin ? (p) => spin.message(`Uploading ${p.uploaded}/${p.total} \u2014 ${p.current}`) : void 0
|
|
1013
1141
|
});
|
|
1014
1142
|
if (uploadResult.errors.length > 0) {
|
|
1143
|
+
spin?.error(`Upload failed: ${uploadResult.errors.length} file(s)`);
|
|
1015
1144
|
const message = `Upload partially failed: ${uploadResult.errors.length} file(s) failed:
|
|
1016
1145
|
- ${uploadResult.errors.join("\n - ")}`;
|
|
1017
1146
|
throw new PartialUploadError(message);
|
|
1018
1147
|
}
|
|
1148
|
+
spin?.stop(`Uploaded ${uploadResult.fileCount} files`);
|
|
1019
1149
|
const mode = options.promote ? "production" : "preview";
|
|
1020
1150
|
let finalizeResult;
|
|
1021
1151
|
try {
|
|
@@ -1028,6 +1158,25 @@ async function deploy(options, deps = {}) {
|
|
|
1028
1158
|
} catch (err) {
|
|
1029
1159
|
rethrowProxy("deploy finalize failed", err);
|
|
1030
1160
|
}
|
|
1161
|
+
if (options.promote && !options.json) {
|
|
1162
|
+
try {
|
|
1163
|
+
const preview = await client.getAlias({
|
|
1164
|
+
site: config.site,
|
|
1165
|
+
mode: "preview"
|
|
1166
|
+
});
|
|
1167
|
+
if (preview && preview.deployId !== finalizeResult.deployId) {
|
|
1168
|
+
warn(
|
|
1169
|
+
`Preview alias still points to ${preview.deployId}; it will not auto-update. Run \`universe static deploy\` (without --promote) to refresh preview.`
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
} catch (err) {
|
|
1173
|
+
if (err instanceof ProxyError && (err.status === 401 || err.status === 403)) {
|
|
1174
|
+
warn(
|
|
1175
|
+
`Preview alias probe got ${err.status} (${err.code}) \u2014 token may need rotation: ${err.message}`
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1031
1180
|
if (options.json) {
|
|
1032
1181
|
emitJson(
|
|
1033
1182
|
buildEnvelope("deploy", true, {
|
|
@@ -1074,17 +1223,15 @@ async function deploy(options, deps = {}) {
|
|
|
1074
1223
|
code = EXIT_USAGE;
|
|
1075
1224
|
message = String(err);
|
|
1076
1225
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
error(message);
|
|
1081
|
-
}
|
|
1226
|
+
outputError({ json: options.json, command: "deploy" }, code, message, {
|
|
1227
|
+
logError: error
|
|
1228
|
+
});
|
|
1082
1229
|
exit(code);
|
|
1083
1230
|
}
|
|
1084
1231
|
}
|
|
1085
1232
|
|
|
1086
1233
|
// src/commands/login.ts
|
|
1087
|
-
import { log as
|
|
1234
|
+
import { log as log3 } from "@clack/prompts";
|
|
1088
1235
|
|
|
1089
1236
|
// src/lib/device-flow.ts
|
|
1090
1237
|
var DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
@@ -1169,9 +1316,9 @@ async function login(options, deps = {}) {
|
|
|
1169
1316
|
const runFlow = deps.runDeviceFlow ?? runDeviceFlow;
|
|
1170
1317
|
const save = deps.saveToken ?? saveToken;
|
|
1171
1318
|
const load = deps.loadToken ?? loadToken;
|
|
1172
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1173
|
-
const info = deps.logInfo ?? ((s) =>
|
|
1174
|
-
const error = deps.logError ?? ((s) =>
|
|
1319
|
+
const success = deps.logSuccess ?? ((s) => log3.success(s));
|
|
1320
|
+
const info = deps.logInfo ?? ((s) => log3.info(s));
|
|
1321
|
+
const error = deps.logError ?? ((s) => log3.error(s));
|
|
1175
1322
|
const exit = deps.exit ?? exitWithCode;
|
|
1176
1323
|
const envClientId = env["UNIVERSE_GH_CLIENT_ID"];
|
|
1177
1324
|
const clientId = envClientId && envClientId.trim().length > 0 ? envClientId : DEFAULT_GH_CLIENT_ID;
|
|
@@ -1222,17 +1369,12 @@ async function login(options, deps = {}) {
|
|
|
1222
1369
|
});
|
|
1223
1370
|
} catch (err) {
|
|
1224
1371
|
const message = err instanceof Error ? err.message : String(err);
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
error: { code: EXIT_CREDENTIALS, message }
|
|
1232
|
-
});
|
|
1233
|
-
} else {
|
|
1234
|
-
error(message);
|
|
1235
|
-
}
|
|
1372
|
+
outputError(
|
|
1373
|
+
{ json: options.json, command: "login" },
|
|
1374
|
+
EXIT_CREDENTIALS,
|
|
1375
|
+
message,
|
|
1376
|
+
{ logError: error }
|
|
1377
|
+
);
|
|
1236
1378
|
exit(EXIT_CREDENTIALS);
|
|
1237
1379
|
return;
|
|
1238
1380
|
}
|
|
@@ -1245,15 +1387,15 @@ async function login(options, deps = {}) {
|
|
|
1245
1387
|
}
|
|
1246
1388
|
|
|
1247
1389
|
// src/commands/logout.ts
|
|
1248
|
-
import { log as
|
|
1390
|
+
import { log as log4 } from "@clack/prompts";
|
|
1249
1391
|
function emitJson3(envelope) {
|
|
1250
1392
|
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
1251
1393
|
}
|
|
1252
1394
|
async function logout(options, deps = {}) {
|
|
1253
1395
|
const load = deps.loadToken ?? loadToken;
|
|
1254
1396
|
const del = deps.deleteToken ?? deleteToken;
|
|
1255
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1256
|
-
const info = deps.logInfo ?? ((s) =>
|
|
1397
|
+
const success = deps.logSuccess ?? ((s) => log4.success(s));
|
|
1398
|
+
const info = deps.logInfo ?? ((s) => log4.info(s));
|
|
1257
1399
|
const existing = await load();
|
|
1258
1400
|
await del();
|
|
1259
1401
|
if (options.json) {
|
|
@@ -1270,7 +1412,7 @@ async function logout(options, deps = {}) {
|
|
|
1270
1412
|
// src/commands/ls.ts
|
|
1271
1413
|
import { readFile as readFile3 } from "fs/promises";
|
|
1272
1414
|
import { resolve as resolve3 } from "path";
|
|
1273
|
-
import { log as
|
|
1415
|
+
import { log as log5 } from "@clack/prompts";
|
|
1274
1416
|
var defaultReadPlatformYaml2 = async (cwd) => {
|
|
1275
1417
|
return readFile3(resolve3(cwd, "platform.yaml"), "utf-8");
|
|
1276
1418
|
};
|
|
@@ -1320,9 +1462,9 @@ async function ls(options, deps = {}) {
|
|
|
1320
1462
|
const readYaml = deps.readPlatformYaml ?? defaultReadPlatformYaml2;
|
|
1321
1463
|
const resolveId = deps.resolveIdentity ?? resolveIdentity;
|
|
1322
1464
|
const mkClient = deps.createProxyClient ?? createProxyClient;
|
|
1323
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1324
|
-
const info = deps.logInfo ?? ((s) =>
|
|
1325
|
-
const error = deps.logError ?? ((s) =>
|
|
1465
|
+
const success = deps.logSuccess ?? ((s) => log5.success(s));
|
|
1466
|
+
const info = deps.logInfo ?? ((s) => log5.info(s));
|
|
1467
|
+
const error = deps.logError ?? ((s) => log5.error(s));
|
|
1326
1468
|
const exit = deps.exit ?? exitWithCode;
|
|
1327
1469
|
try {
|
|
1328
1470
|
const identity = await resolveId({ env });
|
|
@@ -1343,7 +1485,8 @@ async function ls(options, deps = {}) {
|
|
|
1343
1485
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
1344
1486
|
const client = mkClient({
|
|
1345
1487
|
baseUrl,
|
|
1346
|
-
getAuthToken: () => identity.token
|
|
1488
|
+
getAuthToken: () => identity.token,
|
|
1489
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
1347
1490
|
});
|
|
1348
1491
|
const raw = await client.siteDeploys({ site });
|
|
1349
1492
|
const sorted = [...raw].sort(
|
|
@@ -1367,11 +1510,9 @@ async function ls(options, deps = {}) {
|
|
|
1367
1510
|
success(formatTable(deploys));
|
|
1368
1511
|
} catch (err) {
|
|
1369
1512
|
const { code, message } = wrapProxyError("ls", err);
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
}
|
|
1373
|
-
error(message);
|
|
1374
|
-
}
|
|
1513
|
+
outputError({ json: options.json, command: "ls" }, code, message, {
|
|
1514
|
+
logError: error
|
|
1515
|
+
});
|
|
1375
1516
|
exit(code);
|
|
1376
1517
|
}
|
|
1377
1518
|
}
|
|
@@ -1379,7 +1520,7 @@ async function ls(options, deps = {}) {
|
|
|
1379
1520
|
// src/commands/promote.ts
|
|
1380
1521
|
import { readFile as readFile4 } from "fs/promises";
|
|
1381
1522
|
import { resolve as resolve4 } from "path";
|
|
1382
|
-
import { confirm, isCancel, log as
|
|
1523
|
+
import { confirm, isCancel, log as log6 } from "@clack/prompts";
|
|
1383
1524
|
var defaultPromptConfirm = async (msg) => {
|
|
1384
1525
|
const r = await confirm({ message: msg, initialValue: false });
|
|
1385
1526
|
if (isCancel(r)) return false;
|
|
@@ -1413,8 +1554,8 @@ async function promote(options, deps = {}) {
|
|
|
1413
1554
|
const readYaml = deps.readPlatformYaml ?? defaultReadPlatformYaml3;
|
|
1414
1555
|
const resolveId = deps.resolveIdentity ?? resolveIdentity;
|
|
1415
1556
|
const mkClient = deps.createProxyClient ?? createProxyClient;
|
|
1416
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1417
|
-
const error = deps.logError ?? ((s) =>
|
|
1557
|
+
const success = deps.logSuccess ?? ((s) => log6.success(s));
|
|
1558
|
+
const error = deps.logError ?? ((s) => log6.error(s));
|
|
1418
1559
|
const exit = deps.exit ?? exitWithCode;
|
|
1419
1560
|
const promptConfirm = deps.promptConfirm ?? defaultPromptConfirm;
|
|
1420
1561
|
try {
|
|
@@ -1428,7 +1569,8 @@ async function promote(options, deps = {}) {
|
|
|
1428
1569
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
1429
1570
|
const client = mkClient({
|
|
1430
1571
|
baseUrl,
|
|
1431
|
-
getAuthToken: () => identity.token
|
|
1572
|
+
getAuthToken: () => identity.token,
|
|
1573
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
1432
1574
|
});
|
|
1433
1575
|
let result;
|
|
1434
1576
|
if (options.from) {
|
|
@@ -1526,16 +1668,11 @@ async function promote(options, deps = {}) {
|
|
|
1526
1668
|
}
|
|
1527
1669
|
} catch (err) {
|
|
1528
1670
|
const { code, message } = wrapProxyError("promote", err);
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
emitJson5(envelope);
|
|
1535
|
-
}
|
|
1536
|
-
} else {
|
|
1537
|
-
error(message);
|
|
1538
|
-
}
|
|
1671
|
+
const extras = err instanceof AliasDriftError ? { current: err.current } : void 0;
|
|
1672
|
+
outputError({ json: options.json, command: "promote" }, code, message, {
|
|
1673
|
+
logError: error,
|
|
1674
|
+
extras
|
|
1675
|
+
});
|
|
1539
1676
|
exit(code);
|
|
1540
1677
|
}
|
|
1541
1678
|
}
|
|
@@ -1543,7 +1680,7 @@ async function promote(options, deps = {}) {
|
|
|
1543
1680
|
// src/commands/rollback.ts
|
|
1544
1681
|
import { readFile as readFile5 } from "fs/promises";
|
|
1545
1682
|
import { resolve as resolve5 } from "path";
|
|
1546
|
-
import { confirm as confirm2, isCancel as isCancel2, log as
|
|
1683
|
+
import { confirm as confirm2, isCancel as isCancel2, log as log7 } from "@clack/prompts";
|
|
1547
1684
|
var defaultPromptConfirm2 = async (msg) => {
|
|
1548
1685
|
const r = await confirm2({ message: msg, initialValue: false });
|
|
1549
1686
|
if (isCancel2(r)) return false;
|
|
@@ -1577,8 +1714,8 @@ async function rollback(options, deps = {}) {
|
|
|
1577
1714
|
const readYaml = deps.readPlatformYaml ?? defaultReadPlatformYaml4;
|
|
1578
1715
|
const resolveId = deps.resolveIdentity ?? resolveIdentity;
|
|
1579
1716
|
const mkClient = deps.createProxyClient ?? createProxyClient;
|
|
1580
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1581
|
-
const error = deps.logError ?? ((s) =>
|
|
1717
|
+
const success = deps.logSuccess ?? ((s) => log7.success(s));
|
|
1718
|
+
const error = deps.logError ?? ((s) => log7.error(s));
|
|
1582
1719
|
const exit = deps.exit ?? exitWithCode;
|
|
1583
1720
|
const promptConfirm = deps.promptConfirm ?? defaultPromptConfirm2;
|
|
1584
1721
|
try {
|
|
@@ -1597,7 +1734,8 @@ async function rollback(options, deps = {}) {
|
|
|
1597
1734
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
1598
1735
|
const client = mkClient({
|
|
1599
1736
|
baseUrl,
|
|
1600
|
-
getAuthToken: () => identity.token
|
|
1737
|
+
getAuthToken: () => identity.token,
|
|
1738
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
1601
1739
|
});
|
|
1602
1740
|
const to = options.to.trim();
|
|
1603
1741
|
const prod = await client.getAlias({
|
|
@@ -1650,22 +1788,17 @@ async function rollback(options, deps = {}) {
|
|
|
1650
1788
|
}
|
|
1651
1789
|
} catch (err) {
|
|
1652
1790
|
const { code, message } = wrapProxyError("rollback", err);
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
emitJson6(envelope);
|
|
1659
|
-
}
|
|
1660
|
-
} else {
|
|
1661
|
-
error(message);
|
|
1662
|
-
}
|
|
1791
|
+
const extras = err instanceof AliasDriftError ? { current: err.current } : void 0;
|
|
1792
|
+
outputError({ json: options.json, command: "rollback" }, code, message, {
|
|
1793
|
+
logError: error,
|
|
1794
|
+
extras
|
|
1795
|
+
});
|
|
1663
1796
|
exit(code);
|
|
1664
1797
|
}
|
|
1665
1798
|
}
|
|
1666
1799
|
|
|
1667
1800
|
// src/commands/whoami.ts
|
|
1668
|
-
import { log as
|
|
1801
|
+
import { log as log8 } from "@clack/prompts";
|
|
1669
1802
|
var DEFAULT_PROXY_URL2 = "https://uploads.freecode.camp";
|
|
1670
1803
|
function emitJson7(envelope) {
|
|
1671
1804
|
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
@@ -1674,24 +1807,26 @@ async function whoami(options, deps = {}) {
|
|
|
1674
1807
|
const env = deps.env ?? process.env;
|
|
1675
1808
|
const resolve6 = deps.resolveIdentity ?? resolveIdentity;
|
|
1676
1809
|
const mkClient = deps.createProxyClient ?? createProxyClient;
|
|
1677
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1678
|
-
const error = deps.logError ?? ((s) =>
|
|
1810
|
+
const success = deps.logSuccess ?? ((s) => log8.success(s));
|
|
1811
|
+
const error = deps.logError ?? ((s) => log8.error(s));
|
|
1679
1812
|
const exit = deps.exit ?? exitWithCode;
|
|
1680
1813
|
const identity = await resolve6({ env });
|
|
1681
1814
|
if (!identity) {
|
|
1682
1815
|
const msg = "No GitHub identity available. Run `universe login`, set $GITHUB_TOKEN, or install the gh CLI.";
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1816
|
+
outputError(
|
|
1817
|
+
{ json: options.json, command: "whoami" },
|
|
1818
|
+
EXIT_CREDENTIALS,
|
|
1819
|
+
msg,
|
|
1820
|
+
{ logError: error }
|
|
1821
|
+
);
|
|
1688
1822
|
exit(EXIT_CREDENTIALS);
|
|
1689
1823
|
return;
|
|
1690
1824
|
}
|
|
1691
1825
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL2;
|
|
1692
1826
|
const client = mkClient({
|
|
1693
1827
|
baseUrl,
|
|
1694
|
-
getAuthToken: () => identity.token
|
|
1828
|
+
getAuthToken: () => identity.token,
|
|
1829
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
1695
1830
|
});
|
|
1696
1831
|
try {
|
|
1697
1832
|
const result = await client.whoami();
|
|
@@ -1717,17 +1852,15 @@ async function whoami(options, deps = {}) {
|
|
|
1717
1852
|
} catch (err) {
|
|
1718
1853
|
const exitCode = err instanceof CliError ? err.exitCode : EXIT_CREDENTIALS;
|
|
1719
1854
|
const message = err instanceof ProxyError ? `whoami failed (${err.code}): ${err.message}` : err instanceof Error ? err.message : String(err);
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
}
|
|
1723
|
-
error(message);
|
|
1724
|
-
}
|
|
1855
|
+
outputError({ json: options.json, command: "whoami" }, exitCode, message, {
|
|
1856
|
+
logError: error
|
|
1857
|
+
});
|
|
1725
1858
|
exit(exitCode);
|
|
1726
1859
|
}
|
|
1727
1860
|
}
|
|
1728
1861
|
|
|
1729
1862
|
// src/commands/sites/ls.ts
|
|
1730
|
-
import { log as
|
|
1863
|
+
import { log as log9 } from "@clack/prompts";
|
|
1731
1864
|
|
|
1732
1865
|
// src/commands/sites/_shared.ts
|
|
1733
1866
|
function emitJson8(envelope) {
|
|
@@ -1751,7 +1884,8 @@ async function setupClient(deps) {
|
|
|
1751
1884
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
1752
1885
|
const client = mkClient({
|
|
1753
1886
|
baseUrl,
|
|
1754
|
-
getAuthToken: () => identity.token
|
|
1887
|
+
getAuthToken: () => identity.token,
|
|
1888
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
1755
1889
|
});
|
|
1756
1890
|
return { client, identitySource: identity.source };
|
|
1757
1891
|
}
|
|
@@ -1774,11 +1908,11 @@ function formatTable2(rows) {
|
|
|
1774
1908
|
}
|
|
1775
1909
|
async function ls2(options, deps = {}) {
|
|
1776
1910
|
const command = "sites ls";
|
|
1777
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1778
|
-
const error = deps.logError ?? ((s) =>
|
|
1911
|
+
const success = deps.logSuccess ?? ((s) => log9.message(s));
|
|
1912
|
+
const error = deps.logError ?? ((s) => log9.error(s));
|
|
1779
1913
|
const exit = deps.exit ?? exitWithCode;
|
|
1780
1914
|
try {
|
|
1781
|
-
const { client } = await setupClient(deps);
|
|
1915
|
+
const { client, identitySource } = await setupClient(deps);
|
|
1782
1916
|
let rows = await client.listSites();
|
|
1783
1917
|
let scope = "all";
|
|
1784
1918
|
if (options.mine) {
|
|
@@ -1792,7 +1926,8 @@ async function ls2(options, deps = {}) {
|
|
|
1792
1926
|
buildEnvelope(command, true, {
|
|
1793
1927
|
count: rows.length,
|
|
1794
1928
|
scope,
|
|
1795
|
-
sites: rows
|
|
1929
|
+
sites: rows,
|
|
1930
|
+
identitySource
|
|
1796
1931
|
})
|
|
1797
1932
|
);
|
|
1798
1933
|
} else {
|
|
@@ -1800,28 +1935,26 @@ async function ls2(options, deps = {}) {
|
|
|
1800
1935
|
}
|
|
1801
1936
|
} catch (err) {
|
|
1802
1937
|
const { code, message } = wrapProxyError(command, err);
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
}
|
|
1806
|
-
error(message);
|
|
1807
|
-
}
|
|
1938
|
+
outputError({ json: options.json, command }, code, message, {
|
|
1939
|
+
logError: error
|
|
1940
|
+
});
|
|
1808
1941
|
exit(code);
|
|
1809
1942
|
}
|
|
1810
1943
|
}
|
|
1811
1944
|
|
|
1812
1945
|
// src/commands/sites/register.ts
|
|
1813
|
-
import { log as
|
|
1946
|
+
import { log as log10 } from "@clack/prompts";
|
|
1814
1947
|
async function register(options, deps = {}) {
|
|
1815
1948
|
const command = "sites register";
|
|
1816
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1817
|
-
const error = deps.logError ?? ((s) =>
|
|
1949
|
+
const success = deps.logSuccess ?? ((s) => log10.success(s));
|
|
1950
|
+
const error = deps.logError ?? ((s) => log10.error(s));
|
|
1818
1951
|
const exit = deps.exit ?? exitWithCode;
|
|
1819
1952
|
try {
|
|
1820
1953
|
if (!options.slug || options.slug.trim().length === 0) {
|
|
1821
1954
|
throw new UsageError("slug is required (positional argument)");
|
|
1822
1955
|
}
|
|
1823
1956
|
const teams = parseTeamsFlag(options.team);
|
|
1824
|
-
const { client } = await setupClient(deps);
|
|
1957
|
+
const { client, identitySource } = await setupClient(deps);
|
|
1825
1958
|
const row = await client.registerSite({
|
|
1826
1959
|
slug: options.slug,
|
|
1827
1960
|
teams: teams.length > 0 ? teams : void 0
|
|
@@ -1832,7 +1965,8 @@ async function register(options, deps = {}) {
|
|
|
1832
1965
|
slug: row.slug,
|
|
1833
1966
|
teams: row.teams,
|
|
1834
1967
|
createdAt: row.createdAt,
|
|
1835
|
-
createdBy: row.createdBy
|
|
1968
|
+
createdBy: row.createdBy,
|
|
1969
|
+
identitySource
|
|
1836
1970
|
})
|
|
1837
1971
|
);
|
|
1838
1972
|
} else {
|
|
@@ -1849,33 +1983,32 @@ async function register(options, deps = {}) {
|
|
|
1849
1983
|
}
|
|
1850
1984
|
} catch (err) {
|
|
1851
1985
|
const { code, message } = wrapProxyError(command, err);
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
}
|
|
1855
|
-
error(message);
|
|
1856
|
-
}
|
|
1986
|
+
outputError({ json: options.json, command }, code, message, {
|
|
1987
|
+
logError: error
|
|
1988
|
+
});
|
|
1857
1989
|
exit(code);
|
|
1858
1990
|
}
|
|
1859
1991
|
}
|
|
1860
1992
|
|
|
1861
1993
|
// src/commands/sites/rm.ts
|
|
1862
|
-
import { log as
|
|
1994
|
+
import { log as log11 } from "@clack/prompts";
|
|
1863
1995
|
async function rm2(options, deps = {}) {
|
|
1864
1996
|
const command = "sites rm";
|
|
1865
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1866
|
-
const error = deps.logError ?? ((s) =>
|
|
1997
|
+
const success = deps.logSuccess ?? ((s) => log11.success(s));
|
|
1998
|
+
const error = deps.logError ?? ((s) => log11.error(s));
|
|
1867
1999
|
const exit = deps.exit ?? exitWithCode;
|
|
1868
2000
|
try {
|
|
1869
2001
|
if (!options.slug || options.slug.trim().length === 0) {
|
|
1870
2002
|
throw new UsageError("slug is required (positional argument)");
|
|
1871
2003
|
}
|
|
1872
|
-
const { client } = await setupClient(deps);
|
|
2004
|
+
const { client, identitySource } = await setupClient(deps);
|
|
1873
2005
|
await client.deleteSite({ slug: options.slug });
|
|
1874
2006
|
if (options.json) {
|
|
1875
2007
|
emitJson8(
|
|
1876
2008
|
buildEnvelope(command, true, {
|
|
1877
2009
|
slug: options.slug,
|
|
1878
|
-
deleted: true
|
|
2010
|
+
deleted: true,
|
|
2011
|
+
identitySource
|
|
1879
2012
|
})
|
|
1880
2013
|
);
|
|
1881
2014
|
} else {
|
|
@@ -1890,21 +2023,19 @@ async function rm2(options, deps = {}) {
|
|
|
1890
2023
|
}
|
|
1891
2024
|
} catch (err) {
|
|
1892
2025
|
const { code, message } = wrapProxyError(command, err);
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
}
|
|
1896
|
-
error(message);
|
|
1897
|
-
}
|
|
2026
|
+
outputError({ json: options.json, command }, code, message, {
|
|
2027
|
+
logError: error
|
|
2028
|
+
});
|
|
1898
2029
|
exit(code);
|
|
1899
2030
|
}
|
|
1900
2031
|
}
|
|
1901
2032
|
|
|
1902
2033
|
// src/commands/sites/update.ts
|
|
1903
|
-
import { log as
|
|
2034
|
+
import { log as log12 } from "@clack/prompts";
|
|
1904
2035
|
async function update(options, deps = {}) {
|
|
1905
2036
|
const command = "sites update";
|
|
1906
|
-
const success = deps.logSuccess ?? ((s) =>
|
|
1907
|
-
const error = deps.logError ?? ((s) =>
|
|
2037
|
+
const success = deps.logSuccess ?? ((s) => log12.success(s));
|
|
2038
|
+
const error = deps.logError ?? ((s) => log12.error(s));
|
|
1908
2039
|
const exit = deps.exit ?? exitWithCode;
|
|
1909
2040
|
try {
|
|
1910
2041
|
if (!options.slug || options.slug.trim().length === 0) {
|
|
@@ -1916,7 +2047,7 @@ async function update(options, deps = {}) {
|
|
|
1916
2047
|
"--team is required with at least one slug; use `sites rm` to remove a site"
|
|
1917
2048
|
);
|
|
1918
2049
|
}
|
|
1919
|
-
const { client } = await setupClient(deps);
|
|
2050
|
+
const { client, identitySource } = await setupClient(deps);
|
|
1920
2051
|
const row = await client.updateSite({
|
|
1921
2052
|
slug: options.slug,
|
|
1922
2053
|
teams
|
|
@@ -1926,7 +2057,8 @@ async function update(options, deps = {}) {
|
|
|
1926
2057
|
buildEnvelope(command, true, {
|
|
1927
2058
|
slug: row.slug,
|
|
1928
2059
|
teams: row.teams,
|
|
1929
|
-
updatedAt: row.updatedAt
|
|
2060
|
+
updatedAt: row.updatedAt,
|
|
2061
|
+
identitySource
|
|
1930
2062
|
})
|
|
1931
2063
|
);
|
|
1932
2064
|
} else {
|
|
@@ -1942,81 +2074,15 @@ async function update(options, deps = {}) {
|
|
|
1942
2074
|
}
|
|
1943
2075
|
} catch (err) {
|
|
1944
2076
|
const { code, message } = wrapProxyError(command, err);
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
}
|
|
1948
|
-
error(message);
|
|
1949
|
-
}
|
|
2077
|
+
outputError({ json: options.json, command }, code, message, {
|
|
2078
|
+
logError: error
|
|
2079
|
+
});
|
|
1950
2080
|
exit(code);
|
|
1951
2081
|
}
|
|
1952
2082
|
}
|
|
1953
2083
|
|
|
1954
|
-
// src/output/format.ts
|
|
1955
|
-
import { log as log12 } from "@clack/prompts";
|
|
1956
|
-
|
|
1957
|
-
// src/output/redact.ts
|
|
1958
|
-
var AWS_KEY_PREFIX_PATTERN = /(?:AKIA|ASIA|AROA|AIDA|ACCA|ANPA|ABIA|AGPA)[A-Z0-9]{12,}/g;
|
|
1959
|
-
var URL_CREDS_PATTERN = /https?:\/\/[^@\s]+@/g;
|
|
1960
|
-
var CREDENTIAL_CONTEXT_PATTERN = /(?:access_key_id|secret_access_key|accessKeyId|secretAccessKey|secret|password|token|key|credential|auth)\s*[=:]\s*([A-Za-z0-9/+=]{21,})/gi;
|
|
1961
|
-
var HEX_CREDENTIAL_CONTEXT_PATTERN = /(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key)\s*[=:]\s*([a-f0-9]{32,})/gi;
|
|
1962
|
-
var JSON_CREDENTIAL_PATTERN = /"(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key|accessKeyId|secretAccessKey)"\s*:\s*"[^"]+"/gi;
|
|
1963
|
-
var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
|
|
1964
|
-
function maskAwsKey(match) {
|
|
1965
|
-
return match.slice(0, 4) + "****" + match.slice(-4);
|
|
1966
|
-
}
|
|
1967
|
-
function maskUrlCreds(match) {
|
|
1968
|
-
const atIndex = match.lastIndexOf("@");
|
|
1969
|
-
const protocolEnd = match.indexOf("://") + 3;
|
|
1970
|
-
return match.slice(0, protocolEnd) + "****:****@" + match.slice(atIndex + 1);
|
|
1971
|
-
}
|
|
1972
|
-
function redact(value) {
|
|
1973
|
-
let result = value;
|
|
1974
|
-
result = result.replace(URL_CREDS_PATTERN, maskUrlCreds);
|
|
1975
|
-
result = result.replace(AWS_KEY_PREFIX_PATTERN, maskAwsKey);
|
|
1976
|
-
result = result.replace(BEARER_PATTERN, "Bearer ****");
|
|
1977
|
-
result = result.replace(JSON_CREDENTIAL_PATTERN, (match) => {
|
|
1978
|
-
const colonIndex = match.indexOf(":");
|
|
1979
|
-
return match.slice(0, colonIndex + 1) + '"****"';
|
|
1980
|
-
});
|
|
1981
|
-
result = result.replace(
|
|
1982
|
-
CREDENTIAL_CONTEXT_PATTERN,
|
|
1983
|
-
(_match, _secret, _offset, _full) => {
|
|
1984
|
-
const eqIndex = _match.indexOf("=");
|
|
1985
|
-
const colonIndex = _match.indexOf(":");
|
|
1986
|
-
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
1987
|
-
const prefix = _match.slice(0, sepIndex + 1);
|
|
1988
|
-
return prefix + "****";
|
|
1989
|
-
}
|
|
1990
|
-
);
|
|
1991
|
-
result = result.replace(HEX_CREDENTIAL_CONTEXT_PATTERN, (_match, _secret) => {
|
|
1992
|
-
const eqIndex = _match.indexOf("=");
|
|
1993
|
-
const colonIndex = _match.indexOf(":");
|
|
1994
|
-
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
1995
|
-
const prefix = _match.slice(0, sepIndex + 1);
|
|
1996
|
-
return prefix + "****";
|
|
1997
|
-
});
|
|
1998
|
-
return result;
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
|
-
// src/output/format.ts
|
|
2002
|
-
function outputError(ctx, code, message, issues) {
|
|
2003
|
-
const redactedMessage = redact(message);
|
|
2004
|
-
const redactedIssues = issues?.map(redact);
|
|
2005
|
-
if (ctx.json) {
|
|
2006
|
-
const envelope = buildErrorEnvelope(
|
|
2007
|
-
ctx.command,
|
|
2008
|
-
code,
|
|
2009
|
-
redactedMessage,
|
|
2010
|
-
redactedIssues
|
|
2011
|
-
);
|
|
2012
|
-
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
2013
|
-
} else {
|
|
2014
|
-
log12.error(redactedMessage);
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
2084
|
// src/cli.ts
|
|
2019
|
-
var version = true ? "0.
|
|
2085
|
+
var version = true ? "0.7.0" : "0.0.0";
|
|
2020
2086
|
function handleActionError(command, json, err) {
|
|
2021
2087
|
const ctx = { json, command };
|
|
2022
2088
|
const message = err instanceof Error ? err.message : "unknown error";
|