eslint-plugin-node-dependencies 1.1.2 → 1.3.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 CHANGED
@@ -158,6 +158,7 @@ The rules with the following star :star: are included in the `plugin:node-depend
158
158
  | [node-dependencies/absolute-version](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/absolute-version.html) | require or disallow absolute version of dependency. | |
159
159
  | [node-dependencies/no-deprecated](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/no-deprecated.html) | disallow having dependencies on deprecate packages. | |
160
160
  | [node-dependencies/no-restricted-deps](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/no-restricted-deps.html) | Disallows dependence on the specified package. | |
161
+ | [node-dependencies/require-provenance-deps](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/require-provenance-deps.html) | Require provenance information for dependencies | |
161
162
 
162
163
  ### Stylistic Issues
163
164
 
@@ -1,4 +1,4 @@
1
- import type { ESLint, Linter } from "eslint";
1
+ import type { ESLint } from "eslint";
2
2
  import * as jsonParser from "jsonc-eslint-parser";
3
3
  export declare const recommendedConfig: ({
4
4
  plugins: {
@@ -12,6 +12,6 @@ export declare const recommendedConfig: ({
12
12
  languageOptions: {
13
13
  parser: typeof jsonParser;
14
14
  };
15
- rules: Linter.RulesRecord;
15
+ rules: import("@eslint/core").RulesConfig;
16
16
  plugins?: undefined;
17
17
  })[];
@@ -3,7 +3,7 @@ declare const _default: {
3
3
  overrides: {
4
4
  files: string[];
5
5
  parser: string;
6
- rules: import("eslint").Linter.RulesRecord;
6
+ rules: import("@eslint/core").RulesConfig;
7
7
  }[];
8
8
  };
9
9
  export = _default;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ declare const _default: {
8
8
  overrides: {
9
9
  files: string[];
10
10
  parser: string;
11
- rules: import("eslint").Linter.RulesRecord;
11
+ rules: import("@eslint/core").RulesConfig;
12
12
  }[];
13
13
  };
14
14
  "flat/recommended": ({
@@ -23,7 +23,7 @@ declare const _default: {
23
23
  languageOptions: {
24
24
  parser: typeof import("jsonc-eslint-parser");
25
25
  };
26
- rules: import("eslint").Linter.RulesRecord;
26
+ rules: import("@eslint/core").RulesConfig;
27
27
  plugins?: undefined;
28
28
  })[];
29
29
  };
@@ -5,6 +5,7 @@ const utils_1 = require("../utils");
5
5
  const ast_utils_1 = require("../utils/ast-utils");
6
6
  const regexp_1 = require("../utils/regexp");
7
7
  const semver_1 = require("../utils/semver");
8
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
8
9
  const PREFERS = ["always", "never", "ignore"];
9
10
  const SCHEMA_FOR_DEPS_PROPERTIES = {
10
11
  dependencies: { enum: PREFERS },
@@ -100,7 +101,7 @@ exports.default = (0, utils_1.createRule)("absolute-version", {
100
101
  type: "suggestion",
101
102
  },
102
103
  create(context) {
103
- const sourceCode = context.getSourceCode();
104
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
104
105
  if (!sourceCode.parserServices.isJSON) {
105
106
  return {};
106
107
  }
@@ -9,6 +9,7 @@ const semver_1 = __importDefault(require("semver"));
9
9
  const ast_utils_1 = require("../utils/ast-utils");
10
10
  const semver_2 = require("../utils/semver");
11
11
  const meta_1 = require("../utils/meta");
12
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
12
13
  class EnginesContext {
13
14
  constructor(engineNames, validDependencies = new Set()) {
14
15
  this.unprocessedEngines = new Set();
@@ -141,7 +142,7 @@ exports.default = (0, utils_1.createRule)("compat-engines", {
141
142
  },
142
143
  create(context) {
143
144
  var _a, _b, _c;
144
- const sourceCode = context.getSourceCode();
145
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
145
146
  if (!sourceCode.parserServices.isJSON) {
146
147
  return {};
147
148
  }
@@ -4,6 +4,7 @@ const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
4
4
  const utils_1 = require("../utils");
5
5
  const ast_utils_1 = require("../utils/ast-utils");
6
6
  const meta_1 = require("../utils/meta");
7
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
7
8
  exports.default = (0, utils_1.createRule)("no-deprecated", {
8
9
  meta: {
9
10
  docs: {
@@ -30,7 +31,7 @@ exports.default = (0, utils_1.createRule)("no-deprecated", {
30
31
  },
31
32
  create(context) {
32
33
  var _a;
33
- const sourceCode = context.getSourceCode();
34
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
34
35
  if (!sourceCode.parserServices.isJSON) {
35
36
  return {};
36
37
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../utils");
4
4
  const ast_utils_1 = require("../utils/ast-utils");
5
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
5
6
  const DEPS = [
6
7
  "dependencies",
7
8
  "peerDependencies",
@@ -33,7 +34,7 @@ exports.default = (0, utils_1.createRule)("no-dupe-deps", {
33
34
  type: "problem",
34
35
  },
35
36
  create(context) {
36
- const sourceCode = context.getSourceCode();
37
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
37
38
  if (!sourceCode.parserServices.isJSON) {
38
39
  return {};
39
40
  }
@@ -7,6 +7,7 @@ const semver_2 = require("../utils/semver");
7
7
  const ast_utils_1 = require("../utils/ast-utils");
8
8
  const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
9
9
  const meta_1 = require("../utils/meta");
10
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
10
11
  const DEPS = [
11
12
  "dependencies",
12
13
  "peerDependencies",
@@ -173,7 +174,7 @@ exports.default = (0, utils_1.createRule)("no-restricted-deps", {
173
174
  type: "suggestion",
174
175
  },
175
176
  create(context) {
176
- const sourceCode = context.getSourceCode();
177
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
177
178
  if (!sourceCode.parserServices.isJSON) {
178
179
  return {};
179
180
  }
@@ -4,6 +4,7 @@ const semver_1 = require("semver");
4
4
  const utils_1 = require("../utils");
5
5
  const semver_2 = require("../utils/semver");
6
6
  const semver_range_1 = require("../utils/semver-range");
7
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
7
8
  exports.default = (0, utils_1.createRule)("prefer-caret-range-version", {
8
9
  meta: {
9
10
  docs: {
@@ -17,7 +18,7 @@ exports.default = (0, utils_1.createRule)("prefer-caret-range-version", {
17
18
  type: "suggestion",
18
19
  },
19
20
  create(context) {
20
- const sourceCode = context.getSourceCode();
21
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
21
22
  if (!sourceCode.parserServices.isJSON) {
22
23
  return {};
23
24
  }
@@ -4,6 +4,7 @@ const semver_1 = require("semver");
4
4
  const utils_1 = require("../utils");
5
5
  const semver_2 = require("../utils/semver");
6
6
  const semver_range_1 = require("../utils/semver-range");
7
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
7
8
  exports.default = (0, utils_1.createRule)("prefer-tilde-range-version", {
8
9
  meta: {
9
10
  docs: {
@@ -17,7 +18,7 @@ exports.default = (0, utils_1.createRule)("prefer-tilde-range-version", {
17
18
  type: "suggestion",
18
19
  },
19
20
  create(context) {
20
- const sourceCode = context.getSourceCode();
21
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
21
22
  if (!sourceCode.parserServices.isJSON) {
22
23
  return {};
23
24
  }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../types").RuleModule;
2
+ export default _default;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("../utils");
4
+ const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
5
+ const ast_utils_1 = require("../utils/ast-utils");
6
+ const meta_1 = require("../utils/meta");
7
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
8
+ exports.default = (0, utils_1.createRule)("require-provenance-deps", {
9
+ meta: {
10
+ docs: {
11
+ description: "Require provenance information for dependencies",
12
+ category: "Best Practices",
13
+ recommended: false,
14
+ },
15
+ schema: [
16
+ {
17
+ type: "object",
18
+ properties: {
19
+ devDependencies: { type: "boolean" },
20
+ allows: {
21
+ type: "array",
22
+ items: { type: "string" },
23
+ uniqueItems: true,
24
+ },
25
+ },
26
+ additionalProperties: false,
27
+ },
28
+ ],
29
+ messages: {
30
+ missingProvenance: 'Dependency "{{name}}" has versions without provenance information: {{versions}}.',
31
+ },
32
+ type: "suggestion",
33
+ },
34
+ create(context) {
35
+ var _a;
36
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
37
+ if (!sourceCode.parserServices.isJSON) {
38
+ return {};
39
+ }
40
+ const devDependencies = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.devDependencies);
41
+ function extractNoProvenanceRanges(meta) {
42
+ var _a, _b;
43
+ const noProvenanceRanges = [];
44
+ let prev = null;
45
+ for (let index = 0; index < meta.length; index++) {
46
+ const m = meta[index];
47
+ if ((_b = (_a = m.dist) === null || _a === void 0 ? void 0 : _a.attestations) === null || _b === void 0 ? void 0 : _b.provenance) {
48
+ prev = null;
49
+ continue;
50
+ }
51
+ if (prev == null) {
52
+ prev = [m.version, m.version];
53
+ noProvenanceRanges.push(prev);
54
+ }
55
+ else {
56
+ prev[1] = m.version;
57
+ }
58
+ }
59
+ return noProvenanceRanges;
60
+ }
61
+ return (0, utils_1.defineJsonVisitor)({
62
+ [devDependencies
63
+ ? "dependencies, peerDependencies, devDependencies"
64
+ : "dependencies, peerDependencies"](node) {
65
+ var _a, _b;
66
+ const name = (0, ast_utils_1.getKeyFromJSONProperty)(node);
67
+ const ver = (0, jsonc_eslint_parser_1.getStaticJSONValue)(node.value);
68
+ if (typeof name !== "string" || typeof ver !== "string" || !ver) {
69
+ return;
70
+ }
71
+ if ((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allows) === null || _b === void 0 ? void 0 : _b.includes(name)) {
72
+ return;
73
+ }
74
+ const meta = (0, meta_1.getMetaFromNpm)(name, ver).get();
75
+ if (!meta || !meta.length) {
76
+ return;
77
+ }
78
+ const noProvenanceRanges = extractNoProvenanceRanges(meta);
79
+ if (noProvenanceRanges.length === 0) {
80
+ return;
81
+ }
82
+ context.report({
83
+ loc: node.loc,
84
+ messageId: "missingProvenance",
85
+ data: {
86
+ name,
87
+ versions: formatList(noProvenanceRanges.map(([from, to]) => from === to ? `${from}` : `${from} - ${to}`)),
88
+ },
89
+ });
90
+ },
91
+ });
92
+ function formatList(items) {
93
+ return items.length <= 2
94
+ ? items.join(" and ")
95
+ : `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
96
+ }
97
+ },
98
+ });
@@ -4,6 +4,7 @@ const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
4
4
  const utils_1 = require("../utils");
5
5
  const ast_utils_1 = require("../utils/ast-utils");
6
6
  const semver_1 = require("../utils/semver");
7
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
7
8
  exports.default = (0, utils_1.createRule)("valid-semver", {
8
9
  meta: {
9
10
  docs: {
@@ -16,7 +17,7 @@ exports.default = (0, utils_1.createRule)("valid-semver", {
16
17
  type: "problem",
17
18
  },
18
19
  create(context) {
19
- const sourceCode = context.getSourceCode();
20
+ const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
20
21
  if (!sourceCode.parserServices.isJSON) {
21
22
  return {};
22
23
  }
@@ -12,6 +12,11 @@ export type NpmPackageMeta = PackageMeta & {
12
12
  "dist-tags": {
13
13
  [key: string]: string | void;
14
14
  } | undefined;
15
+ dist?: {
16
+ attestations?: {
17
+ provenance?: Record<string, unknown>;
18
+ };
19
+ };
15
20
  };
16
21
  export declare function getMetaFromNodeModules(name: string, ver: string, options: {
17
22
  context: Rule.RuleContext;
@@ -47,14 +47,16 @@ const semver_1 = require("./semver");
47
47
  const semver_2 = require("semver");
48
48
  const npm_package_arg_1 = __importDefault(require("npm-package-arg"));
49
49
  const package_json_1 = require("./package-json");
50
+ const eslint_compat_utils_1 = require("eslint-compat-utils");
50
51
  const TTL = 1000 * 60 * 60;
52
+ const CACHE_VERSION = 2;
51
53
  const CACHED_META_ROOT = path_1.default.join(__dirname, `../../.cached_meta`);
52
54
  function getMetaFromNodeModules(name, ver, options) {
53
55
  try {
54
- const ownerJsonPath = options.ownerPackageJsonPath || options.context.getFilename();
56
+ const ownerJsonPath = options.ownerPackageJsonPath || (0, eslint_compat_utils_1.getFilename)(options.context);
55
57
  const relativeTo = path_1.default.join(ownerJsonPath && path_1.default.isAbsolute(ownerJsonPath)
56
58
  ? (0, path_1.dirname)(ownerJsonPath)
57
- : getCwd(options.context), "__placeholder__.js");
59
+ : (0, eslint_compat_utils_1.getCwd)(options.context), "__placeholder__.js");
58
60
  const req = module_1.default.createRequire(relativeTo);
59
61
  const where = req.resolve(`${name}/package.json`);
60
62
  const pkg = req(where);
@@ -176,7 +178,10 @@ function getMetaFromName(name, cachedFilePath) {
176
178
  return null;
177
179
  }
178
180
  const data = require(cachedFilePath);
179
- if (data.meta == null) {
181
+ if (!data || data.meta == null) {
182
+ return null;
183
+ }
184
+ if (data.v !== CACHE_VERSION) {
180
185
  return null;
181
186
  }
182
187
  const alive = Boolean((typeof data.expired === "number" && data.expired >= Date.now()) ||
@@ -202,6 +207,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
202
207
  optionalDependencies: vm.optionalDependencies,
203
208
  "dist-tags": allMeta["dist-tags"],
204
209
  deprecated: vm.deprecated,
210
+ dist: vm.dist,
205
211
  };
206
212
  });
207
213
  }
@@ -210,6 +216,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
210
216
  }
211
217
  const timestamp = Date.now();
212
218
  const content = {
219
+ v: CACHE_VERSION,
213
220
  meta,
214
221
  timestamp,
215
222
  expired: timestamp + Math.floor(Math.random() * 1000 * 60),
@@ -260,9 +267,3 @@ function makeDirs(dir) {
260
267
  fs_1.default.mkdirSync(d);
261
268
  }
262
269
  }
263
- function getCwd(context) {
264
- if (context.getCwd) {
265
- return context.getCwd();
266
- }
267
- return path_1.default.resolve("");
268
- }
@@ -11,6 +11,7 @@ const no_dupe_deps_1 = __importDefault(require("../rules/no-dupe-deps"));
11
11
  const no_restricted_deps_1 = __importDefault(require("../rules/no-restricted-deps"));
12
12
  const prefer_caret_range_version_1 = __importDefault(require("../rules/prefer-caret-range-version"));
13
13
  const prefer_tilde_range_version_1 = __importDefault(require("../rules/prefer-tilde-range-version"));
14
+ const require_provenance_deps_1 = __importDefault(require("../rules/require-provenance-deps"));
14
15
  const valid_engines_1 = __importDefault(require("../rules/valid-engines"));
15
16
  const valid_semver_1 = __importDefault(require("../rules/valid-semver"));
16
17
  exports.rules = [
@@ -21,6 +22,7 @@ exports.rules = [
21
22
  no_restricted_deps_1.default,
22
23
  prefer_caret_range_version_1.default,
23
24
  prefer_tilde_range_version_1.default,
25
+ require_provenance_deps_1.default,
24
26
  valid_engines_1.default,
25
27
  valid_semver_1.default,
26
28
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-node-dependencies",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "description": "ESLint plugin to check Node.js dependencies.",
5
5
  "repository": "git+https://github.com/ota-meshi/eslint-plugin-node-dependencies.git",
6
6
  "homepage": "https://github.com/ota-meshi/eslint-plugin-node-dependencies#readme",
@@ -33,6 +33,7 @@
33
33
  "eslint": ">=6.0.0"
34
34
  },
35
35
  "dependencies": {
36
+ "eslint-compat-utils": "^0.6.5",
36
37
  "jsonc-eslint-parser": "^2.0.2",
37
38
  "npm-package-arg": "^12.0.2",
38
39
  "package-json": "^10.0.1",