Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363// node:util: inspect/format (./inspect.ts), inherits, deprecate, promisify,// callbackify, debuglog, styleText (./styletext.ts) and the util.types predicates// (./util/types.ts). parseArgs (./util/parse-args.ts), parseEnv (./util/parse-env.ts)// and MIMEType/MIMEParams (./util/mime.ts) are their own files so other builtins and// other chunks can import them directly (process.loadEnvFile needs parseEnv).import { isDeepStrictEqual } from "./util/comparisons";import { invalidArgType as richInvalidArgType } from "./errors";import { format, formatWithOptions, inspect, stripVTControlCharacters } from "./inspect";import type { GuestProcess } from "./process";import { makeStyleText } from "./styletext";import { MIMEParams, MIMEType } from "./util/mime";import { parseArgs } from "./util/parse-args";import { parseEnv } from "./util/parse-env";import { types } from "./util/types";import { SIGNALS, type Signal } from "../shared/protocol";
export { parseEnv };
type Fn = (...args: any[]) => any;
function invalidArgType(name: string, expected: string, value: unknown): TypeError { const got = value === null ? "null" : value === undefined ? "undefined" : `type ${typeof value}`; return Object.assign(new TypeError(`The "${name}" argument must be ${expected}. Received ${got}`), { code: "ERR_INVALID_ARG_TYPE" });}
function inherits(ctor: Fn, superCtor: Fn): void { if (ctor === undefined || ctor === null) throw invalidArgType("ctor", "of type function", ctor); if (superCtor === undefined || superCtor === null) throw invalidArgType("superCtor", "of type function", superCtor); if (superCtor.prototype === undefined) throw invalidArgType("superCtor.prototype", "of type object", superCtor.prototype); Object.defineProperty(ctor, "super_", { value: superCtor, writable: true, configurable: true }); Object.setPrototypeOf(ctor.prototype, superCtor.prototype);}
const promisifyCustom = Symbol.for("nodejs.util.promisify.custom");
function promisify(original: Fn): Fn { if (typeof original !== "function") throw invalidArgType("original", "of type function", original); const custom = (original as Fn & { [promisifyCustom]?: Fn })[promisifyCustom]; if (custom !== undefined) { if (typeof custom !== "function") throw invalidArgType("util.promisify.custom", "of type function", custom); return Object.defineProperty(custom, promisifyCustom, { value: custom, enumerable: false, writable: false, configurable: true }); } function fn(this: unknown, ...args: unknown[]): Promise<unknown> { return new Promise((resolve, reject) => { Reflect.apply(original, this, [...args, (err: unknown, value: unknown) => (err ? reject(err) : resolve(value))]); }); } Object.setPrototypeOf(fn, Object.getPrototypeOf(original)); Object.defineProperty(fn, promisifyCustom, { value: fn, enumerable: false, writable: false, configurable: true }); return Object.defineProperties(fn, Object.getOwnPropertyDescriptors(original));}promisify.custom = promisifyCustom;
function callbackify(original: Fn): Fn { if (typeof original !== "function") throw invalidArgType("original", "of type function", original); function callbackified(this: unknown, ...args: unknown[]): void { const cb = args.pop(); if (typeof cb !== "function") throw invalidArgType("last argument", "of type function", cb); const onRejected = (reason: unknown): void => { if (!reason) { reason = Object.assign(new Error("Promise was rejected with a falsy value"), { code: "ERR_FALSY_VALUE_REJECTION", reason }); } queueMicrotask(() => cb(reason)); }; Reflect.apply(original, this, args).then((v: unknown) => queueMicrotask(() => cb(null, v)), onRejected); } Object.defineProperties(callbackified, Object.getOwnPropertyDescriptors(original)); return callbackified;}
// util.getSystemErrorName/Map/Message: libuv's own small table of errno -> {name, text},// built from this platform's errno.h (os.ts) — see uv_err_name/uv_strerror. A number// outside the table gets Node's own fallback text, matching Node exactly for unknowns.const SYSTEM_ERRORS: Record<number, [name: string, message: string]> = { 1: ["EPERM", "operation not permitted"], 2: ["ENOENT", "no such file or directory"], 3: ["ESRCH", "no such process"], 4: ["EINTR", "interrupted system call"], 5: ["EIO", "i/o error"], 6: ["ENXIO", "no such device or address"], 7: ["E2BIG", "argument list too long"], 8: ["ENOEXEC", "exec format error"], 9: ["EBADF", "bad file descriptor"], 12: ["ENOMEM", "not enough memory"], 13: ["EACCES", "permission denied"], 14: ["EFAULT", "bad address in system call argument"], 16: ["EBUSY", "resource busy or locked"], 17: ["EEXIST", "file already exists"], 18: ["EXDEV", "cross-device link not permitted"], 19: ["ENODEV", "no such device"], 20: ["ENOTDIR", "not a directory"], 21: ["EISDIR", "illegal operation on a directory"], 22: ["EINVAL", "invalid argument"], 23: ["ENFILE", "file table overflow"], 24: ["EMFILE", "too many open files"], 25: ["ENOTTY", "inappropriate ioctl for device"], 26: ["ETXTBSY", "text file is busy"], 27: ["EFBIG", "file too large"], 28: ["ENOSPC", "no space left on device"], 29: ["ESPIPE", "invalid seek"], 30: ["EROFS", "read-only file system"], 31: ["EMLINK", "too many links"], 32: ["EPIPE", "broken pipe"], 34: ["ERANGE", "result too large"], 35: ["EAGAIN", "resource temporarily unavailable"], 37: ["EALREADY", "connection already in progress"], 38: ["ENOTSOCK", "socket operation on non-socket"], 39: ["EDESTADDRREQ", "destination address required"], 40: ["EMSGSIZE", "message too long"], 41: ["EPROTOTYPE", "protocol wrong type for socket"], 42: ["ENOPROTOOPT", "protocol not available"], 43: ["EPROTONOSUPPORT", "protocol not supported"], 45: ["ENOTSUP", "operation not supported on socket"], 47: ["EAFNOSUPPORT", "address family not supported"], 48: ["EADDRINUSE", "address already in use"], 49: ["EADDRNOTAVAIL", "address not available"], 50: ["ENETDOWN", "network is down"], 51: ["ENETUNREACH", "network is unreachable"], 53: ["ECONNABORTED", "software caused connection abort"], 54: ["ECONNRESET", "connection reset by peer"], 55: ["ENOBUFS", "no buffer space available"], 56: ["EISCONN", "socket is already connected"], 57: ["ENOTCONN", "socket is not connected"], 60: ["ETIMEDOUT", "connection timed out"], 61: ["ECONNREFUSED", "connection refused"], 62: ["ELOOP", "too many symbolic links encountered"], 63: ["ENAMETOOLONG", "name too long"], 65: ["EHOSTUNREACH", "host is unreachable"], 66: ["ENOTEMPTY", "directory not empty"], 78: ["ENOSYS", "function not implemented"], 84: ["EOVERFLOW", "value too large for defined data type"], 89: ["ECANCELED", "operation canceled"], 92: ["EILSEQ", "illegal byte sequence"], 96: ["ENODATA", "no data available"], 100: ["EPROTO", "protocol error"],};
function outOfRange(name: string, range: string, value: unknown): RangeError { return Object.assign(new RangeError(`The value of "${name}" is out of range. It must be ${range}. Received ${value}`), { code: "ERR_OUT_OF_RANGE" });}
function checkErrnoArg(err: unknown): number { if (typeof err !== "number") throw richInvalidArgType("err", "of type number", err); if (err >= 0 || !Number.isSafeInteger(err)) throw outOfRange("err", "a negative integer", err); return err;}
function getSystemErrorName(err: unknown): string { const n = checkErrnoArg(err); const found = SYSTEM_ERRORS[-n]; return found ? found[0] : `Unknown system error ${n}`;}
function getSystemErrorMessage(err: unknown): string { const n = checkErrnoArg(err); const found = SYSTEM_ERRORS[-n]; return found ? found[1] : `Unknown system error ${n}`;}
function getSystemErrorMap(): Map<number, [name: string, message: string]> { const map = new Map<number, [string, string]>(); for (const [n, entry] of Object.entries(SYSTEM_ERRORS)) map.set(-Number(n), entry); return map;}
function abortError(signal: AbortSignal): Error { return Object.assign(new Error("The operation was aborted"), { name: "AbortError", code: "ABORT_ERR", cause: signal.reason });}
/** util.aborted: resolves once `signal` fires, as long as `resource` has not itself * been collected (no engine weak-callback for that here, so `resource` just has to * be a non-null object, as Node requires). */async function aborted(signal: unknown, resource: unknown): Promise<void> { if (!(signal instanceof AbortSignal)) throw richInvalidArgType("signal", "an instance of AbortSignal", signal); if (resource === null || typeof resource !== "object") throw richInvalidArgType("resource", "of type object", resource); if (signal.aborted) return; await new Promise<void>((resolve) => signal.addEventListener("abort", () => resolve(), { once: true }));}
const SIGNAL_EXIT_CODE: Record<string, number> = Object.fromEntries(Object.entries(SIGNALS).map(([name, n]) => [name, 128 + n]));
function convertProcessSignalToExitCode(signalCode: unknown): number { if (typeof signalCode !== "string" || !Object.hasOwn(SIGNAL_EXIT_CODE, signalCode)) { const options = Object.keys(SIGNAL_EXIT_CODE).map((s) => `'${s}'`).join(", "); throw Object.assign( new TypeError(`The argument 'signalCode' must be one of: ${options}. Received ${inspect(signalCode)}`), { code: "ERR_INVALID_ARG_VALUE" }, ); } return SIGNAL_EXIT_CODE[signalCode as Signal]!;}
/** util.getCallSites: the live JS call stack, V8's own format (Error.prepareStackTrace). * No scriptId: that is a V8-internal binding Node reaches directly, which untrusted * guest code cannot. */function getCallSites(frameCount: unknown = 10, options?: unknown): Array<{ functionName: string; scriptName: string; lineNumber: number; columnNumber: number; column: number;}> { let count = frameCount; let opts = options; if (opts === undefined && typeof count === "object" && count !== null) { opts = count; count = 10; } if (typeof count !== "number" || !Number.isInteger(count) || count < 1 || count > 200) { throw Object.assign(new RangeError(`The value of "frameCount" is out of range. It must be >= 1 && <= 200. Received ${count}`), { code: "ERR_OUT_OF_RANGE" }); } const limit = Error.stackTraceLimit; const prepare = Error.prepareStackTrace; type CallSite = { getFunctionName(): string | null; getFileName(): string | null; getLineNumber(): number; getColumnNumber(): number }; let sites: CallSite[] = []; try { Error.stackTraceLimit = count + 1; Error.prepareStackTrace = (_err: unknown, callSites: unknown) => { sites = callSites as CallSite[]; return ""; }; const holder = {} as { stack?: unknown }; Error.captureStackTrace(holder, getCallSites); void holder.stack; } finally { Error.stackTraceLimit = limit; Error.prepareStackTrace = prepare; } return sites.slice(0, count).map((site) => ({ functionName: site.getFunctionName() ?? "", scriptName: site.getFileName() ?? "", lineNumber: site.getLineNumber(), columnNumber: site.getColumnNumber(), column: site.getColumnNumber(), }));}
const enum Op { Delete = -1, Nop = 0, Insert = 1 }
function validateDiffInput(value: unknown, name: string): void { if (Array.isArray(value)) { value.forEach((v, i) => { if (typeof v !== "string") throw richInvalidArgType(`${name}[${i}]`, "of type string", v); }); return; } if (typeof value !== "string") throw richInvalidArgType(name, "of type string", value);}
/** util.diff: a Myers diff over characters (for strings) or elements (for arrays), * matching Node's lib/internal/assert/myers_diff.js algorithm. */function diff(actual: string | string[], expected: string | string[]): Array<[Op, unknown]> { if (actual === expected) return []; validateDiffInput(actual, "actual"); validateDiffInput(expected, "expected"); const a = actual as unknown as { length: number; [i: number]: unknown }; const b = expected as unknown as { length: number; [i: number]: unknown }; const aLen = a.length; const bLen = b.length; const max = aLen + bLen; const v = new Int32Array(2 * max + 1); const trace: Int32Array[] = [];
let found: number | undefined; for (let d = 0; d <= max && found === undefined; d++) { trace.push(v.slice()); for (let k = -d; k <= d; k += 2) { const offset = k + max; const prev = v[offset - 1]!; const next = v[offset + 1]!; let x = k === -d || (k !== d && prev < next) ? next : prev + 1; let y = x - k; while (x < aLen && y < bLen && a[x] === b[y]) { x++; y++; } v[offset] = x; if (x >= aLen && y >= bLen) { found = d; break; } } } return backtrackDiff(trace, a, b, max);}
function backtrackDiff(trace: Int32Array[], a: { length: number; [i: number]: unknown }, b: { length: number; [i: number]: unknown }, max: number): Array<[Op, unknown]> { let x = a.length; let y = b.length; const result: Array<[Op, unknown]> = []; for (let d = trace.length - 1; d >= 0; d--) { const v = trace[d]!; const k = x - y; const offset = k + max; const prevK = k === -d || (k !== d && v[offset - 1]! < v[offset + 1]!) ? k + 1 : k - 1; const prevX = v[prevK + max]!; const prevY = prevX - prevK; while (x > prevX && y > prevY) { result.push([Op.Nop, a[x - 1]]); x--; y--; } if (d > 0) { if (x > prevX) result.push([Op.Insert, a[--x]]); else result.push([Op.Delete, b[--y]]); } } return result.reverse();}
export function makeUtil(process: GuestProcess, isMainThread: () => boolean) { const warnedCodes = new Set<string>();
/** Node's deprecate: one warning per code (or per wrapper without one), honoring * process.noDeprecation and process.throwDeprecation. */ function deprecate<T extends Fn>(fn: T, msg: string, code?: string): T { if (typeof fn !== "function") throw invalidArgType("fn", "of type function", fn); let warned = false; function deprecated(this: unknown, ...args: unknown[]): unknown { const p = process as GuestProcess & { noDeprecation?: boolean; throwDeprecation?: boolean }; if (!p.noDeprecation && !warned && !(code !== undefined && warnedCodes.has(code))) { warned = true; if (code !== undefined) warnedCodes.add(code); if (p.throwDeprecation) throw Object.assign(new Error(msg), { name: "DeprecationWarning", code }); process.emitWarning(msg, "DeprecationWarning", code); } return new.target ? Reflect.construct(fn, args, new.target) : Reflect.apply(fn, this, args); } Object.setPrototypeOf(deprecated, fn); if (fn.prototype) deprecated.prototype = fn.prototype; return deprecated as unknown as T; }
/** debuglog(section): a no-op unless NODE_DEBUG names the section. */ function debuglog(section: string, cb?: (fn: Fn) => void): Fn & { enabled: boolean } { const names = (process.env.NODE_DEBUG ?? "").split(/[\s,]+/).filter(Boolean).map((s) => s.toUpperCase()); const tag = section.toUpperCase(); const enabled = names.some((n) => n === tag || (n.endsWith("*") && tag.startsWith(n.slice(0, -1)))); const log = Object.assign( enabled ? (...args: unknown[]) => process.stderr.write(`${tag} ${process.pid}: ${format(...args)}\n`) : () => {}, { enabled }, ); cb?.(log); return log; }
/** util.setTraceSigInt: there is no terminal-level SIGINT watchdog to toggle (no * raw-terminal escape hatch outside a handled signal), so this only enforces the * worker-thread restriction Node itself applies and otherwise does nothing. */ function setTraceSigInt(enable: unknown): void { if (!isMainThread()) { throw Object.assign(new TypeError("Calling util.setTraceSigInt() is not supported in workers"), { code: "ERR_WORKER_UNSUPPORTED_OPERATION" }); } void enable; }
return { format, formatWithOptions, inspect, inherits, deprecate, promisify, callbackify, debuglog, debug: debuglog, types, isArray: Array.isArray, stripVTControlCharacters, styleText: makeStyleText(() => process.stdout), isDeepStrictEqual, TextEncoder, TextDecoder, MIMEType, MIMEParams, parseArgs: (config?: unknown) => parseArgs(config as never, () => process.argv.slice(2)), parseEnv, aborted, getSystemErrorName, getSystemErrorMap, getSystemErrorMessage, toUSVString: (input: unknown) => `${input}`.toWellFormed(), // Transferring across a worker boundary rides on structured clone (clone.ts), // which does not special-case AbortSignal; within one realm these behave like // the plain constructors, so same-realm use (the common case) works as-is. transferableAbortController: () => new AbortController(), transferableAbortSignal: (signal: unknown) => { if (!(signal instanceof AbortSignal)) throw richInvalidArgType("signal", "an instance of AbortSignal", signal); return signal; }, getCallSites, diff, convertProcessSignalToExitCode, setTraceSigInt, };}