eslint-plugin-esm 0.3.0 → 0.4.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/CHANGELOG.md +10 -0
- package/dist/index.js +3 -3
- package/dist/rules/no-useless-path-segments.d.ts +5 -0
- package/dist/rules/no-useless-path-segments.d.ts.map +1 -0
- package/dist/rules/no-useless-path-segments.js +28 -0
- package/doc/rules/{nearest-relative-path.md → no-useless-path-segments.md} +7 -1
- package/package.json +2 -2
- package/src/index.ts +2 -2
- package/src/rules/{nearest-relative-path.spec.ts → no-useless-path-segments.spec.ts} +10 -2
- package/src/rules/{nearest-relative-path.ts → no-useless-path-segments.ts} +5 -2
- package/dist/rules/nearest-relative-path.d.ts +0 -5
- package/dist/rules/nearest-relative-path.d.ts.map +0 -1
- package/dist/rules/nearest-relative-path.js +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# eslint-plugin-esm
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 85cd2d5: refactor(eslint-plugin-esm): rename rule `nearest-relative-path` to `no-useless-path-segments`
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 36c4c6b: fix(eslint-plugin-esm): report on `./..` and `./`
|
|
12
|
+
|
|
3
13
|
## 0.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { nearestRelativePath } from "./rules/nearest-relative-path.js";
|
|
2
1
|
import { noDirectoryImports } from "./rules/no-directory-imports.js";
|
|
3
2
|
import { noDynamicImports } from "./rules/no-dynamic-imports.js";
|
|
4
3
|
import { noEmptyExports } from "./rules/no-empty-exports.js";
|
|
@@ -9,9 +8,9 @@ import { noRenameExports } from "./rules/no-rename-exports.js";
|
|
|
9
8
|
import { noRenameImports } from "./rules/no-rename-imports.js";
|
|
10
9
|
import { noSideEffectImports } from "./rules/no-side-effect-imports.js";
|
|
11
10
|
import { noTsFileImports } from "./rules/no-ts-file-imports.js";
|
|
11
|
+
import { noUselessPathSegments } from "./rules/no-useless-path-segments.js";
|
|
12
12
|
import { requiredExports } from "./rules/required-exports.js";
|
|
13
13
|
export const rules = {
|
|
14
|
-
[nearestRelativePath.name]: nearestRelativePath.rule,
|
|
15
14
|
[noDirectoryImports.name]: noDirectoryImports.rule,
|
|
16
15
|
[noDynamicImports.name]: noDynamicImports.rule,
|
|
17
16
|
[noEmptyExports.name]: noEmptyExports.rule,
|
|
@@ -22,6 +21,7 @@ export const rules = {
|
|
|
22
21
|
[noRenameImports.name]: noRenameImports.rule,
|
|
23
22
|
[noSideEffectImports.name]: noSideEffectImports.rule,
|
|
24
23
|
[noTsFileImports.name]: noTsFileImports.rule,
|
|
24
|
+
[noUselessPathSegments.name]: noUselessPathSegments.rule,
|
|
25
25
|
[requiredExports.name]: requiredExports.rule,
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDeEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU5RCxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUc7SUFDbkIsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxJQUFJO0lBQ2xELENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsSUFBSTtJQUM5QyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjLENBQUMsSUFBSTtJQUMxQyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLG1CQUFtQixDQUFDLElBQUk7SUFDcEQsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxJQUFJO0lBQ3BELENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEVBQUUsdUJBQXVCLENBQUMsSUFBSTtJQUM1RCxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxlQUFlLENBQUMsSUFBSTtJQUM1QyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxlQUFlLENBQUMsSUFBSTtJQUM1QyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLG1CQUFtQixDQUFDLElBQUk7SUFDcEQsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsZUFBZSxDQUFDLElBQUk7SUFDNUMsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxxQkFBcUIsQ0FBQyxJQUFJO0lBQ3hELENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLGVBQWUsQ0FBQyxJQUFJO0NBQzdDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBub0RpcmVjdG9yeUltcG9ydHMgfSBmcm9tIFwiLi9ydWxlcy9uby1kaXJlY3RvcnktaW1wb3J0cy5qc1wiO1xuaW1wb3J0IHsgbm9EeW5hbWljSW1wb3J0cyB9IGZyb20gXCIuL3J1bGVzL25vLWR5bmFtaWMtaW1wb3J0cy5qc1wiO1xuaW1wb3J0IHsgbm9FbXB0eUV4cG9ydHMgfSBmcm9tIFwiLi9ydWxlcy9uby1lbXB0eS1leHBvcnRzLmpzXCI7XG5pbXBvcnQgeyBub0dpdElnbm9yZWRJbXBvcnRzIH0gZnJvbSBcIi4vcnVsZXMvbm8tZ2l0LWlnbm9yZWQtaW1wb3J0cy5qc1wiO1xuaW1wb3J0IHsgbm9QaGFudG9tRGVwSW1wb3J0cyB9IGZyb20gXCIuL3J1bGVzL25vLXBoYW50b20tZGVwLWltcG9ydHMuanNcIjtcbmltcG9ydCB7IG5vUmVsYXRpdmVQYXJlbnRJbXBvcnRzIH0gZnJvbSBcIi4vcnVsZXMvbm8tcmVsYXRpdmUtcGFyZW50LWltcG9ydHMuanNcIjtcbmltcG9ydCB7IG5vUmVuYW1lRXhwb3J0cyB9IGZyb20gXCIuL3J1bGVzL25vLXJlbmFtZS1leHBvcnRzLmpzXCI7XG5pbXBvcnQgeyBub1JlbmFtZUltcG9ydHMgfSBmcm9tIFwiLi9ydWxlcy9uby1yZW5hbWUtaW1wb3J0cy5qc1wiO1xuaW1wb3J0IHsgbm9TaWRlRWZmZWN0SW1wb3J0cyB9IGZyb20gXCIuL3J1bGVzL25vLXNpZGUtZWZmZWN0LWltcG9ydHMuanNcIjtcbmltcG9ydCB7IG5vVHNGaWxlSW1wb3J0cyB9IGZyb20gXCIuL3J1bGVzL25vLXRzLWZpbGUtaW1wb3J0cy5qc1wiO1xuaW1wb3J0IHsgbm9Vc2VsZXNzUGF0aFNlZ21lbnRzIH0gZnJvbSBcIi4vcnVsZXMvbm8tdXNlbGVzcy1wYXRoLXNlZ21lbnRzLmpzXCI7XG5pbXBvcnQgeyByZXF1aXJlZEV4cG9ydHMgfSBmcm9tIFwiLi9ydWxlcy9yZXF1aXJlZC1leHBvcnRzLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBydWxlcyA9IHtcbiAgW25vRGlyZWN0b3J5SW1wb3J0cy5uYW1lXTogbm9EaXJlY3RvcnlJbXBvcnRzLnJ1bGUsXG4gIFtub0R5bmFtaWNJbXBvcnRzLm5hbWVdOiBub0R5bmFtaWNJbXBvcnRzLnJ1bGUsXG4gIFtub0VtcHR5RXhwb3J0cy5uYW1lXTogbm9FbXB0eUV4cG9ydHMucnVsZSxcbiAgW25vR2l0SWdub3JlZEltcG9ydHMubmFtZV06IG5vR2l0SWdub3JlZEltcG9ydHMucnVsZSxcbiAgW25vUGhhbnRvbURlcEltcG9ydHMubmFtZV06IG5vUGhhbnRvbURlcEltcG9ydHMucnVsZSxcbiAgW25vUmVsYXRpdmVQYXJlbnRJbXBvcnRzLm5hbWVdOiBub1JlbGF0aXZlUGFyZW50SW1wb3J0cy5ydWxlLFxuICBbbm9SZW5hbWVFeHBvcnRzLm5hbWVdOiBub1JlbmFtZUV4cG9ydHMucnVsZSxcbiAgW25vUmVuYW1lSW1wb3J0cy5uYW1lXTogbm9SZW5hbWVJbXBvcnRzLnJ1bGUsXG4gIFtub1NpZGVFZmZlY3RJbXBvcnRzLm5hbWVdOiBub1NpZGVFZmZlY3RJbXBvcnRzLnJ1bGUsXG4gIFtub1RzRmlsZUltcG9ydHMubmFtZV06IG5vVHNGaWxlSW1wb3J0cy5ydWxlLFxuICBbbm9Vc2VsZXNzUGF0aFNlZ21lbnRzLm5hbWVdOiBub1VzZWxlc3NQYXRoU2VnbWVudHMucnVsZSxcbiAgW3JlcXVpcmVkRXhwb3J0cy5uYW1lXTogcmVxdWlyZWRFeHBvcnRzLnJ1bGUsXG59O1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-useless-path-segments.d.ts","sourceRoot":"","sources":["../../src/rules/no-useless-path-segments.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB;;;CAIhC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { create, createRule, getRuleName, getSourceType } from "../common.js";
|
|
3
|
+
export const noUselessPathSegments = createRule({
|
|
4
|
+
name: getRuleName(import.meta.url),
|
|
5
|
+
message: "The relative source path should be a nearest relative path.",
|
|
6
|
+
create: (context) => create(context, check),
|
|
7
|
+
});
|
|
8
|
+
function check(filename, source) {
|
|
9
|
+
if (getSourceType(source) !== "local" ||
|
|
10
|
+
source.startsWith("/") ||
|
|
11
|
+
source === ".") {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (source.endsWith("/")) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
const currentPath = path.dirname(filename);
|
|
18
|
+
const absoluteSource = path.resolve(currentPath, source);
|
|
19
|
+
// compatible with windows
|
|
20
|
+
let resultPath = path
|
|
21
|
+
.relative(currentPath, absoluteSource)
|
|
22
|
+
.replaceAll("\\", "/");
|
|
23
|
+
if (!resultPath.startsWith("./") && !resultPath.startsWith("..")) {
|
|
24
|
+
resultPath = `./${resultPath}`;
|
|
25
|
+
}
|
|
26
|
+
return resultPath !== source;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdXNlbGVzcy1wYXRoLXNlZ21lbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLXVzZWxlc3MtcGF0aC1zZWdtZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU5RSxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxVQUFVLENBQUM7SUFDOUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNsQyxPQUFPLEVBQUUsNkRBQTZEO0lBQ3RFLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUM7Q0FDNUMsQ0FBQyxDQUFDO0FBRUgsU0FBUyxLQUFLLENBQUMsUUFBZ0IsRUFBRSxNQUFjO0lBQzdDLElBQ0UsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLE9BQU87UUFDakMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsRUFDZCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6RCwwQkFBMEI7SUFDMUIsSUFBSSxVQUFVLEdBQUcsSUFBSTtTQUNsQixRQUFRLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQztTQUNyQyxVQUFVLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2pFLFVBQVUsR0FBRyxLQUFLLFVBQVUsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFDRCxPQUFPLFVBQVUsS0FBSyxNQUFNLENBQUM7QUFDL0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGNyZWF0ZSwgY3JlYXRlUnVsZSwgZ2V0UnVsZU5hbWUsIGdldFNvdXJjZVR5cGUgfSBmcm9tIFwiLi4vY29tbW9uLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBub1VzZWxlc3NQYXRoU2VnbWVudHMgPSBjcmVhdGVSdWxlKHtcbiAgbmFtZTogZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKSxcbiAgbWVzc2FnZTogXCJUaGUgcmVsYXRpdmUgc291cmNlIHBhdGggc2hvdWxkIGJlIGEgbmVhcmVzdCByZWxhdGl2ZSBwYXRoLlwiLFxuICBjcmVhdGU6IChjb250ZXh0KSA9PiBjcmVhdGUoY29udGV4dCwgY2hlY2spLFxufSk7XG5cbmZ1bmN0aW9uIGNoZWNrKGZpbGVuYW1lOiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nKSB7XG4gIGlmIChcbiAgICBnZXRTb3VyY2VUeXBlKHNvdXJjZSkgIT09IFwibG9jYWxcIiB8fFxuICAgIHNvdXJjZS5zdGFydHNXaXRoKFwiL1wiKSB8fFxuICAgIHNvdXJjZSA9PT0gXCIuXCJcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChzb3VyY2UuZW5kc1dpdGgoXCIvXCIpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgY29uc3QgY3VycmVudFBhdGggPSBwYXRoLmRpcm5hbWUoZmlsZW5hbWUpO1xuICBjb25zdCBhYnNvbHV0ZVNvdXJjZSA9IHBhdGgucmVzb2x2ZShjdXJyZW50UGF0aCwgc291cmNlKTtcbiAgLy8gY29tcGF0aWJsZSB3aXRoIHdpbmRvd3NcbiAgbGV0IHJlc3VsdFBhdGggPSBwYXRoXG4gICAgLnJlbGF0aXZlKGN1cnJlbnRQYXRoLCBhYnNvbHV0ZVNvdXJjZSlcbiAgICAucmVwbGFjZUFsbChcIlxcXFxcIiwgXCIvXCIpO1xuICBpZiAoIXJlc3VsdFBhdGguc3RhcnRzV2l0aChcIi4vXCIpICYmICFyZXN1bHRQYXRoLnN0YXJ0c1dpdGgoXCIuLlwiKSkge1xuICAgIHJlc3VsdFBhdGggPSBgLi8ke3Jlc3VsdFBhdGh9YDtcbiAgfVxuICByZXR1cm4gcmVzdWx0UGF0aCAhPT0gc291cmNlO1xufVxuIl19
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- prettier-ignore-start -->
|
|
2
|
-
#
|
|
2
|
+
# no-useless-path-segments
|
|
3
3
|
|
|
4
4
|
The relative source path should be a nearest relative path.
|
|
5
5
|
|
|
@@ -27,6 +27,10 @@ import "./../foo" // filename: /a/b/c/d/e.js
|
|
|
27
27
|
import("./../foo") // filename: /a/b/c/d/e.js
|
|
28
28
|
export * from "./../foo" // filename: /a/b/c/d/e.js
|
|
29
29
|
export {a} from "./../foo" // filename: /a/b/c/d/e.js
|
|
30
|
+
import foo from "./" // filename: /a/b/c/d/e.js
|
|
31
|
+
import foo from '../' // filename: /a/b/c/d/e.js
|
|
32
|
+
import foo from '../../' // filename: /a/b/c/d/e.js
|
|
33
|
+
import foo from './..' // filename: /a/b/c/d/e.js
|
|
30
34
|
```
|
|
31
35
|
|
|
32
36
|
### Pass
|
|
@@ -44,5 +48,7 @@ export * from "./a" // filename: /a/b/c/d/e.js
|
|
|
44
48
|
export {a} from "a" // filename: /a/b/c/d/e.js
|
|
45
49
|
export {a} from "./a" // filename: /a/b/c/d/e.js
|
|
46
50
|
import foo from "." // filename: /a/b/c/d/e.js
|
|
51
|
+
import foo from '..' // filename: /a/b/c/d/e.js
|
|
52
|
+
import foo from '../..' // filename: /a/b/c/d/e.js
|
|
47
53
|
```
|
|
48
54
|
<!-- prettier-ignore-end -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-esm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "ESLint plugin for linting ESM (import/export syntax)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@types/estree": "1.0.6",
|
|
30
30
|
"@types/json-schema": "7.0.15",
|
|
31
31
|
"@types/node": "22.9.1",
|
|
32
|
-
"@typescript-eslint/parser": "8.18.
|
|
32
|
+
"@typescript-eslint/parser": "8.18.2",
|
|
33
33
|
"eslint": "8.57.1",
|
|
34
34
|
"outdent": "0.8.0",
|
|
35
35
|
"tsx": "4.19.2"
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { nearestRelativePath } from "./rules/nearest-relative-path.js";
|
|
2
1
|
import { noDirectoryImports } from "./rules/no-directory-imports.js";
|
|
3
2
|
import { noDynamicImports } from "./rules/no-dynamic-imports.js";
|
|
4
3
|
import { noEmptyExports } from "./rules/no-empty-exports.js";
|
|
@@ -9,10 +8,10 @@ import { noRenameExports } from "./rules/no-rename-exports.js";
|
|
|
9
8
|
import { noRenameImports } from "./rules/no-rename-imports.js";
|
|
10
9
|
import { noSideEffectImports } from "./rules/no-side-effect-imports.js";
|
|
11
10
|
import { noTsFileImports } from "./rules/no-ts-file-imports.js";
|
|
11
|
+
import { noUselessPathSegments } from "./rules/no-useless-path-segments.js";
|
|
12
12
|
import { requiredExports } from "./rules/required-exports.js";
|
|
13
13
|
|
|
14
14
|
export const rules = {
|
|
15
|
-
[nearestRelativePath.name]: nearestRelativePath.rule,
|
|
16
15
|
[noDirectoryImports.name]: noDirectoryImports.rule,
|
|
17
16
|
[noDynamicImports.name]: noDynamicImports.rule,
|
|
18
17
|
[noEmptyExports.name]: noEmptyExports.rule,
|
|
@@ -23,5 +22,6 @@ export const rules = {
|
|
|
23
22
|
[noRenameImports.name]: noRenameImports.rule,
|
|
24
23
|
[noSideEffectImports.name]: noSideEffectImports.rule,
|
|
25
24
|
[noTsFileImports.name]: noTsFileImports.rule,
|
|
25
|
+
[noUselessPathSegments.name]: noUselessPathSegments.rule,
|
|
26
26
|
[requiredExports.name]: requiredExports.rule,
|
|
27
27
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { test } from "../test.spec.js";
|
|
2
|
-
import {
|
|
2
|
+
import { noUselessPathSegments } from "./no-useless-path-segments.js";
|
|
3
3
|
|
|
4
4
|
const valid = [
|
|
5
5
|
'import xxx from "../a"',
|
|
@@ -13,7 +13,10 @@ const valid = [
|
|
|
13
13
|
'export * from "./a"',
|
|
14
14
|
'export {a} from "a"',
|
|
15
15
|
'export {a} from "./a"',
|
|
16
|
+
|
|
16
17
|
'import foo from "."',
|
|
18
|
+
"import foo from '..'",
|
|
19
|
+
"import foo from '../..'",
|
|
17
20
|
].map((code) => ({ code, filename: "/a/b/c/d/e.js" }));
|
|
18
21
|
|
|
19
22
|
const invalid = [
|
|
@@ -39,6 +42,11 @@ const invalid = [
|
|
|
39
42
|
'import("./../foo")',
|
|
40
43
|
'export * from "./../foo"',
|
|
41
44
|
'export {a} from "./../foo"',
|
|
45
|
+
|
|
46
|
+
'import foo from "./"',
|
|
47
|
+
"import foo from '../'",
|
|
48
|
+
"import foo from '../../'",
|
|
49
|
+
"import foo from './..'",
|
|
42
50
|
].map((code) => ({ code, filename: "/a/b/c/d/e.js" }));
|
|
43
51
|
|
|
44
|
-
test({ valid, invalid, ...
|
|
52
|
+
test({ valid, invalid, ...noUselessPathSegments });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { create, createRule, getRuleName, getSourceType } from "../common.js";
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const noUselessPathSegments = createRule({
|
|
5
5
|
name: getRuleName(import.meta.url),
|
|
6
6
|
message: "The relative source path should be a nearest relative path.",
|
|
7
7
|
create: (context) => create(context, check),
|
|
@@ -15,13 +15,16 @@ function check(filename: string, source: string) {
|
|
|
15
15
|
) {
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
|
+
if (source.endsWith("/")) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
18
21
|
const currentPath = path.dirname(filename);
|
|
19
22
|
const absoluteSource = path.resolve(currentPath, source);
|
|
20
23
|
// compatible with windows
|
|
21
24
|
let resultPath = path
|
|
22
25
|
.relative(currentPath, absoluteSource)
|
|
23
26
|
.replaceAll("\\", "/");
|
|
24
|
-
if (!resultPath.startsWith("./") && !resultPath.startsWith("
|
|
27
|
+
if (!resultPath.startsWith("./") && !resultPath.startsWith("..")) {
|
|
25
28
|
resultPath = `./${resultPath}`;
|
|
26
29
|
}
|
|
27
30
|
return resultPath !== source;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nearest-relative-path.d.ts","sourceRoot":"","sources":["../../src/rules/nearest-relative-path.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB;;;CAI9B,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { create, createRule, getRuleName, getSourceType } from "../common.js";
|
|
3
|
-
export const nearestRelativePath = createRule({
|
|
4
|
-
name: getRuleName(import.meta.url),
|
|
5
|
-
message: "The relative source path should be a nearest relative path.",
|
|
6
|
-
create: (context) => create(context, check),
|
|
7
|
-
});
|
|
8
|
-
function check(filename, source) {
|
|
9
|
-
if (getSourceType(source) !== "local" ||
|
|
10
|
-
source.startsWith("/") ||
|
|
11
|
-
source === ".") {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
const currentPath = path.dirname(filename);
|
|
15
|
-
const absoluteSource = path.resolve(currentPath, source);
|
|
16
|
-
// compatible with windows
|
|
17
|
-
let resultPath = path
|
|
18
|
-
.relative(currentPath, absoluteSource)
|
|
19
|
-
.replaceAll("\\", "/");
|
|
20
|
-
if (!resultPath.startsWith("./") && !resultPath.startsWith("../")) {
|
|
21
|
-
resultPath = `./${resultPath}`;
|
|
22
|
-
}
|
|
23
|
-
return resultPath !== source;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVhcmVzdC1yZWxhdGl2ZS1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25lYXJlc3QtcmVsYXRpdmUtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU5RSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxVQUFVLENBQUM7SUFDNUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNsQyxPQUFPLEVBQUUsNkRBQTZEO0lBQ3RFLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUM7Q0FDNUMsQ0FBQyxDQUFDO0FBRUgsU0FBUyxLQUFLLENBQUMsUUFBZ0IsRUFBRSxNQUFjO0lBQzdDLElBQ0UsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLE9BQU87UUFDakMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsRUFDZCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6RCwwQkFBMEI7SUFDMUIsSUFBSSxVQUFVLEdBQUcsSUFBSTtTQUNsQixRQUFRLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQztTQUNyQyxVQUFVLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xFLFVBQVUsR0FBRyxLQUFLLFVBQVUsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFDRCxPQUFPLFVBQVUsS0FBSyxNQUFNLENBQUM7QUFDL0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGNyZWF0ZSwgY3JlYXRlUnVsZSwgZ2V0UnVsZU5hbWUsIGdldFNvdXJjZVR5cGUgfSBmcm9tIFwiLi4vY29tbW9uLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBuZWFyZXN0UmVsYXRpdmVQYXRoID0gY3JlYXRlUnVsZSh7XG4gIG5hbWU6IGdldFJ1bGVOYW1lKGltcG9ydC5tZXRhLnVybCksXG4gIG1lc3NhZ2U6IFwiVGhlIHJlbGF0aXZlIHNvdXJjZSBwYXRoIHNob3VsZCBiZSBhIG5lYXJlc3QgcmVsYXRpdmUgcGF0aC5cIixcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4gY3JlYXRlKGNvbnRleHQsIGNoZWNrKSxcbn0pO1xuXG5mdW5jdGlvbiBjaGVjayhmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZykge1xuICBpZiAoXG4gICAgZ2V0U291cmNlVHlwZShzb3VyY2UpICE9PSBcImxvY2FsXCIgfHxcbiAgICBzb3VyY2Uuc3RhcnRzV2l0aChcIi9cIikgfHxcbiAgICBzb3VyY2UgPT09IFwiLlwiXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBjdXJyZW50UGF0aCA9IHBhdGguZGlybmFtZShmaWxlbmFtZSk7XG4gIGNvbnN0IGFic29sdXRlU291cmNlID0gcGF0aC5yZXNvbHZlKGN1cnJlbnRQYXRoLCBzb3VyY2UpO1xuICAvLyBjb21wYXRpYmxlIHdpdGggd2luZG93c1xuICBsZXQgcmVzdWx0UGF0aCA9IHBhdGhcbiAgICAucmVsYXRpdmUoY3VycmVudFBhdGgsIGFic29sdXRlU291cmNlKVxuICAgIC5yZXBsYWNlQWxsKFwiXFxcXFwiLCBcIi9cIik7XG4gIGlmICghcmVzdWx0UGF0aC5zdGFydHNXaXRoKFwiLi9cIikgJiYgIXJlc3VsdFBhdGguc3RhcnRzV2l0aChcIi4uL1wiKSkge1xuICAgIHJlc3VsdFBhdGggPSBgLi8ke3Jlc3VsdFBhdGh9YDtcbiAgfVxuICByZXR1cm4gcmVzdWx0UGF0aCAhPT0gc291cmNlO1xufVxuIl19
|