eslint-plugin-esm 0.1.1 → 0.2.1

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # eslint-plugin-esm
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 2b04bbd: fix(eslint-plugin-esm): allow module existing in peerDependencies for `no-phantom-dep-imports` rule
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 28edf1c: feat(eslint-plugin-esm)!: support `allowDevDependencies` option
14
+
3
15
  ## 0.1.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # eslint-plugin-esm
2
2
 
3
- [![](https://img.shields.io/npm/l/eslint-plugin-esm.svg)](https://github.com/zanminkian/git-validator/blob/main/LICENSE)
3
+ [![](https://img.shields.io/npm/l/eslint-plugin-esm.svg)](https://github.com/zanminkian/fenge/blob/main/LICENSE)
4
4
  [![](https://img.shields.io/npm/v/eslint-plugin-esm.svg)](https://www.npmjs.com/package/eslint-plugin-esm)
5
5
  [![](https://img.shields.io/npm/dm/eslint-plugin-esm.svg)](https://www.npmjs.com/package/eslint-plugin-esm)
6
6
  [![](https://packagephobia.com/badge?p=eslint-plugin-esm)](https://packagephobia.com/result?p=eslint-plugin-esm)
@@ -8,6 +8,12 @@
8
8
 
9
9
  ESLint plugin for linting ESM (import/export syntax)
10
10
 
11
+ ## Feature
12
+
13
+ - Faster than `eslint-plugin-import`.
14
+ - Easier than `eslint-plugin-import`
15
+ - Zero dependencies.
16
+
11
17
  ## Requirement
12
18
 
13
19
  - ESLint >= 8.57.0
@@ -33,7 +39,7 @@ export default [
33
39
  rules: {
34
40
  "esm/no-git-ignored-imports": "error"
35
41
  ...
36
- // Visit https://github.com/zanminkian/git-validator/tree/main/packages/eslint-plugin-esm/doc/rules for more other rules
42
+ // Visit https://github.com/zanminkian/fenge/tree/main/packages/eslint-plugin-esm/doc/rules for more other rules
37
43
  },
38
44
  },
39
45
  ...
@@ -53,7 +59,7 @@ Config `package.json`
53
59
 
54
60
  ## Rules
55
61
 
56
- Click [here](https://github.com/zanminkian/git-validator/tree/main/packages/eslint-plugin-esm/doc/rules).
62
+ Click [here](https://github.com/zanminkian/fenge/tree/main/packages/eslint-plugin-esm/doc/rules).
57
63
 
58
64
  ## License
59
65
 
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;
@@ -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;AAEhB,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EAEP,OAAO,EACP,IAAmB,EACnB,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAEhB,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"}
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
- // ...(schema && { schema }),
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQVN6QyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUM7QUFFNUMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxFQUN6QixJQUFJLEVBQ0osT0FBTztBQUNQLFVBQVU7QUFDVixPQUFPLEVBQ1AsSUFBSSxHQUFHLFlBQVksRUFDbkIsTUFBTSxHQVFQO0lBQ0MsTUFBTSxJQUFJLEdBQW9CO1FBQzVCLElBQUksRUFBRTtZQUNKLDZCQUE2QjtZQUM3QixHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDM0IsUUFBUSxFQUFFO2dCQUNSLENBQUMsa0JBQWtCLENBQUMsRUFBRSxPQUFPO2FBQzlCO1lBQ0QsSUFBSTtZQUNKLElBQUksRUFBRTtnQkFDSixnQkFBZ0I7Z0JBQ2hCLFdBQVcsRUFBRSxPQUFPO2FBQ3JCO1NBQ0Y7UUFDRCxNQUFNO0tBQ1AsQ0FBQztJQUNGLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQUMsYUFBcUI7SUFDL0MseUJBQXlCO0lBQ3pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQVFEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLENBQ3BCLE9BQXlCLEVBQ3pCLEtBQTJFLEVBQ3hELEVBQUU7SUFDckIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFxQixFQUFFLEVBQUU7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUN6QixJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUFFLE9BQU87UUFDdEMsSUFBSSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPO1FBQ2xELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDO1lBQ2xELE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUMsQ0FBQztJQUNGLE9BQU87UUFDTCxpQkFBaUIsRUFBRSxNQUFNO1FBQ3pCLGdCQUFnQixFQUFFLE1BQU07UUFDeEIsb0JBQW9CLEVBQUUsTUFBTTtRQUM1QixzQkFBc0IsRUFBRSxNQUFNO0tBQy9CLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQWM7SUFDMUMsSUFDRSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUN0QixNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztRQUN2QixNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUN4QixNQUFNLEtBQUssR0FBRztRQUNkLE1BQU0sS0FBSyxJQUFJLEVBQ2YsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMvQixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwibm9kZTp1cmxcIjtcbmltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcbmltcG9ydCB0eXBlIHtcbiAgRXhwb3J0QWxsRGVjbGFyYXRpb24sXG4gIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24sXG4gIEltcG9ydERlY2xhcmF0aW9uLFxuICBJbXBvcnRFeHByZXNzaW9uLFxufSBmcm9tIFwiZXN0cmVlXCI7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01FU1NBR0VfSUQgPSBcImRlZmF1bHRcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJ1bGUoe1xuICBuYW1lLFxuICBtZXNzYWdlLFxuICAvLyBzY2hlbWEsXG4gIGZpeGFibGUsXG4gIHR5cGUgPSBcInN1Z2dlc3Rpb25cIixcbiAgY3JlYXRlLFxufToge1xuICBuYW1lOiBzdHJpbmc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgLy8gc2NoZW1hPzogSlNPTlNjaGVtYTRbXTtcbiAgZml4YWJsZT86IFJ1bGUuUnVsZU1ldGFEYXRhW1wiZml4YWJsZVwiXTtcbiAgdHlwZT86IFJ1bGUuUnVsZU1ldGFEYXRhW1widHlwZVwiXTtcbiAgY3JlYXRlOiAoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCkgPT4gUnVsZS5SdWxlTGlzdGVuZXI7XG59KTogeyBuYW1lOiBzdHJpbmc7IHJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSB9IHtcbiAgY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICAgIG1ldGE6IHtcbiAgICAgIC8vIC4uLihzY2hlbWEgJiYgeyBzY2hlbWEgfSksXG4gICAgICAuLi4oZml4YWJsZSAmJiB7IGZpeGFibGUgfSksXG4gICAgICBtZXNzYWdlczoge1xuICAgICAgICBbREVGQVVMVF9NRVNTQUdFX0lEXTogbWVzc2FnZSxcbiAgICAgIH0sXG4gICAgICB0eXBlLFxuICAgICAgZG9jczoge1xuICAgICAgICAvLyBUT0RPOiBhZGQgdXJsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBtZXNzYWdlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGNyZWF0ZSxcbiAgfTtcbiAgcmV0dXJuIHsgbmFtZSwgcnVsZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVsZU5hbWUoaW1wb3J0TWV0YVVybDogc3RyaW5nKSB7XG4gIC8vIHJlbW92ZSAnLmpzJyBleHRlbnNpb25cbiAgcmV0dXJuIHBhdGguYmFzZW5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnRNZXRhVXJsKSkuc2xpY2UoMCwgLTMpO1xufVxuXG5leHBvcnQgdHlwZSBJbXBvcnRhdGlvbk5vZGUgPVxuICB8IEltcG9ydERlY2xhcmF0aW9uXG4gIHwgSW1wb3J0RXhwcmVzc2lvblxuICB8IEV4cG9ydEFsbERlY2xhcmF0aW9uXG4gIHwgRXhwb3J0TmFtZWREZWNsYXJhdGlvbjtcblxuLyoqXG4gKiBDcmVhdGUgRVNMaW50IFJ1bGVMaXN0ZW5lciB0byBjaGVjayBzdHJpbmcgaW1wb3J0YXRpb24gc291cmNlLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IFJ1bGVDb250ZXh0XG4gKiBAcGFyYW0gY2hlY2sgdGhlIGNoZWNrIGxvZ2ljXG4gKiBAcmV0dXJucyBFU0xpbnQgUnVsZUxpc3RlbmVyXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSAoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGNoZWNrOiAoZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmcsIG5vZGU6IEltcG9ydGF0aW9uTm9kZSkgPT4gYm9vbGVhbixcbik6IFJ1bGUuUnVsZUxpc3RlbmVyID0+IHtcbiAgY29uc3QgaGFuZGxlID0gKG5vZGU6IEltcG9ydGF0aW9uTm9kZSkgPT4ge1xuICAgIGlmICghbm9kZS5zb3VyY2UpIHJldHVybjtcbiAgICBpZiAoIShcInZhbHVlXCIgaW4gbm9kZS5zb3VyY2UpKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBub2RlLnNvdXJjZS52YWx1ZSAhPT0gXCJzdHJpbmdcIikgcmV0dXJuO1xuICAgIGlmIChjaGVjayhjb250ZXh0LmZpbGVuYW1lLCBub2RlLnNvdXJjZS52YWx1ZSwgbm9kZSkpXG4gICAgICBjb250ZXh0LnJlcG9ydCh7IG5vZGU6IG5vZGUuc291cmNlLCBtZXNzYWdlSWQ6IERFRkFVTFRfTUVTU0FHRV9JRCB9KTtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBJbXBvcnREZWNsYXJhdGlvbjogaGFuZGxlLFxuICAgIEltcG9ydEV4cHJlc3Npb246IGhhbmRsZSxcbiAgICBFeHBvcnRBbGxEZWNsYXJhdGlvbjogaGFuZGxlLFxuICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb246IGhhbmRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTb3VyY2VUeXBlKHNvdXJjZTogc3RyaW5nKSB7XG4gIGlmIChcbiAgICBzb3VyY2Uuc3RhcnRzV2l0aChcIi9cIikgfHxcbiAgICBzb3VyY2Uuc3RhcnRzV2l0aChcIi4vXCIpIHx8XG4gICAgc291cmNlLnN0YXJ0c1dpdGgoXCIuLi9cIikgfHxcbiAgICBzb3VyY2UgPT09IFwiLlwiIHx8XG4gICAgc291cmNlID09PSBcIi4uXCJcbiAgKSB7XG4gICAgcmV0dXJuIFwibG9jYWxcIjtcbiAgfVxuICBpZiAoc291cmNlLnN0YXJ0c1dpdGgoXCJub2RlOlwiKSkge1xuICAgIHJldHVybiBcImJ1aWx0aW5cIjtcbiAgfVxuICByZXR1cm4gXCJtb2R1bGVcIjtcbn1cbiJdfQ==
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":"AAkDA,eAAO,MAAM,mBAAmB;;;CAK9B,CAAC"}
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;;;CA+D9B,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, } from "../common.js";
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,54 @@ 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
- create: (context) => create(context, check),
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 './'` and `import {foo} from 'node:foo'`
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 peerDep = "peerDependencies" in pkgJson.content &&
66
+ isObject(pkgJson.content.peerDependencies)
67
+ ? pkgJson.content.peerDependencies
68
+ : {};
69
+ const devDep = "devDependencies" in pkgJson.content &&
70
+ isObject(pkgJson.content.devDependencies)
71
+ ? pkgJson.content.devDependencies
72
+ : {};
73
+ const moduleName = source
74
+ .split("/")
75
+ .slice(0, source.startsWith("@") ? 2 : 1)
76
+ .join("/");
77
+ const isInDep = moduleName in dep || moduleName in peerDep;
78
+ const isInDev = moduleName in devDep;
79
+ if ("importKind" in node && node.importKind === "type") {
80
+ return moduleName.startsWith("@") && moduleName.includes("/")
81
+ ? !(isInDep ||
82
+ isInDev ||
83
+ `@types/${moduleName.slice(1).replace("/", "_")}` in devDep)
84
+ : !(isInDep || isInDev || `@types/${moduleName}` in devDep);
85
+ }
86
+ else {
87
+ return allowDevDependencies ? !(isInDep || isInDev) : !isInDep;
88
+ }
89
+ }),
42
90
  });
43
- function check(filename, source, node) {
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
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tcGhhbnRvbS1kZXAtaW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1waGFudG9tLWRlcC1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFOUUsU0FBUyxRQUFRLENBQUMsS0FBYztJQUM5QixPQUFPLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDO0FBQ3JELENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxRQUFnQjtJQUM5QixJQUFJLENBQUM7UUFDSCxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXlELENBQUMsQ0FBQyxvQ0FBb0M7QUFDcEgsU0FBUyxVQUFVLENBQ2pCLEdBQVc7SUFFWCxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNuQixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUNELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ25ELElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQVksSUFBSSxDQUFD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Q0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3hDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUViLE1BQU0sT0FBTyxHQUFHLFVBQVUsSUFBSSxHQUFHLElBQUksVUFBVSxJQUFJLE9BQU8sQ0FBQztRQUMzRCxNQUFNLE9BQU8sR0FBRyxVQUFVLElBQUksTUFBTSxDQUFDO1FBQ3JDLElBQUksWUFBWSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3ZELE9BQU8sVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztnQkFDM0QsQ0FBQyxDQUFDLENBQUMsQ0FDQyxPQUFPO29CQUNQLE9BQU87b0JBQ1AsVUFBVSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxNQUFNLENBQzVEO2dCQUNILENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE9BQU8sSUFBSSxVQUFVLFVBQVUsRUFBRSxJQUFJLE1BQU0sQ0FBQyxDQUFDO1FBQ2hFLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDakUsQ0FBQztJQUNILENBQUMsQ0FBQztDQUNMLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSBcIm5vZGU6cHJvY2Vzc1wiO1xuaW1wb3J0IHsgY3JlYXRlLCBjcmVhdGVSdWxlLCBnZXRSdWxlTmFtZSwgZ2V0U291cmNlVHlwZSB9IGZyb20gXCIuLi9jb21tb24uanNcIjtcblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWU6IHVua25vd24pIHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn1cblxuZnVuY3Rpb24gaXNGaWxlKGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZnMuc3RhdFN5bmMoZmlsZVBhdGgpLmlzRmlsZSgpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmNvbnN0IGNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHsgcGF0aDogc3RyaW5nOyBjb250ZW50OiBvYmplY3QgfSB8IHVuZGVmaW5lZD4oKTsgLy8ga2V5IGlzIGRpciwgdmFsdWUgaXMgcGFja2FnZS5qc29uXG5mdW5jdGlvbiBnZXRQa2dKc29uKFxuICBkaXI6IHN0cmluZyxcbik6IHsgcGF0aDogc3RyaW5nOyBjb250ZW50OiBvYmplY3QgfSB8IHVuZGVmaW5lZCB7XG4gIGlmIChjYWNoZS5oYXMoZGlyKSkge1xuICAgIHJldHVybiBjYWNoZS5nZXQoZGlyKTtcbiAgfVxuICBjb25zdCBwa2dKc29uUGF0aCA9IHBhdGguam9pbihkaXIsIFwicGFja2FnZS5qc29uXCIpO1xuICBpZiAoaXNGaWxlKHBrZ0pzb25QYXRoKSkge1xuICAgIGNvbnN0IGNvbnRlbnQ6IHVua25vd24gPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwa2dKc29uUGF0aCwgXCJ1dGY4XCIpKTtcbiAgICBjb25zdCByZXN1bHQgPSBpc09iamVjdChjb250ZW50KVxuICAgICAgPyB7IHBhdGg6IHBrZ0pzb25QYXRoLCBjb250ZW50IH1cbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGNhY2hlLnNldChkaXIsIHJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGlmIGl0IGlzIGEgZGlyZWN0b3J5XG4gIGlmIChkaXIgPT09IHByb2Nlc3MuY3dkKCkgfHwgZGlyID09PSBcIi9cIikge1xuICAgIC8vIHN0b3AgaGVyZVxuICAgIGNhY2hlLnNldChkaXIsIHVuZGVmaW5lZCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBnZXRQa2dKc29uKHBhdGguam9pbihkaXIsIFwiLi5cIikpO1xufVxuXG5leHBvcnQgY29uc3Qgbm9QaGFudG9tRGVwSW1wb3J0cyA9IGNyZWF0ZVJ1bGUoe1xuICBuYW1lOiBnZXRSdWxlTmFtZShpbXBvcnQubWV0YS51cmwpLFxuICBtZXNzYWdlOlxuICAgIFwiRGlzYWxsb3cgaW1wb3J0aW5nIGZyb20gYSBtb2R1bGUgd2hpY2ggdGhlIG5lYXJlc3QgYHBhY2thZ2UuanNvbmAgZG9lc24ndCBpbmNsdWRlIGl0LlwiLFxuICBzY2hlbWE6IFtcbiAgICB7XG4gICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhbGxvd0RldkRlcGVuZGVuY2llczogeyB0eXBlOiBcImJvb2xlYW5cIiB9LFxuICAgICAgfSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICB9LFxuICBdLFxuICBjcmVhdGU6IChjb250ZXh0KSA9PlxuICAgIGNyZWF0ZShjb250ZXh0LCAoZmlsZW5hbWUsIHNvdXJjZSwgbm9kZSkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBhbGxvd0RldkRlcGVuZGVuY2llcyA9IGZhbHNlLFxuICAgICAgfTogeyBhbGxvd0RldkRlcGVuZGVuY2llczogYm9vbGVhbiB9ID0gY29udGV4dC5vcHRpb25zWzBdID8/IHt9O1xuXG4gICAgICAvLyBpZ25vcmUgYGltcG9ydCB7Zm9vfSBmcm9tICcuLydgIGFuZCBgaW1wb3J0IHtmb299IGZyb20gJ25vZGU6Zm9vJ2BcbiAgICAgIGlmIChnZXRTb3VyY2VUeXBlKHNvdXJjZSkgIT09IFwibW9kdWxlXCIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgcGtnSnNvbiA9IGdldFBrZ0pzb24ocGF0aC5kaXJuYW1lKGZpbGVuYW1lKSk7XG4gICAgICAvLyBjYW5ub3QgZmluZCBwYWNrYWdlLmpzb24gZmlsZVxuICAgICAgaWYgKCFwa2dKc29uKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVwID1cbiAgICAgICAgXCJkZXBlbmRlbmNpZXNcIiBpbiBwa2dKc29uLmNvbnRlbnQgJiZcbiAgICAgICAgaXNPYmplY3QocGtnSnNvbi5jb250ZW50LmRlcGVuZGVuY2llcylcbiAgICAgICAgICA/IHBrZ0pzb24uY29udGVudC5kZXBlbmRlbmNpZXNcbiAgICAgICAgICA6IHt9O1xuICAgICAgY29uc3QgcGVlckRlcCA9XG4gICAgICAgIFwicGVlckRlcGVuZGVuY2llc1wiIGluIHBrZ0pzb24uY29udGVudCAmJlxuICAgICAgICBpc09iamVjdChwa2dKc29uLmNvbnRlbnQucGVlckRlcGVuZGVuY2llcylcbiAgICAgICAgICA/IHBrZ0pzb24uY29udGVudC5wZWVyRGVwZW5kZW5jaWVzXG4gICAgICAgICAgOiB7fTtcbiAgICAgIGNvbnN0IGRldkRlcCA9XG4gICAgICAgIFwiZGV2RGVwZW5kZW5jaWVzXCIgaW4gcGtnSnNvbi5jb250ZW50ICYmXG4gICAgICAgIGlzT2JqZWN0KHBrZ0pzb24uY29udGVudC5kZXZEZXBlbmRlbmNpZXMpXG4gICAgICAgICAgPyBwa2dKc29uLmNvbnRlbnQuZGV2RGVwZW5kZW5jaWVzXG4gICAgICAgICAgOiB7fTtcblxuICAgICAgY29uc3QgbW9kdWxlTmFtZSA9IHNvdXJjZVxuICAgICAgICAuc3BsaXQoXCIvXCIpXG4gICAgICAgIC5zbGljZSgwLCBzb3VyY2Uuc3RhcnRzV2l0aChcIkBcIikgPyAyIDogMSlcbiAgICAgICAgLmpvaW4oXCIvXCIpO1xuXG4gICAgICBjb25zdCBpc0luRGVwID0gbW9kdWxlTmFtZSBpbiBkZXAgfHwgbW9kdWxlTmFtZSBpbiBwZWVyRGVwO1xuICAgICAgY29uc3QgaXNJbkRldiA9IG1vZHVsZU5hbWUgaW4gZGV2RGVwO1xuICAgICAgaWYgKFwiaW1wb3J0S2luZFwiIGluIG5vZGUgJiYgbm9kZS5pbXBvcnRLaW5kID09PSBcInR5cGVcIikge1xuICAgICAgICByZXR1cm4gbW9kdWxlTmFtZS5zdGFydHNXaXRoKFwiQFwiKSAmJiBtb2R1bGVOYW1lLmluY2x1ZGVzKFwiL1wiKVxuICAgICAgICAgID8gIShcbiAgICAgICAgICAgICAgaXNJbkRlcCB8fFxuICAgICAgICAgICAgICBpc0luRGV2IHx8XG4gICAgICAgICAgICAgIGBAdHlwZXMvJHttb2R1bGVOYW1lLnNsaWNlKDEpLnJlcGxhY2UoXCIvXCIsIFwiX1wiKX1gIGluIGRldkRlcFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogIShpc0luRGVwIHx8IGlzSW5EZXYgfHwgYEB0eXBlcy8ke21vZHVsZU5hbWV9YCBpbiBkZXZEZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGFsbG93RGV2RGVwZW5kZW5jaWVzID8gIShpc0luRGVwIHx8IGlzSW5EZXYpIDogIWlzSW5EZXA7XG4gICAgICB9XG4gICAgfSksXG59KTtcbiJdfQ==
@@ -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' // filename: /foo/src/rules/no-phantom-dep-imports.spec.ts
13
- import eslint from 'eslint' // filename: /foo/foo.js
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 {Foo} from 'foo'
24
- import eslint from 'eslint' // filename: /foo/src/rules/no-phantom-dep-imports.spec.ts
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-esm",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "ESLint plugin for linting ESM (import/export syntax)",
5
5
  "keywords": [
6
6
  "eslint",
@@ -14,10 +14,10 @@
14
14
  "es6",
15
15
  "module"
16
16
  ],
17
- "homepage": "https://github.com/zanminkian/git-validator/tree/main/packages/eslint-plugin-esm",
17
+ "homepage": "https://github.com/zanminkian/fenge/tree/main/packages/eslint-plugin-esm",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/zanminkian/git-validator.git",
20
+ "url": "git+https://github.com/zanminkian/fenge.git",
21
21
  "directory": "packages/eslint-plugin-esm"
22
22
  },
23
23
  "license": "MIT",
@@ -29,7 +29,7 @@
29
29
  "@types/eslint": "8.56.11",
30
30
  "@types/estree": "1.0.6",
31
31
  "@types/json-schema": "7.0.15",
32
- "@types/node": "22.5.5",
32
+ "@types/node": "22.7.5",
33
33
  "@typescript-eslint/parser": "7.16.1",
34
34
  "eslint": "8.57.0",
35
35
  "outdent": "0.8.0"
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
- // schema,
17
+ schema,
17
18
  fixable,
18
19
  type = "suggestion",
19
20
  create,
20
21
  }: {
21
22
  name: string;
22
23
  message: string;
23
- // schema?: JSONSchema4[];
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
- // ...(schema && { schema }),
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
- { code: "import type {Foo} from 'foo'" },
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
- filename: fileURLToPath(import.meta.url),
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 eslint from 'eslint'",
24
- filename: path.join(process.cwd(), "foo.js"),
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,63 @@ 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
- create: (context) => create(context, check),
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
- function check(filename: string, source: string, node: ImportationNode) {
59
- // ignore `import type {foo} from 'foo'`
60
- if ("importKind" in node && node.importKind === "type") {
61
- return false;
62
- }
63
- // ignore `import {foo} from './'`
64
- if (getSourceType(source) !== "module") {
65
- return false;
66
- }
67
- const pkgJson = getPkgJson(path.dirname(filename));
68
- // cannot find package.json file
69
- if (!pkgJson) {
70
- return true;
71
- }
72
- const dep =
73
- "dependencies" in pkgJson.content && isObject(pkgJson.content.dependencies)
74
- ? pkgJson.content.dependencies
75
- : {};
76
- const devDep =
77
- "devDependencies" in pkgJson.content &&
78
- isObject(pkgJson.content.devDependencies)
79
- ? pkgJson.content.devDependencies
80
- : {};
64
+ // ignore `import {foo} from './'` and `import {foo} from 'node:foo'`
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 peerDep =
79
+ "peerDependencies" in pkgJson.content &&
80
+ isObject(pkgJson.content.peerDependencies)
81
+ ? pkgJson.content.peerDependencies
82
+ : {};
83
+ const devDep =
84
+ "devDependencies" in pkgJson.content &&
85
+ isObject(pkgJson.content.devDependencies)
86
+ ? pkgJson.content.devDependencies
87
+ : {};
81
88
 
82
- const moduleName = source
83
- .split("/")
84
- .slice(0, source.startsWith("@") ? 2 : 1)
85
- .join("/");
86
- if (["test", "spec"].includes(filename.split(".").at(-2) ?? "")) {
87
- return !(moduleName in dep || moduleName in devDep);
88
- }
89
- return !(moduleName in dep);
90
- }
89
+ const moduleName = source
90
+ .split("/")
91
+ .slice(0, source.startsWith("@") ? 2 : 1)
92
+ .join("/");
93
+
94
+ const isInDep = moduleName in dep || moduleName in peerDep;
95
+ const isInDev = moduleName in devDep;
96
+ if ("importKind" in node && node.importKind === "type") {
97
+ return moduleName.startsWith("@") && moduleName.includes("/")
98
+ ? !(
99
+ isInDep ||
100
+ isInDev ||
101
+ `@types/${moduleName.slice(1).replace("/", "_")}` in devDep
102
+ )
103
+ : !(isInDep || isInDev || `@types/${moduleName}` in devDep);
104
+ } else {
105
+ return allowDevDependencies ? !(isInDep || isInDev) : !isInDep;
106
+ }
107
+ }),
108
+ });
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 = string | { code: string; filename?: string };
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
- ? `${testCase.code} // filename: ${testCase.filename}`
79
- : testCase.code,
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 -->