1 | /**
|
2 | * @fileoverview Restrict usage of specified node modules.
|
3 | * @author Christian Schulz
|
4 | */
|
5 | ;
|
6 |
|
7 | //------------------------------------------------------------------------------
|
8 | // Rule Definition
|
9 | //------------------------------------------------------------------------------
|
10 |
|
11 | module.exports = function(context) {
|
12 | // trim restricted module names
|
13 | var restrictedModules = context.options;
|
14 |
|
15 | // if no modules are restricted we don't need to check the CallExpressions
|
16 | if (restrictedModules.length === 0) {
|
17 | return {};
|
18 | }
|
19 |
|
20 | /**
|
21 | * Function to check if a node is a string literal.
|
22 | * @param {ASTNode} node The node to check.
|
23 | * @returns {boolean} If the node is a string literal.
|
24 | */
|
25 | function isString(node) {
|
26 | return node && node.type === "Literal" && typeof node.value === "string";
|
27 | }
|
28 |
|
29 | /**
|
30 | * Function to check if a node is a require call.
|
31 | * @param {ASTNode} node The node to check.
|
32 | * @returns {boolean} If the node is a require call.
|
33 | */
|
34 | function isRequireCall(node) {
|
35 | return node.callee.type === "Identifier" && node.callee.name === "require";
|
36 | }
|
37 |
|
38 | /**
|
39 | * Function to check if a node has an argument that is an restricted module and return its name.
|
40 | * @param {ASTNode} node The node to check
|
41 | * @returns {undefined|String} restricted module name or undefined if node argument isn't restricted.
|
42 | */
|
43 | function getRestrictedModuleName(node) {
|
44 | var moduleName;
|
45 |
|
46 | // node has arguments and first argument is string
|
47 | if (node.arguments.length && isString(node.arguments[0])) {
|
48 | var argumentValue = node.arguments[0].value.trim();
|
49 |
|
50 | // check if argument value is in restricted modules array
|
51 | if (restrictedModules.indexOf(argumentValue) !== -1) {
|
52 | moduleName = argumentValue;
|
53 | }
|
54 | }
|
55 |
|
56 | return moduleName;
|
57 | }
|
58 |
|
59 | return {
|
60 | "CallExpression": function(node) {
|
61 | if (isRequireCall(node)) {
|
62 | var restrictedModuleName = getRestrictedModuleName(node);
|
63 |
|
64 | if (restrictedModuleName) {
|
65 | context.report(node, "'{{moduleName}}' module is restricted from being used.", {
|
66 | moduleName: restrictedModuleName
|
67 | });
|
68 | }
|
69 | }
|
70 | }
|
71 | };
|
72 | };
|
73 |
|
74 | module.exports.schema = {
|
75 | "type": "array",
|
76 | "items": {
|
77 | "type": "string"
|
78 | },
|
79 | "uniqueItems": true
|
80 | };
|