Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@contrast/core

Package Overview
Dependencies
Maintainers
9
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@contrast/core - npm Package Compare versions

Comparing version 1.31.1 to 1.31.2

145

lib/capture-stacktrace.js

@@ -15,3 +15,3 @@ /*

*/
// @ts-check
'use strict';

@@ -22,2 +22,5 @@

/** @typedef {import('.').Frame} Frame */
/** @typedef {import('.').CreateSnapshotOpts} CreateSnapshotOpts */
const EVAL_ORIGIN_REGEX = /\((.*?):(\d+):\d+\)/;

@@ -33,8 +36,10 @@

core.captureStacktrace = function(...args) {
return stacktraceFactory.captureStacktrace(...args);
/** @type {StacktraceFactory['captureStacktrace']} */
core.captureStacktrace = function (obj, opts, key) {
return stacktraceFactory.captureStacktrace(obj, opts, key);
};
core.createSnapshot = function(...args) {
return stacktraceFactory.createSnapshot(...args);
/** @type {StacktraceFactory['createSnapshot']} */
core.createSnapshot = function (opts) {
return stacktraceFactory.createSnapshot(opts);
};

@@ -45,8 +50,9 @@

/**
* The factory will set stacktrace limit for stackframe lists created by it.
* @param {number} stackTraceLimit set the stack trace limit
* @param {function} isAgentPath function indicating if path is agent code
*/
class StacktraceFactory {
/**
* The factory will set stacktrace limit for stackframe lists created by it.
* @param {Object} opts
* @param {number} opts.stackTraceLimit set the stack trace limit
* @param {(path: string) => boolean} opts.isAgentPath function indicating if path is agent code
*/
constructor({ stackTraceLimit, isAgentPath }) {

@@ -57,2 +63,9 @@ this.stackTraceLimit = stackTraceLimit;

/**
* @template T
* @param {T} obj
* @param {CreateSnapshotOpts} opts
* @param {string} key
* @returns {T}
*/
captureStacktrace(obj, opts, key = 'stack') {

@@ -80,50 +93,60 @@ let stack;

/**
* @param {Frame} frame
* @returns {boolean}
*/
shouldAppendFrame(frame) {
return (
!!frame.file &&
!this.isAgentPath(frame.file) &&
!`${frame.type}${frame.method}`.includes('ContrastMethods')
);
}
/**
* Creates a function that will build a stacktrace when invoked. It will keep
* an error in a closure whose stack will be generated and processed when the
* returned function executes. The result will be cached.
* @param {object} params
* @param {function} params.limitFn The constructorOpt param used when creating stack
* @returns {function}
* @param {CreateSnapshotOpts} params
* @returns {() => Frame[]}
*/
createSnapshot({ constructorOpt, prependFrames } = {}) {
const { isAgentPath } = this;
const target = {};
this.appendStackGetter(target, constructorOpt);
let ret;
let frames;
/**
* Generates array of frames from `target`'s `stack` getter
* @returns {array}
* @returns {Frame[]}
*/
function snapshot() {
if (!ret) {
const callsites = StacktraceFactory.generateCallsites(target);
/* eslint-disable complexity */
ret = (callsites || []).reduce((acc, callsite) => {
if (StacktraceFactory.isCallsiteValid(callsite)) {
const frame = StacktraceFactory.makeFrame(callsite);
if (
frame.file &&
!`${frame.type}${frame.method}`.includes('ContrastMethods')
) {
if (!isAgentPath(frame.file)) {
const snapshot = () => {
if (!frames) {
// @ts-expect-error target has had a stack getter appended above.
const callsites = StacktraceFactory.generateCallsites(target) ?? [];
frames = callsites.reduce(
/**
* @param {Frame[]} acc
* @param {NodeJS.CallSite} callsite
*/
(acc, callsite) => {
if (StacktraceFactory.isCallsiteValid(callsite)) {
const frame = StacktraceFactory.makeFrame(callsite);
if (this.shouldAppendFrame(frame)) {
acc.push(frame);
}
}
}
return acc;
}, []);
return acc;
},
[],
);
}
if (!prependFrames) return ret;
if (!prependFrames) return frames;
return [
...prependFrames.map((f) => (typeof f == 'function' ? fnInspect.funcInfo(f) : f)),
...ret
...frames,
];
}
};

@@ -135,12 +158,16 @@ return snapshot;

* Based on stacktrace limit and constructor opt, will append a stack getter
* @param {} error
* @param {} limitFn
* @param {any} obj
* @param {Function=} constructorOpt
*/
appendStackGetter(error, constructorOpt) {
appendStackGetter(obj, constructorOpt) {
const { stackTraceLimit } = Error;
Error.stackTraceLimit = this.stackTraceLimit;
Error.captureStackTrace(error, constructorOpt);
Error.captureStackTrace(obj, constructorOpt);
Error.stackTraceLimit = stackTraceLimit;
}
/**
* @param {any} callsite
* @returns {boolean}
*/
static isCallsiteValid(callsite) {

@@ -152,16 +179,28 @@ return callsite instanceof Callsite;

* Creates an array frame objects from an array of Callsite instances
* @param {} callsite
* @returns {}
* @param {NodeJS.CallSite} callsite
* @returns {Frame}
*/
static makeFrame(callsite) {
let evalOrigin, file, lineNumber, method, type;
/** @type {string | undefined} */
let evalOrigin;
/** @type {string | undefined} */
let file;
/** @type {number | null} */
let lineNumber = null;
/** @type {string | null} */
let method = null;
/** @type {string | null} */
let type;
if (callsite.isEval()) {
evalOrigin = StacktraceFactory.formatFileName(callsite.getEvalOrigin());
[, file, lineNumber] = evalOrigin.match(EVAL_ORIGIN_REGEX) || evalOrigin.endsWith('.ejs');
const matches = EVAL_ORIGIN_REGEX.exec(evalOrigin);
if (matches) {
file = matches[1];
lineNumber = parseInt(matches[2]);
}
}
file = file || callsite.getFileName();
lineNumber = lineNumber || callsite.getLineNumber();
file = file ?? callsite.getFileName();
lineNumber = lineNumber ?? callsite.getLineNumber();
method = callsite.getFunctionName();

@@ -178,2 +217,6 @@ type = callsite.getTypeName();

/**
* @param {string} fileName
* @returns {string}
*/
static formatFileName(fileName = '') {

@@ -193,11 +236,11 @@ const cwd = `${process.cwd()}/`;

* using an ephemeral monkey patch.
* @param {object} error object with a `stack` getter property
* @returns {}
* @param {Error} error object with a `stack` getter property
* @returns {NodeJS.CallSite[]}
*/
static generateCallsites(error) {
let callsites;
let callsites = [];
const { prepareStackTrace } = Error;
Error.prepareStackTrace = function(_, _callsites) {
Error.prepareStackTrace = function contrastPrepareStackTrace(_, _callsites) {
callsites = _callsites;

@@ -204,0 +247,0 @@ return _callsites;

@@ -18,2 +18,16 @@ /*

interface Frame {
eval: string | undefined;
file: string | undefined;
lineNumber: number | null;
method: string | null;
type: string | null;
}
/* eslint-disable @typescript-eslint/ban-types */
interface CreateSnapshotOpts {
constructorOpt?: Function;
prependFrames?: (Function | Frame)[];
}
export interface Core {

@@ -25,4 +39,4 @@ agentName: string;

captureStackTrace(...args: any[]): any;
captureSnapshot(...args: any[]): any;
captureStackTrace<T>(obj: T, opts: CreateSnapshotOpts, key: string): T;
createSnapshot(opts?: CreateSnapshotOpts): () => Frame[];

@@ -29,0 +43,0 @@ isAgentPath(path: string): boolean;

@@ -15,7 +15,4 @@ /*

*/
'use strict';
/**
*/
module.exports = function(core) {

@@ -25,2 +22,5 @@ const { config } = core;

/**
* Returns true if the provided path matches any of the configured filters.
* @param {string} path
* @returns {boolean}
*/

@@ -27,0 +27,0 @@ function isAgentPath(path) {

{
"name": "@contrast/core",
"version": "1.31.1",
"version": "1.31.2",
"description": "Preconfigured Contrast agent core services and models",

@@ -5,0 +5,0 @@ "license": "SEE LICENSE IN LICENSE",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc