Skip to content

Instantly share code, notes, and snippets.

@ryangoree
Last active November 7, 2024 21:31
Show Gist options
  • Save ryangoree/b82256d70c5d9bed769b94a8d72bb38a to your computer and use it in GitHub Desktop.
Save ryangoree/b82256d70c5d9bed769b94a8d72bb38a to your computer and use it in GitHub Desktop.
Attempts to get the path to the file that called the function that called this function.

Get Caller Path

Attempts to get the path to the file that called the function that called this function.

📦 Install

npm i gist:b82256d70c5d9bed769b94a8d72bb38a

Usage

Caller:

// /path/to/caller.ts
import { foo } from './path/to/callee.ts';

foo();

Callee:

// /path/to/callee.ts
import { getCallerPath } from 'get-caller-path';

export function foo() {
  console.log(getCallerPath()); // /path/to/caller.ts
}
/**
* Attempts to get the path to the file that called the function that called
* this function.
*
* @example
*
* #### Caller:
* ```ts
* // /path/to/caller.ts
* import { foo } from './path/to/callee.ts';
*
* foo();
* ```
*
* #### Callee:
*
* ```ts
* // /path/to/callee.ts
* import { getCallerPath } from 'src/utils/get-caller';
*
* export function foo() {
* console.log(getCallerPath()); // /path/to/caller.ts
* }
* ```
*/
export declare function getCallerPath(): string | undefined;
/**
* Attempts to get the path to the file that called the function that called
* this function.
*
* @example
*
* #### Caller:
* ```ts
* // /path/to/caller.ts
* import { foo } from './path/to/callee.ts';
*
* foo();
* ```
*
* #### Callee:
*
* ```ts
* // /path/to/callee.ts
* import { getCallerPath } from 'src/utils/get-caller';
*
* export function foo() {
* console.log(getCallerPath()); // /path/to/caller.ts
* }
* ```
*/
export function getCallerPath() {
/**
* 0 = error name and message
*
* 1 = path to this file
*
* 2 = path to the file that called this function. The one that wants to know
* it's caller.
*
* 3 = path to the file that called the function that called this function
* (this is the file that the caller of this function wants)
*/
const callerIndex = 3;
const err = new Error();
// Attempt to overwrite the `prepareStackTrace` function. This will work in
// v8 environments, but will be ignored otherwise.
// https://v8.dev/docs/stack-trace-api#customizing-stack-traces
const originalPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
Error.captureStackTrace(err);
Error.prepareStackTrace = originalPrepareStackTrace;
if (!err.stack) return undefined;
// If the stack is an array, we're in a v8 environment and can use the
// `getFileName` method on the call site.
if (Array.isArray(err.stack)) {
const caller = err.stack[callerIndex];
return caller?.getFileName();
}
// If the stack is a string, we're in a non-v8 environment and need to parse
// the stack string to get the file path.
// https://regex101.com/r/yyMI5W/1
const callerLine = err.stack.split('\n')[callerIndex].trim();
const callerFile = callerLine.match(/(file|\/)[^\s]+?(?=(:\d|\)))/)?.[0];
if (!callerFile) return undefined;
return new URL(callerFile, import.meta.url).pathname;
}
{
"version": "0.0.1",
"name": "get-caller-path",
"main": "getCallerPath.js",
"types": "getCallerPath.d.ts",
"type": "module",
"author": "Ryan Goree (https://github.com/ryangoree)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment