2024-06-23 21:23:06 +02:00
|
|
|
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
|
|
|
|
2024-06-23 21:23:06 +02:00
|
|
|
export function getProxyFetchOptions(params: {
|
|
|
|
npmConfigGetCwd: string;
|
2024-10-05 21:22:00 +02:00
|
|
|
}): FetchOptionsLike {
|
2024-06-23 21:23:06 +02:00
|
|
|
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))
|
2024-06-23 21:23:06 +02:00
|
|
|
.reduce(
|
2024-08-07 16:07:07 +02:00
|
|
|
(cfg: Record<string, string | string[]>, [key, value]) =>
|
2024-06-23 21:23:06 +02:00
|
|
|
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(
|
2024-06-23 21:23:06 +02:00
|
|
|
...(() => {
|
|
|
|
const cafileContent = fs.readFileSync(cafile).toString("utf8");
|
2024-06-14 21:53:17 +02:00
|
|
|
|
|
|
|
const newLinePlaceholder = "NEW_LINE_PLACEHOLDER_xIsPsK23svt";
|
|
|
|
|
2024-06-23 21:23:06 +02:00
|
|
|
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(
|
2024-06-14 21:53:17 +02:00
|
|
|
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-06-23 21:23:06 +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
|
|
|
|
};
|
|
|
|
}
|
2024-06-23 21:23:06 +02:00
|
|
|
|
|
|
|
function ensureArray<T>(arg0: T | T[]) {
|
2024-08-07 16:07:07 +02:00
|
|
|
return Array.isArray(arg0) ? arg0 : arg0 === undefined ? [] : [arg0];
|
2024-06-23 21:23:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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(", ")
|
|
|
|
);
|
|
|
|
}
|