@bedrockio/eslint-plugin 1.4.9 → 1.5.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.
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Patched Vite resolver for eslint-plugin-import.
3
+ *
4
+ * Based on `eslint-import-resolver-vite`:
5
+ * https://github.com/pzmosquito/eslint-import-resolver-vite
6
+ *
7
+ * The upstream resolver replaces every matching path segment when applying
8
+ * aliases. This breaks imports like `docs/components/...` when both `docs`
9
+ * and `components` are aliases, producing invalid paths.
10
+ *
11
+ * This version fixes the behavior so aliases only match the **leading prefix**
12
+ * of the import specifier, which matches how Vite/Rollup aliasing works.
13
+ *
14
+ * Additional improvements
15
+ * -----------------------
16
+ * - Supports both object and array alias forms used by Vite
17
+ * - Supports RegExp `find` entries in array aliases
18
+ * - Avoids rewriting absolute paths incorrectly
19
+ * - Cleans up root/publicDir resolution logic
20
+ *
21
+ */
22
+
23
+ import path from 'node:path';
24
+ import resolve from 'resolve';
25
+ import createDebug from 'debug';
26
+ import { existsSync } from 'node:fs';
27
+
28
+ const namespace = 'eslint-plugin-import:resolver:vite';
29
+ const log = createDebug(namespace);
30
+
31
+ function loadViteConfig(config) {
32
+ if (!config) {
33
+ throw new Error("'config' option must be a path to a vite config file.");
34
+ }
35
+
36
+ const file = path.resolve(process.cwd(), config);
37
+
38
+ if (!existsSync(file)) {
39
+ return;
40
+ }
41
+
42
+ const mod = require(file);
43
+ return mod.default || mod;
44
+ }
45
+
46
+ function tryResolve(source, resolveOptions, label) {
47
+ log('resolving:\t', `(${label})`, source);
48
+ const resolvedPath = resolve.sync(source, resolveOptions);
49
+ log('resolved:\t', resolvedPath);
50
+ return { found: true, path: resolvedPath };
51
+ }
52
+
53
+ function normalizeAliasEntries(alias) {
54
+ if (!alias) {
55
+ return [];
56
+ }
57
+
58
+ if (Array.isArray(alias)) {
59
+ return alias.filter(Boolean).map((entry) => ({
60
+ find: entry.find,
61
+ replacement: entry.replacement,
62
+ }));
63
+ }
64
+
65
+ if (typeof alias === 'object') {
66
+ return Object.entries(alias).map(([find, replacement]) => ({
67
+ find,
68
+ replacement,
69
+ }));
70
+ }
71
+
72
+ throw new Error(
73
+ 'The alias must be either an object, or an array of objects.',
74
+ );
75
+ }
76
+
77
+ function applyStringAlias(source, find, replacement) {
78
+ if (source === find) {
79
+ return replacement;
80
+ }
81
+
82
+ if (source.startsWith(find + '/')) {
83
+ return replacement + source.slice(find.length);
84
+ }
85
+
86
+ return null;
87
+ }
88
+
89
+ function processAlias(alias, source) {
90
+ const entries = normalizeAliasEntries(alias);
91
+
92
+ for (const { find, replacement } of entries) {
93
+ if (!find || !replacement) {
94
+ continue;
95
+ }
96
+
97
+ if (find instanceof RegExp) {
98
+ if (find.test(source)) {
99
+ return source.replace(find, replacement);
100
+ }
101
+ continue;
102
+ }
103
+
104
+ if (typeof find === 'string') {
105
+ const resolved = applyStringAlias(source, find, replacement);
106
+ if (resolved) {
107
+ return resolved;
108
+ }
109
+ }
110
+ }
111
+
112
+ return source;
113
+ }
114
+
115
+ function resolveRoot(root) {
116
+ if (!root) {
117
+ return process.cwd();
118
+ }
119
+
120
+ if (path.isAbsolute(root)) {
121
+ return root;
122
+ }
123
+
124
+ return path.resolve(process.cwd(), root);
125
+ }
126
+
127
+ export const interfaceVersion = 2;
128
+
129
+ function resolveImport(source, file, config) {
130
+ log('\nin file:\t', file);
131
+
132
+ if (resolve.isCore(source)) {
133
+ log('resolved:\t', source);
134
+ return { found: true, path: null };
135
+ }
136
+
137
+ const viteConfig = loadViteConfig(config?.config);
138
+ if (!viteConfig) {
139
+ return { found: false };
140
+ }
141
+
142
+ const defaultExtensions = ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'];
143
+ const viteResolve = viteConfig.resolve || {};
144
+ const extensions = viteResolve.extensions || defaultExtensions;
145
+ const resolveOptions = {
146
+ basedir: path.dirname(file),
147
+ extensions,
148
+ };
149
+
150
+ try {
151
+ return tryResolve(source, resolveOptions, 'as is');
152
+ } catch {}
153
+
154
+ const parsedSource = processAlias(viteResolve.alias, source);
155
+ if (parsedSource !== source) {
156
+ try {
157
+ return tryResolve(parsedSource, resolveOptions, 'with alias');
158
+ } catch {}
159
+ }
160
+
161
+ if (path.isAbsolute(parsedSource)) {
162
+ try {
163
+ return tryResolve(parsedSource, resolveOptions, 'absolute path');
164
+ } catch {}
165
+ }
166
+
167
+ if (viteConfig.publicDir !== false) {
168
+ const rootDir = resolveRoot(viteConfig.root);
169
+ const publicDir = viteConfig.publicDir || 'public';
170
+ const publicBase = path.isAbsolute(publicDir)
171
+ ? publicDir
172
+ : path.resolve(rootDir, publicDir);
173
+
174
+ const publicSource = path.resolve(publicBase, parsedSource);
175
+
176
+ try {
177
+ return tryResolve(publicSource, resolveOptions, 'in public directory');
178
+ } catch {}
179
+ }
180
+
181
+ log('ERROR:\t', 'Unable to resolve');
182
+ return { found: false };
183
+ }
184
+
185
+ export function createViteImportResolver(config) {
186
+ return {
187
+ interfaceVersion: 3,
188
+ name: 'eslint-import-resolver-vite',
189
+ resolve: (source, file) => resolveImport(source, file, config),
190
+ };
191
+ }
192
+
193
+ export { resolveImport as resolve };
package/src/typescript.js CHANGED
@@ -1,33 +1,30 @@
1
- let ts;
2
- let importError;
3
-
4
- try {
5
- // This is to make this package optional.
6
- ts = await import('typescript-eslint');
7
- } catch (err) {
8
- // Package not installed. Capture error to
9
- // allow re-throwing if plugin is accessed,
10
- // otherwise allow it to export silently.
11
- importError = err;
12
- }
1
+ import ts from 'typescript-eslint';
13
2
 
14
3
  export default {
4
+ name: 'typescript',
15
5
  files: ['**/*.{ts,tsx}'],
16
6
  ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
17
7
  languageOptions: {
18
- parser: ts?.parser,
8
+ ecmaVersion: 'latest',
9
+ sourceType: 'module',
10
+ parser: ts.parser,
19
11
  },
20
- get plugins() {
21
- if (importError) {
22
- throw importError;
23
- }
24
- return {
25
- '@typescript-eslint': ts?.plugin,
26
- };
12
+ plugins: {
13
+ '@typescript-eslint': ts.plugin,
27
14
  },
28
15
  rules: {
29
- ...ts?.plugin.configs.recommended.rules,
16
+ // Pull in `eslint-recommended` adjustments from typescript-eslint.
17
+ // This disables core ESLint rules that conflict with TypeScript (e.g. no-undef).
18
+ ...ts.plugin.configs['eslint-recommended'].overrides[0].rules,
19
+
20
+ // Pull in the TypeScript recommended rules themselves.
21
+ // Avoid the flat config version as it's an array.
22
+ ...ts.plugin.configs.recommended.rules,
30
23
  '@typescript-eslint/no-unused-vars': 'warn',
31
24
  '@typescript-eslint/no-explicit-any': 'off',
25
+
26
+ // The above configs try to slip this rule in there despite it
27
+ // not being part of eslint-recommended so force it off again.
28
+ 'prefer-const': 'off',
32
29
  },
33
30
  };
package/src/vite.js ADDED
@@ -0,0 +1,23 @@
1
+ import globals from 'globals';
2
+
3
+ export default {
4
+ name: 'vite',
5
+ files: ['**/*.{js,jsx,ts,tsx,mdx}'],
6
+ ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
7
+ languageOptions: {
8
+ ecmaVersion: 'latest',
9
+ sourceType: 'module',
10
+ globals: globals.browser,
11
+ },
12
+ settings: {
13
+ 'import/resolver': {
14
+ exports: true,
15
+ ['@bedrockio/eslint-plugin/resolvers/vite']: {
16
+ config: './vite.config.js',
17
+ },
18
+ node: {
19
+ moduleDirectory: ['node_modules', 'src'],
20
+ },
21
+ },
22
+ },
23
+ };
@@ -1,17 +1,15 @@
1
- import * as plugin from 'eslint-plugin-import';
2
- import importRules from './importRules.js';
1
+ import globals from 'globals';
3
2
 
4
3
  export default {
5
- ...plugin.flatConfigs.recommended,
6
- files: ['**/*.{js,jsx,ts,tsx}'],
4
+ name: 'webpack',
5
+ files: ['**/*.{js,jsx,ts,tsx,mdx}'],
7
6
  ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
8
7
  languageOptions: {
9
8
  ecmaVersion: 'latest',
10
9
  sourceType: 'module',
10
+ globals: globals.browser,
11
11
  },
12
12
  rules: {
13
- ...plugin.flatConfigs.recommended.rules,
14
- ...importRules,
15
13
  'import/no-unresolved': [
16
14
  'warn',
17
15
  {
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _default = exports.default = {
8
- 'import/no-unresolved': 'warn',
9
- 'import/no-named-as-default-member': 'off',
10
- 'import/first': 'warn',
11
- 'import/order': ['warn', {
12
- 'newlines-between': 'always-and-inside-groups',
13
- sortTypesGroup: true,
14
- alphabetize: {
15
- order: 'asc',
16
- caseInsensitive: false
17
- },
18
- named: true,
19
- warnOnUnassignedImports: true,
20
- consolidateIslands: 'inside-groups',
21
- groups: ['builtin', 'unknown', 'external', 'internal', ['parent', 'sibling'], 'index', 'object', 'type'],
22
- pathGroups: [{
23
- pattern: 'semantic',
24
- group: 'external'
25
- }, {
26
- pattern: '+(stores|helpers|layouts|@stores|@helpers|@layouts){,/**}',
27
- group: 'internal',
28
- position: 'before'
29
- }, {
30
- pattern: '+(screens|modals|components|@screens|@modals|@components){,/**}',
31
- group: 'internal'
32
- }, {
33
- pattern: '+(hooks|@hooks|utils|@utils){,/**}',
34
- group: 'internal',
35
- position: 'after'
36
- }, {
37
- pattern: '+(assets|@assets){,**}',
38
- group: 'sibling',
39
- position: 'after'
40
- }, {
41
- pattern: '**/*.+(css|less|scss|png|jpg|svg|json)',
42
- group: 'type',
43
- position: 'after'
44
- }, {
45
- pattern: './**/*.+(css|less|scss|png|jpg|svg|json)',
46
- group: 'type',
47
- position: 'after'
48
- }]
49
- }]
50
- };
@@ -1,31 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var plugin = _interopRequireWildcard(require("eslint-plugin-import"));
8
- var _importRules = _interopRequireDefault(require("./importRules.js"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
- var _default = exports.default = {
12
- ...plugin.flatConfigs.recommended,
13
- files: ['**/*.{js,jsx}'],
14
- ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
15
- languageOptions: {
16
- ecmaVersion: 'latest',
17
- sourceType: 'module'
18
- },
19
- rules: {
20
- ..._importRules.default
21
- },
22
- settings: {
23
- 'import/resolver': {
24
- exports: true,
25
- node: {
26
- moduleDirectory: ['node_modules', 'src'],
27
- extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.css', '.less', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.webm', '.mp4']
28
- }
29
- }
30
- }
31
- };
@@ -1,47 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _path = _interopRequireDefault(require("path"));
8
- var plugin = _interopRequireWildcard(require("eslint-plugin-import"));
9
- var _importRules = _interopRequireDefault(require("./importRules.js"));
10
- var _fs = require("fs");
11
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
- async function loadConfig() {
14
- const file = _path.default.join(process.cwd(), 'vite.config.js');
15
- if (!(0, _fs.existsSync)(file)) {
16
- // This file will be imported from index.js so
17
- // bail if no vite.config.js file exists.
18
- return;
19
- }
20
- const module = await (specifier => new Promise(r => r(`${specifier}`)).then(s => _interopRequireWildcard(require(s))))(file);
21
- return module.default;
22
- }
23
- const viteConfig = await loadConfig();
24
- var _default = exports.default = {
25
- ...plugin.flatConfigs.recommended,
26
- files: ['**/*.{js,jsx,ts,tsx}'],
27
- ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
28
- languageOptions: {
29
- ecmaVersion: 'latest',
30
- sourceType: 'module'
31
- },
32
- rules: {
33
- ...plugin.flatConfigs.recommended.rules,
34
- ..._importRules.default
35
- },
36
- settings: {
37
- 'import/resolver': {
38
- exports: true,
39
- vite: {
40
- viteConfig
41
- },
42
- node: {
43
- moduleDirectory: ['node_modules', 'src']
44
- }
45
- }
46
- }
47
- };
@@ -1,39 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var plugin = _interopRequireWildcard(require("eslint-plugin-import"));
8
- var _importRules = _interopRequireDefault(require("./importRules.js"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
- var _default = exports.default = {
12
- ...plugin.flatConfigs.recommended,
13
- files: ['**/*.{js,jsx,ts,tsx}'],
14
- ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
15
- languageOptions: {
16
- ecmaVersion: 'latest',
17
- sourceType: 'module'
18
- },
19
- rules: {
20
- ...plugin.flatConfigs.recommended.rules,
21
- ..._importRules.default,
22
- 'import/no-unresolved': ['warn', {
23
- // package.json "style" may be used here which
24
- // will resolve for webpack but not within the
25
- // eslint plugin
26
- ignore: ['\\.css$']
27
- }]
28
- },
29
- settings: {
30
- 'import/resolver': {
31
- webpack: {
32
- config: './webpack.config.js'
33
- },
34
- node: {
35
- moduleDirectory: ['node_modules', 'src']
36
- }
37
- }
38
- }
39
- };
@@ -1,65 +0,0 @@
1
- export default {
2
- 'import/no-unresolved': 'warn',
3
- 'import/no-named-as-default-member': 'off',
4
- 'import/first': 'warn',
5
- 'import/order': [
6
- 'warn',
7
- {
8
- 'newlines-between': 'always-and-inside-groups',
9
- sortTypesGroup: true,
10
- alphabetize: {
11
- order: 'asc',
12
- caseInsensitive: false,
13
- },
14
- named: true,
15
- warnOnUnassignedImports: true,
16
- consolidateIslands: 'inside-groups',
17
- groups: [
18
- 'builtin',
19
- 'unknown',
20
- 'external',
21
- 'internal',
22
- ['parent', 'sibling'],
23
- 'index',
24
- 'object',
25
- 'type',
26
- ],
27
- pathGroups: [
28
- {
29
- pattern: 'semantic',
30
- group: 'external',
31
- },
32
- {
33
- pattern: '+(stores|helpers|layouts|@stores|@helpers|@layouts){,/**}',
34
- group: 'internal',
35
- position: 'before',
36
- },
37
- {
38
- pattern:
39
- '+(screens|modals|components|@screens|@modals|@components){,/**}',
40
- group: 'internal',
41
- },
42
- {
43
- pattern: '+(hooks|@hooks|utils|@utils){,/**}',
44
- group: 'internal',
45
- position: 'after',
46
- },
47
- {
48
- pattern: '+(assets|@assets){,**}',
49
- group: 'sibling',
50
- position: 'after',
51
- },
52
- {
53
- pattern: '**/*.+(css|less|scss|png|jpg|svg|json)',
54
- group: 'type',
55
- position: 'after',
56
- },
57
- {
58
- pattern: './**/*.+(css|less|scss|png|jpg|svg|json)',
59
- group: 'type',
60
- position: 'after',
61
- },
62
- ],
63
- },
64
- ],
65
- };
@@ -1,45 +0,0 @@
1
- import path from 'path';
2
- import * as plugin from 'eslint-plugin-import';
3
- import importRules from './importRules.js';
4
- import { existsSync } from 'fs';
5
-
6
- async function loadConfig() {
7
- const file = path.join(process.cwd(), 'vite.config.js');
8
-
9
- if (!existsSync(file)) {
10
- // This file will be imported from index.js so
11
- // bail if no vite.config.js file exists.
12
- return;
13
- }
14
-
15
- const module = await import(file);
16
-
17
- return module.default;
18
- }
19
-
20
- const viteConfig = await loadConfig();
21
-
22
- export default {
23
- ...plugin.flatConfigs.recommended,
24
- files: ['**/*.{js,jsx,ts,tsx}'],
25
- ignores: ['node_modules/**/*', '**/dist/**/*', '**/*.d.ts'],
26
- languageOptions: {
27
- ecmaVersion: 'latest',
28
- sourceType: 'module',
29
- },
30
- rules: {
31
- ...plugin.flatConfigs.recommended.rules,
32
- ...importRules,
33
- },
34
- settings: {
35
- 'import/resolver': {
36
- exports: true,
37
- vite: {
38
- viteConfig,
39
- },
40
- node: {
41
- moduleDirectory: ['node_modules', 'src'],
42
- },
43
- },
44
- },
45
- };