@stacktrace-lite/core
Version:
> Parse, filter, and format JavaScript stack traces with plugins for browsers and Node.js.
59 lines (58 loc) • 2.04 kB
JavaScript
/**
* Filter an array of {@link StackFrame} entries using include/exclude matchers and presets.
*
* @param frames - The input stack frames to filter.
* @param opts - Optional filtering options (include/exclude matchers and preset).
* @returns The filtered list of stack frames, in original order.
*
* @remarks
* Matching order:
* 1. Start with `exclude` (plus any entries added by `preset`).
* 2. If a frame matches **any** exclude matcher, it is removed.
* 3. If `include` is provided, a frame must match **at least one** include matcher to be kept.
* 4. Otherwise, the frame is kept.
*
* **Matcher behavior**
* - `RegExp`: tested against `frame.fileName ?? ''`.
* - Function: receives the `frame` and should return `true` to indicate a match.
*
* @example
* ```ts
* // Typical "clean stack" for UI error overlays:
* const clean = filterStack(frames, {
* preset: 'app-only',
* include: [/\/src\//], // focus on your own source files
* exclude: [/\.spec\./, /test\//] // trim tests if present in stacks
* });
* ```
*/
export function filterStack(frames, opts = {}) {
let exclude = opts.exclude ?? [];
if (opts.preset === 'app-only') {
exclude = [
/node_modules/,
/\bwebpack\b/,
/\binternal\b/,
/\b<anonymous>\b/,
/native/,
...exclude,
];
}
else if (opts.preset === 'minimal') {
exclude = [/node_modules/, /<anonymous>/, ...exclude];
}
return frames.filter((frame) => {
const file = frame.fileName ?? '';
// Apply exclude first
if (exclude.some((r) => (typeof r === 'function' ? r(frame) : r.test(file)))) {
return false;
}
// If include is provided, require at least one match
if (opts.include && opts.include.length > 0) {
const ok = opts.include.some((r) => (typeof r === 'function' ? r(frame) : r.test(file)));
if (!ok)
return false;
}
return true;
});
}