npm-pkg-lint 2.1.0 → 2.1.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/dist/index.js CHANGED
@@ -15851,8 +15851,8 @@ async function verifyTarball(pkg, tarball) {
15851
15851
  {
15852
15852
  messages,
15853
15853
  filePath: tarball.reportPath ?? tarball.filePath,
15854
- errorCount: messages.length,
15855
- warningCount: 0,
15854
+ errorCount: messages.filter((it) => it.severity === 2).length,
15855
+ warningCount: messages.filter((it) => it.severity === 1).length,
15856
15856
  fixableErrorCount: 0,
15857
15857
  fixableWarningCount: 0
15858
15858
  }
@@ -17734,26 +17734,67 @@ async function persistentCacheSet(key, data) {
17734
17734
 
17735
17735
  // src/utils/npm-info.ts
17736
17736
  var cache = /* @__PURE__ */ new Map();
17737
- async function npmInfo(pkg) {
17737
+ function isExecaError(error) {
17738
+ return Boolean(error && error instanceof Error && "stdout" in error);
17739
+ }
17740
+ function isNpmInfoError(error) {
17741
+ return Boolean(error && error instanceof Error && "summary" in error);
17742
+ }
17743
+ function tryParse(maybeJson) {
17744
+ try {
17745
+ return JSON.parse(maybeJson);
17746
+ } catch {
17747
+ return null;
17748
+ }
17749
+ }
17750
+ async function npmInfo(pkg, options = { ignoreUnpublished: false }) {
17751
+ const { ignoreUnpublished } = options;
17738
17752
  const cached = cache.get(pkg);
17739
- if (cached) {
17753
+ if (cached === null) {
17754
+ if (ignoreUnpublished) {
17755
+ return null;
17756
+ }
17757
+ } else if (cached) {
17740
17758
  return cached;
17741
17759
  }
17742
17760
  const persistent = await persistentCacheGet(pkg);
17743
17761
  if (persistent) {
17744
17762
  return persistent;
17745
17763
  }
17746
- const result = await execa("npm", ["info", "--json", pkg]);
17747
- const pkgData = JSON.parse(result.stdout);
17748
- cache.set(pkg, pkgData);
17749
- await persistentCacheSet(pkg, pkgData);
17750
- return pkgData;
17764
+ try {
17765
+ const result = await execa("npm", ["info", "--json", pkg]);
17766
+ const pkgData = JSON.parse(result.stdout);
17767
+ cache.set(pkg, pkgData);
17768
+ await persistentCacheSet(pkg, pkgData);
17769
+ return pkgData;
17770
+ } catch (err) {
17771
+ if (!isExecaError(err)) {
17772
+ throw err;
17773
+ }
17774
+ const parsed = tryParse(err.stdout);
17775
+ if (!parsed) {
17776
+ throw err;
17777
+ }
17778
+ const { code, summary, detail } = parsed.error;
17779
+ cache.set(pkg, null);
17780
+ if (ignoreUnpublished && code === "E404") {
17781
+ return null;
17782
+ }
17783
+ const wrappedError = new Error(summary);
17784
+ wrappedError.code = code;
17785
+ wrappedError.summary = summary;
17786
+ wrappedError.detail = detail;
17787
+ throw wrappedError;
17788
+ }
17751
17789
  }
17752
17790
 
17753
17791
  // src/rules/verify-engine-constraint.ts
17754
17792
  var ruleId4 = "invalid-engine-constraint";
17755
17793
  async function* getDeepDependencies(pkg, dependency) {
17756
- const pkgData = dependency ? await npmInfo(dependency) : pkg;
17794
+ const pkgData = dependency ? await npmInfo(dependency, { ignoreUnpublished: true }) : pkg;
17795
+ if (!pkgData) {
17796
+ return;
17797
+ }
17757
17798
  for (const [key, value] of Object.entries(pkgData.dependencies ?? {})) {
17758
17799
  if (key === "@types/node") {
17759
17800
  continue;
@@ -17763,8 +17804,26 @@ async function* getDeepDependencies(pkg, dependency) {
17763
17804
  yield* getDeepDependencies(pkg, deep);
17764
17805
  }
17765
17806
  }
17807
+ async function verifyDependency(dependency, minDeclared, declaredConstraint) {
17808
+ var _a;
17809
+ const pkgData = await npmInfo(dependency);
17810
+ const constraint = (_a = pkgData.engines) == null ? void 0 : _a.node;
17811
+ if (!constraint) {
17812
+ return null;
17813
+ }
17814
+ if (!import_semver2.default.satisfies(minDeclared, constraint)) {
17815
+ return {
17816
+ ruleId: ruleId4,
17817
+ severity: 2,
17818
+ message: `the transitive dependency "${dependency}" (node ${constraint}) does not satisfy the declared node engine "${declaredConstraint}"`,
17819
+ line: 1,
17820
+ column: 1
17821
+ };
17822
+ }
17823
+ return null;
17824
+ }
17766
17825
  async function verifyEngineConstraint(pkg) {
17767
- var _a, _b;
17826
+ var _a;
17768
17827
  const declaredConstraint = (_a = pkg.engines) == null ? void 0 : _a.node;
17769
17828
  if (!declaredConstraint) {
17770
17829
  return [];
@@ -17774,20 +17833,29 @@ async function verifyEngineConstraint(pkg) {
17774
17833
  throw new Error(`Failed to parse engine constraint "${declaredConstraint}"`);
17775
17834
  }
17776
17835
  const messages = [];
17836
+ const visited = /* @__PURE__ */ new Set();
17777
17837
  for await (const dependency of getDeepDependencies(pkg)) {
17778
- const pkgData = await npmInfo(dependency);
17779
- const constraint = (_b = pkgData.engines) == null ? void 0 : _b.node;
17780
- if (!constraint) {
17838
+ if (visited.has(dependency)) {
17781
17839
  continue;
17782
17840
  }
17783
- if (!import_semver2.default.satisfies(minDeclared, constraint)) {
17784
- messages.push({
17785
- ruleId: ruleId4,
17786
- severity: 2,
17787
- message: `the transitive dependency "${dependency}" (node ${constraint}) does not satisfy the declared node engine "${declaredConstraint}"`,
17788
- line: 1,
17789
- column: 1
17790
- });
17841
+ visited.add(dependency);
17842
+ try {
17843
+ const message = await verifyDependency(dependency, minDeclared, declaredConstraint);
17844
+ if (message) {
17845
+ messages.push(message);
17846
+ }
17847
+ } catch (err) {
17848
+ if (isNpmInfoError(err) && err.code === "E404") {
17849
+ messages.push({
17850
+ ruleId: ruleId4,
17851
+ severity: 1,
17852
+ message: `the transitive dependency "${dependency}" is not published to the NPM registry`,
17853
+ line: 1,
17854
+ column: 1
17855
+ });
17856
+ continue;
17857
+ }
17858
+ throw err;
17791
17859
  }
17792
17860
  }
17793
17861
  return messages;
@@ -17896,8 +17964,8 @@ async function verifyPackageJson(pkg, filePath, options = {}) {
17896
17964
  {
17897
17965
  messages,
17898
17966
  filePath,
17899
- errorCount: messages.length,
17900
- warningCount: 0,
17967
+ errorCount: messages.filter((it) => it.severity === 2).length,
17968
+ warningCount: messages.filter((it) => it.severity === 1).length,
17901
17969
  fixableErrorCount: 0,
17902
17970
  fixableWarningCount: 0
17903
17971
  }