Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

@mnrendra/stack-trace

versiondownloadssizecoveragescorecardreleasesemanticlicense

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Useful for debugging, logging, or building tools that need to trace call origins at runtime.

Features

Install

npm i @mnrendra/stack-trace

API Reference

stackTrace

Captures v8 stack trace from a specific caller.

Type

(callee?: ((...args: any)=>any)|null,options?: Options)=>NodeJS.CallSite[]

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.
optionsOptionsOptional options to affect the captured frames. By default, the limit option is set to Infinity to capture all frames. To capture only a specific number of frames, set the limit option to a positive number.

Return

NodeJS.CallSite[]

Array of CallSite objects representing the captured stack trace frames.

Options

NameTypeDefaultDescription
limitnumberInfinitySpecifies the number of stack frames to be collected by a stack trace. The default value is Infinity, but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

getCallerSite

Gets the caller's CallSite object captured from stackTrace.

Type

(callee?: ((...args: any)=>any)|null)=>NodeJS.CallSite

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

NodeJS.CallSite

First CallSite object captured in the stack trace.

extractFilePath

Extracts the file name from a CallSite object and converts it to a file path if the value is a file URL.
This utility ensures that the returned value is an absolute path.

Type

(callSite: NodeJS.CallSite)=>string

Parameters

NameTypeDescription
callSiteNodeJS.CallSiteCallSite object captured from stackTrace.

Return

string

Absolute path of the file name extracted from a CallSite object.

Throws

If the extracted file name is not a string or not absolute.

getCallerFile

Gets the caller's file extracted from the result of getCallerSite and ensures it returns an absolute path using extractFilePath.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's file.

Throws

If the extracted file name is not a string or not absolute.

getCallerDir

Gets the caller's directory extracted from the result of getCallerFile.

Type

(callee?: ((...args: any)=>any)|null)=>string

Parameters

NameTypeDescription
callee((...args: any) => any) | nullOptional callee function to specify the caller. If undefined or null, tracing starts from the current caller.

Return

string

Absolute path of the caller's directory.

Throws

If the extracted file name is not a string or not absolute.

Usage

ES Modules

/foo/callee.mjs

import{dirname}from'node:path'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: file:///foo/callee.mjsconsole.log(callerSite2.getFileName())// Output: file:///foo/caller.mjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.mjsconsole.log(filePath2)// Output: /foo/caller.mjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.mjsconsole.log(callerFile2)// Output: /foo/caller.mjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}exportdefaultcallee

/foo/caller.mjs

importcalleefrom'./callee.mjs'constcaller=()=>callee()caller()

CommonJS

/foo/callee.cjs

const{ dirname }=require('node:path')const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require('@mnrendra/stack-trace')constcallee=()=>{// `stackTrace`:const[callSite1]=stackTrace()const[callSite2]=stackTrace(callee,{limit: 1})// Pass the `callee` function as the callee.console.log(callSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callSite1.getFunctionName())// Output: calleeconsole.log(callSite2.getFunctionName())// Output: caller// `getCallerSite`:constcallerSite1=getCallerSite()constcallerSite2=getCallerSite(callee)// Pass the `callee` function as the callee.console.log(callerSite1.getFileName()===callSite1.getFileName())// Output: trueconsole.log(callerSite2.getFileName()===callSite2.getFileName())// Output: trueconsole.log(callerSite1.getFileName())// Output: /foo/callee.cjsconsole.log(callerSite2.getFileName())// Output: /foo/caller.cjsconsole.log(callerSite1.getFunctionName()===callSite1.getFunctionName())// Output: trueconsole.log(callerSite2.getFunctionName()===callSite2.getFunctionName())// Output: trueconsole.log(callerSite1.getFunctionName())// Output: calleeconsole.log(callerSite2.getFunctionName())// Output: caller// `extractFilePath`:constfilePath1=extractFilePath(callerSite1)constfilePath2=extractFilePath(callerSite2)console.log(filePath1)// Output: /foo/callee.cjsconsole.log(filePath2)// Output: /foo/caller.cjs// `getCallerFile`:constcallerFile1=getCallerFile()constcallerFile2=getCallerFile(callee)// Pass the `callee` function as the callee.console.log(callerFile1===filePath1)// Output: trueconsole.log(callerFile2===filePath2)// Output: trueconsole.log(callerFile1)// Output: /foo/callee.cjsconsole.log(callerFile2)// Output: /foo/caller.cjs// `getCallerDir`:constcallerDir1=getCallerDir()constcallerDir2=getCallerDir(callee)// Pass the `callee` function as the callee.console.log(callerDir1===dirname(filePath1))// Output: trueconsole.log(callerDir2===dirname(filePath2))// Output: trueconsole.log(callerDir1)// Output: /fooconsole.log(callerDir2)// Output: /foo}module.exports=callee

/foo/caller.cjs

constcallee=require('./callee.cjs')constcaller=()=>callee()caller()

Note:

  • In ES Modules, getFileName returns a file URL (e.g., file:///foo), instead of a file path (/foo).
    To convert it to a file path, use either url.fileURLToPath or the extractFilePath utility.

  • By default stackTrace will capture all caller's frames.
    To capture only a specific number of frames, set the limit option to a positive number.

Examples

  1. Call from a development project

/foo/project-name/src/index.mjs:

import{dirname}from'node:path'import{fileURLToPath}from'node:url'import{stackTrace,getCallerSite,extractFilePath,getCallerFile,getCallerDir}from'@mnrendra/stack-trace'// `stackTrace`:constcaller1=()=>stackTrace()const[callSite]=caller1()constfileName=callSite.getFileName()console.log(fileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(fileName))// Output: /foo/project-name/src/index.mjs// `getCallerSite`:constcaller2=()=>getCallerSite()constcallerSite=caller2()constcallerFileName=callerSite.getFileName()console.log(callerFileName===fileName)// Output: trueconsole.log(callerFileName)// Output: file:///foo/project-name/src/index.mjsconsole.log(fileURLToPath(callerFileName))// Output: /foo/project-name/src/index.mjs// `extractFilePath`:constfilePath=extractFilePath(callerSite)console.log(filePath===fileURLToPath(callerFileName))// Output: trueconsole.log(filePath)// Output: /foo/project-name/src/index.mjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/project-name/src/index.mjs// `getCallerDir`:constcaller4=()=>getCallerDir()constcallerDir=caller4()console.log(callerDir===dirname(filePath))// Output: trueconsole.log(callerDir)// Output: /foo/project-name/src
  1. Call from a production package

/foo/consumer/node_modules/module-name/dist/index.cjs:

"use strict";const{ dirname }=require("node:path");const{
stackTrace,
getCallerSite,
extractFilePath,
getCallerFile,
getCallerDir
}=require("@mnrendra/stack-trace");// `stackTrace`:constcaller1=()=>stackTrace();const[callSite]=caller1();constfileName=callSite.getFileName();console.log(fileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerSite`:constcaller2=()=>getCallerSite();constcallerSite=caller2();constcallerFileName=callerSite.getFileName();console.log(callerFileName===fileName);// Output: trueconsole.log(callerFileName);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `extractFilePath`:constfilePath=extractFilePath(callerSite);console.log(filePath===callerFileName);// Output: trueconsole.log(filePath);// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerFile`:constcaller3=()=>getCallerFile()constcallerFile=caller3()console.log(callerFile===filePath)// Output: trueconsole.log(callerFile)// Output: /foo/consumer/node_modules/module-name/dist/index.cjs// `getCallerDir`:constcaller4=()=>getCallerDir();constcallerDir=caller4();console.log(callerDir===dirname(filePath));// Output: trueconsole.log(callerDir);// Output: /foo/consumer/node_modules/module-name/dist

Types

Options

stackTrace's options interface.

import{typeOptions,stackTrace}from'@mnrendra/stack-trace'constoptions: Options={limit: 1}constcaller=(): NodeJS.CallSite[]=>stackTrace(caller,options)constcallSites=caller()console.log(callSites.length)// Output: 1

Security

We take security seriously in this project. If you discover a vulnerability, we strongly encourage you to report it in a responsible manner.

Please open a Security Advisory to report any vulnerabilities.

For more information, please refer to our Security Policy.

Contributing

We appreciate your help in making this project better. Please follow the guidelines to ensure that your contributions are smoothly integrated.

License

MIT

Author

@mnrendra

About

A lightweight stack trace utility to retrieve CallSite objects from a specific caller.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages