eslint-plugin-esm 0.0.0 → 0.1.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 +7 -0
- package/README.md +60 -0
- package/dist/common.d.ts +24 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +65 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -2
- package/dist/rules/nearest-relative-path.d.ts +5 -0
- package/dist/rules/nearest-relative-path.d.ts.map +1 -0
- package/dist/rules/nearest-relative-path.js +23 -0
- package/dist/rules/no-directory-imports.d.ts +5 -0
- package/dist/rules/no-directory-imports.d.ts.map +1 -0
- package/dist/rules/no-directory-imports.js +31 -0
- package/dist/rules/no-dynamic-imports.d.ts +5 -0
- package/dist/rules/no-dynamic-imports.d.ts.map +1 -0
- package/dist/rules/no-dynamic-imports.js +14 -0
- package/dist/rules/no-git-ignored-imports.d.ts +5 -0
- package/dist/rules/no-git-ignored-imports.d.ts.map +1 -0
- package/dist/rules/no-git-ignored-imports.js +46 -0
- package/dist/rules/no-phantom-dep-imports.d.ts +5 -0
- package/dist/rules/no-phantom-dep-imports.d.ts.map +1 -0
- package/dist/rules/no-phantom-dep-imports.js +73 -0
- package/dist/rules/no-relative-parent-imports.d.ts +5 -0
- package/dist/rules/no-relative-parent-imports.d.ts.map +1 -0
- package/dist/rules/no-relative-parent-imports.js +11 -0
- package/dist/rules/no-rename-exports.d.ts +5 -0
- package/dist/rules/no-rename-exports.d.ts.map +1 -0
- package/dist/rules/no-rename-exports.js +13 -0
- package/dist/rules/no-rename-imports.d.ts +5 -0
- package/dist/rules/no-rename-imports.d.ts.map +1 -0
- package/dist/rules/no-rename-imports.js +13 -0
- package/dist/rules/no-side-effect-imports.d.ts +5 -0
- package/dist/rules/no-side-effect-imports.d.ts.map +1 -0
- package/dist/rules/no-side-effect-imports.js +33 -0
- package/dist/rules/no-ts-file-imports.d.ts +5 -0
- package/dist/rules/no-ts-file-imports.d.ts.map +1 -0
- package/dist/rules/no-ts-file-imports.js +18 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +16 -0
- package/doc/rules/nearest-relative-path.md +47 -0
- package/doc/rules/no-directory-imports.md +30 -0
- package/doc/rules/no-dynamic-imports.md +30 -0
- package/doc/rules/no-git-ignored-imports.md +36 -0
- package/doc/rules/no-phantom-dep-imports.md +26 -0
- package/doc/rules/no-relative-parent-imports.md +33 -0
- package/doc/rules/no-rename-exports.md +29 -0
- package/doc/rules/no-rename-imports.md +28 -0
- package/doc/rules/no-side-effect-imports.md +31 -0
- package/doc/rules/no-ts-file-imports.md +119 -0
- package/package.json +6 -4
- package/src/common.ts +96 -0
- package/src/index.ts +23 -0
- package/src/rules/nearest-relative-path.spec.ts +43 -0
- package/src/rules/nearest-relative-path.ts +24 -0
- package/src/rules/no-directory-imports.spec.ts +31 -0
- package/src/rules/no-directory-imports.ts +34 -0
- package/src/rules/no-dynamic-imports.spec.ts +27 -0
- package/src/rules/no-dynamic-imports.ts +15 -0
- package/src/rules/no-git-ignored-imports.spec.ts +40 -0
- package/src/rules/no-git-ignored-imports.ts +53 -0
- package/src/rules/no-phantom-dep-imports.spec.ts +28 -0
- package/src/rules/no-phantom-dep-imports.ts +90 -0
- package/src/rules/no-relative-parent-imports.spec.ts +28 -0
- package/src/rules/no-relative-parent-imports.ts +13 -0
- package/src/rules/no-rename-exports.spec.ts +22 -0
- package/src/rules/no-rename-exports.ts +13 -0
- package/src/rules/no-rename-imports.spec.ts +22 -0
- package/src/rules/no-rename-imports.ts +13 -0
- package/src/rules/no-side-effect-imports.spec.ts +25 -0
- package/src/rules/no-side-effect-imports.ts +44 -0
- package/src/rules/no-ts-file-imports.spec.ts +39 -0
- package/src/rules/no-ts-file-imports.ts +23 -0
- package/src/test.spec.ts +110 -0
- package/src/utils.ts +15 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createRule, DEFAULT_MESSAGE_ID, getRuleName } from "../common.js";
|
|
2
|
+
const ignores = [
|
|
3
|
+
"^reflect-metadata$",
|
|
4
|
+
// https://github.com/vitejs/vite/blob/main/packages/vite/client.d.ts
|
|
5
|
+
"(?<!\\.module)\\.css$",
|
|
6
|
+
"(?<!\\.module)\\.scss$",
|
|
7
|
+
"(?<!\\.module)\\.sass$",
|
|
8
|
+
"(?<!\\.module)\\.less$",
|
|
9
|
+
"(?<!\\.module)\\.styl$",
|
|
10
|
+
"(?<!\\.module)\\.stylus$",
|
|
11
|
+
"(?<!\\.module)\\.pcss$",
|
|
12
|
+
"(?<!\\.module)\\.sss$",
|
|
13
|
+
];
|
|
14
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
|
|
15
|
+
export const noSideEffectImports = createRule({
|
|
16
|
+
name: getRuleName(import.meta.url),
|
|
17
|
+
message: "Side effect import is often used for polyfills and css. It's unsafe to use it.",
|
|
18
|
+
create: (context) => {
|
|
19
|
+
if ([".d.ts", ".d.cts", ".d.mts", ".d.tsx"].some((ext) => context.filename.endsWith(ext))) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const ignoreExps = ignores.map((ignore) => new RegExp(ignore));
|
|
23
|
+
return {
|
|
24
|
+
"ImportDeclaration[specifiers.length=0]": (node) => {
|
|
25
|
+
if (ignoreExps.some((exp) => exp.test(node.source.value?.toString() ?? ""))) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
context.report({ node, messageId: DEFAULT_MESSAGE_ID });
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tc2lkZS1lZmZlY3QtaW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1zaWRlLWVmZmVjdC1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQUUsa0JBQWtCLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTNFLE1BQU0sT0FBTyxHQUFHO0lBQ2Qsb0JBQW9CO0lBQ3BCLHFFQUFxRTtJQUNyRSx1QkFBdUI7SUFDdkIsd0JBQXdCO0lBQ3hCLHdCQUF3QjtJQUN4Qix3QkFBd0I7SUFDeEIsd0JBQXdCO0lBQ3hCLDBCQUEwQjtJQUMxQix3QkFBd0I7SUFDeEIsdUJBQXVCO0NBQ3hCLENBQUM7QUFFRixzRkFBc0Y7QUFDdEYsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsVUFBVSxDQUFDO0lBQzVDLElBQUksRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbEMsT0FBTyxFQUNMLGdGQUFnRjtJQUNsRixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNsQixJQUNFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDbkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQy9CLEVBQ0QsQ0FBQztZQUNELE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDL0QsT0FBTztZQUNMLHdDQUF3QyxFQUFFLENBQUMsSUFBdUIsRUFBRSxFQUFFO2dCQUNwRSxJQUNFLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUN0QixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUM5QyxFQUNELENBQUM7b0JBQ0QsT0FBTztnQkFDVCxDQUFDO2dCQUNELE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztZQUMxRCxDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEltcG9ydERlY2xhcmF0aW9uIH0gZnJvbSBcImVzdHJlZVwiO1xuaW1wb3J0IHsgY3JlYXRlUnVsZSwgREVGQVVMVF9NRVNTQUdFX0lELCBnZXRSdWxlTmFtZSB9IGZyb20gXCIuLi9jb21tb24uanNcIjtcblxuY29uc3QgaWdub3JlcyA9IFtcbiAgXCJecmVmbGVjdC1tZXRhZGF0YSRcIixcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3ZpdGVqcy92aXRlL2Jsb2IvbWFpbi9wYWNrYWdlcy92aXRlL2NsaWVudC5kLnRzXG4gIFwiKD88IVxcXFwubW9kdWxlKVxcXFwuY3NzJFwiLFxuICBcIig/PCFcXFxcLm1vZHVsZSlcXFxcLnNjc3MkXCIsXG4gIFwiKD88IVxcXFwubW9kdWxlKVxcXFwuc2FzcyRcIixcbiAgXCIoPzwhXFxcXC5tb2R1bGUpXFxcXC5sZXNzJFwiLFxuICBcIig/PCFcXFxcLm1vZHVsZSlcXFxcLnN0eWwkXCIsXG4gIFwiKD88IVxcXFwubW9kdWxlKVxcXFwuc3R5bHVzJFwiLFxuICBcIig/PCFcXFxcLm1vZHVsZSlcXFxcLnBjc3MkXCIsXG4gIFwiKD88IVxcXFwubW9kdWxlKVxcXFwuc3NzJFwiLFxuXTtcblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvU3RhdGVtZW50cy9pbXBvcnRcbmV4cG9ydCBjb25zdCBub1NpZGVFZmZlY3RJbXBvcnRzID0gY3JlYXRlUnVsZSh7XG4gIG5hbWU6IGdldFJ1bGVOYW1lKGltcG9ydC5tZXRhLnVybCksXG4gIG1lc3NhZ2U6XG4gICAgXCJTaWRlIGVmZmVjdCBpbXBvcnQgaXMgb2Z0ZW4gdXNlZCBmb3IgcG9seWZpbGxzIGFuZCBjc3MuIEl0J3MgdW5zYWZlIHRvIHVzZSBpdC5cIixcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4ge1xuICAgIGlmIChcbiAgICAgIFtcIi5kLnRzXCIsIFwiLmQuY3RzXCIsIFwiLmQubXRzXCIsIFwiLmQudHN4XCJdLnNvbWUoKGV4dCkgPT5cbiAgICAgICAgY29udGV4dC5maWxlbmFtZS5lbmRzV2l0aChleHQpLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBpZ25vcmVFeHBzID0gaWdub3Jlcy5tYXAoKGlnbm9yZSkgPT4gbmV3IFJlZ0V4cChpZ25vcmUpKTtcbiAgICByZXR1cm4ge1xuICAgICAgXCJJbXBvcnREZWNsYXJhdGlvbltzcGVjaWZpZXJzLmxlbmd0aD0wXVwiOiAobm9kZTogSW1wb3J0RGVjbGFyYXRpb24pID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGlnbm9yZUV4cHMuc29tZSgoZXhwKSA9PlxuICAgICAgICAgICAgZXhwLnRlc3Qobm9kZS5zb3VyY2UudmFsdWU/LnRvU3RyaW5nKCkgPz8gXCJcIiksXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlSWQ6IERFRkFVTFRfTUVTU0FHRV9JRCB9KTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfSxcbn0pO1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-ts-file-imports.d.ts","sourceRoot":"","sources":["../../src/rules/no-ts-file-imports.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe;;;CAI1B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { create, createRule, getRuleName } from "../common.js";
|
|
2
|
+
export const noTsFileImports = createRule({
|
|
3
|
+
name: getRuleName(import.meta.url),
|
|
4
|
+
message: "Disallow importing from a declaration style file or a ts file",
|
|
5
|
+
create: (context) => create(context, check),
|
|
6
|
+
});
|
|
7
|
+
function check(filename, source) {
|
|
8
|
+
// disabled this rule in declaration files
|
|
9
|
+
if ([".d.ts", ".d.cts", ".d.mts", ".d.tsx"].some((ext) => filename.endsWith(ext))) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const file = source.split("/").at(-1);
|
|
13
|
+
if (!file || file.includes(".d.")) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return [".ts", ".cts", ".mts", ".tsx"].some((ext) => file.endsWith(ext));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdHMtZmlsZS1pbXBvcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLXRzLWZpbGUtaW1wb3J0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFL0QsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQztJQUN4QyxJQUFJLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2xDLE9BQU8sRUFBRSwrREFBK0Q7SUFDeEUsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQztDQUM1QyxDQUFDLENBQUM7QUFFSCxTQUFTLEtBQUssQ0FBQyxRQUFnQixFQUFFLE1BQWM7SUFDN0MsMENBQTBDO0lBQzFDLElBQ0UsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUNuRCxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUN2QixFQUNELENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlLCBjcmVhdGVSdWxlLCBnZXRSdWxlTmFtZSB9IGZyb20gXCIuLi9jb21tb24uanNcIjtcblxuZXhwb3J0IGNvbnN0IG5vVHNGaWxlSW1wb3J0cyA9IGNyZWF0ZVJ1bGUoe1xuICBuYW1lOiBnZXRSdWxlTmFtZShpbXBvcnQubWV0YS51cmwpLFxuICBtZXNzYWdlOiBcIkRpc2FsbG93IGltcG9ydGluZyBmcm9tIGEgZGVjbGFyYXRpb24gc3R5bGUgZmlsZSBvciBhIHRzIGZpbGVcIixcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4gY3JlYXRlKGNvbnRleHQsIGNoZWNrKSxcbn0pO1xuXG5mdW5jdGlvbiBjaGVjayhmaWxlbmFtZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZykge1xuICAvLyBkaXNhYmxlZCB0aGlzIHJ1bGUgaW4gZGVjbGFyYXRpb24gZmlsZXNcbiAgaWYgKFxuICAgIFtcIi5kLnRzXCIsIFwiLmQuY3RzXCIsIFwiLmQubXRzXCIsIFwiLmQudHN4XCJdLnNvbWUoKGV4dCkgPT5cbiAgICAgIGZpbGVuYW1lLmVuZHNXaXRoKGV4dCksXG4gICAgKVxuICApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgZmlsZSA9IHNvdXJjZS5zcGxpdChcIi9cIikuYXQoLTEpO1xuICBpZiAoIWZpbGUgfHwgZmlsZS5pbmNsdWRlcyhcIi5kLlwiKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBbXCIudHNcIiwgXCIuY3RzXCIsIFwiLm10c1wiLCBcIi50c3hcIl0uc29tZSgoZXh0KSA9PiBmaWxlLmVuZHNXaXRoKGV4dCkpO1xufVxuIl19
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAW1E"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Like [lodash.memoize](https://lodash.com/docs/4.17.15#memoize)
|
|
3
|
+
*/
|
|
4
|
+
export function memoize(fn) {
|
|
5
|
+
const cache = new Map(); // memory leak
|
|
6
|
+
return (arg) => {
|
|
7
|
+
if (cache.has(arg)) {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
9
|
+
return cache.get(arg);
|
|
10
|
+
}
|
|
11
|
+
const result = fn(arg);
|
|
12
|
+
cache.set(arg, result);
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFXLEVBQXFCO0lBQ3JELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFZLENBQUMsQ0FBQyxjQUFjO0lBQ2pELE9BQU8sQ0FBQyxHQUFRLEVBQUUsRUFBRTtRQUNsQixJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNuQixvRUFBb0U7WUFDcEUsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBRSxDQUFDO1FBQ3pCLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGlrZSBbbG9kYXNoLm1lbW9pemVdKGh0dHBzOi8vbG9kYXNoLmNvbS9kb2NzLzQuMTcuMTUjbWVtb2l6ZSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lbW9pemU8QXJnLCBSZXM+KGZuOiAoYXJnOiBBcmcpID0+IFJlcyk6IChhcmc6IEFyZykgPT4gUmVzIHtcbiAgY29uc3QgY2FjaGUgPSBuZXcgTWFwPEFyZywgUmVzPigpOyAvLyBtZW1vcnkgbGVha1xuICByZXR1cm4gKGFyZzogQXJnKSA9PiB7XG4gICAgaWYgKGNhY2hlLmhhcyhhcmcpKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgcmV0dXJuIGNhY2hlLmdldChhcmcpITtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gZm4oYXJnKTtcbiAgICBjYWNoZS5zZXQoYXJnLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG4iXX0=
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# nearest-relative-path
|
|
3
|
+
|
|
4
|
+
The relative source path should be a nearest relative path.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import xxx from ".././../a" // filename: /a/b/c/d/e.js
|
|
12
|
+
import ".././../a" // filename: /a/b/c/d/e.js
|
|
13
|
+
import(".././../a") // filename: /a/b/c/d/e.js
|
|
14
|
+
export * from ".././../a" // filename: /a/b/c/d/e.js
|
|
15
|
+
export {a} from ".././../a" // filename: /a/b/c/d/e.js
|
|
16
|
+
import xxx from "./../a" // filename: /a/b/c/d/e.js
|
|
17
|
+
import "./../a" // filename: /a/b/c/d/e.js
|
|
18
|
+
import("./../a") // filename: /a/b/c/d/e.js
|
|
19
|
+
export * from "./../a" // filename: /a/b/c/d/e.js
|
|
20
|
+
export {a} from "./../a" // filename: /a/b/c/d/e.js
|
|
21
|
+
import "././foo" // filename: /a/b/c/d/e.js
|
|
22
|
+
import "./../.././foo" // filename: /a/b/c/d/e.js
|
|
23
|
+
import("./../.././foo") // filename: /a/b/c/d/e.js
|
|
24
|
+
export * from "./../.././foo" // filename: /a/b/c/d/e.js
|
|
25
|
+
export {a} from "./../.././foo" // filename: /a/b/c/d/e.js
|
|
26
|
+
import "./../foo" // filename: /a/b/c/d/e.js
|
|
27
|
+
import("./../foo") // filename: /a/b/c/d/e.js
|
|
28
|
+
export * from "./../foo" // filename: /a/b/c/d/e.js
|
|
29
|
+
export {a} from "./../foo" // filename: /a/b/c/d/e.js
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Pass
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import xxx from "../a" // filename: /a/b/c/d/e.js
|
|
36
|
+
import "../a" // filename: /a/b/c/d/e.js
|
|
37
|
+
import("../a") // filename: /a/b/c/d/e.js
|
|
38
|
+
require("../a") // filename: /a/b/c/d/e.js
|
|
39
|
+
import xxx from "./a" // filename: /a/b/c/d/e.js
|
|
40
|
+
import xxx from "a" // filename: /a/b/c/d/e.js
|
|
41
|
+
import xxx from ".a" // filename: /a/b/c/d/e.js
|
|
42
|
+
export * from "a" // filename: /a/b/c/d/e.js
|
|
43
|
+
export * from "./a" // filename: /a/b/c/d/e.js
|
|
44
|
+
export {a} from "a" // filename: /a/b/c/d/e.js
|
|
45
|
+
export {a} from "./a" // filename: /a/b/c/d/e.js
|
|
46
|
+
```
|
|
47
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-directory-imports
|
|
3
|
+
|
|
4
|
+
Disallow importing from a directory.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import foo from '.' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
12
|
+
import foo from './' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
13
|
+
import foo from '..' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
14
|
+
import foo from '../' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
15
|
+
import foo from '../rules' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
16
|
+
import foo from '../rules/' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
17
|
+
import foo from '../../src' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
18
|
+
import foo from '/foo' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Pass
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import foo from 'foo' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
25
|
+
import foo from './foo' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
26
|
+
import foo from '/foo/index.js' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
27
|
+
import foo from '/foo/index.ts' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
28
|
+
import foo from '/foo/package.json' // filename: /foo/src/rules/no-directory-imports.spec.ts
|
|
29
|
+
```
|
|
30
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-dynamic-imports
|
|
3
|
+
|
|
4
|
+
`import()` should be called with string literal.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import(false)
|
|
12
|
+
import(123)
|
|
13
|
+
await import(123)
|
|
14
|
+
import(`foo`)
|
|
15
|
+
import(foo)
|
|
16
|
+
import({})
|
|
17
|
+
import([])
|
|
18
|
+
const foo = await import(foo)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Pass
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import('foo')
|
|
25
|
+
import("foo")
|
|
26
|
+
import("./foo")
|
|
27
|
+
await import("foo")
|
|
28
|
+
const foo = await import("foo")
|
|
29
|
+
```
|
|
30
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-git-ignored-imports
|
|
3
|
+
|
|
4
|
+
Disallow to import module from a git-ignored path.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import foo from './dist/foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
12
|
+
import './dist/foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
13
|
+
import('./dist/foo') // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
14
|
+
export * from './dist/foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
15
|
+
export {name} from './dist/foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
16
|
+
import foo from '../dist/index.js' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
17
|
+
import foo from '../../node_modules/foo/bar.js' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
18
|
+
import foo from '/foo/tmp' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
19
|
+
import foo from '/foo/tmp' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
20
|
+
import foo from '../../test/for-test' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
21
|
+
import foo from '../../../../../for-test' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Pass
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import foo from 'foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
28
|
+
import 'foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
29
|
+
require('foo') // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
30
|
+
import('foo') // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
31
|
+
export * from 'foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
32
|
+
export {name} from 'foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
33
|
+
import foo from '.foo' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
34
|
+
import foo from '../../../../for-test' // filename: /foo/src/rules/no-git-ignored-imports.spec.ts
|
|
35
|
+
```
|
|
36
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-phantom-dep-imports
|
|
3
|
+
|
|
4
|
+
Disallow importing from a module which the nearest `package.json` doesn't include it.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {type Foo} from 'foo'
|
|
12
|
+
import foo from 'foo' // filename: /foo/src/rules/no-phantom-dep-imports.spec.ts
|
|
13
|
+
import eslint from 'eslint' // filename: /foo/foo.js
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Pass
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import foo from '/foo'
|
|
20
|
+
import foo from './foo'
|
|
21
|
+
import foo from '../foo'
|
|
22
|
+
import foo from 'node:foo'
|
|
23
|
+
import type {Foo} from 'foo'
|
|
24
|
+
import eslint from 'eslint' // filename: /foo/src/rules/no-phantom-dep-imports.spec.ts
|
|
25
|
+
```
|
|
26
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-relative-parent-imports
|
|
3
|
+
|
|
4
|
+
Disallow importing module from a relative parent path too deeply.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import foo from '../../../foo'
|
|
12
|
+
import '../../../foo'
|
|
13
|
+
import('../../../foo')
|
|
14
|
+
export * from '../../../foo'
|
|
15
|
+
export {name} from '../../../foo'
|
|
16
|
+
import foo from '../../../../foo'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Pass
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import foo from 'foo'
|
|
23
|
+
import 'foo'
|
|
24
|
+
require('foo')
|
|
25
|
+
import('foo')
|
|
26
|
+
export * from 'foo'
|
|
27
|
+
export {name} from 'foo'
|
|
28
|
+
import foo from '.foo'
|
|
29
|
+
import foo from './foo'
|
|
30
|
+
import foo from '../foo'
|
|
31
|
+
import foo from '../../foo'
|
|
32
|
+
```
|
|
33
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-rename-exports
|
|
3
|
+
|
|
4
|
+
Disallow renaming the named-exports.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
let foo=1; export {foo as bar}
|
|
12
|
+
let foo=1; export {foo as default}
|
|
13
|
+
export {foo as bar} from './foo'
|
|
14
|
+
export {default as foo} from './foo'
|
|
15
|
+
export {type Foo as Bar}
|
|
16
|
+
export type {Foo as Bar}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Pass
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
let foo=1; export {foo}
|
|
23
|
+
export let foo
|
|
24
|
+
export const foo = bar
|
|
25
|
+
export default foo
|
|
26
|
+
export default {}
|
|
27
|
+
export {}
|
|
28
|
+
```
|
|
29
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-rename-imports
|
|
3
|
+
|
|
4
|
+
Disallow renaming the named-imports.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {foo as bar} from 'foo'
|
|
12
|
+
import {default as foo} from 'foo'
|
|
13
|
+
import type {foo as bar} from 'foo'
|
|
14
|
+
import {type foo as bar} from 'foo'
|
|
15
|
+
import type {default as foo} from 'foo'
|
|
16
|
+
import {type default as foo} from 'foo'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Pass
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import Foo from 'foo'
|
|
23
|
+
import {foo, bar} from 'foo'
|
|
24
|
+
import {type foo} from 'foo'
|
|
25
|
+
import type {foo} from 'foo'
|
|
26
|
+
import type Foo from 'foo'
|
|
27
|
+
```
|
|
28
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-side-effect-imports
|
|
3
|
+
|
|
4
|
+
Side effect import is often used for polyfills and css. It's unsafe to use it.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import 'foo' // filename: foo.ts
|
|
12
|
+
import './foo' // filename: foo.ts
|
|
13
|
+
import {} from 'foo' // filename: foo.ts
|
|
14
|
+
import {} from './foo' // filename: foo.ts
|
|
15
|
+
import './reflect-metadata' // filename: foo.ts
|
|
16
|
+
import './foo.module.css' // filename: foo.ts
|
|
17
|
+
import 'foo.module.css' // filename: foo.ts
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Pass
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import 'reflect-metadata' // filename: foo.ts
|
|
24
|
+
import {} from 'reflect-metadata' // filename: foo.ts
|
|
25
|
+
import 'foo.css' // filename: foo.ts
|
|
26
|
+
import './foo.css' // filename: foo.ts
|
|
27
|
+
import 'module.css' // filename: foo.ts
|
|
28
|
+
import {foo} from 'foo' // filename: foo.ts
|
|
29
|
+
import 'foo' // filename: foo.d.ts
|
|
30
|
+
```
|
|
31
|
+
<!-- prettier-ignore-end -->
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<!-- prettier-ignore-start -->
|
|
2
|
+
# no-ts-file-imports
|
|
3
|
+
|
|
4
|
+
Disallow importing from a declaration style file or a ts file
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Fail
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import foo from './foo.ts' // filename: bar.js
|
|
12
|
+
import foo from './foo.ts' // filename: bar
|
|
13
|
+
import foo from './foo.ts' // filename: bar.ts
|
|
14
|
+
import foo from './foo.ts' // filename: bar.tsx
|
|
15
|
+
import foo from './foo.cts' // filename: bar.js
|
|
16
|
+
import foo from './foo.cts' // filename: bar
|
|
17
|
+
import foo from './foo.cts' // filename: bar.ts
|
|
18
|
+
import foo from './foo.cts' // filename: bar.tsx
|
|
19
|
+
import foo from './foo.mts' // filename: bar.js
|
|
20
|
+
import foo from './foo.mts' // filename: bar
|
|
21
|
+
import foo from './foo.mts' // filename: bar.ts
|
|
22
|
+
import foo from './foo.mts' // filename: bar.tsx
|
|
23
|
+
import foo from './foo.tsx' // filename: bar.js
|
|
24
|
+
import foo from './foo.tsx' // filename: bar
|
|
25
|
+
import foo from './foo.tsx' // filename: bar.ts
|
|
26
|
+
import foo from './foo.tsx' // filename: bar.tsx
|
|
27
|
+
import foo from 'foo.d.bar' // filename: bar.js
|
|
28
|
+
import foo from 'foo.d.bar' // filename: bar
|
|
29
|
+
import foo from 'foo.d.bar' // filename: bar.ts
|
|
30
|
+
import foo from 'foo.d.bar' // filename: bar.tsx
|
|
31
|
+
import foo from './foo.d.bar' // filename: bar.js
|
|
32
|
+
import foo from './foo.d.bar' // filename: bar
|
|
33
|
+
import foo from './foo.d.bar' // filename: bar.ts
|
|
34
|
+
import foo from './foo.d.bar' // filename: bar.tsx
|
|
35
|
+
import foo from './foo/foo.d.bar' // filename: bar.js
|
|
36
|
+
import foo from './foo/foo.d.bar' // filename: bar
|
|
37
|
+
import foo from './foo/foo.d.bar' // filename: bar.ts
|
|
38
|
+
import foo from './foo/foo.d.bar' // filename: bar.tsx
|
|
39
|
+
import foo from './foo.d.ts' // filename: bar.js
|
|
40
|
+
import foo from './foo.d.ts' // filename: bar
|
|
41
|
+
import foo from './foo.d.ts' // filename: bar.ts
|
|
42
|
+
import foo from './foo.d.ts' // filename: bar.tsx
|
|
43
|
+
import foo from './foo.d.cts' // filename: bar.js
|
|
44
|
+
import foo from './foo.d.cts' // filename: bar
|
|
45
|
+
import foo from './foo.d.cts' // filename: bar.ts
|
|
46
|
+
import foo from './foo.d.cts' // filename: bar.tsx
|
|
47
|
+
import foo from './foo.d.mts' // filename: bar.js
|
|
48
|
+
import foo from './foo.d.mts' // filename: bar
|
|
49
|
+
import foo from './foo.d.mts' // filename: bar.ts
|
|
50
|
+
import foo from './foo.d.mts' // filename: bar.tsx
|
|
51
|
+
import foo from './foo.d.tsx' // filename: bar.js
|
|
52
|
+
import foo from './foo.d.tsx' // filename: bar
|
|
53
|
+
import foo from './foo.d.tsx' // filename: bar.ts
|
|
54
|
+
import foo from './foo.d.tsx' // filename: bar.tsx
|
|
55
|
+
import foo from './foo.d.js' // filename: bar.js
|
|
56
|
+
import foo from './foo.d.js' // filename: bar
|
|
57
|
+
import foo from './foo.d.js' // filename: bar.ts
|
|
58
|
+
import foo from './foo.d.js' // filename: bar.tsx
|
|
59
|
+
import foo from './foo.d.cjs' // filename: bar.js
|
|
60
|
+
import foo from './foo.d.cjs' // filename: bar
|
|
61
|
+
import foo from './foo.d.cjs' // filename: bar.ts
|
|
62
|
+
import foo from './foo.d.cjs' // filename: bar.tsx
|
|
63
|
+
import foo from './foo.d.mjs' // filename: bar.js
|
|
64
|
+
import foo from './foo.d.mjs' // filename: bar
|
|
65
|
+
import foo from './foo.d.mjs' // filename: bar.ts
|
|
66
|
+
import foo from './foo.d.mjs' // filename: bar.tsx
|
|
67
|
+
import foo from './foo.d.jsx' // filename: bar.js
|
|
68
|
+
import foo from './foo.d.jsx' // filename: bar
|
|
69
|
+
import foo from './foo.d.jsx' // filename: bar.ts
|
|
70
|
+
import foo from './foo.d.jsx' // filename: bar.tsx
|
|
71
|
+
import foo from '/foo.ts' // filename: bar.js
|
|
72
|
+
import foo from '/foo.ts' // filename: bar
|
|
73
|
+
import foo from '/foo.ts' // filename: bar.ts
|
|
74
|
+
import foo from '/foo.ts' // filename: bar.tsx
|
|
75
|
+
import foo from '/foo.d.js' // filename: bar.js
|
|
76
|
+
import foo from '/foo.d.js' // filename: bar
|
|
77
|
+
import foo from '/foo.d.js' // filename: bar.ts
|
|
78
|
+
import foo from '/foo.d.js' // filename: bar.tsx
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Pass
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import foo from './foo.ts' // filename: bar.d.ts
|
|
85
|
+
import foo from './foo.ts' // filename: bar.d.tsx
|
|
86
|
+
import foo from './foo.cts' // filename: bar.d.ts
|
|
87
|
+
import foo from './foo.cts' // filename: bar.d.tsx
|
|
88
|
+
import foo from './foo.mts' // filename: bar.d.ts
|
|
89
|
+
import foo from './foo.mts' // filename: bar.d.tsx
|
|
90
|
+
import foo from './foo.tsx' // filename: bar.d.ts
|
|
91
|
+
import foo from './foo.tsx' // filename: bar.d.tsx
|
|
92
|
+
import foo from 'foo.d.bar' // filename: bar.d.ts
|
|
93
|
+
import foo from 'foo.d.bar' // filename: bar.d.tsx
|
|
94
|
+
import foo from './foo.d.bar' // filename: bar.d.ts
|
|
95
|
+
import foo from './foo.d.bar' // filename: bar.d.tsx
|
|
96
|
+
import foo from './foo/foo.d.bar' // filename: bar.d.ts
|
|
97
|
+
import foo from './foo/foo.d.bar' // filename: bar.d.tsx
|
|
98
|
+
import foo from './foo.d.ts' // filename: bar.d.ts
|
|
99
|
+
import foo from './foo.d.ts' // filename: bar.d.tsx
|
|
100
|
+
import foo from './foo.d.cts' // filename: bar.d.ts
|
|
101
|
+
import foo from './foo.d.cts' // filename: bar.d.tsx
|
|
102
|
+
import foo from './foo.d.mts' // filename: bar.d.ts
|
|
103
|
+
import foo from './foo.d.mts' // filename: bar.d.tsx
|
|
104
|
+
import foo from './foo.d.tsx' // filename: bar.d.ts
|
|
105
|
+
import foo from './foo.d.tsx' // filename: bar.d.tsx
|
|
106
|
+
import foo from './foo.d.js' // filename: bar.d.ts
|
|
107
|
+
import foo from './foo.d.js' // filename: bar.d.tsx
|
|
108
|
+
import foo from './foo.d.cjs' // filename: bar.d.ts
|
|
109
|
+
import foo from './foo.d.cjs' // filename: bar.d.tsx
|
|
110
|
+
import foo from './foo.d.mjs' // filename: bar.d.ts
|
|
111
|
+
import foo from './foo.d.mjs' // filename: bar.d.tsx
|
|
112
|
+
import foo from './foo.d.jsx' // filename: bar.d.ts
|
|
113
|
+
import foo from './foo.d.jsx' // filename: bar.d.tsx
|
|
114
|
+
import foo from '/foo.ts' // filename: bar.d.ts
|
|
115
|
+
import foo from '/foo.ts' // filename: bar.d.tsx
|
|
116
|
+
import foo from '/foo.d.js' // filename: bar.d.ts
|
|
117
|
+
import foo from '/foo.d.js' // filename: bar.d.tsx
|
|
118
|
+
```
|
|
119
|
+
<!-- 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.1.0",
|
|
4
4
|
"description": "ESLint plugin for linting ESM (import/export syntax)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -29,11 +29,13 @@
|
|
|
29
29
|
"@types/eslint": "8.56.11",
|
|
30
30
|
"@types/estree": "1.0.5",
|
|
31
31
|
"@types/json-schema": "7.0.15",
|
|
32
|
-
"@types/node": "22.5.
|
|
32
|
+
"@types/node": "22.5.5",
|
|
33
33
|
"@typescript-eslint/parser": "7.16.1",
|
|
34
|
-
"eslint": "8.57.0"
|
|
34
|
+
"eslint": "8.57.0",
|
|
35
|
+
"outdent": "0.8.0"
|
|
35
36
|
},
|
|
36
37
|
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.build.json"
|
|
38
|
+
"build": "tsc -p tsconfig.build.json",
|
|
39
|
+
"test": "globstar -- node --test --import @swc-node/register/esm-register src/**/*.spec.ts"
|
|
38
40
|
}
|
|
39
41
|
}
|
package/src/common.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import type { Rule } from "eslint";
|
|
4
|
+
import type {
|
|
5
|
+
ExportAllDeclaration,
|
|
6
|
+
ExportNamedDeclaration,
|
|
7
|
+
ImportDeclaration,
|
|
8
|
+
ImportExpression,
|
|
9
|
+
} from "estree";
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_MESSAGE_ID = "default";
|
|
12
|
+
|
|
13
|
+
export function createRule({
|
|
14
|
+
name,
|
|
15
|
+
message,
|
|
16
|
+
// schema,
|
|
17
|
+
fixable,
|
|
18
|
+
type = "suggestion",
|
|
19
|
+
create,
|
|
20
|
+
}: {
|
|
21
|
+
name: string;
|
|
22
|
+
message: string;
|
|
23
|
+
// schema?: JSONSchema4[];
|
|
24
|
+
fixable?: Rule.RuleMetaData["fixable"];
|
|
25
|
+
type?: Rule.RuleMetaData["type"];
|
|
26
|
+
create: (context: Rule.RuleContext) => Rule.RuleListener;
|
|
27
|
+
}): { name: string; rule: Rule.RuleModule } {
|
|
28
|
+
const rule: Rule.RuleModule = {
|
|
29
|
+
meta: {
|
|
30
|
+
// ...(schema && { schema }),
|
|
31
|
+
...(fixable && { fixable }),
|
|
32
|
+
messages: {
|
|
33
|
+
[DEFAULT_MESSAGE_ID]: message,
|
|
34
|
+
},
|
|
35
|
+
type,
|
|
36
|
+
docs: {
|
|
37
|
+
// TODO: add url
|
|
38
|
+
description: message,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
create,
|
|
42
|
+
};
|
|
43
|
+
return { name, rule };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getRuleName(importMetaUrl: string) {
|
|
47
|
+
// remove '.js' extension
|
|
48
|
+
return path.basename(fileURLToPath(importMetaUrl)).slice(0, -3);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type ImportationNode =
|
|
52
|
+
| ImportDeclaration
|
|
53
|
+
| ImportExpression
|
|
54
|
+
| ExportAllDeclaration
|
|
55
|
+
| ExportNamedDeclaration;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Create ESLint RuleListener to check string importation source.
|
|
59
|
+
* @param context ESLint RuleContext
|
|
60
|
+
* @param check the check logic
|
|
61
|
+
* @returns ESLint RuleListener
|
|
62
|
+
*/
|
|
63
|
+
export const create = (
|
|
64
|
+
context: Rule.RuleContext,
|
|
65
|
+
check: (filename: string, source: string, node: ImportationNode) => boolean,
|
|
66
|
+
): Rule.RuleListener => {
|
|
67
|
+
const handle = (node: ImportationNode) => {
|
|
68
|
+
if (!node.source) return;
|
|
69
|
+
if (!("value" in node.source)) return;
|
|
70
|
+
if (typeof node.source.value !== "string") return;
|
|
71
|
+
if (check(context.filename, node.source.value, node))
|
|
72
|
+
context.report({ node: node.source, messageId: DEFAULT_MESSAGE_ID });
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
ImportDeclaration: handle,
|
|
76
|
+
ImportExpression: handle,
|
|
77
|
+
ExportAllDeclaration: handle,
|
|
78
|
+
ExportNamedDeclaration: handle,
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export function getSourceType(source: string) {
|
|
83
|
+
if (
|
|
84
|
+
source.startsWith("/") ||
|
|
85
|
+
source.startsWith("./") ||
|
|
86
|
+
source.startsWith("../") ||
|
|
87
|
+
source === "." ||
|
|
88
|
+
source === ".."
|
|
89
|
+
) {
|
|
90
|
+
return "local";
|
|
91
|
+
}
|
|
92
|
+
if (source.startsWith("node:")) {
|
|
93
|
+
return "builtin";
|
|
94
|
+
}
|
|
95
|
+
return "module";
|
|
96
|
+
}
|