eslint-plugin-stratified-design 0.10.0 → 0.12.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.
@@ -167,6 +167,8 @@ module.exports = {
167
167
  const isFileIndex = isFileIndexOfModule(options, fileDir, filePath);
168
168
 
169
169
  const report = (node) => {
170
+ if (node.importKind === "type") return;
171
+
170
172
  if (isExcludedFile) return;
171
173
 
172
174
  const { modulePath, isModuleExcluded } = createModulePath(
@@ -16,7 +16,7 @@ const { createAliases, fromCwd, match } = require("../helpers/common");
16
16
  * @typedef {import('eslint').AST.Token} Token
17
17
  * @typedef {import('eslint').SourceCode} SourceCode
18
18
  * @typedef {{
19
- * import: { member: string[], from: string },
19
+ * import: { member: '*' | string[], from: string },
20
20
  * allow: string[],
21
21
  * disallow: string[],
22
22
  * }} ImportPath
@@ -30,6 +30,8 @@ const DEFAULT = "default";
30
30
 
31
31
  const NAMESPACE = "*";
32
32
 
33
+ const ANY_MEMBER = "*";
34
+
33
35
  const importSchema = {
34
36
  type: "object",
35
37
  properties: {
@@ -37,8 +39,16 @@ const importSchema = {
37
39
  type: "object",
38
40
  properties: {
39
41
  member: {
40
- type: "array",
41
- items: [{ type: "string" }], // 'default' means default specifier
42
+ oneOf: [
43
+ {
44
+ type: "array",
45
+ items: [{ type: "string" }], // 'default' means default specifier
46
+ },
47
+ {
48
+ type: "string",
49
+ pattern: `^[${ANY_MEMBER}]$`
50
+ }
51
+ ]
42
52
  },
43
53
  from: { type: "string" },
44
54
  },
@@ -93,7 +103,7 @@ module.exports = {
93
103
  additionalItems: false,
94
104
  },
95
105
  messages: {
96
- "no-disallowed-imports": "'{{member}}' should NOT be imported",
106
+ "no-disallowed-imports": "{{member}} should NOT be imported from '{{from}}'",
97
107
  },
98
108
  },
99
109
  create(context) {
@@ -126,6 +136,10 @@ module.exports = {
126
136
  return [theMember, theImportSpec];
127
137
  }
128
138
 
139
+ if (importSpec.import.member === ANY_MEMBER) {
140
+ return ['Any member', importSpec]
141
+ }
142
+
129
143
  const importedSpecifiers = node.specifiers.map((specifier) => {
130
144
  if (specifier.type === "ImportSpecifier")
131
145
  return specifier.imported.name;
@@ -143,16 +157,14 @@ module.exports = {
143
157
  match(fromCwd(context.cwd, modulePath))(importSpec.import.from)
144
158
  ) {
145
159
  if (member === DEFAULT || member === NAMESPACE) {
146
- return [
147
- node.specifiers.find(
148
- ({ type }) =>
149
- type === "ImportDefaultSpecifier" ||
150
- type === "ImportNamespaceSpecifier"
151
- ).local.name,
152
- importSpec,
153
- ];
160
+ const theMember = node.specifiers.find(
161
+ ({ type }) =>
162
+ type === "ImportDefaultSpecifier" ||
163
+ type === "ImportNamespaceSpecifier"
164
+ ).local.name
165
+ return [`'${theMember}'`, importSpec];
154
166
  }
155
- return [member, importSpec];
167
+ return [`'${member}'`, importSpec];
156
168
  }
157
169
 
158
170
  return [undefined, undefined];
@@ -174,7 +186,7 @@ module.exports = {
174
186
  context.report({
175
187
  node,
176
188
  messageId: "no-disallowed-imports",
177
- data: { member: theMember },
189
+ data: { member: theMember, from: theImportSpec.import.from },
178
190
  });
179
191
  },
180
192
  };
@@ -124,6 +124,8 @@ module.exports = {
124
124
  * @returns
125
125
  */
126
126
  const report = (node) => {
127
+ if (node.importKind === "type") return;
128
+
127
129
  if (!isStructureValid) {
128
130
  reportError(node, "invalid-json");
129
131
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-stratified-design",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "ESlint rules for stratified design",
5
5
  "keywords": [
6
6
  "eslint",
@@ -27,6 +27,7 @@
27
27
  "requireindex": "^1.2.0"
28
28
  },
29
29
  "devDependencies": {
30
+ "@typescript-eslint/parser": "^7.1.0",
30
31
  "eslint": "^8.19.0",
31
32
  "eslint-plugin-eslint-plugin": "^5.0.0",
32
33
  "eslint-plugin-node": "^11.1.0",
@@ -9,7 +9,8 @@
9
9
  //------------------------------------------------------------------------------
10
10
 
11
11
  const rule = require("../../../lib/rules/lower-level-imports"),
12
- RuleTester = require("eslint").RuleTester;
12
+ RuleTester = require("eslint").RuleTester,
13
+ path = require("path");
13
14
 
14
15
  //------------------------------------------------------------------------------
15
16
  // Tests
@@ -28,7 +29,10 @@ const structure = [
28
29
  ];
29
30
 
30
31
  const ruleTester = new RuleTester({
31
- parserOptions: { ecmaVersion: 2022, sourceType: "module" },
32
+ parser: path.resolve(
33
+ "./node_modules/@typescript-eslint/parser/dist/parser.js"
34
+ ),
35
+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
32
36
  });
33
37
 
34
38
  ruleTester.run("lower-level-imports", rule, {
@@ -232,6 +236,11 @@ ruleTester.run("lower-level-imports", rule, {
232
236
  filename: "./src/layer1/subLayer2.js",
233
237
  options: [{ structure, root: "./src", aliases: { "@/": "./src/" } }],
234
238
  },
239
+ {
240
+ code: "import type { SomeType } from '@/layer2/subLayer2'",
241
+ filename: "./src/layer1/subLayer2.js",
242
+ options: [{ structure, root: "./src", aliases: { "@/": "./src/" } }],
243
+ },
235
244
  ],
236
245
  invalid: [
237
246
  {
@@ -131,6 +131,34 @@ ruleTester.run("no-disallowed-imports", rule, {
131
131
  },
132
132
  ],
133
133
  },
134
+ {
135
+ code: "import { anyMember } from './fileA'",
136
+ filename: "./src/fileB.js",
137
+ options: [
138
+ {
139
+ imports: [
140
+ {
141
+ import: { member: "*", from: "src/fileA" },
142
+ allow: ["src/**/*.js"],
143
+ },
144
+ ],
145
+ },
146
+ ],
147
+ },
148
+ {
149
+ code: "import * as namespace from './fileA'",
150
+ filename: "./src/fileB.js",
151
+ options: [
152
+ {
153
+ imports: [
154
+ {
155
+ import: { member: "*", from: "src/fileA" },
156
+ allow: ["src/**/*.js"],
157
+ },
158
+ ],
159
+ },
160
+ ],
161
+ },
134
162
  ],
135
163
  invalid: [
136
164
  {
@@ -146,7 +174,7 @@ ruleTester.run("no-disallowed-imports", rule, {
146
174
  ],
147
175
  },
148
176
  ],
149
- errors: [{ messageId: "no-disallowed-imports", data: { member: "foo" } }],
177
+ errors: [{ messageId: "no-disallowed-imports", data: { member: "'foo'", from: "src/fileA" } }],
150
178
  },
151
179
  {
152
180
  code: "import { foo } from './fileA'",
@@ -161,7 +189,7 @@ ruleTester.run("no-disallowed-imports", rule, {
161
189
  ],
162
190
  },
163
191
  ],
164
- errors: [{ messageId: "no-disallowed-imports", data: { member: "foo" } }],
192
+ errors: [{ messageId: "no-disallowed-imports", data: { member: "'foo'", from: "src/fileA" } }],
165
193
  },
166
194
  {
167
195
  code: "import { foo } from './fileA'",
@@ -177,7 +205,7 @@ ruleTester.run("no-disallowed-imports", rule, {
177
205
  ],
178
206
  },
179
207
  ],
180
- errors: [{ messageId: "no-disallowed-imports", data: { member: "foo" } }],
208
+ errors: [{ messageId: "no-disallowed-imports", data: { member: "'foo'", from: "src/fileA" } }],
181
209
  },
182
210
  {
183
211
  code: "import foo from './fileA'",
@@ -192,7 +220,7 @@ ruleTester.run("no-disallowed-imports", rule, {
192
220
  ],
193
221
  },
194
222
  ],
195
- errors: [{ messageId: "no-disallowed-imports", data: { member: "foo" } }],
223
+ errors: [{ messageId: "no-disallowed-imports", data: { member: "'foo'", from: "src/fileA" } }],
196
224
  },
197
225
  {
198
226
  code: "import * as name from './fileA'",
@@ -208,7 +236,24 @@ ruleTester.run("no-disallowed-imports", rule, {
208
236
  },
209
237
  ],
210
238
  errors: [
211
- { messageId: "no-disallowed-imports", data: { member: "name" } },
239
+ { messageId: "no-disallowed-imports", data: { member: "'name'", from: "src/fileA" } },
240
+ ],
241
+ },
242
+ {
243
+ code: "import { anyMember } from './fileA'",
244
+ filename: "./src/fileB.js",
245
+ options: [
246
+ {
247
+ imports: [
248
+ {
249
+ import: { member: "*", from: "src/fileA" },
250
+ disallow: ["src/**/*.js"],
251
+ },
252
+ ],
253
+ },
254
+ ],
255
+ errors: [
256
+ { messageId: "no-disallowed-imports", data: { member: "Any member", from: "src/fileA" } },
212
257
  ],
213
258
  },
214
259
  ],
@@ -10,6 +10,7 @@
10
10
 
11
11
  const rule = require("../../../lib/rules/stratified-imports");
12
12
  const RuleTester = require("eslint").RuleTester;
13
+ const path = require("path");
13
14
 
14
15
  //------------------------------------------------------------------------------
15
16
  // Tests
@@ -57,7 +58,10 @@ const RuleTester = require("eslint").RuleTester;
57
58
  */
58
59
 
59
60
  const ruleTester = new RuleTester({
60
- parserOptions: { ecmaVersion: 2022, sourceType: "module" },
61
+ parser: path.resolve(
62
+ "./node_modules/@typescript-eslint/parser/dist/parser.js"
63
+ ),
64
+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
61
65
  });
62
66
 
63
67
  ruleTester.run("stratified-imports", rule, {
@@ -162,6 +166,11 @@ ruleTester.run("stratified-imports", rule, {
162
166
  filename: "./mocked/stratified-imports/layerA.js",
163
167
  options: [{ aliases: { "@/": "./mocked/stratified-imports/" } }],
164
168
  },
169
+ {
170
+ code: "import type { SomeType } from './layerA'",
171
+ filename: "./mocked/stratified-imports/layerB.js",
172
+ options: [],
173
+ },
165
174
  ],
166
175
  invalid: [
167
176
  {