Skip to content

Commit ffac971

Browse files
committed
refactor: rewrite to typescript
1 parent 09fd652 commit ffac971

File tree

4 files changed

+81
-52
lines changed

4 files changed

+81
-52
lines changed

.eslintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
"templates": true,
3636
"ignoreRequire": true,
3737
"lang": "en_US",
38-
"skipWords": [],
38+
"skipWords": [
39+
"tsconfig"
40+
],
3941
// Check if word contains numbers
4042
"skipIfMatch": [
4143
"\\d+",

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"devDependencies": {
1212
"@commitlint/cli": "^17.0.0",
1313
"@commitlint/config-conventional": "^17.0.0",
14+
"@types/eslint": "^8.56.6",
1415
"@types/jest": "^27.5.1",
1516
"@types/node": "^17.0.35",
1617
"@typescript-eslint/eslint-plugin": "^5.25.0",
Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
'use strict';
22

3-
const fs = require('fs');
4-
const path = require('path');
3+
import { Rule } from 'eslint';
4+
import fs from 'fs';
5+
import path from 'path';
56

6-
function findDirWithFile(filename) {
7+
function findDirWithFile(filename: string) {
78
let dir = path.resolve(filename);
89

910
do {
1011
dir = path.dirname(dir);
1112
} while (!fs.existsSync(path.join(dir, filename)) && dir !== '/');
1213

1314
if (!fs.existsSync(path.join(dir, filename))) {
14-
return;
15+
return null;
1516
}
1617

1718
return dir;
1819
}
1920

20-
function findAlias(baseDir, importPath, filePath, ignoredPaths = []) {
21+
function findAlias(
22+
baseDir: string,
23+
importPath: string,
24+
filePath: string,
25+
ignoredPaths: string[] = [],
26+
) {
2127
if (fs.existsSync(path.join(baseDir, 'tsconfig.json'))) {
2228
const tsconfig = JSON.parse(
2329
fs.readFileSync(path.join(baseDir, 'tsconfig.json')).toString('utf8'),
2430
);
2531

26-
const paths = tsconfig?.compilerOptions?.paths ?? {};
32+
const paths: Record<string, string[]> = tsconfig?.compilerOptions?.paths ?? {};
2733
for (const [alias, aliasPaths] of Object.entries(paths)) {
2834
// TODO: support full featured glob patterns instead of trivial cases like `@utils/*` and `src/utils/*`
2935
const matchedPath = aliasPaths.find((dirPath) => {
@@ -72,55 +78,58 @@ function findAlias(baseDir, importPath, filePath, ignoredPaths = []) {
7278

7379
// TODO: implement option to force relative path instead of alias (for remove alias case)
7480
// TODO: add tests
75-
// TODO: move to package
76-
module.exports = {
77-
'proper-import-aliases': {
78-
meta: {
79-
fixable: true,
80-
},
81-
create: function (context) {
82-
const baseDir = findDirWithFile('package.json');
83-
84-
return {
85-
ImportDeclaration(node) {
86-
const [{ ignoredPaths = [] } = {}] = context.options;
81+
const rule: Rule.RuleModule = {
82+
meta: {
83+
fixable: 'code',
84+
},
85+
create(context) {
86+
const baseDir = findDirWithFile('package.json');
87+
88+
if (!baseDir) throw new Error("Can't find base dir");
89+
90+
return {
91+
ImportDeclaration(node) {
92+
const [{ ignoredPaths = [] } = {}] = context.options as [
93+
{ ignoredPaths: string[] },
94+
];
95+
96+
const source = node.source.value;
97+
if (typeof source === 'string' && source.startsWith('.')) {
98+
const filename = context.getFilename();
8799

88100
const resolvedIgnoredPaths = ignoredPaths.map((ignoredPath) =>
89101
path.normalize(path.join(path.dirname(filename), ignoredPath)),
90102
);
91103

92-
const source = node.source.value;
93-
if (source.startsWith('.')) {
94-
const filename = context.getFilename();
95-
96-
const absolutePath = path.normalize(
97-
path.join(path.dirname(filename), source),
98-
);
99-
100-
const replacement = findAlias(
101-
baseDir,
102-
absolutePath,
103-
filename,
104-
resolvedIgnoredPaths,
105-
);
106-
107-
if (!replacement) return;
108-
109-
context.report({
110-
node,
111-
message: `Update import to ${replacement}`,
112-
fix: function (fixer) {
113-
// TODO: preserve quotes
114-
const quote = `'`;
115-
return fixer.replaceText(
116-
node.source,
117-
quote + replacement + quote,
118-
);
119-
},
120-
});
121-
}
122-
},
123-
};
124-
},
104+
const absolutePath = path.normalize(
105+
path.join(path.dirname(filename), source),
106+
);
107+
108+
const replacement = findAlias(
109+
baseDir,
110+
absolutePath,
111+
filename,
112+
resolvedIgnoredPaths,
113+
);
114+
115+
if (!replacement) return;
116+
117+
context.report({
118+
node,
119+
message: `Update import to ${replacement}`,
120+
fix(fixer) {
121+
// TODO: preserve quotes
122+
const quote = `'`;
123+
return fixer.replaceText(
124+
node.source,
125+
quote + replacement + quote,
126+
);
127+
},
128+
});
129+
}
130+
},
131+
};
125132
},
126133
};
134+
135+
export default rule;

0 commit comments

Comments
 (0)