@mrpalmer/eslint-plugin 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/lib/constants.d.ts +2 -0
- package/lib/constants.js +1 -0
- package/lib/index.d.ts +36 -0
- package/lib/index.js +31 -0
- package/lib/meta.d.ts +4 -0
- package/lib/meta.js +17 -0
- package/lib/rules/shorten-paths.d.ts +8 -0
- package/lib/rules/shorten-paths.js +70 -0
- package/lib/rules/sort-imports.d.ts +19 -0
- package/lib/rules/sort-imports.js +636 -0
- package/lib/rules/sort-named.d.ts +8 -0
- package/lib/rules/sort-named.js +436 -0
- package/lib/types.d.ts +12 -0
- package/lib/types.js +1 -0
- package/lib/utils/array.d.ts +6 -0
- package/lib/utils/array.js +23 -0
- package/lib/utils/ast.d.ts +4 -0
- package/lib/utils/ast.js +102 -0
- package/lib/utils/create-rule.d.ts +2 -0
- package/lib/utils/create-rule.js +58 -0
- package/lib/utils/import-path-options.d.ts +6 -0
- package/lib/utils/import-path-options.js +98 -0
- package/lib/utils/import-type.d.ts +3 -0
- package/lib/utils/import-type.js +88 -0
- package/lib/utils/settings.d.ts +3 -0
- package/lib/utils/settings.js +20 -0
- package/lib/utils/shortest-path.d.ts +2 -0
- package/lib/utils/shortest-path.js +45 -0
- package/lib/utils/ts-config.d.ts +16 -0
- package/lib/utils/ts-config.js +54 -0
- package/package.json +31 -0
package/lib/constants.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const pluginName = 'mrpalmer';
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
configs: {
|
|
4
|
+
recommended: {
|
|
5
|
+
name: string;
|
|
6
|
+
plugins: {
|
|
7
|
+
mrpalmer: {
|
|
8
|
+
meta: {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
};
|
|
12
|
+
rules: {
|
|
13
|
+
'shorten-paths': TSESLint.RuleModule<"shortenImport" | "shortenExport", import("./rules/shorten-paths.js").Options, unknown, TSESLint.RuleListener>;
|
|
14
|
+
'sort-imports': TSESLint.RuleModule<"error" | "order" | "noLineBetweenImports", [import("./rules/sort-imports.js").Options], unknown, TSESLint.RuleListener>;
|
|
15
|
+
'sort-named': TSESLint.RuleModule<"order", [import("./rules/sort-named.js").Options], unknown, TSESLint.RuleListener>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
rules: {
|
|
20
|
+
'mrpalmer/shorten-paths': "warn";
|
|
21
|
+
'mrpalmer/sort-imports': "warn";
|
|
22
|
+
'mrpalmer/sort-named': "warn";
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
meta: {
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
};
|
|
30
|
+
rules: {
|
|
31
|
+
'shorten-paths': TSESLint.RuleModule<"shortenImport" | "shortenExport", import("./rules/shorten-paths.js").Options, unknown, TSESLint.RuleListener>;
|
|
32
|
+
'sort-imports': TSESLint.RuleModule<"error" | "order" | "noLineBetweenImports", [import("./rules/sort-imports.js").Options], unknown, TSESLint.RuleListener>;
|
|
33
|
+
'sort-named': TSESLint.RuleModule<"order", [import("./rules/sort-named.js").Options], unknown, TSESLint.RuleListener>;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export default _default;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { meta } from './meta.js';
|
|
2
|
+
// rules
|
|
3
|
+
import shortenPathsRule from './rules/shorten-paths.js';
|
|
4
|
+
import sortImportsRule from './rules/sort-imports.js';
|
|
5
|
+
import sortNamedRule from './rules/sort-named.js';
|
|
6
|
+
const rules = {
|
|
7
|
+
'shorten-paths': shortenPathsRule,
|
|
8
|
+
'sort-imports': sortImportsRule,
|
|
9
|
+
'sort-named': sortNamedRule,
|
|
10
|
+
};
|
|
11
|
+
const plugin = {
|
|
12
|
+
meta,
|
|
13
|
+
rules,
|
|
14
|
+
};
|
|
15
|
+
const recommended = {
|
|
16
|
+
name: 'mrpalmer/recommended',
|
|
17
|
+
plugins: {
|
|
18
|
+
mrpalmer: plugin,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
'mrpalmer/shorten-paths': 'warn',
|
|
22
|
+
'mrpalmer/sort-imports': 'warn',
|
|
23
|
+
'mrpalmer/sort-named': 'warn',
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export default {
|
|
27
|
+
...plugin,
|
|
28
|
+
configs: {
|
|
29
|
+
recommended,
|
|
30
|
+
},
|
|
31
|
+
};
|
package/lib/meta.d.ts
ADDED
package/lib/meta.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
const { name, version } = getMeta(require('../package.json'));
|
|
4
|
+
export const meta = { name, version };
|
|
5
|
+
function getMeta(pkgJson) {
|
|
6
|
+
if (typeof pkgJson !== 'object' || pkgJson === null) {
|
|
7
|
+
throw new TypeError('Expected an object');
|
|
8
|
+
}
|
|
9
|
+
if (!('name' in pkgJson) || !('version' in pkgJson)) {
|
|
10
|
+
throw new TypeError('Expected name and version properties in package.json');
|
|
11
|
+
}
|
|
12
|
+
const { name, version } = pkgJson;
|
|
13
|
+
if (typeof name !== 'string' || typeof version !== 'string') {
|
|
14
|
+
throw new TypeError('Expected name and version properties to be strings');
|
|
15
|
+
}
|
|
16
|
+
return { name, version };
|
|
17
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type MessageIds = 'shortenImport' | 'shortenExport';
|
|
2
|
+
export type Options = [
|
|
3
|
+
{
|
|
4
|
+
breakTies: 'alias' | 'relative';
|
|
5
|
+
}
|
|
6
|
+
];
|
|
7
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { createRule } from '../utils/create-rule.js';
|
|
3
|
+
import { loadConfig } from '../utils/ts-config.js';
|
|
4
|
+
import { getImportPathOptions } from '../utils/import-path-options.js';
|
|
5
|
+
import { getShortestPath } from '../utils/shortest-path.js';
|
|
6
|
+
export default createRule({
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'suggestion',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Ensure the shortest available path is used for imports and exports.',
|
|
11
|
+
},
|
|
12
|
+
fixable: 'code',
|
|
13
|
+
schema: [
|
|
14
|
+
{
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
breakTies: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
enum: ['alias', 'relative'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
messages: {
|
|
26
|
+
shortenImport: 'Import can be shortened to "{{path}}"',
|
|
27
|
+
shortenExport: 'Export can be shortened to "{{path}}"',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultOptions: [
|
|
31
|
+
{
|
|
32
|
+
breakTies: 'alias',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
create(context, options) {
|
|
36
|
+
const config = loadConfig(context.settings);
|
|
37
|
+
const absolutePath = path.resolve(process.cwd(), context.filename);
|
|
38
|
+
return {
|
|
39
|
+
'ImportDeclaration,ExportNamedDeclaration,ExportAllDeclaration'(node) {
|
|
40
|
+
if (!node.source) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const originalPath = node.source.value;
|
|
44
|
+
const pathOptions = getImportPathOptions({
|
|
45
|
+
originalPath,
|
|
46
|
+
filePath: absolutePath,
|
|
47
|
+
tsconfig: config,
|
|
48
|
+
});
|
|
49
|
+
const shortest = getShortestPath(pathOptions, options);
|
|
50
|
+
if (originalPath === shortest) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
context.report({
|
|
54
|
+
node: node.source,
|
|
55
|
+
messageId:
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
57
|
+
node.type === 'ImportDeclaration'
|
|
58
|
+
? 'shortenImport'
|
|
59
|
+
: 'shortenExport',
|
|
60
|
+
data: {
|
|
61
|
+
path: shortest,
|
|
62
|
+
},
|
|
63
|
+
fix(fixer) {
|
|
64
|
+
return fixer.replaceText(node.source, `'${shortest}'`);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import { type MinimatchOptions } from 'minimatch';
|
|
3
|
+
import type { Arrayable } from '../types.js';
|
|
4
|
+
import { type ImportType as ImportType_ } from '../utils/import-type.js';
|
|
5
|
+
type ImportType = ImportType_ | 'core';
|
|
6
|
+
interface PathGroup {
|
|
7
|
+
pattern: string;
|
|
8
|
+
group: ImportType;
|
|
9
|
+
patternOptions?: MinimatchOptions;
|
|
10
|
+
position?: 'before' | 'after';
|
|
11
|
+
isSideEffect?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface Options {
|
|
14
|
+
groups: ReadonlyArray<Arrayable<ImportType>>;
|
|
15
|
+
pathGroups: PathGroup[];
|
|
16
|
+
}
|
|
17
|
+
type MessageId = 'error' | 'order' | 'noLineBetweenImports';
|
|
18
|
+
declare const _default: TSESLint.RuleModule<MessageId, [Options], unknown, TSESLint.RuleListener>;
|
|
19
|
+
export default _default;
|