eslint-plugin-restrict-replace-import 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ root: true,
5
+ extends: [
6
+ "eslint:recommended",
7
+ "plugin:eslint-plugin/recommended",
8
+ "plugin:node/recommended",
9
+ ],
10
+ env: {
11
+ node: true,
12
+ },
13
+ overrides: [
14
+ {
15
+ files: ["tests/**/*.js"],
16
+ env: { mocha: true },
17
+ },
18
+ ],
19
+ };
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # eslint-plugin-restrict-replace-import
2
+
3
+ ESLint Plugin for Restricting and Replacing Import.
4
+
5
+ Automatically fixable with replacement package!
6
+
7
+ ## Installation
8
+
9
+ You'll first need to install [ESLint](https://eslint.org/):
10
+
11
+ ```sh
12
+ npm i eslint --save-dev
13
+ ```
14
+
15
+ Next, install `eslint-plugin-restrict-replace-import`:
16
+
17
+ ```sh
18
+ npm install eslint-plugin-restrict-replace-import --save-dev
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Add `restrict-import` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
24
+
25
+ ```json
26
+ {
27
+ "plugins": ["restrict-import"]
28
+ }
29
+ ```
30
+
31
+ Then configure the rules you want to use under the rules section.
32
+
33
+ ```json
34
+ {
35
+ "rules": {
36
+ "restrict-import/rule-name": [
37
+ "error",
38
+ ["restricted-package1", "restricted-package2"]
39
+ ]
40
+ }
41
+ }
42
+ ```
43
+
44
+ You can also specify an alternative package to import instead:
45
+
46
+ ```json
47
+ {
48
+ "rules": {
49
+ "restrict-import/rule-name": [
50
+ "error",
51
+ [
52
+ {
53
+ "name": "restricted-package1",
54
+ "alternative": "replacement-package1"
55
+ },
56
+ {
57
+ "name": "restricted-package2",
58
+ "alternative": "replacement-package2"
59
+ }
60
+ ]
61
+ ]
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Rules
67
+
68
+ <!-- begin auto-generated rules list -->
69
+
70
+ 🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
71
+
72
+ | Name | Description | 🔧 |
73
+ | :----------------------------------------------- | :--------------------------------------- | :-- |
74
+ | [restrict-import](docs/rules/restrict-import.md) | Prevent the Import of a Specific Package | 🔧 |
75
+
76
+ <!-- end auto-generated rules list -->
@@ -0,0 +1,71 @@
1
+ # Prevent the Import of a Specific Package (`restrict-import/restrict-import`)
2
+
3
+ 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4
+
5
+ <!-- end auto-generated rule header -->
6
+
7
+ This rule aims to prevent the import of a specific package.
8
+
9
+ With additional configuration, this rule can also suggest an alternative package to import instead.
10
+
11
+ If the alternative package is specified, auto-fixing will replace the import statement with the alternative package.
12
+
13
+ ## Rule Details
14
+
15
+ Example configuration:
16
+
17
+ ```json
18
+ {
19
+ "rules": {
20
+ "restrict-import/restrict-import": [
21
+ "error",
22
+ [
23
+ {
24
+ "name": "test-package",
25
+ "alternative": "replacement-package"
26
+ },
27
+ "another-package"
28
+ ]
29
+ ]
30
+ }
31
+ }
32
+ ```
33
+
34
+ Examples of **incorrect** code for this rule:
35
+
36
+ ```js
37
+ import testPackage from "test-package";
38
+
39
+ import anotherPackage from "another-package";
40
+ ```
41
+
42
+ Examples of **correct** code for this rule:
43
+
44
+ ```js
45
+ import testPackage from "replacement-package";
46
+
47
+ import theOtherPackage from "the-other-package";
48
+ ```
49
+
50
+ ### Options
51
+
52
+ This rule takes a single argument, an array of strings or objects.
53
+
54
+ Each string or object represents a package that should be restricted.
55
+
56
+ If the array element is a string, it represents the name of the package that should be restricted.
57
+
58
+ If the array element is an object, it represents the name of the package that should be restricted and the alternative package that should be suggested instead.
59
+
60
+ The alternative package is optional.
61
+
62
+ Scheme:
63
+
64
+ ```ts
65
+ type Restriction =
66
+ | string
67
+ | {
68
+ target: string;
69
+ replacement?: string;
70
+ };
71
+ ```
package/lib/index.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview ESLint Plugin for Restricting Import
3
+ * @author shiwoo.park
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Requirements
9
+ //------------------------------------------------------------------------------
10
+
11
+ const requireIndex = require("requireindex");
12
+
13
+ //------------------------------------------------------------------------------
14
+ // Plugin Definition
15
+ //------------------------------------------------------------------------------
16
+
17
+
18
+ // import all rules in lib/rules
19
+ module.exports.rules = requireIndex(__dirname + "/rules");
20
+
21
+
22
+
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @fileoverview Prevent the Import of a Specific Package
3
+ * @author shiwoo.park
4
+ */
5
+ "use strict";
6
+
7
+ /** @type {import('eslint').Rule.RuleModule} */
8
+ module.exports = {
9
+ meta: {
10
+ type: "problem",
11
+ docs: {
12
+ description:
13
+ "Prevent the Import of a Specific Package",
14
+ recommended: false,
15
+ url: "https://github.com/custardcream98/eslint-plugin-restrict-replace-import/blob/main/docs/rules/restrict-import.md",
16
+ },
17
+ fixable: "code",
18
+
19
+ messages: {
20
+ ImportRestriction:
21
+ "`{{ name }}` is restricted from being used.",
22
+ ImportRestrictionWithReplacement:
23
+ "`{{ name }}` is restricted from being used. Replace it with `{{ replacement }}`.",
24
+ },
25
+
26
+ schema: [
27
+ {
28
+ type: "object",
29
+ properties: {
30
+ restrictedPackages: {
31
+ type: "array",
32
+ items: {
33
+ anyOf: [
34
+ {
35
+ type: "string",
36
+ },
37
+ {
38
+ type: "object",
39
+ properties: {
40
+ target: {
41
+ type: "string",
42
+ required: true,
43
+ },
44
+ replacement: {
45
+ type: "string",
46
+ required: false,
47
+ },
48
+ },
49
+ },
50
+ ],
51
+ },
52
+ },
53
+ },
54
+ },
55
+ ],
56
+ },
57
+
58
+ create(context) {
59
+ const option = context.options[0];
60
+
61
+ const restrictedPackages = new Map();
62
+
63
+ option.restrictedPackages.forEach((packageName) => {
64
+ if (typeof packageName === "string") {
65
+ restrictedPackages.set(packageName, null);
66
+ return;
67
+ }
68
+
69
+ restrictedPackages.set(
70
+ packageName.target,
71
+ packageName.replacement
72
+ ? packageName.replacement
73
+ : null
74
+ );
75
+ });
76
+
77
+ const checkRestricted = (importSource) => {
78
+ const isRestricted =
79
+ restrictedPackages.has(importSource);
80
+
81
+ return isRestricted;
82
+ };
83
+
84
+ const getReplacement = (importSource) => {
85
+ const replacement =
86
+ restrictedPackages.get(importSource);
87
+
88
+ return replacement;
89
+ };
90
+
91
+ return {
92
+ ImportDeclaration(node) {
93
+ const importSource = node.source.value;
94
+ const importSourceType = node.source.type;
95
+
96
+ const isRestricted = checkRestricted(importSource);
97
+
98
+ if (
99
+ !isRestricted ||
100
+ importSourceType !== "Literal"
101
+ ) {
102
+ return;
103
+ }
104
+
105
+ const replacement = getReplacement(importSource);
106
+ const quote = node.source.raw.includes("'")
107
+ ? "'"
108
+ : '"';
109
+
110
+ context.report({
111
+ node,
112
+ messageId: replacement
113
+ ? "ImportRestrictionWithReplacement"
114
+ : "ImportRestriction",
115
+ data: {
116
+ name: importSource,
117
+ replacement,
118
+ },
119
+ fix: (fixer) => {
120
+ if (!replacement) {
121
+ return;
122
+ }
123
+
124
+ return fixer.replaceText(
125
+ node.source,
126
+ `${quote}${replacement}${quote}`
127
+ );
128
+ },
129
+ });
130
+ },
131
+ };
132
+ },
133
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "eslint-plugin-restrict-replace-import",
3
+ "version": "1.0.0",
4
+ "description": "ESLint Plugin for Restricting and Replacing Import",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslintplugin",
8
+ "eslint-plugin",
9
+ "import",
10
+ "restrict"
11
+ ],
12
+ "author": "shiwoo.park",
13
+ "bugs": {
14
+ "url": "https://github.com/custardcream98/eslint-plugin-restrict-replace-import/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/custardcream98/eslint-plugin-restrict-replace-import.git"
19
+ },
20
+ "main": "./lib/index.js",
21
+ "exports": "./lib/index.js",
22
+ "scripts": {
23
+ "lint": "npm-run-all \"lint:*\"",
24
+ "lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
25
+ "lint:js": "eslint .",
26
+ "test": "mocha tests --recursive",
27
+ "update:eslint-docs": "eslint-doc-generator"
28
+ },
29
+ "dependencies": {
30
+ "requireindex": "^1.2.0"
31
+ },
32
+ "devDependencies": {
33
+ "eslint": "^8.19.0",
34
+ "eslint-doc-generator": "^1.0.0",
35
+ "eslint-plugin-eslint-plugin": "^5.0.0",
36
+ "eslint-plugin-node": "^11.1.0",
37
+ "mocha": "^10.0.0",
38
+ "npm-run-all": "^4.1.5"
39
+ },
40
+ "engines": {
41
+ "node": "^14.17.0 || ^16.0.0 || >= 18.0.0"
42
+ },
43
+ "peerDependencies": {
44
+ "eslint": ">=7"
45
+ },
46
+ "license": "ISC"
47
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @fileoverview Prevent the Import of a Specific Package
3
+ * @author shiwoo.park
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Requirements
9
+ //------------------------------------------------------------------------------
10
+
11
+ const rule = require("../../../lib/rules/restrict-import"),
12
+ RuleTester = require("eslint").RuleTester;
13
+
14
+ //------------------------------------------------------------------------------
15
+ // Tests
16
+ //------------------------------------------------------------------------------
17
+
18
+ const ruleTester = new RuleTester({
19
+ parserOptions: {
20
+ ecmaVersion: 2015,
21
+ sourceType: "module",
22
+ },
23
+ });
24
+
25
+ const OPTIONS = [
26
+ {
27
+ restrictedPackages: [
28
+ "lodash",
29
+ {
30
+ target: "react",
31
+ replacement: "preact",
32
+ },
33
+ ],
34
+ },
35
+ ];
36
+
37
+ ruleTester.run("restrict-import", rule, {
38
+ valid: [
39
+ {
40
+ code: "import _ from 'underscore'",
41
+ options: OPTIONS,
42
+ },
43
+ {
44
+ code: "import _ from 'lodash-es'",
45
+ options: OPTIONS,
46
+ },
47
+ {
48
+ code: "import { useState } from 'preact'",
49
+ options: OPTIONS,
50
+ },
51
+ ],
52
+
53
+ invalid: [
54
+ {
55
+ code: "import _ from 'lodash'",
56
+ errors: [
57
+ {
58
+ message:
59
+ "`lodash` is restricted from being used.",
60
+ type: "ImportDeclaration",
61
+ },
62
+ ],
63
+ options: OPTIONS,
64
+ output: null,
65
+ },
66
+ {
67
+ code: "import { useState } from 'react'",
68
+ errors: [
69
+ {
70
+ message:
71
+ "`react` is restricted from being used. Replace it with `preact`.",
72
+ type: "ImportDeclaration",
73
+ },
74
+ ],
75
+ options: OPTIONS,
76
+ output: "import { useState } from 'preact'",
77
+ },
78
+ ],
79
+ });