basant307/AI_Governance_Project
045
1'use strict';2 3exports.__esModule = true;4 5/** @typedef {import('estree').Node} Node */6/** @typedef {{ arguments: import('estree').CallExpression['arguments'], callee: Node }} Call */7/** @typedef {import('estree').ImportDeclaration | import('estree').ExportNamedDeclaration | import('estree').ExportAllDeclaration} Declaration */8 9/**10 * Returns an object of node visitors that will call11 * 'visitor' with every discovered module path.12 *13 * @type {(import('./moduleVisitor').default)}14 */15exports.default = function visitModules(visitor, options) {16 const ignore = options && options.ignore;17 const amd = !!(options && options.amd);18 const commonjs = !!(options && options.commonjs);19 // if esmodule is not explicitly disabled, it is assumed to be enabled20 const esmodule = !!Object.assign({ esmodule: true }, options).esmodule;21 22 const ignoreRegExps = ignore == null ? [] : ignore.map((p) => new RegExp(p));23 24 /** @type {(source: undefined | null | import('estree').Literal, importer: Parameters<typeof visitor>[1]) => void} */25 function checkSourceValue(source, importer) {26 if (source == null) { return; } //?27 28 // handle ignore29 if (ignoreRegExps.some((re) => re.test(String(source.value)))) { return; }30 31 // fire visitor32 visitor(source, importer);33 }34 35 // for import-y declarations36 /** @type {(node: Declaration) => void} */37 function checkSource(node) {38 checkSourceValue(node.source, node);39 }40 41 // for esmodule dynamic `import()` calls42 /** @type {(node: import('estree').ImportExpression | import('estree').CallExpression) => void} */43 function checkImportCall(node) {44 /** @type {import('estree').Expression | import('estree').Literal | import('estree').CallExpression['arguments'][0]} */45 let modulePath;46 // refs https://github.com/estree/estree/blob/HEAD/es2020.md#importexpression47 if (node.type === 'ImportExpression') {48 modulePath = node.source;49 } else if (node.type === 'CallExpression') {50 // @ts-expect-error this structure is from an older version of eslint51 if (node.callee.type !== 'Import') { return; }52 if (node.arguments.length !== 1) { return; }53 54 modulePath = node.arguments[0];55 } else {56 throw new TypeError('this should be unreachable');57 }58 59 if (modulePath.type !== 'Literal') { return; }60 if (typeof modulePath.value !== 'string') { return; }61 62 checkSourceValue(modulePath, node);63 }64 65 // for CommonJS `require` calls66 // adapted from @mctep: https://git.io/v4rAu67 /** @type {(call: Call) => void} */68 function checkCommon(call) {69 if (call.callee.type !== 'Identifier') { return; }70 if (call.callee.name !== 'require') { return; }71 if (call.arguments.length !== 1) { return; }72 73 const modulePath = call.arguments[0];74 if (modulePath.type !== 'Literal') { return; }75 if (typeof modulePath.value !== 'string') { return; }76 77 checkSourceValue(modulePath, call);78 }79 80 /** @type {(call: Call) => void} */81 function checkAMD(call) {82 if (call.callee.type !== 'Identifier') { return; }83 if (call.callee.name !== 'require' && call.callee.name !== 'define') { return; }84 if (call.arguments.length !== 2) { return; }85 86 const modules = call.arguments[0];87 if (modules.type !== 'ArrayExpression') { return; }88 89 for (const element of modules.elements) {90 if (!element) { continue; }91 if (element.type !== 'Literal') { continue; }92 if (typeof element.value !== 'string') { continue; }93 94 if (95 element.value === 'require'96 || element.value === 'exports'97 ) {98 continue; // magic modules: https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#magic-modules99 }100 101 checkSourceValue(element, element);102 }103 }104 105 const visitors = {};106 if (esmodule) {107 Object.assign(visitors, {108 ImportDeclaration: checkSource,109 ExportNamedDeclaration: checkSource,110 ExportAllDeclaration: checkSource,111 CallExpression: checkImportCall,112 ImportExpression: checkImportCall,113 });114 }115 116 if (commonjs || amd) {117 const currentCallExpression = visitors.CallExpression;118 visitors.CallExpression = /** @type {(call: Call) => void} */ function (call) {119 if (currentCallExpression) { currentCallExpression(call); }120 if (commonjs) { checkCommon(call); }121 if (amd) { checkAMD(call); }122 };123 }124 125 return visitors;126};127 128/**129 * make an options schema for the module visitor, optionally adding extra fields.130 * @type {import('./moduleVisitor').makeOptionsSchema}131 */132function makeOptionsSchema(additionalProperties) {133 /** @type {import('./moduleVisitor').Schema} */134 const base = {135 type: 'object',136 properties: {137 commonjs: { type: 'boolean' },138 amd: { type: 'boolean' },139 esmodule: { type: 'boolean' },140 ignore: {141 type: 'array',142 minItems: 1,143 items: { type: 'string' },144 uniqueItems: true,145 },146 },147 additionalProperties: false,148 };149 150 if (additionalProperties) {151 for (const key in additionalProperties) {152 // @ts-expect-error TS always has trouble with arbitrary object assignment/mutation153 base.properties[key] = additionalProperties[key];154 }155 }156 157 return base;158}159exports.makeOptionsSchema = makeOptionsSchema;160 161/**162 * json schema object for options parameter. can be used to build rule options schema object.163 */164exports.optionsSchema = makeOptionsSchema();165 