renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
145 lines (144 loc) • 5.21 kB
JavaScript
import { regEx } from "../util/regex.js";
import { ExecError } from "../util/exec/exec-error.js";
import { redactedFields, sanitize } from "../util/sanitize.js";
import { isArray, isBuffer, isDate, isEmptyObject, isError, isFunction, isNonEmptyObject, isNonEmptyStringAndNotWhitespace, isObject, isPlainObject, isString } from "@sindresorhus/is";
import { RequestError } from "got";
import { DateTime } from "luxon";
import { ZodError } from "zod/v4";
//#region lib/logger/utils.ts
const contentFields = [
"content",
"contents",
"packageLockParsed",
"yarnLockParsed"
];
function prepareZodIssues(input) {
if (!isPlainObject(input)) return null;
let err = null;
// v8 ignore else -- TODO: add test #40625
if (isArray(input._errors, isString)) if (input._errors.length === 1) err = input._errors[0];
else if (input._errors.length > 1) err = input._errors;
else err = null;
delete input._errors;
if (isEmptyObject(input)) return err;
const output = {};
const entries = Object.entries(input);
for (const [key, value] of entries.slice(0, 3)) {
const child = prepareZodIssues(value);
// v8 ignore else -- TODO: add test #40625
if (child !== null) output[key] = child;
}
if (entries.length > 3) output.___ = `... ${entries.length - 3} more`;
return output;
}
function prepareZodError(err) {
Object.defineProperty(err, "message", {
get: () => "Schema error",
/* v8 ignore start -- TODO: drop set? */
set: () => {}
});
return {
message: err.message,
stack: err.stack,
issues: prepareZodIssues(err.format())
};
}
function prepareError(err) {
if (err instanceof ZodError) return prepareZodError(err);
const response = { ...err };
if (!response.message && err.message) response.message = err.message;
if (!response.stack && err.stack) response.stack = err.stack;
if (err instanceof AggregateError) response.errors = err.errors.map((error) => prepareError(error));
if (err instanceof ExecError && isNonEmptyObject(err.options?.env)) {
const env = Object.keys(err.options.env);
response.options = {
...err.options,
env
};
}
if (err instanceof RequestError) {
const options = {
headers: structuredClone(err.options.headers),
url: err.options.url?.toString(),
hostType: err.options.context.hostType
};
response.options = options;
options.username = err.options.username;
options.password = err.options.password;
options.method = err.options.method;
options.http2 = err.options.http2;
// v8 ignore else -- TODO: add test #40625
if (err.response) response.response = {
statusCode: err.response.statusCode,
statusMessage: err.response.statusMessage,
body: err.name === "TimeoutError" ? void 0 : structuredClone(err.response.body),
headers: structuredClone(err.response.headers),
httpVersion: err.response.httpVersion,
retryCount: err.response.retryCount
};
}
return response;
}
function isNested(value) {
return isArray(value) || isObject(value);
}
function sanitizeValue(value, seen = /* @__PURE__ */ new WeakMap()) {
if (isString(value)) return sanitize(sanitizeUrls(value));
if (value instanceof String) return sanitize(sanitizeUrls(value.toString()));
if (isDate(value)) return value;
if (DateTime.isDateTime(value)) return value.toISO();
if (isFunction(value)) return "[function]";
if (isBuffer(value)) return "[content]";
if (isError(value)) return sanitizeValue(prepareError(value), seen);
if (isArray(value)) {
const length = value.length;
const arrayResult = Array(length);
seen.set(value, arrayResult);
for (let idx = 0; idx < length; idx += 1) {
const val = value[idx];
arrayResult[idx] = isNested(val) && seen.has(val) ? seen.get(val) : sanitizeValue(val, seen);
}
return arrayResult;
}
if (isObject(value)) {
const objectResult = {};
seen.set(value, objectResult);
for (const [key, val] of Object.entries(value)) {
let curValue;
if (!val) curValue = val;
else if (redactedFields.includes(key)) if (isString(val) && regEx(/^{{\s*secrets\..*}}$/).test(val)) curValue = val;
else curValue = "***********";
else if (contentFields.includes(key)) curValue = "[content]";
else if (key === "secrets") {
curValue = {};
Object.keys(val).forEach((secretKey) => {
curValue[secretKey] = "***********";
});
} else curValue = seen.has(val) ? seen.get(val) : sanitizeValue(val, seen);
const sanitizedKey = sanitizeValue(key, seen);
objectResult[sanitizedKey] = curValue;
}
return objectResult;
}
return value;
}
const urlRe = /[a-z]{3,9}:\/\/[^@/]+@[a-z0-9.-]+/gi;
const urlCredRe = /\/\/[^@]+@/g;
const dataUriCredRe = /^(data:[0-9a-z-]+\/[0-9a-z-]+;).+/i;
function sanitizeUrls(text) {
return text.replace(urlRe, (url) => {
return url.replace(urlCredRe, "//**redacted**@");
}).replace(dataUriCredRe, "$1**redacted**");
}
function getEnv(key) {
return [process.env[`RENOVATE_${key}`], process.env[key]].map((v) => v?.toLowerCase().trim()).find(isNonEmptyStringAndNotWhitespace);
}
function getMessage(p1, p2) {
return isString(p1) ? p1 : p2;
}
function toMeta(p1) {
return isObject(p1) ? p1 : {};
}
//#endregion
export { prepareError as default, getEnv, getMessage, sanitizeValue, toMeta };
//# sourceMappingURL=utils.js.map