@crutchcrew/oxlint-plugin-import-access 1.0.1 → 1.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/README.md +1 -1
- package/dist/core/checkImportability.d.ts +5 -0
- package/dist/index.js +38 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ This plugin adds a directory-level layer between a file and the whole project: a
|
|
|
38
38
|
| **Checks unsaved edits in the editor** | ✅ | ✅ | ❌ skipped until saved |
|
|
39
39
|
| **Same results as the original rule** | ✅ verified¹ | – | ✅ |
|
|
40
40
|
|
|
41
|
-
¹ With `defaultImportability: "public"`, which makes exports without an access tag `@public` like in the original. This plugin's default is `"package"`.
|
|
41
|
+
¹ With `defaultImportability: "public"`, which makes exports without an access tag `@public` like in the original. This plugin's default is `"package"`. This plugin also checks the members used through namespace imports (`import * as foo`), which the original doesn't check.
|
|
42
42
|
|
|
43
43
|
## Install
|
|
44
44
|
|
|
@@ -53,6 +53,11 @@ export declare class ImportabilityPolicy {
|
|
|
53
53
|
#private;
|
|
54
54
|
readonly options: PackageOptions;
|
|
55
55
|
constructor(options: PackageOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Whether some export of `specifier` could be reported. Cheap way to skip namespace imports
|
|
58
|
+
* of external modules and of modules whose exports are all public.
|
|
59
|
+
*/
|
|
60
|
+
mayReport(checker: ImportabilityChecker, importerFileName: string, specifier: string): boolean;
|
|
56
61
|
/**
|
|
57
62
|
* Check importing `name` (the export name, `default` for default imports) via `specifier`.
|
|
58
63
|
*/
|
package/dist/index.js
CHANGED
|
@@ -941,10 +941,17 @@ class ImportabilityPolicy {
|
|
|
941
941
|
const packageName = lookupPackageName(importerFileName);
|
|
942
942
|
return packageName !== null && (specifier === packageName || specifier.startsWith(`${packageName}/`));
|
|
943
943
|
}
|
|
944
|
-
|
|
944
|
+
#targetModule(checker, importerFileName, specifier) {
|
|
945
945
|
const { defaultImportability, projectDirectory } = this.options;
|
|
946
946
|
const assumeAllPublic = defaultImportability === "public";
|
|
947
|
-
|
|
947
|
+
return checker.targetModule(importerFileName, specifier, projectDirectory, assumeAllPublic);
|
|
948
|
+
}
|
|
949
|
+
mayReport(checker, importerFileName, specifier) {
|
|
950
|
+
return this.#targetModule(checker, importerFileName, specifier)?.names !== undefined;
|
|
951
|
+
}
|
|
952
|
+
check(checker, importerFileName, specifier, name) {
|
|
953
|
+
const { defaultImportability } = this.options;
|
|
954
|
+
const module = this.#targetModule(checker, importerFileName, specifier);
|
|
948
955
|
const found = module && checker.findExport(module, name);
|
|
949
956
|
if (found === undefined || !found.entries[0].checked) {
|
|
950
957
|
return;
|
|
@@ -1003,6 +1010,21 @@ function realFileName(fileName) {
|
|
|
1003
1010
|
function nameOf(node) {
|
|
1004
1011
|
return node.type === "Literal" ? node.value : node.name;
|
|
1005
1012
|
}
|
|
1013
|
+
function accessedMember(identifier) {
|
|
1014
|
+
const parent = identifier.parent;
|
|
1015
|
+
if (parent.type === "MemberExpression" && parent.object === identifier) {
|
|
1016
|
+
const { property } = parent;
|
|
1017
|
+
if (property.type === "Identifier" && !parent.computed) {
|
|
1018
|
+
return { node: property, name: property.name };
|
|
1019
|
+
}
|
|
1020
|
+
if (property.type === "Literal" && typeof property.value === "string") {
|
|
1021
|
+
return { node: property, name: property.value };
|
|
1022
|
+
}
|
|
1023
|
+
} else if (parent.type === "TSQualifiedName") {
|
|
1024
|
+
return { node: parent.right, name: parent.right.name };
|
|
1025
|
+
}
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1006
1028
|
var rule = {
|
|
1007
1029
|
meta: {
|
|
1008
1030
|
type: "problem",
|
|
@@ -1060,6 +1082,20 @@ var rule = {
|
|
|
1060
1082
|
ImportDefaultSpecifier(node) {
|
|
1061
1083
|
check(node, node.parent.source.value, "default", false);
|
|
1062
1084
|
},
|
|
1085
|
+
ImportNamespaceSpecifier(node) {
|
|
1086
|
+
const specifier = node.parent.source.value;
|
|
1087
|
+
if (!policy.mayReport(checker, importer, specifier)) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
for (const variable of context.sourceCode.getDeclaredVariables(node)) {
|
|
1091
|
+
for (const { identifier } of variable.references) {
|
|
1092
|
+
const member = accessedMember(identifier);
|
|
1093
|
+
if (member !== undefined) {
|
|
1094
|
+
check(member.node, specifier, member.name, false);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
},
|
|
1063
1099
|
ExportSpecifier(node) {
|
|
1064
1100
|
const { source } = node.parent;
|
|
1065
1101
|
if (source !== null) {
|
package/package.json
CHANGED