Socket
Socket
Sign inDemoInstall

babel-plugin-jest-hoist

Package Overview
Dependencies
21
Maintainers
3
Versions
187
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 29.6.3 to 30.0.0-alpha.0

build/index.mjs

239

build/index.js

@@ -1,9 +0,23 @@

'use strict';
/*!
* /**
* * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* * This source code is licensed under the MIT license found in the
* * LICENSE file in the root directory of this source tree.
* * /
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;
Object.defineProperty(exports, '__esModule', {
Object.defineProperty(exports, "__esModule", ({
value: true
});
exports.default = jestHoist;
}));
exports["default"] = jestHoist;
function _template() {
const data = require('@babel/template');
const data = require("@babel/template");
_template = function () {

@@ -15,3 +29,3 @@ return data;

function _types() {
const data = require('@babel/types');
const data = require("@babel/types");
_types = function () {

@@ -40,73 +54,10 @@ return data;

// We also allow variables prefixed with `mock` as an escape-hatch.
const ALLOWED_IDENTIFIERS = new Set(
[
'Array',
'ArrayBuffer',
'Boolean',
'BigInt',
'DataView',
'Date',
'Error',
'EvalError',
'Float32Array',
'Float64Array',
'Function',
'Generator',
'GeneratorFunction',
'Infinity',
'Int16Array',
'Int32Array',
'Int8Array',
'InternalError',
'Intl',
'JSON',
'Map',
'Math',
'NaN',
'Number',
'Object',
'Promise',
'Proxy',
'RangeError',
'ReferenceError',
'Reflect',
'RegExp',
'Set',
'String',
'Symbol',
'SyntaxError',
'TypeError',
'URIError',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'WeakMap',
'WeakSet',
'arguments',
'console',
'expect',
'isNaN',
'jest',
'parseFloat',
'parseInt',
'exports',
'require',
'module',
'__filename',
'__dirname',
'undefined',
...Object.getOwnPropertyNames(globalThis)
].sort()
);
const ALLOWED_IDENTIFIERS = new Set(['Array', 'ArrayBuffer', 'Boolean', 'BigInt', 'DataView', 'Date', 'Error', 'EvalError', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'Infinity', 'Int16Array', 'Int32Array', 'Int8Array', 'InternalError', 'Intl', 'JSON', 'Map', 'Math', 'NaN', 'Number', 'Object', 'Promise', 'Proxy', 'RangeError', 'ReferenceError', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'SyntaxError', 'TypeError', 'URIError', 'Uint16Array', 'Uint32Array', 'Uint8Array', 'Uint8ClampedArray', 'WeakMap', 'WeakSet', 'arguments', 'console', 'expect', 'isNaN', 'jest', 'parseFloat', 'parseInt', 'exports', 'require', 'module', '__filename', '__dirname', 'undefined', ...Object.getOwnPropertyNames(globalThis)].sort());
const IDVisitor = {
ReferencedIdentifier(path, {ids}) {
ReferencedIdentifier(path, {
ids
}) {
ids.add(path);
},
blacklist: [
'TypeAnnotation',
'TSTypeAnnotation',
'TSTypeQuery',
'TSTypeReference'
]
denylist: ['TypeAnnotation', 'TSTypeAnnotation', 'TSTypeQuery', 'TSTypeReference']
};

@@ -120,10 +71,7 @@ const FUNCTIONS = Object.create(null);

if (!moduleFactory.isFunction()) {
throw moduleFactory.buildCodeFrameError(
'The second argument of `jest.mock` must be an inline function.\n',
TypeError
);
throw moduleFactory.buildCodeFrameError('The second argument of `jest.mock` must be an inline function.\n', TypeError);
}
const ids = new Set();
const parentScope = moduleFactory.parentPath.scope;
// @ts-expect-error: ReferencedIdentifier and blacklist are not known on visitors
// @ts-expect-error: ReferencedIdentifier and denylist are not known on visitors
moduleFactory.traverse(IDVisitor, {

@@ -133,3 +81,5 @@ ids

for (const id of ids) {
const {name} = id.node;
const {
name
} = id.node;
let found = false;

@@ -145,11 +95,11 @@ let scope = id.scope;

if (!found) {
let isAllowedIdentifier =
(scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name)) ||
/^mock/i.test(name) ||
// Allow istanbul's coverage variable to pass.
/^(?:__)?cov/.test(name);
let isAllowedIdentifier = scope.hasGlobal(name) && ALLOWED_IDENTIFIERS.has(name) || /^mock/i.test(name) ||
// Allow istanbul's coverage variable to pass.
/^(?:__)?cov/.test(name);
if (!isAllowedIdentifier) {
const binding = scope.bindings[name];
if (binding?.path.isVariableDeclarator()) {
const {node} = binding.path;
const {
node
} = binding.path;
const initNode = node.init;

@@ -163,8 +113,3 @@ if (initNode && binding.constant && scope.isPure(initNode, true)) {

const imported = binding.path.node.imported;
if (
importDecl.node.source.value === JEST_GLOBALS_MODULE_NAME &&
((0, _types().isIdentifier)(imported)
? imported.name
: imported.value) === JEST_GLOBALS_MODULE_JEST_EXPORT_NAME
) {
if (importDecl.node.source.value === JEST_GLOBALS_MODULE_NAME && ((0, _types().isIdentifier)(imported) ? imported.name : imported.value) === JEST_GLOBALS_MODULE_JEST_EXPORT_NAME) {
isAllowedIdentifier = true;

@@ -178,14 +123,3 @@ // Imports are already hoisted, so we don't need to add it

if (!isAllowedIdentifier) {
throw id.buildCodeFrameError(
'The module factory of `jest.mock()` is not allowed to ' +
'reference any out-of-scope variables.\n' +
`Invalid variable access: ${name}\n` +
`Allowed objects: ${Array.from(ALLOWED_IDENTIFIERS).join(
', '
)}.\n` +
'Note: This is a precaution to guard against uninitialized mock ' +
'variables. If it is ensured that the mock is required lazily, ' +
'variable names prefixed with `mock` (case insensitive) are permitted.\n',
ReferenceError
);
throw id.buildCodeFrameError('The module factory of `jest.mock()` is not allowed to ' + 'reference any out-of-scope variables.\n' + `Invalid variable access: ${name}\n` + `Allowed objects: ${Array.from(ALLOWED_IDENTIFIERS).join(', ')}.\n` + 'Note: This is a precaution to guard against uninitialized mock ' + 'variables. If it is ensured that the mock is required lazily, ' + 'variable names prefixed with `mock` (case insensitive) are permitted.\n', ReferenceError);
}

@@ -200,4 +134,3 @@ }

FUNCTIONS.deepUnmock = args => args.length === 1 && args[0].isStringLiteral();
FUNCTIONS.disableAutomock = FUNCTIONS.enableAutomock = args =>
args.length === 0;
FUNCTIONS.disableAutomock = FUNCTIONS.enableAutomock = args => args.length === 0;
const createJestObjectGetter = (0, _template().statement)`

@@ -212,26 +145,11 @@ function GETTER_NAME() {

// global
if (
expression.isIdentifier() &&
expression.node.name === JEST_GLOBAL_NAME &&
!expression.scope.hasBinding(JEST_GLOBAL_NAME)
) {
if (expression.isIdentifier() && expression.node.name === JEST_GLOBAL_NAME && !expression.scope.hasBinding(JEST_GLOBAL_NAME)) {
return true;
}
// import { jest } from '@jest/globals'
if (
expression.referencesImport(
JEST_GLOBALS_MODULE_NAME,
JEST_GLOBALS_MODULE_JEST_EXPORT_NAME
)
) {
if (expression.referencesImport(JEST_GLOBALS_MODULE_NAME, JEST_GLOBALS_MODULE_JEST_EXPORT_NAME)) {
return true;
}
// import * as JestGlobals from '@jest/globals'
if (
expression.isMemberExpression() &&
!expression.node.computed &&
expression.get('object').referencesImport(JEST_GLOBALS_MODULE_NAME, '*') &&
expression.node.property.type === 'Identifier' &&
expression.node.property.name === JEST_GLOBALS_MODULE_JEST_EXPORT_NAME
) {
if (expression.isMemberExpression() && !expression.node.computed && expression.get('object').referencesImport(JEST_GLOBALS_MODULE_NAME, '*') && expression.node.property.type === 'Identifier' && expression.node.property.name === JEST_GLOBALS_MODULE_JEST_EXPORT_NAME) {
return true;

@@ -253,6 +171,5 @@ }

const propertyName = property.node.name;
const jestObjExpr = isJestObject(object)
? object
: // The Jest object could be returned from another call since the functions are all chainable.
extractJestObjExprIfHoistable(object)?.path;
const jestObjExpr = isJestObject(object) ? object :
// The Jest object could be returned from another call since the functions are all chainable.
extractJestObjExprIfHoistable(object)?.path;
if (!jestObjExpr) {

@@ -267,12 +184,7 @@ return null;

let functionHasHoistableScope = functionIsHoistable;
for (
let path = expr;
path && !functionHasHoistableScope;
path = path.parentPath
) {
for (let path = expr; path && !functionHasHoistableScope; path = path.parentPath) {
functionHasHoistableScope = hoistedJestExpressions.has(
// @ts-expect-error: it's ok if path.node is not an Expression, .has will
// just return false.
path.node
);
// @ts-expect-error: it's ok if path.node is not an Expression, .has will
// just return false.
path.node);
}

@@ -292,3 +204,5 @@ if (functionHasHoistableScope) {

return {
pre({path: program}) {
pre({
path: program
}) {
this.declareJestObjGetterIdentifier = () => {

@@ -298,11 +212,8 @@ if (this.jestObjGetterIdentifier) {

}
this.jestObjGetterIdentifier =
program.scope.generateUidIdentifier('getJestObj');
program.unshiftContainer('body', [
createJestObjectGetter({
GETTER_NAME: this.jestObjGetterIdentifier.name,
JEST_GLOBALS_MODULE_JEST_EXPORT_NAME,
JEST_GLOBALS_MODULE_NAME
})
]);
this.jestObjGetterIdentifier = program.scope.generateUidIdentifier('getJestObj');
program.unshiftContainer('body', [createJestObjectGetter({
GETTER_NAME: this.jestObjGetterIdentifier.name,
JEST_GLOBALS_MODULE_JEST_EXPORT_NAME,
JEST_GLOBALS_MODULE_NAME
})]);
return this.jestObjGetterIdentifier;

@@ -313,10 +224,5 @@ };

ExpressionStatement(exprStmt) {
const jestObjInfo = extractJestObjExprIfHoistable(
exprStmt.get('expression')
);
const jestObjInfo = extractJestObjExprIfHoistable(exprStmt.get('expression'));
if (jestObjInfo) {
const jestCallExpr = (0, _types().callExpression)(
this.declareJestObjGetterIdentifier(),
[]
);
const jestCallExpr = (0, _types().callExpression)(this.declareJestObjGetterIdentifier(), []);
jestObjInfo.path.replaceWith(jestCallExpr);

@@ -330,3 +236,5 @@ if (jestObjInfo.hoist) {

// in `post` to make sure we come after an import transform and can unshift above the `require`s
post({path: program}) {
post({
path: program
}) {
visitBlock(program);

@@ -338,6 +246,3 @@ program.traverse({

// use a temporary empty statement instead of the real first statement, which may itself be hoisted
const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer(
'body',
[(0, _types().emptyStatement)(), (0, _types().emptyStatement)()]
);
const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer('body', [(0, _types().emptyStatement)(), (0, _types().emptyStatement)()]);
block.traverse({

@@ -347,3 +252,3 @@ CallExpression: visitCallExpr,

// do not traverse into nested blocks, or we'll hoist calls in there out to this block
blacklist: ['BlockStatement']
denylist: ['BlockStatement']
});

@@ -369,3 +274,6 @@ callsHoistPoint.remove();

varDecl.parentPath.assertVariableDeclaration();
const {kind, declarations} = varDecl.parent;
const {
kind,
declarations
} = varDecl.parent;
if (declarations.length === 1) {

@@ -376,5 +284,3 @@ varDecl.parentPath.remove();

}
varsHoistPoint.insertBefore(
(0, _types().variableDeclaration)(kind, [varDecl.node])
);
varsHoistPoint.insertBefore((0, _types().variableDeclaration)(kind, [varDecl.node]));
}

@@ -387,1 +293,6 @@ }

/* eslint-enable */
})();
module.exports = __webpack_exports__;
/******/ })()
;
{
"name": "babel-plugin-jest-hoist",
"version": "29.6.3",
"version": "30.0.0-alpha.0",
"repository": {

@@ -10,3 +10,3 @@ "type": "git",

"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
"node": "^16.10.0 || ^18.12.0 || >=20.0.0"
},

@@ -19,2 +19,4 @@ "license": "MIT",

"types": "./build/index.d.ts",
"require": "./build/index.js",
"import": "./build/index.mjs",
"default": "./build/index.js"

@@ -34,2 +36,3 @@ },

"@babel/preset-typescript": "^7.0.0",
"@prettier/sync": "^0.3.0",
"@types/babel__template": "^7.0.2",

@@ -39,3 +42,3 @@ "@types/node": "*",

"babel-plugin-tester": "^11.0.2",
"prettier": "^2.1.1"
"prettier": "^3.0.3"
},

@@ -45,3 +48,3 @@ "publishConfig": {

},
"gitHead": "fb7d95c8af6e0d65a8b65348433d8a0ea0725b5b"
"gitHead": "780ae28333df4d188b2ef78bd19d4ed5bc53562d"
}
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc