@socketsecurity/lib 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/logger.d.ts CHANGED
@@ -6,9 +6,7 @@ type LogSymbols = {
6
6
  warn: string;
7
7
  };
8
8
  type LoggerMethods = {
9
- [K in keyof typeof console]: (typeof console)[K] extends (...args: infer A
10
- // biome-ignore lint/suspicious/noExplicitAny: Console method return types are dynamic.
11
- ) => any ? (...args: A) => Logger : (typeof console)[K];
9
+ [K in keyof typeof console]: (typeof console)[K] extends (...args: infer A) => any ? (...args: A) => Logger : (typeof console)[K];
12
10
  };
13
11
  interface Task {
14
12
  run<T>(f: () => T): T;
package/dist/logger.js CHANGED
@@ -50,7 +50,6 @@ function constructConsole(...args) {
50
50
  _Console = nodeConsole.Console;
51
51
  }
52
52
  return ReflectConstruct(
53
- // biome-ignore lint/style/noNonNullAssertion: Initialized above.
54
53
  _Console,
55
54
  // eslint-disable-line no-undef
56
55
  args
@@ -133,10 +132,7 @@ const maxIndentation = 1e3;
133
132
  const privateConsole = /* @__PURE__ */ new WeakMap();
134
133
  const consoleSymbols = Object.getOwnPropertySymbols(globalConsole);
135
134
  const incLogCallCountSymbol = Symbol.for("logger.logCallCount++");
136
- const kGroupIndentationWidthSymbol = (
137
- // biome-ignore lint/suspicious/noExplicitAny: Symbol property access.
138
- consoleSymbols.find((s) => s.label === "kGroupIndentWidth") ?? Symbol("kGroupIndentWidth")
139
- );
135
+ const kGroupIndentationWidthSymbol = consoleSymbols.find((s) => s.label === "kGroupIndentWidth") ?? Symbol("kGroupIndentWidth");
140
136
  const lastWasBlankSymbol = Symbol.for("logger.lastWasBlank");
141
137
  class Logger {
142
138
  static LOG_SYMBOLS = LOG_SYMBOLS;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/logger.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Console logging utilities with line prefix support.\n * Provides enhanced console methods with formatted output capabilities.\n */\n\nimport isUnicodeSupported from './external/@socketregistry/is-unicode-supported'\nimport yoctocolorsCjs from './external/yoctocolors-cjs'\nimport { objectAssign, objectFreeze } from './objects'\nimport { applyLinePrefix, isBlankString } from './strings'\n\n// Type definitions\ntype LogSymbols = {\n fail: string\n info: string\n success: string\n warn: string\n}\n\ntype LoggerMethods = {\n [K in keyof typeof console]: (typeof console)[K] extends (\n ...args: infer A\n // biome-ignore lint/suspicious/noExplicitAny: Console method return types are dynamic.\n ) => any\n ? (...args: A) => Logger\n : (typeof console)[K]\n}\n\ninterface Task {\n run<T>(f: () => T): T\n}\n\nexport type { LogSymbols, LoggerMethods, Task }\n\nconst globalConsole = console\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst ReflectConstruct = Reflect.construct\n\nlet _Console: typeof import('console').Console | undefined\n/**\n * Construct a new Console instance.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction constructConsole(...args: unknown[]) {\n if (_Console === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n const nodeConsole = /*@__PURE__*/ require('node:console')\n _Console = nodeConsole.Console\n }\n return ReflectConstruct(\n // biome-ignore lint/style/noNonNullAssertion: Initialized above.\n _Console! as new (\n ...args: unknown[]\n ) => Console, // eslint-disable-line no-undef\n args,\n )\n}\n\n/**\n * Get the yoctocolors module for terminal colors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getYoctocolors() {\n return yoctocolorsCjs\n}\n\nexport const LOG_SYMBOLS = /*@__PURE__*/ (() => {\n const target: Record<string, string> = {\n __proto__: null,\n } as unknown as Record<string, string>\n // Mutable handler to simulate a frozen target.\n const handler: ProxyHandler<Record<string, string>> = {\n __proto__: null,\n } as unknown as ProxyHandler<Record<string, string>>\n const init = () => {\n const supported = isUnicodeSupported()\n const colors = getYoctocolors()\n objectAssign(target, {\n fail: colors.red(supported ? '\u2716' : '\u00D7'),\n info: colors.blue(supported ? '\u2139' : 'i'),\n success: colors.green(supported ? '\u2714' : '\u221A'),\n warn: colors.yellow(supported ? '\u26A0' : '\u203C'),\n })\n objectFreeze(target)\n // The handler of a Proxy is mutable after proxy instantiation.\n // We delete the traps to defer to native behavior.\n for (const trapName in handler) {\n delete handler[trapName as keyof ProxyHandler<Record<string, string>>]\n }\n }\n for (const trapName of Reflect.ownKeys(Reflect)) {\n const fn = (Reflect as Record<PropertyKey, unknown>)[trapName]\n if (typeof fn === 'function') {\n ;(handler as Record<string, (...args: unknown[]) => unknown>)[\n trapName as string\n ] = (...args: unknown[]) => {\n init()\n return fn(...args)\n }\n }\n }\n return new Proxy(target, handler)\n})()\n\nconst boundConsoleEntries = [\n // Add bound properties from console[kBindProperties](ignoreErrors, colorMode, groupIndentation).\n // https://github.com/nodejs/node/blob/v24.0.1/lib/internal/console/constructor.js#L230-L265\n '_stderrErrorHandler',\n '_stdoutErrorHandler',\n // Add methods that need to be bound to function properly.\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'createTask',\n 'debug',\n 'dir',\n 'dirxml',\n 'error',\n // Skip group methods because in at least Node 20 with the Node --frozen-intrinsics\n // flag it triggers a readonly property for Symbol(kGroupIndent). Instead, we\n // implement these methods ourselves.\n //'group',\n //'groupCollapsed',\n //'groupEnd',\n 'info',\n 'log',\n 'table',\n 'time',\n 'timeEnd',\n 'timeLog',\n 'trace',\n 'warn',\n]\n // biome-ignore lint/suspicious/noExplicitAny: Dynamic console method access.\n .filter(n => typeof (globalConsole as any)[n] === 'function')\n // biome-ignore lint/suspicious/noExplicitAny: Dynamic console method access.\n .map(n => [n, (globalConsole as any)[n].bind(globalConsole)])\n\nconst consolePropAttributes = {\n __proto__: null,\n writable: true,\n enumerable: false,\n configurable: true,\n}\nconst maxIndentation = 1000\nconst privateConsole = new WeakMap()\n\nconst consoleSymbols = Object.getOwnPropertySymbols(globalConsole)\nexport const incLogCallCountSymbol = Symbol.for('logger.logCallCount++')\nconst kGroupIndentationWidthSymbol =\n // biome-ignore lint/suspicious/noExplicitAny: Symbol property access.\n consoleSymbols.find(s => (s as any).label === 'kGroupIndentWidth') ??\n Symbol('kGroupIndentWidth')\nexport const lastWasBlankSymbol = Symbol.for('logger.lastWasBlank')\n\n/**\n * Custom Logger class that wraps console with additional features.\n * Supports indentation, symbols, and blank line tracking.\n */\n/*@__PURE__*/\nexport class Logger {\n static LOG_SYMBOLS = LOG_SYMBOLS\n\n #parent?: Logger\n #boundStream?: 'stderr' | 'stdout'\n #stderrLogger?: Logger\n #stdoutLogger?: Logger\n #stderrIndention = ''\n #stdoutIndention = ''\n #lastWasBlank = false\n #logCallCount = 0\n #constructorArgs: unknown[]\n #options: Record<string, unknown>\n\n constructor(...args: unknown[]) {\n // Store constructor args for child loggers\n this.#constructorArgs = args\n\n // Store options if provided (for future extensibility)\n const options = args['0']\n if (typeof options === 'object' && options !== null) {\n this.#options = { __proto__: null, ...options }\n } else {\n this.#options = { __proto__: null }\n }\n\n if (args.length) {\n privateConsole.set(this, constructConsole(...args))\n } else {\n // Create a new console that acts like the builtin one so that it will\n // work with Node's --frozen-intrinsics flag.\n const con = constructConsole({\n stdout: process.stdout,\n stderr: process.stderr,\n }) as typeof console & Record<string, unknown>\n for (const { 0: key, 1: method } of boundConsoleEntries) {\n con[key] = method\n }\n privateConsole.set(this, con)\n }\n }\n\n /**\n * Get a logger instance bound to stderr.\n * All operations on this instance will use stderr.\n */\n get stderr(): Logger {\n if (!this.#stderrLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stderr'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stderrLogger = instance\n }\n return this.#stderrLogger\n }\n\n /**\n * Get a logger instance bound to stdout.\n * All operations on this instance will use stdout.\n */\n get stdout(): Logger {\n if (!this.#stdoutLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stdout'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stdoutLogger = instance\n }\n return this.#stdoutLogger\n }\n\n /**\n * Get the root logger (for accessing shared indentation state).\n * @private\n */\n #getRoot(): Logger {\n return this.#parent || this\n }\n\n /**\n * Get indentation for a specific stream.\n * @private\n */\n #getIndent(stream: 'stderr' | 'stdout'): string {\n const root = this.#getRoot()\n return stream === 'stderr' ? root.#stderrIndention : root.#stdoutIndention\n }\n\n /**\n * Set indentation for a specific stream.\n * @private\n */\n #setIndent(stream: 'stderr' | 'stdout', value: string): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrIndention = value\n } else {\n root.#stdoutIndention = value\n }\n }\n\n /**\n * Get the target stream for this logger instance.\n * @private\n */\n #getTargetStream(): 'stderr' | 'stdout' {\n return this.#boundStream || 'stderr'\n }\n\n /**\n * Apply a console method with indentation.\n * @private\n */\n #apply(\n methodName: string,\n args: unknown[],\n stream?: 'stderr' | 'stdout',\n ): this {\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n const text = args.at(0)\n const hasText = typeof text === 'string'\n // Determine which stream this method writes to\n const targetStream = stream || (methodName === 'log' ? 'stdout' : 'stderr')\n const indent = this.#getIndent(targetStream)\n const logArgs = hasText\n ? [applyLinePrefix(text, { prefix: indent }), ...args.slice(1)]\n : args\n ReflectApply(\n con[methodName] as (...args: unknown[]) => unknown,\n con,\n logArgs,\n )\n this[lastWasBlankSymbol](hasText && isBlankString(logArgs[0]))\n // biome-ignore lint/suspicious/noExplicitAny: Symbol method access.\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Strip log symbols from the start of text.\n * @private\n */\n #stripSymbols(text: string): string {\n // Strip both unicode and emoji forms of log symbols from the start.\n // Matches: \u2716, \u2717, \u00D7, \u2716\uFE0F, \u26A0, \u203C, \u26A0\uFE0F, \u2714, \u2713, \u221A, \u2714\uFE0F, \u2713\uFE0F, \u2139, \u2139\uFE0F\n // Also handles variation selectors (U+FE0F) and whitespace after symbol.\n // Note: We don't strip standalone 'i' to avoid breaking words like 'info'.\n return text.replace(/^[\u2716\u2717\u00D7\u26A0\u203C\u2714\u2713\u221A\u2139]\\uFE0F?\\s*/u, '')\n }\n\n /**\n * Apply a method with a symbol prefix.\n * @private\n */\n #symbolApply(symbolType: string, args: unknown[]): this {\n const con = privateConsole.get(this)\n let text = args.at(0)\n // biome-ignore lint/suspicious/noImplicitAnyLet: Flexible argument handling.\n let extras\n if (typeof text === 'string') {\n text = this.#stripSymbols(text)\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n // Note: Meta status messages (info/fail/etc) always go to stderr.\n const indent = this.#getIndent('stderr')\n con.error(\n applyLinePrefix(`${LOG_SYMBOLS[symbolType]} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this.#lastWasBlank = false\n // biome-ignore lint/suspicious/noExplicitAny: Symbol method access.\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Get the current log call count.\n */\n get logCallCount() {\n return this.#logCallCount\n }\n\n /**\n * Increment the log call count.\n */\n [incLogCallCountSymbol]() {\n this.#logCallCount += 1\n return this\n }\n\n /**\n * Set whether the last logged line was blank.\n */\n [lastWasBlankSymbol](value: unknown): this {\n this.#lastWasBlank = !!value\n return this\n }\n\n /**\n * Log an assertion.\n */\n assert(value: unknown, ...message: unknown[]): this {\n const con = privateConsole.get(this)\n con.assert(value, ...message)\n this[lastWasBlankSymbol](false)\n return value ? this : this[incLogCallCountSymbol]()\n }\n\n /**\n * Clear the visible terminal screen.\n * Only available on the main logger instance.\n */\n clearVisible() {\n if (this.#boundStream) {\n throw new Error(\n 'clearVisible() is only available on the main logger instance, not on stream-bound instances',\n )\n }\n const con = privateConsole.get(this)\n con.clear()\n // biome-ignore lint/suspicious/noExplicitAny: Internal console property access.\n if ((con as any)._stdout.isTTY) {\n // biome-ignore lint/suspicious/noExplicitAny: Symbol method access.\n ;(this as any)[lastWasBlankSymbol](true)\n this.#logCallCount = 0\n }\n return this\n }\n\n /**\n * Log a count for the given label.\n */\n count(label?: string): this {\n const con = privateConsole.get(this)\n con.count(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Create a task with a given name.\n */\n createTask(name: string): Task {\n return {\n run: <T>(f: () => T): T => {\n this.log(`Starting task: ${name}`)\n const result = f()\n this.log(`Completed task: ${name}`)\n return result\n },\n }\n }\n\n /**\n * Decrease indentation level.\n * If called on main logger, affects both streams.\n * If called on stream-bound logger, affects only that stream.\n */\n dedent(spaces = 2) {\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current.slice(0, -spaces))\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent.slice(0, -spaces))\n this.#setIndent('stdout', stdoutCurrent.slice(0, -spaces))\n }\n return this\n }\n\n /**\n * Display an object's properties.\n */\n dir(obj: unknown, options?: unknown): this {\n const con = privateConsole.get(this)\n con.dir(obj, options)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Display data as XML.\n */\n dirxml(...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.dirxml(data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log an error message.\n */\n error(...args: unknown[]): this {\n return this.#apply('error', args)\n }\n\n /**\n * Log a newline to stderr if last line wasn't blank.\n */\n errorNewline() {\n return this.#lastWasBlank ? this : this.error('')\n }\n\n /**\n * Log a failure message with symbol.\n */\n fail(...args: unknown[]): this {\n return this.#symbolApply('fail', args)\n }\n\n /**\n * Start a new log group.\n */\n group(...label: unknown[]): this {\n const { length } = label\n if (length) {\n ReflectApply(this.log, this, label)\n }\n // biome-ignore lint/suspicious/noExplicitAny: Symbol property access.\n this.indent((this as any)[kGroupIndentationWidthSymbol])\n if (length) {\n // biome-ignore lint/suspicious/noExplicitAny: Symbol method access.\n ;(this as any)[lastWasBlankSymbol](false)\n // biome-ignore lint/suspicious/noExplicitAny: Symbol method access.\n ;(this as any)[incLogCallCountSymbol]()\n }\n return this\n }\n\n /**\n * Start a new collapsed log group (alias for group).\n */\n // groupCollapsed is an alias of group.\n // https://nodejs.org/api/console.html#consolegroupcollapsed\n groupCollapsed(...label: unknown[]): this {\n return ReflectApply(this.group, this, label)\n }\n\n /**\n * End the current log group.\n */\n groupEnd() {\n // biome-ignore lint/suspicious/noExplicitAny: Symbol property access.\n this.dedent((this as any)[kGroupIndentationWidthSymbol])\n return this\n }\n\n /**\n * Increase indentation level.\n * If called on main logger, affects both streams.\n * If called on stream-bound logger, affects only that stream.\n */\n indent(spaces = 2) {\n const spacesToAdd = ' '.repeat(Math.min(spaces, maxIndentation))\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current + spacesToAdd)\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent + spacesToAdd)\n this.#setIndent('stdout', stdoutCurrent + spacesToAdd)\n }\n return this\n }\n\n /**\n * Log an info message with symbol.\n */\n info(...args: unknown[]): this {\n return this.#symbolApply('info', args)\n }\n\n /**\n * Log a message.\n */\n log(...args: unknown[]): this {\n return this.#apply('log', args)\n }\n\n /**\n * Log a newline to stdout if last line wasn't blank.\n */\n logNewline() {\n return this.#lastWasBlank ? this : this.log('')\n }\n\n /**\n * Reset indentation to zero.\n * If called on main logger, resets both streams.\n * If called on stream-bound logger, resets only that stream.\n */\n resetIndent() {\n if (this.#boundStream) {\n // Only reset bound stream\n this.#setIndent(this.#boundStream, '')\n } else {\n // Reset both streams\n this.#setIndent('stderr', '')\n this.#setIndent('stdout', '')\n }\n return this\n }\n\n /**\n * Log a main step with blank line before (stateless).\n */\n step(msg: string, ...extras: unknown[]): this {\n // Add blank line before the step message.\n if (!this.#lastWasBlank) {\n // Use this.log() to properly track the blank line.\n this.log('')\n }\n // Let log() handle all tracking.\n return this.log(msg, ...extras)\n }\n\n /**\n * Log an indented substep (stateless).\n */\n substep(msg: string, ...extras: unknown[]): this {\n // Add 2-space indent to the message.\n const indentedMsg = ` ${msg}`\n // Let log() handle all tracking.\n return this.log(indentedMsg, ...extras)\n }\n\n /**\n * Log a success message with symbol.\n */\n success(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Log a done message (alias for success).\n * Does NOT auto-clear. Call clearLine() first if needed after progress().\n */\n done(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Display data in a table format.\n */\n table(tabularData: unknown, properties?: readonly string[]): this {\n const con = privateConsole.get(this)\n con.table(tabularData, properties)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * End a timer and log the elapsed time.\n */\n timeEnd(label?: string): this {\n const con = privateConsole.get(this)\n con.timeEnd(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log the current timer value.\n */\n timeLog(label?: string, ...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.timeLog(label, ...data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log a stack trace.\n */\n trace(message?: unknown, ...args: unknown[]): this {\n const con = privateConsole.get(this)\n con.trace(message, ...args)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log a warning message with symbol.\n */\n warn(...args: unknown[]): this {\n return this.#symbolApply('warn', args)\n }\n\n /**\n * Write to stdout without a newline or indentation.\n */\n write(text: string): this {\n const con = privateConsole.get(this)\n con._stdout.write(text)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Show a progress indicator (can be cleared with clearLine).\n * Simple status message without spinner animation.\n */\n progress(text: string): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n streamObj.write(`\u2234 ${text}`)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Clear the current line.\n */\n clearLine(): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n if (streamObj.isTTY) {\n streamObj.cursorTo(0)\n streamObj.clearLine(0)\n } else {\n streamObj.write('\\r\\x1b[K')\n }\n return this\n }\n}\n\nObject.defineProperties(\n Logger.prototype,\n Object.fromEntries(\n (() => {\n const entries: Array<[string | symbol, PropertyDescriptor]> = [\n [\n kGroupIndentationWidthSymbol,\n {\n ...consolePropAttributes,\n value: 2,\n },\n ],\n [\n Symbol.toStringTag,\n {\n __proto__: null,\n configurable: true,\n value: 'logger',\n } as PropertyDescriptor,\n ],\n ]\n for (const { 0: key, 1: value } of Object.entries(globalConsole)) {\n // biome-ignore lint/suspicious/noExplicitAny: Dynamic prototype check.\n if (!(Logger.prototype as any)[key] && typeof value === 'function') {\n // Dynamically name the log method without using Object.defineProperty.\n const { [key]: func } = {\n [key](...args: unknown[]) {\n const con = privateConsole.get(this)\n // biome-ignore lint/suspicious/noExplicitAny: Dynamic console method access.\n const result = (con as any)[key](...args)\n return result === undefined || result === con ? this : result\n },\n }\n entries.push([\n key,\n {\n ...consolePropAttributes,\n value: func,\n },\n ])\n }\n }\n return entries\n })(),\n ),\n)\n\nexport const logger = new Logger()\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @fileoverview Console logging utilities with line prefix support.\n * Provides enhanced console methods with formatted output capabilities.\n */\n\nimport isUnicodeSupported from './external/@socketregistry/is-unicode-supported'\nimport yoctocolorsCjs from './external/yoctocolors-cjs'\nimport { objectAssign, objectFreeze } from './objects'\nimport { applyLinePrefix, isBlankString } from './strings'\n\n// Type definitions\ntype LogSymbols = {\n fail: string\n info: string\n success: string\n warn: string\n}\n\ntype LoggerMethods = {\n [K in keyof typeof console]: (typeof console)[K] extends (\n ...args: infer A\n ) => any\n ? (...args: A) => Logger\n : (typeof console)[K]\n}\n\ninterface Task {\n run<T>(f: () => T): T\n}\n\nexport type { LogSymbols, LoggerMethods, Task }\n\nconst globalConsole = console\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst ReflectConstruct = Reflect.construct\n\nlet _Console: typeof import('console').Console | undefined\n/**\n * Construct a new Console instance.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction constructConsole(...args: unknown[]) {\n if (_Console === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n const nodeConsole = /*@__PURE__*/ require('node:console')\n _Console = nodeConsole.Console\n }\n return ReflectConstruct(\n _Console! as new (\n ...args: unknown[]\n ) => Console, // eslint-disable-line no-undef\n args,\n )\n}\n\n/**\n * Get the yoctocolors module for terminal colors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getYoctocolors() {\n return yoctocolorsCjs\n}\n\nexport const LOG_SYMBOLS = /*@__PURE__*/ (() => {\n const target: Record<string, string> = {\n __proto__: null,\n } as unknown as Record<string, string>\n // Mutable handler to simulate a frozen target.\n const handler: ProxyHandler<Record<string, string>> = {\n __proto__: null,\n } as unknown as ProxyHandler<Record<string, string>>\n const init = () => {\n const supported = isUnicodeSupported()\n const colors = getYoctocolors()\n objectAssign(target, {\n fail: colors.red(supported ? '\u2716' : '\u00D7'),\n info: colors.blue(supported ? '\u2139' : 'i'),\n success: colors.green(supported ? '\u2714' : '\u221A'),\n warn: colors.yellow(supported ? '\u26A0' : '\u203C'),\n })\n objectFreeze(target)\n // The handler of a Proxy is mutable after proxy instantiation.\n // We delete the traps to defer to native behavior.\n for (const trapName in handler) {\n delete handler[trapName as keyof ProxyHandler<Record<string, string>>]\n }\n }\n for (const trapName of Reflect.ownKeys(Reflect)) {\n const fn = (Reflect as Record<PropertyKey, unknown>)[trapName]\n if (typeof fn === 'function') {\n ;(handler as Record<string, (...args: unknown[]) => unknown>)[\n trapName as string\n ] = (...args: unknown[]) => {\n init()\n return fn(...args)\n }\n }\n }\n return new Proxy(target, handler)\n})()\n\nconst boundConsoleEntries = [\n // Add bound properties from console[kBindProperties](ignoreErrors, colorMode, groupIndentation).\n // https://github.com/nodejs/node/blob/v24.0.1/lib/internal/console/constructor.js#L230-L265\n '_stderrErrorHandler',\n '_stdoutErrorHandler',\n // Add methods that need to be bound to function properly.\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'createTask',\n 'debug',\n 'dir',\n 'dirxml',\n 'error',\n // Skip group methods because in at least Node 20 with the Node --frozen-intrinsics\n // flag it triggers a readonly property for Symbol(kGroupIndent). Instead, we\n // implement these methods ourselves.\n //'group',\n //'groupCollapsed',\n //'groupEnd',\n 'info',\n 'log',\n 'table',\n 'time',\n 'timeEnd',\n 'timeLog',\n 'trace',\n 'warn',\n]\n .filter(n => typeof (globalConsole as any)[n] === 'function')\n .map(n => [n, (globalConsole as any)[n].bind(globalConsole)])\n\nconst consolePropAttributes = {\n __proto__: null,\n writable: true,\n enumerable: false,\n configurable: true,\n}\nconst maxIndentation = 1000\nconst privateConsole = new WeakMap()\n\nconst consoleSymbols = Object.getOwnPropertySymbols(globalConsole)\nexport const incLogCallCountSymbol = Symbol.for('logger.logCallCount++')\nconst kGroupIndentationWidthSymbol =\n consoleSymbols.find(s => (s as any).label === 'kGroupIndentWidth') ??\n Symbol('kGroupIndentWidth')\nexport const lastWasBlankSymbol = Symbol.for('logger.lastWasBlank')\n\n/**\n * Custom Logger class that wraps console with additional features.\n * Supports indentation, symbols, and blank line tracking.\n */\n/*@__PURE__*/\nexport class Logger {\n static LOG_SYMBOLS = LOG_SYMBOLS\n\n #parent?: Logger\n #boundStream?: 'stderr' | 'stdout'\n #stderrLogger?: Logger\n #stdoutLogger?: Logger\n #stderrIndention = ''\n #stdoutIndention = ''\n #lastWasBlank = false\n #logCallCount = 0\n #constructorArgs: unknown[]\n #options: Record<string, unknown>\n\n constructor(...args: unknown[]) {\n // Store constructor args for child loggers\n this.#constructorArgs = args\n\n // Store options if provided (for future extensibility)\n const options = args['0']\n if (typeof options === 'object' && options !== null) {\n this.#options = { __proto__: null, ...options }\n } else {\n this.#options = { __proto__: null }\n }\n\n if (args.length) {\n privateConsole.set(this, constructConsole(...args))\n } else {\n // Create a new console that acts like the builtin one so that it will\n // work with Node's --frozen-intrinsics flag.\n const con = constructConsole({\n stdout: process.stdout,\n stderr: process.stderr,\n }) as typeof console & Record<string, unknown>\n for (const { 0: key, 1: method } of boundConsoleEntries) {\n con[key] = method\n }\n privateConsole.set(this, con)\n }\n }\n\n /**\n * Get a logger instance bound to stderr.\n * All operations on this instance will use stderr.\n */\n get stderr(): Logger {\n if (!this.#stderrLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stderr'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stderrLogger = instance\n }\n return this.#stderrLogger\n }\n\n /**\n * Get a logger instance bound to stdout.\n * All operations on this instance will use stdout.\n */\n get stdout(): Logger {\n if (!this.#stdoutLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stdout'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stdoutLogger = instance\n }\n return this.#stdoutLogger\n }\n\n /**\n * Get the root logger (for accessing shared indentation state).\n * @private\n */\n #getRoot(): Logger {\n return this.#parent || this\n }\n\n /**\n * Get indentation for a specific stream.\n * @private\n */\n #getIndent(stream: 'stderr' | 'stdout'): string {\n const root = this.#getRoot()\n return stream === 'stderr' ? root.#stderrIndention : root.#stdoutIndention\n }\n\n /**\n * Set indentation for a specific stream.\n * @private\n */\n #setIndent(stream: 'stderr' | 'stdout', value: string): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrIndention = value\n } else {\n root.#stdoutIndention = value\n }\n }\n\n /**\n * Get the target stream for this logger instance.\n * @private\n */\n #getTargetStream(): 'stderr' | 'stdout' {\n return this.#boundStream || 'stderr'\n }\n\n /**\n * Apply a console method with indentation.\n * @private\n */\n #apply(\n methodName: string,\n args: unknown[],\n stream?: 'stderr' | 'stdout',\n ): this {\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n const text = args.at(0)\n const hasText = typeof text === 'string'\n // Determine which stream this method writes to\n const targetStream = stream || (methodName === 'log' ? 'stdout' : 'stderr')\n const indent = this.#getIndent(targetStream)\n const logArgs = hasText\n ? [applyLinePrefix(text, { prefix: indent }), ...args.slice(1)]\n : args\n ReflectApply(\n con[methodName] as (...args: unknown[]) => unknown,\n con,\n logArgs,\n )\n this[lastWasBlankSymbol](hasText && isBlankString(logArgs[0]))\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Strip log symbols from the start of text.\n * @private\n */\n #stripSymbols(text: string): string {\n // Strip both unicode and emoji forms of log symbols from the start.\n // Matches: \u2716, \u2717, \u00D7, \u2716\uFE0F, \u26A0, \u203C, \u26A0\uFE0F, \u2714, \u2713, \u221A, \u2714\uFE0F, \u2713\uFE0F, \u2139, \u2139\uFE0F\n // Also handles variation selectors (U+FE0F) and whitespace after symbol.\n // Note: We don't strip standalone 'i' to avoid breaking words like 'info'.\n return text.replace(/^[\u2716\u2717\u00D7\u26A0\u203C\u2714\u2713\u221A\u2139]\\uFE0F?\\s*/u, '')\n }\n\n /**\n * Apply a method with a symbol prefix.\n * @private\n */\n #symbolApply(symbolType: string, args: unknown[]): this {\n const con = privateConsole.get(this)\n let text = args.at(0)\n // biome-ignore lint/suspicious/noImplicitAnyLet: Flexible argument handling.\n let extras\n if (typeof text === 'string') {\n text = this.#stripSymbols(text)\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n // Note: Meta status messages (info/fail/etc) always go to stderr.\n const indent = this.#getIndent('stderr')\n con.error(\n applyLinePrefix(`${LOG_SYMBOLS[symbolType]} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this.#lastWasBlank = false\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Get the current log call count.\n */\n get logCallCount() {\n return this.#logCallCount\n }\n\n /**\n * Increment the log call count.\n */\n [incLogCallCountSymbol]() {\n this.#logCallCount += 1\n return this\n }\n\n /**\n * Set whether the last logged line was blank.\n */\n [lastWasBlankSymbol](value: unknown): this {\n this.#lastWasBlank = !!value\n return this\n }\n\n /**\n * Log an assertion.\n */\n assert(value: unknown, ...message: unknown[]): this {\n const con = privateConsole.get(this)\n con.assert(value, ...message)\n this[lastWasBlankSymbol](false)\n return value ? this : this[incLogCallCountSymbol]()\n }\n\n /**\n * Clear the visible terminal screen.\n * Only available on the main logger instance.\n */\n clearVisible() {\n if (this.#boundStream) {\n throw new Error(\n 'clearVisible() is only available on the main logger instance, not on stream-bound instances',\n )\n }\n const con = privateConsole.get(this)\n con.clear()\n if ((con as any)._stdout.isTTY) {\n ;(this as any)[lastWasBlankSymbol](true)\n this.#logCallCount = 0\n }\n return this\n }\n\n /**\n * Log a count for the given label.\n */\n count(label?: string): this {\n const con = privateConsole.get(this)\n con.count(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Create a task with a given name.\n */\n createTask(name: string): Task {\n return {\n run: <T>(f: () => T): T => {\n this.log(`Starting task: ${name}`)\n const result = f()\n this.log(`Completed task: ${name}`)\n return result\n },\n }\n }\n\n /**\n * Decrease indentation level.\n * If called on main logger, affects both streams.\n * If called on stream-bound logger, affects only that stream.\n */\n dedent(spaces = 2) {\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current.slice(0, -spaces))\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent.slice(0, -spaces))\n this.#setIndent('stdout', stdoutCurrent.slice(0, -spaces))\n }\n return this\n }\n\n /**\n * Display an object's properties.\n */\n dir(obj: unknown, options?: unknown): this {\n const con = privateConsole.get(this)\n con.dir(obj, options)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Display data as XML.\n */\n dirxml(...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.dirxml(data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log an error message.\n */\n error(...args: unknown[]): this {\n return this.#apply('error', args)\n }\n\n /**\n * Log a newline to stderr if last line wasn't blank.\n */\n errorNewline() {\n return this.#lastWasBlank ? this : this.error('')\n }\n\n /**\n * Log a failure message with symbol.\n */\n fail(...args: unknown[]): this {\n return this.#symbolApply('fail', args)\n }\n\n /**\n * Start a new log group.\n */\n group(...label: unknown[]): this {\n const { length } = label\n if (length) {\n ReflectApply(this.log, this, label)\n }\n this.indent((this as any)[kGroupIndentationWidthSymbol])\n if (length) {\n ;(this as any)[lastWasBlankSymbol](false)\n ;(this as any)[incLogCallCountSymbol]()\n }\n return this\n }\n\n /**\n * Start a new collapsed log group (alias for group).\n */\n // groupCollapsed is an alias of group.\n // https://nodejs.org/api/console.html#consolegroupcollapsed\n groupCollapsed(...label: unknown[]): this {\n return ReflectApply(this.group, this, label)\n }\n\n /**\n * End the current log group.\n */\n groupEnd() {\n this.dedent((this as any)[kGroupIndentationWidthSymbol])\n return this\n }\n\n /**\n * Increase indentation level.\n * If called on main logger, affects both streams.\n * If called on stream-bound logger, affects only that stream.\n */\n indent(spaces = 2) {\n const spacesToAdd = ' '.repeat(Math.min(spaces, maxIndentation))\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current + spacesToAdd)\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent + spacesToAdd)\n this.#setIndent('stdout', stdoutCurrent + spacesToAdd)\n }\n return this\n }\n\n /**\n * Log an info message with symbol.\n */\n info(...args: unknown[]): this {\n return this.#symbolApply('info', args)\n }\n\n /**\n * Log a message.\n */\n log(...args: unknown[]): this {\n return this.#apply('log', args)\n }\n\n /**\n * Log a newline to stdout if last line wasn't blank.\n */\n logNewline() {\n return this.#lastWasBlank ? this : this.log('')\n }\n\n /**\n * Reset indentation to zero.\n * If called on main logger, resets both streams.\n * If called on stream-bound logger, resets only that stream.\n */\n resetIndent() {\n if (this.#boundStream) {\n // Only reset bound stream\n this.#setIndent(this.#boundStream, '')\n } else {\n // Reset both streams\n this.#setIndent('stderr', '')\n this.#setIndent('stdout', '')\n }\n return this\n }\n\n /**\n * Log a main step with blank line before (stateless).\n */\n step(msg: string, ...extras: unknown[]): this {\n // Add blank line before the step message.\n if (!this.#lastWasBlank) {\n // Use this.log() to properly track the blank line.\n this.log('')\n }\n // Let log() handle all tracking.\n return this.log(msg, ...extras)\n }\n\n /**\n * Log an indented substep (stateless).\n */\n substep(msg: string, ...extras: unknown[]): this {\n // Add 2-space indent to the message.\n const indentedMsg = ` ${msg}`\n // Let log() handle all tracking.\n return this.log(indentedMsg, ...extras)\n }\n\n /**\n * Log a success message with symbol.\n */\n success(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Log a done message (alias for success).\n * Does NOT auto-clear. Call clearLine() first if needed after progress().\n */\n done(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Display data in a table format.\n */\n table(tabularData: unknown, properties?: readonly string[]): this {\n const con = privateConsole.get(this)\n con.table(tabularData, properties)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * End a timer and log the elapsed time.\n */\n timeEnd(label?: string): this {\n const con = privateConsole.get(this)\n con.timeEnd(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log the current timer value.\n */\n timeLog(label?: string, ...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.timeLog(label, ...data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log a stack trace.\n */\n trace(message?: unknown, ...args: unknown[]): this {\n const con = privateConsole.get(this)\n con.trace(message, ...args)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Log a warning message with symbol.\n */\n warn(...args: unknown[]): this {\n return this.#symbolApply('warn', args)\n }\n\n /**\n * Write to stdout without a newline or indentation.\n */\n write(text: string): this {\n const con = privateConsole.get(this)\n con._stdout.write(text)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Show a progress indicator (can be cleared with clearLine).\n * Simple status message without spinner animation.\n */\n progress(text: string): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n streamObj.write(`\u2234 ${text}`)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Clear the current line.\n */\n clearLine(): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n if (streamObj.isTTY) {\n streamObj.cursorTo(0)\n streamObj.clearLine(0)\n } else {\n streamObj.write('\\r\\x1b[K')\n }\n return this\n }\n}\n\nObject.defineProperties(\n Logger.prototype,\n Object.fromEntries(\n (() => {\n const entries: Array<[string | symbol, PropertyDescriptor]> = [\n [\n kGroupIndentationWidthSymbol,\n {\n ...consolePropAttributes,\n value: 2,\n },\n ],\n [\n Symbol.toStringTag,\n {\n __proto__: null,\n configurable: true,\n value: 'logger',\n } as PropertyDescriptor,\n ],\n ]\n for (const { 0: key, 1: value } of Object.entries(globalConsole)) {\n if (!(Logger.prototype as any)[key] && typeof value === 'function') {\n // Dynamically name the log method without using Object.defineProperty.\n const { [key]: func } = {\n [key](...args: unknown[]) {\n const con = privateConsole.get(this)\n const result = (con as any)[key](...args)\n return result === undefined || result === con ? this : result\n },\n }\n entries.push([\n key,\n {\n ...consolePropAttributes,\n value: func,\n },\n ])\n }\n }\n return entries\n })(),\n ),\n)\n\nexport const logger = new Logger()\n"],
5
+ "mappings": "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",
6
6
  "names": ["yoctocolorsCjs", "isUnicodeSupported"]
7
7
  }
@@ -7,7 +7,7 @@ export interface RetryOptions {
7
7
  maxDelayMs?: number;
8
8
  maxTimeout?: number;
9
9
  minTimeout?: number;
10
- onRetry?: (attempt: number, error: unknown, delay: number) => boolean | undefined;
10
+ onRetry?: (attempt: number, error: unknown, delay: number) => boolean | number | undefined;
11
11
  onRetryCancelOnFalse?: boolean;
12
12
  onRetryRethrow?: boolean;
13
13
  retries?: number;
package/dist/promises.js CHANGED
@@ -232,6 +232,9 @@ async function pRetry(callbackFn, options) {
232
232
  if (result === false && onRetryCancelOnFalse) {
233
233
  break;
234
234
  }
235
+ if (typeof result === "number" && result >= 0) {
236
+ waitTime = Math.min(result, maxDelayMs);
237
+ }
235
238
  } catch (e2) {
236
239
  if (onRetryRethrow) {
237
240
  throw e2;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/promises.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Promise utilities including chunked iteration and timers.\n * Provides async control flow helpers and promise-based timing functions.\n */\n\nimport { UNDEFINED_TOKEN } from '#constants/core'\nimport { getAbortSignal } from '#constants/process'\n\nimport { arrayChunk } from './arrays'\n\nconst abortSignal = getAbortSignal()\n\nexport interface RetryOptions {\n args?: unknown[]\n backoffFactor?: number\n baseDelayMs?: number\n factor?: number\n jitter?: boolean\n maxDelayMs?: number\n maxTimeout?: number\n minTimeout?: number\n onRetry?: (\n attempt: number,\n error: unknown,\n delay: number,\n ) => boolean | undefined\n onRetryCancelOnFalse?: boolean\n onRetryRethrow?: boolean\n retries?: number\n signal?: AbortSignal\n}\n\nexport interface IterationOptions {\n concurrency?: number\n retries?: number | RetryOptions\n signal?: AbortSignal\n}\n\nlet _timers: typeof import('node:timers/promises') | undefined\n/**\n * Get the timers/promises module.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getTimers() {\n if (_timers === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _timers = /*@__PURE__*/ require('node:timers/promises')\n }\n return _timers as typeof import('node:timers/promises')\n}\n\n/**\n * Normalize options for iteration functions.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeIterationOptions(\n options?: number | IterationOptions,\n): { concurrency: number; retries: RetryOptions; signal: AbortSignal } {\n // Handle number as concurrency shorthand\n const opts = typeof options === 'number' ? { concurrency: options } : options\n\n const {\n // The number of concurrent executions performed at one time.\n concurrency = 1,\n // Retries as a number or options object.\n retries,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = { __proto__: null, ...opts } as IterationOptions\n\n // Ensure concurrency is at least 1\n const normalizedConcurrency = Math.max(1, concurrency)\n const retryOpts = resolveRetryOptions(retries)\n return {\n __proto__: null,\n concurrency: normalizedConcurrency,\n retries: normalizeRetryOptions({ signal, ...retryOpts }),\n signal,\n } as { concurrency: number; retries: RetryOptions; signal: AbortSignal }\n}\n\n/**\n * Normalize options for retry functionality.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const resolved = resolveRetryOptions(options)\n const {\n // Arguments to pass to the callback function.\n args = [],\n // Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n backoffFactor = resolved.factor || 2,\n // Initial delay before the first retry (in milliseconds).\n baseDelayMs = resolved.minTimeout || 200,\n // Whether to apply randomness to spread out retries.\n jitter = true,\n // Upper limit for any backoff delay (in milliseconds).\n maxDelayMs = resolved.maxTimeout || 10_000,\n // Optional callback invoked on each retry attempt:\n // (attempt: number, error: unknown, delay: number) => void\n onRetry,\n // Whether onRetry can cancel retries by returning `false`.\n onRetryCancelOnFalse = false,\n // Whether onRetry will rethrow errors.\n onRetryRethrow = false,\n // Number of retry attempts (0 = no retries, only initial attempt).\n retries = resolved.retries || 0,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = resolved\n return {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n minTimeout: baseDelayMs,\n maxTimeout: maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } as RetryOptions\n}\n\n/**\n * Resolve retry options from various input formats.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const defaults = {\n __proto__: null,\n retries: 0,\n minTimeout: 200,\n maxTimeout: 10_000,\n factor: 2,\n }\n\n if (typeof options === 'number') {\n return { ...defaults, retries: options }\n }\n\n return options ? { ...defaults, ...options } : defaults\n}\n\n/**\n * Execute an async function for each array element with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEach<T>(\n array: T[],\n callbackFn: (item: T) => Promise<unknown>,\n options?: number | IterationOptions,\n): Promise<void> {\n const iterOpts = normalizeIterationOptions(options)\n const { concurrency, retries, signal } = iterOpts\n\n // Process items with concurrency control.\n const chunks = arrayChunk(array, concurrency)\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // Process each item in the chunk concurrently.\n // eslint-disable-next-line no-await-in-loop\n await Promise.all(\n chunk.map((item: T) =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retries,\n args: [item],\n signal,\n }),\n ),\n )\n }\n}\n\n/**\n * Filter an array asynchronously with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilter<T>(\n array: T[],\n callbackFn: (item: T) => Promise<boolean>,\n options?: number | IterationOptions,\n): Promise<T[]> {\n const iterOpts = normalizeIterationOptions(options)\n return (\n await pFilterChunk(\n arrayChunk(array, iterOpts.concurrency),\n callbackFn,\n iterOpts.retries,\n )\n ).flat()\n}\n\n/**\n * Process array in chunks with an async callback.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEachChunk<T>(\n array: T[],\n callbackFn: (chunk: T[]) => Promise<unknown>,\n options?: RetryOptions & { chunkSize?: number },\n): Promise<void> {\n const { chunkSize = 100, ...retryOpts } = options || {}\n const chunks = arrayChunk(array, chunkSize)\n const normalizedRetryOpts = normalizeRetryOptions(retryOpts)\n const { signal } = normalizedRetryOpts\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n await pRetry((...args: unknown[]) => callbackFn(args[0] as T[]), {\n ...normalizedRetryOpts,\n args: [chunk],\n })\n }\n}\n\n/**\n * Filter chunked arrays with an async predicate.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilterChunk<T>(\n chunks: T[][],\n callbackFn: (value: T) => Promise<boolean>,\n options?: number | RetryOptions,\n): Promise<T[][]> {\n const retryOpts = normalizeRetryOptions(options)\n const { signal } = retryOpts\n const { length } = chunks\n const filteredChunks = Array(length)\n for (let i = 0; i < length; i += 1) {\n // Process each chunk, filtering based on the callback function.\n if (signal?.aborted) {\n filteredChunks[i] = []\n } else {\n const chunk = chunks[i] as T[]\n // eslint-disable-next-line no-await-in-loop\n const predicateResults = await Promise.all(\n chunk.map(value =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retryOpts,\n args: [value],\n }),\n ),\n )\n filteredChunks[i] = chunk.filter((_v, i) => predicateResults[i])\n }\n }\n return filteredChunks\n}\n\n/**\n * Retry an async function with exponential backoff.\n * @throws {Error} The last error if all retries fail.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pRetry<T>(\n callbackFn: (...args: unknown[]) => Promise<T>,\n options?: number | RetryOptions,\n): Promise<T | undefined> {\n const {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } = normalizeRetryOptions(options)\n if (signal?.aborted) {\n return undefined\n }\n if (retries === 0) {\n return await callbackFn(...(args || []), { signal })\n }\n\n const timers = getTimers()\n\n let attempts = retries as number\n let delay = baseDelayMs as number\n let error: unknown = UNDEFINED_TOKEN\n\n while (attempts-- >= 0) {\n // Check abort before attempt.\n if (signal?.aborted) {\n return undefined\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n return await callbackFn(...(args || []), { signal })\n } catch (e) {\n if (error === UNDEFINED_TOKEN) {\n error = e\n }\n if (attempts < 0) {\n break\n }\n let waitTime = delay\n if (jitter) {\n // Add randomness: Pick a value between 0 and `delay`.\n waitTime += Math.floor(Math.random() * delay)\n }\n // Clamp wait time to max delay.\n waitTime = Math.min(waitTime, maxDelayMs as number)\n if (typeof onRetry === 'function') {\n try {\n const result = onRetry((retries as number) - attempts, e, waitTime)\n if (result === false && onRetryCancelOnFalse) {\n break\n }\n } catch (e) {\n if (onRetryRethrow) {\n throw e\n }\n }\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n await timers.setTimeout(waitTime, undefined, { signal })\n } catch {\n // setTimeout was aborted.\n return undefined\n }\n\n // Check abort again after delay.\n if (signal?.aborted) {\n return undefined\n }\n\n // Exponentially increase the delay for the next attempt, capping at maxDelayMs.\n delay = Math.min(delay * (backoffFactor as number), maxDelayMs as number)\n }\n }\n if (error !== UNDEFINED_TOKEN) {\n throw error\n }\n return undefined\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @fileoverview Promise utilities including chunked iteration and timers.\n * Provides async control flow helpers and promise-based timing functions.\n */\n\nimport { UNDEFINED_TOKEN } from '#constants/core'\nimport { getAbortSignal } from '#constants/process'\n\nimport { arrayChunk } from './arrays'\n\nconst abortSignal = getAbortSignal()\n\nexport interface RetryOptions {\n args?: unknown[]\n backoffFactor?: number\n baseDelayMs?: number\n factor?: number\n jitter?: boolean\n maxDelayMs?: number\n maxTimeout?: number\n minTimeout?: number\n onRetry?: (\n attempt: number,\n error: unknown,\n delay: number,\n ) => boolean | number | undefined\n onRetryCancelOnFalse?: boolean\n onRetryRethrow?: boolean\n retries?: number\n signal?: AbortSignal\n}\n\nexport interface IterationOptions {\n concurrency?: number\n retries?: number | RetryOptions\n signal?: AbortSignal\n}\n\nlet _timers: typeof import('node:timers/promises') | undefined\n/**\n * Get the timers/promises module.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getTimers() {\n if (_timers === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _timers = /*@__PURE__*/ require('node:timers/promises')\n }\n return _timers as typeof import('node:timers/promises')\n}\n\n/**\n * Normalize options for iteration functions.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeIterationOptions(\n options?: number | IterationOptions,\n): { concurrency: number; retries: RetryOptions; signal: AbortSignal } {\n // Handle number as concurrency shorthand\n const opts = typeof options === 'number' ? { concurrency: options } : options\n\n const {\n // The number of concurrent executions performed at one time.\n concurrency = 1,\n // Retries as a number or options object.\n retries,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = { __proto__: null, ...opts } as IterationOptions\n\n // Ensure concurrency is at least 1\n const normalizedConcurrency = Math.max(1, concurrency)\n const retryOpts = resolveRetryOptions(retries)\n return {\n __proto__: null,\n concurrency: normalizedConcurrency,\n retries: normalizeRetryOptions({ signal, ...retryOpts }),\n signal,\n } as { concurrency: number; retries: RetryOptions; signal: AbortSignal }\n}\n\n/**\n * Normalize options for retry functionality.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const resolved = resolveRetryOptions(options)\n const {\n // Arguments to pass to the callback function.\n args = [],\n // Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n backoffFactor = resolved.factor || 2,\n // Initial delay before the first retry (in milliseconds).\n baseDelayMs = resolved.minTimeout || 200,\n // Whether to apply randomness to spread out retries.\n jitter = true,\n // Upper limit for any backoff delay (in milliseconds).\n maxDelayMs = resolved.maxTimeout || 10_000,\n // Optional callback invoked on each retry attempt:\n // (attempt: number, error: unknown, delay: number) => void\n onRetry,\n // Whether onRetry can cancel retries by returning `false`.\n onRetryCancelOnFalse = false,\n // Whether onRetry will rethrow errors.\n onRetryRethrow = false,\n // Number of retry attempts (0 = no retries, only initial attempt).\n retries = resolved.retries || 0,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = resolved\n return {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n minTimeout: baseDelayMs,\n maxTimeout: maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } as RetryOptions\n}\n\n/**\n * Resolve retry options from various input formats.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const defaults = {\n __proto__: null,\n retries: 0,\n minTimeout: 200,\n maxTimeout: 10_000,\n factor: 2,\n }\n\n if (typeof options === 'number') {\n return { ...defaults, retries: options }\n }\n\n return options ? { ...defaults, ...options } : defaults\n}\n\n/**\n * Execute an async function for each array element with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEach<T>(\n array: T[],\n callbackFn: (item: T) => Promise<unknown>,\n options?: number | IterationOptions,\n): Promise<void> {\n const iterOpts = normalizeIterationOptions(options)\n const { concurrency, retries, signal } = iterOpts\n\n // Process items with concurrency control.\n const chunks = arrayChunk(array, concurrency)\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // Process each item in the chunk concurrently.\n // eslint-disable-next-line no-await-in-loop\n await Promise.all(\n chunk.map((item: T) =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retries,\n args: [item],\n signal,\n }),\n ),\n )\n }\n}\n\n/**\n * Filter an array asynchronously with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilter<T>(\n array: T[],\n callbackFn: (item: T) => Promise<boolean>,\n options?: number | IterationOptions,\n): Promise<T[]> {\n const iterOpts = normalizeIterationOptions(options)\n return (\n await pFilterChunk(\n arrayChunk(array, iterOpts.concurrency),\n callbackFn,\n iterOpts.retries,\n )\n ).flat()\n}\n\n/**\n * Process array in chunks with an async callback.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEachChunk<T>(\n array: T[],\n callbackFn: (chunk: T[]) => Promise<unknown>,\n options?: RetryOptions & { chunkSize?: number },\n): Promise<void> {\n const { chunkSize = 100, ...retryOpts } = options || {}\n const chunks = arrayChunk(array, chunkSize)\n const normalizedRetryOpts = normalizeRetryOptions(retryOpts)\n const { signal } = normalizedRetryOpts\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n await pRetry((...args: unknown[]) => callbackFn(args[0] as T[]), {\n ...normalizedRetryOpts,\n args: [chunk],\n })\n }\n}\n\n/**\n * Filter chunked arrays with an async predicate.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilterChunk<T>(\n chunks: T[][],\n callbackFn: (value: T) => Promise<boolean>,\n options?: number | RetryOptions,\n): Promise<T[][]> {\n const retryOpts = normalizeRetryOptions(options)\n const { signal } = retryOpts\n const { length } = chunks\n const filteredChunks = Array(length)\n for (let i = 0; i < length; i += 1) {\n // Process each chunk, filtering based on the callback function.\n if (signal?.aborted) {\n filteredChunks[i] = []\n } else {\n const chunk = chunks[i] as T[]\n // eslint-disable-next-line no-await-in-loop\n const predicateResults = await Promise.all(\n chunk.map(value =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retryOpts,\n args: [value],\n }),\n ),\n )\n filteredChunks[i] = chunk.filter((_v, i) => predicateResults[i])\n }\n }\n return filteredChunks\n}\n\n/**\n * Retry an async function with exponential backoff.\n * @throws {Error} The last error if all retries fail.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pRetry<T>(\n callbackFn: (...args: unknown[]) => Promise<T>,\n options?: number | RetryOptions,\n): Promise<T | undefined> {\n const {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } = normalizeRetryOptions(options)\n if (signal?.aborted) {\n return undefined\n }\n if (retries === 0) {\n return await callbackFn(...(args || []), { signal })\n }\n\n const timers = getTimers()\n\n let attempts = retries as number\n let delay = baseDelayMs as number\n let error: unknown = UNDEFINED_TOKEN\n\n while (attempts-- >= 0) {\n // Check abort before attempt.\n if (signal?.aborted) {\n return undefined\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n return await callbackFn(...(args || []), { signal })\n } catch (e) {\n if (error === UNDEFINED_TOKEN) {\n error = e\n }\n if (attempts < 0) {\n break\n }\n let waitTime = delay\n if (jitter) {\n // Add randomness: Pick a value between 0 and `delay`.\n waitTime += Math.floor(Math.random() * delay)\n }\n // Clamp wait time to max delay.\n waitTime = Math.min(waitTime, maxDelayMs as number)\n if (typeof onRetry === 'function') {\n try {\n const result = onRetry((retries as number) - attempts, e, waitTime)\n if (result === false && onRetryCancelOnFalse) {\n break\n }\n // If onRetry returns a number, use it as the custom delay.\n if (typeof result === 'number' && result >= 0) {\n waitTime = Math.min(result, maxDelayMs as number)\n }\n } catch (e) {\n if (onRetryRethrow) {\n throw e\n }\n }\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n await timers.setTimeout(waitTime, undefined, { signal })\n } catch {\n // setTimeout was aborted.\n return undefined\n }\n\n // Check abort again after delay.\n if (signal?.aborted) {\n return undefined\n }\n\n // Exponentially increase the delay for the next attempt, capping at maxDelayMs.\n delay = Math.min(delay * (backoffFactor as number), maxDelayMs as number)\n }\n }\n if (error !== UNDEFINED_TOKEN) {\n throw error\n }\n return undefined\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["i", "e"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/signal-exit.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Process signal handling utilities.\n * Provides cross-platform signal exit detection and cleanup handlers.\n */\n\n// Inlined signal-exit:\n// https://socket.dev/npm/package/signal-exit/overview/4.1.0\n// ISC License\n// Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors\n\n// This is not the set of all possible signals.\n//\n// It IS, however, the set of all signals that trigger\n// an exit on either Linux or BSD systems. Linux is a\n// superset of the signal names supported on BSD, and\n// the unknown signals just fail to register, so we can\n// catch that easily enough.\n//\n// Don't bother with SIGKILL. It's uncatchable, which\n// means that we can't fire any callbacks anyway.\n//\n// If a user does happen to register a handler on a non-\n// fatal signal like SIGWINCH or something, and then\n// exit, it'll end up firing `process.emit('exit')`, so\n// the handler will be fired anyway.\n//\n// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n// artificially, inherently leave the process in a\n// state from which it is not safe to try and enter JS\n// listeners.\n\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst globalProcess = globalThis.process as\n | (NodeJS.Process & {\n // biome-ignore lint/suspicious/noExplicitAny: Signal exit emitter can be any event emitter.\n __signal_exit_emitter__?: any\n reallyExit?: (code?: number | undefined) => never\n })\n | undefined\nconst originalProcessEmit = globalProcess?.emit\nconst platform = globalProcess?.platform ?? ''\nconst originalProcessReallyExit = globalProcess?.reallyExit as\n | ((code?: number | undefined) => never)\n | undefined\nconst WIN32 = platform === 'win32'\n\nlet _events: typeof import('node:events') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getEvents() {\n if (_events === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _events = /*@__PURE__*/ require('node:events')\n }\n return _events as typeof import('node:events')\n}\n\n// Type for tracking emitted signals.\ntype EmittedSignals = {\n // Using string as signals can include custom events like 'exit' and 'afterexit'.\n [signal: string]: boolean\n}\n\ntype SignalExitEmitter = import('node:events').EventEmitter & {\n count?: number\n emitted?: EmittedSignals\n infinite?: boolean\n}\nlet _emitter: SignalExitEmitter | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getEmitter() {\n if (_emitter === undefined) {\n if (globalProcess?.__signal_exit_emitter__) {\n _emitter = globalProcess.__signal_exit_emitter__\n } else if (globalProcess) {\n const EventEmitter = getEvents().EventEmitter\n _emitter = globalProcess.__signal_exit_emitter__ =\n new EventEmitter() as SignalExitEmitter\n _emitter.count = 0\n _emitter.emitted = { __proto__: null } as unknown as EmittedSignals\n }\n // Because this emitter is a global, we have to check to see if a\n // previous version of this library failed to enable infinite listeners.\n // I know what you're about to say. But literally everything about\n // signal-exit is a compromise with evil. Get used to it.\n if (_emitter && !_emitter.infinite) {\n _emitter.setMaxListeners(Number.POSITIVE_INFINITY)\n _emitter.infinite = true\n }\n }\n return _emitter as SignalExitEmitter\n}\n\ntype SignalListener = () => void\n// Type for signal listeners indexed by signal name.\ntype SignalListenerMap = {\n [signal: string]: SignalListener\n}\nlet _sigListeners: SignalListenerMap | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getSignalListeners() {\n if (_sigListeners === undefined) {\n _sigListeners = { __proto__: null } as unknown as SignalListenerMap\n const emitter = getEmitter()\n const sigs = getSignals()\n for (const sig of sigs) {\n _sigListeners[sig] = function listener() {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = globalProcess?.listeners(sig as NodeJS.Signals) || []\n if (listeners.length === emitter.count) {\n unload()\n emit('exit', null, sig)\n emit('afterexit', null, sig)\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead.\n const killSig = WIN32 && sig === 'SIGHUP' ? 'SIGINT' : sig\n globalProcess?.kill(globalProcess?.pid, killSig)\n }\n }\n }\n }\n return _sigListeners as SignalListenerMap\n}\n\nlet _signals: string[] | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getSignals() {\n if (_signals === undefined) {\n _signals = ['SIGABRT', 'SIGALRM', 'SIGHUP', 'SIGINT', 'SIGTERM']\n if (!WIN32) {\n _signals.push(\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT',\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n }\n if (platform === 'linux') {\n _signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT', 'SIGUNUSED')\n }\n }\n return _signals as string[]\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction emit(event: string, code: number | null, signal: string | null): void {\n const emitter = getEmitter()\n if (emitter.emitted?.[event]) {\n return\n }\n if (emitter.emitted) {\n emitter.emitted[event] = true\n }\n emitter.emit(event, code, signal)\n}\n\nlet loaded = false\n\n/**\n * Load signal handlers and hook into process exit events.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function load(): void {\n if (loaded || !globalProcess) {\n return\n }\n loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n const emitter = getEmitter()\n if (emitter.count !== undefined) {\n emitter.count += 1\n }\n\n const sigs = getSignals()\n const sigListeners = getSignalListeners()\n _signals = sigs.filter(sig => {\n try {\n globalProcess.on(\n sig as NodeJS.Signals,\n sigListeners[sig] as SignalListener,\n )\n return true\n } catch {}\n return false\n })\n\n globalProcess.emit = processEmit as typeof globalProcess.emit\n globalProcess.reallyExit = processReallyExit\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction processEmit(\n this: NodeJS.Process,\n eventName: string,\n exitCode?: number | undefined,\n // biome-ignore lint/suspicious/noExplicitAny: Process emit args can be any type.\n ...args: any[]\n): boolean {\n if (eventName === 'exit') {\n let actualExitCode = exitCode\n if (actualExitCode === undefined) {\n const processExitCode = globalProcess?.exitCode\n actualExitCode =\n typeof processExitCode === 'number' ? processExitCode : undefined\n } else if (globalProcess) {\n globalProcess.exitCode = actualExitCode\n }\n const result = ReflectApply(\n originalProcessEmit as (...args: unknown[]) => boolean,\n this,\n [eventName, actualExitCode, ...args],\n ) as boolean\n const numExitCode =\n typeof actualExitCode === 'number' ? actualExitCode : null\n emit('exit', numExitCode, null)\n emit('afterexit', numExitCode, null)\n return result\n }\n return ReflectApply(\n originalProcessEmit as (...args: unknown[]) => boolean,\n this,\n [eventName, exitCode, ...args],\n ) as boolean\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction processReallyExit(code?: number | undefined): never {\n const exitCode = code || 0\n if (globalProcess) {\n globalProcess.exitCode = exitCode\n }\n emit('exit', exitCode, null)\n emit('afterexit', exitCode, null)\n ReflectApply(\n originalProcessReallyExit as (code?: number) => never,\n globalProcess,\n [exitCode],\n )\n throw new Error('processReallyExit should never return')\n}\n\nexport interface OnExitOptions {\n alwaysLast?: boolean\n}\n\n/**\n * Register a callback to run on process exit or signal.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function onExit(\n cb: (code: number | null, signal: string | null) => void,\n options?: OnExitOptions | undefined,\n): () => void {\n if (!globalProcess) {\n return function remove() {}\n }\n if (typeof cb !== 'function') {\n throw new TypeError('a callback must be provided for exit handler')\n }\n if (loaded === false) {\n load()\n }\n const { alwaysLast } = { __proto__: null, ...options } as OnExitOptions\n\n let eventName = 'exit'\n if (alwaysLast) {\n eventName = 'afterexit'\n }\n\n const emitter = getEmitter()\n emitter.on(eventName, cb)\n\n return function remove() {\n emitter.removeListener(eventName, cb)\n if (\n !emitter.listeners('exit').length &&\n !emitter.listeners('afterexit').length\n ) {\n unload()\n }\n }\n}\n\n/**\n * Get the list of signals that are currently being monitored.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function signals(): string[] | undefined {\n return _signals\n}\n\n/**\n * Unload signal handlers and restore original process behavior.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function unload(): void {\n if (!loaded || !globalProcess) {\n return\n }\n loaded = false\n\n const sigs = getSignals()\n const sigListeners = getSignalListeners()\n for (const sig of sigs) {\n try {\n globalProcess.removeListener(\n sig as NodeJS.Signals,\n sigListeners[sig] as SignalListener,\n )\n } catch {}\n }\n globalProcess.emit = originalProcessEmit as typeof globalProcess.emit\n if (originalProcessReallyExit !== undefined) {\n globalProcess.reallyExit = originalProcessReallyExit\n }\n const emitter = getEmitter()\n if (emitter.count !== undefined) {\n emitter.count -= 1\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @fileoverview Process signal handling utilities.\n * Provides cross-platform signal exit detection and cleanup handlers.\n */\n\n// Inlined signal-exit:\n// https://socket.dev/npm/package/signal-exit/overview/4.1.0\n// ISC License\n// Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors\n\n// This is not the set of all possible signals.\n//\n// It IS, however, the set of all signals that trigger\n// an exit on either Linux or BSD systems. Linux is a\n// superset of the signal names supported on BSD, and\n// the unknown signals just fail to register, so we can\n// catch that easily enough.\n//\n// Don't bother with SIGKILL. It's uncatchable, which\n// means that we can't fire any callbacks anyway.\n//\n// If a user does happen to register a handler on a non-\n// fatal signal like SIGWINCH or something, and then\n// exit, it'll end up firing `process.emit('exit')`, so\n// the handler will be fired anyway.\n//\n// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised\n// artificially, inherently leave the process in a\n// state from which it is not safe to try and enter JS\n// listeners.\n\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst globalProcess = globalThis.process as\n | (NodeJS.Process & {\n __signal_exit_emitter__?: any\n reallyExit?: (code?: number | undefined) => never\n })\n | undefined\nconst originalProcessEmit = globalProcess?.emit\nconst platform = globalProcess?.platform ?? ''\nconst originalProcessReallyExit = globalProcess?.reallyExit as\n | ((code?: number | undefined) => never)\n | undefined\nconst WIN32 = platform === 'win32'\n\nlet _events: typeof import('node:events') | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getEvents() {\n if (_events === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _events = /*@__PURE__*/ require('node:events')\n }\n return _events as typeof import('node:events')\n}\n\n// Type for tracking emitted signals.\ntype EmittedSignals = {\n // Using string as signals can include custom events like 'exit' and 'afterexit'.\n [signal: string]: boolean\n}\n\ntype SignalExitEmitter = import('node:events').EventEmitter & {\n count?: number\n emitted?: EmittedSignals\n infinite?: boolean\n}\nlet _emitter: SignalExitEmitter | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getEmitter() {\n if (_emitter === undefined) {\n if (globalProcess?.__signal_exit_emitter__) {\n _emitter = globalProcess.__signal_exit_emitter__\n } else if (globalProcess) {\n const EventEmitter = getEvents().EventEmitter\n _emitter = globalProcess.__signal_exit_emitter__ =\n new EventEmitter() as SignalExitEmitter\n _emitter.count = 0\n _emitter.emitted = { __proto__: null } as unknown as EmittedSignals\n }\n // Because this emitter is a global, we have to check to see if a\n // previous version of this library failed to enable infinite listeners.\n // I know what you're about to say. But literally everything about\n // signal-exit is a compromise with evil. Get used to it.\n if (_emitter && !_emitter.infinite) {\n _emitter.setMaxListeners(Number.POSITIVE_INFINITY)\n _emitter.infinite = true\n }\n }\n return _emitter as SignalExitEmitter\n}\n\ntype SignalListener = () => void\n// Type for signal listeners indexed by signal name.\ntype SignalListenerMap = {\n [signal: string]: SignalListener\n}\nlet _sigListeners: SignalListenerMap | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getSignalListeners() {\n if (_sigListeners === undefined) {\n _sigListeners = { __proto__: null } as unknown as SignalListenerMap\n const emitter = getEmitter()\n const sigs = getSignals()\n for (const sig of sigs) {\n _sigListeners[sig] = function listener() {\n // If there are no other listeners, an exit is coming!\n // Simplest way: remove us and then re-send the signal.\n // We know that this will kill the process, so we can\n // safely emit now.\n const listeners = globalProcess?.listeners(sig as NodeJS.Signals) || []\n if (listeners.length === emitter.count) {\n unload()\n emit('exit', null, sig)\n emit('afterexit', null, sig)\n // \"SIGHUP\" throws an `ENOSYS` error on Windows,\n // so use a supported signal instead.\n const killSig = WIN32 && sig === 'SIGHUP' ? 'SIGINT' : sig\n globalProcess?.kill(globalProcess?.pid, killSig)\n }\n }\n }\n }\n return _sigListeners as SignalListenerMap\n}\n\nlet _signals: string[] | undefined\n/*@__NO_SIDE_EFFECTS__*/\nfunction getSignals() {\n if (_signals === undefined) {\n _signals = ['SIGABRT', 'SIGALRM', 'SIGHUP', 'SIGINT', 'SIGTERM']\n if (!WIN32) {\n _signals.push(\n 'SIGVTALRM',\n 'SIGXCPU',\n 'SIGXFSZ',\n 'SIGUSR2',\n 'SIGTRAP',\n 'SIGSYS',\n 'SIGQUIT',\n 'SIGIOT',\n // should detect profiler and enable/disable accordingly.\n // see #21\n // 'SIGPROF'\n )\n }\n if (platform === 'linux') {\n _signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT', 'SIGUNUSED')\n }\n }\n return _signals as string[]\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction emit(event: string, code: number | null, signal: string | null): void {\n const emitter = getEmitter()\n if (emitter.emitted?.[event]) {\n return\n }\n if (emitter.emitted) {\n emitter.emitted[event] = true\n }\n emitter.emit(event, code, signal)\n}\n\nlet loaded = false\n\n/**\n * Load signal handlers and hook into process exit events.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function load(): void {\n if (loaded || !globalProcess) {\n return\n }\n loaded = true\n\n // This is the number of onSignalExit's that are in play.\n // It's important so that we can count the correct number of\n // listeners on signals, and don't wait for the other one to\n // handle it instead of us.\n const emitter = getEmitter()\n if (emitter.count !== undefined) {\n emitter.count += 1\n }\n\n const sigs = getSignals()\n const sigListeners = getSignalListeners()\n _signals = sigs.filter(sig => {\n try {\n globalProcess.on(\n sig as NodeJS.Signals,\n sigListeners[sig] as SignalListener,\n )\n return true\n } catch {}\n return false\n })\n\n globalProcess.emit = processEmit as typeof globalProcess.emit\n globalProcess.reallyExit = processReallyExit\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction processEmit(\n this: NodeJS.Process,\n eventName: string,\n exitCode?: number | undefined,\n ...args: any[]\n): boolean {\n if (eventName === 'exit') {\n let actualExitCode = exitCode\n if (actualExitCode === undefined) {\n const processExitCode = globalProcess?.exitCode\n actualExitCode =\n typeof processExitCode === 'number' ? processExitCode : undefined\n } else if (globalProcess) {\n globalProcess.exitCode = actualExitCode\n }\n const result = ReflectApply(\n originalProcessEmit as (...args: unknown[]) => boolean,\n this,\n [eventName, actualExitCode, ...args],\n ) as boolean\n const numExitCode =\n typeof actualExitCode === 'number' ? actualExitCode : null\n emit('exit', numExitCode, null)\n emit('afterexit', numExitCode, null)\n return result\n }\n return ReflectApply(\n originalProcessEmit as (...args: unknown[]) => boolean,\n this,\n [eventName, exitCode, ...args],\n ) as boolean\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction processReallyExit(code?: number | undefined): never {\n const exitCode = code || 0\n if (globalProcess) {\n globalProcess.exitCode = exitCode\n }\n emit('exit', exitCode, null)\n emit('afterexit', exitCode, null)\n ReflectApply(\n originalProcessReallyExit as (code?: number) => never,\n globalProcess,\n [exitCode],\n )\n throw new Error('processReallyExit should never return')\n}\n\nexport interface OnExitOptions {\n alwaysLast?: boolean\n}\n\n/**\n * Register a callback to run on process exit or signal.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function onExit(\n cb: (code: number | null, signal: string | null) => void,\n options?: OnExitOptions | undefined,\n): () => void {\n if (!globalProcess) {\n return function remove() {}\n }\n if (typeof cb !== 'function') {\n throw new TypeError('a callback must be provided for exit handler')\n }\n if (loaded === false) {\n load()\n }\n const { alwaysLast } = { __proto__: null, ...options } as OnExitOptions\n\n let eventName = 'exit'\n if (alwaysLast) {\n eventName = 'afterexit'\n }\n\n const emitter = getEmitter()\n emitter.on(eventName, cb)\n\n return function remove() {\n emitter.removeListener(eventName, cb)\n if (\n !emitter.listeners('exit').length &&\n !emitter.listeners('afterexit').length\n ) {\n unload()\n }\n }\n}\n\n/**\n * Get the list of signals that are currently being monitored.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function signals(): string[] | undefined {\n return _signals\n}\n\n/**\n * Unload signal handlers and restore original process behavior.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function unload(): void {\n if (!loaded || !globalProcess) {\n return\n }\n loaded = false\n\n const sigs = getSignals()\n const sigListeners = getSignalListeners()\n for (const sig of sigs) {\n try {\n globalProcess.removeListener(\n sig as NodeJS.Signals,\n sigListeners[sig] as SignalListener,\n )\n } catch {}\n }\n globalProcess.emit = originalProcessEmit as typeof globalProcess.emit\n if (originalProcessReallyExit !== undefined) {\n globalProcess.reallyExit = originalProcessReallyExit\n }\n const emitter = getEmitter()\n if (emitter.count !== undefined) {\n emitter.count -= 1\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/sorts.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/sorts.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Sorting comparison functions including locale-aware and natural sorting.\n * Provides various comparison utilities for arrays and collections.\n */\n\nlet _localeCompare: ((x: string, y: string) => number) | undefined\n/**\n * Compare two strings using locale-aware comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function localeCompare(x: string, y: string): number {\n if (_localeCompare === undefined) {\n // Lazily call new Intl.Collator() because in Node it can take 10-14ms.\n _localeCompare = new Intl.Collator().compare\n }\n return _localeCompare(x, y)\n}\n\nlet _naturalCompare: ((x: string, y: string) => number) | undefined\n/**\n * Compare two strings using natural sorting (numeric-aware, case-insensitive).\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function naturalCompare(x: string, y: string): number {\n if (_naturalCompare === undefined) {\n // Lazily call new Intl.Collator() because in Node it can take 10-14ms.\n _naturalCompare = new Intl.Collator(\n // The `undefined` locale means it uses the default locale of the user's\n // environment.\n undefined,\n {\n // Enables numeric sorting: numbers in strings are compared by value,\n // e.g. 'file2' comes before 'file10' as numbers and not 'file10' before\n // 'file2' as plain text.\n numeric: true,\n // Makes the comparison case-insensitive and ignores diacritics, e.g.\n // 'a', 'A', and '\u00E1' are treated as equivalent.\n sensitivity: 'base',\n },\n ).compare\n }\n return _naturalCompare(x, y)\n}\n\n// Type for fast-sort sorter function.\ntype FastSortFunction = ReturnType<\n typeof import('fast-sort').createNewSortInstance\n>\n\nlet _naturalSorter: FastSortFunction | undefined\n/**\n * Sort an array using natural comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function naturalSorter<T>(\n arrayToSort: T[],\n): ReturnType<FastSortFunction> {\n if (_naturalSorter === undefined) {\n const fastSort = /*@__PURE__*/ require('./external/fast-sort')\n // biome-ignore lint/suspicious/noExplicitAny: Fast-sort API requires dynamic method access.\n _naturalSorter = (fastSort as any).createNewSortInstance({\n comparer: naturalCompare,\n })\n }\n return _naturalSorter?.(arrayToSort)\n}\n\n/**\n * Simple string comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function compareStr(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\n/**\n * Compare semantic versions.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function compareSemver(a: string, b: string): number {\n const semver = /*@__PURE__*/ require('./external/semver')\n const validA = semver.valid(a)\n const validB = semver.valid(b)\n\n if (!validA && !validB) {\n return 0\n }\n if (!validA) {\n return -1\n }\n if (!validB) {\n return 1\n }\n // biome-ignore lint/suspicious/noExplicitAny: Semver API requires dynamic method access.\n return (semver as any).compare(a, b)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,IAAI;AAAA;AAKG,SAAS,cAAc,GAAW,GAAmB;AAC1D,MAAI,mBAAmB,QAAW;AAEhC,qBAAiB,IAAI,KAAK,SAAS,EAAE;AAAA,EACvC;AACA,SAAO,eAAe,GAAG,CAAC;AAC5B;AAEA,IAAI;AAAA;AAKG,SAAS,eAAe,GAAW,GAAmB;AAC3D,MAAI,oBAAoB,QAAW;AAEjC,sBAAkB,IAAI,KAAK;AAAA;AAAA;AAAA,MAGzB;AAAA,MACA;AAAA;AAAA;AAAA;AAAA,QAIE,SAAS;AAAA;AAAA;AAAA,QAGT,aAAa;AAAA,MACf;AAAA,IACF,EAAE;AAAA,EACJ;AACA,SAAO,gBAAgB,GAAG,CAAC;AAC7B;AAOA,IAAI;AAAA;AAKG,SAAS,cACd,aAC8B;AAC9B,MAAI,mBAAmB,QAAW;AAChC,UAAM,WAAyB,QAAQ,sBAAsB;AAE7D,qBAAkB,SAAiB,sBAAsB;AAAA,MACvD,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO,iBAAiB,WAAW;AACrC;AAAA;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;AAAA;AAMO,SAAS,cAAc,GAAW,GAAmB;AAC1D,QAAM,SAAuB,QAAQ,mBAAmB;AACxD,QAAM,SAAS,OAAO,MAAM,CAAC;AAC7B,QAAM,SAAS,OAAO,MAAM,CAAC;AAE7B,MAAI,CAAC,UAAU,CAAC,QAAQ;AACtB,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,SAAQ,OAAe,QAAQ,GAAG,CAAC;AACrC;",
4
+ "sourcesContent": ["/**\n * @fileoverview Sorting comparison functions including locale-aware and natural sorting.\n * Provides various comparison utilities for arrays and collections.\n */\n\nlet _localeCompare: ((x: string, y: string) => number) | undefined\n/**\n * Compare two strings using locale-aware comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function localeCompare(x: string, y: string): number {\n if (_localeCompare === undefined) {\n // Lazily call new Intl.Collator() because in Node it can take 10-14ms.\n _localeCompare = new Intl.Collator().compare\n }\n return _localeCompare(x, y)\n}\n\nlet _naturalCompare: ((x: string, y: string) => number) | undefined\n/**\n * Compare two strings using natural sorting (numeric-aware, case-insensitive).\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function naturalCompare(x: string, y: string): number {\n if (_naturalCompare === undefined) {\n // Lazily call new Intl.Collator() because in Node it can take 10-14ms.\n _naturalCompare = new Intl.Collator(\n // The `undefined` locale means it uses the default locale of the user's\n // environment.\n undefined,\n {\n // Enables numeric sorting: numbers in strings are compared by value,\n // e.g. 'file2' comes before 'file10' as numbers and not 'file10' before\n // 'file2' as plain text.\n numeric: true,\n // Makes the comparison case-insensitive and ignores diacritics, e.g.\n // 'a', 'A', and '\u00E1' are treated as equivalent.\n sensitivity: 'base',\n },\n ).compare\n }\n return _naturalCompare(x, y)\n}\n\n// Type for fast-sort sorter function.\ntype FastSortFunction = ReturnType<\n typeof import('fast-sort').createNewSortInstance\n>\n\nlet _naturalSorter: FastSortFunction | undefined\n/**\n * Sort an array using natural comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function naturalSorter<T>(\n arrayToSort: T[],\n): ReturnType<FastSortFunction> {\n if (_naturalSorter === undefined) {\n const fastSort = /*@__PURE__*/ require('./external/fast-sort')\n _naturalSorter = (fastSort as any).createNewSortInstance({\n comparer: naturalCompare,\n })\n }\n return _naturalSorter?.(arrayToSort)\n}\n\n/**\n * Simple string comparison.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function compareStr(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\n/**\n * Compare semantic versions.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function compareSemver(a: string, b: string): number {\n const semver = /*@__PURE__*/ require('./external/semver')\n const validA = semver.valid(a)\n const validB = semver.valid(b)\n\n if (!validA && !validB) {\n return 0\n }\n if (!validA) {\n return -1\n }\n if (!validB) {\n return 1\n }\n return (semver as any).compare(a, b)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,IAAI;AAAA;AAKG,SAAS,cAAc,GAAW,GAAmB;AAC1D,MAAI,mBAAmB,QAAW;AAEhC,qBAAiB,IAAI,KAAK,SAAS,EAAE;AAAA,EACvC;AACA,SAAO,eAAe,GAAG,CAAC;AAC5B;AAEA,IAAI;AAAA;AAKG,SAAS,eAAe,GAAW,GAAmB;AAC3D,MAAI,oBAAoB,QAAW;AAEjC,sBAAkB,IAAI,KAAK;AAAA;AAAA;AAAA,MAGzB;AAAA,MACA;AAAA;AAAA;AAAA;AAAA,QAIE,SAAS;AAAA;AAAA;AAAA,QAGT,aAAa;AAAA,MACf;AAAA,IACF,EAAE;AAAA,EACJ;AACA,SAAO,gBAAgB,GAAG,CAAC;AAC7B;AAOA,IAAI;AAAA;AAKG,SAAS,cACd,aAC8B;AAC9B,MAAI,mBAAmB,QAAW;AAChC,UAAM,WAAyB,QAAQ,sBAAsB;AAC7D,qBAAkB,SAAiB,sBAAsB;AAAA,MACvD,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO,iBAAiB,WAAW;AACrC;AAAA;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;AAAA;AAMO,SAAS,cAAc,GAAW,GAAmB;AAC1D,QAAM,SAAuB,QAAQ,mBAAmB;AACxD,QAAM,SAAS,OAAO,MAAM,CAAC;AAC7B,QAAM,SAAS,OAAO,MAAM,CAAC;AAE7B,MAAI,CAAC,UAAU,CAAC,QAAQ;AACtB,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SAAQ,OAAe,QAAQ,GAAG,CAAC;AACrC;",
6
6
  "names": []
7
7
  }
package/dist/spawn.d.ts CHANGED
@@ -75,7 +75,6 @@ interface NodeSpawnOptions {
75
75
  cwd?: string | URL | undefined;
76
76
  env?: NodeJS.ProcessEnv | undefined;
77
77
  argv0?: string | undefined;
78
- // biome-ignore lint/suspicious/noExplicitAny: Stdio can be complex union of types from Node.js.
79
78
  stdio?: any;
80
79
  detached?: boolean | undefined;
81
80
  uid?: number | undefined;
@@ -94,7 +93,6 @@ interface ChildProcessType {
94
93
  stdin: NodeJS.WritableStream | null;
95
94
  stdout: NodeJS.ReadableStream | null;
96
95
  stderr: NodeJS.ReadableStream | null;
97
- // biome-ignore lint/suspicious/noExplicitAny: IPC channel type from Node.js.
98
96
  readonly channel?: any;
99
97
  readonly stdio: [
100
98
  NodeJS.WritableStream | null,
@@ -111,20 +109,9 @@ interface ChildProcessType {
111
109
  readonly spawnargs: string[];
112
110
  readonly spawnfile: string;
113
111
  kill(signal?: NodeJS.Signals | number): boolean;
114
- // biome-ignore lint/suspicious/noExplicitAny: IPC message type from Node.js.
115
112
  send(message: any, callback?: (error: Error | null) => void): boolean;
116
- send(
117
- // biome-ignore lint/suspicious/noExplicitAny: IPC message and handle types from Node.js.
118
- message: any,
119
- // biome-ignore lint/suspicious/noExplicitAny: IPC message and handle types from Node.js.
120
- sendHandle?: any | undefined, callback?: (error: Error | null) => void): boolean;
121
- send(
122
- // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.
123
- message: any,
124
- // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.
125
- sendHandle?: any | undefined,
126
- // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.
127
- options?: any | undefined, callback?: (error: Error | null) => void): boolean;
113
+ send(message: any, sendHandle?: any | undefined, callback?: (error: Error | null) => void): boolean;
114
+ send(message: any, sendHandle?: any | undefined, options?: any | undefined, callback?: (error: Error | null) => void): boolean;
128
115
  disconnect(): void;
129
116
  unref(): void;
130
117
  ref(): void;
@@ -139,15 +126,10 @@ interface WritableStreamType {
139
126
  writableObjectMode: boolean;
140
127
  writableCorked: number;
141
128
  destroyed: boolean;
142
- write(
143
- // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.
144
- chunk: any, encoding?: BufferEncoding | undefined, callback?: (error?: Error | null) => void): boolean;
145
- // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.
129
+ write(chunk: any, encoding?: BufferEncoding | undefined, callback?: (error?: Error | null) => void): boolean;
146
130
  write(chunk: any, callback?: (error?: Error | null) => void): boolean;
147
131
  end(cb?: () => void): this;
148
- // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.
149
132
  end(chunk: any, cb?: () => void): this;
150
- // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.
151
133
  end(chunk: any, encoding?: BufferEncoding | undefined, cb?: () => void): this;
152
134
  cork(): void;
153
135
  uncork(): void;
package/dist/spawn.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/spawn.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Child process spawning utilities with cross-platform support.\n * Provides enhanced spawn functionality with stdio handling and error management.\n *\n * SECURITY: Array-Based Arguments Prevent Command Injection\n *\n * This module uses array-based arguments for all command execution, which is the\n * PRIMARY DEFENSE against command injection attacks. When you pass arguments as\n * an array to spawn():\n *\n * spawn('npx', ['sfw', tool, ...args], { shell: true })\n *\n * Node.js handles escaping automatically. Each argument is passed directly to the\n * OS without shell interpretation. Shell metacharacters like ; | & $ ( ) ` are\n * treated as LITERAL STRINGS, not as commands. This approach is secure even when\n * shell: true is used on Windows for .cmd/.bat file resolution.\n *\n * UNSAFE ALTERNATIVE (not used in this codebase):\n * spawn(`npx sfw ${tool} ${args.join(' ')}`, { shell: true }) // \u2716 VULNERABLE\n *\n * String concatenation allows injection. For example, if tool = \"foo; rm -rf /\",\n * the shell would execute both commands. Array-based arguments prevent this.\n *\n * References:\n * - https://nodejs.org/api/child_process.html#child_processspawncommand-args-options\n * - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html\n */\n\nimport { getAbortSignal, getSpinner } from '#constants/process'\n\nimport { isArray } from './arrays'\n\nconst abortSignal = getAbortSignal()\nconst spinner = getSpinner()\n\nimport { getOwn, hasOwn } from './objects'\nimport { stripAnsi } from './strings'\n\n// Define BufferEncoding type for TypeScript compatibility.\ntype BufferEncoding = globalThis.BufferEncoding\n\nconst windowsScriptExtRegExp = /\\.(?:cmd|bat|ps1)$/i\n\nlet _child_process: typeof import('node:child_process') | undefined\n/**\n * Lazily load the child_process module.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getChildProcess() {\n if (_child_process === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _child_process = /*@__PURE__*/ require('node:child_process')\n }\n return _child_process as typeof import('node:child_process')\n}\n\n// Type for promise-spawn options.\nexport type PromiseSpawnOptions = {\n cwd?: string | undefined\n stdioString?: boolean | undefined\n stdio?: StdioType | undefined\n env?: NodeJS.ProcessEnv | undefined\n shell?: boolean | string | undefined\n signal?: AbortSignal | undefined\n timeout?: number | undefined\n uid?: number | undefined\n gid?: number | undefined\n}\n\n// Type for promise-spawn result.\nexport type PromiseSpawnResult = Promise<{\n cmd: string\n args: string[] | readonly string[]\n code: number\n signal: NodeJS.Signals | null\n stdout: string | Buffer\n stderr: string | Buffer\n}> & {\n process: ChildProcessType\n stdin: WritableStreamType | null\n}\n\nlet _npmCliPromiseSpawn:\n | ((\n cmd: string,\n args: string[],\n options?: PromiseSpawnOptions | undefined,\n extra?: SpawnExtra | undefined,\n ) => PromiseSpawnResult)\n | undefined\n/**\n * Lazily load the promise-spawn module for async process spawning.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getNpmcliPromiseSpawn() {\n if (_npmCliPromiseSpawn === undefined) {\n _npmCliPromiseSpawn = /*@__PURE__*/ require('./external/@npmcli/promise-spawn')\n }\n return _npmCliPromiseSpawn as unknown as typeof import('@npmcli/promise-spawn')\n}\n\nlet _path: typeof import('node:path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path as typeof import('node:path')\n}\n\n/**\n * Check if a value is a spawn error.\n */\nexport type SpawnError = {\n args: string[]\n cmd: string\n code: number\n name: string\n message: string\n signal: NodeJS.Signals | null\n stack: string\n stderr: string | Buffer\n stdout: string | Buffer\n}\n\nexport type SpawnErrorWithOutputString = SpawnError & {\n stdout: string\n stderr: string\n}\n\nexport type SpawnErrorWithOutputBuffer = SpawnError & {\n stdout: Buffer\n stderr: Buffer\n}\n\nexport type SpawnExtra = Record<string, unknown>\n\nexport type IOType = 'pipe' | 'ignore' | 'inherit' | 'overlapped'\nexport type StdioType = IOType | 'ipc' | Array<IOType | 'ipc'>\n\nexport interface SpawnSyncReturns<T> {\n pid: number\n output: Array<T | null>\n stdout: T\n stderr: T\n status: number | null\n signal: NodeJS.Signals | null\n error?: Error | undefined\n}\n\n/**\n * Check if a value is a spawn error with expected properties.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isSpawnError(value: unknown): value is SpawnError {\n if (value === null || typeof value !== 'object') {\n return false\n }\n // Check for spawn-specific error properties.\n const err = value as Record<string, unknown>\n return (\n (hasOwn(err, 'code') && typeof err['code'] !== 'undefined') ||\n (hasOwn(err, 'errno') && typeof err['errno'] !== 'undefined') ||\n (hasOwn(err, 'syscall') && typeof err['syscall'] === 'string')\n )\n}\n\n/**\n * Check if stdio configuration matches a specific type.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isStdioType(\n stdio: string | string[],\n type?: StdioType | undefined,\n): boolean {\n // If called with one argument, check if it's a valid stdio type.\n // biome-ignore lint/complexity/noArguments: Function overload detection for single vs two-arg calls.\n if (arguments.length === 1) {\n const validTypes = ['pipe', 'ignore', 'inherit', 'overlapped']\n return typeof stdio === 'string' && validTypes.includes(stdio)\n }\n // Original two-argument behavior.\n return (\n stdio === type ||\n ((stdio === null || stdio === undefined) && type === 'pipe') ||\n (isArray(stdio) &&\n stdio.length > 2 &&\n stdio[0] === type &&\n stdio[1] === type &&\n stdio[2] === type)\n )\n}\n\n/**\n * Strip ANSI escape codes from spawn result stdout and stderr.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction stripAnsiFromSpawnResult(result: unknown): unknown {\n const res = result as {\n stdout?: string | Buffer\n stderr?: string | Buffer\n }\n const { stderr, stdout } = res\n if (typeof stdout === 'string') {\n res.stdout = stripAnsi(stdout)\n }\n if (typeof stderr === 'string') {\n res.stderr = stripAnsi(stderr)\n }\n return res\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n// Duplicated from Node.js child_process.SpawnOptions\n// These are the options passed to child_process.spawn()\ninterface NodeSpawnOptions {\n cwd?: string | URL | undefined\n env?: NodeJS.ProcessEnv | undefined\n argv0?: string | undefined\n // biome-ignore lint/suspicious/noExplicitAny: Stdio can be complex union of types from Node.js.\n stdio?: any\n detached?: boolean | undefined\n uid?: number | undefined\n gid?: number | undefined\n serialization?: 'json' | 'advanced' | undefined\n shell?: boolean | string | undefined\n windowsVerbatimArguments?: boolean | undefined\n windowsHide?: boolean | undefined\n signal?: AbortSignal | undefined\n timeout?: number | undefined\n killSignal?: NodeJS.Signals | number | undefined\n}\n\n// Duplicated from Node.js child_process.ChildProcess\n// This represents a spawned child process\ninterface ChildProcessType {\n stdin: NodeJS.WritableStream | null\n stdout: NodeJS.ReadableStream | null\n stderr: NodeJS.ReadableStream | null\n // biome-ignore lint/suspicious/noExplicitAny: IPC channel type from Node.js.\n readonly channel?: any\n readonly stdio: [\n NodeJS.WritableStream | null,\n NodeJS.ReadableStream | null,\n NodeJS.ReadableStream | null,\n NodeJS.ReadableStream | NodeJS.WritableStream | null | undefined,\n NodeJS.ReadableStream | NodeJS.WritableStream | null | undefined,\n ]\n readonly killed: boolean\n readonly pid?: number | undefined\n readonly connected: boolean\n readonly exitCode: number | null\n readonly signalCode: NodeJS.Signals | null\n readonly spawnargs: string[]\n readonly spawnfile: string\n kill(signal?: NodeJS.Signals | number): boolean\n // biome-ignore lint/suspicious/noExplicitAny: IPC message type from Node.js.\n send(message: any, callback?: (error: Error | null) => void): boolean\n send(\n // biome-ignore lint/suspicious/noExplicitAny: IPC message and handle types from Node.js.\n message: any,\n // biome-ignore lint/suspicious/noExplicitAny: IPC message and handle types from Node.js.\n sendHandle?: any | undefined,\n callback?: (error: Error | null) => void,\n ): boolean\n send(\n // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.\n message: any,\n // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.\n sendHandle?: any | undefined,\n // biome-ignore lint/suspicious/noExplicitAny: IPC message, handle, and options types from Node.js.\n options?: any | undefined,\n callback?: (error: Error | null) => void,\n ): boolean\n disconnect(): void\n unref(): void\n ref(): void\n}\n\n// Duplicated from Node.js stream.Writable\ninterface WritableStreamType {\n writable: boolean\n writableEnded: boolean\n writableFinished: boolean\n writableHighWaterMark: number\n writableLength: number\n writableObjectMode: boolean\n writableCorked: number\n destroyed: boolean\n write(\n // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.\n chunk: any,\n encoding?: BufferEncoding | undefined,\n callback?: (error?: Error | null) => void,\n ): boolean\n // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.\n write(chunk: any, callback?: (error?: Error | null) => void): boolean\n end(cb?: () => void): this\n // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.\n end(chunk: any, cb?: () => void): this\n // biome-ignore lint/suspicious/noExplicitAny: Stream chunk can be any type.\n end(chunk: any, encoding?: BufferEncoding | undefined, cb?: () => void): this\n cork(): void\n uncork(): void\n destroy(error?: Error | undefined): this\n}\n\n/**\n * Spawn a child process with enhanced error handling and output capture.\n */\nexport type SpawnOptions = import('./objects').Remap<\n NodeSpawnOptions & {\n spinner?: import('./spinner').Spinner | undefined\n stdioString?: boolean\n stripAnsi?: boolean\n }\n>\nexport type SpawnResult = PromiseSpawnResult\nexport type SpawnStdioResult = {\n cmd: string\n args: string[] | readonly string[]\n code: number\n signal: NodeJS.Signals | null\n stdout: string | Buffer\n stderr: string | Buffer\n}\n\n/**\n * Spawn a child process and return a promise that resolves when it completes.\n *\n * SECURITY: This function uses array-based arguments which prevent command injection.\n * Arguments in the `args` array are passed directly to the OS without shell\n * interpretation. Shell metacharacters (;|&$()`) are treated as literal strings,\n * not as commands or operators. This is the PRIMARY SECURITY DEFENSE.\n *\n * Even when shell: true is used (on Windows for .cmd/.bat execution), the array-based\n * approach remains secure because Node.js properly escapes each argument before passing\n * to the shell.\n *\n * @param cmd - Command to execute (not user-controlled)\n * @param args - Array of arguments (safe even with user input due to array-based passing)\n * @param options - Spawn options\n * @param extra - Extra options for promise-spawn\n *\n * @example\n * // \u2714 DO THIS - Array-based arguments\n * spawn('git', ['commit', '-m', userMessage])\n * // Each argument is properly escaped, even if userMessage = \"foo; rm -rf /\"\n *\n * @example\n * // \u2716 NEVER DO THIS - String concatenation\n * spawn(`git commit -m \"${userMessage}\"`, { shell: true })\n * // Vulnerable to injection if userMessage = '\"; rm -rf / #'\n */\nexport function spawn(\n cmd: string,\n args?: string[] | readonly string[],\n options?: SpawnOptions | undefined,\n extra?: SpawnExtra | undefined,\n): SpawnResult {\n // Windows cmd.exe command resolution for .cmd/.bat/.ps1 files:\n //\n // When shell: true is used on Windows with script files (.cmd, .bat, .ps1),\n // cmd.exe can have issues executing full paths. The solution is to use just\n // the command basename without extension and let cmd.exe find it via PATH.\n //\n // How cmd.exe resolves commands:\n // 1. Searches current directory first\n // 2. Then searches each directory in PATH environment variable\n // 3. For each directory, tries extensions from PATHEXT (.COM, .EXE, .BAT, .CMD, etc.)\n // 4. Executes the first match found\n //\n // Example: Given 'C:\\pnpm\\pnpm.cmd' with shell: true\n // 1. Extract basename without extension: 'pnpm'\n // 2. cmd.exe searches PATH directories for 'pnpm'\n // 3. PATHEXT causes it to try 'pnpm.com', 'pnpm.exe', 'pnpm.bat', 'pnpm.cmd', etc.\n // 4. Finds and executes 'C:\\pnpm\\pnpm.cmd'\n //\n // This approach is consistent with how other tools handle Windows execution:\n // - npm's promise-spawn: uses which.sync() to find commands in PATH\n // - cross-spawn: spawns cmd.exe with escaped arguments\n // - execa: uses cross-spawn under the hood for Windows support\n //\n // See: https://github.com/nodejs/node/issues/3675\n const shell = getOwn(options, 'shell')\n // Inline WIN32 constant for coverage mode compatibility\n const WIN32 = process.platform === 'win32'\n let actualCmd = cmd\n if (WIN32 && shell && windowsScriptExtRegExp.test(actualCmd)) {\n const path = getPath()\n // Extract just the command name without path and extension.\n actualCmd = path.basename(actualCmd, path.extname(actualCmd))\n }\n const {\n spinner: optionsSpinner = spinner,\n stripAnsi: shouldStripAnsi = true,\n ...spawnOptions\n } = { __proto__: null, ...options } as SpawnOptions\n const spinnerInstance = optionsSpinner\n const { env, stdio, stdioString = true } = spawnOptions\n // The stdio option can be a string or an array.\n // https://nodejs.org/api/child_process.html#optionsstdio\n const wasSpinning = !!spinnerInstance?.isSpinning\n const shouldStopSpinner =\n wasSpinning && !isStdioType(stdio, 'ignore') && !isStdioType(stdio, 'pipe')\n const shouldRestartSpinner = shouldStopSpinner\n if (shouldStopSpinner) {\n spinnerInstance.stop()\n }\n const npmCliPromiseSpawn = getNpmcliPromiseSpawn()\n // Use __proto__: null to prevent prototype pollution when passing to\n // third-party code, Node.js built-ins, or JavaScript built-in methods.\n // https://github.com/npm/promise-spawn\n // https://github.com/nodejs/node/blob/v24.0.1/lib/child_process.js#L674-L678\n const promiseSpawnOpts = {\n __proto__: null,\n cwd: typeof spawnOptions.cwd === 'string' ? spawnOptions.cwd : undefined,\n env: {\n __proto__: null,\n ...process.env,\n ...env,\n } as unknown as NodeJS.ProcessEnv,\n signal: abortSignal,\n stdio: spawnOptions.stdio,\n stdioString,\n shell: spawnOptions.shell,\n timeout: spawnOptions.timeout,\n uid: spawnOptions.uid,\n gid: spawnOptions.gid,\n } as unknown as PromiseSpawnOptions\n const spawnPromise = npmCliPromiseSpawn(\n actualCmd,\n args ? [...args] : [],\n promiseSpawnOpts as Parameters<typeof npmCliPromiseSpawn>[2],\n extra,\n )\n const oldSpawnPromise = spawnPromise\n let newSpawnPromise: PromiseSpawnResult\n if (shouldStripAnsi && stdioString) {\n newSpawnPromise = spawnPromise\n .then(result => {\n const strippedResult = stripAnsiFromSpawnResult(result)\n // Add exitCode as an alias for code.\n if ('code' in (strippedResult as { code?: number })) {\n ;(strippedResult as { code: number; exitCode: number }).exitCode = (\n strippedResult as { code: number }\n ).code\n }\n return strippedResult\n })\n .catch(error => {\n throw stripAnsiFromSpawnResult(error)\n }) as PromiseSpawnResult\n } else {\n newSpawnPromise = spawnPromise.then(result => {\n // Add exitCode as an alias for code.\n if ('code' in result) {\n const res = result as typeof result & { exitCode: number }\n res.exitCode = result.code\n return res\n }\n return result\n }) as PromiseSpawnResult\n }\n if (shouldRestartSpinner) {\n newSpawnPromise = newSpawnPromise.finally(() => {\n spinnerInstance.start()\n }) as PromiseSpawnResult\n }\n // Copy process and stdin properties from original promise\n ;(newSpawnPromise as unknown as PromiseSpawnResult).process =\n oldSpawnPromise.process\n ;(newSpawnPromise as unknown as PromiseSpawnResult).stdin = (\n oldSpawnPromise as unknown as PromiseSpawnResult\n ).stdin\n return newSpawnPromise as SpawnResult\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n/**\n * Synchronously spawn a child process.\n */\nexport type SpawnSyncOptions = Omit<SpawnOptions, 'spinner'>\nexport function spawnSync(\n cmd: string,\n args?: string[] | readonly string[],\n options?: SpawnSyncOptions | undefined,\n): SpawnSyncReturns<string | Buffer> {\n // Windows cmd.exe command resolution for .cmd/.bat/.ps1 files:\n // See spawn() function above for detailed explanation of this approach.\n const shell = getOwn(options, 'shell')\n // Inline WIN32 constant for coverage mode compatibility\n const WIN32 = process.platform === 'win32'\n let actualCmd = cmd\n if (WIN32 && shell && windowsScriptExtRegExp.test(actualCmd)) {\n const path = getPath()\n // Extract just the command name without path and extension.\n actualCmd = path.basename(actualCmd, path.extname(actualCmd))\n }\n const { stripAnsi: shouldStripAnsi = true, ...rawSpawnOptions } = {\n __proto__: null,\n ...options,\n } as SpawnSyncOptions\n const { stdioString: rawStdioString = true } = rawSpawnOptions\n const rawEncoding = rawStdioString ? 'utf8' : 'buffer'\n const spawnOptions = {\n encoding: rawEncoding,\n ...rawSpawnOptions,\n } as NodeSpawnOptions & { encoding: BufferEncoding | 'buffer' }\n const stdioString = spawnOptions.encoding !== 'buffer'\n const result = getChildProcess().spawnSync(actualCmd, args, spawnOptions)\n if (stdioString) {\n const { stderr, stdout } = result\n if (stdout) {\n result.stdout = stdout.toString().trim()\n }\n if (stderr) {\n result.stderr = stderr.toString().trim()\n }\n }\n return (\n shouldStripAnsi && stdioString ? stripAnsiFromSpawnResult(result) : result\n ) as SpawnSyncReturns<string | Buffer>\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @fileoverview Child process spawning utilities with cross-platform support.\n * Provides enhanced spawn functionality with stdio handling and error management.\n *\n * SECURITY: Array-Based Arguments Prevent Command Injection\n *\n * This module uses array-based arguments for all command execution, which is the\n * PRIMARY DEFENSE against command injection attacks. When you pass arguments as\n * an array to spawn():\n *\n * spawn('npx', ['sfw', tool, ...args], { shell: true })\n *\n * Node.js handles escaping automatically. Each argument is passed directly to the\n * OS without shell interpretation. Shell metacharacters like ; | & $ ( ) ` are\n * treated as LITERAL STRINGS, not as commands. This approach is secure even when\n * shell: true is used on Windows for .cmd/.bat file resolution.\n *\n * UNSAFE ALTERNATIVE (not used in this codebase):\n * spawn(`npx sfw ${tool} ${args.join(' ')}`, { shell: true }) // \u2716 VULNERABLE\n *\n * String concatenation allows injection. For example, if tool = \"foo; rm -rf /\",\n * the shell would execute both commands. Array-based arguments prevent this.\n *\n * References:\n * - https://nodejs.org/api/child_process.html#child_processspawncommand-args-options\n * - https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html\n */\n\nimport { getAbortSignal, getSpinner } from '#constants/process'\n\nimport { isArray } from './arrays'\n\nconst abortSignal = getAbortSignal()\nconst spinner = getSpinner()\n\nimport { getOwn, hasOwn } from './objects'\nimport { stripAnsi } from './strings'\n\n// Define BufferEncoding type for TypeScript compatibility.\ntype BufferEncoding = globalThis.BufferEncoding\n\nconst windowsScriptExtRegExp = /\\.(?:cmd|bat|ps1)$/i\n\nlet _child_process: typeof import('node:child_process') | undefined\n/**\n * Lazily load the child_process module.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getChildProcess() {\n if (_child_process === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _child_process = /*@__PURE__*/ require('node:child_process')\n }\n return _child_process as typeof import('node:child_process')\n}\n\n// Type for promise-spawn options.\nexport type PromiseSpawnOptions = {\n cwd?: string | undefined\n stdioString?: boolean | undefined\n stdio?: StdioType | undefined\n env?: NodeJS.ProcessEnv | undefined\n shell?: boolean | string | undefined\n signal?: AbortSignal | undefined\n timeout?: number | undefined\n uid?: number | undefined\n gid?: number | undefined\n}\n\n// Type for promise-spawn result.\nexport type PromiseSpawnResult = Promise<{\n cmd: string\n args: string[] | readonly string[]\n code: number\n signal: NodeJS.Signals | null\n stdout: string | Buffer\n stderr: string | Buffer\n}> & {\n process: ChildProcessType\n stdin: WritableStreamType | null\n}\n\nlet _npmCliPromiseSpawn:\n | ((\n cmd: string,\n args: string[],\n options?: PromiseSpawnOptions | undefined,\n extra?: SpawnExtra | undefined,\n ) => PromiseSpawnResult)\n | undefined\n/**\n * Lazily load the promise-spawn module for async process spawning.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getNpmcliPromiseSpawn() {\n if (_npmCliPromiseSpawn === undefined) {\n _npmCliPromiseSpawn = /*@__PURE__*/ require('./external/@npmcli/promise-spawn')\n }\n return _npmCliPromiseSpawn as unknown as typeof import('@npmcli/promise-spawn')\n}\n\nlet _path: typeof import('node:path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path as typeof import('node:path')\n}\n\n/**\n * Check if a value is a spawn error.\n */\nexport type SpawnError = {\n args: string[]\n cmd: string\n code: number\n name: string\n message: string\n signal: NodeJS.Signals | null\n stack: string\n stderr: string | Buffer\n stdout: string | Buffer\n}\n\nexport type SpawnErrorWithOutputString = SpawnError & {\n stdout: string\n stderr: string\n}\n\nexport type SpawnErrorWithOutputBuffer = SpawnError & {\n stdout: Buffer\n stderr: Buffer\n}\n\nexport type SpawnExtra = Record<string, unknown>\n\nexport type IOType = 'pipe' | 'ignore' | 'inherit' | 'overlapped'\nexport type StdioType = IOType | 'ipc' | Array<IOType | 'ipc'>\n\nexport interface SpawnSyncReturns<T> {\n pid: number\n output: Array<T | null>\n stdout: T\n stderr: T\n status: number | null\n signal: NodeJS.Signals | null\n error?: Error | undefined\n}\n\n/**\n * Check if a value is a spawn error with expected properties.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isSpawnError(value: unknown): value is SpawnError {\n if (value === null || typeof value !== 'object') {\n return false\n }\n // Check for spawn-specific error properties.\n const err = value as Record<string, unknown>\n return (\n (hasOwn(err, 'code') && typeof err['code'] !== 'undefined') ||\n (hasOwn(err, 'errno') && typeof err['errno'] !== 'undefined') ||\n (hasOwn(err, 'syscall') && typeof err['syscall'] === 'string')\n )\n}\n\n/**\n * Check if stdio configuration matches a specific type.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isStdioType(\n stdio: string | string[],\n type?: StdioType | undefined,\n): boolean {\n // If called with one argument, check if it's a valid stdio type.\n // biome-ignore lint/complexity/noArguments: Function overload detection for single vs two-arg calls.\n if (arguments.length === 1) {\n const validTypes = ['pipe', 'ignore', 'inherit', 'overlapped']\n return typeof stdio === 'string' && validTypes.includes(stdio)\n }\n // Original two-argument behavior.\n return (\n stdio === type ||\n ((stdio === null || stdio === undefined) && type === 'pipe') ||\n (isArray(stdio) &&\n stdio.length > 2 &&\n stdio[0] === type &&\n stdio[1] === type &&\n stdio[2] === type)\n )\n}\n\n/**\n * Strip ANSI escape codes from spawn result stdout and stderr.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction stripAnsiFromSpawnResult(result: unknown): unknown {\n const res = result as {\n stdout?: string | Buffer\n stderr?: string | Buffer\n }\n const { stderr, stdout } = res\n if (typeof stdout === 'string') {\n res.stdout = stripAnsi(stdout)\n }\n if (typeof stderr === 'string') {\n res.stderr = stripAnsi(stderr)\n }\n return res\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n// Duplicated from Node.js child_process.SpawnOptions\n// These are the options passed to child_process.spawn()\ninterface NodeSpawnOptions {\n cwd?: string | URL | undefined\n env?: NodeJS.ProcessEnv | undefined\n argv0?: string | undefined\n stdio?: any\n detached?: boolean | undefined\n uid?: number | undefined\n gid?: number | undefined\n serialization?: 'json' | 'advanced' | undefined\n shell?: boolean | string | undefined\n windowsVerbatimArguments?: boolean | undefined\n windowsHide?: boolean | undefined\n signal?: AbortSignal | undefined\n timeout?: number | undefined\n killSignal?: NodeJS.Signals | number | undefined\n}\n\n// Duplicated from Node.js child_process.ChildProcess\n// This represents a spawned child process\ninterface ChildProcessType {\n stdin: NodeJS.WritableStream | null\n stdout: NodeJS.ReadableStream | null\n stderr: NodeJS.ReadableStream | null\n readonly channel?: any\n readonly stdio: [\n NodeJS.WritableStream | null,\n NodeJS.ReadableStream | null,\n NodeJS.ReadableStream | null,\n NodeJS.ReadableStream | NodeJS.WritableStream | null | undefined,\n NodeJS.ReadableStream | NodeJS.WritableStream | null | undefined,\n ]\n readonly killed: boolean\n readonly pid?: number | undefined\n readonly connected: boolean\n readonly exitCode: number | null\n readonly signalCode: NodeJS.Signals | null\n readonly spawnargs: string[]\n readonly spawnfile: string\n kill(signal?: NodeJS.Signals | number): boolean\n send(message: any, callback?: (error: Error | null) => void): boolean\n send(\n message: any,\n sendHandle?: any | undefined,\n callback?: (error: Error | null) => void,\n ): boolean\n send(\n message: any,\n sendHandle?: any | undefined,\n options?: any | undefined,\n callback?: (error: Error | null) => void,\n ): boolean\n disconnect(): void\n unref(): void\n ref(): void\n}\n\n// Duplicated from Node.js stream.Writable\ninterface WritableStreamType {\n writable: boolean\n writableEnded: boolean\n writableFinished: boolean\n writableHighWaterMark: number\n writableLength: number\n writableObjectMode: boolean\n writableCorked: number\n destroyed: boolean\n write(\n chunk: any,\n encoding?: BufferEncoding | undefined,\n callback?: (error?: Error | null) => void,\n ): boolean\n write(chunk: any, callback?: (error?: Error | null) => void): boolean\n end(cb?: () => void): this\n end(chunk: any, cb?: () => void): this\n end(chunk: any, encoding?: BufferEncoding | undefined, cb?: () => void): this\n cork(): void\n uncork(): void\n destroy(error?: Error | undefined): this\n}\n\n/**\n * Spawn a child process with enhanced error handling and output capture.\n */\nexport type SpawnOptions = import('./objects').Remap<\n NodeSpawnOptions & {\n spinner?: import('./spinner').Spinner | undefined\n stdioString?: boolean\n stripAnsi?: boolean\n }\n>\nexport type SpawnResult = PromiseSpawnResult\nexport type SpawnStdioResult = {\n cmd: string\n args: string[] | readonly string[]\n code: number\n signal: NodeJS.Signals | null\n stdout: string | Buffer\n stderr: string | Buffer\n}\n\n/**\n * Spawn a child process and return a promise that resolves when it completes.\n *\n * SECURITY: This function uses array-based arguments which prevent command injection.\n * Arguments in the `args` array are passed directly to the OS without shell\n * interpretation. Shell metacharacters (;|&$()`) are treated as literal strings,\n * not as commands or operators. This is the PRIMARY SECURITY DEFENSE.\n *\n * Even when shell: true is used (on Windows for .cmd/.bat execution), the array-based\n * approach remains secure because Node.js properly escapes each argument before passing\n * to the shell.\n *\n * @param cmd - Command to execute (not user-controlled)\n * @param args - Array of arguments (safe even with user input due to array-based passing)\n * @param options - Spawn options\n * @param extra - Extra options for promise-spawn\n *\n * @example\n * // \u2714 DO THIS - Array-based arguments\n * spawn('git', ['commit', '-m', userMessage])\n * // Each argument is properly escaped, even if userMessage = \"foo; rm -rf /\"\n *\n * @example\n * // \u2716 NEVER DO THIS - String concatenation\n * spawn(`git commit -m \"${userMessage}\"`, { shell: true })\n * // Vulnerable to injection if userMessage = '\"; rm -rf / #'\n */\nexport function spawn(\n cmd: string,\n args?: string[] | readonly string[],\n options?: SpawnOptions | undefined,\n extra?: SpawnExtra | undefined,\n): SpawnResult {\n // Windows cmd.exe command resolution for .cmd/.bat/.ps1 files:\n //\n // When shell: true is used on Windows with script files (.cmd, .bat, .ps1),\n // cmd.exe can have issues executing full paths. The solution is to use just\n // the command basename without extension and let cmd.exe find it via PATH.\n //\n // How cmd.exe resolves commands:\n // 1. Searches current directory first\n // 2. Then searches each directory in PATH environment variable\n // 3. For each directory, tries extensions from PATHEXT (.COM, .EXE, .BAT, .CMD, etc.)\n // 4. Executes the first match found\n //\n // Example: Given 'C:\\pnpm\\pnpm.cmd' with shell: true\n // 1. Extract basename without extension: 'pnpm'\n // 2. cmd.exe searches PATH directories for 'pnpm'\n // 3. PATHEXT causes it to try 'pnpm.com', 'pnpm.exe', 'pnpm.bat', 'pnpm.cmd', etc.\n // 4. Finds and executes 'C:\\pnpm\\pnpm.cmd'\n //\n // This approach is consistent with how other tools handle Windows execution:\n // - npm's promise-spawn: uses which.sync() to find commands in PATH\n // - cross-spawn: spawns cmd.exe with escaped arguments\n // - execa: uses cross-spawn under the hood for Windows support\n //\n // See: https://github.com/nodejs/node/issues/3675\n const shell = getOwn(options, 'shell')\n // Inline WIN32 constant for coverage mode compatibility\n const WIN32 = process.platform === 'win32'\n let actualCmd = cmd\n if (WIN32 && shell && windowsScriptExtRegExp.test(actualCmd)) {\n const path = getPath()\n // Extract just the command name without path and extension.\n actualCmd = path.basename(actualCmd, path.extname(actualCmd))\n }\n const {\n spinner: optionsSpinner = spinner,\n stripAnsi: shouldStripAnsi = true,\n ...spawnOptions\n } = { __proto__: null, ...options } as SpawnOptions\n const spinnerInstance = optionsSpinner\n const { env, stdio, stdioString = true } = spawnOptions\n // The stdio option can be a string or an array.\n // https://nodejs.org/api/child_process.html#optionsstdio\n const wasSpinning = !!spinnerInstance?.isSpinning\n const shouldStopSpinner =\n wasSpinning && !isStdioType(stdio, 'ignore') && !isStdioType(stdio, 'pipe')\n const shouldRestartSpinner = shouldStopSpinner\n if (shouldStopSpinner) {\n spinnerInstance.stop()\n }\n const npmCliPromiseSpawn = getNpmcliPromiseSpawn()\n // Use __proto__: null to prevent prototype pollution when passing to\n // third-party code, Node.js built-ins, or JavaScript built-in methods.\n // https://github.com/npm/promise-spawn\n // https://github.com/nodejs/node/blob/v24.0.1/lib/child_process.js#L674-L678\n const promiseSpawnOpts = {\n __proto__: null,\n cwd: typeof spawnOptions.cwd === 'string' ? spawnOptions.cwd : undefined,\n env: {\n __proto__: null,\n ...process.env,\n ...env,\n } as unknown as NodeJS.ProcessEnv,\n signal: abortSignal,\n stdio: spawnOptions.stdio,\n stdioString,\n shell: spawnOptions.shell,\n timeout: spawnOptions.timeout,\n uid: spawnOptions.uid,\n gid: spawnOptions.gid,\n } as unknown as PromiseSpawnOptions\n const spawnPromise = npmCliPromiseSpawn(\n actualCmd,\n args ? [...args] : [],\n promiseSpawnOpts as Parameters<typeof npmCliPromiseSpawn>[2],\n extra,\n )\n const oldSpawnPromise = spawnPromise\n let newSpawnPromise: PromiseSpawnResult\n if (shouldStripAnsi && stdioString) {\n newSpawnPromise = spawnPromise\n .then(result => {\n const strippedResult = stripAnsiFromSpawnResult(result)\n // Add exitCode as an alias for code.\n if ('code' in (strippedResult as { code?: number })) {\n ;(strippedResult as { code: number; exitCode: number }).exitCode = (\n strippedResult as { code: number }\n ).code\n }\n return strippedResult\n })\n .catch(error => {\n throw stripAnsiFromSpawnResult(error)\n }) as PromiseSpawnResult\n } else {\n newSpawnPromise = spawnPromise.then(result => {\n // Add exitCode as an alias for code.\n if ('code' in result) {\n const res = result as typeof result & { exitCode: number }\n res.exitCode = result.code\n return res\n }\n return result\n }) as PromiseSpawnResult\n }\n if (shouldRestartSpinner) {\n newSpawnPromise = newSpawnPromise.finally(() => {\n spinnerInstance.start()\n }) as PromiseSpawnResult\n }\n // Copy process and stdin properties from original promise\n ;(newSpawnPromise as unknown as PromiseSpawnResult).process =\n oldSpawnPromise.process\n ;(newSpawnPromise as unknown as PromiseSpawnResult).stdin = (\n oldSpawnPromise as unknown as PromiseSpawnResult\n ).stdin\n return newSpawnPromise as SpawnResult\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n/**\n * Synchronously spawn a child process.\n */\nexport type SpawnSyncOptions = Omit<SpawnOptions, 'spinner'>\nexport function spawnSync(\n cmd: string,\n args?: string[] | readonly string[],\n options?: SpawnSyncOptions | undefined,\n): SpawnSyncReturns<string | Buffer> {\n // Windows cmd.exe command resolution for .cmd/.bat/.ps1 files:\n // See spawn() function above for detailed explanation of this approach.\n const shell = getOwn(options, 'shell')\n // Inline WIN32 constant for coverage mode compatibility\n const WIN32 = process.platform === 'win32'\n let actualCmd = cmd\n if (WIN32 && shell && windowsScriptExtRegExp.test(actualCmd)) {\n const path = getPath()\n // Extract just the command name without path and extension.\n actualCmd = path.basename(actualCmd, path.extname(actualCmd))\n }\n const { stripAnsi: shouldStripAnsi = true, ...rawSpawnOptions } = {\n __proto__: null,\n ...options,\n } as SpawnSyncOptions\n const { stdioString: rawStdioString = true } = rawSpawnOptions\n const rawEncoding = rawStdioString ? 'utf8' : 'buffer'\n const spawnOptions = {\n encoding: rawEncoding,\n ...rawSpawnOptions,\n } as NodeSpawnOptions & { encoding: BufferEncoding | 'buffer' }\n const stdioString = spawnOptions.encoding !== 'buffer'\n const result = getChildProcess().spawnSync(actualCmd, args, spawnOptions)\n if (stdioString) {\n const { stderr, stdout } = result\n if (stdout) {\n result.stdout = stdout.toString().trim()\n }\n if (stderr) {\n result.stderr = stderr.toString().trim()\n }\n }\n return (\n shouldStripAnsi && stdioString ? stripAnsiFromSpawnResult(result) : result\n ) as SpawnSyncReturns<string | Buffer>\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }