Socket
Socket
Sign inDemoInstall

@contrast/agentify

Package Overview
Dependencies
Maintainers
9
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@contrast/agentify - npm Package Compare versions

Comparing version 1.24.0 to 1.24.1

lib/utils.js

93

lib/function-hooks.js

@@ -21,5 +21,46 @@ /*

const IS_RETURN_REGEX = /^return\W/;
const METHOD_CONTEXT = 'function _contrast_';
const FUNCTION_CONTEXT = 'const _contrast_fn = ';
const FUNCTION_DECL = 'function _contrast_';
const VARIABLE_DECL = 'const _contrast_fn = ';
/**
* Injects some context around a function's toString() to make it syntactically
* valid. The `swc` parser expects input to be a valid `Statement` like one of
* the following:
* ```js
* // (named) function declaration
* function f() {}
* // (named) class declaration
* class C {}
* // variable declaration with an (anonymous?) class or function expression
* const _contrast_fn = function () {};
* const _contrast_fn = () => {};
* const _contrast_fn = class {};
* ```
* @param {string} code original toString() return value
* @returns {string} the contextualized statement
*/
function contextualize(code) {
// in case the class is anonymous we need to prepend a variable declaration.
if (IS_CLASS_REGEX.exec(code)) {
return `${VARIABLE_DECL}${code}`;
}
// if the function is a return, we don't need to add context.
if (!IS_RETURN_REGEX.exec(code)) {
const [orig] = code.split('{');
let lineOne = orig;
// When stringified, class methods look like normal function without the
// `function` keyword. We can normalize this by prepending `function`.
if (!IS_FUNCTION_REGEX.exec(lineOne) && lineOne.indexOf('=>') === -1) {
lineOne = `${FUNCTION_DECL}${lineOne}`;
}
lineOne = `${VARIABLE_DECL}${lineOne}`;
code = code.replace(orig, lineOne);
}
return code;
}
module.exports = function (deps) {

@@ -41,46 +82,14 @@ const {

/**
* Create some code context around a function to make it syntactically valid
* the three general types of syntactic function definitions are:
* - functions (declared with the function keyword)
* - arrow functions
* - class methods
* @param {string} code the user code
* @returns {string} the contextualized function
*/
functionHooks.contextualizeFunction = (code) => {
// Classes themselves are functions, so we need to exit early to avoid
// clobbering the `class` keyword.
if (IS_CLASS_REGEX.exec(code)) return code;
const [orig] = code.split('{');
let lineOne = orig;
// if the function is a return, we don't need to add context.
if (!IS_RETURN_REGEX.exec(lineOne)) {
// When stringified, class methods look like normal function without the
// `function` keyword. We can normalize this by prepending `function`.
if (!IS_FUNCTION_REGEX.exec(lineOne) && lineOne.indexOf('=>') === -1) {
lineOne = `${METHOD_CONTEXT}${lineOne}`;
}
lineOne = `${FUNCTION_CONTEXT}${lineOne}`;
code = code.replace(orig, lineOne);
}
return code;
};
/**
* Returns the rewritten function code. If an error occurs during rewriting,
* we log the error and code information and return the original code string.
* @param {string} code string value of the JavaScript function
* @returns {string} the code rewritten to remove Contrast tokens
* @param {string} code original toString() return value
* @returns {string} the code rewritten to remove Contrast tokens
*/
functionHooks.unwrite = function (code) {
function unwrite(code) {
// cannot parse lone function expressions that are not part of an assignment.
try {
let unwritten = functionHooks.contextualizeFunction(code);
let unwritten = contextualize(code);
unwritten = rewriter.unwriteSync(unwritten);
unwritten = unwritten.replace(METHOD_CONTEXT, '');
unwritten = unwritten.replace(FUNCTION_CONTEXT, '');
unwritten = unwritten.replace(FUNCTION_DECL, '');
unwritten = unwritten.replace(VARIABLE_DECL, '');
unwritten = unwritten.replace(/;\s*$/, ''); // removes trailing semicolon/whitespace

@@ -92,3 +101,3 @@ return unwritten;

}
};
}

@@ -119,3 +128,3 @@ functionHooks.install = function () {

if (code.indexOf('ContrastMethods') > -1) {
const unwritten = functionHooks.unwrite(code);
const unwritten = unwrite(code);
functionHooks.cache.set(data.obj, unwritten);

@@ -122,0 +131,0 @@ result = unwritten;

@@ -20,2 +20,6 @@ /*

const { IntentionalError } = require('@contrast/common');
const {
assertValidOpts,
preStartupValidation
} = require('./utils');

@@ -65,2 +69,5 @@ const ERROR_MESSAGE = 'An error prevented the Contrast agent from installing. The application will be run without instrumentation.';

core.agentify = async function agentify(callback, opts = {}) {
// options are hardcoded, so if this throws it's going to be in testing/dev situation
assertValidOpts(opts);
_callback = callback;

@@ -129,2 +136,5 @@ _opts = opts;

try {
// check supported Node version and correct preload usage before anything else
preStartupValidation(core);
require('@contrast/core/lib/messages')(core);

@@ -137,3 +147,3 @@ require('@contrast/config')(core);

const errorMessage = 'Contrast agent disabled by configuration (enable: false)';
console.log(errorMessage);
console.info(errorMessage);
throw new IntentionalError(errorMessage);

@@ -179,3 +189,4 @@ }

} else {
console.error(new Error(ERROR_MESSAGE, { cause: err }));
console.error(err);
console.error(ERROR_MESSAGE);
}

@@ -182,0 +193,0 @@ }

{
"name": "@contrast/agentify",
"version": "1.24.0",
"version": "1.24.1",
"description": "Configures Contrast agent services and instrumentation within an application",

@@ -14,3 +14,3 @@ "license": "SEE LICENSE IN LICENSE",

"npm": ">=6.13.7 <7 || >= 8.3.1",
"node": ">= 14.15.0"
"node": ">= 14.18.0"
},

@@ -21,16 +21,18 @@ "scripts": {

"dependencies": {
"@contrast/common": "1.20.0",
"@contrast/config": "1.27.0",
"@contrast/core": "1.31.0",
"@contrast/deadzones": "1.1.2",
"@contrast/dep-hooks": "1.3.1",
"@contrast/esm-hooks": "2.5.0",
"@contrast/instrumentation": "1.7.0",
"@contrast/logger": "1.8.0",
"@contrast/metrics": "1.7.0",
"@contrast/patcher": "1.7.1",
"@contrast/reporter": "1.26.0",
"@contrast/rewriter": "1.7.0",
"@contrast/scopes": "1.4.0"
"@contrast/common": "1.20.1",
"@contrast/config": "1.27.1",
"@contrast/core": "1.31.1",
"@contrast/deadzones": "1.1.3",
"@contrast/dep-hooks": "1.3.2",
"@contrast/esm-hooks": "2.5.1",
"@contrast/find-package-json": "^1.1.0",
"@contrast/instrumentation": "1.7.1",
"@contrast/logger": "1.8.1",
"@contrast/metrics": "1.7.1",
"@contrast/patcher": "1.7.2",
"@contrast/reporter": "1.26.1",
"@contrast/rewriter": "1.7.1",
"@contrast/scopes": "1.4.1",
"semver": "^7.6.0"
}
}
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