@tapjs/stack
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -22,4 +22,4 @@ /// <reference types="node" /> | ||
export interface GeneratedResult { | ||
fileName: string | null; | ||
lineNumber: number | null; | ||
fileName?: string | null; | ||
lineNumber?: number | null; | ||
columnNumber?: number | null; | ||
@@ -44,9 +44,9 @@ } | ||
get fileName(): string | null | undefined; | ||
get absoluteFileName(): string | null; | ||
get absoluteFileName(): string | null | undefined; | ||
get cwd(): string | undefined; | ||
set cwd(cwd: string | undefined); | ||
constructor(e: Error | null, c: NodeJS.CallSite | string | Compiled); | ||
toString(): string; | ||
toString(jsStyle?: boolean): string; | ||
toJSON(): CallSiteLikeJSON; | ||
} | ||
//# sourceMappingURL=call-site-like.d.ts.map |
@@ -5,2 +5,3 @@ "use strict"; | ||
const module_1 = require("module"); | ||
const path_1 = require("path"); | ||
const url_1 = require("url"); | ||
@@ -48,3 +49,13 @@ const parse_js_1 = require("./parse.js"); | ||
set cwd(cwd) { | ||
if (cwd === undefined) { | ||
if (this.generated) { | ||
this.generated.fileName = this.#derelativize(this.generated?.fileName); | ||
} | ||
} | ||
this.#cwd = cwd?.replace(/\\/g, '/'); | ||
if (cwd !== undefined) { | ||
if (this.generated) { | ||
this.generated.fileName = this.#relativize(this.generated?.fileName); | ||
} | ||
} | ||
if (this.evalOrigin) | ||
@@ -89,3 +100,7 @@ this.evalOrigin.cwd = cwd; | ||
this.#fileName = typeof fileName === 'string' ? fileName : null; | ||
this.generated = c.generated; | ||
const { generated } = c; | ||
if (generated) { | ||
this.generated = generated; | ||
this.generated.fileName = this.#relativize(generated.fileName); | ||
} | ||
let fname = c.fname?.trim(); | ||
@@ -189,3 +204,3 @@ let method = null; | ||
/* c8 ignore start */ | ||
fileName: genFilename || null, | ||
fileName: this.#relativize(genFilename || null), | ||
/* c8 ignore stop */ | ||
@@ -214,8 +229,58 @@ lineNumber: this.lineNumber, | ||
f = f.replace(/\\/g, '/'); | ||
if (f.startsWith(`${this.#cwd}/`)) { | ||
return f.substring(this.#cwd.length + 1); | ||
try { | ||
const rel = (0, path_1.relative)(this.#cwd, f); | ||
return rel.length < f.length ? rel : f; | ||
} | ||
return f; | ||
catch { | ||
return f; | ||
} | ||
} | ||
toString() { | ||
#derelativize(fileName) { | ||
let f = fileName; | ||
if (!f) | ||
return f; | ||
if (f.startsWith('node:')) | ||
return f; | ||
if (f.startsWith('file://')) | ||
f = (0, url_1.fileURLToPath)(f); | ||
if (this.#cwd === undefined) | ||
return f; | ||
try { | ||
return (0, path_1.resolve)(this.#cwd, f); | ||
} | ||
catch { | ||
return f; | ||
} | ||
} | ||
toString(jsStyle = false) { | ||
// in js style mode, use the origin source file if it is within | ||
// our cwd. Otherwise, use the generated source location. | ||
const useGen = jsStyle && | ||
this.generated?.fileName && | ||
this.fileName && | ||
this.generated.fileName !== this.fileName && | ||
((0, path_1.isAbsolute)(this.fileName) || this.fileName.startsWith('..')); | ||
const { fileName, lineNumber, columnNumber, generated } = useGen && this.generated | ||
? { | ||
fileName: this.#derelativize(this.generated.fileName), | ||
lineNumber: this.generated.lineNumber, | ||
columnNumber: this.generated.columnNumber, | ||
generated: undefined, | ||
} | ||
: jsStyle | ||
? { | ||
fileName: this.#derelativize(this.fileName), | ||
lineNumber: this.lineNumber, | ||
columnNumber: this.columnNumber, | ||
generated: undefined, | ||
} | ||
: this; | ||
const loc = { fileName, lineNumber, columnNumber, generated }; | ||
for (const l of [loc, loc.generated]) { | ||
if (l?.fileName) { | ||
l.fileName = jsStyle | ||
? this.#derelativize(l.fileName) | ||
: this.#relativize(l.fileName); | ||
} | ||
} | ||
let fname = this.functionName || ''; | ||
@@ -248,12 +313,12 @@ let tn = ''; | ||
const nat = this.isNative ? 'native' : ''; | ||
let file = this.fileName || ''; | ||
const hasLC = this.lineNumber && this.columnNumber; | ||
let file = loc.fileName || ''; | ||
const hasLC = loc.lineNumber && loc.columnNumber; | ||
if (this.evalOrigin) { | ||
ev = `eval at ${this.evalOrigin.toString()}`; | ||
ev = `eval at ${this.evalOrigin.toString(jsStyle)}`; | ||
if (hasLC) { | ||
const f = this.fileName || '<anonymous>'; | ||
let lr = `${f}:${this.lineNumber}:${this.columnNumber}`; | ||
if (this.generated && this.generated.fileName) { | ||
const f = this.generated.fileName; | ||
const { lineNumber: l, columnNumber: c } = this.generated; | ||
const f = loc.fileName || '<anonymous>'; | ||
let lr = `${f}:${loc.lineNumber}:${loc.columnNumber}`; | ||
if (loc.generated && loc.generated.fileName) { | ||
const f = loc.generated.fileName; | ||
const { lineNumber: l, columnNumber: c } = loc.generated; | ||
lr = `${f}:${l}:${c} (${lr})`; | ||
@@ -274,3 +339,3 @@ } | ||
/* c8 ignore stop */ | ||
file += `:${this.lineNumber}:${this.columnNumber}`; | ||
file += `:${loc.lineNumber}:${loc.columnNumber}`; | ||
} | ||
@@ -288,5 +353,5 @@ } | ||
let g = ''; | ||
if (this.generated && this.generated.fileName) { | ||
const { fileName, lineNumber, columnNumber } = this.generated; | ||
g = this.#relativize(fileName); | ||
if (loc.generated && loc.generated.fileName) { | ||
const { fileName, lineNumber, columnNumber } = loc.generated; | ||
g = fileName; | ||
/* c8 ignore start */ | ||
@@ -296,3 +361,3 @@ if (!g) | ||
/* c8 ignore stop */ | ||
if (g === this.fileName) | ||
if (g === loc.fileName) | ||
g = ''; | ||
@@ -312,3 +377,4 @@ if (g) { | ||
} | ||
return `${fname}${ev}${g}${file}`; | ||
const pre = jsStyle ? ' at ' : ''; | ||
return `${pre}${fname}${ev}${g}${file}`; | ||
} | ||
@@ -315,0 +381,0 @@ toJSON() { |
@@ -129,2 +129,3 @@ /// <reference types="node" /> | ||
export declare const parseStack: (s: string) => CallSiteLike[]; | ||
export declare const expandStack: (s?: string | CallSiteLike[]) => string; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseStack = exports.captureErrorString = exports.captureError = exports.captureString = exports.at = exports.capture = exports.getFilterIgnoredPackages = exports.setFilterIgnoredPackages = exports.getIgnoredPackagesRE = exports.getIgnoredPackages = exports.removeIgnoredPackage = exports.addIgnoredPackage = exports.setFilterNodeInternals = exports.getFilterNodeInternals = exports.getCwd = exports.setCwd = exports.CallSiteLike = void 0; | ||
exports.expandStack = exports.parseStack = exports.captureErrorString = exports.captureError = exports.captureString = exports.at = exports.capture = exports.getFilterIgnoredPackages = exports.setFilterIgnoredPackages = exports.getIgnoredPackagesRE = exports.getIgnoredPackages = exports.removeIgnoredPackage = exports.addIgnoredPackage = exports.setFilterNodeInternals = exports.getFilterNodeInternals = exports.getCwd = exports.setCwd = exports.CallSiteLike = void 0; | ||
const node_module_1 = require("node:module"); | ||
@@ -292,2 +292,12 @@ const node_path_1 = require("node:path"); | ||
exports.parseStack = parseStack; | ||
const expandStack = (s) => { | ||
if (!s) | ||
return ''; | ||
if (typeof s === 'string') | ||
return (0, exports.expandStack)((0, exports.parseStack)(s)); | ||
return clean(s) | ||
.map(c => c.toString(true) + '\n') | ||
.join(''); | ||
}; | ||
exports.expandStack = expandStack; | ||
//# sourceMappingURL=index.js.map |
@@ -22,4 +22,4 @@ /// <reference types="node" resolution-mode="require"/> | ||
export interface GeneratedResult { | ||
fileName: string | null; | ||
lineNumber: number | null; | ||
fileName?: string | null; | ||
lineNumber?: number | null; | ||
columnNumber?: number | null; | ||
@@ -44,9 +44,9 @@ } | ||
get fileName(): string | null | undefined; | ||
get absoluteFileName(): string | null; | ||
get absoluteFileName(): string | null | undefined; | ||
get cwd(): string | undefined; | ||
set cwd(cwd: string | undefined); | ||
constructor(e: Error | null, c: NodeJS.CallSite | string | Compiled); | ||
toString(): string; | ||
toString(jsStyle?: boolean): string; | ||
toJSON(): CallSiteLikeJSON; | ||
} | ||
//# sourceMappingURL=call-site-like.d.ts.map |
import { findSourceMap } from 'module'; | ||
import { isAbsolute, relative, resolve } from 'path'; | ||
import { fileURLToPath } from 'url'; | ||
@@ -44,3 +45,13 @@ import { isCompiledCallSiteLine, parseCallSiteLine, } from './parse.js'; | ||
set cwd(cwd) { | ||
if (cwd === undefined) { | ||
if (this.generated) { | ||
this.generated.fileName = this.#derelativize(this.generated?.fileName); | ||
} | ||
} | ||
this.#cwd = cwd?.replace(/\\/g, '/'); | ||
if (cwd !== undefined) { | ||
if (this.generated) { | ||
this.generated.fileName = this.#relativize(this.generated?.fileName); | ||
} | ||
} | ||
if (this.evalOrigin) | ||
@@ -85,3 +96,7 @@ this.evalOrigin.cwd = cwd; | ||
this.#fileName = typeof fileName === 'string' ? fileName : null; | ||
this.generated = c.generated; | ||
const { generated } = c; | ||
if (generated) { | ||
this.generated = generated; | ||
this.generated.fileName = this.#relativize(generated.fileName); | ||
} | ||
let fname = c.fname?.trim(); | ||
@@ -185,3 +200,3 @@ let method = null; | ||
/* c8 ignore start */ | ||
fileName: genFilename || null, | ||
fileName: this.#relativize(genFilename || null), | ||
/* c8 ignore stop */ | ||
@@ -210,8 +225,58 @@ lineNumber: this.lineNumber, | ||
f = f.replace(/\\/g, '/'); | ||
if (f.startsWith(`${this.#cwd}/`)) { | ||
return f.substring(this.#cwd.length + 1); | ||
try { | ||
const rel = relative(this.#cwd, f); | ||
return rel.length < f.length ? rel : f; | ||
} | ||
return f; | ||
catch { | ||
return f; | ||
} | ||
} | ||
toString() { | ||
#derelativize(fileName) { | ||
let f = fileName; | ||
if (!f) | ||
return f; | ||
if (f.startsWith('node:')) | ||
return f; | ||
if (f.startsWith('file://')) | ||
f = fileURLToPath(f); | ||
if (this.#cwd === undefined) | ||
return f; | ||
try { | ||
return resolve(this.#cwd, f); | ||
} | ||
catch { | ||
return f; | ||
} | ||
} | ||
toString(jsStyle = false) { | ||
// in js style mode, use the origin source file if it is within | ||
// our cwd. Otherwise, use the generated source location. | ||
const useGen = jsStyle && | ||
this.generated?.fileName && | ||
this.fileName && | ||
this.generated.fileName !== this.fileName && | ||
(isAbsolute(this.fileName) || this.fileName.startsWith('..')); | ||
const { fileName, lineNumber, columnNumber, generated } = useGen && this.generated | ||
? { | ||
fileName: this.#derelativize(this.generated.fileName), | ||
lineNumber: this.generated.lineNumber, | ||
columnNumber: this.generated.columnNumber, | ||
generated: undefined, | ||
} | ||
: jsStyle | ||
? { | ||
fileName: this.#derelativize(this.fileName), | ||
lineNumber: this.lineNumber, | ||
columnNumber: this.columnNumber, | ||
generated: undefined, | ||
} | ||
: this; | ||
const loc = { fileName, lineNumber, columnNumber, generated }; | ||
for (const l of [loc, loc.generated]) { | ||
if (l?.fileName) { | ||
l.fileName = jsStyle | ||
? this.#derelativize(l.fileName) | ||
: this.#relativize(l.fileName); | ||
} | ||
} | ||
let fname = this.functionName || ''; | ||
@@ -244,12 +309,12 @@ let tn = ''; | ||
const nat = this.isNative ? 'native' : ''; | ||
let file = this.fileName || ''; | ||
const hasLC = this.lineNumber && this.columnNumber; | ||
let file = loc.fileName || ''; | ||
const hasLC = loc.lineNumber && loc.columnNumber; | ||
if (this.evalOrigin) { | ||
ev = `eval at ${this.evalOrigin.toString()}`; | ||
ev = `eval at ${this.evalOrigin.toString(jsStyle)}`; | ||
if (hasLC) { | ||
const f = this.fileName || '<anonymous>'; | ||
let lr = `${f}:${this.lineNumber}:${this.columnNumber}`; | ||
if (this.generated && this.generated.fileName) { | ||
const f = this.generated.fileName; | ||
const { lineNumber: l, columnNumber: c } = this.generated; | ||
const f = loc.fileName || '<anonymous>'; | ||
let lr = `${f}:${loc.lineNumber}:${loc.columnNumber}`; | ||
if (loc.generated && loc.generated.fileName) { | ||
const f = loc.generated.fileName; | ||
const { lineNumber: l, columnNumber: c } = loc.generated; | ||
lr = `${f}:${l}:${c} (${lr})`; | ||
@@ -270,3 +335,3 @@ } | ||
/* c8 ignore stop */ | ||
file += `:${this.lineNumber}:${this.columnNumber}`; | ||
file += `:${loc.lineNumber}:${loc.columnNumber}`; | ||
} | ||
@@ -284,5 +349,5 @@ } | ||
let g = ''; | ||
if (this.generated && this.generated.fileName) { | ||
const { fileName, lineNumber, columnNumber } = this.generated; | ||
g = this.#relativize(fileName); | ||
if (loc.generated && loc.generated.fileName) { | ||
const { fileName, lineNumber, columnNumber } = loc.generated; | ||
g = fileName; | ||
/* c8 ignore start */ | ||
@@ -292,3 +357,3 @@ if (!g) | ||
/* c8 ignore stop */ | ||
if (g === this.fileName) | ||
if (g === loc.fileName) | ||
g = ''; | ||
@@ -308,3 +373,4 @@ if (g) { | ||
} | ||
return `${fname}${ev}${g}${file}`; | ||
const pre = jsStyle ? ' at ' : ''; | ||
return `${pre}${fname}${ev}${g}${file}`; | ||
} | ||
@@ -311,0 +377,0 @@ toJSON() { |
@@ -129,2 +129,3 @@ /// <reference types="node" resolution-mode="require"/> | ||
export declare const parseStack: (s: string) => CallSiteLike[]; | ||
export declare const expandStack: (s?: string | CallSiteLike[]) => string; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -272,2 +272,11 @@ import { builtinModules } from 'node:module'; | ||
.map(line => new CallSiteLike(null, line))); | ||
export const expandStack = (s) => { | ||
if (!s) | ||
return ''; | ||
if (typeof s === 'string') | ||
return expandStack(parseStack(s)); | ||
return clean(s) | ||
.map(c => c.toString(true) + '\n') | ||
.join(''); | ||
}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@tapjs/stack", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Utility for working with stack traces", | ||
@@ -5,0 +5,0 @@ "author": "Isaac Z. Schlueter <i@izs.me> (https://blog.izs.me)", |
@@ -110,2 +110,14 @@ # `@tapjs/stack` | ||
## `expandStack(stack?: string | CallSiteLike[]): string` | ||
Expand a stack string (either from `@tapjs/stack` or from a | ||
JS Error object) into its conventional `Error.stack` form, | ||
complete with absolute paths, indentation, and repetitive `at` | ||
prefixes. | ||
When a call site is source mapped, the origin source will be | ||
shown if the generated source is outside the cwd. If the cwd is | ||
not set on the CallSiteLike object, then generated location is | ||
always shown. | ||
## `setCwd(cwd: string | undefined)` | ||
@@ -112,0 +124,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
229073
2230
168