keycloak_theme/src/bin/tools/fetchProxyOptions.ts

120 lines
3.7 KiB
TypeScript
Raw Normal View History

import * as child_process from "child_process";
import * as fs from "fs";
2024-08-07 16:07:07 +02:00
import { exclude } from "tsafe/exclude";
2024-05-24 17:26:38 +02:00
2024-10-05 21:22:00 +02:00
export type FetchOptionsLike = {
proxy: string | undefined;
noProxy: string | string[];
strictSSL: boolean;
cert: string | string[] | undefined;
ca: string[] | undefined;
};
2024-05-24 17:26:38 +02:00
export function getProxyFetchOptions(params: {
npmConfigGetCwd: string;
2024-10-05 21:22:00 +02:00
}): FetchOptionsLike {
const { npmConfigGetCwd } = params;
const cfg = (() => {
const output = child_process
.execSync("npm config get", {
cwd: npmConfigGetCwd
})
.toString("utf8");
return output
.split("\n")
.filter(line => !line.startsWith(";"))
.map(line => line.trim())
2024-08-07 16:07:07 +02:00
.map(line => {
const [key, value] = line.split("=");
if (key === undefined) {
return undefined;
}
if (value === undefined) {
return undefined;
}
return [key.trim(), value.trim()] as const;
})
.filter(exclude(undefined))
.filter(([key]) => key !== "")
.map(([key, value]) => {
if (value.startsWith('"') && value.endsWith('"')) {
return [key, value.slice(1, -1)] as const;
}
if (value === "true" || value === "false") {
return [key, value] as const;
}
return undefined;
})
.filter(exclude(undefined))
.reduce(
2024-08-07 16:07:07 +02:00
(cfg: Record<string, string | string[]>, [key, value]) =>
key in cfg
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
: { ...cfg, [key]: value },
{}
);
})();
2024-05-24 17:26:38 +02:00
const proxy = ensureSingleOrNone(cfg["https-proxy"] ?? cfg["proxy"]);
2024-08-07 11:46:05 +02:00
2024-05-24 17:26:38 +02:00
const noProxy = cfg["noproxy"] ?? cfg["no-proxy"];
2024-08-07 16:07:07 +02:00
const strictSSL = ensureSingleOrNone(cfg["strict-ssl"]) === "true";
2024-08-07 11:46:05 +02:00
2024-05-24 17:26:38 +02:00
const cert = cfg["cert"];
2024-08-07 11:46:05 +02:00
2024-05-24 17:26:38 +02:00
const ca = ensureArray(cfg["ca"] ?? cfg["ca[]"]);
2024-08-07 11:46:05 +02:00
2024-05-24 17:26:38 +02:00
const cafile = ensureSingleOrNone(cfg["cafile"]);
2024-08-07 16:07:07 +02:00
if (cafile !== undefined) {
2024-05-24 17:26:38 +02:00
ca.push(
...(() => {
const cafileContent = fs.readFileSync(cafile).toString("utf8");
const newLinePlaceholder = "NEW_LINE_PLACEHOLDER_xIsPsK23svt";
const chunks = <T>(arr: T[], size: number = 2) =>
arr
.map((_, i) => i % size == 0 && arr.slice(i, i + size))
.filter(Boolean) as T[][];
2024-05-24 17:26:38 +02:00
return chunks(cafileContent.split(/(-----END CERTIFICATE-----)/), 2).map(
ca =>
ca
.join("")
.replace(/\r?\n/g, newLinePlaceholder)
.replace(new RegExp(`^${newLinePlaceholder}`), "")
.replace(new RegExp(newLinePlaceholder, "g"), "\\n")
2024-05-24 17:26:38 +02:00
);
})()
2024-05-24 17:26:38 +02:00
);
}
2024-08-07 16:07:07 +02:00
return {
2024-05-24 17:26:38 +02:00
proxy,
noProxy,
strictSSL,
cert,
ca: ca.length === 0 ? undefined : ca
};
}
function ensureArray<T>(arg0: T | T[]) {
2024-08-07 16:07:07 +02:00
return Array.isArray(arg0) ? arg0 : arg0 === undefined ? [] : [arg0];
}
function ensureSingleOrNone<T>(arg0: T | T[]) {
if (!Array.isArray(arg0)) return arg0;
if (arg0.length === 0) return undefined;
if (arg0.length === 1) return arg0[0];
throw new Error(
"Illegal configuration, expected a single value but found multiple: " +
arg0.map(String).join(", ")
);
}