eslint-plugin-esm 0.1.1 → 0.2.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 +6 -0
- package/dist/common.d.ts +3 -1
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +3 -5
- package/dist/rules/no-phantom-dep-imports.d.ts.map +1 -1
- package/dist/rules/no-phantom-dep-imports.js +49 -33
- package/doc/rules/no-phantom-dep-imports.md +9 -4
- package/package.json +1 -1
- package/src/common.ts +4 -3
- package/src/rules/no-phantom-dep-imports.spec.ts +16 -9
- package/src/rules/no-phantom-dep-imports.ts +58 -41
- package/src/test.spec.ts +19 -6
package/CHANGELOG.md
CHANGED
package/dist/common.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Rule } from "eslint";
|
|
2
2
|
import type { ExportAllDeclaration, ExportNamedDeclaration, ImportDeclaration, ImportExpression } from "estree";
|
|
3
|
+
import type { JSONSchema4 } from "json-schema";
|
|
3
4
|
export declare const DEFAULT_MESSAGE_ID = "default";
|
|
4
|
-
export declare function createRule({ name, message, fixable, type, create, }: {
|
|
5
|
+
export declare function createRule({ name, message, schema, fixable, type, create, }: {
|
|
5
6
|
name: string;
|
|
6
7
|
message: string;
|
|
8
|
+
schema?: JSONSchema4[];
|
|
7
9
|
fixable?: Rule.RuleMetaData["fixable"];
|
|
8
10
|
type?: Rule.RuleMetaData["type"];
|
|
9
11
|
create: (context: Rule.RuleContext) => Rule.RuleListener;
|
package/dist/common.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,MAAM,EACN,OAAO,EACP,IAAmB,EACnB,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,YAAY,CAAC;CAC1D,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAA;CAAE,CAiB1C;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,UAGhD;AAED,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,gBAAgB,GAChB,oBAAoB,GACpB,sBAAsB,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,MAAM,YACR,IAAI,CAAC,WAAW,SAClB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,KAAK,OAAO,KAC1E,IAAI,CAAC,YAcP,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,kCAc3C"}
|
package/dist/common.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
export const DEFAULT_MESSAGE_ID = "default";
|
|
4
|
-
export function createRule({ name, message,
|
|
5
|
-
// schema,
|
|
6
|
-
fixable, type = "suggestion", create, }) {
|
|
4
|
+
export function createRule({ name, message, schema, fixable, type = "suggestion", create, }) {
|
|
7
5
|
const rule = {
|
|
8
6
|
meta: {
|
|
9
|
-
|
|
7
|
+
...(schema && { schema }),
|
|
10
8
|
...(fixable && { fixable }),
|
|
11
9
|
messages: {
|
|
12
10
|
[DEFAULT_MESSAGE_ID]: message,
|
|
@@ -62,4 +60,4 @@ export function getSourceType(source) {
|
|
|
62
60
|
}
|
|
63
61
|
return "module";
|
|
64
62
|
}
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
63
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQVV6QyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUM7QUFFNUMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxFQUN6QixJQUFJLEVBQ0osT0FBTyxFQUNQLE1BQU0sRUFDTixPQUFPLEVBQ1AsSUFBSSxHQUFHLFlBQVksRUFDbkIsTUFBTSxHQVFQO0lBQ0MsTUFBTSxJQUFJLEdBQW9CO1FBQzVCLElBQUksRUFBRTtZQUNKLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUN6QixHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDM0IsUUFBUSxFQUFFO2dCQUNSLENBQUMsa0JBQWtCLENBQUMsRUFBRSxPQUFPO2FBQzlCO1lBQ0QsSUFBSTtZQUNKLElBQUksRUFBRTtnQkFDSixnQkFBZ0I7Z0JBQ2hCLFdBQVcsRUFBRSxPQUFPO2FBQ3JCO1NBQ0Y7UUFDRCxNQUFNO0tBQ1AsQ0FBQztJQUNGLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQUMsYUFBcUI7SUFDL0MseUJBQXlCO0lBQ3pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQVFEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLENBQ3BCLE9BQXlCLEVBQ3pCLEtBQTJFLEVBQ3hELEVBQUU7SUFDckIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFxQixFQUFFLEVBQUU7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUN6QixJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUFFLE9BQU87UUFDdEMsSUFBSSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPO1FBQ2xELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDO1lBQ2xELE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUMsQ0FBQztJQUNGLE9BQU87UUFDTCxpQkFBaUIsRUFBRSxNQUFNO1FBQ3pCLGdCQUFnQixFQUFFLE1BQU07UUFDeEIsb0JBQW9CLEVBQUUsTUFBTTtRQUM1QixzQkFBc0IsRUFBRSxNQUFNO0tBQy9CLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQWM7SUFDMUMsSUFDRSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUN0QixNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztRQUN2QixNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUN4QixNQUFNLEtBQUssR0FBRztRQUNkLE1BQU0sS0FBSyxJQUFJLEVBQ2YsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMvQixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwibm9kZTp1cmxcIjtcbmltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcbmltcG9ydCB0eXBlIHtcbiAgRXhwb3J0QWxsRGVjbGFyYXRpb24sXG4gIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24sXG4gIEltcG9ydERlY2xhcmF0aW9uLFxuICBJbXBvcnRFeHByZXNzaW9uLFxufSBmcm9tIFwiZXN0cmVlXCI7XG5pbXBvcnQgdHlwZSB7IEpTT05TY2hlbWE0IH0gZnJvbSBcImpzb24tc2NoZW1hXCI7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01FU1NBR0VfSUQgPSBcImRlZmF1bHRcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJ1bGUoe1xuICBuYW1lLFxuICBtZXNzYWdlLFxuICBzY2hlbWEsXG4gIGZpeGFibGUsXG4gIHR5cGUgPSBcInN1Z2dlc3Rpb25cIixcbiAgY3JlYXRlLFxufToge1xuICBuYW1lOiBzdHJpbmc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgc2NoZW1hPzogSlNPTlNjaGVtYTRbXTtcbiAgZml4YWJsZT86IFJ1bGUuUnVsZU1ldGFEYXRhW1wiZml4YWJsZVwiXTtcbiAgdHlwZT86IFJ1bGUuUnVsZU1ldGFEYXRhW1widHlwZVwiXTtcbiAgY3JlYXRlOiAoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCkgPT4gUnVsZS5SdWxlTGlzdGVuZXI7XG59KTogeyBuYW1lOiBzdHJpbmc7IHJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSB9IHtcbiAgY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICAgIG1ldGE6IHtcbiAgICAgIC4uLihzY2hlbWEgJiYgeyBzY2hlbWEgfSksXG4gICAgICAuLi4oZml4YWJsZSAmJiB7IGZpeGFibGUgfSksXG4gICAgICBtZXNzYWdlczoge1xuICAgICAgICBbREVGQVVMVF9NRVNTQUdFX0lEXTogbWVzc2FnZSxcbiAgICAgIH0sXG4gICAgICB0eXBlLFxuICAgICAgZG9jczoge1xuICAgICAgICAvLyBUT0RPOiBhZGQgdXJsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBtZXNzYWdlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGNyZWF0ZSxcbiAgfTtcbiAgcmV0dXJuIHsgbmFtZSwgcnVsZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVsZU5hbWUoaW1wb3J0TWV0YVVybDogc3RyaW5nKSB7XG4gIC8vIHJlbW92ZSAnLmpzJyBleHRlbnNpb25cbiAgcmV0dXJuIHBhdGguYmFzZW5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnRNZXRhVXJsKSkuc2xpY2UoMCwgLTMpO1xufVxuXG5leHBvcnQgdHlwZSBJbXBvcnRhdGlvbk5vZGUgPVxuICB8IEltcG9ydERlY2xhcmF0aW9uXG4gIHwgSW1wb3J0RXhwcmVzc2lvblxuICB8IEV4cG9ydEFsbERlY2xhcmF0aW9uXG4gIHwgRXhwb3J0TmFtZWREZWNsYXJhdGlvbjtcblxuLyoqXG4gKiBDcmVhdGUgRVNMaW50IFJ1bGVMaXN0ZW5lciB0byBjaGVjayBzdHJpbmcgaW1wb3J0YXRpb24gc291cmNlLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IFJ1bGVDb250ZXh0XG4gKiBAcGFyYW0gY2hlY2sgdGhlIGNoZWNrIGxvZ2ljXG4gKiBAcmV0dXJucyBFU0xpbnQgUnVsZUxpc3RlbmVyXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSAoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGNoZWNrOiAoZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmcsIG5vZGU6IEltcG9ydGF0aW9uTm9kZSkgPT4gYm9vbGVhbixcbik6IFJ1bGUuUnVsZUxpc3RlbmVyID0+IHtcbiAgY29uc3QgaGFuZGxlID0gKG5vZGU6IEltcG9ydGF0aW9uTm9kZSkgPT4ge1xuICAgIGlmICghbm9kZS5zb3VyY2UpIHJldHVybjtcbiAgICBpZiAoIShcInZhbHVlXCIgaW4gbm9kZS5zb3VyY2UpKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBub2RlLnNvdXJjZS52YWx1ZSAhPT0gXCJzdHJpbmdcIikgcmV0dXJuO1xuICAgIGlmIChjaGVjayhjb250ZXh0LmZpbGVuYW1lLCBub2RlLnNvdXJjZS52YWx1ZSwgbm9kZSkpXG4gICAgICBjb250ZXh0LnJlcG9ydCh7IG5vZGU6IG5vZGUuc291cmNlLCBtZXNzYWdlSWQ6IERFRkFVTFRfTUVTU0FHRV9JRCB9KTtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBJbXBvcnREZWNsYXJhdGlvbjogaGFuZGxlLFxuICAgIEltcG9ydEV4cHJlc3Npb246IGhhbmRsZSxcbiAgICBFeHBvcnRBbGxEZWNsYXJhdGlvbjogaGFuZGxlLFxuICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb246IGhhbmRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTb3VyY2VUeXBlKHNvdXJjZTogc3RyaW5nKSB7XG4gIGlmIChcbiAgICBzb3VyY2Uuc3RhcnRzV2l0aChcIi9cIikgfHxcbiAgICBzb3VyY2Uuc3RhcnRzV2l0aChcIi4vXCIpIHx8XG4gICAgc291cmNlLnN0YXJ0c1dpdGgoXCIuLi9cIikgfHxcbiAgICBzb3VyY2UgPT09IFwiLlwiIHx8XG4gICAgc291cmNlID09PSBcIi4uXCJcbiAgKSB7XG4gICAgcmV0dXJuIFwibG9jYWxcIjtcbiAgfVxuICBpZiAoc291cmNlLnN0YXJ0c1dpdGgoXCJub2RlOlwiKSkge1xuICAgIHJldHVybiBcImJ1aWx0aW5cIjtcbiAgfVxuICByZXR1cm4gXCJtb2R1bGVcIjtcbn1cbiJdfQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-phantom-dep-imports.d.ts","sourceRoot":"","sources":["../../src/rules/no-phantom-dep-imports.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-phantom-dep-imports.d.ts","sourceRoot":"","sources":["../../src/rules/no-phantom-dep-imports.ts"],"names":[],"mappings":"AA4CA,eAAO,MAAM,mBAAmB;;;CA8D9B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import { create, createRule, getRuleName, getSourceType
|
|
4
|
+
import { create, createRule, getRuleName, getSourceType } from "../common.js";
|
|
5
5
|
function isObject(value) {
|
|
6
6
|
return value !== null && typeof value === "object";
|
|
7
7
|
}
|
|
@@ -38,36 +38,52 @@ function getPkgJson(dir) {
|
|
|
38
38
|
export const noPhantomDepImports = createRule({
|
|
39
39
|
name: getRuleName(import.meta.url),
|
|
40
40
|
message: "Disallow importing from a module which the nearest `package.json` doesn't include it.",
|
|
41
|
-
|
|
41
|
+
schema: [
|
|
42
|
+
{
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
allowDevDependencies: { type: "boolean" },
|
|
46
|
+
},
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
create: (context) => create(context, (filename, source, node) => {
|
|
51
|
+
const { allowDevDependencies = false, } = context.options[0] ?? {};
|
|
52
|
+
// ignore `import {foo} from './'`
|
|
53
|
+
if (getSourceType(source) !== "module") {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const pkgJson = getPkgJson(path.dirname(filename));
|
|
57
|
+
// cannot find package.json file
|
|
58
|
+
if (!pkgJson) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const dep = "dependencies" in pkgJson.content &&
|
|
62
|
+
isObject(pkgJson.content.dependencies)
|
|
63
|
+
? pkgJson.content.dependencies
|
|
64
|
+
: {};
|
|
65
|
+
const devDep = "devDependencies" in pkgJson.content &&
|
|
66
|
+
isObject(pkgJson.content.devDependencies)
|
|
67
|
+
? pkgJson.content.devDependencies
|
|
68
|
+
: {};
|
|
69
|
+
const moduleName = source
|
|
70
|
+
.split("/")
|
|
71
|
+
.slice(0, source.startsWith("@") ? 2 : 1)
|
|
72
|
+
.join("/");
|
|
73
|
+
if ("importKind" in node && node.importKind === "type") {
|
|
74
|
+
return moduleName.startsWith("@") && moduleName.includes("/")
|
|
75
|
+
? !(moduleName in dep ||
|
|
76
|
+
moduleName in devDep ||
|
|
77
|
+
`@types/${moduleName.slice(1).replace("/", "_")}` in devDep)
|
|
78
|
+
: !(moduleName in dep ||
|
|
79
|
+
moduleName in devDep ||
|
|
80
|
+
`@types/${moduleName}` in devDep);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return allowDevDependencies
|
|
84
|
+
? !(moduleName in dep || moduleName in devDep)
|
|
85
|
+
: !(moduleName in dep);
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
42
88
|
});
|
|
43
|
-
|
|
44
|
-
// ignore `import type {foo} from 'foo'`
|
|
45
|
-
if ("importKind" in node && node.importKind === "type") {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
// ignore `import {foo} from './'`
|
|
49
|
-
if (getSourceType(source) !== "module") {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
const pkgJson = getPkgJson(path.dirname(filename));
|
|
53
|
-
// cannot find package.json file
|
|
54
|
-
if (!pkgJson) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
const dep = "dependencies" in pkgJson.content && isObject(pkgJson.content.dependencies)
|
|
58
|
-
? pkgJson.content.dependencies
|
|
59
|
-
: {};
|
|
60
|
-
const devDep = "devDependencies" in pkgJson.content &&
|
|
61
|
-
isObject(pkgJson.content.devDependencies)
|
|
62
|
-
? pkgJson.content.devDependencies
|
|
63
|
-
: {};
|
|
64
|
-
const moduleName = source
|
|
65
|
-
.split("/")
|
|
66
|
-
.slice(0, source.startsWith("@") ? 2 : 1)
|
|
67
|
-
.join("/");
|
|
68
|
-
if (["test", "spec"].includes(filename.split(".").at(-2) ?? "")) {
|
|
69
|
-
return !(moduleName in dep || moduleName in devDep);
|
|
70
|
-
}
|
|
71
|
-
return !(moduleName in dep);
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tcGhhbnRvbS1kZXAtaW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1waGFudG9tLWRlcC1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFDTCxNQUFNLEVBQ04sVUFBVSxFQUNWLFdBQVcsRUFDWCxhQUFhLEdBRWQsTUFBTSxjQUFjLENBQUM7QUFFdEIsU0FBUyxRQUFRLENBQUMsS0FBYztJQUM5QixPQUFPLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDO0FBQ3JELENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxRQUFnQjtJQUM5QixJQUFJLENBQUM7UUFDSCxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXlELENBQUMsQ0FBQyxvQ0FBb0M7QUFDcEgsU0FBUyxVQUFVLENBQ2pCLEdBQVc7SUFFWCxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNuQixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ25ELElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQVksSUFBSSxDQUFD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LElBQUksTUFBTSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUNELE9BQU8sQ0FBQyxDQUFDLFVBQVUsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUM5QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgcHJvY2VzcyBmcm9tIFwibm9kZTpwcm9jZXNzXCI7XG5pbXBvcnQge1xuICBjcmVhdGUsXG4gIGNyZWF0ZVJ1bGUsXG4gIGdldFJ1bGVOYW1lLFxuICBnZXRTb3VyY2VUeXBlLFxuICB0eXBlIEltcG9ydGF0aW9uTm9kZSxcbn0gZnJvbSBcIi4uL2NvbW1vbi5qc1wiO1xuXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZTogdW5rbm93bikge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiO1xufVxuXG5mdW5jdGlvbiBpc0ZpbGUoZmlsZVBhdGg6IHN0cmluZykge1xuICB0cnkge1xuICAgIHJldHVybiBmcy5zdGF0U3luYyhmaWxlUGF0aCkuaXNGaWxlKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuY29uc3QgY2FjaGUgPSBuZXcgTWFwPHN0cmluZywgeyBwYXRoOiBzdHJpbmc7IGNvbnRlbnQ6IG9iamVjdCB9IHwgdW5kZWZpbmVkPigpOyAvLyBrZXkgaXMgZGlyLCB2YWx1ZSBpcyBwYWNrYWdlLmpzb25cbmZ1bmN0aW9uIGdldFBrZ0pzb24oXG4gIGRpcjogc3RyaW5nLFxuKTogeyBwYXRoOiBzdHJpbmc7IGNvbnRlbnQ6IG9iamVjdCB9IHwgdW5kZWZpbmVkIHtcbiAgaWYgKGNhY2hlLmhhcyhkaXIpKSB7XG4gICAgcmV0dXJuIGNhY2hlLmdldChkaXIpO1xuICB9XG4gIGNvbnN0IHBrZ0pzb25QYXRoID0gcGF0aC5qb2luKGRpciwgXCJwYWNrYWdlLmpzb25cIik7XG4gIGlmIChpc0ZpbGUocGtnSnNvblBhdGgpKSB7XG4gICAgY29uc3QgY29udGVudDogdW5rbm93biA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBrZ0pzb25QYXRoLCBcInV0ZjhcIikpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGlzT2JqZWN0KGNvbnRlbnQpXG4gICAgICA/IHsgcGF0aDogcGtnSnNvblBhdGgsIGNvbnRlbnQgfVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgY2FjaGUuc2V0KGRpciwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gaWYgaXQgaXMgYSBkaXJlY3RvcnlcbiAgaWYgKGRpciA9PT0gcHJvY2Vzcy5jd2QoKSB8fCBkaXIgPT09IFwiL1wiKSB7XG4gICAgLy8gc3RvcCBoZXJlXG4gICAgY2FjaGUuc2V0KGRpciwgdW5kZWZpbmVkKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIGdldFBrZ0pzb24ocGF0aC5qb2luKGRpciwgXCIuLlwiKSk7XG59XG5cbmV4cG9ydCBjb25zdCBub1BoYW50b21EZXBJbXBvcnRzID0gY3JlYXRlUnVsZSh7XG4gIG5hbWU6IGdldFJ1bGVOYW1lKGltcG9ydC5tZXRhLnVybCksXG4gIG1lc3NhZ2U6XG4gICAgXCJEaXNhbGxvdyBpbXBvcnRpbmcgZnJvbSBhIG1vZHVsZSB3aGljaCB0aGUgbmVhcmVzdCBgcGFja2FnZS5qc29uYCBkb2Vzbid0IGluY2x1ZGUgaXQuXCIsXG4gIGNyZWF0ZTogKGNvbnRleHQpID0+IGNyZWF0ZShjb250ZXh0LCBjaGVjayksXG59KTtcblxuZnVuY3Rpb24gY2hlY2soZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmcsIG5vZGU6IEltcG9ydGF0aW9uTm9kZSkge1xuICAvLyBpZ25vcmUgYGltcG9ydCB0eXBlIHtmb299IGZyb20gJ2ZvbydgXG4gIGlmIChcImltcG9ydEtpbmRcIiBpbiBub2RlICYmIG5vZGUuaW1wb3J0S2luZCA9PT0gXCJ0eXBlXCIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gaWdub3JlIGBpbXBvcnQge2Zvb30gZnJvbSAnLi8nYFxuICBpZiAoZ2V0U291cmNlVHlwZShzb3VyY2UpICE9PSBcIm1vZHVsZVwiKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHBrZ0pzb24gPSBnZXRQa2dKc29uKHBhdGguZGlybmFtZShmaWxlbmFtZSkpO1xuICAvLyBjYW5ub3QgZmluZCBwYWNrYWdlLmpzb24gZmlsZVxuICBpZiAoIXBrZ0pzb24pIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCBkZXAgPVxuICAgIFwiZGVwZW5kZW5jaWVzXCIgaW4gcGtnSnNvbi5jb250ZW50ICYmIGlzT2JqZWN0KHBrZ0pzb24uY29udGVudC5kZXBlbmRlbmNpZXMpXG4gICAgICA/IHBrZ0pzb24uY29udGVudC5kZXBlbmRlbmNpZXNcbiAgICAgIDoge307XG4gIGNvbnN0IGRldkRlcCA9XG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIiBpbiBwa2dKc29uLmNvbnRlbnQgJiZcbiAgICBpc09iamVjdChwa2dKc29uLmNvbnRlbnQuZGV2RGVwZW5kZW5jaWVzKVxuICAgICAgPyBwa2dKc29uLmNvbnRlbnQuZGV2RGVwZW5kZW5jaWVzXG4gICAgICA6IHt9O1xuXG4gIGNvbnN0IG1vZHVsZU5hbWUgPSBzb3VyY2VcbiAgICAuc3BsaXQoXCIvXCIpXG4gICAgLnNsaWNlKDAsIHNvdXJjZS5zdGFydHNXaXRoKFwiQFwiKSA/IDIgOiAxKVxuICAgIC5qb2luKFwiL1wiKTtcbiAgaWYgKFtcInRlc3RcIiwgXCJzcGVjXCJdLmluY2x1ZGVzKGZpbGVuYW1lLnNwbGl0KFwiLlwiKS5hdCgtMikgPz8gXCJcIikpIHtcbiAgICByZXR1cm4gIShtb2R1bGVOYW1lIGluIGRlcCB8fCBtb2R1bGVOYW1lIGluIGRldkRlcCk7XG4gIH1cbiAgcmV0dXJuICEobW9kdWxlTmFtZSBpbiBkZXApO1xufVxuIl19
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tcGhhbnRvbS1kZXAtaW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1waGFudG9tLWRlcC1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFOUUsU0FBUyxRQUFRLENBQUMsS0FBYztJQUM5QixPQUFPLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDO0FBQ3JELENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxRQUFnQjtJQUM5QixJQUFJLENBQUM7UUFDSCxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXlELENBQUMsQ0FBQyxvQ0FBb0M7QUFDcEgsU0FBUyxVQUFVLENBQ2pCLEdBQVc7SUFFWCxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNuQixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ25ELElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQVksSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7WUFDOUIsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUU7WUFDaEMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNkLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCx1QkFBdUI7SUFDdkIsSUFBSSxHQUFHLEtBQUssT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUN6QyxZQUFZO1FBQ1osS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDMUIsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQUVELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLFVBQVUsQ0FBQztJQUM1QyxJQUFJLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2xDLE9BQU8sRUFDTCx1RkFBdUY7SUFDekYsTUFBTSxFQUFFO1FBQ047WUFDRSxJQUFJLEVBQUUsUUFBUTtZQUNkLFVBQVUsRUFBRTtnQkFDVixvQkFBb0IsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7YUFDMUM7WUFDRCxvQkFBb0IsRUFBRSxLQUFLO1NBQzVCO0tBQ0Y7SUFDRCxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNsQixNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUN6QyxNQUFNLEVBQ0osb0JBQW9CLEdBQUcsS0FBSyxHQUM3QixHQUFzQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVoRSxrQ0FBa0M7UUFDbEMsSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDdkMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuRCxnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQ1AsY0FBYyxJQUFJLE9BQU8sQ0FBQyxPQUFPO1lBQ2pDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztZQUNwQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZO1lBQzlCLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDVCxNQUFNLE1BQU0sR0FDVixpQkFBaUIsSUFBSSxPQUFPLENBQUMsT0FBTztZQUNwQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUM7WUFDdkMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZTtZQUNqQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRVQsTUFBTSxVQUFVLEdBQUcsTUFBTTthQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDO2FBQ1YsS0FBSyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4QyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFYixJQUFJLFlBQVksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUN2RCxPQUFPLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7Z0JBQzNELENBQUMsQ0FBQyxDQUFDLENBQ0MsVUFBVSxJQUFJLEdBQUc7b0JBQ2pCLFVBQVUsSUFBSSxNQUFNO29CQUNwQixVQUFVLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FDNUQ7Z0JBQ0gsQ0FBQyxDQUFDLENBQUMsQ0FDQyxVQUFVLElBQUksR0FBRztvQkFDakIsVUFBVSxJQUFJLE1BQU07b0JBQ3BCLFVBQVUsVUFBVSxFQUFFLElBQUksTUFBTSxDQUNqQyxDQUFDO1FBQ1IsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLG9CQUFvQjtnQkFDekIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksR0FBRyxJQUFJLFVBQVUsSUFBSSxNQUFNLENBQUM7Z0JBQzlDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDLENBQUM7Q0FDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJub2RlOnByb2Nlc3NcIjtcbmltcG9ydCB7IGNyZWF0ZSwgY3JlYXRlUnVsZSwgZ2V0UnVsZU5hbWUsIGdldFNvdXJjZVR5cGUgfSBmcm9tIFwiLi4vY29tbW9uLmpzXCI7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlOiB1bmtub3duKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI7XG59XG5cbmZ1bmN0aW9uIGlzRmlsZShmaWxlUGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGZzLnN0YXRTeW5jKGZpbGVQYXRoKS5pc0ZpbGUoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5jb25zdCBjYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCB7IHBhdGg6IHN0cmluZzsgY29udGVudDogb2JqZWN0IH0gfCB1bmRlZmluZWQ+KCk7IC8vIGtleSBpcyBkaXIsIHZhbHVlIGlzIHBhY2thZ2UuanNvblxuZnVuY3Rpb24gZ2V0UGtnSnNvbihcbiAgZGlyOiBzdHJpbmcsXG4pOiB7IHBhdGg6IHN0cmluZzsgY29udGVudDogb2JqZWN0IH0gfCB1bmRlZmluZWQge1xuICBpZiAoY2FjaGUuaGFzKGRpcikpIHtcbiAgICByZXR1cm4gY2FjaGUuZ2V0KGRpcik7XG4gIH1cbiAgY29uc3QgcGtnSnNvblBhdGggPSBwYXRoLmpvaW4oZGlyLCBcInBhY2thZ2UuanNvblwiKTtcbiAgaWYgKGlzRmlsZShwa2dKc29uUGF0aCkpIHtcbiAgICBjb25zdCBjb250ZW50OiB1bmtub3duID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMocGtnSnNvblBhdGgsIFwidXRmOFwiKSk7XG4gICAgY29uc3QgcmVzdWx0ID0gaXNPYmplY3QoY29udGVudClcbiAgICAgID8geyBwYXRoOiBwa2dKc29uUGF0aCwgY29udGVudCB9XG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBjYWNoZS5zZXQoZGlyLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBpdCBpcyBhIGRpcmVjdG9yeVxuICBpZiAoZGlyID09PSBwcm9jZXNzLmN3ZCgpIHx8IGRpciA9PT0gXCIvXCIpIHtcbiAgICAvLyBzdG9wIGhlcmVcbiAgICBjYWNoZS5zZXQoZGlyLCB1bmRlZmluZWQpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gZ2V0UGtnSnNvbihwYXRoLmpvaW4oZGlyLCBcIi4uXCIpKTtcbn1cblxuZXhwb3J0IGNvbnN0IG5vUGhhbnRvbURlcEltcG9ydHMgPSBjcmVhdGVSdWxlKHtcbiAgbmFtZTogZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKSxcbiAgbWVzc2FnZTpcbiAgICBcIkRpc2FsbG93IGltcG9ydGluZyBmcm9tIGEgbW9kdWxlIHdoaWNoIHRoZSBuZWFyZXN0IGBwYWNrYWdlLmpzb25gIGRvZXNuJ3QgaW5jbHVkZSBpdC5cIixcbiAgc2NoZW1hOiBbXG4gICAge1xuICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWxsb3dEZXZEZXBlbmRlbmNpZXM6IHsgdHlwZTogXCJib29sZWFuXCIgfSxcbiAgICAgIH0sXG4gICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgfSxcbiAgXSxcbiAgY3JlYXRlOiAoY29udGV4dCkgPT5cbiAgICBjcmVhdGUoY29udGV4dCwgKGZpbGVuYW1lLCBzb3VyY2UsIG5vZGUpID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWxsb3dEZXZEZXBlbmRlbmNpZXMgPSBmYWxzZSxcbiAgICAgIH06IHsgYWxsb3dEZXZEZXBlbmRlbmNpZXM6IGJvb2xlYW4gfSA9IGNvbnRleHQub3B0aW9uc1swXSA/PyB7fTtcblxuICAgICAgLy8gaWdub3JlIGBpbXBvcnQge2Zvb30gZnJvbSAnLi8nYFxuICAgICAgaWYgKGdldFNvdXJjZVR5cGUoc291cmNlKSAhPT0gXCJtb2R1bGVcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBwa2dKc29uID0gZ2V0UGtnSnNvbihwYXRoLmRpcm5hbWUoZmlsZW5hbWUpKTtcbiAgICAgIC8vIGNhbm5vdCBmaW5kIHBhY2thZ2UuanNvbiBmaWxlXG4gICAgICBpZiAoIXBrZ0pzb24pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjb25zdCBkZXAgPVxuICAgICAgICBcImRlcGVuZGVuY2llc1wiIGluIHBrZ0pzb24uY29udGVudCAmJlxuICAgICAgICBpc09iamVjdChwa2dKc29uLmNvbnRlbnQuZGVwZW5kZW5jaWVzKVxuICAgICAgICAgID8gcGtnSnNvbi5jb250ZW50LmRlcGVuZGVuY2llc1xuICAgICAgICAgIDoge307XG4gICAgICBjb25zdCBkZXZEZXAgPVxuICAgICAgICBcImRldkRlcGVuZGVuY2llc1wiIGluIHBrZ0pzb24uY29udGVudCAmJlxuICAgICAgICBpc09iamVjdChwa2dKc29uLmNvbnRlbnQuZGV2RGVwZW5kZW5jaWVzKVxuICAgICAgICAgID8gcGtnSnNvbi5jb250ZW50LmRldkRlcGVuZGVuY2llc1xuICAgICAgICAgIDoge307XG5cbiAgICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBzb3VyY2VcbiAgICAgICAgLnNwbGl0KFwiL1wiKVxuICAgICAgICAuc2xpY2UoMCwgc291cmNlLnN0YXJ0c1dpdGgoXCJAXCIpID8gMiA6IDEpXG4gICAgICAgIC5qb2luKFwiL1wiKTtcblxuICAgICAgaWYgKFwiaW1wb3J0S2luZFwiIGluIG5vZGUgJiYgbm9kZS5pbXBvcnRLaW5kID09PSBcInR5cGVcIikge1xuICAgICAgICByZXR1cm4gbW9kdWxlTmFtZS5zdGFydHNXaXRoKFwiQFwiKSAmJiBtb2R1bGVOYW1lLmluY2x1ZGVzKFwiL1wiKVxuICAgICAgICAgID8gIShcbiAgICAgICAgICAgICAgbW9kdWxlTmFtZSBpbiBkZXAgfHxcbiAgICAgICAgICAgICAgbW9kdWxlTmFtZSBpbiBkZXZEZXAgfHxcbiAgICAgICAgICAgICAgYEB0eXBlcy8ke21vZHVsZU5hbWUuc2xpY2UoMSkucmVwbGFjZShcIi9cIiwgXCJfXCIpfWAgaW4gZGV2RGVwXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiAhKFxuICAgICAgICAgICAgICBtb2R1bGVOYW1lIGluIGRlcCB8fFxuICAgICAgICAgICAgICBtb2R1bGVOYW1lIGluIGRldkRlcCB8fFxuICAgICAgICAgICAgICBgQHR5cGVzLyR7bW9kdWxlTmFtZX1gIGluIGRldkRlcFxuICAgICAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhbGxvd0RldkRlcGVuZGVuY2llc1xuICAgICAgICAgID8gIShtb2R1bGVOYW1lIGluIGRlcCB8fCBtb2R1bGVOYW1lIGluIGRldkRlcClcbiAgICAgICAgICA6ICEobW9kdWxlTmFtZSBpbiBkZXApO1xuICAgICAgfVxuICAgIH0pLFxufSk7XG4iXX0=
|
|
@@ -8,9 +8,13 @@ Disallow importing from a module which the nearest `package.json` doesn't includ
|
|
|
8
8
|
### Fail
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
|
+
import type foo from 'foo' // options: [{"allowDevDependencies":true}]
|
|
12
|
+
import type foo from 'foo' // options: [{"allowDevDependencies":false}]
|
|
11
13
|
import {type Foo} from 'foo'
|
|
12
|
-
import foo from 'foo'
|
|
13
|
-
import
|
|
14
|
+
import foo from 'foo'
|
|
15
|
+
import {type Foo} from 'eslint'
|
|
16
|
+
import {Foo} from 'eslint'
|
|
17
|
+
import eslint from 'eslint'
|
|
14
18
|
```
|
|
15
19
|
|
|
16
20
|
### Pass
|
|
@@ -20,7 +24,8 @@ import foo from '/foo'
|
|
|
20
24
|
import foo from './foo'
|
|
21
25
|
import foo from '../foo'
|
|
22
26
|
import foo from 'node:foo'
|
|
23
|
-
import type
|
|
24
|
-
import
|
|
27
|
+
import type Foo from 'estree'
|
|
28
|
+
import type {Foo} from 'eslint'
|
|
29
|
+
import eslint from 'eslint' // options: [{"allowDevDependencies":true}]
|
|
25
30
|
```
|
|
26
31
|
<!-- prettier-ignore-end -->
|
package/package.json
CHANGED
package/src/common.ts
CHANGED
|
@@ -7,27 +7,28 @@ import type {
|
|
|
7
7
|
ImportDeclaration,
|
|
8
8
|
ImportExpression,
|
|
9
9
|
} from "estree";
|
|
10
|
+
import type { JSONSchema4 } from "json-schema";
|
|
10
11
|
|
|
11
12
|
export const DEFAULT_MESSAGE_ID = "default";
|
|
12
13
|
|
|
13
14
|
export function createRule({
|
|
14
15
|
name,
|
|
15
16
|
message,
|
|
16
|
-
|
|
17
|
+
schema,
|
|
17
18
|
fixable,
|
|
18
19
|
type = "suggestion",
|
|
19
20
|
create,
|
|
20
21
|
}: {
|
|
21
22
|
name: string;
|
|
22
23
|
message: string;
|
|
23
|
-
|
|
24
|
+
schema?: JSONSchema4[];
|
|
24
25
|
fixable?: Rule.RuleMetaData["fixable"];
|
|
25
26
|
type?: Rule.RuleMetaData["type"];
|
|
26
27
|
create: (context: Rule.RuleContext) => Rule.RuleListener;
|
|
27
28
|
}): { name: string; rule: Rule.RuleModule } {
|
|
28
29
|
const rule: Rule.RuleModule = {
|
|
29
30
|
meta: {
|
|
30
|
-
|
|
31
|
+
...(schema && { schema }),
|
|
31
32
|
...(fixable && { fixable }),
|
|
32
33
|
messages: {
|
|
33
34
|
[DEFAULT_MESSAGE_ID]: message,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
1
|
import { test } from "../test.spec.js";
|
|
5
2
|
import { noPhantomDepImports } from "./no-phantom-dep-imports.js";
|
|
6
3
|
|
|
@@ -9,20 +6,30 @@ const valid = [
|
|
|
9
6
|
{ code: "import foo from './foo'" },
|
|
10
7
|
{ code: "import foo from '../foo'" },
|
|
11
8
|
{ code: "import foo from 'node:foo'" },
|
|
12
|
-
|
|
9
|
+
|
|
10
|
+
{ code: "import type Foo from 'estree'" },
|
|
11
|
+
{ code: "import type {Foo} from 'eslint'" },
|
|
13
12
|
{
|
|
14
13
|
code: "import eslint from 'eslint'",
|
|
15
|
-
|
|
14
|
+
options: [{ allowDevDependencies: true }],
|
|
16
15
|
},
|
|
17
16
|
];
|
|
18
17
|
|
|
19
18
|
const invalid = [
|
|
20
|
-
{ code: "import {type Foo} from 'foo'" },
|
|
21
|
-
{ code: "import foo from 'foo'", filename: fileURLToPath(import.meta.url) },
|
|
22
19
|
{
|
|
23
|
-
code: "import
|
|
24
|
-
|
|
20
|
+
code: "import type foo from 'foo'",
|
|
21
|
+
options: [{ allowDevDependencies: true }],
|
|
25
22
|
},
|
|
23
|
+
{
|
|
24
|
+
code: "import type foo from 'foo'",
|
|
25
|
+
options: [{ allowDevDependencies: false }],
|
|
26
|
+
},
|
|
27
|
+
{ code: "import {type Foo} from 'foo'" },
|
|
28
|
+
{ code: "import foo from 'foo'" },
|
|
29
|
+
|
|
30
|
+
{ code: "import {type Foo} from 'eslint'" },
|
|
31
|
+
{ code: "import {Foo} from 'eslint'" },
|
|
32
|
+
{ code: "import eslint from 'eslint'" },
|
|
26
33
|
];
|
|
27
34
|
|
|
28
35
|
test({ valid, invalid, ...noPhantomDepImports });
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import {
|
|
5
|
-
create,
|
|
6
|
-
createRule,
|
|
7
|
-
getRuleName,
|
|
8
|
-
getSourceType,
|
|
9
|
-
type ImportationNode,
|
|
10
|
-
} from "../common.js";
|
|
4
|
+
import { create, createRule, getRuleName, getSourceType } from "../common.js";
|
|
11
5
|
|
|
12
6
|
function isObject(value: unknown) {
|
|
13
7
|
return value !== null && typeof value === "object";
|
|
@@ -52,39 +46,62 @@ export const noPhantomDepImports = createRule({
|
|
|
52
46
|
name: getRuleName(import.meta.url),
|
|
53
47
|
message:
|
|
54
48
|
"Disallow importing from a module which the nearest `package.json` doesn't include it.",
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
schema: [
|
|
50
|
+
{
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {
|
|
53
|
+
allowDevDependencies: { type: "boolean" },
|
|
54
|
+
},
|
|
55
|
+
additionalProperties: false,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
create: (context) =>
|
|
59
|
+
create(context, (filename, source, node) => {
|
|
60
|
+
const {
|
|
61
|
+
allowDevDependencies = false,
|
|
62
|
+
}: { allowDevDependencies: boolean } = context.options[0] ?? {};
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"devDependencies" in pkgJson.content &&
|
|
78
|
-
isObject(pkgJson.content.devDependencies)
|
|
79
|
-
? pkgJson.content.devDependencies
|
|
80
|
-
: {};
|
|
64
|
+
// ignore `import {foo} from './'`
|
|
65
|
+
if (getSourceType(source) !== "module") {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const pkgJson = getPkgJson(path.dirname(filename));
|
|
69
|
+
// cannot find package.json file
|
|
70
|
+
if (!pkgJson) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const dep =
|
|
74
|
+
"dependencies" in pkgJson.content &&
|
|
75
|
+
isObject(pkgJson.content.dependencies)
|
|
76
|
+
? pkgJson.content.dependencies
|
|
77
|
+
: {};
|
|
78
|
+
const devDep =
|
|
79
|
+
"devDependencies" in pkgJson.content &&
|
|
80
|
+
isObject(pkgJson.content.devDependencies)
|
|
81
|
+
? pkgJson.content.devDependencies
|
|
82
|
+
: {};
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
const moduleName = source
|
|
85
|
+
.split("/")
|
|
86
|
+
.slice(0, source.startsWith("@") ? 2 : 1)
|
|
87
|
+
.join("/");
|
|
88
|
+
|
|
89
|
+
if ("importKind" in node && node.importKind === "type") {
|
|
90
|
+
return moduleName.startsWith("@") && moduleName.includes("/")
|
|
91
|
+
? !(
|
|
92
|
+
moduleName in dep ||
|
|
93
|
+
moduleName in devDep ||
|
|
94
|
+
`@types/${moduleName.slice(1).replace("/", "_")}` in devDep
|
|
95
|
+
)
|
|
96
|
+
: !(
|
|
97
|
+
moduleName in dep ||
|
|
98
|
+
moduleName in devDep ||
|
|
99
|
+
`@types/${moduleName}` in devDep
|
|
100
|
+
);
|
|
101
|
+
} else {
|
|
102
|
+
return allowDevDependencies
|
|
103
|
+
? !(moduleName in dep || moduleName in devDep)
|
|
104
|
+
: !(moduleName in dep);
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
});
|
package/src/test.spec.ts
CHANGED
|
@@ -7,7 +7,9 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { RuleTester, type Rule } from "eslint";
|
|
8
8
|
import { outdent } from "outdent";
|
|
9
9
|
|
|
10
|
-
export type TestCase =
|
|
10
|
+
export type TestCase =
|
|
11
|
+
| string
|
|
12
|
+
| { code: string; filename?: string; options?: unknown };
|
|
11
13
|
|
|
12
14
|
const tester = new RuleTester({
|
|
13
15
|
parser: createRequire(import.meta.url).resolve("@typescript-eslint/parser"),
|
|
@@ -34,6 +36,9 @@ export async function test({
|
|
|
34
36
|
tester.run(name, rule, {
|
|
35
37
|
valid: [testCase],
|
|
36
38
|
invalid: [],
|
|
39
|
+
...(typeof testCase === "object" && testCase.options
|
|
40
|
+
? { options: testCase.options }
|
|
41
|
+
: {}),
|
|
37
42
|
});
|
|
38
43
|
});
|
|
39
44
|
}),
|
|
@@ -48,6 +53,9 @@ export async function test({
|
|
|
48
53
|
tester.run(name, rule, {
|
|
49
54
|
valid: [],
|
|
50
55
|
invalid: [{ code, errors, filename }],
|
|
56
|
+
...(typeof testCase === "object" && testCase.options
|
|
57
|
+
? { options: testCase.options }
|
|
58
|
+
: {}),
|
|
51
59
|
});
|
|
52
60
|
});
|
|
53
61
|
}),
|
|
@@ -73,11 +81,16 @@ async function genDoc({
|
|
|
73
81
|
.map((testCase) =>
|
|
74
82
|
typeof testCase === "string" ? { code: testCase } : testCase,
|
|
75
83
|
)
|
|
76
|
-
.map((testCase) =>
|
|
77
|
-
testCase.filename
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
.map((testCase) => {
|
|
85
|
+
if (!testCase.filename && !testCase.options) {
|
|
86
|
+
return testCase.code;
|
|
87
|
+
}
|
|
88
|
+
const filename = testCase.filename && `filename: ${testCase.filename}`;
|
|
89
|
+
const options =
|
|
90
|
+
testCase.options && `options: ${JSON.stringify(testCase.options)}`;
|
|
91
|
+
const comment = [filename, options].filter((i) => !!i).join(", ");
|
|
92
|
+
return `${testCase.code} // ${comment}`;
|
|
93
|
+
})
|
|
81
94
|
.join("\n");
|
|
82
95
|
const mdContent = outdent`
|
|
83
96
|
<!-- prettier-ignore-start -->
|