| 'use strict'; |
| exports.__esModule = true; |
| |
| /** |
| * Returns an object of node visitors that will call |
| * 'visitor' with every discovered module path. |
| * |
| * todo: correct function prototype for visitor |
| * @param {Function(String)} visitor [description] |
| * @param {[type]} options [description] |
| * @return {object} |
| */ |
| exports.default = function visitModules(visitor, options) { |
| // if esmodule is not explicitly disabled, it is assumed to be enabled |
| options = Object.assign({ esmodule: true }, options); |
| |
| let ignoreRegExps = []; |
| if (options.ignore != null) { |
| ignoreRegExps = options.ignore.map(p => new RegExp(p)); |
| } |
| |
| function checkSourceValue(source, importer) { |
| if (source == null) return; //? |
| |
| // handle ignore |
| if (ignoreRegExps.some(re => re.test(source.value))) return; |
| |
| // fire visitor |
| visitor(source, importer); |
| } |
| |
| // for import-y declarations |
| function checkSource(node) { |
| checkSourceValue(node.source, node); |
| } |
| |
| // for esmodule dynamic `import()` calls |
| function checkImportCall(node) { |
| let modulePath; |
| // refs https://github.com/estree/estree/blob/HEAD/es2020.md#importexpression |
| if (node.type === 'ImportExpression') { |
| modulePath = node.source; |
| } else if (node.type === 'CallExpression') { |
| if (node.callee.type !== 'Import') return; |
| if (node.arguments.length !== 1) return; |
| |
| modulePath = node.arguments[0]; |
| } |
| |
| if (modulePath.type !== 'Literal') return; |
| if (typeof modulePath.value !== 'string') return; |
| |
| checkSourceValue(modulePath, node); |
| } |
| |
| // for CommonJS `require` calls |
| // adapted from @mctep: https://git.io/v4rAu |
| function checkCommon(call) { |
| if (call.callee.type !== 'Identifier') return; |
| if (call.callee.name !== 'require') return; |
| if (call.arguments.length !== 1) return; |
| |
| const modulePath = call.arguments[0]; |
| if (modulePath.type !== 'Literal') return; |
| if (typeof modulePath.value !== 'string') return; |
| |
| checkSourceValue(modulePath, call); |
| } |
| |
| function checkAMD(call) { |
| if (call.callee.type !== 'Identifier') return; |
| if (call.callee.name !== 'require' && |
| call.callee.name !== 'define') return; |
| if (call.arguments.length !== 2) return; |
| |
| const modules = call.arguments[0]; |
| if (modules.type !== 'ArrayExpression') return; |
| |
| for (const element of modules.elements) { |
| if (element.type !== 'Literal') continue; |
| if (typeof element.value !== 'string') continue; |
| |
| if (element.value === 'require' || |
| element.value === 'exports') continue; // magic modules: https://git.io/vByan |
| |
| checkSourceValue(element, element); |
| } |
| } |
| |
| const visitors = {}; |
| if (options.esmodule) { |
| Object.assign(visitors, { |
| 'ImportDeclaration': checkSource, |
| 'ExportNamedDeclaration': checkSource, |
| 'ExportAllDeclaration': checkSource, |
| 'CallExpression': checkImportCall, |
| 'ImportExpression': checkImportCall, |
| }); |
| } |
| |
| if (options.commonjs || options.amd) { |
| const currentCallExpression = visitors['CallExpression']; |
| visitors['CallExpression'] = function (call) { |
| if (currentCallExpression) currentCallExpression(call); |
| if (options.commonjs) checkCommon(call); |
| if (options.amd) checkAMD(call); |
| }; |
| } |
| |
| return visitors; |
| }; |
| |
| /** |
| * make an options schema for the module visitor, optionally |
| * adding extra fields. |
| */ |
| function makeOptionsSchema(additionalProperties) { |
| const base = { |
| 'type': 'object', |
| 'properties': { |
| 'commonjs': { 'type': 'boolean' }, |
| 'amd': { 'type': 'boolean' }, |
| 'esmodule': { 'type': 'boolean' }, |
| 'ignore': { |
| 'type': 'array', |
| 'minItems': 1, |
| 'items': { 'type': 'string' }, |
| 'uniqueItems': true, |
| }, |
| }, |
| 'additionalProperties': false, |
| }; |
| |
| if (additionalProperties) { |
| for (const key in additionalProperties) { |
| base.properties[key] = additionalProperties[key]; |
| } |
| } |
| |
| return base; |
| } |
| exports.makeOptionsSchema = makeOptionsSchema; |
| |
| /** |
| * json schema object for options parameter. can be used to build |
| * rule options schema object. |
| * @type {Object} |
| */ |
| exports.optionsSchema = makeOptionsSchema(); |