@socketsecurity/lib 2.2.0 → 2.3.0
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 +19 -0
- package/dist/bin.d.ts +27 -4
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +3 -3
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.3.0](https://github.com/SocketDev/socket-lib/releases/tag/v2.3.0) - 2025-10-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Binary utility wrapper functions**: Added `which()` and `whichSync()` wrapper functions to `bin` module
|
|
13
|
+
- Cross-platform binary lookup that respects PATH environment variable
|
|
14
|
+
- Synchronous and asynchronous variants for different use cases
|
|
15
|
+
- Integrates with existing binary resolution utilities
|
|
16
|
+
|
|
17
|
+
## [2.2.1](https://github.com/SocketDev/socket-lib/releases/tag/v2.2.1) - 2025-10-28
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Logger write() method**: Fixed `write()` to bypass Console formatting when outputting raw text
|
|
22
|
+
- Previously, `write()` used Console's internal `_stdout` stream which applied unintended formatting like group indentation
|
|
23
|
+
- Now stores a reference to the original stdout stream in a dedicated private field (`#originalStdout`) during construction
|
|
24
|
+
- The `write()` method uses this stored reference to write directly to the raw stream, bypassing all Console formatting layers
|
|
25
|
+
- Ensures raw text output without any formatting applied, fixing test failures in CI environments where writes after `indent()` were unexpectedly formatted
|
|
26
|
+
|
|
8
27
|
## [2.2.0](https://github.com/SocketDev/socket-lib/releases/tag/v2.2.0) - 2025-10-28
|
|
9
28
|
|
|
10
29
|
### Added
|
package/dist/bin.d.ts
CHANGED
|
@@ -10,18 +10,41 @@ export declare function execBin(binPath: string, args?: string[], options?: impo
|
|
|
10
10
|
stdout: string | Buffer<ArrayBufferLike>;
|
|
11
11
|
stderr: string | Buffer<ArrayBufferLike>;
|
|
12
12
|
}>;
|
|
13
|
+
/**
|
|
14
|
+
* Options for the which function.
|
|
15
|
+
*/
|
|
16
|
+
export interface WhichOptions {
|
|
17
|
+
/** If true, return all matches instead of just the first one. */
|
|
18
|
+
all?: boolean | undefined;
|
|
19
|
+
/** If true, return null instead of throwing when no match is found. */
|
|
20
|
+
nothrow?: boolean | undefined;
|
|
21
|
+
/** Path to search in. */
|
|
22
|
+
path?: string | undefined;
|
|
23
|
+
/** Path separator character. */
|
|
24
|
+
pathExt?: string | undefined;
|
|
25
|
+
/** Environment variables to use. */
|
|
26
|
+
env?: Record<string, string | undefined> | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Find an executable in the system PATH asynchronously.
|
|
30
|
+
* Wrapper around the which package for lazy loading.
|
|
31
|
+
*/
|
|
32
|
+
export declare function which(binName: string, options?: WhichOptions): Promise<string | string[] | undefined>;
|
|
33
|
+
/**
|
|
34
|
+
* Find an executable in the system PATH synchronously.
|
|
35
|
+
* Wrapper around the which package for lazy loading.
|
|
36
|
+
*/
|
|
37
|
+
export declare function whichSync(binName: string, options?: WhichOptions): string | string[] | undefined;
|
|
13
38
|
/**
|
|
14
39
|
* Find and resolve a binary in the system PATH asynchronously.
|
|
15
|
-
* @template {import('which').Options} T
|
|
16
40
|
* @throws {Error} If the binary is not found and nothrow is false.
|
|
17
41
|
*/
|
|
18
|
-
export declare function whichBin(binName: string, options?:
|
|
42
|
+
export declare function whichBin(binName: string, options?: WhichOptions): Promise<string | string[] | undefined>;
|
|
19
43
|
/**
|
|
20
44
|
* Find and resolve a binary in the system PATH synchronously.
|
|
21
|
-
* @template {import('which').Options} T
|
|
22
45
|
* @throws {Error} If the binary is not found and nothrow is false.
|
|
23
46
|
*/
|
|
24
|
-
export declare function whichBinSync(binName: string, options?:
|
|
47
|
+
export declare function whichBinSync(binName: string, options?: WhichOptions): string | string[] | undefined;
|
|
25
48
|
/**
|
|
26
49
|
* Check if a directory path contains any shadow bin patterns.
|
|
27
50
|
*/
|
package/dist/bin.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var
|
|
2
|
+
var j=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var X=(n,e)=>{for(var i in e)j(n,i,{get:e[i],enumerable:!0})},k=(n,e,i,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of W(e))!F.call(n,s)&&s!==i&&j(n,s,{get:()=>e[s],enumerable:!(c=J(e,s))||c.enumerable});return n};var q=n=>k(j({},"__esModule",{value:!0}),n);var U={};X(U,{execBin:()=>M,findRealBin:()=>_,findRealNpm:()=>Y,findRealPnpm:()=>H,findRealYarn:()=>T,isShadowBinPath:()=>C,resolveBinPathSync:()=>g,which:()=>z,whichBin:()=>D,whichBinSync:()=>A,whichSync:()=>R});module.exports=q(U);var h=require("#env/home"),x=require("#env/windows"),O=require("#env/xdg"),$=require("#constants/platform"),B=require("./fs"),l=require("./path"),E=require("./spawn");let I;function P(){return I===void 0&&(I=require("node:fs")),I}let v;function y(){return v===void 0&&(v=require("node:path")),v}let N;function w(){return N===void 0&&(N=require("./external/which")),N}async function M(n,e,i){const c=(0,l.isPath)(n)?g(n):await D(n);if(!c){const r=new Error(`Binary not found: ${n}`);throw r.code="ENOENT",r}const s=Array.isArray(c)?c[0]:c;return await(0,E.spawn)(s,e??[],{shell:$.WIN32,...i})}async function z(n,e){return await w()(n,e)}function R(n,e){return w().sync(n,e)}async function D(n,e){const i=w(),c={nothrow:!0,...e},s=await i(n,c);if(c?.all){const r=Array.isArray(s)?s:typeof s=="string"?[s]:void 0;return r?.length?r.map(p=>g(p)):r}if(s)return g(s)}function A(n,e){const i={nothrow:!0,...e},c=R(n,i);if(i.all){const s=Array.isArray(c)?c:typeof c=="string"?[c]:void 0;return s?.length?s.map(r=>g(r)):s}if(c)return g(c)}function C(n){return n?n.replace(/\\/g,"/").includes("node_modules/.bin"):!1}function _(n,e=[]){const i=P(),c=y(),s=w();for(const p of e)if(i?.existsSync(p))return p;const r=s?.sync(n,{nothrow:!0});if(r){const p=c?.dirname(r);if(C(p)){const a=s?.sync(n,{all:!0,nothrow:!0})||[],d=Array.isArray(a)?a:typeof a=="string"?[a]:[];for(const m of d){const o=c?.dirname(m);if(!C(o))return m}}return r}}function Y(){const n=P(),e=y(),i=e?.dirname(process.execPath),c=e?.join(i,"npm");if(n?.existsSync(c))return c;const r=_("npm",["/usr/local/bin/npm","/usr/bin/npm"]);if(r&&n?.existsSync(r))return r;const p=A("npm",{nothrow:!0});return p&&typeof p=="string"&&n?.existsSync(p)?p:"npm"}function H(){const n=y(),e=$.WIN32?[n?.join((0,x.getAppdata)(),"npm","pnpm.cmd"),n?.join((0,x.getAppdata)(),"npm","pnpm"),n?.join((0,x.getLocalappdata)(),"pnpm","pnpm.cmd"),n?.join((0,x.getLocalappdata)(),"pnpm","pnpm"),"C:\\Program Files\\nodejs\\pnpm.cmd","C:\\Program Files\\nodejs\\pnpm"].filter(Boolean):["/usr/local/bin/pnpm","/usr/bin/pnpm",n?.join((0,O.getXdgDataHome)()||`${(0,h.getHome)()}/.local/share`,"pnpm/pnpm"),n?.join((0,h.getHome)(),".pnpm/pnpm")].filter(Boolean);return _("pnpm",e)??""}function T(){const n=y(),e=["/usr/local/bin/yarn","/usr/bin/yarn",n?.join((0,h.getHome)(),".yarn/bin/yarn"),n?.join((0,h.getHome)(),".config/yarn/global/node_modules/.bin/yarn")].filter(Boolean);return _("yarn",e)??""}function g(n){const e=P(),i=y();if(!i?.isAbsolute(n))try{const a=A(n);a&&(n=a)}catch{}if(n=(0,l.normalizePath)(n),n===".")return n;const c=i?.extname(n),s=c.toLowerCase(),r=i?.basename(n,c),p=r==="node"?-1:/(?<=\/)\.volta\//i.exec(n)?.index??-1;if(p!==-1){const a=n.slice(0,p),d=i?.join(a,"tools"),m=i?.join(d,"image"),o=i?.join(d,"user"),t=(0,B.readJsonSync)(i?.join(o,"platform.json"),{throws:!1}),u=t?.node?.runtime,L=t?.node?.npm;let f="";if(r==="npm"||r==="npx"){if(L){const S=`bin/${r}-cli.js`;f=i?.join(m,`npm/${L}/${S}`),u&&!e?.existsSync(f)&&(f=i?.join(m,`node/${u}/lib/node_modules/npm/${S}`),e?.existsSync(f)||(f=""))}}else{const S=i?.join(o,"bin"),b=(0,B.readJsonSync)(i?.join(S,`${r}.json`),{throws:!1})?.package;b&&(f=i?.join(m,`packages/${b}/bin/${r}`),e?.existsSync(f)||(f=`${f}.cmd`,e?.existsSync(f)||(f="")))}if(f){try{return(0,l.normalizePath)(e?.realpathSync.native(f))}catch{}return f}}if($.WIN32){const a=s===""||s===".cmd"||s===".exe"||s===".ps1",d=r==="npm"||r==="npx",m=r==="pnpm"||r==="yarn";if(a&&d){const t=i?.join(i?.dirname(n),`node_modules/npm/bin/${r}-cli.js`);if(e?.existsSync(t)){try{return e?.realpathSync.native(t)}catch{}return t}}let o="";if(a&&s!==".exe"&&e?.existsSync(n)){const t=e?.readFileSync(n,"utf8");d?s===".cmd"?o=r==="npm"?/(?<="NPM_CLI_JS=%~dp0\\).*(?=")/.exec(t)?.[0]||"":/(?<="NPX_CLI_JS=%~dp0\\).*(?=")/.exec(t)?.[0]||"":s===""?o=r==="npm"?/(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(t)?.[0]||"":/(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(t)?.[0]||"":s===".ps1"&&(o=r==="npm"?/(?<=\$NPM_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(t)?.[0]||"":/(?<=\$NPX_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(t)?.[0]||""):m?s===".cmd"?(o=/(?<=node\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(t)?.[1]||"",o||(o=/(?<="%~dp0\\[^"]*node[^"]*"\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(t)?.[1]||""),o||(o=/(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(t)?.[0]||"")):s===""?(o=/(?<="\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(t)?.[0]||"",o||(o=/(?<=exec\s+node\s+"\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(t)?.[0]||""),o||(o=/(?<="\$basedir\/).*(?=" "\$@"\n)/.exec(t)?.[0]||"")):s===".ps1"&&(o=/(?<="\$basedir\/).*(?=" $args\n)/.exec(t)?.[0]||""):s===".cmd"?o=/(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(t)?.[0]||"":s===""?o=/(?<="$basedir\/).*(?=" "\$@"\n)/.exec(t)?.[0]||"":s===".ps1"&&(o=/(?<="\$basedir\/).*(?=" $args\n)/.exec(t)?.[0]||""),o&&(n=(0,l.normalizePath)(i?.resolve(i?.dirname(n),o)))}}else{let a=s==="";const d=r==="pnpm"||r==="yarn",m=r==="npm"||r==="npx";if(d&&n.includes("/.bin/pnpm/bin/")){const o=n.indexOf("/.bin/pnpm");if(o!==-1){const t=n.slice(0,o+10);try{(e?.statSync(t)).isFile()&&(n=(0,l.normalizePath)(t),a=!i?.extname(n))}catch{}}}if(a&&(d||m)&&e?.existsSync(n)){const o=e?.readFileSync(n,"utf8");let t="";if(d){if(t=/(?<="\$basedir\/)\.tools\/[^"]+(?="\s+"\$@")/.exec(o)?.[0]||"",t||(t=/(?<="\$basedir\/)[^"]+(?="\s+"\$@")/.exec(o)?.[0]||""),!t){const u=/exec\s+node\s+"?\$basedir\/([^"]+)"?\s+"\$@"/.exec(o);u&&(t=u[1]||"")}t&&r==="pnpm"&&t.startsWith("pnpm/")&&(t=`../${t}`)}else m&&(t=r==="npm"?/(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(o)?.[0]||"":/(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(o)?.[0]||"");t&&(n=(0,l.normalizePath)(i?.resolve(i?.dirname(n),t)))}}try{const a=e?.realpathSync.native(n);return(0,l.normalizePath)(a)}catch{}return(0,l.normalizePath)(n)}0&&(module.exports={execBin,findRealBin,findRealNpm,findRealPnpm,findRealYarn,isShadowBinPath,resolveBinPathSync,which,whichBin,whichBinSync,whichSync});
|
|
3
3
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/bin.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Binary path resolution and execution utilities for package managers.\n * Provides cross-platform bin path lookup, command execution, and path normalization.\n */\n\nimport { getHome } from '#env/home'\nimport { getAppdata, getLocalappdata } from '#env/windows'\nimport { getXdgDataHome } from '#env/xdg'\n\nimport { WIN32 } from '#constants/platform'\nimport { readJsonSync } from './fs'\nimport { getOwn } from './objects'\nimport { isPath, normalizePath } from './path'\nimport { spawn } from './spawn'\n\nlet _fs: typeof import('node:fs') | undefined\n/**\n * Lazily load the fs module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFs() {\n if (_fs === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _fs = /*@__PURE__*/ require('node:fs')\n }\n return _fs!\n}\n\nlet _path: typeof import('node:path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path!\n}\n\nlet _which: typeof import('which') | undefined\n/**\n * Lazily load the which module for finding executables.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getWhich() {\n if (_which === undefined) {\n _which = /*@__PURE__*/ require('./external/which')\n }\n return _which!\n}\n\n/**\n * Execute a binary with the given arguments.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function execBin(\n binPath: string,\n args?: string[],\n options?: import('./spawn').SpawnOptions,\n) {\n // Resolve the binary path.\n const resolvedPath = isPath(binPath)\n ? resolveBinPathSync(binPath)\n : await whichBin(binPath)\n\n if (!resolvedPath) {\n const error = new Error(`Binary not found: ${binPath}`) as Error & {\n code: string\n }\n error.code = 'ENOENT'\n throw error\n }\n\n // Execute the binary directly.\n const binCommand = Array.isArray(resolvedPath)\n ? resolvedPath[0]!\n : resolvedPath\n // On Windows, binaries are often .cmd files that require shell to execute.\n return await spawn(binCommand, args ?? [], {\n shell: WIN32,\n ...options,\n })\n}\n\n/**\n * Find and resolve a binary in the system PATH asynchronously.\n * @template {import('which').Options} T\n * @throws {Error} If the binary is not found and nothrow is false.\n */\nexport async function whichBin(\n binName: string,\n options?: import('which').Options,\n): Promise<string | string[] | undefined> {\n const which = getWhich()\n // Default to nothrow: true if not specified to return undefined instead of throwing\n const opts = { nothrow: true, ...options }\n // Depending on options `which` may throw if `binName` is not found.\n // With nothrow: true, it returns null when `binName` is not found.\n const result = await which?.(binName, opts)\n\n // When 'all: true' is specified, ensure we always return an array.\n if (options?.all) {\n const paths = Array.isArray(result)\n ? result\n : typeof result === 'string'\n ? [result]\n : undefined\n // If all is true and we have paths, resolve each one.\n return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths\n }\n\n // If result is undefined (binary not found), return undefined\n if (!result) {\n return undefined\n }\n\n return resolveBinPathSync(result)\n}\n\n/**\n * Find and resolve a binary in the system PATH synchronously.\n * @template {import('which').Options} T\n * @throws {Error} If the binary is not found and nothrow is false.\n */\nexport function whichBinSync(\n binName: string,\n options?: import('which').Options,\n): string | string[] | undefined {\n // Default to nothrow: true if not specified to return undefined instead of throwing\n const opts = { nothrow: true, ...options }\n // Depending on options `which` may throw if `binName` is not found.\n // With nothrow: true, it returns null when `binName` is not found.\n const result = getWhich()?.sync(binName, opts)\n\n // When 'all: true' is specified, ensure we always return an array.\n if (getOwn(options, 'all')) {\n const paths = Array.isArray(result)\n ? result\n : typeof result === 'string'\n ? [result]\n : undefined\n // If all is true and we have paths, resolve each one.\n return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths\n }\n\n // If result is undefined (binary not found), return undefined\n if (!result) {\n return undefined\n }\n\n return resolveBinPathSync(result)\n}\n\n/**\n * Check if a directory path contains any shadow bin patterns.\n */\nexport function isShadowBinPath(dirPath: string | undefined): boolean {\n if (!dirPath) {\n return false\n }\n // Check for node_modules/.bin pattern (Unix and Windows)\n const normalized = dirPath.replace(/\\\\/g, '/')\n return normalized.includes('node_modules/.bin')\n}\n\n/**\n * Find the real executable for a binary, bypassing shadow bins.\n */\nexport function findRealBin(\n binName: string,\n commonPaths: string[] = [],\n): string | undefined {\n const fs = getFs()\n const path = getPath()\n const which = getWhich()\n\n // Try common locations first.\n for (const binPath of commonPaths) {\n if (fs?.existsSync(binPath)) {\n return binPath\n }\n }\n\n // Fall back to which.sync if no direct path found.\n const binPath = which?.sync(binName, { nothrow: true })\n if (binPath) {\n const binDir = path?.dirname(binPath)\n\n if (isShadowBinPath(binDir)) {\n // This is likely a shadowed binary, try to find the real one.\n const allPaths = which?.sync(binName, { all: true, nothrow: true }) || []\n // Ensure allPaths is an array.\n const pathsArray = Array.isArray(allPaths)\n ? allPaths\n : typeof allPaths === 'string'\n ? [allPaths]\n : []\n\n for (const altPath of pathsArray) {\n const altDir = path?.dirname(altPath)\n if (!isShadowBinPath(altDir)) {\n return altPath\n }\n }\n }\n return binPath\n }\n // If all else fails, return undefined to indicate binary not found.\n return undefined\n}\n\n/**\n * Find the real npm executable, bypassing any aliases and shadow bins.\n */\nexport function findRealNpm(): string {\n const fs = getFs()\n const path = getPath()\n\n // Try to find npm in the same directory as the node executable.\n const nodeDir = path?.dirname(process.execPath)\n const npmInNodeDir = path?.join(nodeDir, 'npm')\n\n if (fs?.existsSync(npmInNodeDir)) {\n return npmInNodeDir\n }\n\n // Try common npm locations.\n const commonPaths = ['/usr/local/bin/npm', '/usr/bin/npm']\n const result = findRealBin('npm', commonPaths)\n\n // If we found a valid path, return it.\n if (result && fs?.existsSync(result)) {\n return result\n }\n\n // As a last resort, try to use whichBinSync to find npm.\n // This handles cases where npm is installed in non-standard locations.\n const npmPath = whichBinSync('npm', { nothrow: true })\n if (npmPath && typeof npmPath === 'string' && fs?.existsSync(npmPath)) {\n return npmPath\n }\n\n // Return the basic 'npm' and let the system resolve it.\n return 'npm'\n}\n\n/**\n * Find the real pnpm executable, bypassing any aliases and shadow bins.\n */\nexport function findRealPnpm(): string {\n const path = getPath()\n\n // Try common pnpm locations.\n const commonPaths = WIN32\n ? [\n // Windows common paths.\n path?.join(getAppdata() as string, 'npm', 'pnpm.cmd'),\n path?.join(getAppdata() as string, 'npm', 'pnpm'),\n path?.join(getLocalappdata() as string, 'pnpm', 'pnpm.cmd'),\n path?.join(getLocalappdata() as string, 'pnpm', 'pnpm'),\n 'C:\\\\Program Files\\\\nodejs\\\\pnpm.cmd',\n 'C:\\\\Program Files\\\\nodejs\\\\pnpm',\n ].filter(Boolean)\n : [\n // Unix common paths.\n '/usr/local/bin/pnpm',\n '/usr/bin/pnpm',\n path?.join(\n (getXdgDataHome() as string) || `${getHome() as string}/.local/share`,\n 'pnpm/pnpm',\n ),\n path?.join(getHome() as string, '.pnpm/pnpm'),\n ].filter(Boolean)\n\n return findRealBin('pnpm', commonPaths) ?? ''\n}\n\n/**\n * Find the real yarn executable, bypassing any aliases and shadow bins.\n */\nexport function findRealYarn(): string {\n const path = getPath()\n\n // Try common yarn locations.\n const commonPaths = [\n '/usr/local/bin/yarn',\n '/usr/bin/yarn',\n path?.join(getHome() as string, '.yarn/bin/yarn'),\n path?.join(\n getHome() as string,\n '.config/yarn/global/node_modules/.bin/yarn',\n ),\n ].filter(Boolean)\n\n return findRealBin('yarn', commonPaths) ?? ''\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n/**\n * Resolve a binary path to its actual executable file.\n * Handles Windows .cmd wrappers and Unix shell scripts.\n */\nexport function resolveBinPathSync(binPath: string): string {\n const fs = getFs()\n const path = getPath()\n\n // If it's not an absolute path, try to find it in PATH first\n if (!path?.isAbsolute(binPath)) {\n try {\n const resolved = whichBinSync(binPath)\n if (resolved) {\n binPath = resolved as string\n }\n } catch {}\n }\n\n // Normalize the path once for consistent pattern matching.\n binPath = normalizePath(binPath)\n\n // Handle empty string that normalized to '.' (current directory)\n if (binPath === '.') {\n return binPath\n }\n\n const ext = path?.extname(binPath)\n const extLowered = ext.toLowerCase()\n const basename = path?.basename(binPath, ext)\n const voltaIndex =\n basename === 'node' ? -1 : (/(?<=\\/)\\.volta\\//i.exec(binPath)?.index ?? -1)\n if (voltaIndex !== -1) {\n const voltaPath = binPath.slice(0, voltaIndex)\n const voltaToolsPath = path?.join(voltaPath, 'tools')\n const voltaImagePath = path?.join(voltaToolsPath, 'image')\n const voltaUserPath = path?.join(voltaToolsPath, 'user')\n const voltaPlatform = readJsonSync(\n path?.join(voltaUserPath, 'platform.json'),\n { throws: false },\n ) as any\n const voltaNodeVersion = voltaPlatform?.node?.runtime\n const voltaNpmVersion = voltaPlatform?.node?.npm\n let voltaBinPath = ''\n if (basename === 'npm' || basename === 'npx') {\n if (voltaNpmVersion) {\n const relCliPath = `bin/${basename}-cli.js`\n voltaBinPath = path?.join(\n voltaImagePath,\n `npm/${voltaNpmVersion}/${relCliPath}`,\n )\n if (voltaNodeVersion && !fs?.existsSync(voltaBinPath)) {\n voltaBinPath = path?.join(\n voltaImagePath,\n `node/${voltaNodeVersion}/lib/node_modules/npm/${relCliPath}`,\n )\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = ''\n }\n }\n }\n } else {\n const voltaUserBinPath = path?.join(voltaUserPath, 'bin')\n const binInfo = readJsonSync(\n path?.join(voltaUserBinPath, `${basename}.json`),\n { throws: false },\n ) as any\n const binPackage = binInfo?.package\n if (binPackage) {\n voltaBinPath = path?.join(\n voltaImagePath,\n `packages/${binPackage}/bin/${basename}`,\n )\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = `${voltaBinPath}.cmd`\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = ''\n }\n }\n }\n }\n if (voltaBinPath) {\n try {\n return normalizePath(fs?.realpathSync.native(voltaBinPath))\n } catch {}\n return voltaBinPath\n }\n }\n if (WIN32) {\n const hasKnownExt =\n extLowered === '' ||\n extLowered === '.cmd' ||\n extLowered === '.exe' ||\n extLowered === '.ps1'\n const isNpmOrNpx = basename === 'npm' || basename === 'npx'\n const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'\n if (hasKnownExt && isNpmOrNpx) {\n // The quick route assumes a bin path like: C:\\Program Files\\nodejs\\npm.cmd\n const quickPath = path?.join(\n path?.dirname(binPath),\n `node_modules/npm/bin/${basename}-cli.js`,\n )\n if (fs?.existsSync(quickPath)) {\n try {\n return fs?.realpathSync.native(quickPath)\n } catch {}\n return quickPath\n }\n }\n let relPath = ''\n if (\n hasKnownExt &&\n // Only parse shell scripts and batch files, not actual executables.\n // .exe files are already executables and don't need path resolution from wrapper scripts.\n extLowered !== '.exe' &&\n // Check if file exists before attempting to read it to avoid ENOENT errors.\n fs?.existsSync(binPath)\n ) {\n const source = fs?.readFileSync(binPath, 'utf8')\n if (isNpmOrNpx) {\n if (extLowered === '.cmd') {\n // \"npm.cmd\" and \"npx.cmd\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm.cmd\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx.cmd\n relPath =\n basename === 'npm'\n ? /(?<=\"NPM_CLI_JS=%~dp0\\\\).*(?=\")/.exec(source)?.[0] || ''\n : /(?<=\"NPX_CLI_JS=%~dp0\\\\).*(?=\")/.exec(source)?.[0] || ''\n } else if (extLowered === '') {\n // Extensionless \"npm\" and \"npx\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx\n relPath =\n basename === 'npm'\n ? /(?<=NPM_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] ||\n ''\n : /(?<=NPX_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] ||\n ''\n } else if (extLowered === '.ps1') {\n // \"npm.ps1\" and \"npx.ps1\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm.ps1\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx.ps1\n relPath =\n basename === 'npm'\n ? /(?<=\\$NPM_CLI_JS=\"\\$PSScriptRoot\\/).*(?=\")/.exec(\n source,\n )?.[0] || ''\n : /(?<=\\$NPX_CLI_JS=\"\\$PSScriptRoot\\/).*(?=\")/.exec(\n source,\n )?.[0] || ''\n }\n } else if (isPnpmOrYarn) {\n if (extLowered === '.cmd') {\n // pnpm.cmd and yarn.cmd can have different formats depending on installation method\n // Common formats include:\n // 1. Setup-pnpm action format: node \"%~dp0\\..\\pnpm\\bin\\pnpm.cjs\" %*\n // 2. npm install -g pnpm format: similar to cmd-shim\n // 3. Standalone installer format: various patterns\n\n // Try setup-pnpm/setup-yarn action format first\n relPath =\n /(?<=node\\s+\")%~dp0\\\\([^\"]+)(?=\"\\s+%\\*)/.exec(source)?.[1] || ''\n\n // Try alternative format: \"%~dp0\\node.exe\" \"%~dp0\\..\\package\\bin\\binary.js\" %*\n if (!relPath) {\n relPath =\n /(?<=\"%~dp0\\\\[^\"]*node[^\"]*\"\\s+\")%~dp0\\\\([^\"]+)(?=\"\\s+%\\*)/.exec(\n source,\n )?.[1] || ''\n }\n\n // Try cmd-shim format as fallback\n if (!relPath) {\n relPath = /(?<=\"%dp0%\\\\).*(?=\" %\\*\\r\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '') {\n // Extensionless pnpm/yarn - try common shebang formats\n // Handle pnpm installed via standalone installer or global install\n // Format: exec \"$basedir/node\" \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n // Note: may have multiple spaces between arguments\n relPath =\n /(?<=\"\\$basedir\\/)\\.tools\\/pnpm\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(\n source,\n )?.[0] || ''\n if (!relPath) {\n // Also try: exec node \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n relPath =\n /(?<=exec\\s+node\\s+\"\\$basedir\\/)\\.tools\\/pnpm\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(\n source,\n )?.[0] || ''\n }\n if (!relPath) {\n // Try standard cmd-shim format: exec node \"$basedir/../package/bin/binary.js\" \"$@\"\n relPath = /(?<=\"\\$basedir\\/).*(?=\" \"\\$@\"\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '.ps1') {\n // PowerShell format\n relPath = /(?<=\"\\$basedir\\/).*(?=\" $args\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '.cmd') {\n // \"bin.CMD\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L98:\n //\n // @ECHO off\n // GOTO start\n // :find_dp0\n // SET dp0=%~dp0\n // EXIT /b\n // :start\n // SETLOCAL\n // CALL :find_dp0\n //\n // IF EXIST \"%dp0%\\node.exe\" (\n // SET \"_prog=%dp0%\\node.exe\"\n // ) ELSE (\n // SET \"_prog=node\"\n // SET PATHEXT=%PATHEXT:;.JS;=;%\n // )\n //\n // endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & \"%_prog%\" \"%dp0%\\..\\<PACKAGE_NAME>\\path\\to\\bin.js\" %*\n relPath = /(?<=\"%dp0%\\\\).*(?=\" %\\*\\r\\n)/.exec(source)?.[0] || ''\n } else if (extLowered === '') {\n // Extensionless \"bin\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L138:\n //\n // #!/bin/sh\n // basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n //\n // case `uname` in\n // *CYGWIN*|*MINGW*|*MSYS*)\n // if command -v cygpath > /dev/null 2>&1; then\n // basedir=`cygpath -w \"$basedir\"`\n // fi\n // ;;\n // esac\n //\n // if [ -x \"$basedir/node\" ]; then\n // exec \"$basedir/node\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" \"$@\"\n // else\n // exec node \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" \"$@\"\n // fi\n relPath = /(?<=\"$basedir\\/).*(?=\" \"\\$@\"\\n)/.exec(source)?.[0] || ''\n } else if (extLowered === '.ps1') {\n // \"bin.PS1\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L192:\n //\n // #!/usr/bin/env pwsh\n // $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n //\n // $exe=\"\"\n // if ($PSVersionTable.PSVersion -lt \"6.0\" -or $IsWindows) {\n // # Fix case when both the Windows and Linux builds of Node\n // # are installed in the same directory\n // $exe=\".exe\"\n // }\n // $ret=0\n // if (Test-Path \"$basedir/node$exe\") {\n // # Support pipeline input\n // if ($MyInvocation.ExpectingInput) {\n // $input | & \"$basedir/node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // } else {\n // & \"$basedir/node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // }\n // $ret=$LASTEXITCODE\n // } else {\n // # Support pipeline input\n // if ($MyInvocation.ExpectingInput) {\n // $input | & \"node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // } else {\n // & \"node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // }\n // $ret=$LASTEXITCODE\n // }\n // exit $ret\n relPath = /(?<=\"\\$basedir\\/).*(?=\" $args\\n)/.exec(source)?.[0] || ''\n }\n if (relPath) {\n binPath = normalizePath(path?.resolve(path?.dirname(binPath), relPath))\n }\n }\n } else {\n // Handle Unix shell scripts (non-Windows platforms)\n let hasNoExt = extLowered === ''\n const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'\n const isNpmOrNpx = basename === 'npm' || basename === 'npx'\n\n // Handle special case where pnpm path in CI has extra segments.\n // In setup-pnpm GitHub Action, the path might be malformed like:\n // /home/user/setup-pnpm/node_modules/.bin/pnpm/bin/pnpm.cjs\n // This happens when the shell script contains a relative path that\n // when resolved, creates an invalid nested structure.\n if (isPnpmOrYarn && binPath.includes('/.bin/pnpm/bin/')) {\n // Extract the correct pnpm bin path.\n const binIndex = binPath.indexOf('/.bin/pnpm')\n if (binIndex !== -1) {\n // Get the base path up to /.bin/pnpm.\n const baseBinPath = binPath.slice(0, binIndex + '/.bin/pnpm'.length)\n // Check if the original shell script exists.\n try {\n const stats = fs?.statSync(baseBinPath)\n // Only use this path if it's a file (the shell script).\n if (stats.isFile()) {\n binPath = normalizePath(baseBinPath)\n // Recompute hasNoExt since we changed the path.\n hasNoExt = !path?.extname(binPath)\n }\n } catch {\n // If stat fails, continue with the original path.\n }\n }\n }\n\n if (\n hasNoExt &&\n (isPnpmOrYarn || isNpmOrNpx) &&\n // For extensionless files (Unix shell scripts), verify existence before reading.\n // This prevents ENOENT errors when the bin path doesn't exist.\n fs?.existsSync(binPath)\n ) {\n const source = fs?.readFileSync(binPath, 'utf8')\n let relPath = ''\n\n if (isPnpmOrYarn) {\n // Handle pnpm/yarn Unix shell scripts.\n // Format: exec \"$basedir/node\" \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n // or: exec node \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n relPath =\n /(?<=\"\\$basedir\\/)\\.tools\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(source)?.[0] || ''\n if (!relPath) {\n // Try standard cmd-shim format: exec node \"$basedir/../package/bin/binary.js\" \"$@\"\n // Example: exec node \"$basedir/../pnpm/bin/pnpm.cjs\" \"$@\"\n // ^^^^^^^^^^^^^^^^^^^^^ captures this part\n // This regex needs to be more careful to not match \"$@\" at the end.\n relPath =\n /(?<=\"\\$basedir\\/)[^\"]+(?=\"\\s+\"\\$@\")/.exec(source)?.[0] || ''\n }\n // Special case for setup-pnpm GitHub Action which may use a different format.\n // The setup-pnpm action creates a shell script that references ../pnpm/bin/pnpm.cjs\n if (!relPath) {\n // Try to match: exec node \"$basedir/../pnpm/bin/pnpm.cjs\" \"$@\"\n const match = /exec\\s+node\\s+\"?\\$basedir\\/([^\"]+)\"?\\s+\"\\$@\"/.exec(\n source,\n )\n if (match) {\n relPath = match[1] || ''\n }\n }\n // Check if the extracted path looks wrong (e.g., pnpm/bin/pnpm.cjs without ../).\n // This happens with setup-pnpm action when it creates a malformed shell script.\n if (relPath && basename === 'pnpm' && relPath.startsWith('pnpm/')) {\n // The path should be ../pnpm/... not pnpm/...\n // Prepend ../ to fix the relative path.\n relPath = `../${relPath}`\n }\n } else if (isNpmOrNpx) {\n // Handle npm/npx Unix shell scripts\n relPath =\n basename === 'npm'\n ? /(?<=NPM_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] || ''\n : /(?<=NPX_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] || ''\n }\n\n if (relPath) {\n // Resolve the relative path to handle .. segments properly.\n binPath = normalizePath(path?.resolve(path?.dirname(binPath), relPath))\n }\n }\n }\n try {\n const realPath = fs?.realpathSync.native(binPath)\n return normalizePath(realPath)\n } catch {}\n // Return normalized path even if realpath fails.\n return normalizePath(binPath)\n}\n"],
|
|
5
|
-
"mappings": ";4ZAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,gBAAAC,EAAA,gBAAAC,EAAA,iBAAAC,EAAA,iBAAAC,EAAA,oBAAAC,EAAA,uBAAAC,EAAA,aAAAC,EAAA,iBAAAC,IAAA,eAAAC,
|
|
6
|
-
"names": ["bin_exports", "__export", "execBin", "findRealBin", "findRealNpm", "findRealPnpm", "findRealYarn", "isShadowBinPath", "resolveBinPathSync", "whichBin", "whichBinSync", "__toCommonJS", "import_home", "import_windows", "import_xdg", "import_platform", "import_fs", "
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Binary path resolution and execution utilities for package managers.\n * Provides cross-platform bin path lookup, command execution, and path normalization.\n */\n\nimport { getHome } from '#env/home'\nimport { getAppdata, getLocalappdata } from '#env/windows'\nimport { getXdgDataHome } from '#env/xdg'\n\nimport { WIN32 } from '#constants/platform'\nimport { readJsonSync } from './fs'\nimport { isPath, normalizePath } from './path'\nimport { spawn } from './spawn'\n\nlet _fs: typeof import('node:fs') | undefined\n/**\n * Lazily load the fs module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getFs() {\n if (_fs === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _fs = /*@__PURE__*/ require('node:fs')\n }\n return _fs!\n}\n\nlet _path: typeof import('node:path') | undefined\n/**\n * Lazily load the path module to avoid Webpack errors.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getPath() {\n if (_path === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _path = /*@__PURE__*/ require('node:path')\n }\n return _path!\n}\n\nlet _which: typeof import('which') | undefined\n/**\n * Lazily load the which module for finding executables.\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getWhich() {\n if (_which === undefined) {\n _which = /*@__PURE__*/ require('./external/which')\n }\n return _which!\n}\n\n/**\n * Execute a binary with the given arguments.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function execBin(\n binPath: string,\n args?: string[],\n options?: import('./spawn').SpawnOptions,\n) {\n // Resolve the binary path.\n const resolvedPath = isPath(binPath)\n ? resolveBinPathSync(binPath)\n : await whichBin(binPath)\n\n if (!resolvedPath) {\n const error = new Error(`Binary not found: ${binPath}`) as Error & {\n code: string\n }\n error.code = 'ENOENT'\n throw error\n }\n\n // Execute the binary directly.\n const binCommand = Array.isArray(resolvedPath)\n ? resolvedPath[0]!\n : resolvedPath\n // On Windows, binaries are often .cmd files that require shell to execute.\n return await spawn(binCommand, args ?? [], {\n shell: WIN32,\n ...options,\n })\n}\n\n/**\n * Options for the which function.\n */\nexport interface WhichOptions {\n /** If true, return all matches instead of just the first one. */\n all?: boolean | undefined\n /** If true, return null instead of throwing when no match is found. */\n nothrow?: boolean | undefined\n /** Path to search in. */\n path?: string | undefined\n /** Path separator character. */\n pathExt?: string | undefined\n /** Environment variables to use. */\n env?: Record<string, string | undefined> | undefined\n}\n\n/**\n * Find an executable in the system PATH asynchronously.\n * Wrapper around the which package for lazy loading.\n */\nexport async function which(\n binName: string,\n options?: WhichOptions,\n): Promise<string | string[] | undefined> {\n return await getWhich()(binName, options)\n}\n\n/**\n * Find an executable in the system PATH synchronously.\n * Wrapper around the which package for lazy loading.\n */\nexport function whichSync(\n binName: string,\n options?: WhichOptions,\n): string | string[] | undefined {\n return getWhich().sync(binName, options)\n}\n\n/**\n * Find and resolve a binary in the system PATH asynchronously.\n * @throws {Error} If the binary is not found and nothrow is false.\n */\nexport async function whichBin(\n binName: string,\n options?: WhichOptions,\n): Promise<string | string[] | undefined> {\n const which = getWhich()\n // Default to nothrow: true if not specified to return undefined instead of throwing\n const opts = { nothrow: true, ...options }\n // Depending on options `which` may throw if `binName` is not found.\n // With nothrow: true, it returns null when `binName` is not found.\n const result = await which(binName, opts)\n\n // When 'all: true' is specified, ensure we always return an array.\n if (opts?.all) {\n const paths = Array.isArray(result)\n ? result\n : typeof result === 'string'\n ? [result]\n : undefined\n // If all is true and we have paths, resolve each one.\n return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths\n }\n\n // If result is undefined (binary not found), return undefined\n if (!result) {\n return undefined\n }\n\n return resolveBinPathSync(result)\n}\n\n/**\n * Find and resolve a binary in the system PATH synchronously.\n * @throws {Error} If the binary is not found and nothrow is false.\n */\nexport function whichBinSync(\n binName: string,\n options?: WhichOptions,\n): string | string[] | undefined {\n // Default to nothrow: true if not specified to return undefined instead of throwing\n const opts = { nothrow: true, ...options }\n // Depending on options `which` may throw if `binName` is not found.\n // With nothrow: true, it returns null when `binName` is not found.\n const result = whichSync(binName, opts)\n\n // When 'all: true' is specified, ensure we always return an array.\n if (opts.all) {\n const paths = Array.isArray(result)\n ? result\n : typeof result === 'string'\n ? [result]\n : undefined\n // If all is true and we have paths, resolve each one.\n return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths\n }\n\n // If result is undefined (binary not found), return undefined\n if (!result) {\n return undefined\n }\n\n return resolveBinPathSync(result as string)\n}\n\n/**\n * Check if a directory path contains any shadow bin patterns.\n */\nexport function isShadowBinPath(dirPath: string | undefined): boolean {\n if (!dirPath) {\n return false\n }\n // Check for node_modules/.bin pattern (Unix and Windows)\n const normalized = dirPath.replace(/\\\\/g, '/')\n return normalized.includes('node_modules/.bin')\n}\n\n/**\n * Find the real executable for a binary, bypassing shadow bins.\n */\nexport function findRealBin(\n binName: string,\n commonPaths: string[] = [],\n): string | undefined {\n const fs = getFs()\n const path = getPath()\n const which = getWhich()\n\n // Try common locations first.\n for (const binPath of commonPaths) {\n if (fs?.existsSync(binPath)) {\n return binPath\n }\n }\n\n // Fall back to which.sync if no direct path found.\n const binPath = which?.sync(binName, { nothrow: true })\n if (binPath) {\n const binDir = path?.dirname(binPath)\n\n if (isShadowBinPath(binDir)) {\n // This is likely a shadowed binary, try to find the real one.\n const allPaths = which?.sync(binName, { all: true, nothrow: true }) || []\n // Ensure allPaths is an array.\n const pathsArray = Array.isArray(allPaths)\n ? allPaths\n : typeof allPaths === 'string'\n ? [allPaths]\n : []\n\n for (const altPath of pathsArray) {\n const altDir = path?.dirname(altPath)\n if (!isShadowBinPath(altDir)) {\n return altPath\n }\n }\n }\n return binPath\n }\n // If all else fails, return undefined to indicate binary not found.\n return undefined\n}\n\n/**\n * Find the real npm executable, bypassing any aliases and shadow bins.\n */\nexport function findRealNpm(): string {\n const fs = getFs()\n const path = getPath()\n\n // Try to find npm in the same directory as the node executable.\n const nodeDir = path?.dirname(process.execPath)\n const npmInNodeDir = path?.join(nodeDir, 'npm')\n\n if (fs?.existsSync(npmInNodeDir)) {\n return npmInNodeDir\n }\n\n // Try common npm locations.\n const commonPaths = ['/usr/local/bin/npm', '/usr/bin/npm']\n const result = findRealBin('npm', commonPaths)\n\n // If we found a valid path, return it.\n if (result && fs?.existsSync(result)) {\n return result\n }\n\n // As a last resort, try to use whichBinSync to find npm.\n // This handles cases where npm is installed in non-standard locations.\n const npmPath = whichBinSync('npm', { nothrow: true })\n if (npmPath && typeof npmPath === 'string' && fs?.existsSync(npmPath)) {\n return npmPath\n }\n\n // Return the basic 'npm' and let the system resolve it.\n return 'npm'\n}\n\n/**\n * Find the real pnpm executable, bypassing any aliases and shadow bins.\n */\nexport function findRealPnpm(): string {\n const path = getPath()\n\n // Try common pnpm locations.\n const commonPaths = WIN32\n ? [\n // Windows common paths.\n path?.join(getAppdata() as string, 'npm', 'pnpm.cmd'),\n path?.join(getAppdata() as string, 'npm', 'pnpm'),\n path?.join(getLocalappdata() as string, 'pnpm', 'pnpm.cmd'),\n path?.join(getLocalappdata() as string, 'pnpm', 'pnpm'),\n 'C:\\\\Program Files\\\\nodejs\\\\pnpm.cmd',\n 'C:\\\\Program Files\\\\nodejs\\\\pnpm',\n ].filter(Boolean)\n : [\n // Unix common paths.\n '/usr/local/bin/pnpm',\n '/usr/bin/pnpm',\n path?.join(\n (getXdgDataHome() as string) || `${getHome() as string}/.local/share`,\n 'pnpm/pnpm',\n ),\n path?.join(getHome() as string, '.pnpm/pnpm'),\n ].filter(Boolean)\n\n return findRealBin('pnpm', commonPaths) ?? ''\n}\n\n/**\n * Find the real yarn executable, bypassing any aliases and shadow bins.\n */\nexport function findRealYarn(): string {\n const path = getPath()\n\n // Try common yarn locations.\n const commonPaths = [\n '/usr/local/bin/yarn',\n '/usr/bin/yarn',\n path?.join(getHome() as string, '.yarn/bin/yarn'),\n path?.join(\n getHome() as string,\n '.config/yarn/global/node_modules/.bin/yarn',\n ),\n ].filter(Boolean)\n\n return findRealBin('yarn', commonPaths) ?? ''\n}\n\n/*@__NO_SIDE_EFFECTS__*/\n/**\n * Resolve a binary path to its actual executable file.\n * Handles Windows .cmd wrappers and Unix shell scripts.\n */\nexport function resolveBinPathSync(binPath: string): string {\n const fs = getFs()\n const path = getPath()\n\n // If it's not an absolute path, try to find it in PATH first\n if (!path?.isAbsolute(binPath)) {\n try {\n const resolved = whichBinSync(binPath)\n if (resolved) {\n binPath = resolved as string\n }\n } catch {}\n }\n\n // Normalize the path once for consistent pattern matching.\n binPath = normalizePath(binPath)\n\n // Handle empty string that normalized to '.' (current directory)\n if (binPath === '.') {\n return binPath\n }\n\n const ext = path?.extname(binPath)\n const extLowered = ext.toLowerCase()\n const basename = path?.basename(binPath, ext)\n const voltaIndex =\n basename === 'node' ? -1 : (/(?<=\\/)\\.volta\\//i.exec(binPath)?.index ?? -1)\n if (voltaIndex !== -1) {\n const voltaPath = binPath.slice(0, voltaIndex)\n const voltaToolsPath = path?.join(voltaPath, 'tools')\n const voltaImagePath = path?.join(voltaToolsPath, 'image')\n const voltaUserPath = path?.join(voltaToolsPath, 'user')\n const voltaPlatform = readJsonSync(\n path?.join(voltaUserPath, 'platform.json'),\n { throws: false },\n ) as any\n const voltaNodeVersion = voltaPlatform?.node?.runtime\n const voltaNpmVersion = voltaPlatform?.node?.npm\n let voltaBinPath = ''\n if (basename === 'npm' || basename === 'npx') {\n if (voltaNpmVersion) {\n const relCliPath = `bin/${basename}-cli.js`\n voltaBinPath = path?.join(\n voltaImagePath,\n `npm/${voltaNpmVersion}/${relCliPath}`,\n )\n if (voltaNodeVersion && !fs?.existsSync(voltaBinPath)) {\n voltaBinPath = path?.join(\n voltaImagePath,\n `node/${voltaNodeVersion}/lib/node_modules/npm/${relCliPath}`,\n )\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = ''\n }\n }\n }\n } else {\n const voltaUserBinPath = path?.join(voltaUserPath, 'bin')\n const binInfo = readJsonSync(\n path?.join(voltaUserBinPath, `${basename}.json`),\n { throws: false },\n ) as any\n const binPackage = binInfo?.package\n if (binPackage) {\n voltaBinPath = path?.join(\n voltaImagePath,\n `packages/${binPackage}/bin/${basename}`,\n )\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = `${voltaBinPath}.cmd`\n if (!fs?.existsSync(voltaBinPath)) {\n voltaBinPath = ''\n }\n }\n }\n }\n if (voltaBinPath) {\n try {\n return normalizePath(fs?.realpathSync.native(voltaBinPath))\n } catch {}\n return voltaBinPath\n }\n }\n if (WIN32) {\n const hasKnownExt =\n extLowered === '' ||\n extLowered === '.cmd' ||\n extLowered === '.exe' ||\n extLowered === '.ps1'\n const isNpmOrNpx = basename === 'npm' || basename === 'npx'\n const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'\n if (hasKnownExt && isNpmOrNpx) {\n // The quick route assumes a bin path like: C:\\Program Files\\nodejs\\npm.cmd\n const quickPath = path?.join(\n path?.dirname(binPath),\n `node_modules/npm/bin/${basename}-cli.js`,\n )\n if (fs?.existsSync(quickPath)) {\n try {\n return fs?.realpathSync.native(quickPath)\n } catch {}\n return quickPath\n }\n }\n let relPath = ''\n if (\n hasKnownExt &&\n // Only parse shell scripts and batch files, not actual executables.\n // .exe files are already executables and don't need path resolution from wrapper scripts.\n extLowered !== '.exe' &&\n // Check if file exists before attempting to read it to avoid ENOENT errors.\n fs?.existsSync(binPath)\n ) {\n const source = fs?.readFileSync(binPath, 'utf8')\n if (isNpmOrNpx) {\n if (extLowered === '.cmd') {\n // \"npm.cmd\" and \"npx.cmd\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm.cmd\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx.cmd\n relPath =\n basename === 'npm'\n ? /(?<=\"NPM_CLI_JS=%~dp0\\\\).*(?=\")/.exec(source)?.[0] || ''\n : /(?<=\"NPX_CLI_JS=%~dp0\\\\).*(?=\")/.exec(source)?.[0] || ''\n } else if (extLowered === '') {\n // Extensionless \"npm\" and \"npx\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx\n relPath =\n basename === 'npm'\n ? /(?<=NPM_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] ||\n ''\n : /(?<=NPX_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] ||\n ''\n } else if (extLowered === '.ps1') {\n // \"npm.ps1\" and \"npx.ps1\" defined by\n // https://github.com/npm/cli/blob/v11.4.2/bin/npm.ps1\n // https://github.com/npm/cli/blob/v11.4.2/bin/npx.ps1\n relPath =\n basename === 'npm'\n ? /(?<=\\$NPM_CLI_JS=\"\\$PSScriptRoot\\/).*(?=\")/.exec(\n source,\n )?.[0] || ''\n : /(?<=\\$NPX_CLI_JS=\"\\$PSScriptRoot\\/).*(?=\")/.exec(\n source,\n )?.[0] || ''\n }\n } else if (isPnpmOrYarn) {\n if (extLowered === '.cmd') {\n // pnpm.cmd and yarn.cmd can have different formats depending on installation method\n // Common formats include:\n // 1. Setup-pnpm action format: node \"%~dp0\\..\\pnpm\\bin\\pnpm.cjs\" %*\n // 2. npm install -g pnpm format: similar to cmd-shim\n // 3. Standalone installer format: various patterns\n\n // Try setup-pnpm/setup-yarn action format first\n relPath =\n /(?<=node\\s+\")%~dp0\\\\([^\"]+)(?=\"\\s+%\\*)/.exec(source)?.[1] || ''\n\n // Try alternative format: \"%~dp0\\node.exe\" \"%~dp0\\..\\package\\bin\\binary.js\" %*\n if (!relPath) {\n relPath =\n /(?<=\"%~dp0\\\\[^\"]*node[^\"]*\"\\s+\")%~dp0\\\\([^\"]+)(?=\"\\s+%\\*)/.exec(\n source,\n )?.[1] || ''\n }\n\n // Try cmd-shim format as fallback\n if (!relPath) {\n relPath = /(?<=\"%dp0%\\\\).*(?=\" %\\*\\r\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '') {\n // Extensionless pnpm/yarn - try common shebang formats\n // Handle pnpm installed via standalone installer or global install\n // Format: exec \"$basedir/node\" \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n // Note: may have multiple spaces between arguments\n relPath =\n /(?<=\"\\$basedir\\/)\\.tools\\/pnpm\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(\n source,\n )?.[0] || ''\n if (!relPath) {\n // Also try: exec node \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n relPath =\n /(?<=exec\\s+node\\s+\"\\$basedir\\/)\\.tools\\/pnpm\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(\n source,\n )?.[0] || ''\n }\n if (!relPath) {\n // Try standard cmd-shim format: exec node \"$basedir/../package/bin/binary.js\" \"$@\"\n relPath = /(?<=\"\\$basedir\\/).*(?=\" \"\\$@\"\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '.ps1') {\n // PowerShell format\n relPath = /(?<=\"\\$basedir\\/).*(?=\" $args\\n)/.exec(source)?.[0] || ''\n }\n } else if (extLowered === '.cmd') {\n // \"bin.CMD\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L98:\n //\n // @ECHO off\n // GOTO start\n // :find_dp0\n // SET dp0=%~dp0\n // EXIT /b\n // :start\n // SETLOCAL\n // CALL :find_dp0\n //\n // IF EXIST \"%dp0%\\node.exe\" (\n // SET \"_prog=%dp0%\\node.exe\"\n // ) ELSE (\n // SET \"_prog=node\"\n // SET PATHEXT=%PATHEXT:;.JS;=;%\n // )\n //\n // endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & \"%_prog%\" \"%dp0%\\..\\<PACKAGE_NAME>\\path\\to\\bin.js\" %*\n relPath = /(?<=\"%dp0%\\\\).*(?=\" %\\*\\r\\n)/.exec(source)?.[0] || ''\n } else if (extLowered === '') {\n // Extensionless \"bin\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L138:\n //\n // #!/bin/sh\n // basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n //\n // case `uname` in\n // *CYGWIN*|*MINGW*|*MSYS*)\n // if command -v cygpath > /dev/null 2>&1; then\n // basedir=`cygpath -w \"$basedir\"`\n // fi\n // ;;\n // esac\n //\n // if [ -x \"$basedir/node\" ]; then\n // exec \"$basedir/node\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" \"$@\"\n // else\n // exec node \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" \"$@\"\n // fi\n relPath = /(?<=\"$basedir\\/).*(?=\" \"\\$@\"\\n)/.exec(source)?.[0] || ''\n } else if (extLowered === '.ps1') {\n // \"bin.PS1\" generated by\n // https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L192:\n //\n // #!/usr/bin/env pwsh\n // $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n //\n // $exe=\"\"\n // if ($PSVersionTable.PSVersion -lt \"6.0\" -or $IsWindows) {\n // # Fix case when both the Windows and Linux builds of Node\n // # are installed in the same directory\n // $exe=\".exe\"\n // }\n // $ret=0\n // if (Test-Path \"$basedir/node$exe\") {\n // # Support pipeline input\n // if ($MyInvocation.ExpectingInput) {\n // $input | & \"$basedir/node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // } else {\n // & \"$basedir/node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // }\n // $ret=$LASTEXITCODE\n // } else {\n // # Support pipeline input\n // if ($MyInvocation.ExpectingInput) {\n // $input | & \"node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // } else {\n // & \"node$exe\" \"$basedir/../<PACKAGE_NAME>/path/to/bin.js\" $args\n // }\n // $ret=$LASTEXITCODE\n // }\n // exit $ret\n relPath = /(?<=\"\\$basedir\\/).*(?=\" $args\\n)/.exec(source)?.[0] || ''\n }\n if (relPath) {\n binPath = normalizePath(path?.resolve(path?.dirname(binPath), relPath))\n }\n }\n } else {\n // Handle Unix shell scripts (non-Windows platforms)\n let hasNoExt = extLowered === ''\n const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'\n const isNpmOrNpx = basename === 'npm' || basename === 'npx'\n\n // Handle special case where pnpm path in CI has extra segments.\n // In setup-pnpm GitHub Action, the path might be malformed like:\n // /home/user/setup-pnpm/node_modules/.bin/pnpm/bin/pnpm.cjs\n // This happens when the shell script contains a relative path that\n // when resolved, creates an invalid nested structure.\n if (isPnpmOrYarn && binPath.includes('/.bin/pnpm/bin/')) {\n // Extract the correct pnpm bin path.\n const binIndex = binPath.indexOf('/.bin/pnpm')\n if (binIndex !== -1) {\n // Get the base path up to /.bin/pnpm.\n const baseBinPath = binPath.slice(0, binIndex + '/.bin/pnpm'.length)\n // Check if the original shell script exists.\n try {\n const stats = fs?.statSync(baseBinPath)\n // Only use this path if it's a file (the shell script).\n if (stats.isFile()) {\n binPath = normalizePath(baseBinPath)\n // Recompute hasNoExt since we changed the path.\n hasNoExt = !path?.extname(binPath)\n }\n } catch {\n // If stat fails, continue with the original path.\n }\n }\n }\n\n if (\n hasNoExt &&\n (isPnpmOrYarn || isNpmOrNpx) &&\n // For extensionless files (Unix shell scripts), verify existence before reading.\n // This prevents ENOENT errors when the bin path doesn't exist.\n fs?.existsSync(binPath)\n ) {\n const source = fs?.readFileSync(binPath, 'utf8')\n let relPath = ''\n\n if (isPnpmOrYarn) {\n // Handle pnpm/yarn Unix shell scripts.\n // Format: exec \"$basedir/node\" \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n // or: exec node \"$basedir/.tools/pnpm/VERSION/...\" \"$@\"\n relPath =\n /(?<=\"\\$basedir\\/)\\.tools\\/[^\"]+(?=\"\\s+\"\\$@\")/.exec(source)?.[0] || ''\n if (!relPath) {\n // Try standard cmd-shim format: exec node \"$basedir/../package/bin/binary.js\" \"$@\"\n // Example: exec node \"$basedir/../pnpm/bin/pnpm.cjs\" \"$@\"\n // ^^^^^^^^^^^^^^^^^^^^^ captures this part\n // This regex needs to be more careful to not match \"$@\" at the end.\n relPath =\n /(?<=\"\\$basedir\\/)[^\"]+(?=\"\\s+\"\\$@\")/.exec(source)?.[0] || ''\n }\n // Special case for setup-pnpm GitHub Action which may use a different format.\n // The setup-pnpm action creates a shell script that references ../pnpm/bin/pnpm.cjs\n if (!relPath) {\n // Try to match: exec node \"$basedir/../pnpm/bin/pnpm.cjs\" \"$@\"\n const match = /exec\\s+node\\s+\"?\\$basedir\\/([^\"]+)\"?\\s+\"\\$@\"/.exec(\n source,\n )\n if (match) {\n relPath = match[1] || ''\n }\n }\n // Check if the extracted path looks wrong (e.g., pnpm/bin/pnpm.cjs without ../).\n // This happens with setup-pnpm action when it creates a malformed shell script.\n if (relPath && basename === 'pnpm' && relPath.startsWith('pnpm/')) {\n // The path should be ../pnpm/... not pnpm/...\n // Prepend ../ to fix the relative path.\n relPath = `../${relPath}`\n }\n } else if (isNpmOrNpx) {\n // Handle npm/npx Unix shell scripts\n relPath =\n basename === 'npm'\n ? /(?<=NPM_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] || ''\n : /(?<=NPX_CLI_JS=\"\\$CLI_BASEDIR\\/).*(?=\")/.exec(source)?.[0] || ''\n }\n\n if (relPath) {\n // Resolve the relative path to handle .. segments properly.\n binPath = normalizePath(path?.resolve(path?.dirname(binPath), relPath))\n }\n }\n }\n try {\n const realPath = fs?.realpathSync.native(binPath)\n return normalizePath(realPath)\n } catch {}\n // Return normalized path even if realpath fails.\n return normalizePath(binPath)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["bin_exports", "__export", "execBin", "findRealBin", "findRealNpm", "findRealPnpm", "findRealYarn", "isShadowBinPath", "resolveBinPathSync", "which", "whichBin", "whichBinSync", "whichSync", "__toCommonJS", "import_home", "import_windows", "import_xdg", "import_platform", "import_fs", "import_path", "import_spawn", "_fs", "getFs", "_path", "getPath", "_which", "getWhich", "binPath", "args", "options", "resolvedPath", "error", "binCommand", "binName", "opts", "result", "paths", "p", "dirPath", "commonPaths", "fs", "path", "binDir", "allPaths", "pathsArray", "altPath", "altDir", "nodeDir", "npmInNodeDir", "npmPath", "resolved", "ext", "extLowered", "basename", "voltaIndex", "voltaPath", "voltaToolsPath", "voltaImagePath", "voltaUserPath", "voltaPlatform", "voltaNodeVersion", "voltaNpmVersion", "voltaBinPath", "relCliPath", "voltaUserBinPath", "binPackage", "hasKnownExt", "isNpmOrNpx", "isPnpmOrYarn", "quickPath", "relPath", "source", "hasNoExt", "binIndex", "baseBinPath", "match", "realPath"]
|
|
7
7
|
}
|
package/dist/logger.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* Socket Lib - Built with esbuild */
|
|
2
|
-
var O=Object.create;var g=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var W=(o,t)=>{for(var s in t)g(o,s,{get:t[s],enumerable:!0})},_=(o,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of P(t))!E.call(o,e)&&e!==s&&g(o,e,{get:()=>t[e],enumerable:!(n=j(t,e))||n.enumerable});return o};var L=(o,t,s)=>(s=o!=null?O(A(o)):{},_(t||!o||!o.__esModule?g(s,"default",{value:o,enumerable:!0}):s,o)),B=o=>_(g({},"__esModule",{value:!0}),o);var Y={};W(Y,{LOG_SYMBOLS:()=>f,Logger:()=>h,incLogCallCountSymbol:()=>u,lastWasBlankSymbol:()=>i,logger:()=>H});module.exports=B(Y);var S=L(require("./external/@socketregistry/is-unicode-supported")),R=L(require("./external/yoctocolors-cjs")),p=require("./objects"),a=require("./strings");const d=console,y=Reflect.apply,I=Reflect.construct;let w;function C(...o){return w===void 0&&(w=require("node:console").Console),I(w,o)}function $(){return R.default}const f=(()=>{const o={__proto__:null},t={__proto__:null},s=()=>{const n=(0,S.default)(),e=$();(0,p.objectAssign)(o,{fail:e.red(n?"\u2716":"\xD7"),info:e.blue(n?"\u2139":"i"),step:e.cyan(n?"\u2192":">"),success:e.green(n?"\u2714":"\u221A"),warn:e.yellow(n?"\u26A0":"\u203C")}),(0,p.objectFreeze)(o);for(const c in t)delete t[c]};for(const n of Reflect.ownKeys(Reflect)){const e=Reflect[n];typeof e=="function"&&(t[n]=(...c)=>(s(),e(...c)))}return new Proxy(o,t)})(),M=["_stderrErrorHandler","_stdoutErrorHandler","assert","clear","count","countReset","createTask","debug","dir","dirxml","error","info","log","table","time","timeEnd","timeLog","trace","warn"].filter(o=>typeof d[o]=="function").map(o=>[o,d[o].bind(d)]),x={__proto__:null,writable:!0,enumerable:!1,configurable:!0},K=1e3,r=new WeakMap,G=Object.getOwnPropertySymbols(d),u=Symbol.for("logger.logCallCount++"),k=G.find(o=>o.label==="kGroupIndentWidth")??Symbol("kGroupIndentWidth"),i=Symbol.for("logger.lastWasBlank");class h{static LOG_SYMBOLS=f;#
|
|
2
|
+
var O=Object.create;var g=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var W=(o,t)=>{for(var s in t)g(o,s,{get:t[s],enumerable:!0})},_=(o,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of P(t))!E.call(o,e)&&e!==s&&g(o,e,{get:()=>t[e],enumerable:!(n=j(t,e))||n.enumerable});return o};var L=(o,t,s)=>(s=o!=null?O(A(o)):{},_(t||!o||!o.__esModule?g(s,"default",{value:o,enumerable:!0}):s,o)),B=o=>_(g({},"__esModule",{value:!0}),o);var Y={};W(Y,{LOG_SYMBOLS:()=>f,Logger:()=>h,incLogCallCountSymbol:()=>u,lastWasBlankSymbol:()=>i,logger:()=>H});module.exports=B(Y);var S=L(require("./external/@socketregistry/is-unicode-supported")),R=L(require("./external/yoctocolors-cjs")),p=require("./objects"),a=require("./strings");const d=console,y=Reflect.apply,I=Reflect.construct;let w;function C(...o){return w===void 0&&(w=require("node:console").Console),I(w,o)}function $(){return R.default}const f=(()=>{const o={__proto__:null},t={__proto__:null},s=()=>{const n=(0,S.default)(),e=$();(0,p.objectAssign)(o,{fail:e.red(n?"\u2716":"\xD7"),info:e.blue(n?"\u2139":"i"),step:e.cyan(n?"\u2192":">"),success:e.green(n?"\u2714":"\u221A"),warn:e.yellow(n?"\u26A0":"\u203C")}),(0,p.objectFreeze)(o);for(const c in t)delete t[c]};for(const n of Reflect.ownKeys(Reflect)){const e=Reflect[n];typeof e=="function"&&(t[n]=(...c)=>(s(),e(...c)))}return new Proxy(o,t)})(),M=["_stderrErrorHandler","_stdoutErrorHandler","assert","clear","count","countReset","createTask","debug","dir","dirxml","error","info","log","table","time","timeEnd","timeLog","trace","warn"].filter(o=>typeof d[o]=="function").map(o=>[o,d[o].bind(d)]),x={__proto__:null,writable:!0,enumerable:!1,configurable:!0},K=1e3,r=new WeakMap,G=Object.getOwnPropertySymbols(d),u=Symbol.for("logger.logCallCount++"),k=G.find(o=>o.label==="kGroupIndentWidth")??Symbol("kGroupIndentWidth"),i=Symbol.for("logger.lastWasBlank");class h{static LOG_SYMBOLS=f;#u;#t;#l;#h;#g="";#f="";#p=!1;#y=!1;#a=0;#i;#e;#w;constructor(...t){this.#i=t;const s=t[0];if(typeof s=="object"&&s!==null?(this.#e={__proto__:null,...s},this.#w=s.stdout):this.#e={__proto__:null},t.length)r.set(this,C(...t));else{const n=C({stdout:process.stdout,stderr:process.stderr});for(const{0:e,1:c}of M)n[e]=c;r.set(this,n)}}get stderr(){if(!this.#l){const t=new h(...this.#i);t.#u=this,t.#t="stderr",t.#e={__proto__:null,...this.#e},this.#l=t}return this.#l}get stdout(){if(!this.#h){const t=new h(...this.#i);t.#u=this,t.#t="stdout",t.#e={__proto__:null,...this.#e},this.#h=t}return this.#h}#o(){return this.#u||this}#s(t){const s=this.#o();return t==="stderr"?s.#g:s.#f}#n(t,s){const n=this.#o();t==="stderr"?n.#g=s:n.#f=s}#d(t){const s=this.#o();return t==="stderr"?s.#p:s.#y}#c(t,s){const n=this.#o();t==="stderr"?n.#p=s:n.#y=s}#k(){return this.#t||"stderr"}#m(t,s,n){const e=r.get(this),c=s.at(0),l=typeof c=="string",m=n||(t==="log"?"stdout":"stderr"),T=this.#s(m),b=l?[(0,a.applyLinePrefix)(c,{prefix:T}),...s.slice(1)]:s;return y(e[t],e,b),this[i](l&&(0,a.isBlankString)(b[0]),m),this[u](),this}#b(t){return t.replace(/^[✖✗×⚠‼✔✓√ℹ→]\uFE0F?\s*/u,"")}#r(t,s){const n=r.get(this);let e=s.at(0),c;typeof e=="string"?(e=this.#b(e),c=s.slice(1)):(c=s,e="");const l=this.#s("stderr");return n.error((0,a.applyLinePrefix)(`${f[t]} ${e}`,{prefix:l}),...c),this[i](!1,"stderr"),this[u](),this}get logCallCount(){return this.#o().#a}[u](){const t=this.#o();return t.#a+=1,this}[i](t,s){return s?this.#c(s,!!t):this.#t?this.#c(this.#t,!!t):(this.#c("stderr",!!t),this.#c("stdout",!!t)),this}assert(t,...s){return r.get(this).assert(t,...s),this[i](!1),t?this:this[u]()}clearVisible(){if(this.#t)throw new Error("clearVisible() is only available on the main logger instance, not on stream-bound instances");const t=r.get(this);return t.clear(),t._stdout.isTTY&&(this[i](!0),this.#a=0),this}count(t){return r.get(this).count(t),this[i](!1),this[u]()}createTask(t){return{run:s=>{this.log(`Starting task: ${t}`);const n=s();return this.log(`Completed task: ${t}`),n}}}dedent(t=2){if(this.#t){const s=this.#s(this.#t);this.#n(this.#t,s.slice(0,-t))}else{const s=this.#s("stderr"),n=this.#s("stdout");this.#n("stderr",s.slice(0,-t)),this.#n("stdout",n.slice(0,-t))}return this}dir(t,s){return r.get(this).dir(t,s),this[i](!1),this[u]()}dirxml(...t){return r.get(this).dirxml(t),this[i](!1),this[u]()}error(...t){return this.#m("error",t)}errorNewline(){return this.#d("stderr")?this:this.error("")}fail(...t){return this.#r("fail",t)}group(...t){const{length:s}=t;return s&&y(this.log,this,t),this.indent(this[k]),s&&(this[i](!1),this[u]()),this}groupCollapsed(...t){return y(this.group,this,t)}groupEnd(){return this.dedent(this[k]),this}indent(t=2){const s=" ".repeat(Math.min(t,K));if(this.#t){const n=this.#s(this.#t);this.#n(this.#t,n+s)}else{const n=this.#s("stderr"),e=this.#s("stdout");this.#n("stderr",n+s),this.#n("stdout",e+s)}return this}info(...t){return this.#r("info",t)}log(...t){return this.#m("log",t)}logNewline(){return this.#d("stdout")?this:this.log("")}resetIndent(){return this.#t?this.#n(this.#t,""):(this.#n("stderr",""),this.#n("stdout","")),this}step(t,...s){this.#d("stdout")||this.log("");const n=this.#b(t),e=this.#s("stdout");return r.get(this).log((0,a.applyLinePrefix)(`${f.step} ${n}`,{prefix:e}),...s),this[i](!1,"stdout"),this[u](),this}substep(t,...s){const n=` ${t}`;return this.log(n,...s)}success(...t){return this.#r("success",t)}done(...t){return this.#r("success",t)}table(t,s){return r.get(this).table(t,s),this[i](!1),this[u]()}timeEnd(t){return r.get(this).timeEnd(t),this[i](!1),this[u]()}timeLog(t,...s){return r.get(this).timeLog(t,...s),this[i](!1),this[u]()}trace(t,...s){return r.get(this).trace(t,...s),this[i](!1),this[u]()}warn(...t){return this.#r("warn",t)}write(t){const s=r.get(this);return(this.#w||this.#i[0]?.stdout||s._stdout).write(t),this[i](!1),this}progress(t){const s=r.get(this);return(this.#k()==="stderr"?s._stderr:s._stdout).write(`\u2234 ${t}`),this[i](!1),this}clearLine(){const t=r.get(this),n=this.#k()==="stderr"?t._stderr:t._stdout;return n.isTTY?(n.cursorTo(0),n.clearLine(0)):n.write("\r\x1B[K"),this}}Object.defineProperties(h.prototype,Object.fromEntries((()=>{const o=[[k,{...x,value:2}],[Symbol.toStringTag,{__proto__:null,configurable:!0,value:"logger"}]];for(const{0:t,1:s}of Object.entries(d))if(!h.prototype[t]&&typeof s=="function"){const{[t]:n}={[t](...e){const c=r.get(this),l=c[t](...e);return l===void 0||l===c?this:l}};o.push([t,{...x,value:n}])}return o})()));const H=new h;0&&(module.exports={LOG_SYMBOLS,Logger,incLogCallCountSymbol,lastWasBlankSymbol,logger});
|
|
3
3
|
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/logger.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Console logging utilities with line prefix support.\n * Provides enhanced console methods with formatted output capabilities.\n */\n\nimport isUnicodeSupported from './external/@socketregistry/is-unicode-supported'\nimport yoctocolorsCjs from './external/yoctocolors-cjs'\nimport { objectAssign, objectFreeze } from './objects'\nimport { applyLinePrefix, isBlankString } from './strings'\n\n/**\n * Log symbols for terminal output with colored indicators.\n *\n * Each symbol provides visual feedback for different message types, with\n * Unicode and ASCII fallback support.\n *\n * @example\n * ```typescript\n * import { LOG_SYMBOLS } from '@socketsecurity/lib'\n *\n * console.log(`${LOG_SYMBOLS.success} Operation completed`)\n * console.log(`${LOG_SYMBOLS.fail} Operation failed`)\n * console.log(`${LOG_SYMBOLS.warn} Warning message`)\n * console.log(`${LOG_SYMBOLS.info} Information message`)\n * console.log(`${LOG_SYMBOLS.step} Processing step`)\n * ```\n */\ntype LogSymbols = {\n /** Red colored failure symbol (\u2716 or \u00D7 in ASCII) */\n fail: string\n /** Blue colored information symbol (\u2139 or i in ASCII) */\n info: string\n /** Cyan colored step symbol (\u2192 or > in ASCII) */\n step: string\n /** Green colored success symbol (\u2714 or \u221A in ASCII) */\n success: string\n /** Yellow colored warning symbol (\u26A0 or \u203C in ASCII) */\n warn: string\n}\n\n/**\n * Type definition for logger methods that mirror console methods.\n *\n * All methods return the logger instance for method chaining.\n */\ntype LoggerMethods = {\n [K in keyof typeof console]: (typeof console)[K] extends (\n ...args: infer A\n ) => any\n ? (...args: A) => Logger\n : (typeof console)[K]\n}\n\n/**\n * A task that can be executed with automatic start/complete logging.\n *\n * @example\n * ```typescript\n * const task = logger.createTask('Database migration')\n * task.run(() => {\n * // Migration logic here\n * })\n * // Logs: \"Starting task: Database migration\"\n * // Logs: \"Completed task: Database migration\"\n * ```\n */\ninterface Task {\n /**\n * Executes the task function with automatic logging.\n *\n * @template T - The return type of the task function\n * @param f - The function to execute\n * @returns The result of the task function\n */\n run<T>(f: () => T): T\n}\n\nexport type { LogSymbols, LoggerMethods, Task }\n\nconst globalConsole = console\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst ReflectConstruct = Reflect.construct\n\nlet _Console: typeof import('console').Console | undefined\n/**\n * Construct a new Console instance.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction constructConsole(...args: unknown[]) {\n if (_Console === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n const nodeConsole = /*@__PURE__*/ require('node:console')\n _Console = nodeConsole.Console\n }\n return ReflectConstruct(\n _Console! as new (\n ...args: unknown[]\n ) => Console, // eslint-disable-line no-undef\n args,\n )\n}\n\n/**\n * Get the yoctocolors module for terminal colors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getYoctocolors() {\n return yoctocolorsCjs\n}\n\n/**\n * Log symbols for terminal output with colored indicators.\n *\n * Provides colored Unicode symbols (\u2714, \u2716, \u26A0, \u2139, \u2192) with ASCII fallbacks (\u221A, \u00D7, \u203C, i, >)\n * for terminals that don't support Unicode. Symbols are color-coded: green for\n * success, red for failure, yellow for warnings, blue for info, cyan for step.\n *\n * The symbols are lazily initialized on first access and then frozen for immutability.\n *\n * @example\n * ```typescript\n * import { LOG_SYMBOLS } from '@socketsecurity/lib'\n *\n * console.log(`${LOG_SYMBOLS.success} Build completed`) // Green \u2714\n * console.log(`${LOG_SYMBOLS.fail} Build failed`) // Red \u2716\n * console.log(`${LOG_SYMBOLS.warn} Deprecated API used`) // Yellow \u26A0\n * console.log(`${LOG_SYMBOLS.info} Starting process`) // Blue \u2139\n * console.log(`${LOG_SYMBOLS.step} Processing files`) // Cyan \u2192\n * ```\n */\nexport const LOG_SYMBOLS = /*@__PURE__*/ (() => {\n const target: Record<string, string> = {\n __proto__: null,\n } as unknown as Record<string, string>\n // Mutable handler to simulate a frozen target.\n const handler: ProxyHandler<Record<string, string>> = {\n __proto__: null,\n } as unknown as ProxyHandler<Record<string, string>>\n const init = () => {\n const supported = isUnicodeSupported()\n const colors = getYoctocolors()\n objectAssign(target, {\n fail: colors.red(supported ? '\u2716' : '\u00D7'),\n info: colors.blue(supported ? '\u2139' : 'i'),\n step: colors.cyan(supported ? '\u2192' : '>'),\n success: colors.green(supported ? '\u2714' : '\u221A'),\n warn: colors.yellow(supported ? '\u26A0' : '\u203C'),\n })\n objectFreeze(target)\n // The handler of a Proxy is mutable after proxy instantiation.\n // We delete the traps to defer to native behavior.\n for (const trapName in handler) {\n delete handler[trapName as keyof ProxyHandler<Record<string, string>>]\n }\n }\n for (const trapName of Reflect.ownKeys(Reflect)) {\n const fn = (Reflect as Record<PropertyKey, unknown>)[trapName]\n if (typeof fn === 'function') {\n ;(handler as Record<string, (...args: unknown[]) => unknown>)[\n trapName as string\n ] = (...args: unknown[]) => {\n init()\n return fn(...args)\n }\n }\n }\n return new Proxy(target, handler)\n})()\n\nconst boundConsoleEntries = [\n // Add bound properties from console[kBindProperties](ignoreErrors, colorMode, groupIndentation).\n // https://github.com/nodejs/node/blob/v24.0.1/lib/internal/console/constructor.js#L230-L265\n '_stderrErrorHandler',\n '_stdoutErrorHandler',\n // Add methods that need to be bound to function properly.\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'createTask',\n 'debug',\n 'dir',\n 'dirxml',\n 'error',\n // Skip group methods because in at least Node 20 with the Node --frozen-intrinsics\n // flag it triggers a readonly property for Symbol(kGroupIndent). Instead, we\n // implement these methods ourselves.\n //'group',\n //'groupCollapsed',\n //'groupEnd',\n 'info',\n 'log',\n 'table',\n 'time',\n 'timeEnd',\n 'timeLog',\n 'trace',\n 'warn',\n]\n .filter(n => typeof (globalConsole as any)[n] === 'function')\n .map(n => [n, (globalConsole as any)[n].bind(globalConsole)])\n\nconst consolePropAttributes = {\n __proto__: null,\n writable: true,\n enumerable: false,\n configurable: true,\n}\nconst maxIndentation = 1000\nconst privateConsole = new WeakMap()\n\nconst consoleSymbols = Object.getOwnPropertySymbols(globalConsole)\n\n/**\n * Symbol for incrementing the internal log call counter.\n *\n * This is an internal symbol used to track the number of times logging\n * methods have been called on a logger instance.\n */\nexport const incLogCallCountSymbol = Symbol.for('logger.logCallCount++')\n\nconst kGroupIndentationWidthSymbol =\n consoleSymbols.find(s => (s as any).label === 'kGroupIndentWidth') ??\n Symbol('kGroupIndentWidth')\n\n/**\n * Symbol for tracking whether the last logged line was blank.\n *\n * This is used internally to prevent multiple consecutive blank lines\n * and to determine whether to add spacing before certain messages.\n */\nexport const lastWasBlankSymbol = Symbol.for('logger.lastWasBlank')\n\n/**\n * Enhanced console logger with indentation, colored symbols, and stream management.\n *\n * Provides a fluent API for logging with automatic indentation tracking, colored\n * status symbols, separate stderr/stdout management, and method chaining. All\n * methods return `this` for easy chaining.\n *\n * Features:\n * - Automatic line prefixing with indentation\n * - Colored status symbols (success, fail, warn, info)\n * - Separate indentation tracking for stderr and stdout\n * - Stream-bound logger instances via `.stderr` and `.stdout`\n * - Group/indentation management\n * - Progress indicators with clearable lines\n * - Task execution with automatic logging\n *\n * @example\n * ```typescript\n * import { logger } from '@socketsecurity/lib'\n *\n * // Basic logging with symbols\n * logger.success('Build completed')\n * logger.fail('Build failed')\n * logger.warn('Deprecated API')\n * logger.info('Starting process')\n *\n * // Indentation and grouping\n * logger.log('Processing files:')\n * logger.indent()\n * logger.log('file1.js')\n * logger.log('file2.js')\n * logger.dedent()\n *\n * // Method chaining\n * logger\n * .log('Step 1')\n * .indent()\n * .log('Substep 1.1')\n * .log('Substep 1.2')\n * .dedent()\n * .log('Step 2')\n *\n * // Stream-specific logging\n * logger.stdout.log('Normal output')\n * logger.stderr.error('Error message')\n *\n * // Progress indicators\n * logger.progress('Processing...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Done')\n *\n * // Task execution\n * const task = logger.createTask('Migration')\n * task.run(() => {\n * // Migration logic\n * })\n * ```\n */\n/*@__PURE__*/\nexport class Logger {\n /**\n * Static reference to log symbols for convenience.\n *\n * @example\n * ```typescript\n * console.log(`${Logger.LOG_SYMBOLS.success} Done`)\n * ```\n */\n static LOG_SYMBOLS = LOG_SYMBOLS\n\n #parent?: Logger\n #boundStream?: 'stderr' | 'stdout'\n #stderrLogger?: Logger\n #stdoutLogger?: Logger\n #stderrIndention = ''\n #stdoutIndention = ''\n #stderrLastWasBlank = false\n #stdoutLastWasBlank = false\n #logCallCount = 0\n #constructorArgs: unknown[]\n #options: Record<string, unknown>\n\n /**\n * Creates a new Logger instance.\n *\n * When called without arguments, creates a logger using the default\n * `process.stdout` and `process.stderr` streams. Can accept custom\n * console constructor arguments for advanced use cases.\n *\n * @param args - Optional console constructor arguments\n *\n * @example\n * ```typescript\n * // Default logger\n * const logger = new Logger()\n *\n * // Custom streams (advanced)\n * const customLogger = new Logger({\n * stdout: customWritableStream,\n * stderr: customErrorStream\n * })\n * ```\n */\n constructor(...args: unknown[]) {\n // Store constructor args for child loggers\n this.#constructorArgs = args\n\n // Store options if provided (for future extensibility)\n const options = args['0']\n if (typeof options === 'object' && options !== null) {\n this.#options = { __proto__: null, ...options }\n } else {\n this.#options = { __proto__: null }\n }\n\n if (args.length) {\n privateConsole.set(this, constructConsole(...args))\n } else {\n // Create a new console that acts like the builtin one so that it will\n // work with Node's --frozen-intrinsics flag.\n const con = constructConsole({\n stdout: process.stdout,\n stderr: process.stderr,\n }) as typeof console & Record<string, unknown>\n for (const { 0: key, 1: method } of boundConsoleEntries) {\n con[key] = method\n }\n privateConsole.set(this, con)\n }\n }\n\n /**\n * Gets a logger instance bound exclusively to stderr.\n *\n * All logging operations on this instance will write to stderr only.\n * Indentation is tracked separately from stdout. The instance is\n * cached and reused on subsequent accesses.\n *\n * @returns A logger instance bound to stderr\n *\n * @example\n * ```typescript\n * // Write errors to stderr\n * logger.stderr.error('Configuration invalid')\n * logger.stderr.warn('Using fallback settings')\n *\n * // Indent only affects stderr\n * logger.stderr.indent()\n * logger.stderr.error('Nested error details')\n * logger.stderr.dedent()\n * ```\n */\n get stderr(): Logger {\n if (!this.#stderrLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stderr'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stderrLogger = instance\n }\n return this.#stderrLogger\n }\n\n /**\n * Gets a logger instance bound exclusively to stdout.\n *\n * All logging operations on this instance will write to stdout only.\n * Indentation is tracked separately from stderr. The instance is\n * cached and reused on subsequent accesses.\n *\n * @returns A logger instance bound to stdout\n *\n * @example\n * ```typescript\n * // Write normal output to stdout\n * logger.stdout.log('Processing started')\n * logger.stdout.log('Items processed: 42')\n *\n * // Indent only affects stdout\n * logger.stdout.indent()\n * logger.stdout.log('Detailed output')\n * logger.stdout.dedent()\n * ```\n */\n get stdout(): Logger {\n if (!this.#stdoutLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stdout'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stdoutLogger = instance\n }\n return this.#stdoutLogger\n }\n\n /**\n * Get the root logger (for accessing shared indentation state).\n * @private\n */\n #getRoot(): Logger {\n return this.#parent || this\n }\n\n /**\n * Get indentation for a specific stream.\n * @private\n */\n #getIndent(stream: 'stderr' | 'stdout'): string {\n const root = this.#getRoot()\n return stream === 'stderr' ? root.#stderrIndention : root.#stdoutIndention\n }\n\n /**\n * Set indentation for a specific stream.\n * @private\n */\n #setIndent(stream: 'stderr' | 'stdout', value: string): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrIndention = value\n } else {\n root.#stdoutIndention = value\n }\n }\n\n /**\n * Get lastWasBlank state for a specific stream.\n * @private\n */\n #getLastWasBlank(stream: 'stderr' | 'stdout'): boolean {\n const root = this.#getRoot()\n return stream === 'stderr'\n ? root.#stderrLastWasBlank\n : root.#stdoutLastWasBlank\n }\n\n /**\n * Set lastWasBlank state for a specific stream.\n * @private\n */\n #setLastWasBlank(stream: 'stderr' | 'stdout', value: boolean): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrLastWasBlank = value\n } else {\n root.#stdoutLastWasBlank = value\n }\n }\n\n /**\n * Get the target stream for this logger instance.\n * @private\n */\n #getTargetStream(): 'stderr' | 'stdout' {\n return this.#boundStream || 'stderr'\n }\n\n /**\n * Apply a console method with indentation.\n * @private\n */\n #apply(\n methodName: string,\n args: unknown[],\n stream?: 'stderr' | 'stdout',\n ): this {\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n const text = args.at(0)\n const hasText = typeof text === 'string'\n // Determine which stream this method writes to\n const targetStream = stream || (methodName === 'log' ? 'stdout' : 'stderr')\n const indent = this.#getIndent(targetStream)\n const logArgs = hasText\n ? [applyLinePrefix(text, { prefix: indent }), ...args.slice(1)]\n : args\n ReflectApply(\n con[methodName] as (...args: unknown[]) => unknown,\n con,\n logArgs,\n )\n this[lastWasBlankSymbol](hasText && isBlankString(logArgs[0]), targetStream)\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Strip log symbols from the start of text.\n * @private\n */\n #stripSymbols(text: string): string {\n // Strip both unicode and emoji forms of log symbols from the start.\n // Matches: \u2716, \u2717, \u00D7, \u2716\uFE0F, \u26A0, \u203C, \u26A0\uFE0F, \u2714, \u2713, \u221A, \u2714\uFE0F, \u2713\uFE0F, \u2139, \u2139\uFE0F, \u2192, >\n // Also handles variation selectors (U+FE0F) and whitespace after symbol.\n // Note: We don't strip standalone 'i' or '>' to avoid breaking words.\n return text.replace(/^[\u2716\u2717\u00D7\u26A0\u203C\u2714\u2713\u221A\u2139\u2192]\\uFE0F?\\s*/u, '')\n }\n\n /**\n * Apply a method with a symbol prefix.\n * @private\n */\n #symbolApply(symbolType: string, args: unknown[]): this {\n const con = privateConsole.get(this)\n let text = args.at(0)\n // biome-ignore lint/suspicious/noImplicitAnyLet: Flexible argument handling.\n let extras\n if (typeof text === 'string') {\n text = this.#stripSymbols(text)\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n // Note: Meta status messages (info/fail/etc) always go to stderr.\n const indent = this.#getIndent('stderr')\n con.error(\n applyLinePrefix(`${LOG_SYMBOLS[symbolType]} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this[lastWasBlankSymbol](false, 'stderr')\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Gets the total number of log calls made on this logger instance.\n *\n * Tracks all logging method calls including `log()`, `error()`, `warn()`,\n * `success()`, `fail()`, etc. Useful for testing and monitoring logging activity.\n *\n * @returns The number of times logging methods have been called\n *\n * @example\n * ```typescript\n * logger.log('Message 1')\n * logger.error('Message 2')\n * console.log(logger.logCallCount) // 2\n * ```\n */\n get logCallCount() {\n const root = this.#getRoot()\n return root.#logCallCount\n }\n\n /**\n * Increments the internal log call counter.\n *\n * This is called automatically by logging methods and should not\n * be called directly in normal usage.\n *\n * @returns The logger instance for chaining\n */\n [incLogCallCountSymbol]() {\n const root = this.#getRoot()\n root.#logCallCount += 1\n return this\n }\n\n /**\n * Sets whether the last logged line was blank.\n *\n * Used internally to track blank lines and prevent duplicate spacing.\n * This is called automatically by logging methods.\n *\n * @param value - Whether the last line was blank\n * @param stream - Optional stream to update (defaults to both streams if not bound, or target stream if bound)\n * @returns The logger instance for chaining\n */\n [lastWasBlankSymbol](value: unknown, stream?: 'stderr' | 'stdout'): this {\n if (stream) {\n // Explicit stream specified\n this.#setLastWasBlank(stream, !!value)\n } else if (this.#boundStream) {\n // Stream-bound logger - affect only the bound stream\n this.#setLastWasBlank(this.#boundStream, !!value)\n } else {\n // Root logger with no stream specified - affect both streams\n this.#setLastWasBlank('stderr', !!value)\n this.#setLastWasBlank('stdout', !!value)\n }\n return this\n }\n\n /**\n * Logs an assertion failure message if the value is falsy.\n *\n * Works like `console.assert()` but returns the logger for chaining.\n * If the value is truthy, nothing is logged. If falsy, logs an error\n * message with an assertion failure.\n *\n * @param value - The value to test\n * @param message - Optional message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.assert(true, 'This will not log')\n * logger.assert(false, 'Assertion failed: value is false')\n * logger.assert(items.length > 0, 'No items found')\n * ```\n */\n assert(value: unknown, ...message: unknown[]): this {\n const con = privateConsole.get(this)\n con.assert(value, ...message)\n this[lastWasBlankSymbol](false)\n return value ? this : this[incLogCallCountSymbol]()\n }\n\n /**\n * Clears the visible terminal screen.\n *\n * Only available on the main logger instance, not on stream-bound instances\n * (`.stderr` or `.stdout`). Resets the log call count and blank line tracking\n * if the output is a TTY.\n *\n * @returns The logger instance for chaining\n * @throws {Error} If called on a stream-bound logger instance\n *\n * @example\n * ```typescript\n * logger.log('Some output')\n * logger.clearVisible() // Screen is now clear\n *\n * // Error: Can't call on stream-bound instance\n * logger.stderr.clearVisible() // throws\n * ```\n */\n clearVisible() {\n if (this.#boundStream) {\n throw new Error(\n 'clearVisible() is only available on the main logger instance, not on stream-bound instances',\n )\n }\n const con = privateConsole.get(this)\n con.clear()\n if ((con as any)._stdout.isTTY) {\n ;(this as any)[lastWasBlankSymbol](true)\n this.#logCallCount = 0\n }\n return this\n }\n\n /**\n * Increments and logs a counter for the given label.\n *\n * Each unique label maintains its own counter. Works like `console.count()`.\n *\n * @param label - Optional label for the counter\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.count('requests') // requests: 1\n * logger.count('requests') // requests: 2\n * logger.count('errors') // errors: 1\n * logger.count() // default: 1\n * ```\n */\n count(label?: string | undefined): this {\n const con = privateConsole.get(this)\n con.count(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Creates a task that logs start and completion messages automatically.\n *\n * Returns a task object with a `run()` method that executes the provided\n * function and logs \"Starting task: {name}\" before execution and\n * \"Completed task: {name}\" after completion.\n *\n * @param name - The name of the task\n * @returns A task object with a `run()` method\n *\n * @example\n * ```typescript\n * const task = logger.createTask('Database Migration')\n * const result = task.run(() => {\n * // Logs: \"Starting task: Database Migration\"\n * migrateDatabase()\n * return 'success'\n * // Logs: \"Completed task: Database Migration\"\n * })\n * console.log(result) // 'success'\n * ```\n */\n createTask(name: string): Task {\n return {\n run: <T>(f: () => T): T => {\n this.log(`Starting task: ${name}`)\n const result = f()\n this.log(`Completed task: ${name}`)\n return result\n },\n }\n }\n\n /**\n * Decreases the indentation level by removing spaces from the prefix.\n *\n * When called on the main logger, affects both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), affects\n * only that stream's indentation.\n *\n * @param spaces - Number of spaces to remove from indentation\n * @default 2\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.indent()\n * logger.log('Indented')\n * logger.dedent()\n * logger.log('Back to normal')\n *\n * // Remove custom amount\n * logger.indent(4)\n * logger.log('Four spaces')\n * logger.dedent(4)\n *\n * // Stream-specific dedent\n * logger.stdout.indent()\n * logger.stdout.log('Indented stdout')\n * logger.stdout.dedent()\n * ```\n */\n dedent(spaces = 2) {\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current.slice(0, -spaces))\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent.slice(0, -spaces))\n this.#setIndent('stdout', stdoutCurrent.slice(0, -spaces))\n }\n return this\n }\n\n /**\n * Displays an object's properties in a formatted way.\n *\n * Works like `console.dir()` with customizable options for depth,\n * colors, etc. Useful for inspecting complex objects.\n *\n * @param obj - The object to display\n * @param options - Optional formatting options (Node.js inspect options)\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: { c: 2, d: { e: 3 } } }\n * logger.dir(obj)\n * logger.dir(obj, { depth: 1 }) // Limit nesting depth\n * logger.dir(obj, { colors: true }) // Enable colors\n * ```\n */\n dir(obj: unknown, options?: unknown | undefined): this {\n const con = privateConsole.get(this)\n con.dir(obj, options)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Displays data as XML/HTML in a formatted way.\n *\n * Works like `console.dirxml()`. In Node.js, behaves the same as `dir()`.\n *\n * @param data - The data to display\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.dirxml(document.body) // In browser environments\n * logger.dirxml(xmlObject) // In Node.js\n * ```\n */\n dirxml(...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.dirxml(data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs an error message to stderr.\n *\n * Automatically applies current indentation. All arguments are formatted\n * and logged like `console.error()`.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.error('Build failed')\n * logger.error('Error code:', 500)\n * logger.error('Details:', { message: 'Not found' })\n * ```\n */\n error(...args: unknown[]): this {\n return this.#apply('error', args)\n }\n\n /**\n * Logs a newline to stderr only if the last line wasn't already blank.\n *\n * Prevents multiple consecutive blank lines. Useful for adding spacing\n * between sections without creating excessive whitespace.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.error('Error message')\n * logger.errorNewline() // Adds blank line\n * logger.errorNewline() // Does nothing (already blank)\n * logger.error('Next section')\n * ```\n */\n errorNewline() {\n return this.#getLastWasBlank('stderr') ? this : this.error('')\n }\n\n /**\n * Logs a failure message with a red colored fail symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.fail` (red \u2716).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.fail('Build failed')\n * logger.fail('Test suite failed:', { passed: 5, failed: 3 })\n * ```\n */\n fail(...args: unknown[]): this {\n return this.#symbolApply('fail', args)\n }\n\n /**\n * Starts a new indented log group.\n *\n * If a label is provided, it's logged before increasing indentation.\n * Groups can be nested. Each group increases indentation by the\n * `kGroupIndentWidth` (default 2 spaces). Call `groupEnd()` to close.\n *\n * @param label - Optional label to display before the group\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.group('Processing files:')\n * logger.log('file1.js')\n * logger.log('file2.js')\n * logger.groupEnd()\n *\n * // Nested groups\n * logger.group('Outer')\n * logger.log('Outer content')\n * logger.group('Inner')\n * logger.log('Inner content')\n * logger.groupEnd()\n * logger.groupEnd()\n * ```\n */\n group(...label: unknown[]): this {\n const { length } = label\n if (length) {\n ReflectApply(this.log, this, label)\n }\n this.indent((this as any)[kGroupIndentationWidthSymbol])\n if (length) {\n ;(this as any)[lastWasBlankSymbol](false)\n ;(this as any)[incLogCallCountSymbol]()\n }\n return this\n }\n\n /**\n * Starts a new collapsed log group (alias for `group()`).\n *\n * In browser consoles, this creates a collapsed group. In Node.js,\n * it behaves identically to `group()`.\n *\n * @param label - Optional label to display before the group\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.groupCollapsed('Details')\n * logger.log('Hidden by default in browsers')\n * logger.groupEnd()\n * ```\n */\n // groupCollapsed is an alias of group.\n // https://nodejs.org/api/console.html#consolegroupcollapsed\n groupCollapsed(...label: unknown[]): this {\n return ReflectApply(this.group, this, label)\n }\n\n /**\n * Ends the current log group and decreases indentation.\n *\n * Must be called once for each `group()` or `groupCollapsed()` call\n * to properly close the group and restore indentation.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.group('Group 1')\n * logger.log('Content')\n * logger.groupEnd() // Closes 'Group 1'\n * ```\n */\n groupEnd() {\n this.dedent((this as any)[kGroupIndentationWidthSymbol])\n return this\n }\n\n /**\n * Increases the indentation level by adding spaces to the prefix.\n *\n * When called on the main logger, affects both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), affects\n * only that stream's indentation. Maximum indentation is 1000 spaces.\n *\n * @param spaces - Number of spaces to add to indentation\n * @default 2\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Level 0')\n * logger.indent()\n * logger.log('Level 1')\n * logger.indent()\n * logger.log('Level 2')\n * logger.dedent()\n * logger.dedent()\n *\n * // Custom indent amount\n * logger.indent(4)\n * logger.log('Indented 4 spaces')\n * logger.dedent(4)\n *\n * // Stream-specific indent\n * logger.stdout.indent()\n * logger.stdout.log('Only stdout is indented')\n * ```\n */\n indent(spaces = 2) {\n const spacesToAdd = ' '.repeat(Math.min(spaces, maxIndentation))\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current + spacesToAdd)\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent + spacesToAdd)\n this.#setIndent('stdout', stdoutCurrent + spacesToAdd)\n }\n return this\n }\n\n /**\n * Logs an informational message with a blue colored info symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.info` (blue \u2139).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.info('Starting build process')\n * logger.info('Configuration loaded:', config)\n * logger.info('Using cache directory:', cacheDir)\n * ```\n */\n info(...args: unknown[]): this {\n return this.#symbolApply('info', args)\n }\n\n /**\n * Logs a message to stdout.\n *\n * Automatically applies current indentation. All arguments are formatted\n * and logged like `console.log()`. This is the primary method for\n * standard output.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Processing complete')\n * logger.log('Items processed:', 42)\n * logger.log('Results:', { success: true, count: 10 })\n *\n * // Method chaining\n * logger.log('Step 1').log('Step 2').log('Step 3')\n * ```\n */\n log(...args: unknown[]): this {\n return this.#apply('log', args)\n }\n\n /**\n * Logs a newline to stdout only if the last line wasn't already blank.\n *\n * Prevents multiple consecutive blank lines. Useful for adding spacing\n * between sections without creating excessive whitespace.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Section 1')\n * logger.logNewline() // Adds blank line\n * logger.logNewline() // Does nothing (already blank)\n * logger.log('Section 2')\n * ```\n */\n logNewline() {\n return this.#getLastWasBlank('stdout') ? this : this.log('')\n }\n\n /**\n * Resets all indentation to zero.\n *\n * When called on the main logger, resets both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), resets\n * only that stream's indentation.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.indent().indent().indent()\n * logger.log('Very indented')\n * logger.resetIndent()\n * logger.log('Back to zero indentation')\n *\n * // Reset only stdout\n * logger.stdout.resetIndent()\n * ```\n */\n resetIndent() {\n if (this.#boundStream) {\n // Only reset bound stream\n this.#setIndent(this.#boundStream, '')\n } else {\n // Reset both streams\n this.#setIndent('stderr', '')\n this.#setIndent('stdout', '')\n }\n return this\n }\n\n /**\n * Logs a main step message with a cyan arrow symbol and blank line before it.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.step` (cyan \u2192) and\n * adds a blank line before the message unless the last line was already blank.\n * Useful for marking major steps in a process with clear visual separation.\n * Always outputs to stdout. If the message starts with an existing symbol,\n * it will be stripped and replaced.\n *\n * @param msg - The step message to log\n * @param extras - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.step('Building project')\n * logger.log('Compiling TypeScript...')\n * logger.step('Running tests')\n * logger.log('Running test suite...')\n * // Output:\n * // [blank line]\n * // \u2192 Building project\n * // Compiling TypeScript...\n * // [blank line]\n * // \u2192 Running tests\n * // Running test suite...\n * ```\n */\n step(msg: string, ...extras: unknown[]): this {\n // Add blank line before the step message.\n if (!this.#getLastWasBlank('stdout')) {\n // Use this.log() to properly track the blank line.\n this.log('')\n }\n // Strip existing symbols from the message.\n const text = this.#stripSymbols(msg)\n // Note: Step messages always go to stdout (unlike info/fail/etc which go to stderr).\n const indent = this.#getIndent('stdout')\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n con.log(\n applyLinePrefix(`${LOG_SYMBOLS.step} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this[lastWasBlankSymbol](false, 'stdout')\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Logs an indented substep message (stateless).\n *\n * Adds a 2-space indent to the message without affecting the logger's\n * indentation state. Useful for showing sub-items under a main step.\n *\n * @param msg - The substep message to log\n * @param extras - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Installing dependencies:')\n * logger.substep('Installing react')\n * logger.substep('Installing typescript')\n * logger.substep('Installing eslint')\n * // Output:\n * // Installing dependencies:\n * // Installing react\n * // Installing typescript\n * // Installing eslint\n * ```\n */\n substep(msg: string, ...extras: unknown[]): this {\n // Add 2-space indent to the message.\n const indentedMsg = ` ${msg}`\n // Let log() handle all tracking.\n return this.log(indentedMsg, ...extras)\n }\n\n /**\n * Logs a success message with a green colored success symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.success` (green \u2714).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.success('Build completed')\n * logger.success('Tests passed:', { total: 42, passed: 42 })\n * logger.success('Deployment successful')\n * ```\n */\n success(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Logs a completion message with a success symbol (alias for `success()`).\n *\n * Provides semantic clarity when marking something as \"done\". Does NOT\n * automatically clear the current line - call `clearLine()` first if\n * needed after using `progress()`.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.done('Task completed')\n *\n * // After progress indicator\n * logger.progress('Processing...')\n * // ... do work ...\n * logger.clearLine()\n * logger.done('Processing complete')\n * ```\n */\n done(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Displays data in a table format.\n *\n * Works like `console.table()`. Accepts arrays of objects or\n * objects with nested objects. Optionally specify which properties\n * to include in the table.\n *\n * @param tabularData - The data to display as a table\n * @param properties - Optional array of property names to include\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * // Array of objects\n * logger.table([\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 }\n * ])\n *\n * // Specify properties to show\n * logger.table(users, ['name', 'email'])\n *\n * // Object with nested objects\n * logger.table({\n * user1: { name: 'Alice', age: 30 },\n * user2: { name: 'Bob', age: 25 }\n * })\n * ```\n */\n table(\n tabularData: unknown,\n properties?: readonly string[] | undefined,\n ): this {\n const con = privateConsole.get(this)\n con.table(tabularData, properties)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Ends a timer and logs the elapsed time.\n *\n * Logs the duration since `console.time()` was called with the same\n * label. The timer is stopped and removed.\n *\n * @param label - Optional label for the timer\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * console.time('operation')\n * // ... do work ...\n * logger.timeEnd('operation')\n * // Logs: \"operation: 123.456ms\"\n *\n * console.time()\n * // ... do work ...\n * logger.timeEnd()\n * // Logs: \"default: 123.456ms\"\n * ```\n */\n timeEnd(label?: string | undefined): this {\n const con = privateConsole.get(this)\n con.timeEnd(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs the current value of a timer without stopping it.\n *\n * Logs the duration since `console.time()` was called with the same\n * label, but keeps the timer running. Can include additional data\n * to log alongside the time.\n *\n * @param label - Optional label for the timer\n * @param data - Additional data to log with the time\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * console.time('process')\n * // ... partial work ...\n * logger.timeLog('process', 'Checkpoint 1')\n * // Logs: \"process: 123.456ms Checkpoint 1\"\n * // ... more work ...\n * logger.timeLog('process', 'Checkpoint 2')\n * // Logs: \"process: 234.567ms Checkpoint 2\"\n * console.timeEnd('process')\n * ```\n */\n timeLog(label?: string | undefined, ...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.timeLog(label, ...data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs a stack trace to the console.\n *\n * Works like `console.trace()`. Shows the call stack leading to\n * where this method was called. Useful for debugging.\n *\n * @param message - Optional message to display with the trace\n * @param args - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * function debugFunction() {\n * logger.trace('Debug point reached')\n * }\n *\n * logger.trace('Trace from here')\n * logger.trace('Error context:', { userId: 123 })\n * ```\n */\n trace(message?: unknown | undefined, ...args: unknown[]): this {\n const con = privateConsole.get(this)\n con.trace(message, ...args)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs a warning message with a yellow colored warning symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.warn` (yellow \u26A0).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.warn('Deprecated API used')\n * logger.warn('Low memory:', { available: '100MB' })\n * logger.warn('Missing optional configuration')\n * ```\n */\n warn(...args: unknown[]): this {\n return this.#symbolApply('warn', args)\n }\n\n /**\n * Writes text directly to stdout without a newline or indentation.\n *\n * Useful for progress indicators or custom formatting where you need\n * low-level control. Does not apply any indentation or formatting.\n *\n * @param text - The text to write\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.write('Processing... ')\n * // ... do work ...\n * logger.write('done\\n')\n *\n * // Build a line incrementally\n * logger.write('Step 1')\n * logger.write('... Step 2')\n * logger.write('... Step 3\\n')\n * ```\n */\n write(text: string): this {\n const con = privateConsole.get(this)\n con._stdout.write(text)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Shows a progress indicator that can be cleared with `clearLine()`.\n *\n * Displays a simple status message with a '\u2234' prefix. Does not include\n * animation or spinner. Intended to be cleared once the operation completes.\n * The output stream (stderr or stdout) depends on whether the logger is\n * stream-bound.\n *\n * @param text - The progress message to display\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.progress('Processing files...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Files processed')\n *\n * // Stream-specific progress\n * logger.stdout.progress('Loading...')\n * // ... do work ...\n * logger.stdout.clearLine()\n * logger.stdout.log('Done')\n * ```\n */\n progress(text: string): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n streamObj.write(`\u2234 ${text}`)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Clears the current line in the terminal.\n *\n * Moves the cursor to the beginning of the line and clears all content.\n * Works in both TTY and non-TTY environments. Useful for clearing\n * progress indicators created with `progress()`.\n *\n * The stream to clear (stderr or stdout) depends on whether the logger\n * is stream-bound.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.progress('Loading...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Loaded')\n *\n * // Clear multiple progress updates\n * for (const file of files) {\n * logger.progress(`Processing ${file}`)\n * processFile(file)\n * logger.clearLine()\n * }\n * logger.success('All files processed')\n * ```\n */\n clearLine(): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n if (streamObj.isTTY) {\n streamObj.cursorTo(0)\n streamObj.clearLine(0)\n } else {\n streamObj.write('\\r\\x1b[K')\n }\n return this\n }\n}\n\nObject.defineProperties(\n Logger.prototype,\n Object.fromEntries(\n (() => {\n const entries: Array<[string | symbol, PropertyDescriptor]> = [\n [\n kGroupIndentationWidthSymbol,\n {\n ...consolePropAttributes,\n value: 2,\n },\n ],\n [\n Symbol.toStringTag,\n {\n __proto__: null,\n configurable: true,\n value: 'logger',\n } as PropertyDescriptor,\n ],\n ]\n for (const { 0: key, 1: value } of Object.entries(globalConsole)) {\n if (!(Logger.prototype as any)[key] && typeof value === 'function') {\n // Dynamically name the log method without using Object.defineProperty.\n const { [key]: func } = {\n [key](...args: unknown[]) {\n const con = privateConsole.get(this)\n const result = (con as any)[key](...args)\n return result === undefined || result === con ? this : result\n },\n }\n entries.push([\n key,\n {\n ...consolePropAttributes,\n value: func,\n },\n ])\n }\n }\n return entries\n })(),\n ),\n)\n\n/**\n * Default logger instance for the application.\n *\n * A pre-configured `Logger` instance that uses the standard `process.stdout`\n * and `process.stderr` streams. This is the recommended logger to import\n * and use throughout your application.\n *\n * @example\n * ```typescript\n * import { logger } from '@socketsecurity/lib'\n *\n * logger.log('Application started')\n * logger.success('Configuration loaded')\n * logger.indent()\n * logger.log('Using port 3000')\n * logger.dedent()\n * ```\n */\nexport const logger = new Logger()\n"],
|
|
5
|
-
"mappings": ";6iBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,WAAAC,EAAA,0BAAAC,EAAA,uBAAAC,EAAA,WAAAC,IAAA,eAAAC,EAAAP,GAKA,IAAAQ,EAA+B,8DAC/BC,EAA2B,yCAC3BC,EAA2C,qBAC3CC,EAA+C,qBAuE/C,MAAMC,EAAgB,QAKhBC,EAAe,QAAQ,MACvBC,EAAmB,QAAQ,UAEjC,IAAIC,EAMJ,SAASC,KAAoBC,EAAiB,CAC5C,OAAIF,IAAa,SAIfA,EADkC,QAAQ,cAAc,EACjC,SAElBD,EACLC,EAGAE,CACF,CACF,CAOA,SAASC,GAAiB,CACxB,OAAO,EAAAC,OACT,CAsBO,MAAMjB,GAA6B,IAAM,CAC9C,MAAMkB,EAAiC,CACrC,UAAW,IACb,EAEMC,EAAgD,CACpD,UAAW,IACb,EACMC,EAAO,IAAM,CACjB,MAAMC,KAAY,EAAAC,SAAmB,EAC/BC,EAASP,EAAe,KAC9B,gBAAaE,EAAQ,CACnB,KAAMK,EAAO,IAAIF,EAAY,SAAM,MAAG,EACtC,KAAME,EAAO,KAAKF,EAAY,SAAM,GAAG,EACvC,KAAME,EAAO,KAAKF,EAAY,SAAM,GAAG,EACvC,QAASE,EAAO,MAAMF,EAAY,SAAM,QAAG,EAC3C,KAAME,EAAO,OAAOF,EAAY,SAAM,QAAG,CAC3C,CAAC,KACD,gBAAaH,CAAM,EAGnB,UAAWM,KAAYL,EACrB,OAAOA,EAAQK,CAAsD,CAEzE,EACA,UAAWA,KAAY,QAAQ,QAAQ,OAAO,EAAG,CAC/C,MAAMC,EAAM,QAAyCD,CAAQ,EACzD,OAAOC,GAAO,aACdN,EACAK,CACF,EAAI,IAAIT,KACNK,EAAK,EACEK,EAAG,GAAGV,CAAI,GAGvB,CACA,OAAO,IAAI,MAAMG,EAAQC,CAAO,CAClC,GAAG,EAEGO,EAAsB,CAG1B,sBACA,sBAEA,SACA,QACA,QACA,aACA,aACA,QACA,MACA,SACA,QAOA,OACA,MACA,QACA,OACA,UACA,UACA,QACA,MACF,EACG,OAAOC,GAAK,OAAQjB,EAAsBiB,CAAC,GAAM,UAAU,EAC3D,IAAIA,GAAK,CAACA,EAAIjB,EAAsBiB,CAAC,EAAE,KAAKjB,CAAa,CAAC,CAAC,EAExDkB,EAAwB,CAC5B,UAAW,KACX,SAAU,GACV,WAAY,GACZ,aAAc,EAChB,EACMC,EAAiB,IACjBC,EAAiB,IAAI,QAErBC,EAAiB,OAAO,sBAAsBrB,CAAa,EAQpDR,EAAwB,OAAO,IAAI,uBAAuB,EAEjE8B,EACJD,EAAe,KAAKE,GAAMA,EAAU,QAAU,mBAAmB,GACjE,OAAO,mBAAmB,EAQf9B,EAAqB,OAAO,IAAI,qBAAqB,EA8D3D,MAAMF,CAAO,CASlB,OAAO,YAAcD,EAErBkC,GACAC,GACAC,GACAC,GACAC,GAAmB,GACnBC,GAAmB,GACnBC,GAAsB,GACtBC,GAAsB,GACtBC,GAAgB,EAChBC,GACAC,GAuBA,
|
|
6
|
-
"names": ["logger_exports", "__export", "LOG_SYMBOLS", "Logger", "incLogCallCountSymbol", "lastWasBlankSymbol", "logger", "__toCommonJS", "import_is_unicode_supported", "import_yoctocolors_cjs", "import_objects", "import_strings", "globalConsole", "ReflectApply", "ReflectConstruct", "_Console", "constructConsole", "args", "getYoctocolors", "yoctocolorsCjs", "target", "handler", "init", "supported", "isUnicodeSupported", "colors", "trapName", "fn", "boundConsoleEntries", "n", "consolePropAttributes", "maxIndentation", "privateConsole", "consoleSymbols", "kGroupIndentationWidthSymbol", "s", "#parent", "#boundStream", "#stderrLogger", "#stdoutLogger", "#stderrIndention", "#stdoutIndention", "#stderrLastWasBlank", "#stdoutLastWasBlank", "#logCallCount", "#constructorArgs", "#options", "options", "con", "key", "method", "instance", "#getRoot", "#getIndent", "stream", "root", "#setIndent", "value", "#getLastWasBlank", "#setLastWasBlank", "#getTargetStream", "#apply", "methodName", "text", "hasText", "targetStream", "indent", "logArgs", "#stripSymbols", "#symbolApply", "symbolType", "extras", "message", "label", "name", "f", "result", "spaces", "current", "stderrCurrent", "stdoutCurrent", "obj", "data", "length", "spacesToAdd", "msg", "indentedMsg", "tabularData", "properties", "streamObj", "entries", "func"]
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Console logging utilities with line prefix support.\n * Provides enhanced console methods with formatted output capabilities.\n */\n\nimport isUnicodeSupported from './external/@socketregistry/is-unicode-supported'\nimport yoctocolorsCjs from './external/yoctocolors-cjs'\nimport { objectAssign, objectFreeze } from './objects'\nimport { applyLinePrefix, isBlankString } from './strings'\n\n/**\n * Log symbols for terminal output with colored indicators.\n *\n * Each symbol provides visual feedback for different message types, with\n * Unicode and ASCII fallback support.\n *\n * @example\n * ```typescript\n * import { LOG_SYMBOLS } from '@socketsecurity/lib'\n *\n * console.log(`${LOG_SYMBOLS.success} Operation completed`)\n * console.log(`${LOG_SYMBOLS.fail} Operation failed`)\n * console.log(`${LOG_SYMBOLS.warn} Warning message`)\n * console.log(`${LOG_SYMBOLS.info} Information message`)\n * console.log(`${LOG_SYMBOLS.step} Processing step`)\n * ```\n */\ntype LogSymbols = {\n /** Red colored failure symbol (\u2716 or \u00D7 in ASCII) */\n fail: string\n /** Blue colored information symbol (\u2139 or i in ASCII) */\n info: string\n /** Cyan colored step symbol (\u2192 or > in ASCII) */\n step: string\n /** Green colored success symbol (\u2714 or \u221A in ASCII) */\n success: string\n /** Yellow colored warning symbol (\u26A0 or \u203C in ASCII) */\n warn: string\n}\n\n/**\n * Type definition for logger methods that mirror console methods.\n *\n * All methods return the logger instance for method chaining.\n */\ntype LoggerMethods = {\n [K in keyof typeof console]: (typeof console)[K] extends (\n ...args: infer A\n ) => any\n ? (...args: A) => Logger\n : (typeof console)[K]\n}\n\n/**\n * A task that can be executed with automatic start/complete logging.\n *\n * @example\n * ```typescript\n * const task = logger.createTask('Database migration')\n * task.run(() => {\n * // Migration logic here\n * })\n * // Logs: \"Starting task: Database migration\"\n * // Logs: \"Completed task: Database migration\"\n * ```\n */\ninterface Task {\n /**\n * Executes the task function with automatic logging.\n *\n * @template T - The return type of the task function\n * @param f - The function to execute\n * @returns The result of the task function\n */\n run<T>(f: () => T): T\n}\n\nexport type { LogSymbols, LoggerMethods, Task }\n\nconst globalConsole = console\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\nconst ReflectApply = Reflect.apply\nconst ReflectConstruct = Reflect.construct\n\nlet _Console: typeof import('console').Console | undefined\n/**\n * Construct a new Console instance.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction constructConsole(...args: unknown[]) {\n if (_Console === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n const nodeConsole = /*@__PURE__*/ require('node:console')\n _Console = nodeConsole.Console\n }\n return ReflectConstruct(\n _Console! as new (\n ...args: unknown[]\n ) => Console, // eslint-disable-line no-undef\n args,\n )\n}\n\n/**\n * Get the yoctocolors module for terminal colors.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getYoctocolors() {\n return yoctocolorsCjs\n}\n\n/**\n * Log symbols for terminal output with colored indicators.\n *\n * Provides colored Unicode symbols (\u2714, \u2716, \u26A0, \u2139, \u2192) with ASCII fallbacks (\u221A, \u00D7, \u203C, i, >)\n * for terminals that don't support Unicode. Symbols are color-coded: green for\n * success, red for failure, yellow for warnings, blue for info, cyan for step.\n *\n * The symbols are lazily initialized on first access and then frozen for immutability.\n *\n * @example\n * ```typescript\n * import { LOG_SYMBOLS } from '@socketsecurity/lib'\n *\n * console.log(`${LOG_SYMBOLS.success} Build completed`) // Green \u2714\n * console.log(`${LOG_SYMBOLS.fail} Build failed`) // Red \u2716\n * console.log(`${LOG_SYMBOLS.warn} Deprecated API used`) // Yellow \u26A0\n * console.log(`${LOG_SYMBOLS.info} Starting process`) // Blue \u2139\n * console.log(`${LOG_SYMBOLS.step} Processing files`) // Cyan \u2192\n * ```\n */\nexport const LOG_SYMBOLS = /*@__PURE__*/ (() => {\n const target: Record<string, string> = {\n __proto__: null,\n } as unknown as Record<string, string>\n // Mutable handler to simulate a frozen target.\n const handler: ProxyHandler<Record<string, string>> = {\n __proto__: null,\n } as unknown as ProxyHandler<Record<string, string>>\n const init = () => {\n const supported = isUnicodeSupported()\n const colors = getYoctocolors()\n objectAssign(target, {\n fail: colors.red(supported ? '\u2716' : '\u00D7'),\n info: colors.blue(supported ? '\u2139' : 'i'),\n step: colors.cyan(supported ? '\u2192' : '>'),\n success: colors.green(supported ? '\u2714' : '\u221A'),\n warn: colors.yellow(supported ? '\u26A0' : '\u203C'),\n })\n objectFreeze(target)\n // The handler of a Proxy is mutable after proxy instantiation.\n // We delete the traps to defer to native behavior.\n for (const trapName in handler) {\n delete handler[trapName as keyof ProxyHandler<Record<string, string>>]\n }\n }\n for (const trapName of Reflect.ownKeys(Reflect)) {\n const fn = (Reflect as Record<PropertyKey, unknown>)[trapName]\n if (typeof fn === 'function') {\n ;(handler as Record<string, (...args: unknown[]) => unknown>)[\n trapName as string\n ] = (...args: unknown[]) => {\n init()\n return fn(...args)\n }\n }\n }\n return new Proxy(target, handler)\n})()\n\nconst boundConsoleEntries = [\n // Add bound properties from console[kBindProperties](ignoreErrors, colorMode, groupIndentation).\n // https://github.com/nodejs/node/blob/v24.0.1/lib/internal/console/constructor.js#L230-L265\n '_stderrErrorHandler',\n '_stdoutErrorHandler',\n // Add methods that need to be bound to function properly.\n 'assert',\n 'clear',\n 'count',\n 'countReset',\n 'createTask',\n 'debug',\n 'dir',\n 'dirxml',\n 'error',\n // Skip group methods because in at least Node 20 with the Node --frozen-intrinsics\n // flag it triggers a readonly property for Symbol(kGroupIndent). Instead, we\n // implement these methods ourselves.\n //'group',\n //'groupCollapsed',\n //'groupEnd',\n 'info',\n 'log',\n 'table',\n 'time',\n 'timeEnd',\n 'timeLog',\n 'trace',\n 'warn',\n]\n .filter(n => typeof (globalConsole as any)[n] === 'function')\n .map(n => [n, (globalConsole as any)[n].bind(globalConsole)])\n\nconst consolePropAttributes = {\n __proto__: null,\n writable: true,\n enumerable: false,\n configurable: true,\n}\nconst maxIndentation = 1000\nconst privateConsole = new WeakMap()\n\nconst consoleSymbols = Object.getOwnPropertySymbols(globalConsole)\n\n/**\n * Symbol for incrementing the internal log call counter.\n *\n * This is an internal symbol used to track the number of times logging\n * methods have been called on a logger instance.\n */\nexport const incLogCallCountSymbol = Symbol.for('logger.logCallCount++')\n\nconst kGroupIndentationWidthSymbol =\n consoleSymbols.find(s => (s as any).label === 'kGroupIndentWidth') ??\n Symbol('kGroupIndentWidth')\n\n/**\n * Symbol for tracking whether the last logged line was blank.\n *\n * This is used internally to prevent multiple consecutive blank lines\n * and to determine whether to add spacing before certain messages.\n */\nexport const lastWasBlankSymbol = Symbol.for('logger.lastWasBlank')\n\n/**\n * Enhanced console logger with indentation, colored symbols, and stream management.\n *\n * Provides a fluent API for logging with automatic indentation tracking, colored\n * status symbols, separate stderr/stdout management, and method chaining. All\n * methods return `this` for easy chaining.\n *\n * Features:\n * - Automatic line prefixing with indentation\n * - Colored status symbols (success, fail, warn, info)\n * - Separate indentation tracking for stderr and stdout\n * - Stream-bound logger instances via `.stderr` and `.stdout`\n * - Group/indentation management\n * - Progress indicators with clearable lines\n * - Task execution with automatic logging\n *\n * @example\n * ```typescript\n * import { logger } from '@socketsecurity/lib'\n *\n * // Basic logging with symbols\n * logger.success('Build completed')\n * logger.fail('Build failed')\n * logger.warn('Deprecated API')\n * logger.info('Starting process')\n *\n * // Indentation and grouping\n * logger.log('Processing files:')\n * logger.indent()\n * logger.log('file1.js')\n * logger.log('file2.js')\n * logger.dedent()\n *\n * // Method chaining\n * logger\n * .log('Step 1')\n * .indent()\n * .log('Substep 1.1')\n * .log('Substep 1.2')\n * .dedent()\n * .log('Step 2')\n *\n * // Stream-specific logging\n * logger.stdout.log('Normal output')\n * logger.stderr.error('Error message')\n *\n * // Progress indicators\n * logger.progress('Processing...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Done')\n *\n * // Task execution\n * const task = logger.createTask('Migration')\n * task.run(() => {\n * // Migration logic\n * })\n * ```\n */\n/*@__PURE__*/\nexport class Logger {\n /**\n * Static reference to log symbols for convenience.\n *\n * @example\n * ```typescript\n * console.log(`${Logger.LOG_SYMBOLS.success} Done`)\n * ```\n */\n static LOG_SYMBOLS = LOG_SYMBOLS\n\n #parent?: Logger\n #boundStream?: 'stderr' | 'stdout'\n #stderrLogger?: Logger\n #stdoutLogger?: Logger\n #stderrIndention = ''\n #stdoutIndention = ''\n #stderrLastWasBlank = false\n #stdoutLastWasBlank = false\n #logCallCount = 0\n #constructorArgs: unknown[]\n #options: Record<string, unknown>\n #originalStdout?: any\n\n /**\n * Creates a new Logger instance.\n *\n * When called without arguments, creates a logger using the default\n * `process.stdout` and `process.stderr` streams. Can accept custom\n * console constructor arguments for advanced use cases.\n *\n * @param args - Optional console constructor arguments\n *\n * @example\n * ```typescript\n * // Default logger\n * const logger = new Logger()\n *\n * // Custom streams (advanced)\n * const customLogger = new Logger({\n * stdout: customWritableStream,\n * stderr: customErrorStream\n * })\n * ```\n */\n constructor(...args: unknown[]) {\n // Store constructor args for child loggers\n this.#constructorArgs = args\n\n // Store options if provided (for future extensibility)\n const options = args['0']\n if (typeof options === 'object' && options !== null) {\n this.#options = { __proto__: null, ...options }\n // Store reference to original stdout stream to bypass Console formatting\n this.#originalStdout = (options as any).stdout\n } else {\n this.#options = { __proto__: null }\n }\n\n if (args.length) {\n privateConsole.set(this, constructConsole(...args))\n } else {\n // Create a new console that acts like the builtin one so that it will\n // work with Node's --frozen-intrinsics flag.\n const con = constructConsole({\n stdout: process.stdout,\n stderr: process.stderr,\n }) as typeof console & Record<string, unknown>\n for (const { 0: key, 1: method } of boundConsoleEntries) {\n con[key] = method\n }\n privateConsole.set(this, con)\n }\n }\n\n /**\n * Gets a logger instance bound exclusively to stderr.\n *\n * All logging operations on this instance will write to stderr only.\n * Indentation is tracked separately from stdout. The instance is\n * cached and reused on subsequent accesses.\n *\n * @returns A logger instance bound to stderr\n *\n * @example\n * ```typescript\n * // Write errors to stderr\n * logger.stderr.error('Configuration invalid')\n * logger.stderr.warn('Using fallback settings')\n *\n * // Indent only affects stderr\n * logger.stderr.indent()\n * logger.stderr.error('Nested error details')\n * logger.stderr.dedent()\n * ```\n */\n get stderr(): Logger {\n if (!this.#stderrLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stderr'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stderrLogger = instance\n }\n return this.#stderrLogger\n }\n\n /**\n * Gets a logger instance bound exclusively to stdout.\n *\n * All logging operations on this instance will write to stdout only.\n * Indentation is tracked separately from stderr. The instance is\n * cached and reused on subsequent accesses.\n *\n * @returns A logger instance bound to stdout\n *\n * @example\n * ```typescript\n * // Write normal output to stdout\n * logger.stdout.log('Processing started')\n * logger.stdout.log('Items processed: 42')\n *\n * // Indent only affects stdout\n * logger.stdout.indent()\n * logger.stdout.log('Detailed output')\n * logger.stdout.dedent()\n * ```\n */\n get stdout(): Logger {\n if (!this.#stdoutLogger) {\n // Pass parent's constructor args to maintain config\n const instance = new Logger(...this.#constructorArgs)\n instance.#parent = this\n instance.#boundStream = 'stdout'\n instance.#options = { __proto__: null, ...this.#options }\n this.#stdoutLogger = instance\n }\n return this.#stdoutLogger\n }\n\n /**\n * Get the root logger (for accessing shared indentation state).\n * @private\n */\n #getRoot(): Logger {\n return this.#parent || this\n }\n\n /**\n * Get indentation for a specific stream.\n * @private\n */\n #getIndent(stream: 'stderr' | 'stdout'): string {\n const root = this.#getRoot()\n return stream === 'stderr' ? root.#stderrIndention : root.#stdoutIndention\n }\n\n /**\n * Set indentation for a specific stream.\n * @private\n */\n #setIndent(stream: 'stderr' | 'stdout', value: string): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrIndention = value\n } else {\n root.#stdoutIndention = value\n }\n }\n\n /**\n * Get lastWasBlank state for a specific stream.\n * @private\n */\n #getLastWasBlank(stream: 'stderr' | 'stdout'): boolean {\n const root = this.#getRoot()\n return stream === 'stderr'\n ? root.#stderrLastWasBlank\n : root.#stdoutLastWasBlank\n }\n\n /**\n * Set lastWasBlank state for a specific stream.\n * @private\n */\n #setLastWasBlank(stream: 'stderr' | 'stdout', value: boolean): void {\n const root = this.#getRoot()\n if (stream === 'stderr') {\n root.#stderrLastWasBlank = value\n } else {\n root.#stdoutLastWasBlank = value\n }\n }\n\n /**\n * Get the target stream for this logger instance.\n * @private\n */\n #getTargetStream(): 'stderr' | 'stdout' {\n return this.#boundStream || 'stderr'\n }\n\n /**\n * Apply a console method with indentation.\n * @private\n */\n #apply(\n methodName: string,\n args: unknown[],\n stream?: 'stderr' | 'stdout',\n ): this {\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n const text = args.at(0)\n const hasText = typeof text === 'string'\n // Determine which stream this method writes to\n const targetStream = stream || (methodName === 'log' ? 'stdout' : 'stderr')\n const indent = this.#getIndent(targetStream)\n const logArgs = hasText\n ? [applyLinePrefix(text, { prefix: indent }), ...args.slice(1)]\n : args\n ReflectApply(\n con[methodName] as (...args: unknown[]) => unknown,\n con,\n logArgs,\n )\n this[lastWasBlankSymbol](hasText && isBlankString(logArgs[0]), targetStream)\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Strip log symbols from the start of text.\n * @private\n */\n #stripSymbols(text: string): string {\n // Strip both unicode and emoji forms of log symbols from the start.\n // Matches: \u2716, \u2717, \u00D7, \u2716\uFE0F, \u26A0, \u203C, \u26A0\uFE0F, \u2714, \u2713, \u221A, \u2714\uFE0F, \u2713\uFE0F, \u2139, \u2139\uFE0F, \u2192, >\n // Also handles variation selectors (U+FE0F) and whitespace after symbol.\n // Note: We don't strip standalone 'i' or '>' to avoid breaking words.\n return text.replace(/^[\u2716\u2717\u00D7\u26A0\u203C\u2714\u2713\u221A\u2139\u2192]\\uFE0F?\\s*/u, '')\n }\n\n /**\n * Apply a method with a symbol prefix.\n * @private\n */\n #symbolApply(symbolType: string, args: unknown[]): this {\n const con = privateConsole.get(this)\n let text = args.at(0)\n // biome-ignore lint/suspicious/noImplicitAnyLet: Flexible argument handling.\n let extras\n if (typeof text === 'string') {\n text = this.#stripSymbols(text)\n extras = args.slice(1)\n } else {\n extras = args\n text = ''\n }\n // Note: Meta status messages (info/fail/etc) always go to stderr.\n const indent = this.#getIndent('stderr')\n con.error(\n applyLinePrefix(`${LOG_SYMBOLS[symbolType]} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this[lastWasBlankSymbol](false, 'stderr')\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Gets the total number of log calls made on this logger instance.\n *\n * Tracks all logging method calls including `log()`, `error()`, `warn()`,\n * `success()`, `fail()`, etc. Useful for testing and monitoring logging activity.\n *\n * @returns The number of times logging methods have been called\n *\n * @example\n * ```typescript\n * logger.log('Message 1')\n * logger.error('Message 2')\n * console.log(logger.logCallCount) // 2\n * ```\n */\n get logCallCount() {\n const root = this.#getRoot()\n return root.#logCallCount\n }\n\n /**\n * Increments the internal log call counter.\n *\n * This is called automatically by logging methods and should not\n * be called directly in normal usage.\n *\n * @returns The logger instance for chaining\n */\n [incLogCallCountSymbol]() {\n const root = this.#getRoot()\n root.#logCallCount += 1\n return this\n }\n\n /**\n * Sets whether the last logged line was blank.\n *\n * Used internally to track blank lines and prevent duplicate spacing.\n * This is called automatically by logging methods.\n *\n * @param value - Whether the last line was blank\n * @param stream - Optional stream to update (defaults to both streams if not bound, or target stream if bound)\n * @returns The logger instance for chaining\n */\n [lastWasBlankSymbol](value: unknown, stream?: 'stderr' | 'stdout'): this {\n if (stream) {\n // Explicit stream specified\n this.#setLastWasBlank(stream, !!value)\n } else if (this.#boundStream) {\n // Stream-bound logger - affect only the bound stream\n this.#setLastWasBlank(this.#boundStream, !!value)\n } else {\n // Root logger with no stream specified - affect both streams\n this.#setLastWasBlank('stderr', !!value)\n this.#setLastWasBlank('stdout', !!value)\n }\n return this\n }\n\n /**\n * Logs an assertion failure message if the value is falsy.\n *\n * Works like `console.assert()` but returns the logger for chaining.\n * If the value is truthy, nothing is logged. If falsy, logs an error\n * message with an assertion failure.\n *\n * @param value - The value to test\n * @param message - Optional message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.assert(true, 'This will not log')\n * logger.assert(false, 'Assertion failed: value is false')\n * logger.assert(items.length > 0, 'No items found')\n * ```\n */\n assert(value: unknown, ...message: unknown[]): this {\n const con = privateConsole.get(this)\n con.assert(value, ...message)\n this[lastWasBlankSymbol](false)\n return value ? this : this[incLogCallCountSymbol]()\n }\n\n /**\n * Clears the visible terminal screen.\n *\n * Only available on the main logger instance, not on stream-bound instances\n * (`.stderr` or `.stdout`). Resets the log call count and blank line tracking\n * if the output is a TTY.\n *\n * @returns The logger instance for chaining\n * @throws {Error} If called on a stream-bound logger instance\n *\n * @example\n * ```typescript\n * logger.log('Some output')\n * logger.clearVisible() // Screen is now clear\n *\n * // Error: Can't call on stream-bound instance\n * logger.stderr.clearVisible() // throws\n * ```\n */\n clearVisible() {\n if (this.#boundStream) {\n throw new Error(\n 'clearVisible() is only available on the main logger instance, not on stream-bound instances',\n )\n }\n const con = privateConsole.get(this)\n con.clear()\n if ((con as any)._stdout.isTTY) {\n ;(this as any)[lastWasBlankSymbol](true)\n this.#logCallCount = 0\n }\n return this\n }\n\n /**\n * Increments and logs a counter for the given label.\n *\n * Each unique label maintains its own counter. Works like `console.count()`.\n *\n * @param label - Optional label for the counter\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.count('requests') // requests: 1\n * logger.count('requests') // requests: 2\n * logger.count('errors') // errors: 1\n * logger.count() // default: 1\n * ```\n */\n count(label?: string | undefined): this {\n const con = privateConsole.get(this)\n con.count(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Creates a task that logs start and completion messages automatically.\n *\n * Returns a task object with a `run()` method that executes the provided\n * function and logs \"Starting task: {name}\" before execution and\n * \"Completed task: {name}\" after completion.\n *\n * @param name - The name of the task\n * @returns A task object with a `run()` method\n *\n * @example\n * ```typescript\n * const task = logger.createTask('Database Migration')\n * const result = task.run(() => {\n * // Logs: \"Starting task: Database Migration\"\n * migrateDatabase()\n * return 'success'\n * // Logs: \"Completed task: Database Migration\"\n * })\n * console.log(result) // 'success'\n * ```\n */\n createTask(name: string): Task {\n return {\n run: <T>(f: () => T): T => {\n this.log(`Starting task: ${name}`)\n const result = f()\n this.log(`Completed task: ${name}`)\n return result\n },\n }\n }\n\n /**\n * Decreases the indentation level by removing spaces from the prefix.\n *\n * When called on the main logger, affects both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), affects\n * only that stream's indentation.\n *\n * @param spaces - Number of spaces to remove from indentation\n * @default 2\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.indent()\n * logger.log('Indented')\n * logger.dedent()\n * logger.log('Back to normal')\n *\n * // Remove custom amount\n * logger.indent(4)\n * logger.log('Four spaces')\n * logger.dedent(4)\n *\n * // Stream-specific dedent\n * logger.stdout.indent()\n * logger.stdout.log('Indented stdout')\n * logger.stdout.dedent()\n * ```\n */\n dedent(spaces = 2) {\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current.slice(0, -spaces))\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent.slice(0, -spaces))\n this.#setIndent('stdout', stdoutCurrent.slice(0, -spaces))\n }\n return this\n }\n\n /**\n * Displays an object's properties in a formatted way.\n *\n * Works like `console.dir()` with customizable options for depth,\n * colors, etc. Useful for inspecting complex objects.\n *\n * @param obj - The object to display\n * @param options - Optional formatting options (Node.js inspect options)\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: { c: 2, d: { e: 3 } } }\n * logger.dir(obj)\n * logger.dir(obj, { depth: 1 }) // Limit nesting depth\n * logger.dir(obj, { colors: true }) // Enable colors\n * ```\n */\n dir(obj: unknown, options?: unknown | undefined): this {\n const con = privateConsole.get(this)\n con.dir(obj, options)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Displays data as XML/HTML in a formatted way.\n *\n * Works like `console.dirxml()`. In Node.js, behaves the same as `dir()`.\n *\n * @param data - The data to display\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.dirxml(document.body) // In browser environments\n * logger.dirxml(xmlObject) // In Node.js\n * ```\n */\n dirxml(...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.dirxml(data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs an error message to stderr.\n *\n * Automatically applies current indentation. All arguments are formatted\n * and logged like `console.error()`.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.error('Build failed')\n * logger.error('Error code:', 500)\n * logger.error('Details:', { message: 'Not found' })\n * ```\n */\n error(...args: unknown[]): this {\n return this.#apply('error', args)\n }\n\n /**\n * Logs a newline to stderr only if the last line wasn't already blank.\n *\n * Prevents multiple consecutive blank lines. Useful for adding spacing\n * between sections without creating excessive whitespace.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.error('Error message')\n * logger.errorNewline() // Adds blank line\n * logger.errorNewline() // Does nothing (already blank)\n * logger.error('Next section')\n * ```\n */\n errorNewline() {\n return this.#getLastWasBlank('stderr') ? this : this.error('')\n }\n\n /**\n * Logs a failure message with a red colored fail symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.fail` (red \u2716).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.fail('Build failed')\n * logger.fail('Test suite failed:', { passed: 5, failed: 3 })\n * ```\n */\n fail(...args: unknown[]): this {\n return this.#symbolApply('fail', args)\n }\n\n /**\n * Starts a new indented log group.\n *\n * If a label is provided, it's logged before increasing indentation.\n * Groups can be nested. Each group increases indentation by the\n * `kGroupIndentWidth` (default 2 spaces). Call `groupEnd()` to close.\n *\n * @param label - Optional label to display before the group\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.group('Processing files:')\n * logger.log('file1.js')\n * logger.log('file2.js')\n * logger.groupEnd()\n *\n * // Nested groups\n * logger.group('Outer')\n * logger.log('Outer content')\n * logger.group('Inner')\n * logger.log('Inner content')\n * logger.groupEnd()\n * logger.groupEnd()\n * ```\n */\n group(...label: unknown[]): this {\n const { length } = label\n if (length) {\n ReflectApply(this.log, this, label)\n }\n this.indent((this as any)[kGroupIndentationWidthSymbol])\n if (length) {\n ;(this as any)[lastWasBlankSymbol](false)\n ;(this as any)[incLogCallCountSymbol]()\n }\n return this\n }\n\n /**\n * Starts a new collapsed log group (alias for `group()`).\n *\n * In browser consoles, this creates a collapsed group. In Node.js,\n * it behaves identically to `group()`.\n *\n * @param label - Optional label to display before the group\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.groupCollapsed('Details')\n * logger.log('Hidden by default in browsers')\n * logger.groupEnd()\n * ```\n */\n // groupCollapsed is an alias of group.\n // https://nodejs.org/api/console.html#consolegroupcollapsed\n groupCollapsed(...label: unknown[]): this {\n return ReflectApply(this.group, this, label)\n }\n\n /**\n * Ends the current log group and decreases indentation.\n *\n * Must be called once for each `group()` or `groupCollapsed()` call\n * to properly close the group and restore indentation.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.group('Group 1')\n * logger.log('Content')\n * logger.groupEnd() // Closes 'Group 1'\n * ```\n */\n groupEnd() {\n this.dedent((this as any)[kGroupIndentationWidthSymbol])\n return this\n }\n\n /**\n * Increases the indentation level by adding spaces to the prefix.\n *\n * When called on the main logger, affects both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), affects\n * only that stream's indentation. Maximum indentation is 1000 spaces.\n *\n * @param spaces - Number of spaces to add to indentation\n * @default 2\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Level 0')\n * logger.indent()\n * logger.log('Level 1')\n * logger.indent()\n * logger.log('Level 2')\n * logger.dedent()\n * logger.dedent()\n *\n * // Custom indent amount\n * logger.indent(4)\n * logger.log('Indented 4 spaces')\n * logger.dedent(4)\n *\n * // Stream-specific indent\n * logger.stdout.indent()\n * logger.stdout.log('Only stdout is indented')\n * ```\n */\n indent(spaces = 2) {\n const spacesToAdd = ' '.repeat(Math.min(spaces, maxIndentation))\n if (this.#boundStream) {\n // Only affect bound stream\n const current = this.#getIndent(this.#boundStream)\n this.#setIndent(this.#boundStream, current + spacesToAdd)\n } else {\n // Affect both streams\n const stderrCurrent = this.#getIndent('stderr')\n const stdoutCurrent = this.#getIndent('stdout')\n this.#setIndent('stderr', stderrCurrent + spacesToAdd)\n this.#setIndent('stdout', stdoutCurrent + spacesToAdd)\n }\n return this\n }\n\n /**\n * Logs an informational message with a blue colored info symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.info` (blue \u2139).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.info('Starting build process')\n * logger.info('Configuration loaded:', config)\n * logger.info('Using cache directory:', cacheDir)\n * ```\n */\n info(...args: unknown[]): this {\n return this.#symbolApply('info', args)\n }\n\n /**\n * Logs a message to stdout.\n *\n * Automatically applies current indentation. All arguments are formatted\n * and logged like `console.log()`. This is the primary method for\n * standard output.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Processing complete')\n * logger.log('Items processed:', 42)\n * logger.log('Results:', { success: true, count: 10 })\n *\n * // Method chaining\n * logger.log('Step 1').log('Step 2').log('Step 3')\n * ```\n */\n log(...args: unknown[]): this {\n return this.#apply('log', args)\n }\n\n /**\n * Logs a newline to stdout only if the last line wasn't already blank.\n *\n * Prevents multiple consecutive blank lines. Useful for adding spacing\n * between sections without creating excessive whitespace.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Section 1')\n * logger.logNewline() // Adds blank line\n * logger.logNewline() // Does nothing (already blank)\n * logger.log('Section 2')\n * ```\n */\n logNewline() {\n return this.#getLastWasBlank('stdout') ? this : this.log('')\n }\n\n /**\n * Resets all indentation to zero.\n *\n * When called on the main logger, resets both stderr and stdout indentation.\n * When called on a stream-bound logger (`.stderr` or `.stdout`), resets\n * only that stream's indentation.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.indent().indent().indent()\n * logger.log('Very indented')\n * logger.resetIndent()\n * logger.log('Back to zero indentation')\n *\n * // Reset only stdout\n * logger.stdout.resetIndent()\n * ```\n */\n resetIndent() {\n if (this.#boundStream) {\n // Only reset bound stream\n this.#setIndent(this.#boundStream, '')\n } else {\n // Reset both streams\n this.#setIndent('stderr', '')\n this.#setIndent('stdout', '')\n }\n return this\n }\n\n /**\n * Logs a main step message with a cyan arrow symbol and blank line before it.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.step` (cyan \u2192) and\n * adds a blank line before the message unless the last line was already blank.\n * Useful for marking major steps in a process with clear visual separation.\n * Always outputs to stdout. If the message starts with an existing symbol,\n * it will be stripped and replaced.\n *\n * @param msg - The step message to log\n * @param extras - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.step('Building project')\n * logger.log('Compiling TypeScript...')\n * logger.step('Running tests')\n * logger.log('Running test suite...')\n * // Output:\n * // [blank line]\n * // \u2192 Building project\n * // Compiling TypeScript...\n * // [blank line]\n * // \u2192 Running tests\n * // Running test suite...\n * ```\n */\n step(msg: string, ...extras: unknown[]): this {\n // Add blank line before the step message.\n if (!this.#getLastWasBlank('stdout')) {\n // Use this.log() to properly track the blank line.\n this.log('')\n }\n // Strip existing symbols from the message.\n const text = this.#stripSymbols(msg)\n // Note: Step messages always go to stdout (unlike info/fail/etc which go to stderr).\n const indent = this.#getIndent('stdout')\n const con = privateConsole.get(this) as typeof console &\n Record<string, unknown>\n con.log(\n applyLinePrefix(`${LOG_SYMBOLS.step} ${text}`, {\n prefix: indent,\n }),\n ...extras,\n )\n this[lastWasBlankSymbol](false, 'stdout')\n ;(this as any)[incLogCallCountSymbol]()\n return this\n }\n\n /**\n * Logs an indented substep message (stateless).\n *\n * Adds a 2-space indent to the message without affecting the logger's\n * indentation state. Useful for showing sub-items under a main step.\n *\n * @param msg - The substep message to log\n * @param extras - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.log('Installing dependencies:')\n * logger.substep('Installing react')\n * logger.substep('Installing typescript')\n * logger.substep('Installing eslint')\n * // Output:\n * // Installing dependencies:\n * // Installing react\n * // Installing typescript\n * // Installing eslint\n * ```\n */\n substep(msg: string, ...extras: unknown[]): this {\n // Add 2-space indent to the message.\n const indentedMsg = ` ${msg}`\n // Let log() handle all tracking.\n return this.log(indentedMsg, ...extras)\n }\n\n /**\n * Logs a success message with a green colored success symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.success` (green \u2714).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.success('Build completed')\n * logger.success('Tests passed:', { total: 42, passed: 42 })\n * logger.success('Deployment successful')\n * ```\n */\n success(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Logs a completion message with a success symbol (alias for `success()`).\n *\n * Provides semantic clarity when marking something as \"done\". Does NOT\n * automatically clear the current line - call `clearLine()` first if\n * needed after using `progress()`.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.done('Task completed')\n *\n * // After progress indicator\n * logger.progress('Processing...')\n * // ... do work ...\n * logger.clearLine()\n * logger.done('Processing complete')\n * ```\n */\n done(...args: unknown[]): this {\n return this.#symbolApply('success', args)\n }\n\n /**\n * Displays data in a table format.\n *\n * Works like `console.table()`. Accepts arrays of objects or\n * objects with nested objects. Optionally specify which properties\n * to include in the table.\n *\n * @param tabularData - The data to display as a table\n * @param properties - Optional array of property names to include\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * // Array of objects\n * logger.table([\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 }\n * ])\n *\n * // Specify properties to show\n * logger.table(users, ['name', 'email'])\n *\n * // Object with nested objects\n * logger.table({\n * user1: { name: 'Alice', age: 30 },\n * user2: { name: 'Bob', age: 25 }\n * })\n * ```\n */\n table(\n tabularData: unknown,\n properties?: readonly string[] | undefined,\n ): this {\n const con = privateConsole.get(this)\n con.table(tabularData, properties)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Ends a timer and logs the elapsed time.\n *\n * Logs the duration since `console.time()` was called with the same\n * label. The timer is stopped and removed.\n *\n * @param label - Optional label for the timer\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * console.time('operation')\n * // ... do work ...\n * logger.timeEnd('operation')\n * // Logs: \"operation: 123.456ms\"\n *\n * console.time()\n * // ... do work ...\n * logger.timeEnd()\n * // Logs: \"default: 123.456ms\"\n * ```\n */\n timeEnd(label?: string | undefined): this {\n const con = privateConsole.get(this)\n con.timeEnd(label)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs the current value of a timer without stopping it.\n *\n * Logs the duration since `console.time()` was called with the same\n * label, but keeps the timer running. Can include additional data\n * to log alongside the time.\n *\n * @param label - Optional label for the timer\n * @param data - Additional data to log with the time\n * @default 'default'\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * console.time('process')\n * // ... partial work ...\n * logger.timeLog('process', 'Checkpoint 1')\n * // Logs: \"process: 123.456ms Checkpoint 1\"\n * // ... more work ...\n * logger.timeLog('process', 'Checkpoint 2')\n * // Logs: \"process: 234.567ms Checkpoint 2\"\n * console.timeEnd('process')\n * ```\n */\n timeLog(label?: string | undefined, ...data: unknown[]): this {\n const con = privateConsole.get(this)\n con.timeLog(label, ...data)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs a stack trace to the console.\n *\n * Works like `console.trace()`. Shows the call stack leading to\n * where this method was called. Useful for debugging.\n *\n * @param message - Optional message to display with the trace\n * @param args - Additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * function debugFunction() {\n * logger.trace('Debug point reached')\n * }\n *\n * logger.trace('Trace from here')\n * logger.trace('Error context:', { userId: 123 })\n * ```\n */\n trace(message?: unknown | undefined, ...args: unknown[]): this {\n const con = privateConsole.get(this)\n con.trace(message, ...args)\n this[lastWasBlankSymbol](false)\n return this[incLogCallCountSymbol]()\n }\n\n /**\n * Logs a warning message with a yellow colored warning symbol.\n *\n * Automatically prefixes the message with `LOG_SYMBOLS.warn` (yellow \u26A0).\n * Always outputs to stderr. If the message starts with an existing\n * symbol, it will be stripped and replaced.\n *\n * @param args - Message and additional arguments to log\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.warn('Deprecated API used')\n * logger.warn('Low memory:', { available: '100MB' })\n * logger.warn('Missing optional configuration')\n * ```\n */\n warn(...args: unknown[]): this {\n return this.#symbolApply('warn', args)\n }\n\n /**\n * Writes text directly to stdout without a newline or indentation.\n *\n * Useful for progress indicators or custom formatting where you need\n * low-level control. Does not apply any indentation or formatting.\n *\n * @param text - The text to write\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.write('Processing... ')\n * // ... do work ...\n * logger.write('done\\n')\n *\n * // Build a line incrementally\n * logger.write('Step 1')\n * logger.write('... Step 2')\n * logger.write('... Step 3\\n')\n * ```\n */\n write(text: string): this {\n const con = privateConsole.get(this)\n // Write directly to the original stdout stream to bypass Console formatting\n // (e.g., group indentation). Try multiple approaches to get the raw stream:\n // 1. Use stored reference from constructor options\n // 2. Try to get from constructor args\n // 3. Fall back to con._stdout (which applies formatting)\n const stdout =\n this.#originalStdout ||\n (this.#constructorArgs[0] as any)?.stdout ||\n con._stdout\n stdout.write(text)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Shows a progress indicator that can be cleared with `clearLine()`.\n *\n * Displays a simple status message with a '\u2234' prefix. Does not include\n * animation or spinner. Intended to be cleared once the operation completes.\n * The output stream (stderr or stdout) depends on whether the logger is\n * stream-bound.\n *\n * @param text - The progress message to display\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.progress('Processing files...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Files processed')\n *\n * // Stream-specific progress\n * logger.stdout.progress('Loading...')\n * // ... do work ...\n * logger.stdout.clearLine()\n * logger.stdout.log('Done')\n * ```\n */\n progress(text: string): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n streamObj.write(`\u2234 ${text}`)\n this[lastWasBlankSymbol](false)\n return this\n }\n\n /**\n * Clears the current line in the terminal.\n *\n * Moves the cursor to the beginning of the line and clears all content.\n * Works in both TTY and non-TTY environments. Useful for clearing\n * progress indicators created with `progress()`.\n *\n * The stream to clear (stderr or stdout) depends on whether the logger\n * is stream-bound.\n *\n * @returns The logger instance for chaining\n *\n * @example\n * ```typescript\n * logger.progress('Loading...')\n * // ... do work ...\n * logger.clearLine()\n * logger.success('Loaded')\n *\n * // Clear multiple progress updates\n * for (const file of files) {\n * logger.progress(`Processing ${file}`)\n * processFile(file)\n * logger.clearLine()\n * }\n * logger.success('All files processed')\n * ```\n */\n clearLine(): this {\n const con = privateConsole.get(this)\n const stream = this.#getTargetStream()\n const streamObj = stream === 'stderr' ? con._stderr : con._stdout\n if (streamObj.isTTY) {\n streamObj.cursorTo(0)\n streamObj.clearLine(0)\n } else {\n streamObj.write('\\r\\x1b[K')\n }\n return this\n }\n}\n\nObject.defineProperties(\n Logger.prototype,\n Object.fromEntries(\n (() => {\n const entries: Array<[string | symbol, PropertyDescriptor]> = [\n [\n kGroupIndentationWidthSymbol,\n {\n ...consolePropAttributes,\n value: 2,\n },\n ],\n [\n Symbol.toStringTag,\n {\n __proto__: null,\n configurable: true,\n value: 'logger',\n } as PropertyDescriptor,\n ],\n ]\n for (const { 0: key, 1: value } of Object.entries(globalConsole)) {\n if (!(Logger.prototype as any)[key] && typeof value === 'function') {\n // Dynamically name the log method without using Object.defineProperty.\n const { [key]: func } = {\n [key](...args: unknown[]) {\n const con = privateConsole.get(this)\n const result = (con as any)[key](...args)\n return result === undefined || result === con ? this : result\n },\n }\n entries.push([\n key,\n {\n ...consolePropAttributes,\n value: func,\n },\n ])\n }\n }\n return entries\n })(),\n ),\n)\n\n/**\n * Default logger instance for the application.\n *\n * A pre-configured `Logger` instance that uses the standard `process.stdout`\n * and `process.stderr` streams. This is the recommended logger to import\n * and use throughout your application.\n *\n * @example\n * ```typescript\n * import { logger } from '@socketsecurity/lib'\n *\n * logger.log('Application started')\n * logger.success('Configuration loaded')\n * logger.indent()\n * logger.log('Using port 3000')\n * logger.dedent()\n * ```\n */\nexport const logger = new Logger()\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["logger_exports", "__export", "LOG_SYMBOLS", "Logger", "incLogCallCountSymbol", "lastWasBlankSymbol", "logger", "__toCommonJS", "import_is_unicode_supported", "import_yoctocolors_cjs", "import_objects", "import_strings", "globalConsole", "ReflectApply", "ReflectConstruct", "_Console", "constructConsole", "args", "getYoctocolors", "yoctocolorsCjs", "target", "handler", "init", "supported", "isUnicodeSupported", "colors", "trapName", "fn", "boundConsoleEntries", "n", "consolePropAttributes", "maxIndentation", "privateConsole", "consoleSymbols", "kGroupIndentationWidthSymbol", "s", "#parent", "#boundStream", "#stderrLogger", "#stdoutLogger", "#stderrIndention", "#stdoutIndention", "#stderrLastWasBlank", "#stdoutLastWasBlank", "#logCallCount", "#constructorArgs", "#options", "#originalStdout", "options", "con", "key", "method", "instance", "#getRoot", "#getIndent", "stream", "root", "#setIndent", "value", "#getLastWasBlank", "#setLastWasBlank", "#getTargetStream", "#apply", "methodName", "text", "hasText", "targetStream", "indent", "logArgs", "#stripSymbols", "#symbolApply", "symbolType", "extras", "message", "label", "name", "f", "result", "spaces", "current", "stderrCurrent", "stdoutCurrent", "obj", "data", "length", "spacesToAdd", "msg", "indentedMsg", "tabularData", "properties", "streamObj", "entries", "func"]
|
|
7
7
|
}
|