@socketsecurity/lib 3.2.2 → 3.2.4
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/CHANGELOG.md +27 -0
- package/dist/abort.js +1 -1
- package/dist/agent.js +1 -1
- package/dist/ansi.js +1 -1
- package/dist/argv/flags.js +1 -1
- package/dist/argv/parse.js +1 -1
- package/dist/arrays.js +1 -1
- package/dist/bin.js +1 -1
- package/dist/cacache.js +1 -1
- package/dist/cache-with-ttl.js +1 -1
- package/dist/constants/agents.js +1 -1
- package/dist/constants/core.js +1 -1
- package/dist/constants/encoding.js +1 -1
- package/dist/constants/github.js +1 -1
- package/dist/constants/licenses.js +1 -1
- package/dist/constants/node.js +1 -1
- package/dist/constants/packages.js +1 -1
- package/dist/constants/paths.js +1 -1
- package/dist/constants/platform.js +1 -1
- package/dist/constants/process.js +1 -1
- package/dist/constants/socket.js +1 -1
- package/dist/constants/testing.js +1 -1
- package/dist/constants/time.js +1 -1
- package/dist/constants/typescript.js +1 -1
- package/dist/cover/code.js +1 -1
- package/dist/cover/formatters.js +1 -1
- package/dist/cover/type.js +1 -1
- package/dist/cover/types.js +1 -1
- package/dist/debug.js +1 -1
- package/dist/dlx-binary.js +1 -1
- package/dist/dlx-manifest.js +1 -1
- package/dist/dlx-package.js +1 -1
- package/dist/dlx.js +1 -1
- package/dist/effects/pulse-frames.js +4 -4
- package/dist/effects/text-shimmer.js +1 -1
- package/dist/effects/types.js +1 -1
- package/dist/effects/ultra.js +1 -1
- package/dist/env/ci.js +1 -1
- package/dist/env/debug.js +1 -1
- package/dist/env/github.js +1 -1
- package/dist/env/helpers.js +1 -1
- package/dist/env/home.js +1 -1
- package/dist/env/locale.js +1 -1
- package/dist/env/node-auth-token.js +1 -1
- package/dist/env/node-env.js +1 -1
- package/dist/env/npm.js +1 -1
- package/dist/env/package-manager.js +1 -1
- package/dist/env/path.js +1 -1
- package/dist/env/pre-commit.js +1 -1
- package/dist/env/rewire.js +1 -1
- package/dist/env/shell.js +1 -1
- package/dist/env/socket-cli-shadow.js +1 -1
- package/dist/env/socket-cli.js +1 -1
- package/dist/env/socket.js +1 -1
- package/dist/env/temp-dir.js +1 -1
- package/dist/env/term.js +1 -1
- package/dist/env/test.js +1 -1
- package/dist/env/windows.js +1 -1
- package/dist/env/xdg.js +1 -1
- package/dist/env.js +1 -1
- package/dist/external/@inquirer/confirm.js +16 -15
- package/dist/external/@inquirer/input.js +16 -15
- package/dist/external/@inquirer/password.js +17 -16
- package/dist/external/@inquirer/search.js +18 -17
- package/dist/external/@inquirer/select.js +19 -18
- package/dist/external/@npmcli/package-json/lib/read-package.js +7 -1
- package/dist/external/@npmcli/package-json/lib/sort.js +6 -1
- package/dist/external/@npmcli/package-json.js +18 -0
- package/dist/external/@npmcli/promise-spawn.js +2 -1
- package/dist/external/@socketregistry/is-unicode-supported.js +2 -1
- package/dist/external/@socketregistry/packageurl-js.js +3 -2
- package/dist/external/@socketregistry/yocto-spinner.js +5 -4
- package/dist/external/@yarnpkg/extensions.js +2 -1
- package/dist/external/cacache.js +10 -9
- package/dist/external/debug.js +2 -5
- package/dist/external/del.js +3 -2
- package/dist/external/fast-glob.js +3 -2
- package/dist/external/fast-sort.js +2 -1
- package/dist/external/get-east-asian-width.js +2 -1
- package/dist/external/libnpmexec.js +6 -0
- package/dist/external/libnpmpack.js +68 -71
- package/dist/external/make-fetch-happen.js +17 -20
- package/dist/external/normalize-package-data.js +3 -2
- package/dist/external/npm-package-arg.js +3 -2
- package/dist/external/pacote.js +38 -41
- package/dist/external/picomatch.js +2 -1
- package/dist/external/semver.js +2 -1
- package/dist/external/spdx-correct.js +2 -1
- package/dist/external/spdx-expression-parse.js +2 -1
- package/dist/external/streaming-iterables.js +2 -1
- package/dist/external/validate-npm-package-name.js +2 -1
- package/dist/external/which.js +2 -1
- package/dist/external/yargs-parser.js +2 -1
- package/dist/external/yoctocolors-cjs.js +2 -1
- package/dist/external/zod.js +10 -9
- package/dist/fs.js +1 -1
- package/dist/functions.js +1 -1
- package/dist/git.js +1 -1
- package/dist/github.js +1 -1
- package/dist/globs.js +1 -1
- package/dist/http-request.js +1 -1
- package/dist/ipc.js +1 -1
- package/dist/json.js +1 -1
- package/dist/links/index.js +1 -1
- package/dist/logger.d.ts +29 -4
- package/dist/logger.js +34 -5
- package/dist/maintained-node-versions.js +1 -1
- package/dist/memoization.js +1 -1
- package/dist/objects.js +1 -1
- package/dist/packages/editable.js +1 -1
- package/dist/packages/exports.js +1 -1
- package/dist/packages/isolation.js +1 -1
- package/dist/packages/licenses.js +1 -1
- package/dist/packages/manifest.js +1 -1
- package/dist/packages/normalize.js +1 -1
- package/dist/packages/operations.js +1 -1
- package/dist/packages/paths.js +1 -1
- package/dist/packages/provenance.js +1 -1
- package/dist/packages/specs.js +1 -1
- package/dist/packages/validation.js +1 -1
- package/dist/packages.js +1 -1
- package/dist/path.js +1 -1
- package/dist/paths/rewire.js +1 -1
- package/dist/paths.js +1 -1
- package/dist/performance.js +1 -1
- package/dist/process-lock.js +1 -1
- package/dist/promise-queue.js +1 -1
- package/dist/promises.js +1 -1
- package/dist/regexps.js +1 -1
- package/dist/sea.js +1 -1
- package/dist/shadow.js +1 -1
- package/dist/signal-exit.js +1 -1
- package/dist/sorts.js +1 -1
- package/dist/spawn.js +1 -1
- package/dist/spinner.js +1 -1
- package/dist/ssri.js +1 -1
- package/dist/stdio/clear.js +1 -1
- package/dist/stdio/divider.js +1 -1
- package/dist/stdio/footer.js +1 -1
- package/dist/stdio/header.js +1 -1
- package/dist/stdio/mask.js +1 -1
- package/dist/stdio/progress.js +1 -1
- package/dist/stdio/prompts.js +1 -1
- package/dist/stdio/stderr.js +1 -1
- package/dist/stdio/stdout.js +1 -1
- package/dist/streams.js +1 -1
- package/dist/strings.js +1 -1
- package/dist/suppress-warnings.js +1 -1
- package/dist/tables.js +1 -1
- package/dist/temporary-executor.js +1 -1
- package/dist/themes/context.js +1 -1
- package/dist/themes/index.js +1 -1
- package/dist/themes/themes.js +1 -1
- package/dist/themes/types.js +1 -1
- package/dist/themes/utils.js +1 -1
- package/dist/types.js +1 -1
- package/dist/url.js +1 -1
- package/dist/utils/get-ipc.js +1 -1
- package/dist/validation/json-parser.js +1 -1
- package/dist/validation/types.js +1 -1
- package/dist/versions.js +1 -1
- package/dist/words.js +1 -1
- package/dist/zod.js +1 -1
- package/package.json +1 -1
- package/dist/abort.js.map +0 -7
- package/dist/agent.js.map +0 -7
- package/dist/ansi.js.map +0 -7
- package/dist/argv/flags.js.map +0 -7
- package/dist/argv/parse.js.map +0 -7
- package/dist/arrays.js.map +0 -7
- package/dist/bin.js.map +0 -7
- package/dist/cacache.js.map +0 -7
- package/dist/cache-with-ttl.js.map +0 -7
- package/dist/constants/agents.js.map +0 -7
- package/dist/constants/core.js.map +0 -7
- package/dist/constants/encoding.js.map +0 -7
- package/dist/constants/github.js.map +0 -7
- package/dist/constants/licenses.js.map +0 -7
- package/dist/constants/node.js.map +0 -7
- package/dist/constants/packages.js.map +0 -7
- package/dist/constants/paths.js.map +0 -7
- package/dist/constants/platform.js.map +0 -7
- package/dist/constants/process.js.map +0 -7
- package/dist/constants/socket.js.map +0 -7
- package/dist/constants/testing.js.map +0 -7
- package/dist/constants/time.js.map +0 -7
- package/dist/constants/typescript.js.map +0 -7
- package/dist/cover/code.js.map +0 -7
- package/dist/cover/formatters.js.map +0 -7
- package/dist/cover/type.js.map +0 -7
- package/dist/cover/types.js.map +0 -7
- package/dist/debug.js.map +0 -7
- package/dist/dlx-binary.js.map +0 -7
- package/dist/dlx-manifest.js.map +0 -7
- package/dist/dlx-package.js.map +0 -7
- package/dist/dlx.js.map +0 -7
- package/dist/effects/pulse-frames.js.map +0 -7
- package/dist/effects/text-shimmer.js.map +0 -7
- package/dist/effects/types.js.map +0 -7
- package/dist/effects/ultra.js.map +0 -7
- package/dist/env/ci.js.map +0 -7
- package/dist/env/debug.js.map +0 -7
- package/dist/env/github.js.map +0 -7
- package/dist/env/helpers.js.map +0 -7
- package/dist/env/home.js.map +0 -7
- package/dist/env/locale.js.map +0 -7
- package/dist/env/node-auth-token.js.map +0 -7
- package/dist/env/node-env.js.map +0 -7
- package/dist/env/npm.js.map +0 -7
- package/dist/env/package-manager.js.map +0 -7
- package/dist/env/path.js.map +0 -7
- package/dist/env/pre-commit.js.map +0 -7
- package/dist/env/rewire.js.map +0 -7
- package/dist/env/shell.js.map +0 -7
- package/dist/env/socket-cli-shadow.js.map +0 -7
- package/dist/env/socket-cli.js.map +0 -7
- package/dist/env/socket.js.map +0 -7
- package/dist/env/temp-dir.js.map +0 -7
- package/dist/env/term.js.map +0 -7
- package/dist/env/test.js.map +0 -7
- package/dist/env/windows.js.map +0 -7
- package/dist/env/xdg.js.map +0 -7
- package/dist/env.js.map +0 -7
- package/dist/external/@npmcli/package-json/index.js +0 -1
- package/dist/external/@socketregistry/is-unicode-supported.d.ts +0 -2
- package/dist/external/@socketregistry/yocto-spinner.d.ts +0 -12
- package/dist/external/@yarnpkg/extensions.d.ts +0 -4
- package/dist/external/cacache.d.ts +0 -86
- package/dist/external/debug.d.ts +0 -22
- package/dist/external/del.d.ts +0 -1
- package/dist/external/fast-sort.d.ts +0 -3
- package/dist/external/get-east-asian-width.d.ts +0 -5
- package/dist/external/libnpmexec.d.ts +0 -33
- package/dist/external/libnpmpack.d.ts +0 -2
- package/dist/external/make-fetch-happen.d.ts +0 -15
- package/dist/external/pacote.d.ts +0 -14
- package/dist/external/semver.d.ts +0 -2
- package/dist/external/yargs-parser.d.ts +0 -2
- package/dist/external/yoctocolors-cjs.d.ts +0 -52
- package/dist/external/zod.d.ts +0 -1
- package/dist/fs.js.map +0 -7
- package/dist/functions.js.map +0 -7
- package/dist/git.js.map +0 -7
- package/dist/github.js.map +0 -7
- package/dist/globs.js.map +0 -7
- package/dist/http-request.js.map +0 -7
- package/dist/ipc.js.map +0 -7
- package/dist/json.js.map +0 -7
- package/dist/links/index.js.map +0 -7
- package/dist/logger.js.map +0 -7
- package/dist/maintained-node-versions.js.map +0 -7
- package/dist/memoization.js.map +0 -7
- package/dist/objects.js.map +0 -7
- package/dist/packages/editable.js.map +0 -7
- package/dist/packages/exports.js.map +0 -7
- package/dist/packages/isolation.js.map +0 -7
- package/dist/packages/licenses.js.map +0 -7
- package/dist/packages/manifest.js.map +0 -7
- package/dist/packages/normalize.js.map +0 -7
- package/dist/packages/operations.js.map +0 -7
- package/dist/packages/paths.js.map +0 -7
- package/dist/packages/provenance.js.map +0 -7
- package/dist/packages/specs.js.map +0 -7
- package/dist/packages/validation.js.map +0 -7
- package/dist/packages.js.map +0 -7
- package/dist/path.js.map +0 -7
- package/dist/paths/rewire.js.map +0 -7
- package/dist/paths.js.map +0 -7
- package/dist/performance.js.map +0 -7
- package/dist/process-lock.js.map +0 -7
- package/dist/promise-queue.js.map +0 -7
- package/dist/promises.js.map +0 -7
- package/dist/regexps.js.map +0 -7
- package/dist/sea.js.map +0 -7
- package/dist/shadow.js.map +0 -7
- package/dist/signal-exit.js.map +0 -7
- package/dist/sorts.js.map +0 -7
- package/dist/spawn.js.map +0 -7
- package/dist/spinner.js.map +0 -7
- package/dist/ssri.js.map +0 -7
- package/dist/stdio/clear.js.map +0 -7
- package/dist/stdio/divider.js.map +0 -7
- package/dist/stdio/footer.js.map +0 -7
- package/dist/stdio/header.js.map +0 -7
- package/dist/stdio/mask.js.map +0 -7
- package/dist/stdio/progress.js.map +0 -7
- package/dist/stdio/prompts.js.map +0 -7
- package/dist/stdio/stderr.js.map +0 -7
- package/dist/stdio/stdout.js.map +0 -7
- package/dist/streams.js.map +0 -7
- package/dist/strings.js.map +0 -7
- package/dist/suppress-warnings.js.map +0 -7
- package/dist/tables.js.map +0 -7
- package/dist/temporary-executor.js.map +0 -7
- package/dist/themes/context.js.map +0 -7
- package/dist/themes/index.js.map +0 -7
- package/dist/themes/themes.js.map +0 -7
- package/dist/themes/types.js.map +0 -7
- package/dist/themes/utils.js.map +0 -7
- package/dist/types.js.map +0 -7
- package/dist/url.js.map +0 -7
- package/dist/utils/get-ipc.js.map +0 -7
- package/dist/validation/json-parser.js.map +0 -7
- package/dist/validation/types.js.map +0 -7
- package/dist/versions.js.map +0 -7
- package/dist/words.js.map +0 -7
- package/dist/zod.js.map +0 -7
package/dist/signal-exit.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 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 __signal_exit_emitter__?: import('node:events').EventEmitter\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
|
-
"names": []
|
|
7
|
-
}
|
package/dist/sorts.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 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 =\n /*@__PURE__*/ require('./external/fast-sort') as typeof import('fast-sort')\n _naturalSorter = fastSort.createNewSortInstance({\n comparer: naturalCompare,\n }) as FastSortFunction\n }\n return (_naturalSorter as FastSortFunction)(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 =\n /*@__PURE__*/ require('./external/semver') as typeof import('semver')\n const validA: string | null = semver.valid(a)\n const validB: string | null = 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.compare(a, b) as number\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,WACU,QAAQ,sBAAsB;AAC9C,qBAAiB,SAAS,sBAAsB;AAAA,MAC9C,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAQ,eAAoC,WAAW;AACzD;AAAA;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;AAAA;AAMO,SAAS,cAAc,GAAW,GAAmB;AAC1D,QAAM,SACU,QAAQ,mBAAmB;AAC3C,QAAM,SAAwB,OAAO,MAAM,CAAC;AAC5C,QAAM,SAAwB,OAAO,MAAM,CAAC;AAE5C,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,SAAO,OAAO,QAAQ,GAAG,CAAC;AAC5B;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/spawn.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 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 to avoid Webpack bundling issues.\n *\n * @returns The Node.js `child_process` module\n *\n * @example\n * const childProcess = getChildProcess()\n * childProcess.spawnSync('ls', ['-la'])\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/**\n * Options for spawning a child process with promise-based completion.\n *\n * @property {string | undefined} cwd - Current working directory for the process\n * @property {boolean | undefined} stdioString - Convert stdio output to strings (default: `true`)\n * @property {StdioType | undefined} stdio - Stdio configuration (`'pipe'`, `'ignore'`, `'inherit'`, or array)\n * @property {NodeJS.ProcessEnv | undefined} env - Environment variables for the process\n * @property {boolean | string | undefined} shell - Whether to run command in shell, or path to shell\n * @property {AbortSignal | undefined} signal - Signal to abort the process\n * @property {number | undefined} timeout - Maximum time in milliseconds before killing the process\n * @property {number | undefined} uid - User identity of the process (POSIX only)\n * @property {number | undefined} gid - Group identity of the process (POSIX only)\n */\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/**\n * Result returned by {@link spawn} when the child process completes.\n * This is a Promise that resolves with process exit information and output,\n * with additional properties for accessing the running process and stdin stream.\n *\n * @property {ChildProcessType} process - The running child process instance\n * @property {WritableStreamType | null} stdin - Writable stream for process stdin, or `null` if not piped\n *\n * @example\n * const result = spawn('echo', ['hello'])\n * result.stdin?.write('additional input\\n')\n * const { code, stdout } = await result\n * console.log(stdout) // 'hello'\n */\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 `@npmcli/promise-spawn` module for async process spawning.\n *\n * @returns The promise-spawn module that provides Promise-based spawn functionality\n *\n * @example\n * const promiseSpawn = getNpmcliPromiseSpawn()\n * await promiseSpawn('git', ['status'])\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 bundling issues.\n *\n * @returns The Node.js `path` module\n *\n * @example\n * const path = getPath()\n * const basename = path.basename('/foo/bar.txt')\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 * Error object thrown when a spawned process fails.\n * Extends the standard Error with process-specific information including exit code,\n * signal, command details, and captured output.\n *\n * @property {string[]} args - Arguments passed to the command\n * @property {string} cmd - Command that was executed\n * @property {number} code - Process exit code\n * @property {string} name - Error name (typically `'Error'`)\n * @property {string} message - Error message describing the failure\n * @property {NodeJS.Signals | null} signal - Signal that terminated the process, if any\n * @property {string} stack - Stack trace of the error\n * @property {string | Buffer} stderr - Standard error output from the process\n * @property {string | Buffer} stdout - Standard output from the process\n *\n * @example\n * try {\n * await spawn('exit', ['1'])\n * } catch (error) {\n * if (isSpawnError(error)) {\n * console.error(`Command failed with code ${error.code}`)\n * console.error(`stderr: ${error.stderr}`)\n * }\n * }\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\n/**\n * Spawn error variant where stdout and stderr are guaranteed to be strings.\n * This type is used when `stdioString: true` is set in spawn options.\n *\n * @property {string} stdout - Standard output as a string\n * @property {string} stderr - Standard error as a string\n */\nexport type SpawnErrorWithOutputString = SpawnError & {\n stdout: string\n stderr: string\n}\n\n/**\n * Spawn error variant where stdout and stderr are guaranteed to be Buffers.\n * This type is used when `stdioString: false` is set in spawn options.\n *\n * @property {Buffer} stdout - Standard output as a Buffer\n * @property {Buffer} stderr - Standard error as a Buffer\n */\nexport type SpawnErrorWithOutputBuffer = SpawnError & {\n stdout: Buffer\n stderr: Buffer\n}\n\n/**\n * Extra options passed to the underlying promise-spawn implementation.\n * This is an open-ended object for passing additional metadata or configuration.\n */\nexport type SpawnExtra = Record<string, unknown>\n\n/**\n * Valid values for individual stdio streams.\n * - `'pipe'` - Creates a pipe between child and parent (default)\n * - `'ignore'` - Ignores the stream\n * - `'inherit'` - Uses parent's stream\n * - `'overlapped'` - Windows-specific overlapped I/O\n */\nexport type IOType = 'pipe' | 'ignore' | 'inherit' | 'overlapped'\n\n/**\n * Configuration for process stdio (stdin, stdout, stderr) streams.\n * Can be a single value applied to all streams, or an array specifying each stream individually.\n * - `'ipc'` - Creates an IPC channel for communication with the parent\n *\n * @example\n * // All streams piped\n * stdio: 'pipe'\n *\n * @example\n * // Custom configuration per stream: [stdin, stdout, stderr]\n * stdio: ['ignore', 'pipe', 'pipe']\n */\nexport type StdioType = IOType | 'ipc' | Array<IOType | 'ipc'>\n\n/**\n * Result object returned by {@link spawnSync} when the child process completes synchronously.\n *\n * @template T - Type of stdout/stderr (string or Buffer)\n * @property {number} pid - Process ID of the spawned child\n * @property {Array<T | null>} output - Array containing stdout/stderr values\n * @property {T} stdout - Standard output from the process\n * @property {T} stderr - Standard error from the process\n * @property {number | null} status - Exit code, or `null` if killed by signal\n * @property {NodeJS.Signals | null} signal - Signal that terminated the process, or `null`\n * @property {Error | undefined} error - Error object if the spawn failed\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 error properties.\n * Tests for common error properties from child process failures.\n *\n * @param {unknown} value - Value to check\n * @returns {boolean} `true` if the value has spawn error properties\n *\n * @example\n * try {\n * await spawn('nonexistent-command')\n * } catch (error) {\n * if (isSpawnError(error)) {\n * console.error(`Spawn failed: ${error.code}`)\n * }\n * }\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 * When called with one argument, validates if it's a valid stdio type.\n * When called with two arguments, checks if the stdio config matches the specified type.\n *\n * @param {string | string[]} stdio - Stdio configuration to check\n * @param {StdioType | undefined} type - Expected stdio type (optional)\n * @returns {boolean} `true` if stdio matches the type or is valid\n *\n * @example\n * // Check if valid stdio type\n * isStdioType('pipe') // true\n * isStdioType('invalid') // false\n *\n * @example\n * // Check if stdio matches specific type\n * isStdioType('pipe', 'pipe') // true\n * isStdioType(['pipe', 'pipe', 'pipe'], 'pipe') // true\n * isStdioType('ignore', 'pipe') // false\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 * Modifies the result object in place to remove color codes and formatting.\n *\n * @param {unknown} result - Spawn result object with stdout/stderr properties\n * @returns {unknown} The modified result object\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 * Options for spawning a child process with {@link spawn}.\n * Extends Node.js spawn options with additional Socket-specific functionality.\n *\n * @property {import('./spinner').Spinner | undefined} spinner - Spinner instance to pause during execution\n * @property {boolean | undefined} stdioString - Convert output to strings (default: `true`)\n * @property {boolean | undefined} stripAnsi - Remove ANSI codes from output (default: `true`)\n * @property {string | URL | undefined} cwd - Current working directory\n * @property {NodeJS.ProcessEnv | undefined} env - Environment variables\n * @property {StdioType | undefined} stdio - Stdio configuration\n * @property {boolean | string | undefined} shell - Run command in shell\n * @property {number | undefined} timeout - Timeout in milliseconds\n * @property {AbortSignal | undefined} signal - Abort signal\n * @property {number | undefined} uid - User identity (POSIX)\n * @property {number | undefined} gid - Group identity (POSIX)\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\n/**\n * Result object returned when a spawned process completes.\n *\n * @property {string} cmd - Command that was executed\n * @property {string[] | readonly string[]} args - Arguments passed to the command\n * @property {number} code - Process exit code\n * @property {NodeJS.Signals | null} signal - Signal that terminated the process, if any\n * @property {string | Buffer} stdout - Standard output (string if `stdioString: true`, Buffer otherwise)\n * @property {string | Buffer} stderr - Standard error (string if `stdioString: true`, Buffer otherwise)\n */\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 * Provides enhanced error handling, output capture, and cross-platform support.\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 {string} cmd - Command to execute (not user-controlled)\n * @param {string[] | readonly string[] | undefined} args - Array of arguments (safe even with user input)\n * @param {SpawnOptions | undefined} options - Spawn options for process configuration\n * @param {SpawnExtra | undefined} extra - Extra options for promise-spawn\n * @returns {SpawnResult} Promise that resolves with process exit information\n *\n * @throws {SpawnError} When the process exits with non-zero code or is terminated by signal\n *\n * @example\n * // Basic usage - spawn and wait for completion\n * const result = await spawn('git', ['status'])\n * console.log(result.stdout)\n *\n * @example\n * // With options - set working directory and environment\n * const result = await spawn('npm', ['install'], {\n * cwd: '/path/to/project',\n * env: { NODE_ENV: 'production' }\n * })\n *\n * @example\n * // \u2714 DO THIS - Array-based arguments (safe)\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 (vulnerable)\n * spawn(`git commit -m \"${userMessage}\"`, { shell: true })\n * // Vulnerable to injection if userMessage = '\"; rm -rf / #'\n *\n * @example\n * // Access stdin for interactive processes\n * const result = spawn('cat', [])\n * result.stdin?.write('Hello\\n')\n * result.stdin?.end()\n * const { stdout } = await result\n * console.log(stdout) // 'Hello'\n *\n * @example\n * // Handle errors with exit codes\n * try {\n * await spawn('exit', ['1'])\n * } catch (error) {\n * if (isSpawnError(error)) {\n * console.error(`Failed with code ${error.code}`)\n * console.error(error.stderr)\n * }\n * }\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 // Preserve Windows process.env Proxy behavior when no custom env is provided.\n // On Windows, process.env is a Proxy that provides case-insensitive access\n // (PATH vs Path vs path). Spreading creates a plain object that loses this.\n // Only spread when we have custom environment variables to merge.\n const envToUse = env\n ? ({\n __proto__: null,\n ...process.env,\n ...env,\n } as unknown as NodeJS.ProcessEnv)\n : process.env\n\n const promiseSpawnOpts = {\n __proto__: null,\n cwd: typeof spawnOptions.cwd === 'string' ? spawnOptions.cwd : undefined,\n env: envToUse,\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 * Options for synchronously spawning a child process with {@link spawnSync}.\n * Same as {@link SpawnOptions} but excludes the `spinner` property (not applicable for synchronous execution).\n */\nexport type SpawnSyncOptions = Omit<SpawnOptions, 'spinner'>\n\n/**\n * Synchronously spawn a child process and wait for it to complete.\n * Blocks execution until the process exits, returning all output and exit information.\n *\n * WARNING: This function blocks the event loop. Use {@link spawn} for async operations.\n *\n * @param {string} cmd - Command to execute\n * @param {string[] | readonly string[] | undefined} args - Array of arguments\n * @param {SpawnSyncOptions | undefined} options - Spawn options for process configuration\n * @returns {SpawnSyncReturns<string | Buffer>} Process result with exit code and captured output\n *\n * @example\n * // Basic synchronous spawn\n * const result = spawnSync('git', ['status'])\n * console.log(result.stdout)\n * console.log(result.status) // exit code\n *\n * @example\n * // With options\n * const result = spawnSync('npm', ['install'], {\n * cwd: '/path/to/project',\n * stdioString: true\n * })\n * if (result.status !== 0) {\n * console.error(result.stderr)\n * }\n *\n * @example\n * // Get raw buffer output\n * const result = spawnSync('cat', ['binary-file'], {\n * stdioString: false\n * })\n * console.log(result.stdout) // Buffer\n *\n * @example\n * // Handle process errors\n * const result = spawnSync('nonexistent-command')\n * if (result.error) {\n * console.error('Failed to spawn:', result.error)\n * }\n */\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
|
-
"names": []
|
|
7
|
-
}
|
package/dist/spinner.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/spinner.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview CLI spinner utilities for long-running operations.\n * Provides animated progress indicators with CI environment detection.\n */\n\nimport type { Writable } from 'stream'\n\nimport { getCI } from '#env/ci'\nimport { isDebug } from './debug'\nimport { generateSocketSpinnerFrames } from './effects/pulse-frames'\nimport type {\n ShimmerColorGradient,\n ShimmerConfig,\n ShimmerDirection,\n ShimmerState,\n} from './effects/text-shimmer'\nimport { applyShimmer, COLOR_INHERIT, DIR_LTR } from './effects/text-shimmer'\nimport yoctoSpinner from './external/@socketregistry/yocto-spinner'\nimport {\n LOG_SYMBOLS,\n getDefaultLogger,\n incLogCallCountSymbol,\n lastWasBlankSymbol,\n} from './logger'\nimport { hasOwn } from './objects'\nimport { isBlankString, stringWidth } from './strings'\nimport { getTheme } from './themes/context'\nimport { THEMES } from './themes/themes'\nimport { resolveColor } from './themes/utils'\n\n/**\n * Named color values supported by the spinner.\n * Maps to standard terminal colors with bright variants.\n */\nexport type ColorName =\n | 'black'\n | 'blue'\n | 'blueBright'\n | 'cyan'\n | 'cyanBright'\n | 'gray'\n | 'green'\n | 'greenBright'\n | 'magenta'\n | 'magentaBright'\n | 'red'\n | 'redBright'\n | 'white'\n | 'whiteBright'\n | 'yellow'\n | 'yellowBright'\n\n/**\n * Special 'inherit' color value that uses the spinner's current color.\n * Used with shimmer effects to dynamically inherit the spinner color.\n */\nexport type ColorInherit = 'inherit'\n\n/**\n * RGB color tuple with values 0-255 for red, green, and blue channels.\n * @example [140, 82, 255] // Socket purple\n * @example [255, 0, 0] // Red\n */\nexport type ColorRgb = readonly [number, number, number]\n\n/**\n * Union of all supported color types: named colors or RGB tuples.\n */\nexport type ColorValue = ColorName | ColorRgb\n\n/**\n * Symbol types for status messages.\n * Maps to log symbols: success (\u2713), fail (\u2717), info (\u2139), warn (\u26A0).\n */\nexport type SymbolType = 'fail' | 'info' | 'success' | 'warn'\n\n// Map color names to RGB values.\nconst colorToRgb: Record<ColorName, ColorRgb> = {\n __proto__: null,\n black: [0, 0, 0],\n blue: [0, 0, 255],\n blueBright: [100, 149, 237],\n cyan: [0, 255, 255],\n cyanBright: [0, 255, 255],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenBright: [0, 255, 0],\n magenta: [255, 0, 255],\n magentaBright: [255, 105, 180],\n red: [255, 0, 0],\n redBright: [255, 69, 0],\n white: [255, 255, 255],\n whiteBright: [255, 255, 255],\n yellow: [255, 255, 0],\n yellowBright: [255, 255, 153],\n} as Record<ColorName, ColorRgb>\n\n/**\n * Type guard to check if a color value is an RGB tuple.\n * @param value - Color value to check\n * @returns `true` if value is an RGB tuple, `false` if it's a color name\n */\nfunction isRgbTuple(value: ColorValue): value is ColorRgb {\n return Array.isArray(value)\n}\n\n/**\n * Convert a color value to RGB tuple format.\n * Named colors are looked up in the `colorToRgb` map, RGB tuples are returned as-is.\n * @param color - Color name or RGB tuple\n * @returns RGB tuple with values 0-255\n */\nexport function toRgb(color: ColorValue): ColorRgb {\n if (isRgbTuple(color)) {\n return color\n }\n return colorToRgb[color]\n}\n\n/**\n * Progress tracking information for display in spinner.\n * Used by `progress()` and `progressStep()` methods to show animated progress bars.\n */\nexport type ProgressInfo = {\n /** Current progress value */\n current: number\n /** Total/maximum progress value */\n total: number\n /** Optional unit label displayed after the progress count (e.g., 'files', 'items') */\n unit?: string | undefined\n}\n\n/**\n * Internal shimmer state with color configuration.\n * Extends `ShimmerState` with additional color property that can be inherited from spinner.\n */\nexport type ShimmerInfo = ShimmerState & {\n /** Color for shimmer effect - can inherit from spinner, use explicit color, or gradient */\n color: ColorInherit | ColorValue | ShimmerColorGradient\n}\n\n/**\n * Spinner instance for displaying animated loading indicators.\n * Provides methods for status updates, progress tracking, and text shimmer effects.\n *\n * KEY BEHAVIORS:\n * - Methods WITHOUT \"AndStop\" keep the spinner running (e.g., `success()`, `fail()`)\n * - Methods WITH \"AndStop\" auto-clear the spinner line (e.g., `successAndStop()`, `failAndStop()`)\n * - Status messages (done, success, fail, info, warn, step, substep) go to stderr\n * - Data messages (`log()`) go to stdout\n *\n * @example\n * ```ts\n * import { Spinner } from '@socketsecurity/lib/spinner'\n *\n * const spinner = Spinner({ text: 'Loading\u2026' })\n * spinner.start()\n *\n * // Show success while continuing to spin\n * spinner.success('Step 1 complete')\n *\n * // Stop the spinner with success message\n * spinner.successAndStop('All done!')\n * ```\n */\nexport type Spinner = {\n /** Current spinner color as RGB tuple */\n color: ColorRgb\n /** Current spinner animation style */\n spinner: SpinnerStyle\n\n /** Whether spinner is currently animating */\n get isSpinning(): boolean\n\n /** Get current shimmer state (enabled/disabled and configuration) */\n get shimmerState(): ShimmerInfo | undefined\n\n /** Clear the current line without stopping the spinner */\n clear(): Spinner\n\n /** Show debug message without stopping (only if debug mode enabled) */\n debug(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show debug message and stop the spinner (only if debug mode enabled) */\n debugAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Alias for `fail()` - show error without stopping */\n error(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Alias for `failAndStop()` - show error and stop */\n errorAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Show failure (\u2717) without stopping the spinner */\n fail(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show failure (\u2717) and stop the spinner, auto-clearing the line */\n failAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Get current spinner text (getter) or set new text (setter) */\n text(value: string): Spinner\n text(): string\n\n /** Increase indentation by specified spaces (default: 2) */\n indent(spaces?: number | undefined): Spinner\n /** Decrease indentation by specified spaces (default: 2) */\n dedent(spaces?: number | undefined): Spinner\n\n /** Show info (\u2139) message without stopping the spinner */\n info(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show info (\u2139) message and stop the spinner, auto-clearing the line */\n infoAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Log to stdout without stopping the spinner */\n log(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Log and stop the spinner, auto-clearing the line */\n logAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Start spinning with optional text */\n start(text?: string | undefined): Spinner\n /** Stop spinning and clear internal state, auto-clearing the line */\n stop(text?: string | undefined): Spinner\n /** Stop and show final text without clearing the line */\n stopAndPersist(text?: string | undefined): Spinner\n\n /** Show main step message to stderr without stopping */\n step(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show indented substep message to stderr without stopping */\n substep(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Show success (\u2713) without stopping the spinner */\n success(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show success (\u2713) and stop the spinner, auto-clearing the line */\n successAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Alias for `success()` - show success without stopping */\n done(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Alias for `successAndStop()` - show success and stop */\n doneAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n\n /** Update progress bar with current/total values and optional unit */\n progress(current: number, total: number, unit?: string | undefined): Spinner\n /** Increment progress by specified amount (default: 1) */\n progressStep(amount?: number): Spinner\n\n /** Enable shimmer effect (restores saved config or uses defaults) */\n enableShimmer(): Spinner\n /** Disable shimmer effect (preserves config for later re-enable) */\n disableShimmer(): Spinner\n /** Set complete shimmer configuration */\n setShimmer(config: ShimmerConfig): Spinner\n /** Update partial shimmer configuration */\n updateShimmer(config: Partial<ShimmerConfig>): Spinner\n\n /** Show warning (\u26A0) without stopping the spinner */\n warn(text?: string | undefined, ...extras: unknown[]): Spinner\n /** Show warning (\u26A0) and stop the spinner, auto-clearing the line */\n warnAndStop(text?: string | undefined, ...extras: unknown[]): Spinner\n}\n\n/**\n * Configuration options for creating a spinner instance.\n */\nexport type SpinnerOptions = {\n /**\n * Spinner color as RGB tuple or color name.\n * @default [140, 82, 255] Socket purple\n */\n readonly color?: ColorValue | undefined\n /**\n * Shimmer effect configuration or direction string.\n * When enabled, text will have an animated shimmer effect.\n * @default undefined No shimmer effect\n */\n readonly shimmer?: ShimmerConfig | ShimmerDirection | undefined\n /**\n * Animation style with frames and timing.\n * @default 'socket' Custom Socket animation in CLI, minimal in CI\n */\n readonly spinner?: SpinnerStyle | undefined\n /**\n * Abort signal for cancelling the spinner.\n * @default getAbortSignal() from process constants\n */\n readonly signal?: AbortSignal | undefined\n /**\n * Output stream for spinner rendering.\n * @default process.stderr\n */\n readonly stream?: Writable | undefined\n /**\n * Initial text to display with the spinner.\n * @default undefined No initial text\n */\n readonly text?: string | undefined\n /**\n * Theme to use for spinner colors.\n * Accepts theme name ('socket', 'sunset', etc.) or Theme object.\n * @default Current theme from getTheme()\n */\n readonly theme?:\n | import('./themes/types').Theme\n | import('./themes/themes').ThemeName\n | undefined\n}\n\n/**\n * Animation style definition for spinner frames.\n * Defines the visual appearance and timing of the spinner animation.\n */\nexport type SpinnerStyle = {\n /** Array of animation frames (strings to display sequentially) */\n readonly frames: string[]\n /**\n * Milliseconds between frame changes.\n * @default 80 Standard frame rate\n */\n readonly interval?: number | undefined\n}\n\n/**\n * Minimal spinner style for CI environments.\n * Uses empty frame and max interval to effectively disable animation in CI.\n */\nexport const ciSpinner: SpinnerStyle = {\n frames: [''],\n interval: 2_147_483_647,\n}\n\n/**\n * Create a property descriptor for defining non-enumerable properties.\n * Used for adding aliased methods to the Spinner prototype.\n * @param value - Value for the property\n * @returns Property descriptor object\n * @private\n */\nfunction desc(value: unknown) {\n return {\n __proto__: null,\n configurable: true,\n value,\n writable: true,\n }\n}\n\n/**\n * Normalize text input by trimming leading whitespace.\n * Non-string values are converted to empty string.\n * @param value - Text to normalize\n * @returns Normalized string with leading whitespace removed\n * @private\n */\nfunction normalizeText(value: unknown) {\n return typeof value === 'string' ? value.trimStart() : ''\n}\n\n/**\n * Format progress information as a visual progress bar with percentage and count.\n * @param progress - Progress tracking information\n * @returns Formatted string with colored progress bar, percentage, and count\n * @private\n * @example \"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 35% (7/20 files)\"\n */\nfunction formatProgress(progress: ProgressInfo): string {\n const { current, total, unit } = progress\n const percentage = Math.round((current / total) * 100)\n const bar = renderProgressBar(percentage)\n const count = unit ? `${current}/${total} ${unit}` : `${current}/${total}`\n return `${bar} ${percentage}% (${count})`\n}\n\n/**\n * Render a progress bar using block characters (\u2588 for filled, \u2591 for empty).\n * @param percentage - Progress percentage (0-100)\n * @param width - Total width of progress bar in characters\n * @returns Colored progress bar string\n * @default width=20\n * @private\n */\nfunction renderProgressBar(percentage: number, width: number = 20): string {\n const filled = Math.round((percentage / 100) * width)\n const empty = width - filled\n const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(empty)\n // Use cyan color for the progress bar\n const colors =\n /*@__PURE__*/ require('./external/yoctocolors-cjs') as typeof import('yoctocolors-cjs')\n return colors.cyan(bar)\n}\n\nlet _cliSpinners: Record<string, SpinnerStyle> | undefined\n\n/**\n * Get available CLI spinner styles or a specific style by name.\n * Extends the standard cli-spinners collection with Socket custom spinners.\n *\n * Custom spinners:\n * - `socket` (default): Socket pulse animation with sparkles and lightning\n *\n * @param styleName - Optional name of specific spinner style to retrieve\n * @returns Specific spinner style if name provided, all styles if omitted, `undefined` if style not found\n * @see https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json\n *\n * @example\n * ```ts\n * // Get all available spinner styles\n * const allSpinners = getCliSpinners()\n *\n * // Get specific style\n * const socketStyle = getCliSpinners('socket')\n * const dotsStyle = getCliSpinners('dots')\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function getCliSpinners(\n styleName?: string | undefined,\n): SpinnerStyle | Record<string, SpinnerStyle> | undefined {\n if (_cliSpinners === undefined) {\n const YoctoCtor: any = yoctoSpinner as any\n // Get the YoctoSpinner class to access static properties.\n const tempInstance: any = YoctoCtor({})\n const YoctoSpinnerClass: any = tempInstance.constructor as any\n // Extend the standard cli-spinners collection with Socket custom spinners.\n _cliSpinners = {\n __proto__: null,\n ...YoctoSpinnerClass.spinners,\n socket: generateSocketSpinnerFrames(),\n }\n }\n if (typeof styleName === 'string' && _cliSpinners) {\n return hasOwn(_cliSpinners, styleName) ? _cliSpinners[styleName] : undefined\n }\n return _cliSpinners\n}\n\nlet _Spinner: {\n new (options?: SpinnerOptions | undefined): Spinner\n}\nlet _defaultSpinner: SpinnerStyle | undefined\n\n/**\n * Create a spinner instance for displaying loading indicators.\n * Provides an animated CLI spinner with status messages, progress tracking, and shimmer effects.\n *\n * AUTO-CLEAR BEHAVIOR:\n * - All *AndStop() methods AUTO-CLEAR the spinner line via yocto-spinner.stop()\n * Examples: `doneAndStop()`, `successAndStop()`, `failAndStop()`, etc.\n *\n * - Methods WITHOUT \"AndStop\" do NOT clear (spinner keeps spinning)\n * Examples: `done()`, `success()`, `fail()`, etc.\n *\n * STREAM USAGE:\n * - Spinner animation: stderr (yocto-spinner default)\n * - Status methods (done, success, fail, info, warn, step, substep): stderr\n * - Data methods (`log()`): stdout\n *\n * COMPARISON WITH LOGGER:\n * - `logger.done()` does NOT auto-clear (requires manual `logger.clearLine()`)\n * - `spinner.doneAndStop()` DOES auto-clear (built into yocto-spinner.stop())\n * - Pattern: `logger.clearLine().done()` vs `spinner.doneAndStop()`\n *\n * @param options - Configuration options for the spinner\n * @returns New spinner instance\n *\n * @example\n * ```ts\n * import { Spinner } from '@socketsecurity/lib/spinner'\n *\n * // Basic usage\n * const spinner = Spinner({ text: 'Loading data\u2026' })\n * spinner.start()\n * await fetchData()\n * spinner.successAndStop('Data loaded!')\n *\n * // With custom color\n * const spinner = Spinner({\n * text: 'Processing\u2026',\n * color: [255, 0, 0] // Red\n * })\n *\n * // With shimmer effect\n * const spinner = Spinner({\n * text: 'Building\u2026',\n * shimmer: { dir: 'ltr', speed: 0.5 }\n * })\n *\n * // Show progress\n * spinner.progress(5, 10, 'files')\n * spinner.progressStep() // Increment by 1\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function Spinner(options?: SpinnerOptions | undefined): Spinner {\n if (_Spinner === undefined) {\n const YoctoCtor = yoctoSpinner as any\n // Get the actual YoctoSpinner class from an instance\n const tempInstance = YoctoCtor({})\n const YoctoSpinnerClass = tempInstance.constructor\n const logger = getDefaultLogger()\n\n /*@__PURE__*/\n _Spinner = class SpinnerClass extends (YoctoSpinnerClass as any) {\n declare isSpinning: boolean\n #baseText: string = ''\n #indentation: string = ''\n #progress?: ProgressInfo | undefined\n #shimmer?: ShimmerInfo | undefined\n #shimmerSavedConfig?: ShimmerInfo | undefined\n\n constructor(options?: SpinnerOptions | undefined) {\n const opts = { __proto__: null, ...options } as SpinnerOptions\n\n // Get theme from options or current theme\n let theme = getTheme()\n if (opts.theme) {\n // Resolve theme name or use Theme object directly\n if (typeof opts.theme === 'string') {\n theme = THEMES[opts.theme]\n } else {\n theme = opts.theme\n }\n }\n\n // Get default color from theme if not specified\n let defaultColor: ColorValue = theme.colors.primary\n if (theme.effects?.spinner?.color) {\n const resolved = resolveColor(\n theme.effects.spinner.color,\n theme.colors,\n )\n // resolveColor can return 'inherit' or gradients which aren't valid for spinner\n // Fall back to primary for these cases\n if (resolved === 'inherit' || Array.isArray(resolved[0])) {\n defaultColor = theme.colors.primary\n } else {\n defaultColor = resolved as ColorValue\n }\n }\n\n // Convert color option to RGB (default from theme).\n const spinnerColor = opts.color ?? defaultColor\n\n // Validate RGB tuple if provided.\n if (\n isRgbTuple(spinnerColor) &&\n (spinnerColor.length !== 3 ||\n !spinnerColor.every(\n n => typeof n === 'number' && n >= 0 && n <= 255,\n ))\n ) {\n throw new TypeError(\n 'RGB color must be an array of 3 numbers between 0 and 255',\n )\n }\n\n const spinnerColorRgb = toRgb(spinnerColor)\n\n // Parse shimmer config - can be object or direction string.\n let shimmerInfo: ShimmerInfo | undefined\n if (opts.shimmer) {\n let shimmerDir: ShimmerDirection\n let shimmerColor:\n | ColorInherit\n | ColorValue\n | ShimmerColorGradient\n | undefined\n // Default: 0.33 steps per frame (~150ms per step).\n let shimmerSpeed: number = 1 / 3\n\n if (typeof opts.shimmer === 'string') {\n shimmerDir = opts.shimmer\n } else {\n const shimmerConfig = {\n __proto__: null,\n ...opts.shimmer,\n } as ShimmerConfig\n shimmerDir = shimmerConfig.dir ?? DIR_LTR\n shimmerColor = shimmerConfig.color ?? COLOR_INHERIT\n shimmerSpeed = shimmerConfig.speed ?? 1 / 3\n }\n\n // Create shimmer info with initial animation state:\n // - COLOR_INHERIT means use spinner color dynamically\n // - ColorValue (name or RGB tuple) is an explicit override color\n // - undefined color defaults to COLOR_INHERIT\n // - speed controls steps per frame (lower = slower, e.g., 0.33 = ~150ms per step)\n shimmerInfo = {\n __proto__: null,\n color: shimmerColor === undefined ? COLOR_INHERIT : shimmerColor,\n currentDir: DIR_LTR,\n mode: shimmerDir,\n speed: shimmerSpeed,\n step: 0,\n } as ShimmerInfo\n }\n\n // eslint-disable-next-line constructor-super\n super({\n signal: require('#constants/process').getAbortSignal(),\n ...opts,\n // Pass RGB color directly to yocto-spinner (it now supports RGB).\n color: spinnerColorRgb,\n // onRenderFrame callback provides full control over frame + text layout.\n // Calculates spacing based on frame width to prevent text jumping.\n onRenderFrame: (\n frame: string,\n text: string,\n applyColor: (text: string) => string,\n ) => {\n const width = stringWidth(frame)\n // Narrow frames (width 1) get 2 spaces, wide frames (width 2) get 1 space.\n // Total width is consistent: 3 characters (frame + spacing) before text.\n const spacing = width === 1 ? ' ' : ' '\n return frame ? `${applyColor(frame)}${spacing}${text}` : text\n },\n // onFrameUpdate callback is called by yocto-spinner whenever a frame advances.\n // This ensures shimmer updates are perfectly synchronized with animation beats.\n onFrameUpdate: shimmerInfo\n ? () => {\n // Update parent's text without triggering render.\n // Parent's #skipRender flag prevents nested render calls.\n // Only update if we have base text to avoid blank frames.\n if (this.#baseText) {\n super.text = this.#buildDisplayText()\n }\n }\n : undefined,\n })\n\n this.#shimmer = shimmerInfo\n this.#shimmerSavedConfig = shimmerInfo\n }\n\n // Override color getter to ensure it's always RGB.\n get color(): ColorRgb {\n const value = super.color\n return isRgbTuple(value) ? value : toRgb(value)\n }\n\n // Override color setter to always convert to RGB before passing to yocto-spinner.\n set color(value: ColorValue | ColorRgb) {\n super.color = isRgbTuple(value) ? value : toRgb(value)\n }\n\n // Getter to expose current shimmer state.\n get shimmerState(): ShimmerInfo | undefined {\n if (!this.#shimmer) {\n return undefined\n }\n return {\n color: this.#shimmer.color,\n currentDir: this.#shimmer.currentDir,\n mode: this.#shimmer.mode,\n speed: this.#shimmer.speed,\n step: this.#shimmer.step,\n } as ShimmerInfo\n }\n\n /**\n * Apply a yocto-spinner method and update logger state.\n * Handles text normalization, extra arguments, and logger tracking.\n * @private\n */\n #apply(methodName: string, args: unknown[]) {\n let extras: unknown[]\n let text = args.at(0)\n if (typeof text === 'string') {\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n const wasSpinning = this.isSpinning\n const normalized = normalizeText(text)\n if (methodName === 'stop' && !normalized) {\n super[methodName]()\n } else {\n super[methodName](normalized)\n }\n if (methodName === 'stop') {\n if (wasSpinning && normalized) {\n logger[lastWasBlankSymbol](isBlankString(normalized))\n logger[incLogCallCountSymbol]()\n }\n } else {\n logger[lastWasBlankSymbol](false)\n logger[incLogCallCountSymbol]()\n }\n if (extras.length) {\n logger.log(...extras)\n logger[lastWasBlankSymbol](false)\n }\n return this\n }\n\n /**\n * Build the complete display text with progress, shimmer, and indentation.\n * Combines base text, progress bar, shimmer effects, and indentation.\n * @private\n */\n #buildDisplayText() {\n let displayText = this.#baseText\n\n if (this.#progress) {\n const progressText = formatProgress(this.#progress)\n displayText = displayText\n ? `${displayText} ${progressText}`\n : progressText\n }\n\n // Apply shimmer effect if enabled.\n if (displayText && this.#shimmer) {\n // If shimmer color is 'inherit', use current spinner color (getter ensures RGB).\n // Otherwise, check if it's a gradient (array of arrays) or single color.\n let shimmerColor: ColorRgb | ShimmerColorGradient\n if (this.#shimmer.color === COLOR_INHERIT) {\n shimmerColor = this.color\n } else if (Array.isArray(this.#shimmer.color[0])) {\n // It's a gradient - use as is.\n shimmerColor = this.#shimmer.color as ShimmerColorGradient\n } else {\n // It's a single color - convert to RGB.\n shimmerColor = toRgb(this.#shimmer.color as ColorValue)\n }\n\n displayText = applyShimmer(displayText, this.#shimmer, {\n color: shimmerColor,\n direction: this.#shimmer.mode,\n })\n }\n\n // Apply indentation\n if (this.#indentation && displayText) {\n displayText = this.#indentation + displayText\n }\n\n return displayText\n }\n\n /**\n * Show a status message without stopping the spinner.\n * Outputs the symbol and message to stderr, then continues spinning.\n */\n #showStatusAndKeepSpinning(symbolType: SymbolType, args: unknown[]) {\n let text = args.at(0)\n let extras: unknown[]\n if (typeof text === 'string') {\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n\n // Note: Status messages always go to stderr.\n logger.error(`${LOG_SYMBOLS[symbolType]} ${text}`, ...extras)\n return this\n }\n\n /**\n * Update the spinner's displayed text.\n * Rebuilds display text and triggers render.\n * @private\n */\n #updateSpinnerText() {\n // Call the parent class's text setter, which triggers render.\n super.text = this.#buildDisplayText()\n }\n\n /**\n * Show a debug message (\u2139) without stopping the spinner.\n * Only displays if debug mode is enabled via environment variable.\n * Outputs to stderr and continues spinning.\n *\n * @param text - Debug message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n debug(text?: string | undefined, ...extras: unknown[]) {\n if (isDebug()) {\n return this.#showStatusAndKeepSpinning('info', [text, ...extras])\n }\n return this\n }\n\n /**\n * Show a debug message (\u2139) and stop the spinner.\n * Only displays if debug mode is enabled via environment variable.\n * Auto-clears the spinner line before displaying the message.\n *\n * @param text - Debug message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n debugAndStop(text?: string | undefined, ...extras: unknown[]) {\n if (isDebug()) {\n return this.#apply('info', [text, ...extras])\n }\n return this\n }\n\n /**\n * Decrease indentation level by removing spaces from the left.\n * Pass 0 to reset indentation to zero completely.\n *\n * @param spaces - Number of spaces to remove\n * @returns This spinner for chaining\n * @default spaces=2\n *\n * @example\n * ```ts\n * spinner.dedent() // Remove 2 spaces\n * spinner.dedent(4) // Remove 4 spaces\n * spinner.dedent(0) // Reset to zero indentation\n * ```\n */\n dedent(spaces?: number | undefined) {\n // Pass 0 to reset indentation\n if (spaces === 0) {\n this.#indentation = ''\n } else {\n const amount = spaces ?? 2\n const newLength = Math.max(0, this.#indentation.length - amount)\n this.#indentation = this.#indentation.slice(0, newLength)\n }\n this.#updateSpinnerText()\n return this\n }\n\n /**\n * Show a done/success message (\u2713) without stopping the spinner.\n * Alias for `success()` with a shorter name.\n *\n * DESIGN DECISION: Unlike yocto-spinner, our `done()` does NOT stop the spinner.\n * Use `doneAndStop()` if you want to stop the spinner.\n *\n * @param text - Message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n done(text?: string | undefined, ...extras: unknown[]) {\n return this.#showStatusAndKeepSpinning('success', [text, ...extras])\n }\n\n /**\n * Show a done/success message (\u2713) and stop the spinner.\n * Auto-clears the spinner line before displaying the success message.\n *\n * @param text - Message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n doneAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('success', [text, ...extras])\n }\n\n /**\n * Show a failure message (\u2717) without stopping the spinner.\n * DESIGN DECISION: Unlike yocto-spinner, our `fail()` does NOT stop the spinner.\n * This allows displaying errors while continuing to spin.\n * Use `failAndStop()` if you want to stop the spinner.\n *\n * @param text - Error message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n fail(text?: string | undefined, ...extras: unknown[]) {\n return this.#showStatusAndKeepSpinning('fail', [text, ...extras])\n }\n\n /**\n * Show a failure message (\u2717) and stop the spinner.\n * Auto-clears the spinner line before displaying the error message.\n *\n * @param text - Error message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n failAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('error', [text, ...extras])\n }\n\n /**\n * Increase indentation level by adding spaces to the left.\n * Pass 0 to reset indentation to zero completely.\n *\n * @param spaces - Number of spaces to add\n * @returns This spinner for chaining\n * @default spaces=2\n *\n * @example\n * ```ts\n * spinner.indent() // Add 2 spaces\n * spinner.indent(4) // Add 4 spaces\n * spinner.indent(0) // Reset to zero indentation\n * ```\n */\n indent(spaces?: number | undefined) {\n // Pass 0 to reset indentation\n if (spaces === 0) {\n this.#indentation = ''\n } else {\n const amount = spaces ?? 2\n this.#indentation += ' '.repeat(amount)\n }\n this.#updateSpinnerText()\n return this\n }\n\n /**\n * Show an info message (\u2139) without stopping the spinner.\n * Outputs to stderr and continues spinning.\n *\n * @param text - Info message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n info(text?: string | undefined, ...extras: unknown[]) {\n return this.#showStatusAndKeepSpinning('info', [text, ...extras])\n }\n\n /**\n * Show an info message (\u2139) and stop the spinner.\n * Auto-clears the spinner line before displaying the message.\n *\n * @param text - Info message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n infoAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('info', [text, ...extras])\n }\n\n /**\n * Log a message to stdout without stopping the spinner.\n * Unlike other status methods, this outputs to stdout for data logging.\n *\n * @param args - Values to log to stdout\n * @returns This spinner for chaining\n */\n log(...args: unknown[]) {\n logger.log(...args)\n return this\n }\n\n /**\n * Log a message to stdout and stop the spinner.\n * Auto-clears the spinner line before displaying the message.\n *\n * @param text - Message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n logAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('stop', [text, ...extras])\n }\n\n /**\n * Update progress information displayed with the spinner.\n * Shows a progress bar with percentage and optional unit label.\n *\n * @param current - Current progress value\n * @param total - Total/maximum progress value\n * @param unit - Optional unit label (e.g., 'files', 'items')\n * @returns This spinner for chaining\n *\n * @example\n * ```ts\n * spinner.progress(5, 10) // \"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 50% (5/10)\"\n * spinner.progress(7, 20, 'files') // \"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 35% (7/20 files)\"\n * ```\n */\n progress = (\n current: number,\n total: number,\n unit?: string | undefined,\n ) => {\n this.#progress = {\n __proto__: null,\n current,\n total,\n ...(unit ? { unit } : {}),\n } as ProgressInfo\n this.#updateSpinnerText()\n return this\n }\n\n /**\n * Increment progress by a specified amount.\n * Updates the progress bar displayed with the spinner.\n * Clamps the result between 0 and the total value.\n *\n * @param amount - Amount to increment by\n * @returns This spinner for chaining\n * @default amount=1\n *\n * @example\n * ```ts\n * spinner.progress(0, 10, 'files')\n * spinner.progressStep() // Progress: 1/10\n * spinner.progressStep(3) // Progress: 4/10\n * ```\n */\n progressStep(amount: number = 1) {\n if (this.#progress) {\n const newCurrent = this.#progress.current + amount\n this.#progress = {\n __proto__: null,\n current: Math.max(0, Math.min(newCurrent, this.#progress.total)),\n total: this.#progress.total,\n ...(this.#progress.unit ? { unit: this.#progress.unit } : {}),\n } as ProgressInfo\n this.#updateSpinnerText()\n }\n return this\n }\n\n /**\n * Start the spinner animation with optional text.\n * Begins displaying the animated spinner on stderr.\n *\n * @param text - Optional text to display with the spinner\n * @returns This spinner for chaining\n *\n * @example\n * ```ts\n * spinner.start('Loading\u2026')\n * // Later:\n * spinner.successAndStop('Done!')\n * ```\n */\n start(...args: unknown[]) {\n if (args.length) {\n const text = args.at(0)\n const normalized = normalizeText(text)\n // We clear this.text on start when `text` is falsy because yocto-spinner\n // will not clear it otherwise.\n if (!normalized) {\n this.#baseText = ''\n super.text = ''\n } else {\n this.#baseText = normalized\n }\n }\n\n this.#updateSpinnerText()\n // Don't pass text to yocto-spinner.start() since we already set it via #updateSpinnerText().\n // Passing args would cause duplicate message output.\n return this.#apply('start', [])\n }\n\n /**\n * Log a main step message to stderr without stopping the spinner.\n * Adds a blank line before the message for visual separation.\n * Aligns with `logger.step()` to use stderr for status messages.\n *\n * @param text - Step message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n *\n * @example\n * ```ts\n * spinner.step('Building application')\n * spinner.substep('Compiling TypeScript')\n * spinner.substep('Bundling assets')\n * ```\n */\n step(text?: string | undefined, ...extras: unknown[]) {\n if (typeof text === 'string') {\n // Add blank line before step for visual separation.\n logger.error('')\n // Use error (stderr) to align with logger.step() default stream.\n logger.error(text, ...extras)\n }\n return this\n }\n\n /**\n * Log an indented substep message to stderr without stopping the spinner.\n * Adds 2-space indentation to the message.\n * Aligns with `logger.substep()` to use stderr for status messages.\n *\n * @param text - Substep message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n *\n * @example\n * ```ts\n * spinner.step('Building application')\n * spinner.substep('Compiling TypeScript')\n * spinner.substep('Bundling assets')\n * ```\n */\n substep(text?: string | undefined, ...extras: unknown[]) {\n if (typeof text === 'string') {\n // Add 2-space indent for substep.\n // Use error (stderr) to align with logger.substep() default stream.\n logger.error(` ${text}`, ...extras)\n }\n return this\n }\n\n /**\n * Stop the spinner animation and clear internal state.\n * Auto-clears the spinner line via yocto-spinner.stop().\n * Resets progress, shimmer, and text state.\n *\n * @param text - Optional final text to display after stopping\n * @returns This spinner for chaining\n *\n * @example\n * ```ts\n * spinner.start('Processing\u2026')\n * // Do work\n * spinner.stop() // Just stop, no message\n * // or\n * spinner.stop('Finished processing')\n * ```\n */\n stop(...args: unknown[]) {\n // Clear the spinner text BEFORE stopping to prevent ghost frames.\n // This ensures the terminal line is fully cleared before we stop the animation.\n if (!args.length || !args[0]) {\n super.text = ''\n }\n\n // Clear internal state.\n this.#baseText = ''\n this.#progress = undefined\n // Reset shimmer animation state if shimmer is enabled.\n if (this.#shimmer) {\n this.#shimmer.currentDir = DIR_LTR\n this.#shimmer.step = 0\n }\n // Call parent stop (clears screen, sets isSpinning = false).\n const result = this.#apply('stop', args)\n // Ensure text is cleared after stop completes.\n super.text = ''\n return result\n }\n\n /**\n * Show a success message (\u2713) without stopping the spinner.\n * DESIGN DECISION: Unlike yocto-spinner, our `success()` does NOT stop the spinner.\n * This allows displaying success messages while continuing to spin for multi-step operations.\n * Use `successAndStop()` if you want to stop the spinner.\n *\n * @param text - Success message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n success(text?: string | undefined, ...extras: unknown[]) {\n return this.#showStatusAndKeepSpinning('success', [text, ...extras])\n }\n\n /**\n * Show a success message (\u2713) and stop the spinner.\n * Auto-clears the spinner line before displaying the success message.\n *\n * @param text - Success message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n successAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('success', [text, ...extras])\n }\n\n /**\n * Get or set the spinner text.\n * When called with no arguments, returns the current base text.\n * When called with text, updates the display and returns the spinner for chaining.\n *\n * @param value - Text to display (omit to get current text)\n * @returns Current text (getter) or this spinner (setter)\n *\n * @example\n * ```ts\n * // Setter\n * spinner.text('Loading data\u2026')\n * spinner.text('Processing\u2026')\n *\n * // Getter\n * const current = spinner.text()\n * console.log(current) // \"Processing\u2026\"\n * ```\n */\n text(): string\n text(value: string): Spinner\n text(value?: string): string | Spinner {\n // biome-ignore lint/complexity/noArguments: Function overload for getter/setter pattern.\n if (arguments.length === 0) {\n // Getter: return current base text\n return this.#baseText\n }\n // Setter: update base text and refresh display\n this.#baseText = value ?? ''\n this.#updateSpinnerText()\n return this as unknown as Spinner\n }\n\n /**\n * Show a warning message (\u26A0) without stopping the spinner.\n * Outputs to stderr and continues spinning.\n *\n * @param text - Warning message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n warn(text?: string | undefined, ...extras: unknown[]) {\n return this.#showStatusAndKeepSpinning('warn', [text, ...extras])\n }\n\n /**\n * Show a warning message (\u26A0) and stop the spinner.\n * Auto-clears the spinner line before displaying the warning message.\n *\n * @param text - Warning message to display\n * @param extras - Additional values to log\n * @returns This spinner for chaining\n */\n warnAndStop(text?: string | undefined, ...extras: unknown[]) {\n return this.#apply('warning', [text, ...extras])\n }\n\n /**\n * Enable shimmer effect.\n * Restores saved config or uses defaults if no saved config exists.\n *\n * @returns This spinner for chaining\n *\n * @example\n * spinner.enableShimmer()\n */\n enableShimmer(): Spinner {\n if (this.#shimmerSavedConfig) {\n // Restore saved config.\n this.#shimmer = { ...this.#shimmerSavedConfig }\n } else {\n // Create default config.\n this.#shimmer = {\n color: COLOR_INHERIT,\n currentDir: DIR_LTR,\n mode: DIR_LTR,\n speed: 1 / 3,\n step: 0,\n } as ShimmerInfo\n this.#shimmerSavedConfig = this.#shimmer\n }\n\n this.#updateSpinnerText()\n return this as unknown as Spinner\n }\n\n /**\n * Disable shimmer effect.\n * Preserves config for later re-enable via enableShimmer().\n *\n * @returns This spinner for chaining\n *\n * @example\n * spinner.disableShimmer()\n */\n disableShimmer(): Spinner {\n // Disable shimmer but preserve config.\n this.#shimmer = undefined\n this.#updateSpinnerText()\n return this as unknown as Spinner\n }\n\n /**\n * Set complete shimmer configuration.\n * Replaces any existing shimmer config with the provided values.\n * Undefined properties will use default values.\n *\n * @param config - Complete shimmer configuration\n * @returns This spinner for chaining\n *\n * @example\n * spinner.setShimmer({\n * color: [255, 0, 0],\n * dir: 'rtl',\n * speed: 0.5\n * })\n */\n setShimmer(config: ShimmerConfig): Spinner {\n this.#shimmer = {\n color: config.color ?? COLOR_INHERIT,\n currentDir: DIR_LTR,\n mode: config.dir ?? DIR_LTR,\n speed: config.speed ?? 1 / 3,\n step: 0,\n } as ShimmerInfo\n this.#shimmerSavedConfig = this.#shimmer\n this.#updateSpinnerText()\n return this as unknown as Spinner\n }\n\n /**\n * Update partial shimmer configuration.\n * Merges with existing config, enabling shimmer if currently disabled.\n *\n * @param config - Partial shimmer configuration to merge\n * @returns This spinner for chaining\n *\n * @example\n * // Update just the speed\n * spinner.updateShimmer({ speed: 0.5 })\n *\n * // Update direction\n * spinner.updateShimmer({ dir: 'rtl' })\n *\n * // Update multiple properties\n * spinner.updateShimmer({ color: [255, 0, 0], speed: 0.8 })\n */\n updateShimmer(config: Partial<ShimmerConfig>): Spinner {\n const partialConfig = {\n __proto__: null,\n ...config,\n } as Partial<ShimmerConfig>\n\n if (this.#shimmer) {\n // Update existing shimmer.\n this.#shimmer = {\n ...this.#shimmer,\n ...(partialConfig.color !== undefined\n ? { color: partialConfig.color }\n : {}),\n ...(partialConfig.dir !== undefined\n ? { mode: partialConfig.dir }\n : {}),\n ...(partialConfig.speed !== undefined\n ? { speed: partialConfig.speed }\n : {}),\n } as ShimmerInfo\n this.#shimmerSavedConfig = this.#shimmer\n } else if (this.#shimmerSavedConfig) {\n // Restore and update.\n this.#shimmer = {\n ...this.#shimmerSavedConfig,\n ...(partialConfig.color !== undefined\n ? { color: partialConfig.color }\n : {}),\n ...(partialConfig.dir !== undefined\n ? { mode: partialConfig.dir }\n : {}),\n ...(partialConfig.speed !== undefined\n ? { speed: partialConfig.speed }\n : {}),\n } as ShimmerInfo\n this.#shimmerSavedConfig = this.#shimmer\n } else {\n // Create new with partial config.\n this.#shimmer = {\n color: partialConfig.color ?? COLOR_INHERIT,\n currentDir: DIR_LTR,\n mode: partialConfig.dir ?? DIR_LTR,\n speed: partialConfig.speed ?? 1 / 3,\n step: 0,\n } as ShimmerInfo\n this.#shimmerSavedConfig = this.#shimmer\n }\n\n this.#updateSpinnerText()\n return this as unknown as Spinner\n }\n } as unknown as {\n new (options?: SpinnerOptions | undefined): Spinner\n }\n // Add aliases.\n Object.defineProperties(_Spinner.prototype, {\n error: desc(_Spinner.prototype.fail),\n errorAndStop: desc(_Spinner.prototype.failAndStop),\n warning: desc(_Spinner.prototype.warn),\n warningAndStop: desc(_Spinner.prototype.warnAndStop),\n })\n _defaultSpinner = getCI()\n ? ciSpinner\n : (getCliSpinners('socket') as SpinnerStyle)\n }\n return new _Spinner({\n spinner: _defaultSpinner,\n ...options,\n })\n}\n\nlet _spinner: ReturnType<typeof Spinner> | undefined\n\n/**\n * Get the default spinner instance.\n * Lazily creates the spinner to avoid circular dependencies during module initialization.\n * Reuses the same instance across calls.\n *\n * @returns Shared default spinner instance\n *\n * @example\n * ```ts\n * import { getDefaultSpinner } from '@socketsecurity/lib/spinner'\n *\n * const spinner = getDefaultSpinner()\n * spinner.start('Loading\u2026')\n * ```\n */\nexport function getDefaultSpinner(): ReturnType<typeof Spinner> {\n if (_spinner === undefined) {\n _spinner = Spinner()\n }\n return _spinner\n}\n\n// REMOVED: Deprecated `spinner` export\n// Migration: Use getDefaultSpinner() instead\n// See: getDefaultSpinner() function above\n\n/**\n * Configuration options for `withSpinner()` helper.\n * @template T - Return type of the async operation\n */\nexport type WithSpinnerOptions<T> = {\n /** Message to display while the spinner is running */\n message: string\n /** Async function to execute while spinner is active */\n operation: () => Promise<T>\n /**\n * Optional spinner instance to use.\n * If not provided, operation runs without spinner.\n */\n spinner?: Spinner | undefined\n /**\n * Optional spinner options to apply during the operation.\n * These options will be pushed when the operation starts and popped when it completes.\n * Supports color and shimmer configuration.\n */\n withOptions?: Partial<Pick<SpinnerOptions, 'color' | 'shimmer'>> | undefined\n}\n\n/**\n * Execute an async operation with spinner lifecycle management.\n * Ensures `spinner.stop()` is always called via try/finally, even if the operation throws.\n * Provides safe cleanup and consistent spinner behavior.\n *\n * @template T - Return type of the operation\n * @param options - Configuration object\n * @param options.message - Message to display while spinner is running\n * @param options.operation - Async function to execute\n * @param options.spinner - Optional spinner instance (if not provided, no spinner is used)\n * @returns Result of the operation\n * @throws Re-throws any error from operation after stopping spinner\n *\n * @example\n * ```ts\n * import { Spinner, withSpinner } from '@socketsecurity/lib/spinner'\n *\n * const spinner = Spinner()\n *\n * // With spinner instance\n * const result = await withSpinner({\n * message: 'Processing\u2026',\n * operation: async () => {\n * return await processData()\n * },\n * spinner\n * })\n *\n * // Without spinner instance (no-op, just runs operation)\n * const result = await withSpinner({\n * message: 'Processing\u2026',\n * operation: async () => {\n * return await processData()\n * }\n * })\n * ```\n */\nexport async function withSpinner<T>(\n options: WithSpinnerOptions<T>,\n): Promise<T> {\n const { message, operation, spinner, withOptions } = {\n __proto__: null,\n ...options,\n } as WithSpinnerOptions<T>\n\n if (!spinner) {\n return await operation()\n }\n\n // Save current options if we're going to change them\n const savedColor =\n withOptions?.color !== undefined ? spinner.color : undefined\n const savedShimmerState =\n withOptions?.shimmer !== undefined ? spinner.shimmerState : undefined\n\n // Apply temporary options\n if (withOptions?.color !== undefined) {\n spinner.color = toRgb(withOptions.color)\n }\n if (withOptions?.shimmer !== undefined) {\n if (typeof withOptions.shimmer === 'string') {\n spinner.updateShimmer({ dir: withOptions.shimmer })\n } else {\n spinner.setShimmer(withOptions.shimmer)\n }\n }\n\n spinner.start(message)\n try {\n return await operation()\n } finally {\n spinner.stop()\n // Restore previous options\n if (savedColor !== undefined) {\n spinner.color = savedColor\n }\n if (withOptions?.shimmer !== undefined) {\n if (savedShimmerState) {\n spinner.setShimmer({\n color: savedShimmerState.color as any,\n dir: savedShimmerState.mode,\n speed: savedShimmerState.speed,\n })\n } else {\n spinner.disableShimmer()\n }\n }\n }\n}\n\n/**\n * Configuration options for `withSpinnerRestore()` helper.\n * @template T - Return type of the async operation\n */\nexport type WithSpinnerRestoreOptions<T> = {\n /** Async function to execute while spinner is stopped */\n operation: () => Promise<T>\n /** Optional spinner instance to restore after operation */\n spinner?: Spinner | undefined\n /** Whether spinner was spinning before the operation (used to conditionally restart) */\n wasSpinning: boolean\n}\n\n/**\n * Execute an async operation with conditional spinner restart.\n * Useful when you need to temporarily stop a spinner for an operation,\n * then restore it to its previous state (if it was spinning).\n *\n * @template T - Return type of the operation\n * @param options - Configuration object\n * @param options.operation - Async function to execute\n * @param options.spinner - Optional spinner instance to manage\n * @param options.wasSpinning - Whether spinner was spinning before the operation\n * @returns Result of the operation\n * @throws Re-throws any error from operation after restoring spinner state\n *\n * @example\n * ```ts\n * import { getDefaultSpinner, withSpinnerRestore } from '@socketsecurity/lib/spinner'\n *\n * const spinner = getDefaultSpinner()\n * const wasSpinning = spinner.isSpinning\n * spinner.stop()\n *\n * const result = await withSpinnerRestore({\n * operation: async () => {\n * // Do work without spinner\n * return await someOperation()\n * },\n * spinner,\n * wasSpinning\n * })\n * // Spinner is automatically restarted if wasSpinning was true\n * ```\n */\nexport async function withSpinnerRestore<T>(\n options: WithSpinnerRestoreOptions<T>,\n): Promise<T> {\n const { operation, spinner, wasSpinning } = {\n __proto__: null,\n ...options,\n } as WithSpinnerRestoreOptions<T>\n\n try {\n return await operation()\n } finally {\n if (spinner && wasSpinning) {\n spinner.start()\n }\n }\n}\n\n/**\n * Configuration options for `withSpinnerSync()` helper.\n * @template T - Return type of the sync operation\n */\nexport type WithSpinnerSyncOptions<T> = {\n /** Message to display while the spinner is running */\n message: string\n /** Synchronous function to execute while spinner is active */\n operation: () => T\n /**\n * Optional spinner instance to use.\n * If not provided, operation runs without spinner.\n */\n spinner?: Spinner | undefined\n /**\n * Optional spinner options to apply during the operation.\n * These options will be pushed when the operation starts and popped when it completes.\n * Supports color and shimmer configuration.\n */\n withOptions?: Partial<Pick<SpinnerOptions, 'color' | 'shimmer'>> | undefined\n}\n\n/**\n * Execute a synchronous operation with spinner lifecycle management.\n * Ensures `spinner.stop()` is always called via try/finally, even if the operation throws.\n * Provides safe cleanup and consistent spinner behavior for sync operations.\n *\n * @template T - Return type of the operation\n * @param options - Configuration object\n * @param options.message - Message to display while spinner is running\n * @param options.operation - Synchronous function to execute\n * @param options.spinner - Optional spinner instance (if not provided, no spinner is used)\n * @returns Result of the operation\n * @throws Re-throws any error from operation after stopping spinner\n *\n * @example\n * ```ts\n * import { Spinner, withSpinnerSync } from '@socketsecurity/lib/spinner'\n *\n * const spinner = Spinner()\n *\n * const result = withSpinnerSync({\n * message: 'Processing\u2026',\n * operation: () => {\n * return processDataSync()\n * },\n * spinner\n * })\n * ```\n */\nexport function withSpinnerSync<T>(options: WithSpinnerSyncOptions<T>): T {\n const { message, operation, spinner, withOptions } = {\n __proto__: null,\n ...options,\n } as WithSpinnerSyncOptions<T>\n\n if (!spinner) {\n return operation()\n }\n\n // Save current options if we're going to change them\n const savedColor =\n withOptions?.color !== undefined ? spinner.color : undefined\n const savedShimmerState =\n withOptions?.shimmer !== undefined ? spinner.shimmerState : undefined\n\n // Apply temporary options\n if (withOptions?.color !== undefined) {\n spinner.color = toRgb(withOptions.color)\n }\n if (withOptions?.shimmer !== undefined) {\n if (typeof withOptions.shimmer === 'string') {\n spinner.updateShimmer({ dir: withOptions.shimmer })\n } else {\n spinner.setShimmer(withOptions.shimmer)\n }\n }\n\n spinner.start(message)\n try {\n return operation()\n } finally {\n spinner.stop()\n // Restore previous options\n if (savedColor !== undefined) {\n spinner.color = savedColor\n }\n if (withOptions?.shimmer !== undefined) {\n if (savedShimmerState) {\n spinner.setShimmer({\n color: savedShimmerState.color as any,\n dir: savedShimmerState.mode,\n speed: savedShimmerState.speed,\n })\n } else {\n spinner.disableShimmer()\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["yoctoSpinner", "options"]
|
|
7
|
-
}
|
package/dist/ssri.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/ssri.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview SSRI (Subresource Integrity) hash format utilities.\n * Provides conversion and validation for SSRI and hex hash formats.\n */\n\n/**\n * Convert SSRI format hash to hex format.\n *\n * Takes a hash in SSRI format (e.g., \"sha256-base64hash\") and converts it to\n * standard hex format (e.g., \"hexstring\").\n *\n * @param ssri - Hash in SSRI format (algorithm-base64)\n * @returns Hex string representation of the hash\n * @throws Error if SSRI format is invalid\n *\n * @example\n * ```typescript\n * const hex = ssriToHex('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=')\n * // Returns: '76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856'\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function ssriToHex(ssri: string): string {\n const match = /^([a-z0-9]+)-([A-Za-z0-9+/]+=*)$/i.exec(ssri)\n if (!match || !match[2] || match[2].length < 2) {\n throw new Error(`Invalid SSRI format: ${ssri}`)\n }\n const base64Hash = match[2]\n // Convert base64 to hex.\n const buffer = Buffer.from(base64Hash, 'base64')\n return buffer.toString('hex')\n}\n\n/**\n * Convert hex format hash to SSRI format.\n *\n * Takes a hash in hex format and converts it to SSRI format with the specified\n * algorithm prefix (defaults to sha256).\n *\n * @param hex - Hash in hex format\n * @param algorithm - Hash algorithm (default: 'sha256')\n * @returns SSRI format hash (algorithm-base64)\n * @throws Error if hex format is invalid\n *\n * @example\n * ```typescript\n * const ssri = hexToSsri('76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856')\n * // Returns: 'sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY='\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function hexToSsri(hex: string, algorithm = 'sha256'): string {\n if (!/^[a-f0-9]+$/i.test(hex)) {\n throw new Error(`Invalid hex format: ${hex}`)\n }\n // Convert hex to base64.\n const buffer = Buffer.from(hex, 'hex')\n const base64Hash = buffer.toString('base64')\n return `${algorithm}-${base64Hash}`\n}\n\n/**\n * Check if a string is valid SSRI format.\n *\n * Validates that a string matches the SSRI format pattern (algorithm-base64).\n * Does not verify that the base64 encoding is valid.\n *\n * @param value - String to validate\n * @returns True if string matches SSRI format\n *\n * @example\n * ```typescript\n * isValidSsri('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=') // true\n * isValidSsri('76682a9f...') // false\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isValidSsri(value: string): boolean {\n return /^[a-z0-9]+-[A-Za-z0-9+/]{2,}=*$/i.test(value)\n}\n\n/**\n * Check if a string is valid hex format.\n *\n * Validates that a string contains only hexadecimal characters (0-9, a-f).\n * Does not verify hash length or algorithm.\n *\n * @param value - String to validate\n * @returns True if string is valid hex format\n *\n * @example\n * ```typescript\n * isValidHex('76682a9fc3bbe62975176e2541f39a8168877d828d5cad8b56461fc36ac2b856') // true\n * isValidHex('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=') // false\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function isValidHex(value: string): boolean {\n return /^[a-f0-9]+$/i.test(value)\n}\n\n/**\n * Parse SSRI format into components.\n *\n * Extracts the algorithm and base64 hash from an SSRI string.\n *\n * @param ssri - Hash in SSRI format\n * @returns Object with algorithm and base64Hash properties\n * @throws Error if SSRI format is invalid\n *\n * @example\n * ```typescript\n * const { algorithm, base64Hash } = parseSsri('sha256-dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=')\n * // Returns: { algorithm: 'sha256', base64Hash: 'dmgqn8O75il1F24lQfOagWiHfYKNXK2LVkYfw2rCuFY=' }\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function parseSsri(ssri: string): {\n algorithm: string\n base64Hash: string\n} {\n const match = /^([a-z0-9]+)-([A-Za-z0-9+/]+=*)$/i.exec(ssri)\n if (!match || !match[1] || !match[2] || match[2].length < 2) {\n throw new Error(`Invalid SSRI format: ${ssri}`)\n }\n const algorithm = match[1]\n const base64Hash = match[2]\n return { algorithm, base64Hash }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBO,SAAS,UAAU,MAAsB;AAC9C,QAAM,QAAQ,oCAAoC,KAAK,IAAI;AAC3D,MAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,EAAE,SAAS,GAAG;AAC9C,UAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;AAAA,EAChD;AACA,QAAM,aAAa,MAAM,CAAC;AAE1B,QAAM,SAAS,OAAO,KAAK,YAAY,QAAQ;AAC/C,SAAO,OAAO,SAAS,KAAK;AAC9B;AAAA;AAoBO,SAAS,UAAU,KAAa,YAAY,UAAkB;AACnE,MAAI,CAAC,eAAe,KAAK,GAAG,GAAG;AAC7B,UAAM,IAAI,MAAM,uBAAuB,GAAG,EAAE;AAAA,EAC9C;AAEA,QAAM,SAAS,OAAO,KAAK,KAAK,KAAK;AACrC,QAAM,aAAa,OAAO,SAAS,QAAQ;AAC3C,SAAO,GAAG,SAAS,IAAI,UAAU;AACnC;AAAA;AAkBO,SAAS,YAAY,OAAwB;AAClD,SAAO,mCAAmC,KAAK,KAAK;AACtD;AAAA;AAkBO,SAAS,WAAW,OAAwB;AACjD,SAAO,eAAe,KAAK,KAAK;AAClC;AAAA;AAkBO,SAAS,UAAU,MAGxB;AACA,QAAM,QAAQ,oCAAoC,KAAK,IAAI;AAC3D,MAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,EAAE,SAAS,GAAG;AAC3D,UAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;AAAA,EAChD;AACA,QAAM,YAAY,MAAM,CAAC;AACzB,QAAM,aAAa,MAAM,CAAC;AAC1B,SAAO,EAAE,WAAW,WAAW;AACjC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/stdio/clear.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/clear.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Terminal clearing and cursor utilities.\n * Provides functions for clearing lines, screens, and managing cursor position.\n */\n\n/**\n * Clear the current line in the terminal.\n * Uses native TTY methods when available, falls back to ANSI escape codes.\n *\n * ANSI Sequences:\n * - `\\r`: Carriage return (move to line start)\n * - `\\x1b[K`: Clear from cursor to end of line\n *\n * @param stream - Output stream to clear\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * clearLine() // Clear current line on stdout\n * clearLine(process.stderr) // Clear on stderr\n * ```\n */\nexport function clearLine(stream: NodeJS.WriteStream = process.stdout): void {\n if (stream.isTTY) {\n // TTY: Use cursor control\n stream.cursorTo(0)\n stream.clearLine(0)\n } else {\n // Non-TTY: Use ANSI escape codes\n stream.write('\\r\\x1b[K')\n }\n}\n\n/**\n * Clear multiple lines above the current cursor position.\n * Useful for clearing multi-line output like progress bars or status messages.\n *\n * ANSI Sequences:\n * - `\\x1b[1A`: Move cursor up one line\n * - `\\x1b[2K`: Erase entire line\n *\n * @param count - Number of lines to clear\n * @param stream - Output stream to clear\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * console.log('Line 1')\n * console.log('Line 2')\n * console.log('Line 3')\n * clearLines(2) // Clears lines 2 and 3\n * ```\n */\nexport function clearLines(\n count: number,\n stream: NodeJS.WriteStream = process.stdout,\n): void {\n for (let i = 0; i < count; i++) {\n // Move up and clear line\n stream.write('\\x1b[1A\\x1b[2K')\n }\n}\n\n/**\n * Clear the entire screen and reset cursor to top-left.\n * Only works in TTY environments.\n *\n * ANSI Sequence:\n * - `\\x1bc`: Full reset (clear screen and move cursor home)\n *\n * @param stream - Output stream to clear\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * clearScreen() // Clear entire terminal\n * ```\n */\nexport function clearScreen(stream: NodeJS.WriteStream = process.stdout): void {\n if (stream.isTTY) {\n // Clear screen and move cursor to top-left\n stream.write('\\x1bc')\n }\n}\n\n/**\n * Clear the visible terminal screen.\n * Alias for `clearScreen()`.\n *\n * @param stream - Output stream to clear\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * clearVisible() // Same as clearScreen()\n * ```\n */\nexport function clearVisible(\n stream: NodeJS.WriteStream = process.stdout,\n): void {\n clearScreen(stream)\n}\n\n/**\n * Move cursor to the beginning of the current line.\n * Uses native TTY methods when available, falls back to carriage return.\n *\n * @param stream - Output stream to manipulate\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * process.stdout.write('Some text...')\n * cursorToStart()\n * process.stdout.write('New text') // Overwrites from start\n * ```\n */\nexport function cursorToStart(\n stream: NodeJS.WriteStream = process.stdout,\n): void {\n if (stream.isTTY) {\n stream.cursorTo(0)\n } else {\n stream.write('\\r')\n }\n}\n\n/**\n * Hide the terminal cursor.\n * Useful for cleaner output during animations or progress indicators.\n *\n * ANSI Sequence:\n * - `\\x1b[?25l`: DECTCEM hide cursor\n *\n * @param stream - Output stream to manipulate\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * hideCursor()\n * // ... show animation\n * showCursor()\n * ```\n */\nexport function hideCursor(stream: NodeJS.WriteStream = process.stdout): void {\n stream.write('\\x1b[?25l')\n}\n\n/**\n * Show the terminal cursor.\n * Should be called after `hideCursor()` to restore normal cursor visibility.\n *\n * ANSI Sequence:\n * - `\\x1b[?25h`: DECTCEM show cursor\n *\n * @param stream - Output stream to manipulate\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * hideCursor()\n * // ... show animation\n * showCursor()\n * ```\n */\nexport function showCursor(stream: NodeJS.WriteStream = process.stdout): void {\n stream.write('\\x1b[?25h')\n}\n\n/**\n * Save the current cursor position.\n * Can be restored later with `restoreCursor()`.\n *\n * ANSI Sequence:\n * - `\\x1b7`: DECSC save cursor\n *\n * @param stream - Output stream to manipulate\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * saveCursor()\n * console.log('Temporary text')\n * restoreCursor()\n * console.log('Back at saved position')\n * ```\n */\nexport function saveCursor(stream: NodeJS.WriteStream = process.stdout): void {\n stream.write('\\x1b7')\n}\n\n/**\n * Restore cursor to previously saved position.\n * Must be called after `saveCursor()`.\n *\n * ANSI Sequence:\n * - `\\x1b8`: DECRC restore cursor\n *\n * @param stream - Output stream to manipulate\n * @default stream process.stdout\n *\n * @example\n * ```ts\n * saveCursor()\n * console.log('Temporary text')\n * restoreCursor()\n * console.log('Back at saved position')\n * ```\n */\nexport function restoreCursor(\n stream: NodeJS.WriteStream = process.stdout,\n): void {\n stream.write('\\x1b8')\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBO,SAAS,UAAU,SAA6B,QAAQ,QAAc;AAC3E,MAAI,OAAO,OAAO;AAEhB,WAAO,SAAS,CAAC;AACjB,WAAO,UAAU,CAAC;AAAA,EACpB,OAAO;AAEL,WAAO,MAAM,UAAU;AAAA,EACzB;AACF;AAsBO,SAAS,WACd,OACA,SAA6B,QAAQ,QAC/B;AACN,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAE9B,WAAO,MAAM,gBAAgB;AAAA,EAC/B;AACF;AAiBO,SAAS,YAAY,SAA6B,QAAQ,QAAc;AAC7E,MAAI,OAAO,OAAO;AAEhB,WAAO,MAAM,OAAO;AAAA,EACtB;AACF;AAcO,SAAS,aACd,SAA6B,QAAQ,QAC/B;AACN,cAAY,MAAM;AACpB;AAgBO,SAAS,cACd,SAA6B,QAAQ,QAC/B;AACN,MAAI,OAAO,OAAO;AAChB,WAAO,SAAS,CAAC;AAAA,EACnB,OAAO;AACL,WAAO,MAAM,IAAI;AAAA,EACnB;AACF;AAmBO,SAAS,WAAW,SAA6B,QAAQ,QAAc;AAC5E,SAAO,MAAM,WAAW;AAC1B;AAmBO,SAAS,WAAW,SAA6B,QAAQ,QAAc;AAC5E,SAAO,MAAM,WAAW;AAC1B;AAoBO,SAAS,WAAW,SAA6B,QAAQ,QAAc;AAC5E,SAAO,MAAM,OAAO;AACtB;AAoBO,SAAS,cACd,SAA6B,QAAQ,QAC/B;AACN,SAAO,MAAM,OAAO;AACtB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/divider.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Console divider and separator utilities.\n * Provides various line styles for visual separation in CLI output.\n */\n\nimport { repeatString } from '../strings'\n\nexport interface DividerOptions {\n /**\n * Width of the divider line in characters.\n * @default 55\n */\n width?: number | undefined\n /**\n * Character to repeat for the divider line.\n * @default '\u2550'\n */\n char?: string | undefined\n /**\n * Optional color function to apply to the divider.\n * Accepts a function from `yoctocolors` or similar.\n */\n color?: ((text: string) => string) | undefined\n}\n\n/**\n * Create a divider line with custom character and width.\n * Returns a string of repeated characters for visual separation.\n *\n * @param options - Divider formatting options\n * @returns Divider string\n *\n * @example\n * ```ts\n * console.log(divider()) // Default: 55 '\u2550' characters\n * console.log(divider({ char: '-', width: 40 }))\n * console.log(divider({ char: '\u00B7', width: 30 }))\n * ```\n */\nexport function divider(options?: DividerOptions): string {\n const opts = { __proto__: null, ...options } as DividerOptions\n const { char = '\u2550', width = 55 } = opts\n return repeatString(char, width)\n}\n\n/**\n * Print a divider line directly to console.\n *\n * @param options - Divider formatting options\n *\n * @example\n * ```ts\n * printDivider() // Prints default divider\n * printDivider({ char: '\u2500', width: 60 })\n * ```\n */\nexport function printDivider(options?: DividerOptions): void {\n console.log(divider(options))\n}\n\n/**\n * Common divider style presets.\n * Provides quick access to popular divider styles.\n *\n * @example\n * ```ts\n * console.log(dividers.thick()) // \u2550\u2550\u2550\u2550\u2550\u2550\u2550...\n * console.log(dividers.thin()) // \u2500\u2500\u2500\u2500\u2500\u2500\u2500...\n * console.log(dividers.dotted()) // \u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7...\n * ```\n */\nexport const dividers = {\n /** Thick double-line divider using `\u2550` */\n thick: () => divider({ char: '\u2550' }),\n /** Thin single-line divider using `\u2500` */\n thin: () => divider({ char: '\u2500' }),\n /** Double-line divider (alias for thick) */\n double: () => divider({ char: '\u2550' }),\n /** Simple single dash divider using `-` */\n single: () => divider({ char: '-' }),\n /** Dotted divider using `\u00B7` */\n dotted: () => divider({ char: '\u00B7' }),\n /** Dashed divider using `\u254C` */\n dashed: () => divider({ char: '\u254C' }),\n /** Wave divider using `~` */\n wave: () => divider({ char: '~' }),\n /** Star divider using `*` */\n star: () => divider({ char: '*' }),\n /** Diamond divider using `\u25C6` */\n diamond: () => divider({ char: '\u25C6' }),\n /** Arrow divider using `\u2192` */\n arrow: () => divider({ char: '\u2192' }),\n} as const\n\n/**\n * Print a thick divider line (default style).\n * Convenience function using `\u2550` character.\n *\n * @example\n * ```ts\n * printThickDivider()\n * // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * ```\n */\nexport function printThickDivider(): void {\n printDivider({ char: '\u2550' })\n}\n\n/**\n * Print a thin divider line.\n * Convenience function using `\u2500` character.\n *\n * @example\n * ```ts\n * printThinDivider()\n * // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * ```\n */\nexport function printThinDivider(): void {\n printDivider({ char: '\u2500' })\n}\n\n/**\n * Print a dotted divider line.\n * Convenience function using `\u00B7` character.\n *\n * @example\n * ```ts\n * printDottedDivider()\n * // \u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\u00B7\n * ```\n */\nexport function printDottedDivider(): void {\n printDivider({ char: '\u00B7' })\n}\n\n/**\n * Create a section break with blank lines before and after the divider.\n * Useful for creating visual separation between major sections.\n *\n * @param options - Divider formatting options\n * @returns Section break string with newlines\n *\n * @example\n * ```ts\n * console.log('Previous section')\n * console.log(sectionBreak())\n * console.log('Next section')\n * // Output:\n * // Previous section\n * //\n * // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * //\n * // Next section\n * ```\n */\nexport function sectionBreak(options?: DividerOptions): string {\n const div = divider(options)\n return `\\n${div}\\n`\n}\n\n/**\n * Print a section break with spacing directly to console.\n *\n * @param options - Divider formatting options\n *\n * @example\n * ```ts\n * console.log('Previous section')\n * printSectionBreak()\n * console.log('Next section')\n * ```\n */\nexport function printSectionBreak(options?: DividerOptions): void {\n console.log(sectionBreak(options))\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,qBAA6B;AAkCtB,SAAS,QAAQ,SAAkC;AACxD,QAAM,OAAO,EAAE,WAAW,MAAM,GAAG,QAAQ;AAC3C,QAAM,EAAE,OAAO,UAAK,QAAQ,GAAG,IAAI;AACnC,aAAO,6BAAa,MAAM,KAAK;AACjC;AAaO,SAAS,aAAa,SAAgC;AAC3D,UAAQ,IAAI,QAAQ,OAAO,CAAC;AAC9B;AAaO,MAAM,WAAW;AAAA;AAAA,EAEtB,OAAO,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AAAA;AAAA,EAElC,MAAM,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AAAA;AAAA,EAEjC,QAAQ,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AAAA;AAAA,EAEnC,QAAQ,MAAM,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA;AAAA,EAEnC,QAAQ,MAAM,QAAQ,EAAE,MAAM,OAAI,CAAC;AAAA;AAAA,EAEnC,QAAQ,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AAAA;AAAA,EAEnC,MAAM,MAAM,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA;AAAA,EAEjC,MAAM,MAAM,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA;AAAA,EAEjC,SAAS,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AAAA;AAAA,EAEpC,OAAO,MAAM,QAAQ,EAAE,MAAM,SAAI,CAAC;AACpC;AAYO,SAAS,oBAA0B;AACxC,eAAa,EAAE,MAAM,SAAI,CAAC;AAC5B;AAYO,SAAS,mBAAyB;AACvC,eAAa,EAAE,MAAM,SAAI,CAAC;AAC5B;AAYO,SAAS,qBAA2B;AACzC,eAAa,EAAE,MAAM,OAAI,CAAC;AAC5B;AAsBO,SAAS,aAAa,SAAkC;AAC7D,QAAM,MAAM,QAAQ,OAAO;AAC3B,SAAO;AAAA,EAAK,GAAG;AAAA;AACjB;AAcO,SAAS,kBAAkB,SAAgC;AAChE,UAAQ,IAAI,aAAa,OAAO,CAAC;AACnC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/stdio/footer.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/footer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Console footer/summary formatting utilities.\n * Provides consistent footer and summary formatting for CLI applications.\n */\n\nimport colors from '../external/yoctocolors-cjs'\nimport { repeatString } from '../strings'\n\nexport interface FooterOptions {\n /**\n * Width of the footer border in characters.\n * @default 80\n */\n width?: number | undefined\n /**\n * Character to use for the border line.\n * @default '='\n */\n borderChar?: string | undefined\n /**\n * Include ISO timestamp in footer.\n * @default false\n */\n showTimestamp?: boolean | undefined\n /**\n * Show duration since start time.\n * @default false\n */\n showDuration?: boolean | undefined\n /**\n * Start time in milliseconds (from Date.now()).\n * Required when `showDuration` is true.\n */\n startTime?: number | undefined\n /**\n * Color to apply to the footer message.\n * @default 'gray'\n */\n color?:\n | 'cyan'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'magenta'\n | 'red'\n | 'gray'\n | undefined\n}\n\nexport interface SummaryStats {\n /** Total number of items processed */\n total?: number | undefined\n /** Number of successful items */\n success?: number | undefined\n /** Number of failed items */\n failed?: number | undefined\n /** Number of skipped items */\n skipped?: number | undefined\n /** Number of warnings */\n warnings?: number | undefined\n /** Number of errors */\n errors?: number | undefined\n /** Duration in milliseconds (timestamp value, not elapsed time) */\n duration?: number | undefined\n}\n\n/**\n * Create a formatted footer with optional message, timestamp, and duration.\n * Useful for marking the end of CLI output or showing completion status.\n *\n * @param message - Optional message to display in footer\n * @param options - Footer formatting options\n * @returns Formatted footer string with border and optional info\n *\n * @example\n * ```ts\n * const startTime = Date.now()\n * // ... do work\n * console.log(createFooter('Build complete', {\n * width: 60,\n * color: 'green',\n * showDuration: true,\n * startTime\n * }))\n * ```\n */\nexport function createFooter(\n message?: string | undefined,\n options?: FooterOptions,\n): string {\n const {\n borderChar = '=',\n color = 'gray',\n showDuration = false,\n showTimestamp = false,\n startTime,\n width = 80,\n } = { __proto__: null, ...options } as FooterOptions\n\n const border = repeatString(borderChar, width)\n const lines: string[] = []\n\n if (message) {\n const colorFn = color && colors[color] ? colors[color] : (s: string) => s\n lines.push(colorFn(message))\n }\n\n if (showTimestamp) {\n const timestamp = new Date().toISOString()\n lines.push(colors.gray(`Completed at: ${timestamp}`))\n }\n\n if (showDuration && startTime) {\n const duration = Date.now() - startTime\n const seconds = (duration / 1000).toFixed(2)\n lines.push(colors.gray(`Duration: ${seconds}s`))\n }\n\n lines.push(border)\n return lines.join('\\n')\n}\n\n/**\n * Create a summary footer with statistics and colored status indicators.\n * Automatically formats success/failure/warning counts with appropriate colors.\n * Useful for test results, build summaries, or batch operation reports.\n *\n * @param stats - Statistics to display in the summary\n * @param options - Footer formatting options\n * @returns Formatted summary footer string with colored indicators\n *\n * @example\n * ```ts\n * console.log(createSummaryFooter({\n * total: 150,\n * success: 145,\n * failed: 3,\n * skipped: 2,\n * warnings: 5\n * }))\n * // Output: Total: 150 | \u2713 145 passed | \u2717 3 failed | \u25CB 2 skipped | \u26A0 5 warnings\n * // ========================================\n * ```\n */\nexport function createSummaryFooter(\n stats: SummaryStats,\n options?: FooterOptions,\n): string {\n const parts: string[] = []\n\n if (stats.total !== undefined) {\n parts.push(`Total: ${stats.total}`)\n }\n\n if (stats.success !== undefined) {\n parts.push(colors.green(`\u2713 ${stats.success} passed`))\n }\n\n if (stats.failed !== undefined && stats.failed > 0) {\n parts.push(colors.red(`\u2717 ${stats.failed} failed`))\n }\n\n if (stats.skipped !== undefined && stats.skipped > 0) {\n parts.push(colors.yellow(`\u25CB ${stats.skipped} skipped`))\n }\n\n if (stats.warnings !== undefined && stats.warnings > 0) {\n parts.push(colors.yellow(`\u26A0 ${stats.warnings} warnings`))\n }\n\n if (stats.errors !== undefined && stats.errors > 0) {\n parts.push(colors.red(`\u2717 ${stats.errors} errors`))\n }\n\n const message = parts.join(' | ')\n return createFooter(message, {\n ...options,\n showDuration: stats.duration !== undefined,\n ...(stats.duration !== undefined && { startTime: stats.duration }),\n })\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,6BAAmB;AACnB,qBAA6B;AAgFtB,SAAS,aACd,SACA,SACQ;AACR,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB;AAAA,IACA,QAAQ;AAAA,EACV,IAAI,EAAE,WAAW,MAAM,GAAG,QAAQ;AAElC,QAAM,aAAS,6BAAa,YAAY,KAAK;AAC7C,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS;AACX,UAAM,UAAU,SAAS,uBAAAA,QAAO,KAAK,IAAI,uBAAAA,QAAO,KAAK,IAAI,CAAC,MAAc;AACxE,UAAM,KAAK,QAAQ,OAAO,CAAC;AAAA,EAC7B;AAEA,MAAI,eAAe;AACjB,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,KAAK,uBAAAA,QAAO,KAAK,iBAAiB,SAAS,EAAE,CAAC;AAAA,EACtD;AAEA,MAAI,gBAAgB,WAAW;AAC7B,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,UAAM,WAAW,WAAW,KAAM,QAAQ,CAAC;AAC3C,UAAM,KAAK,uBAAAA,QAAO,KAAK,aAAa,OAAO,GAAG,CAAC;AAAA,EACjD;AAEA,QAAM,KAAK,MAAM;AACjB,SAAO,MAAM,KAAK,IAAI;AACxB;AAwBO,SAAS,oBACd,OACA,SACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,MAAI,MAAM,UAAU,QAAW;AAC7B,UAAM,KAAK,UAAU,MAAM,KAAK,EAAE;AAAA,EACpC;AAEA,MAAI,MAAM,YAAY,QAAW;AAC/B,UAAM,KAAK,uBAAAA,QAAO,MAAM,UAAK,MAAM,OAAO,SAAS,CAAC;AAAA,EACtD;AAEA,MAAI,MAAM,WAAW,UAAa,MAAM,SAAS,GAAG;AAClD,UAAM,KAAK,uBAAAA,QAAO,IAAI,UAAK,MAAM,MAAM,SAAS,CAAC;AAAA,EACnD;AAEA,MAAI,MAAM,YAAY,UAAa,MAAM,UAAU,GAAG;AACpD,UAAM,KAAK,uBAAAA,QAAO,OAAO,UAAK,MAAM,OAAO,UAAU,CAAC;AAAA,EACxD;AAEA,MAAI,MAAM,aAAa,UAAa,MAAM,WAAW,GAAG;AACtD,UAAM,KAAK,uBAAAA,QAAO,OAAO,UAAK,MAAM,QAAQ,WAAW,CAAC;AAAA,EAC1D;AAEA,MAAI,MAAM,WAAW,UAAa,MAAM,SAAS,GAAG;AAClD,UAAM,KAAK,uBAAAA,QAAO,IAAI,UAAK,MAAM,MAAM,SAAS,CAAC;AAAA,EACnD;AAEA,QAAM,UAAU,MAAM,KAAK,KAAK;AAChC,SAAO,aAAa,SAAS;AAAA,IAC3B,GAAG;AAAA,IACH,cAAc,MAAM,aAAa;AAAA,IACjC,GAAI,MAAM,aAAa,UAAa,EAAE,WAAW,MAAM,SAAS;AAAA,EAClE,CAAC;AACH;",
|
|
6
|
-
"names": ["colors"]
|
|
7
|
-
}
|
package/dist/stdio/header.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/header.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Console header/banner formatting utilities.\n * Provides consistent header formatting for CLI applications.\n */\n\nimport colors from '../external/yoctocolors-cjs'\nimport { centerText, repeatString } from '../strings'\n\nexport interface HeaderOptions {\n /**\n * Width of the header in characters.\n * @default 80\n */\n width?: number | undefined\n /**\n * Character to use for border lines.\n * @default '='\n */\n borderChar?: string | undefined\n /**\n * Number of blank lines above and below title.\n * @default 1\n */\n padding?: number | undefined\n /**\n * Color to apply to the title text.\n * @default 'cyan'\n */\n color?:\n | 'cyan'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'magenta'\n | 'red'\n | 'gray'\n | undefined\n /**\n * Apply bold styling to title.\n * @default true\n */\n bold?: boolean | undefined\n}\n\n/**\n * Create a formatted header/banner with borders and centered title.\n * Useful for marking the start of CLI output or creating visual sections.\n *\n * @param title - Title text to display in header\n * @param options - Header formatting options\n * @returns Formatted header string with borders and centered title\n *\n * @example\n * ```ts\n * console.log(createHeader('Socket Security Analysis', {\n * width: 70,\n * color: 'cyan',\n * bold: true,\n * padding: 2\n * }))\n * // Output:\n * // ======================================================================\n * //\n * // Socket Security Analysis\n * //\n * // ======================================================================\n * ```\n */\nexport function createHeader(title: string, options?: HeaderOptions): string {\n const {\n bold = true,\n borderChar = '=',\n color = 'cyan',\n padding = 1,\n width = 80,\n } = { __proto__: null, ...options } as HeaderOptions\n\n const border = repeatString(borderChar, width)\n\n // Apply color and bold\n let formattedTitle = title\n if (color && colors[color]) {\n formattedTitle = colors[color](formattedTitle)\n }\n if (bold && colors.bold) {\n formattedTitle = colors.bold(formattedTitle)\n }\n\n const centeredTitle = centerText(formattedTitle, width)\n const paddingLine = repeatString(' ', width)\n\n const lines: string[] = [border]\n\n for (let i = 0; i < padding; i++) {\n lines.push(paddingLine)\n }\n\n lines.push(centeredTitle)\n\n for (let i = 0; i < padding; i++) {\n lines.push(paddingLine)\n }\n\n lines.push(border)\n\n return lines.join('\\n')\n}\n\n/**\n * Create a simple section header without padding.\n * A lighter-weight alternative to `createHeader()` for subsections.\n *\n * @param title - Title text to display in header\n * @param options - Header formatting options\n * @returns Formatted section header string\n *\n * @example\n * ```ts\n * console.log(createSectionHeader('Dependencies', {\n * width: 50,\n * color: 'blue'\n * }))\n * // Output:\n * // --------------------------------------------------\n * // Dependencies\n * // --------------------------------------------------\n * ```\n */\nexport function createSectionHeader(\n title: string,\n options?: HeaderOptions,\n): string {\n const {\n borderChar = '-',\n color = 'blue',\n width = 60,\n } = { __proto__: null, ...options } as HeaderOptions\n\n return createHeader(title, {\n width,\n borderChar,\n padding: 0,\n color,\n bold: false,\n })\n}\n\n/**\n * Print a header directly to stdout with standard formatting.\n * Uses fixed width of 55 characters with `\u2550` borders.\n * Simpler alternative to `createHeader()` for quick headers.\n *\n * @param title - Title text to display\n *\n * @example\n * ```ts\n * printHeader('Package Analysis')\n * // Output:\n * // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * // Package Analysis\n * // \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * ```\n */\nexport function printHeader(title: string): void {\n const border = repeatString('\u2550', 55)\n console.log(border)\n console.log(` ${title}`)\n console.log(border)\n}\n\n/**\n * Print a footer with optional success message.\n * Uses `\u2500` border character for a lighter appearance.\n * Fixed width of 55 characters to match `printHeader()`.\n *\n * @param message - Optional message to display (shown in green)\n *\n * @example\n * ```ts\n * printFooter('Analysis complete')\n * // Output:\n * // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * // Analysis complete (in green)\n * ```\n */\nexport function printFooter(message?: string | undefined): void {\n const border = repeatString('\u2500', 55)\n console.log(border)\n if (message) {\n console.log(colors.green(message))\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,6BAAmB;AACnB,qBAAyC;AA8DlC,SAAS,aAAa,OAAe,SAAiC;AAC3E,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,IAAI,EAAE,WAAW,MAAM,GAAG,QAAQ;AAElC,QAAM,aAAS,6BAAa,YAAY,KAAK;AAG7C,MAAI,iBAAiB;AACrB,MAAI,SAAS,uBAAAA,QAAO,KAAK,GAAG;AAC1B,qBAAiB,uBAAAA,QAAO,KAAK,EAAE,cAAc;AAAA,EAC/C;AACA,MAAI,QAAQ,uBAAAA,QAAO,MAAM;AACvB,qBAAiB,uBAAAA,QAAO,KAAK,cAAc;AAAA,EAC7C;AAEA,QAAM,oBAAgB,2BAAW,gBAAgB,KAAK;AACtD,QAAM,kBAAc,6BAAa,KAAK,KAAK;AAE3C,QAAM,QAAkB,CAAC,MAAM;AAE/B,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,KAAK,WAAW;AAAA,EACxB;AAEA,QAAM,KAAK,aAAa;AAExB,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,KAAK,WAAW;AAAA,EACxB;AAEA,QAAM,KAAK,MAAM;AAEjB,SAAO,MAAM,KAAK,IAAI;AACxB;AAsBO,SAAS,oBACd,OACA,SACQ;AACR,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,IAAI,EAAE,WAAW,MAAM,GAAG,QAAQ;AAElC,SAAO,aAAa,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AACH;AAkBO,SAAS,YAAY,OAAqB;AAC/C,QAAM,aAAS,6BAAa,UAAK,EAAE;AACnC,UAAQ,IAAI,MAAM;AAClB,UAAQ,IAAI,KAAK,KAAK,EAAE;AACxB,UAAQ,IAAI,MAAM;AACpB;AAiBO,SAAS,YAAY,SAAoC;AAC9D,QAAM,aAAS,6BAAa,UAAK,EAAE;AACnC,UAAQ,IAAI,MAAM;AAClB,MAAI,SAAS;AACX,YAAQ,IAAI,uBAAAA,QAAO,MAAM,OAAO,CAAC;AAAA,EACnC;AACF;",
|
|
6
|
-
"names": ["colors"]
|
|
7
|
-
}
|
package/dist/stdio/mask.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/mask.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Interactive output masking utilities for CLI tools.\n * Provides output control with keyboard toggling (ctrl+o).\n *\n * ANSI Escape Sequences Used:\n * - '\\r': Carriage return - moves cursor to beginning of current line.\n * - '\\x1b[K' or '\\x1b[0K': CSI K (erase line) - clear from cursor to end of line.\n * - '\\x1b[2K': CSI 2K - erase entire line.\n * - '\\x1b[1A': CSI A - move cursor up 1 line.\n *\n * Terminal Control:\n * - Raw mode (setRawMode(true)): Captures keypresses immediately without buffering.\n * - TTY detection: Ensures terminal manipulation only occurs in interactive terminals.\n *\n * Key Features:\n * - Output buffering: Stores up to 1000 lines when masked to prevent memory issues.\n * - Graceful cleanup: Always restores terminal to normal mode on exit/error.\n * - Visual feedback: Uses spinner to indicate process is running when output is masked.\n */\n\nimport type { ChildProcess, SpawnOptions } from 'child_process'\nimport { spawn } from 'child_process'\nimport readline from 'readline'\nimport { getDefaultSpinner } from '../spinner.js'\nimport { clearLine } from './clear.js'\nimport { write } from './stdout.js'\n\nconst spinner = getDefaultSpinner()\n\nexport interface OutputMaskOptions {\n /**\n * Current working directory for spawned process.\n * @default process.cwd()\n */\n cwd?: string | undefined\n /**\n * Environment variables for spawned process.\n * @default process.env\n */\n env?: NodeJS.ProcessEnv | undefined\n /**\n * Filter output before displaying or buffering.\n * Return `false` to skip the line, `true` to include it.\n *\n * Useful for filtering non-fatal warnings or noise from test runners.\n * The filter runs on every chunk of output before display/buffering.\n *\n * @param text - The output text chunk (may include ANSI codes)\n * @param stream - Whether this came from 'stdout' or 'stderr'\n * @returns `true` to include this output, `false` to skip it\n *\n * @example\n * ```ts\n * filterOutput: (text, stream) => {\n * // Skip vitest worker termination errors\n * if (text.includes('Terminating worker thread')) return false\n * return true\n * }\n * ```\n */\n filterOutput?:\n | ((text: string, stream: 'stdout' | 'stderr') => boolean)\n | undefined\n /**\n * Progress message to display in spinner.\n * @default 'Running\u2026'\n */\n message?: string | undefined\n /**\n * Override the exit code based on captured output.\n *\n * Useful for handling non-fatal errors that shouldn't fail the build.\n * Called after the process exits with the original code and all captured output.\n * Return a number to override the exit code, or `undefined` to keep original.\n *\n * @param code - Original exit code from the process\n * @param stdout - All captured stdout (even filtered lines are captured)\n * @param stderr - All captured stderr (even filtered lines are captured)\n * @returns New exit code, or `undefined` to keep original\n *\n * @example\n * ```ts\n * overrideExitCode: (code, stdout, stderr) => {\n * // If only worker termination errors, treat as success\n * const output = stdout + stderr\n * const hasWorkerError = output.includes('Terminating worker thread')\n * const hasRealFailure = output.includes('FAIL')\n * if (code !== 0 && hasWorkerError && !hasRealFailure) {\n * return 0 // Override to success\n * }\n * return undefined // Keep original\n * }\n * ```\n */\n overrideExitCode?:\n | ((code: number, stdout: string, stderr: string) => number | undefined)\n | undefined\n /**\n * Start with output visible instead of masked.\n * When `true`, output shows immediately without needing ctrl+o.\n * @default false\n */\n showOutput?: boolean | undefined\n /**\n * Text to show after \"ctrl+o\" in spinner message.\n * @default 'to see full output'\n */\n toggleText?: string | undefined\n}\n\nexport interface OutputMask {\n /** Whether spinner is currently active */\n isSpinning: boolean\n /** Buffered output lines */\n outputBuffer: string[]\n /** All stderr captured (for exit code override) */\n stderrCapture: string\n /** All stdout captured (for exit code override) */\n stdoutCapture: string\n /** Whether output is currently visible */\n verbose: boolean\n}\n\n/**\n * Create an output mask for controlling command output visibility.\n * The mask tracks whether output should be shown or hidden (buffered).\n * When hidden, output is buffered and a spinner is shown instead.\n */\nexport function createOutputMask(options: OutputMaskOptions = {}): OutputMask {\n const { showOutput = false } = options\n\n return {\n isSpinning: !showOutput,\n outputBuffer: [],\n stderrCapture: '',\n stdoutCapture: '',\n verbose: showOutput,\n }\n}\n\n/**\n * Create a keyboard handler for toggling output visibility.\n * Handles two key combinations:\n * - ctrl+o: Toggle between showing and hiding output.\n * - ctrl+c: Cancel the running process.\n * The handler manipulates terminal state using ANSI escape sequences.\n */\nexport function createKeyboardHandler(\n mask: OutputMask,\n child: ChildProcess,\n options: OutputMaskOptions = {},\n): (_str: string, key: readline.Key) => void {\n const { message = 'Running\u2026', toggleText = 'to see full output' } = options\n\n return (_str, key) => {\n // ctrl+o toggles verbose mode.\n if (key?.ctrl && key.name === 'o') {\n mask.verbose = !mask.verbose\n\n if (mask.verbose) {\n // Stop spinner and show buffered output.\n if (mask.isSpinning) {\n spinner.stop()\n mask.isSpinning = false\n }\n\n // Clear the current line (removes spinner remnants).\n clearLine()\n\n // Show buffered output.\n if (mask.outputBuffer.length > 0) {\n console.log('--- Output (ctrl+o to hide) ---')\n mask.outputBuffer.forEach(line => {\n write(line)\n })\n }\n } else {\n // Hide output and show spinner.\n // Clear all the output lines that were shown.\n if (mask.outputBuffer.length > 0) {\n // Calculate number of lines to clear (output + header line).\n const lineCount = mask.outputBuffer.join('').split('\\n').length + 1\n // Move up and clear each line using ANSI escape sequences:\n // - '\\x1b[1A' (CSI A): Move cursor up 1 line.\n // - '\\x1b[2K' (CSI K with param 2): Erase entire line.\n // This combination effectively \"rewinds\" the terminal output.\n for (let i = 0; i < lineCount; i += 1) {\n process.stdout.write('\\x1b[1A\\x1b[2K')\n }\n }\n clearLine()\n\n // Clear the buffer and restart spinner.\n mask.outputBuffer = []\n if (!mask.isSpinning) {\n spinner.start(`${message} (ctrl+o ${toggleText})`)\n mask.isSpinning = true\n }\n }\n }\n // ctrl+c to cancel.\n else if (key?.ctrl && key.name === 'c') {\n // Gracefully terminate child process.\n child.kill('SIGTERM')\n // Restore terminal to normal mode before exiting.\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false)\n }\n throw new Error('Process cancelled by user')\n }\n }\n}\n\n/**\n * Attach output masking to a child process.\n * Returns a promise that resolves with the exit code.\n * This function:\n * - Sets up keyboard input handling in raw mode for immediate key capture.\n * - Buffers stdout/stderr when not in verbose mode.\n * - Shows a spinner when output is masked.\n * - Allows toggling between masked and unmasked output with ctrl+o.\n */\nexport function attachOutputMask(\n child: ChildProcess,\n options: OutputMaskOptions = {},\n): Promise<number> {\n return new Promise((resolve, reject) => {\n const { message = 'Running\u2026' } = options\n const mask = createOutputMask(options)\n\n // Start spinner if not verbose.\n if (mask.isSpinning && process.stdout.isTTY) {\n spinner.start(\n `${message} (ctrl+o ${options.toggleText || 'to see full output'})`,\n )\n }\n\n // Setup keyboard input handling.\n // Raw mode is required to capture ctrl+o without waiting for Enter.\n if (process.stdin.isTTY) {\n readline.emitKeypressEvents(process.stdin)\n process.stdin.setRawMode(true)\n\n const keypressHandler = createKeyboardHandler(mask, child, options)\n process.stdin.on('keypress', keypressHandler)\n\n // Cleanup on exit: restore terminal to normal mode.\n child.on('exit', () => {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false)\n process.stdin.removeListener('keypress', keypressHandler)\n }\n })\n }\n\n // Handle stdout: either show immediately or buffer for later.\n if (child.stdout) {\n child.stdout.on('data', data => {\n const text = data.toString()\n\n // Always capture for exit code override.\n mask.stdoutCapture += text\n\n // Apply filter if provided.\n if (options.filterOutput && !options.filterOutput(text, 'stdout')) {\n // Skip this output.\n return undefined\n }\n\n if (mask.verbose) {\n write(text)\n } else {\n // Buffer the output for later.\n mask.outputBuffer.push(text)\n\n // Keep buffer size reasonable (last 1000 lines).\n // This prevents unbounded memory growth for long-running processes.\n const lines = mask.outputBuffer.join('').split('\\n')\n if (lines.length > 1000) {\n mask.outputBuffer = [lines.slice(-1000).join('\\n')]\n }\n }\n return undefined\n })\n }\n\n // Handle stderr: same as stdout, but write to stderr stream when verbose.\n if (child.stderr) {\n child.stderr.on('data', data => {\n const text = data.toString()\n\n // Always capture for exit code override.\n mask.stderrCapture += text\n\n // Apply filter if provided.\n if (options.filterOutput && !options.filterOutput(text, 'stderr')) {\n // Skip this output.\n return undefined\n }\n\n if (mask.verbose) {\n process.stderr.write(text)\n } else {\n mask.outputBuffer.push(text)\n }\n return undefined\n })\n }\n\n child.on('exit', code => {\n // Cleanup keyboard if needed.\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false)\n }\n\n // Allow caller to override exit code based on output.\n let finalCode = code || 0\n if (options.overrideExitCode) {\n const overridden = options.overrideExitCode(\n finalCode,\n mask.stdoutCapture,\n mask.stderrCapture,\n )\n if (overridden !== undefined) {\n finalCode = overridden\n }\n }\n\n if (mask.isSpinning) {\n if (finalCode === 0) {\n spinner.successAndStop(`${message} completed`)\n } else {\n spinner.failAndStop(`${message} failed`)\n // Show buffered output on failure so user can see what went wrong.\n if (mask.outputBuffer.length > 0 && !mask.verbose) {\n console.log('\\n--- Output ---')\n mask.outputBuffer.forEach(line => {\n write(line)\n })\n }\n }\n }\n\n resolve(finalCode)\n })\n\n child.on('error', error => {\n // Ensure terminal is restored to normal mode on error.\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false)\n }\n\n if (mask.isSpinning) {\n spinner.failAndStop(`${message} error`)\n }\n reject(error)\n })\n })\n}\n\n/**\n * Run a command with interactive output masking.\n * Convenience wrapper around spawn + attachOutputMask.\n * Spawns a child process and attaches the output masking system to it.\n * stdin is inherited, stdout and stderr are piped for masking control.\n */\nexport async function runWithMask(\n command: string,\n args: string[] = [],\n options: OutputMaskOptions & SpawnOptions = {},\n): Promise<number> {\n const {\n message = 'Running\u2026',\n showOutput = false,\n toggleText = 'to see output',\n ...spawnOptions\n } = options\n\n const child = spawn(command, args, {\n stdio: ['inherit', 'pipe', 'pipe'],\n ...spawnOptions,\n })\n\n return await attachOutputMask(child, { message, showOutput, toggleText })\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["readline"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/progress.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Progress bar utilities for CLI applications.\n * Provides various progress indicators including bars, percentages, and spinners.\n */\n\nimport colors from '../external/yoctocolors-cjs'\nimport { repeatString, stripAnsi } from '../strings'\n\nexport interface ProgressBarOptions {\n /**\n * Width of the progress bar in characters.\n * @default 40\n */\n width?: number | undefined\n /**\n * Format template for progress bar display.\n * Available tokens: `:bar`, `:percent`, `:current`, `:total`, `:elapsed`, `:eta`.\n * Custom tokens can be passed via the `tokens` parameter in `update()` or `tick()`.\n * @default ':bar :percent :current/:total'\n * @example\n * ```ts\n * format: ':bar :percent :current/:total :eta'\n * ```\n */\n format?: string | undefined\n /**\n * Character(s) to use for completed portion of bar.\n * @default '\u2588'\n */\n complete?: string | undefined\n /**\n * Character(s) to use for incomplete portion of bar.\n * @default '\u2591'\n */\n incomplete?: string | undefined\n /**\n * Character(s) to use for the head of the progress bar.\n * @default ''\n */\n head?: string | undefined\n /**\n * Clear the progress bar when complete.\n * @default false\n */\n clear?: boolean | undefined\n /**\n * Minimum time between renders in milliseconds.\n * ~60fps = 16ms throttle.\n * @default 16\n */\n renderThrottle?: number | undefined\n /**\n * Stream to write progress bar output to.\n * @default process.stderr\n */\n stream?: NodeJS.WriteStream | undefined\n /**\n * Color to apply to the completed portion of the bar.\n * @default 'cyan'\n */\n color?: 'cyan' | 'green' | 'yellow' | 'blue' | 'magenta' | undefined\n}\n\nexport class ProgressBar {\n private current: number = 0\n private total: number\n private startTime: number\n private lastRender: number = 0\n private stream: NodeJS.WriteStream\n private options: Required<ProgressBarOptions>\n private terminated: boolean = false\n private lastDrawnWidth: number = 0\n\n /**\n * Create a new progress bar instance.\n *\n * @param total - Total number of units for the progress bar\n * @param options - Configuration options for the progress bar\n *\n * @example\n * ```ts\n * const bar = new ProgressBar(100, {\n * width: 50,\n * format: ':bar :percent :current/:total :eta',\n * color: 'green'\n * })\n * ```\n */\n constructor(total: number, options?: ProgressBarOptions) {\n this.total = total\n this.startTime = Date.now()\n this.stream = options?.stream || process.stderr\n this.options = {\n width: 40,\n format: ':bar :percent :current/:total',\n complete: '\u2588',\n incomplete: '\u2591',\n head: '',\n clear: false,\n // ~60fps.\n renderThrottle: 16,\n stream: this.stream,\n color: 'cyan',\n ...options,\n }\n }\n\n /**\n * Update progress to a specific value and redraw the bar.\n * Updates are throttled to prevent excessive rendering (default ~60fps).\n *\n * @param current - Current progress value (will be clamped to total)\n * @param tokens - Optional custom tokens to replace in format string\n *\n * @example\n * ```ts\n * bar.update(50)\n * bar.update(75, { status: 'Processing...' })\n * ```\n */\n update(current: number, tokens?: Record<string, unknown>): void {\n if (this.terminated) {\n return\n }\n\n this.current = Math.min(current, this.total)\n\n // Throttle rendering\n const now = Date.now()\n if (\n now - this.lastRender < this.options.renderThrottle &&\n this.current < this.total\n ) {\n return\n }\n this.lastRender = now\n\n this.render(tokens)\n\n if (this.current >= this.total) {\n this.terminate()\n }\n }\n\n /**\n * Increment progress by a specified amount.\n * Convenience method for `update(current + amount)`.\n *\n * @param amount - Amount to increment by\n * @param tokens - Optional custom tokens to replace in format string\n * @default amount 1\n *\n * @example\n * ```ts\n * bar.tick() // Increment by 1\n * bar.tick(5) // Increment by 5\n * bar.tick(1, { file: 'data.json' })\n * ```\n */\n tick(amount: number = 1, tokens?: Record<string, unknown>): void {\n this.update(this.current + amount, tokens)\n }\n\n /**\n * Render the progress bar.\n */\n private render(tokens?: Record<string, unknown>): void {\n const colorFn = colors[this.options.color] || ((s: string) => s)\n\n // Calculate values\n const percent = Math.floor((this.current / this.total) * 100)\n const elapsed = Date.now() - this.startTime\n const eta =\n this.current === 0\n ? 0\n : (elapsed / this.current) * (this.total - this.current)\n\n // Build bar\n const availableWidth = this.options.width\n const filledWidth = Math.floor((this.current / this.total) * availableWidth)\n const emptyWidth = availableWidth - filledWidth\n\n const filled = repeatString(this.options.complete, filledWidth)\n const empty = repeatString(this.options.incomplete, emptyWidth)\n const bar = colorFn(filled) + empty\n\n // Format output\n let output = this.options.format\n output = output.replace(':bar', bar)\n output = output.replace(':percent', `${percent}%`)\n output = output.replace(':current', String(this.current))\n output = output.replace(':total', String(this.total))\n output = output.replace(':elapsed', this.formatTime(elapsed))\n output = output.replace(':eta', this.formatTime(eta))\n\n // Replace custom tokens\n if (tokens) {\n for (const [key, value] of Object.entries(tokens)) {\n output = output.replace(`:${key}`, String(value))\n }\n }\n\n // Clear line and write\n this.clearLine()\n this.stream.write(output)\n this.lastDrawnWidth = stripAnsi(output).length\n }\n\n /**\n * Clear the current line.\n */\n private clearLine(): void {\n if (this.stream.isTTY) {\n this.stream.cursorTo(0)\n this.stream.clearLine(0)\n } else if (this.lastDrawnWidth > 0) {\n this.stream.write(`\\r${repeatString(' ', this.lastDrawnWidth)}\\r`)\n }\n }\n\n /**\n * Format time in seconds to human readable.\n */\n private formatTime(ms: number): string {\n const seconds = Math.round(ms / 1000)\n if (seconds < 60) {\n return `${seconds}s`\n }\n const minutes = Math.floor(seconds / 60)\n const remainingSeconds = seconds % 60\n return `${minutes}m${remainingSeconds}s`\n }\n\n /**\n * Terminate the progress bar and optionally clear it.\n * Called automatically when progress reaches 100%.\n * If `clear` option is true, removes the bar from terminal.\n * Otherwise, moves to next line to preserve the final state.\n */\n terminate(): void {\n if (this.terminated) {\n return\n }\n this.terminated = true\n\n if (this.options.clear) {\n this.clearLine()\n } else {\n this.stream.write('\\n')\n }\n }\n}\n\n/**\n * Create a simple progress indicator without a graphical bar.\n * Returns a formatted string showing progress as percentage and fraction.\n *\n * @param current - Current progress value\n * @param total - Total progress value\n * @param label - Optional label prefix\n * @returns Formatted progress indicator string\n *\n * @example\n * ```ts\n * createProgressIndicator(50, 100)\n * // Returns: '[50%] 50/100'\n *\n * createProgressIndicator(3, 10, 'Files')\n * // Returns: 'Files: [30%] 3/10'\n * ```\n */\nexport function createProgressIndicator(\n current: number,\n total: number,\n label?: string | undefined,\n): string {\n const percent = Math.floor((current / total) * 100)\n const progress = `${current}/${total}`\n\n let output = ''\n if (label) {\n output += `${label}: `\n }\n\n output += `${colors.cyan(`[${percent}%]`)} ${progress}`\n\n return output\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["colors"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/stdio/prompts.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview User prompt utilities for interactive scripts.\n * Provides inquirer.js integration with spinner support, context handling, and theming.\n */\n\nimport { getAbortSignal, getSpinner } from '#constants/process'\nimport type { ColorValue } from '../spinner'\nimport { getTheme } from '../themes/context'\nimport { THEMES, type ThemeName } from '../themes/themes'\nimport type { Theme } from '../themes/types'\nimport { resolveColor } from '../themes/utils'\nimport yoctocolorsCjs from '../external/yoctocolors-cjs'\n\nconst abortSignal = getAbortSignal()\nconst spinner = getSpinner()\n\n/**\n * Apply a color to text using yoctocolors.\n * Handles both named colors and RGB tuples.\n * @private\n */\nfunction applyColor(text: string, color: ColorValue): string {\n if (typeof color === 'string') {\n // Named color like 'green', 'red', etc.\n return (yoctocolorsCjs as any)[color](text)\n }\n // RGB tuple [r, g, b]\n return yoctocolorsCjs.rgb(color[0], color[1], color[2])(text)\n}\n\n// Type definitions\n\n/**\n * Choice option for select and search prompts.\n *\n * @template Value - Type of the choice value\n */\nexport interface Choice<Value = unknown> {\n /** The value returned when this choice is selected */\n value: Value\n /** Display name for the choice (defaults to value.toString()) */\n name?: string | undefined\n /** Additional description text shown below the choice */\n description?: string | undefined\n /** Short text shown after selection (defaults to name) */\n short?: string | undefined\n /** Whether this choice is disabled, or a reason string */\n disabled?: boolean | string | undefined\n}\n\n/**\n * Context for inquirer prompts.\n * Minimal context interface used by Inquirer prompts.\n * Duplicated from `@inquirer/type` - InquirerContext.\n */\ninterface InquirerContext {\n /** Abort signal for cancelling the prompt */\n signal?: AbortSignal | undefined\n /** Input stream (defaults to process.stdin) */\n input?: NodeJS.ReadableStream | undefined\n /** Output stream (defaults to process.stdout) */\n output?: NodeJS.WritableStream | undefined\n /** Clear the prompt from terminal when done */\n clearPromptOnDone?: boolean | undefined\n}\n\n/**\n * Extended context with spinner support.\n * Allows passing a spinner instance to be managed during prompts.\n */\nexport type Context = import('../objects').Remap<\n InquirerContext & {\n /** Optional spinner to stop/start during prompt display */\n spinner?: import('../spinner').Spinner | undefined\n }\n>\n\n/**\n * Separator for visual grouping in select/checkbox prompts.\n * Creates a non-selectable visual separator line.\n * Duplicated from `@inquirer/select` - Separator.\n * This type definition ensures the Separator type is available in published packages.\n *\n * @example\n * import { Separator } from './prompts'\n *\n * const choices = [\n * { name: 'Option 1', value: 1 },\n * new Separator(),\n * { name: 'Option 2', value: 2 }\n * ]\n */\ndeclare class SeparatorType {\n readonly separator: string\n readonly type: 'separator'\n constructor(separator?: string)\n}\n\nexport type Separator = SeparatorType\n\n/**\n * Resolve theme name or object to Theme.\n * @param theme - Theme name or object\n * @returns Resolved Theme\n */\nfunction resolveTheme(theme: Theme | ThemeName): Theme {\n return typeof theme === 'string' ? THEMES[theme] : theme\n}\n\n/**\n * Check if value is a Socket Theme object.\n * @param value - Value to check\n * @returns True if value is a Socket Theme\n */\nfunction isSocketTheme(value: unknown): value is Theme {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'name' in value &&\n 'colors' in value\n )\n}\n\n/**\n * Convert Socket theme to @inquirer theme format.\n * Maps our theme colors to inquirer's style functions.\n * Handles theme names, Theme objects, and passes through @inquirer themes.\n *\n * @param theme - Socket theme name, Theme object, or @inquirer theme\n * @returns @inquirer theme object\n *\n * @example\n * ```ts\n * // Socket theme name\n * createInquirerTheme('sunset')\n *\n * // Socket Theme object\n * createInquirerTheme(SUNSET_THEME)\n *\n * // @inquirer theme (passes through)\n * createInquirerTheme({ style: {...}, icon: {...} })\n * ```\n */\nexport function createInquirerTheme(\n theme: Theme | ThemeName | unknown,\n): Record<string, unknown> {\n // If it's a string (theme name) or Socket Theme object, convert it\n if (typeof theme === 'string' || isSocketTheme(theme)) {\n const socketTheme = resolveTheme(theme as Theme | ThemeName)\n const promptColor = resolveColor(\n socketTheme.colors.prompt,\n socketTheme.colors,\n ) as ColorValue\n const textDimColor = resolveColor(\n socketTheme.colors.textDim,\n socketTheme.colors,\n ) as ColorValue\n const errorColor = socketTheme.colors.error\n const successColor = socketTheme.colors.success\n const primaryColor = socketTheme.colors.primary\n\n return {\n style: {\n // Message text (uses colors.prompt)\n message: (text: string) => applyColor(text, promptColor),\n // Answer text (uses primary color)\n answer: (text: string) => applyColor(text, primaryColor),\n // Help text / descriptions (uses textDim)\n help: (text: string) => applyColor(text, textDimColor),\n description: (text: string) => applyColor(text, textDimColor),\n // Disabled items (uses textDim)\n disabled: (text: string) => applyColor(text, textDimColor),\n // Error messages (uses error color)\n error: (text: string) => applyColor(text, errorColor),\n // Highlight/active (uses primary color)\n highlight: (text: string) => applyColor(text, primaryColor),\n },\n icon: {\n // Use success color for confirmed items\n checked: applyColor('\u2713', successColor),\n unchecked: ' ',\n // Cursor uses primary color\n cursor: applyColor('\u276F', primaryColor),\n },\n }\n }\n\n // Otherwise it's already an @inquirer theme, return as-is\n return theme as Record<string, unknown>\n}\n\n/**\n * Wrap an inquirer prompt with spinner handling, theme injection, and signal injection.\n * Automatically stops/starts spinners during prompt display, injects the current theme,\n * and injects abort signals. Trims string results and handles cancellation gracefully.\n *\n * @template T - Type of the prompt result\n * @param inquirerPrompt - The inquirer prompt function to wrap\n * @returns Wrapped prompt function with spinner, theme, and signal handling\n *\n * @example\n * const myPrompt = wrapPrompt(rawInquirerPrompt)\n * const result = await myPrompt({ message: 'Enter name:' })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function wrapPrompt<T = unknown>(\n inquirerPrompt: (...args: unknown[]) => Promise<T>,\n): (...args: unknown[]) => Promise<T | undefined> {\n return async (...args) => {\n const origContext = (args.length > 1 ? args[1] : undefined) as\n | Context\n | undefined\n const { spinner: contextSpinner, ...contextWithoutSpinner } =\n origContext ?? ({} as Context)\n const spinnerInstance =\n contextSpinner !== undefined ? contextSpinner : spinner\n const signal = abortSignal\n\n // Inject theme into config (args[0])\n const config = args[0] as Record<string, unknown>\n if (config && typeof config === 'object') {\n if (!config.theme) {\n // No theme provided, use current theme\n config.theme = createInquirerTheme(getTheme())\n } else {\n // Theme provided - let createInquirerTheme handle detection\n config.theme = createInquirerTheme(config.theme)\n }\n }\n\n // Inject signal into context (args[1])\n if (origContext) {\n args[1] = {\n signal,\n ...contextWithoutSpinner,\n }\n } else {\n args[1] = { signal }\n }\n\n const wasSpinning = !!spinnerInstance?.isSpinning\n spinnerInstance?.stop()\n let result: unknown\n try {\n result = await inquirerPrompt(...args)\n } catch (e) {\n if (e instanceof TypeError) {\n throw e\n }\n }\n if (wasSpinning) {\n spinnerInstance.start()\n }\n return (typeof result === 'string' ? result.trim() : result) as\n | T\n | undefined\n }\n}\n\n// c8 ignore start - Third-party inquirer library requires and exports not testable in isolation.\nconst confirmExport = /*@__PURE__*/ require('../external/@inquirer/confirm')\nconst inputExport = /*@__PURE__*/ require('../external/@inquirer/input')\nconst passwordExport = /*@__PURE__*/ require('../external/@inquirer/password')\nconst searchExport = /*@__PURE__*/ require('../external/@inquirer/search')\nconst selectExport = /*@__PURE__*/ require('../external/@inquirer/select')\nconst confirmRaw = confirmExport.default ?? confirmExport\nconst inputRaw = inputExport.default ?? inputExport\nconst passwordRaw = passwordExport.default ?? passwordExport\nconst searchRaw = searchExport.default ?? searchExport\nconst selectRaw = selectExport.default ?? selectExport\nconst ActualSeparator = selectExport.Separator\n// c8 ignore stop\n\n/**\n * Prompt for a yes/no confirmation.\n * Wrapped with spinner handling and abort signal support.\n *\n * @example\n * const answer = await confirm({ message: 'Continue?' })\n * if (answer) { // user confirmed }\n */\nexport const confirm: typeof confirmRaw = wrapPrompt(confirmRaw)\n\n/**\n * Prompt for text input.\n * Wrapped with spinner handling and abort signal support.\n * Result is automatically trimmed.\n *\n * @example\n * const name = await input({ message: 'Enter your name:' })\n */\nexport const input: typeof inputRaw = wrapPrompt(inputRaw)\n\n/**\n * Prompt for password input (hidden characters).\n * Wrapped with spinner handling and abort signal support.\n *\n * @example\n * const token = await password({ message: 'Enter API token:' })\n */\nexport const password: typeof passwordRaw = wrapPrompt(passwordRaw)\n\n/**\n * Prompt with searchable/filterable choices.\n * Wrapped with spinner handling and abort signal support.\n *\n * @example\n * const result = await search({\n * message: 'Select a package:',\n * source: async (input) => fetchPackages(input)\n * })\n */\nexport const search: typeof searchRaw = wrapPrompt(searchRaw)\n\n/**\n * Prompt to select from a list of choices.\n * Wrapped with spinner handling and abort signal support.\n *\n * @example\n * const choice = await select({\n * message: 'Choose an option:',\n * choices: [\n * { name: 'Option 1', value: 'opt1' },\n * { name: 'Option 2', value: 'opt2' }\n * ]\n * })\n */\nexport const select: typeof selectRaw = wrapPrompt(selectRaw)\n\nexport { ActualSeparator as Separator }\n\n/**\n * Create a separator for select prompts.\n * Creates a visual separator line in choice lists.\n *\n * @param text - Optional separator text (defaults to '\u2500\u2500\u2500\u2500\u2500\u2500\u2500')\n * @returns Separator instance\n *\n * @example\n * import { select, createSeparator } from '@socketsecurity/lib/stdio/prompts'\n *\n * const choice = await select({\n * message: 'Choose an option:',\n * choices: [\n * { name: 'Option 1', value: 1 },\n * createSeparator(),\n * { name: 'Option 2', value: 2 }\n * ]\n * })\n */\nexport function createSeparator(\n text?: string,\n): InstanceType<typeof ActualSeparator> {\n return new ActualSeparator(text)\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["yoctocolorsCjs"]
|
|
7
|
-
}
|