@freecodecamp/universe-cli 0.6.0 → 0.7.1
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/README.md +8 -8
- package/dist/index.cjs +361 -171
- package/dist/index.js +326 -211
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8421,6 +8421,27 @@ function w(r, t2) {
|
|
|
8421
8421
|
const e = r;
|
|
8422
8422
|
e.isTTY && e.setRawMode(t2);
|
|
8423
8423
|
}
|
|
8424
|
+
function z({ input: r = import_node_process.stdin, output: t2 = import_node_process.stdout, overwrite: e = true, hideCursor: s = true } = {}) {
|
|
8425
|
+
const i = _.createInterface({ input: r, output: t2, prompt: "", tabSize: 1 });
|
|
8426
|
+
_.emitKeypressEvents(r, i), r instanceof import_node_tty.ReadStream && r.isTTY && r.setRawMode(true);
|
|
8427
|
+
const n = (o, { name: a, sequence: h }) => {
|
|
8428
|
+
const l = String(o);
|
|
8429
|
+
if (V([l, a, h], "cancel")) {
|
|
8430
|
+
s && t2.write(import_sisteransi.cursor.show), process.exit(0);
|
|
8431
|
+
return;
|
|
8432
|
+
}
|
|
8433
|
+
if (!e) return;
|
|
8434
|
+
const f = a === "return" ? 0 : -1, v = a === "return" ? -1 : 0;
|
|
8435
|
+
_.moveCursor(t2, f, v, () => {
|
|
8436
|
+
_.clearLine(t2, 1, () => {
|
|
8437
|
+
r.once("keypress", n);
|
|
8438
|
+
});
|
|
8439
|
+
});
|
|
8440
|
+
};
|
|
8441
|
+
return s && t2.write(import_sisteransi.cursor.hide), r.once("keypress", n), () => {
|
|
8442
|
+
r.off("keypress", n), s && t2.write(import_sisteransi.cursor.show), r instanceof import_node_tty.ReadStream && r.isTTY && !Y && r.setRawMode(false), i.terminal = false, i.close();
|
|
8443
|
+
};
|
|
8444
|
+
}
|
|
8424
8445
|
var O = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80;
|
|
8425
8446
|
var A = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
|
|
8426
8447
|
function R(r, t2, e, s = e) {
|
|
@@ -8579,6 +8600,7 @@ function Ze() {
|
|
|
8579
8600
|
return import_node_process2.default.platform !== "win32" ? import_node_process2.default.env.TERM !== "linux" : !!import_node_process2.default.env.CI || !!import_node_process2.default.env.WT_SESSION || !!import_node_process2.default.env.TERMINUS_SUBLIME || import_node_process2.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process2.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process2.default.env.TERM_PROGRAM === "vscode" || import_node_process2.default.env.TERM === "xterm-256color" || import_node_process2.default.env.TERM === "alacritty" || import_node_process2.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
8580
8601
|
}
|
|
8581
8602
|
var ee = Ze();
|
|
8603
|
+
var ae = () => process.env.CI === "true";
|
|
8582
8604
|
var w2 = (e, i) => ee ? e : i;
|
|
8583
8605
|
var _e = w2("\u25C6", "*");
|
|
8584
8606
|
var oe = w2("\u25A0", "x");
|
|
@@ -8671,6 +8693,59 @@ var O2 = { message: (e = [], { symbol: i = (0, import_node_util2.styleText)("gra
|
|
|
8671
8693
|
}, error: (e, i) => {
|
|
8672
8694
|
O2.message(e, { ...i, symbol: (0, import_node_util2.styleText)("red", ge) });
|
|
8673
8695
|
} };
|
|
8696
|
+
var Ct = (e) => (0, import_node_util2.styleText)("magenta", e);
|
|
8697
|
+
var fe = ({ indicator: e = "dots", onCancel: i, output: s = process.stdout, cancelMessage: r, errorMessage: u2, frames: n = ee ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: o = ee ? 80 : 120, signal: c2, ...a } = {}) => {
|
|
8698
|
+
const l = ae();
|
|
8699
|
+
let $2, y2, p2 = false, m = false, g = "", S2, h = performance.now();
|
|
8700
|
+
const f = O(s), v = a?.styleFrame ?? Ct, T = (_2) => {
|
|
8701
|
+
const A2 = _2 > 1 ? u2 ?? u.messages.error : r ?? u.messages.cancel;
|
|
8702
|
+
m = _2 === 1, p2 && (W(A2, _2), m && typeof i == "function" && i());
|
|
8703
|
+
}, C2 = () => T(2), b = () => T(1), x = () => {
|
|
8704
|
+
process.on("uncaughtExceptionMonitor", C2), process.on("unhandledRejection", C2), process.on("SIGINT", b), process.on("SIGTERM", b), process.on("exit", T), c2 && c2.addEventListener("abort", b);
|
|
8705
|
+
}, G2 = () => {
|
|
8706
|
+
process.removeListener("uncaughtExceptionMonitor", C2), process.removeListener("unhandledRejection", C2), process.removeListener("SIGINT", b), process.removeListener("SIGTERM", b), process.removeListener("exit", T), c2 && c2.removeEventListener("abort", b);
|
|
8707
|
+
}, M2 = () => {
|
|
8708
|
+
if (S2 === void 0) return;
|
|
8709
|
+
l && s.write(`
|
|
8710
|
+
`);
|
|
8711
|
+
const _2 = wrapAnsi(S2, f, { hard: true, trim: false }).split(`
|
|
8712
|
+
`);
|
|
8713
|
+
_2.length > 1 && s.write(import_sisteransi2.cursor.up(_2.length - 1)), s.write(import_sisteransi2.cursor.to(0)), s.write(import_sisteransi2.erase.down());
|
|
8714
|
+
}, R2 = (_2) => _2.replace(/\.+$/, ""), j2 = (_2) => {
|
|
8715
|
+
const A2 = (performance.now() - _2) / 1e3, k = Math.floor(A2 / 60), L = Math.floor(A2 % 60);
|
|
8716
|
+
return k > 0 ? `[${k}m ${L}s]` : `[${L}s]`;
|
|
8717
|
+
}, D2 = a.withGuide ?? u.withGuide, ie = (_2 = "") => {
|
|
8718
|
+
p2 = true, $2 = z({ output: s }), g = R2(_2), h = performance.now(), D2 && s.write(`${(0, import_node_util2.styleText)("gray", d)}
|
|
8719
|
+
`);
|
|
8720
|
+
let A2 = 0, k = 0;
|
|
8721
|
+
x(), y2 = setInterval(() => {
|
|
8722
|
+
if (l && g === S2) return;
|
|
8723
|
+
M2(), S2 = g;
|
|
8724
|
+
const L = v(n[A2]);
|
|
8725
|
+
let Z;
|
|
8726
|
+
if (l) Z = `${L} ${g}...`;
|
|
8727
|
+
else if (e === "timer") Z = `${L} ${g} ${j2(h)}`;
|
|
8728
|
+
else {
|
|
8729
|
+
const Be = ".".repeat(Math.floor(k)).slice(0, 3);
|
|
8730
|
+
Z = `${L} ${g}${Be}`;
|
|
8731
|
+
}
|
|
8732
|
+
const Ne = wrapAnsi(Z, f, { hard: true, trim: false });
|
|
8733
|
+
s.write(Ne), A2 = A2 + 1 < n.length ? A2 + 1 : 0, k = k < 4 ? k + 0.125 : 0;
|
|
8734
|
+
}, o);
|
|
8735
|
+
}, W = (_2 = "", A2 = 0, k = false) => {
|
|
8736
|
+
if (!p2) return;
|
|
8737
|
+
p2 = false, clearInterval(y2), M2();
|
|
8738
|
+
const L = A2 === 0 ? (0, import_node_util2.styleText)("green", F) : A2 === 1 ? (0, import_node_util2.styleText)("red", oe) : (0, import_node_util2.styleText)("red", ue);
|
|
8739
|
+
g = _2 ?? g, k || (e === "timer" ? s.write(`${L} ${g} ${j2(h)}
|
|
8740
|
+
`) : s.write(`${L} ${g}
|
|
8741
|
+
`)), G2(), $2();
|
|
8742
|
+
};
|
|
8743
|
+
return { start: ie, stop: (_2 = "") => W(_2, 0), message: (_2 = "") => {
|
|
8744
|
+
g = R2(_2 ?? g);
|
|
8745
|
+
}, cancel: (_2 = "") => W(_2, 1), error: (_2 = "") => W(_2, 2), clear: () => W("", 0, true), get isCancelled() {
|
|
8746
|
+
return m;
|
|
8747
|
+
} };
|
|
8748
|
+
};
|
|
8674
8749
|
var Ve = { light: w2("\u2500", "-"), heavy: w2("\u2501", "="), block: w2("\u2588", "#") };
|
|
8675
8750
|
var je = `${(0, import_node_util2.styleText)("gray", d)} `;
|
|
8676
8751
|
|
|
@@ -8887,14 +8962,14 @@ async function resolveIdentity(opts = {}) {
|
|
|
8887
8962
|
if (isNonEmpty(ghTokenEnv)) {
|
|
8888
8963
|
return { token: ghTokenEnv.trim(), source: "env_GH_TOKEN" };
|
|
8889
8964
|
}
|
|
8890
|
-
const ghCli = await execGh();
|
|
8891
|
-
if (isNonEmpty(ghCli)) {
|
|
8892
|
-
return { token: ghCli.trim(), source: "gh_cli" };
|
|
8893
|
-
}
|
|
8894
8965
|
const stored = await loadStored();
|
|
8895
8966
|
if (isNonEmpty(stored)) {
|
|
8896
8967
|
return { token: stored.trim(), source: "device_flow" };
|
|
8897
8968
|
}
|
|
8969
|
+
const ghCli = await execGh();
|
|
8970
|
+
if (isNonEmpty(ghCli)) {
|
|
8971
|
+
return { token: ghCli.trim(), source: "gh_cli" };
|
|
8972
|
+
}
|
|
8898
8973
|
return null;
|
|
8899
8974
|
}
|
|
8900
8975
|
|
|
@@ -22862,6 +22937,14 @@ function suggest(target, candidates, threshold = 2) {
|
|
|
22862
22937
|
}
|
|
22863
22938
|
|
|
22864
22939
|
// src/lib/proxy-client.ts
|
|
22940
|
+
var DEFAULT_FETCH_TIMEOUT_MS = 3e4;
|
|
22941
|
+
function parseFetchTimeoutMs(env) {
|
|
22942
|
+
const raw = env["UNIVERSE_FETCH_TIMEOUT_MS"];
|
|
22943
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
22944
|
+
const n = Number(raw);
|
|
22945
|
+
if (!Number.isFinite(n) || n < 0) return void 0;
|
|
22946
|
+
return Math.floor(n);
|
|
22947
|
+
}
|
|
22865
22948
|
var ProxyError = class extends CliError {
|
|
22866
22949
|
exitCode;
|
|
22867
22950
|
status;
|
|
@@ -22939,6 +23022,24 @@ function stripTrailingSlash(url2) {
|
|
|
22939
23022
|
function createProxyClient(cfg) {
|
|
22940
23023
|
const base = stripTrailingSlash(cfg.baseUrl);
|
|
22941
23024
|
const fetchImpl = cfg.fetch ?? globalThis.fetch.bind(globalThis);
|
|
23025
|
+
const timeoutMs = cfg.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
|
|
23026
|
+
function withTimeoutSignal(init) {
|
|
23027
|
+
if (timeoutMs <= 0) return init;
|
|
23028
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
23029
|
+
const merged = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
23030
|
+
return { ...init, signal: merged };
|
|
23031
|
+
}
|
|
23032
|
+
function translateFetchError(err) {
|
|
23033
|
+
if (err instanceof DOMException && (err.name === "TimeoutError" || err.name === "AbortError")) {
|
|
23034
|
+
throw new ProxyError(
|
|
23035
|
+
0,
|
|
23036
|
+
"timeout",
|
|
23037
|
+
`proxy timed out after ${timeoutMs}ms`
|
|
23038
|
+
);
|
|
23039
|
+
}
|
|
23040
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23041
|
+
throw new ProxyError(0, "network_error", `proxy unreachable: ${message}`);
|
|
23042
|
+
}
|
|
22942
23043
|
async function userBearer() {
|
|
22943
23044
|
const tok = await cfg.getAuthToken();
|
|
22944
23045
|
return `Bearer ${tok}`;
|
|
@@ -22946,10 +23047,9 @@ function createProxyClient(cfg) {
|
|
|
22946
23047
|
async function call(url2, init) {
|
|
22947
23048
|
let response;
|
|
22948
23049
|
try {
|
|
22949
|
-
response = await fetchImpl(url2, init);
|
|
23050
|
+
response = await fetchImpl(url2, withTimeoutSignal(init));
|
|
22950
23051
|
} catch (err) {
|
|
22951
|
-
|
|
22952
|
-
throw new ProxyError(0, "network_error", `proxy unreachable: ${message}`);
|
|
23052
|
+
translateFetchError(err);
|
|
22953
23053
|
}
|
|
22954
23054
|
if (!response.ok) {
|
|
22955
23055
|
const env = await readErrorEnvelope(response);
|
|
@@ -23021,20 +23121,18 @@ function createProxyClient(cfg) {
|
|
|
23021
23121
|
const url2 = `${base}/api/site/${encodeURIComponent(req.site)}/alias/${encodeURIComponent(req.mode)}`;
|
|
23022
23122
|
let response;
|
|
23023
23123
|
try {
|
|
23024
|
-
response = await fetchImpl(
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23032
|
-
|
|
23033
|
-
throw new ProxyError(
|
|
23034
|
-
0,
|
|
23035
|
-
"network_error",
|
|
23036
|
-
`proxy unreachable: ${message}`
|
|
23124
|
+
response = await fetchImpl(
|
|
23125
|
+
url2,
|
|
23126
|
+
withTimeoutSignal({
|
|
23127
|
+
method: "GET",
|
|
23128
|
+
headers: {
|
|
23129
|
+
Authorization: await userBearer(),
|
|
23130
|
+
Accept: "application/json"
|
|
23131
|
+
}
|
|
23132
|
+
})
|
|
23037
23133
|
);
|
|
23134
|
+
} catch (err) {
|
|
23135
|
+
translateFetchError(err);
|
|
23038
23136
|
}
|
|
23039
23137
|
if (response.status === 404) return null;
|
|
23040
23138
|
if (!response.ok) {
|
|
@@ -23278,6 +23376,103 @@ function buildErrorEnvelope(command, code, message, issues) {
|
|
|
23278
23376
|
};
|
|
23279
23377
|
}
|
|
23280
23378
|
|
|
23379
|
+
// src/output/redact.ts
|
|
23380
|
+
var AWS_KEY_PREFIX_PATTERN = /(?:AKIA|ASIA|AROA|AIDA|ACCA|ANPA|ABIA|AGPA)[A-Z0-9]{12,}/g;
|
|
23381
|
+
var URL_CREDS_PATTERN = /https?:\/\/[^@\s]+@/g;
|
|
23382
|
+
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;
|
|
23383
|
+
var HEX_CREDENTIAL_CONTEXT_PATTERN = /(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key)\s*[=:]\s*([a-f0-9]{32,})/gi;
|
|
23384
|
+
var JSON_CREDENTIAL_PATTERN = /"(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key|accessKeyId|secretAccessKey)"\s*:\s*"[^"]+"/gi;
|
|
23385
|
+
var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
|
|
23386
|
+
var CREDENTIAL_KEY_PATTERN = /(?:secret|password|token|key|credential|auth)/i;
|
|
23387
|
+
var EXACT_CREDENTIAL_KEYS = /* @__PURE__ */ new Set([
|
|
23388
|
+
"accesskeyid",
|
|
23389
|
+
"secretaccesskey",
|
|
23390
|
+
"access_key_id",
|
|
23391
|
+
"secret_access_key"
|
|
23392
|
+
]);
|
|
23393
|
+
var STANDALONE_LONG_SECRET = /^[A-Za-z0-9/+=]{21,}$/;
|
|
23394
|
+
function maskAwsKey(match) {
|
|
23395
|
+
return match.slice(0, 4) + "****" + match.slice(-4);
|
|
23396
|
+
}
|
|
23397
|
+
function maskUrlCreds(match) {
|
|
23398
|
+
const atIndex = match.lastIndexOf("@");
|
|
23399
|
+
const protocolEnd = match.indexOf("://") + 3;
|
|
23400
|
+
return match.slice(0, protocolEnd) + "****:****@" + match.slice(atIndex + 1);
|
|
23401
|
+
}
|
|
23402
|
+
function redact(value) {
|
|
23403
|
+
let result = value;
|
|
23404
|
+
result = result.replace(URL_CREDS_PATTERN, maskUrlCreds);
|
|
23405
|
+
result = result.replace(AWS_KEY_PREFIX_PATTERN, maskAwsKey);
|
|
23406
|
+
result = result.replace(BEARER_PATTERN, "Bearer ****");
|
|
23407
|
+
result = result.replace(JSON_CREDENTIAL_PATTERN, (match) => {
|
|
23408
|
+
const colonIndex = match.indexOf(":");
|
|
23409
|
+
return match.slice(0, colonIndex + 1) + '"****"';
|
|
23410
|
+
});
|
|
23411
|
+
result = result.replace(
|
|
23412
|
+
CREDENTIAL_CONTEXT_PATTERN,
|
|
23413
|
+
(_match, _secret, _offset, _full) => {
|
|
23414
|
+
const eqIndex = _match.indexOf("=");
|
|
23415
|
+
const colonIndex = _match.indexOf(":");
|
|
23416
|
+
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
23417
|
+
const prefix = _match.slice(0, sepIndex + 1);
|
|
23418
|
+
return prefix + "****";
|
|
23419
|
+
}
|
|
23420
|
+
);
|
|
23421
|
+
result = result.replace(HEX_CREDENTIAL_CONTEXT_PATTERN, (_match, _secret) => {
|
|
23422
|
+
const eqIndex = _match.indexOf("=");
|
|
23423
|
+
const colonIndex = _match.indexOf(":");
|
|
23424
|
+
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
23425
|
+
const prefix = _match.slice(0, sepIndex + 1);
|
|
23426
|
+
return prefix + "****";
|
|
23427
|
+
});
|
|
23428
|
+
return result;
|
|
23429
|
+
}
|
|
23430
|
+
function redactValue(value, keyName) {
|
|
23431
|
+
if (typeof value === "string") {
|
|
23432
|
+
if (keyName && EXACT_CREDENTIAL_KEYS.has(keyName.toLowerCase())) {
|
|
23433
|
+
return "****";
|
|
23434
|
+
}
|
|
23435
|
+
const redacted = redact(value);
|
|
23436
|
+
if (redacted === value && keyName && CREDENTIAL_KEY_PATTERN.test(keyName) && STANDALONE_LONG_SECRET.test(value)) {
|
|
23437
|
+
return "****";
|
|
23438
|
+
}
|
|
23439
|
+
return redacted;
|
|
23440
|
+
}
|
|
23441
|
+
if (Array.isArray(value)) {
|
|
23442
|
+
return value.map((v) => redactValue(v, keyName));
|
|
23443
|
+
}
|
|
23444
|
+
if (value !== null && typeof value === "object") {
|
|
23445
|
+
return redactObject(value);
|
|
23446
|
+
}
|
|
23447
|
+
return value;
|
|
23448
|
+
}
|
|
23449
|
+
function redactObject(obj) {
|
|
23450
|
+
const result = {};
|
|
23451
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
23452
|
+
result[key] = redactValue(value, key);
|
|
23453
|
+
}
|
|
23454
|
+
return result;
|
|
23455
|
+
}
|
|
23456
|
+
|
|
23457
|
+
// src/output/format.ts
|
|
23458
|
+
function outputError(ctx, code, message, optsOrIssues) {
|
|
23459
|
+
const opts = Array.isArray(optsOrIssues) ? { issues: optsOrIssues } : optsOrIssues ?? {};
|
|
23460
|
+
const redactedMessage = redact(message);
|
|
23461
|
+
const redactedIssues = opts.issues?.map(redact);
|
|
23462
|
+
if (ctx.json) {
|
|
23463
|
+
const envelope = buildErrorEnvelope(
|
|
23464
|
+
ctx.command,
|
|
23465
|
+
code,
|
|
23466
|
+
redactedMessage,
|
|
23467
|
+
redactedIssues
|
|
23468
|
+
);
|
|
23469
|
+
const payload = opts.extras ? { ...envelope, ...redactObject(opts.extras) } : envelope;
|
|
23470
|
+
process.stdout.write(JSON.stringify(payload) + "\n");
|
|
23471
|
+
} else {
|
|
23472
|
+
(opts.logError ?? ((m) => O2.error(m)))(redactedMessage);
|
|
23473
|
+
}
|
|
23474
|
+
}
|
|
23475
|
+
|
|
23281
23476
|
// src/commands/deploy.ts
|
|
23282
23477
|
var defaultReadPlatformYaml = async (cwd) => {
|
|
23283
23478
|
return (0, import_promises4.readFile)((0, import_node_path5.resolve)(cwd, "platform.yaml"), "utf-8");
|
|
@@ -23371,6 +23566,7 @@ async function deploy(options, deps = {}) {
|
|
|
23371
23566
|
const build = deps.runBuild ?? runBuild;
|
|
23372
23567
|
const walk = deps.walkFiles ?? walkFiles;
|
|
23373
23568
|
const upload = deps.uploadFiles ?? uploadFiles;
|
|
23569
|
+
const mkSpinner = deps.createSpinner ?? (() => fe());
|
|
23374
23570
|
const success2 = deps.logSuccess ?? ((s) => O2.success(s));
|
|
23375
23571
|
const info = deps.logInfo ?? ((s) => O2.info(s));
|
|
23376
23572
|
const warn = deps.logWarn ?? ((s) => O2.warn(s));
|
|
@@ -23387,7 +23583,8 @@ async function deploy(options, deps = {}) {
|
|
|
23387
23583
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
23388
23584
|
const client = mkClient({
|
|
23389
23585
|
baseUrl,
|
|
23390
|
-
getAuthToken: () => identity.token
|
|
23586
|
+
getAuthToken: () => identity.token,
|
|
23587
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
23391
23588
|
});
|
|
23392
23589
|
let me2;
|
|
23393
23590
|
try {
|
|
@@ -23438,17 +23635,22 @@ async function deploy(options, deps = {}) {
|
|
|
23438
23635
|
} catch (err) {
|
|
23439
23636
|
rethrowProxy("deploy init failed", err);
|
|
23440
23637
|
}
|
|
23638
|
+
const spin = options.json ? null : mkSpinner();
|
|
23639
|
+
spin?.start(`Uploading 0/${filtered.length} files`);
|
|
23441
23640
|
const uploadResult = await upload({
|
|
23442
23641
|
client,
|
|
23443
23642
|
deployId: initResult.deployId,
|
|
23444
23643
|
jwt: initResult.jwt,
|
|
23445
|
-
files: filtered
|
|
23644
|
+
files: filtered,
|
|
23645
|
+
onProgress: spin ? (p2) => spin.message(`Uploading ${p2.uploaded}/${p2.total} \u2014 ${p2.current}`) : void 0
|
|
23446
23646
|
});
|
|
23447
23647
|
if (uploadResult.errors.length > 0) {
|
|
23648
|
+
spin?.error(`Upload failed: ${uploadResult.errors.length} file(s)`);
|
|
23448
23649
|
const message = `Upload partially failed: ${uploadResult.errors.length} file(s) failed:
|
|
23449
23650
|
- ${uploadResult.errors.join("\n - ")}`;
|
|
23450
23651
|
throw new PartialUploadError(message);
|
|
23451
23652
|
}
|
|
23653
|
+
spin?.stop(`Uploaded ${uploadResult.fileCount} files`);
|
|
23452
23654
|
const mode = options.promote ? "production" : "preview";
|
|
23453
23655
|
let finalizeResult;
|
|
23454
23656
|
try {
|
|
@@ -23461,6 +23663,25 @@ async function deploy(options, deps = {}) {
|
|
|
23461
23663
|
} catch (err) {
|
|
23462
23664
|
rethrowProxy("deploy finalize failed", err);
|
|
23463
23665
|
}
|
|
23666
|
+
if (options.promote && !options.json) {
|
|
23667
|
+
try {
|
|
23668
|
+
const preview = await client.getAlias({
|
|
23669
|
+
site: config2.site,
|
|
23670
|
+
mode: "preview"
|
|
23671
|
+
});
|
|
23672
|
+
if (preview && preview.deployId !== finalizeResult.deployId) {
|
|
23673
|
+
warn(
|
|
23674
|
+
`Preview alias still points to ${preview.deployId}; it will not auto-update. Run \`universe static deploy\` (without --promote) to refresh preview.`
|
|
23675
|
+
);
|
|
23676
|
+
}
|
|
23677
|
+
} catch (err) {
|
|
23678
|
+
if (err instanceof ProxyError && (err.status === 401 || err.status === 403)) {
|
|
23679
|
+
warn(
|
|
23680
|
+
`Preview alias probe got ${err.status} (${err.code}) \u2014 token may need rotation: ${err.message}`
|
|
23681
|
+
);
|
|
23682
|
+
}
|
|
23683
|
+
}
|
|
23684
|
+
}
|
|
23464
23685
|
if (options.json) {
|
|
23465
23686
|
emitJson(
|
|
23466
23687
|
buildEnvelope("deploy", true, {
|
|
@@ -23507,11 +23728,9 @@ async function deploy(options, deps = {}) {
|
|
|
23507
23728
|
code = EXIT_USAGE;
|
|
23508
23729
|
message = String(err);
|
|
23509
23730
|
}
|
|
23510
|
-
|
|
23511
|
-
|
|
23512
|
-
}
|
|
23513
|
-
error48(message);
|
|
23514
|
-
}
|
|
23731
|
+
outputError({ json: options.json, command: "deploy" }, code, message, {
|
|
23732
|
+
logError: error48
|
|
23733
|
+
});
|
|
23515
23734
|
exit(code);
|
|
23516
23735
|
}
|
|
23517
23736
|
}
|
|
@@ -23591,6 +23810,19 @@ async function runDeviceFlow(opts) {
|
|
|
23591
23810
|
|
|
23592
23811
|
// src/commands/login.ts
|
|
23593
23812
|
var DEFAULT_SCOPE = "read:org user:email";
|
|
23813
|
+
var DEFAULT_PROXY_URL2 = "https://uploads.freecode.camp";
|
|
23814
|
+
var NO_SITES_WARNING = [
|
|
23815
|
+
"Logged in, but the proxy reports 0 authorized sites for your account.",
|
|
23816
|
+
"This usually means the Universe CLI GitHub App is not installed on the org",
|
|
23817
|
+
"that owns the registry-authz team (production: `freeCodeCamp-Universe`), or",
|
|
23818
|
+
"your account is not on a team granted access to any site.",
|
|
23819
|
+
"",
|
|
23820
|
+
"Next steps:",
|
|
23821
|
+
" 1. Run `universe whoami` to confirm the identity that resolved.",
|
|
23822
|
+
" 2. Ask an org owner to install the Universe CLI GitHub App on the org.",
|
|
23823
|
+
" 3. Confirm your team membership at",
|
|
23824
|
+
" https://github.com/orgs/freeCodeCamp-Universe/teams."
|
|
23825
|
+
].join("\n");
|
|
23594
23826
|
function emitJson2(envelope) {
|
|
23595
23827
|
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
23596
23828
|
}
|
|
@@ -23652,25 +23884,56 @@ async function login(options, deps = {}) {
|
|
|
23652
23884
|
});
|
|
23653
23885
|
} catch (err) {
|
|
23654
23886
|
const message = err instanceof Error ? err.message : String(err);
|
|
23655
|
-
|
|
23656
|
-
|
|
23657
|
-
|
|
23658
|
-
|
|
23659
|
-
|
|
23660
|
-
|
|
23661
|
-
error: { code: EXIT_CREDENTIALS, message }
|
|
23662
|
-
});
|
|
23663
|
-
} else {
|
|
23664
|
-
error48(message);
|
|
23665
|
-
}
|
|
23887
|
+
outputError(
|
|
23888
|
+
{ json: options.json, command: "login" },
|
|
23889
|
+
EXIT_CREDENTIALS,
|
|
23890
|
+
message,
|
|
23891
|
+
{ logError: error48 }
|
|
23892
|
+
);
|
|
23666
23893
|
exit(EXIT_CREDENTIALS);
|
|
23667
23894
|
return;
|
|
23668
23895
|
}
|
|
23669
23896
|
await save(token);
|
|
23897
|
+
const selfCheck = await postLoginSelfCheck(token, env, deps);
|
|
23670
23898
|
if (options.json) {
|
|
23671
|
-
emitJson2(
|
|
23899
|
+
emitJson2(
|
|
23900
|
+
buildEnvelope("login", true, {
|
|
23901
|
+
stored: true,
|
|
23902
|
+
...selfCheck.checked ? {
|
|
23903
|
+
authorizedSitesCount: selfCheck.authorizedSitesCount,
|
|
23904
|
+
...selfCheck.warning ? { warning: selfCheck.warning } : {}
|
|
23905
|
+
} : {}
|
|
23906
|
+
})
|
|
23907
|
+
);
|
|
23672
23908
|
} else {
|
|
23673
23909
|
success2("Logged in. Token stored at ~/.config/universe-cli/token.");
|
|
23910
|
+
if (selfCheck.checked && selfCheck.warning) {
|
|
23911
|
+
const warn = deps.logWarn ?? ((s) => O2.warn(s));
|
|
23912
|
+
warn(selfCheck.warning);
|
|
23913
|
+
}
|
|
23914
|
+
}
|
|
23915
|
+
}
|
|
23916
|
+
async function postLoginSelfCheck(token, env, deps) {
|
|
23917
|
+
const mkClient = deps.createProxyClient ?? createProxyClient;
|
|
23918
|
+
try {
|
|
23919
|
+
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL2;
|
|
23920
|
+
const client = mkClient({
|
|
23921
|
+
baseUrl,
|
|
23922
|
+
getAuthToken: () => token,
|
|
23923
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
23924
|
+
});
|
|
23925
|
+
const result = await client.whoami();
|
|
23926
|
+
const count = result.authorizedSites.length;
|
|
23927
|
+
if (count === 0) {
|
|
23928
|
+
return {
|
|
23929
|
+
checked: true,
|
|
23930
|
+
authorizedSitesCount: 0,
|
|
23931
|
+
warning: NO_SITES_WARNING
|
|
23932
|
+
};
|
|
23933
|
+
}
|
|
23934
|
+
return { checked: true, authorizedSitesCount: count };
|
|
23935
|
+
} catch {
|
|
23936
|
+
return { checked: false, authorizedSitesCount: 0 };
|
|
23674
23937
|
}
|
|
23675
23938
|
}
|
|
23676
23939
|
|
|
@@ -23771,7 +24034,8 @@ async function ls(options, deps = {}) {
|
|
|
23771
24034
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
23772
24035
|
const client = mkClient({
|
|
23773
24036
|
baseUrl,
|
|
23774
|
-
getAuthToken: () => identity.token
|
|
24037
|
+
getAuthToken: () => identity.token,
|
|
24038
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
23775
24039
|
});
|
|
23776
24040
|
const raw = await client.siteDeploys({ site });
|
|
23777
24041
|
const sorted = [...raw].sort(
|
|
@@ -23795,11 +24059,9 @@ async function ls(options, deps = {}) {
|
|
|
23795
24059
|
success2(formatTable(deploys));
|
|
23796
24060
|
} catch (err) {
|
|
23797
24061
|
const { code, message } = wrapProxyError("ls", err);
|
|
23798
|
-
|
|
23799
|
-
|
|
23800
|
-
}
|
|
23801
|
-
error48(message);
|
|
23802
|
-
}
|
|
24062
|
+
outputError({ json: options.json, command: "ls" }, code, message, {
|
|
24063
|
+
logError: error48
|
|
24064
|
+
});
|
|
23803
24065
|
exit(code);
|
|
23804
24066
|
}
|
|
23805
24067
|
}
|
|
@@ -23855,7 +24117,8 @@ async function promote(options, deps = {}) {
|
|
|
23855
24117
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
23856
24118
|
const client = mkClient({
|
|
23857
24119
|
baseUrl,
|
|
23858
|
-
getAuthToken: () => identity.token
|
|
24120
|
+
getAuthToken: () => identity.token,
|
|
24121
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
23859
24122
|
});
|
|
23860
24123
|
let result;
|
|
23861
24124
|
if (options.from) {
|
|
@@ -23953,16 +24216,11 @@ async function promote(options, deps = {}) {
|
|
|
23953
24216
|
}
|
|
23954
24217
|
} catch (err) {
|
|
23955
24218
|
const { code, message } = wrapProxyError("promote", err);
|
|
23956
|
-
|
|
23957
|
-
|
|
23958
|
-
|
|
23959
|
-
|
|
23960
|
-
|
|
23961
|
-
emitJson5(envelope);
|
|
23962
|
-
}
|
|
23963
|
-
} else {
|
|
23964
|
-
error48(message);
|
|
23965
|
-
}
|
|
24219
|
+
const extras = err instanceof AliasDriftError ? { current: err.current } : void 0;
|
|
24220
|
+
outputError({ json: options.json, command: "promote" }, code, message, {
|
|
24221
|
+
logError: error48,
|
|
24222
|
+
extras
|
|
24223
|
+
});
|
|
23966
24224
|
exit(code);
|
|
23967
24225
|
}
|
|
23968
24226
|
}
|
|
@@ -24023,7 +24281,8 @@ async function rollback(options, deps = {}) {
|
|
|
24023
24281
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
24024
24282
|
const client = mkClient({
|
|
24025
24283
|
baseUrl,
|
|
24026
|
-
getAuthToken: () => identity.token
|
|
24284
|
+
getAuthToken: () => identity.token,
|
|
24285
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
24027
24286
|
});
|
|
24028
24287
|
const to = options.to.trim();
|
|
24029
24288
|
const prod = await client.getAlias({
|
|
@@ -24076,22 +24335,17 @@ async function rollback(options, deps = {}) {
|
|
|
24076
24335
|
}
|
|
24077
24336
|
} catch (err) {
|
|
24078
24337
|
const { code, message } = wrapProxyError("rollback", err);
|
|
24079
|
-
|
|
24080
|
-
|
|
24081
|
-
|
|
24082
|
-
|
|
24083
|
-
|
|
24084
|
-
emitJson6(envelope);
|
|
24085
|
-
}
|
|
24086
|
-
} else {
|
|
24087
|
-
error48(message);
|
|
24088
|
-
}
|
|
24338
|
+
const extras = err instanceof AliasDriftError ? { current: err.current } : void 0;
|
|
24339
|
+
outputError({ json: options.json, command: "rollback" }, code, message, {
|
|
24340
|
+
logError: error48,
|
|
24341
|
+
extras
|
|
24342
|
+
});
|
|
24089
24343
|
exit(code);
|
|
24090
24344
|
}
|
|
24091
24345
|
}
|
|
24092
24346
|
|
|
24093
24347
|
// src/commands/whoami.ts
|
|
24094
|
-
var
|
|
24348
|
+
var DEFAULT_PROXY_URL3 = "https://uploads.freecode.camp";
|
|
24095
24349
|
function emitJson7(envelope) {
|
|
24096
24350
|
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
24097
24351
|
}
|
|
@@ -24105,18 +24359,20 @@ async function whoami(options, deps = {}) {
|
|
|
24105
24359
|
const identity = await resolve6({ env });
|
|
24106
24360
|
if (!identity) {
|
|
24107
24361
|
const msg = "No GitHub identity available. Run `universe login`, set $GITHUB_TOKEN, or install the gh CLI.";
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
|
|
24111
|
-
|
|
24112
|
-
|
|
24362
|
+
outputError(
|
|
24363
|
+
{ json: options.json, command: "whoami" },
|
|
24364
|
+
EXIT_CREDENTIALS,
|
|
24365
|
+
msg,
|
|
24366
|
+
{ logError: error48 }
|
|
24367
|
+
);
|
|
24113
24368
|
exit(EXIT_CREDENTIALS);
|
|
24114
24369
|
return;
|
|
24115
24370
|
}
|
|
24116
|
-
const baseUrl = env["UNIVERSE_PROXY_URL"] ??
|
|
24371
|
+
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL3;
|
|
24117
24372
|
const client = mkClient({
|
|
24118
24373
|
baseUrl,
|
|
24119
|
-
getAuthToken: () => identity.token
|
|
24374
|
+
getAuthToken: () => identity.token,
|
|
24375
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
24120
24376
|
});
|
|
24121
24377
|
try {
|
|
24122
24378
|
const result = await client.whoami();
|
|
@@ -24142,11 +24398,9 @@ async function whoami(options, deps = {}) {
|
|
|
24142
24398
|
} catch (err) {
|
|
24143
24399
|
const exitCode = err instanceof CliError ? err.exitCode : EXIT_CREDENTIALS;
|
|
24144
24400
|
const message = err instanceof ProxyError ? `whoami failed (${err.code}): ${err.message}` : err instanceof Error ? err.message : String(err);
|
|
24145
|
-
|
|
24146
|
-
|
|
24147
|
-
}
|
|
24148
|
-
error48(message);
|
|
24149
|
-
}
|
|
24401
|
+
outputError({ json: options.json, command: "whoami" }, exitCode, message, {
|
|
24402
|
+
logError: error48
|
|
24403
|
+
});
|
|
24150
24404
|
exit(exitCode);
|
|
24151
24405
|
}
|
|
24152
24406
|
}
|
|
@@ -24173,7 +24427,8 @@ async function setupClient(deps) {
|
|
|
24173
24427
|
const baseUrl = env["UNIVERSE_PROXY_URL"] ?? DEFAULT_PROXY_URL;
|
|
24174
24428
|
const client = mkClient({
|
|
24175
24429
|
baseUrl,
|
|
24176
|
-
getAuthToken: () => identity.token
|
|
24430
|
+
getAuthToken: () => identity.token,
|
|
24431
|
+
timeoutMs: parseFetchTimeoutMs(env)
|
|
24177
24432
|
});
|
|
24178
24433
|
return { client, identitySource: identity.source };
|
|
24179
24434
|
}
|
|
@@ -24200,7 +24455,7 @@ async function ls2(options, deps = {}) {
|
|
|
24200
24455
|
const error48 = deps.logError ?? ((s) => O2.error(s));
|
|
24201
24456
|
const exit = deps.exit ?? exitWithCode;
|
|
24202
24457
|
try {
|
|
24203
|
-
const { client } = await setupClient(deps);
|
|
24458
|
+
const { client, identitySource } = await setupClient(deps);
|
|
24204
24459
|
let rows = await client.listSites();
|
|
24205
24460
|
let scope = "all";
|
|
24206
24461
|
if (options.mine) {
|
|
@@ -24214,7 +24469,8 @@ async function ls2(options, deps = {}) {
|
|
|
24214
24469
|
buildEnvelope(command, true, {
|
|
24215
24470
|
count: rows.length,
|
|
24216
24471
|
scope,
|
|
24217
|
-
sites: rows
|
|
24472
|
+
sites: rows,
|
|
24473
|
+
identitySource
|
|
24218
24474
|
})
|
|
24219
24475
|
);
|
|
24220
24476
|
} else {
|
|
@@ -24222,11 +24478,9 @@ async function ls2(options, deps = {}) {
|
|
|
24222
24478
|
}
|
|
24223
24479
|
} catch (err) {
|
|
24224
24480
|
const { code, message } = wrapProxyError(command, err);
|
|
24225
|
-
|
|
24226
|
-
|
|
24227
|
-
}
|
|
24228
|
-
error48(message);
|
|
24229
|
-
}
|
|
24481
|
+
outputError({ json: options.json, command }, code, message, {
|
|
24482
|
+
logError: error48
|
|
24483
|
+
});
|
|
24230
24484
|
exit(code);
|
|
24231
24485
|
}
|
|
24232
24486
|
}
|
|
@@ -24242,7 +24496,7 @@ async function register(options, deps = {}) {
|
|
|
24242
24496
|
throw new UsageError("slug is required (positional argument)");
|
|
24243
24497
|
}
|
|
24244
24498
|
const teams = parseTeamsFlag(options.team);
|
|
24245
|
-
const { client } = await setupClient(deps);
|
|
24499
|
+
const { client, identitySource } = await setupClient(deps);
|
|
24246
24500
|
const row = await client.registerSite({
|
|
24247
24501
|
slug: options.slug,
|
|
24248
24502
|
teams: teams.length > 0 ? teams : void 0
|
|
@@ -24253,7 +24507,8 @@ async function register(options, deps = {}) {
|
|
|
24253
24507
|
slug: row.slug,
|
|
24254
24508
|
teams: row.teams,
|
|
24255
24509
|
createdAt: row.createdAt,
|
|
24256
|
-
createdBy: row.createdBy
|
|
24510
|
+
createdBy: row.createdBy,
|
|
24511
|
+
identitySource
|
|
24257
24512
|
})
|
|
24258
24513
|
);
|
|
24259
24514
|
} else {
|
|
@@ -24270,11 +24525,9 @@ async function register(options, deps = {}) {
|
|
|
24270
24525
|
}
|
|
24271
24526
|
} catch (err) {
|
|
24272
24527
|
const { code, message } = wrapProxyError(command, err);
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
}
|
|
24276
|
-
error48(message);
|
|
24277
|
-
}
|
|
24528
|
+
outputError({ json: options.json, command }, code, message, {
|
|
24529
|
+
logError: error48
|
|
24530
|
+
});
|
|
24278
24531
|
exit(code);
|
|
24279
24532
|
}
|
|
24280
24533
|
}
|
|
@@ -24289,13 +24542,14 @@ async function rm2(options, deps = {}) {
|
|
|
24289
24542
|
if (!options.slug || options.slug.trim().length === 0) {
|
|
24290
24543
|
throw new UsageError("slug is required (positional argument)");
|
|
24291
24544
|
}
|
|
24292
|
-
const { client } = await setupClient(deps);
|
|
24545
|
+
const { client, identitySource } = await setupClient(deps);
|
|
24293
24546
|
await client.deleteSite({ slug: options.slug });
|
|
24294
24547
|
if (options.json) {
|
|
24295
24548
|
emitJson8(
|
|
24296
24549
|
buildEnvelope(command, true, {
|
|
24297
24550
|
slug: options.slug,
|
|
24298
|
-
deleted: true
|
|
24551
|
+
deleted: true,
|
|
24552
|
+
identitySource
|
|
24299
24553
|
})
|
|
24300
24554
|
);
|
|
24301
24555
|
} else {
|
|
@@ -24310,11 +24564,9 @@ async function rm2(options, deps = {}) {
|
|
|
24310
24564
|
}
|
|
24311
24565
|
} catch (err) {
|
|
24312
24566
|
const { code, message } = wrapProxyError(command, err);
|
|
24313
|
-
|
|
24314
|
-
|
|
24315
|
-
}
|
|
24316
|
-
error48(message);
|
|
24317
|
-
}
|
|
24567
|
+
outputError({ json: options.json, command }, code, message, {
|
|
24568
|
+
logError: error48
|
|
24569
|
+
});
|
|
24318
24570
|
exit(code);
|
|
24319
24571
|
}
|
|
24320
24572
|
}
|
|
@@ -24335,7 +24587,7 @@ async function update(options, deps = {}) {
|
|
|
24335
24587
|
"--team is required with at least one slug; use `sites rm` to remove a site"
|
|
24336
24588
|
);
|
|
24337
24589
|
}
|
|
24338
|
-
const { client } = await setupClient(deps);
|
|
24590
|
+
const { client, identitySource } = await setupClient(deps);
|
|
24339
24591
|
const row = await client.updateSite({
|
|
24340
24592
|
slug: options.slug,
|
|
24341
24593
|
teams
|
|
@@ -24345,7 +24597,8 @@ async function update(options, deps = {}) {
|
|
|
24345
24597
|
buildEnvelope(command, true, {
|
|
24346
24598
|
slug: row.slug,
|
|
24347
24599
|
teams: row.teams,
|
|
24348
|
-
updatedAt: row.updatedAt
|
|
24600
|
+
updatedAt: row.updatedAt,
|
|
24601
|
+
identitySource
|
|
24349
24602
|
})
|
|
24350
24603
|
);
|
|
24351
24604
|
} else {
|
|
@@ -24361,78 +24614,15 @@ async function update(options, deps = {}) {
|
|
|
24361
24614
|
}
|
|
24362
24615
|
} catch (err) {
|
|
24363
24616
|
const { code, message } = wrapProxyError(command, err);
|
|
24364
|
-
|
|
24365
|
-
|
|
24366
|
-
}
|
|
24367
|
-
error48(message);
|
|
24368
|
-
}
|
|
24617
|
+
outputError({ json: options.json, command }, code, message, {
|
|
24618
|
+
logError: error48
|
|
24619
|
+
});
|
|
24369
24620
|
exit(code);
|
|
24370
24621
|
}
|
|
24371
24622
|
}
|
|
24372
24623
|
|
|
24373
|
-
// src/output/redact.ts
|
|
24374
|
-
var AWS_KEY_PREFIX_PATTERN = /(?:AKIA|ASIA|AROA|AIDA|ACCA|ANPA|ABIA|AGPA)[A-Z0-9]{12,}/g;
|
|
24375
|
-
var URL_CREDS_PATTERN = /https?:\/\/[^@\s]+@/g;
|
|
24376
|
-
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;
|
|
24377
|
-
var HEX_CREDENTIAL_CONTEXT_PATTERN = /(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key)\s*[=:]\s*([a-f0-9]{32,})/gi;
|
|
24378
|
-
var JSON_CREDENTIAL_PATTERN = /"(?:secret|password|token|key|credential|auth|access_key_id|secret_access_key|accessKeyId|secretAccessKey)"\s*:\s*"[^"]+"/gi;
|
|
24379
|
-
var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
|
|
24380
|
-
function maskAwsKey(match) {
|
|
24381
|
-
return match.slice(0, 4) + "****" + match.slice(-4);
|
|
24382
|
-
}
|
|
24383
|
-
function maskUrlCreds(match) {
|
|
24384
|
-
const atIndex = match.lastIndexOf("@");
|
|
24385
|
-
const protocolEnd = match.indexOf("://") + 3;
|
|
24386
|
-
return match.slice(0, protocolEnd) + "****:****@" + match.slice(atIndex + 1);
|
|
24387
|
-
}
|
|
24388
|
-
function redact(value) {
|
|
24389
|
-
let result = value;
|
|
24390
|
-
result = result.replace(URL_CREDS_PATTERN, maskUrlCreds);
|
|
24391
|
-
result = result.replace(AWS_KEY_PREFIX_PATTERN, maskAwsKey);
|
|
24392
|
-
result = result.replace(BEARER_PATTERN, "Bearer ****");
|
|
24393
|
-
result = result.replace(JSON_CREDENTIAL_PATTERN, (match) => {
|
|
24394
|
-
const colonIndex = match.indexOf(":");
|
|
24395
|
-
return match.slice(0, colonIndex + 1) + '"****"';
|
|
24396
|
-
});
|
|
24397
|
-
result = result.replace(
|
|
24398
|
-
CREDENTIAL_CONTEXT_PATTERN,
|
|
24399
|
-
(_match, _secret, _offset, _full) => {
|
|
24400
|
-
const eqIndex = _match.indexOf("=");
|
|
24401
|
-
const colonIndex = _match.indexOf(":");
|
|
24402
|
-
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
24403
|
-
const prefix = _match.slice(0, sepIndex + 1);
|
|
24404
|
-
return prefix + "****";
|
|
24405
|
-
}
|
|
24406
|
-
);
|
|
24407
|
-
result = result.replace(HEX_CREDENTIAL_CONTEXT_PATTERN, (_match, _secret) => {
|
|
24408
|
-
const eqIndex = _match.indexOf("=");
|
|
24409
|
-
const colonIndex = _match.indexOf(":");
|
|
24410
|
-
const sepIndex = eqIndex >= 0 && colonIndex >= 0 ? Math.min(eqIndex, colonIndex) : eqIndex >= 0 ? eqIndex : colonIndex;
|
|
24411
|
-
const prefix = _match.slice(0, sepIndex + 1);
|
|
24412
|
-
return prefix + "****";
|
|
24413
|
-
});
|
|
24414
|
-
return result;
|
|
24415
|
-
}
|
|
24416
|
-
|
|
24417
|
-
// src/output/format.ts
|
|
24418
|
-
function outputError(ctx, code, message, issues) {
|
|
24419
|
-
const redactedMessage = redact(message);
|
|
24420
|
-
const redactedIssues = issues?.map(redact);
|
|
24421
|
-
if (ctx.json) {
|
|
24422
|
-
const envelope = buildErrorEnvelope(
|
|
24423
|
-
ctx.command,
|
|
24424
|
-
code,
|
|
24425
|
-
redactedMessage,
|
|
24426
|
-
redactedIssues
|
|
24427
|
-
);
|
|
24428
|
-
process.stdout.write(JSON.stringify(envelope) + "\n");
|
|
24429
|
-
} else {
|
|
24430
|
-
O2.error(redactedMessage);
|
|
24431
|
-
}
|
|
24432
|
-
}
|
|
24433
|
-
|
|
24434
24624
|
// src/cli.ts
|
|
24435
|
-
var version2 = true ? "0.
|
|
24625
|
+
var version2 = true ? "0.7.1" : "0.0.0";
|
|
24436
24626
|
function handleActionError(command, json2, err) {
|
|
24437
24627
|
const ctx = { json: json2, command };
|
|
24438
24628
|
const message = err instanceof Error ? err.message : "unknown error";
|