UNPKG

@stryke/fs

Version:

A package containing various file system utilities that expand the functionality of NodeJs's built-in `fs` module.

138 lines (136 loc) 4.73 kB
import { getWorkspaceRoot } from "./get-workspace-root.mjs"; import { execSync } from "node:child_process"; import { detectPackageManager } from "@antfu/install-pkg"; import { parseArgs } from "node:util"; //#region src/registry.ts const parseNodeArgs = (args) => { const { values, tokens } = parseArgs({ args, strict: false, tokens: true }); let orphan = null; for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; if (token.kind === "option-terminator") break; if (token.kind === "option") { orphan = typeof token.value === "undefined" ? token : null; continue; } if (token.kind !== "positional") { orphan = null; continue; } if (!orphan) continue; if (orphan.name in values && typeof values[orphan.name] === "string") values[orphan.name] += ` ${token.value}`; else values[orphan.name] = token.value; } return values; }; /** * Tokenizes the arguments string into an array of strings, supporting quoted * values and escaped characters. * Converted from: https://github.com/nodejs/node/blob/c29d53c5cfc63c5a876084e788d70c9e87bed880/src/node_options.cc#L1401 * * @param input - The arguments string to be tokenized. * @returns An array of strings with the tokenized arguments. */ const tokenizeArgs = (input) => { const args = []; let isInString = false; let willStartNewArg = true; for (let i = 0; i < input.length; i++) { let char = input[i]; if (char === "\\" && isInString) { if (input.length === i + 1) throw new Error("Invalid escape character at the end."); char = input[++i]; } else if (char === " " && !isInString) { willStartNewArg = true; continue; } else if (char === "\"") { isInString = !isInString; continue; } if (willStartNewArg) { args.push(char); willStartNewArg = false; } else args[args.length - 1] += char; } if (isInString) throw new Error("Unterminated string"); return args; }; /** * Get the node options from the environment variable `NODE_OPTIONS` and returns * them as an array of strings. * * @returns An array of strings with the node options. */ const getNodeOptionsArgs = () => { if (!process.env.NODE_OPTIONS) return []; return tokenizeArgs(process.env.NODE_OPTIONS); }; /** * Stringify the arguments to be used in a command line. It will ignore any * argument that has a value of `undefined`. * * @param args - The arguments to be stringified. * @returns A string with the arguments. */ function formatNodeOptions(args) { return Object.entries(args).map(([key, value]) => { if (value === true) return `--${key}`; if (value) return `--${key}=${value.includes(" ") && !value.startsWith("\"") ? JSON.stringify(value) : value}`; return null; }).filter((arg) => arg !== null).join(" "); } /** * Get the node options from the `NODE_OPTIONS` environment variable and parse * them into an object without the inspect options. * * @returns An object with the parsed node options. */ function getParsedNodeOptionsWithoutInspect() { const args = getNodeOptionsArgs(); if (args.length === 0) return {}; const parsed = parseNodeArgs(args); delete parsed.inspect; delete parsed["inspect-brk"]; delete parsed.inspect_brk; return parsed; } /** * Get the node options from the `NODE_OPTIONS` environment variable and format * them into a string without the inspect options. * * @returns A string with the formatted node options. */ function getFormattedNodeOptionsWithoutInspect() { const args = getParsedNodeOptionsWithoutInspect(); if (Object.keys(args).length === 0) return ""; return formatNodeOptions(args); } /** * Returns the package registry using the user's package manager. The URL will have a trailing slash. * * @param baseDir - The base directory to detect the package manager from. * @returns The package registry URL with a trailing slash. * @throws Will throw an error if the package manager cannot be detected or if the registry cannot be retrieved. */ async function getRegistry(baseDir) { const pkgManager = await detectPackageManager(getWorkspaceRoot(baseDir)); const resolvedFlags = pkgManager === "npm" ? "--no-workspaces" : ""; let registry = `https://registry.npmjs.org/`; try { const output = execSync(`${pkgManager} config get registry ${resolvedFlags}`, { env: { ...process.env, NODE_OPTIONS: getFormattedNodeOptionsWithoutInspect() } }).toString().trim(); if (output.startsWith("http")) registry = output.endsWith("/") ? output : `${output}/`; } catch (err) { throw new Error(`Failed to get registry from "${pkgManager}".`, { cause: err }); } return registry; } //#endregion export { formatNodeOptions, getFormattedNodeOptionsWithoutInspect, getParsedNodeOptionsWithoutInspect, getRegistry, tokenizeArgs }; //# sourceMappingURL=registry.mjs.map