npm-pkg-lint 4.1.2 → 4.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
@@ -106,6 +106,7 @@ Verifies the presence of files specified in:
106
106
  - `browser`
107
107
  - `module`
108
108
  - `jsnext:main`,
109
+ - `types`
109
110
  - `typings`
110
111
  - `bin`
111
112
  - `man`
@@ -116,6 +117,24 @@ Requires `types` to be the first condition in `exports`.
116
117
 
117
118
  **Why?** For TypeScript to properly detect `types` it need to come before `require` or `import`, else it will fall back to detecting by filename.
118
119
 
120
+ ## TypeScript `types` matching `exports`
121
+
122
+ Requires `types` to match `exports`.
123
+
124
+ **Why?** To avoid issues with newer TS versions resolving with `exports` if present rather than the older `types` field.
125
+
126
+ ## TypeScript prefer `types` over `typings`
127
+
128
+ Requires `types` to be used instead of `typings`.
129
+
130
+ **Why?** While TypeScript allows `typings` to be used as an alias, it is better for consistency to only use one over the other.
131
+
132
+ ## TypeScript conflicting `types` and `typings` fields
133
+
134
+ Requires only one of the two fields `types` and `typings` to be used, not both.
135
+
136
+ **Why?** `typings` is an alias for `types` and if both are set it is unclear which is to be used (and could potentially be set to different values).
137
+
119
138
  ## Disallowed dependencies
120
139
 
121
140
  Disallows certain packages from being included as `dependencies` (use `devDependencies` or `peerDependencies` instead).
package/dist/index.js CHANGED
@@ -7511,6 +7511,7 @@ var git_default = regexp5;
7511
7511
 
7512
7512
  // src/blacklist/jest.ts
7513
7513
  var regexp6 = [
7514
+ directory("__fixtures__"),
7514
7515
  directory("__snapshots__"),
7515
7516
  directory("__tests__"),
7516
7517
  extension(".snap"),
@@ -7532,7 +7533,8 @@ var regexp7 = [
7532
7533
  filename(".npmignore"),
7533
7534
  filename(".npmrc"),
7534
7535
  filename(".nvmrc"),
7535
- filename("lerna.json")
7536
+ filename("lerna.json"),
7537
+ filename("yarn.lock")
7536
7538
  ];
7537
7539
  var node_default = regexp7;
7538
7540
 
@@ -10487,12 +10489,12 @@ var Header = class {
10487
10489
  if (!buf || !(buf.length >= off + 512)) {
10488
10490
  throw new Error("need 512 bytes for header");
10489
10491
  }
10490
- this.path = decString(buf, off, 100);
10491
- this.mode = decNumber(buf, off + 100, 8);
10492
- this.uid = decNumber(buf, off + 108, 8);
10493
- this.gid = decNumber(buf, off + 116, 8);
10494
- this.size = decNumber(buf, off + 124, 12);
10495
- this.mtime = decDate(buf, off + 136, 12);
10492
+ this.path = ex?.path ?? decString(buf, off, 100);
10493
+ this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8);
10494
+ this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8);
10495
+ this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8);
10496
+ this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12);
10497
+ this.mtime = ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12);
10496
10498
  this.cksum = decNumber(buf, off + 148, 12);
10497
10499
  if (gex)
10498
10500
  this.#slurp(gex, true);
@@ -10510,10 +10512,10 @@ var Header = class {
10510
10512
  }
10511
10513
  this.linkpath = decString(buf, off + 157, 100);
10512
10514
  if (buf.subarray(off + 257, off + 265).toString() === "ustar\x0000") {
10513
- this.uname = decString(buf, off + 265, 32);
10514
- this.gname = decString(buf, off + 297, 32);
10515
- this.devmaj = decNumber(buf, off + 329, 8) ?? 0;
10516
- this.devmin = decNumber(buf, off + 337, 8) ?? 0;
10515
+ this.uname = ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32);
10516
+ this.gname = ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32);
10517
+ this.devmaj = ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0;
10518
+ this.devmin = ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0;
10517
10519
  if (buf[off + 475] !== 0) {
10518
10520
  const prefix2 = decString(buf, off + 345, 155);
10519
10521
  this.path = prefix2 + "/" + this.path;
@@ -10522,8 +10524,8 @@ var Header = class {
10522
10524
  if (prefix2) {
10523
10525
  this.path = prefix2 + "/" + this.path;
10524
10526
  }
10525
- this.atime = decDate(buf, off + 476, 12);
10526
- this.ctime = decDate(buf, off + 488, 12);
10527
+ this.atime = ex?.atime ?? gex?.atime ?? decDate(buf, off + 476, 12);
10528
+ this.ctime = ex?.ctime ?? gex?.ctime ?? decDate(buf, off + 488, 12);
10527
10529
  }
10528
10530
  }
10529
10531
  let sum = 8 * 32;
@@ -12330,13 +12332,15 @@ var listFileSync = (opt) => {
12330
12332
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
12331
12333
  if (stat.size < readSize) {
12332
12334
  const buf = Buffer.allocUnsafe(stat.size);
12333
- fs3.readSync(fd, buf, 0, stat.size, 0);
12334
- p.end(buf);
12335
+ const read = fs3.readSync(fd, buf, 0, stat.size, 0);
12336
+ p.end(read === buf.byteLength ? buf : buf.subarray(0, read));
12335
12337
  } else {
12336
12338
  let pos2 = 0;
12337
12339
  const buf = Buffer.allocUnsafe(readSize);
12338
12340
  while (pos2 < stat.size) {
12339
12341
  const bytesRead = fs3.readSync(fd, buf, 0, readSize, pos2);
12342
+ if (bytesRead === 0)
12343
+ break;
12340
12344
  pos2 += bytesRead;
12341
12345
  p.write(buf.subarray(0, bytesRead));
12342
12346
  }
@@ -15322,6 +15326,9 @@ function* requiredFiles(pkg) {
15322
15326
  ruleId
15323
15327
  });
15324
15328
  }
15329
+ if (pkg.types) {
15330
+ yield* yieldRequiredFiles(pkg.types, { field: "types", ruleId: "no-missing-types" });
15331
+ }
15325
15332
  if (pkg.typings) {
15326
15333
  yield* yieldRequiredFiles(pkg.typings, { field: "typings", ruleId: "no-missing-typings" });
15327
15334
  }
@@ -15435,9 +15442,6 @@ async function persistentCacheSet(key, data) {
15435
15442
  await fs13.writeFile(filePath, content, "utf-8");
15436
15443
  }
15437
15444
 
15438
- // src/rules/deprecated-dependency.ts
15439
- var import_semver = __toESM(require_semver2(), 1);
15440
-
15441
15445
  // src/utils/json-location.ts
15442
15446
  function findNextNode(current, segment, datapath) {
15443
15447
  const { value } = current;
@@ -15479,7 +15483,13 @@ import { stripVTControlCharacters } from "node:util";
15479
15483
  var getContext = (raw2) => ({
15480
15484
  start: process3.hrtime.bigint(),
15481
15485
  command: raw2.map((part) => getCommandPart(stripVTControlCharacters(part))).join(" "),
15482
- state: { stdout: "", stderr: "", output: "" }
15486
+ state: {
15487
+ stdout: "",
15488
+ stderr: "",
15489
+ output: "",
15490
+ isIterating: {},
15491
+ nonIterable: [false, false]
15492
+ }
15483
15493
  });
15484
15494
  var getCommandPart = (part) => /[^\w./-]/.test(part) ? `'${part.replaceAll("'", "'\\''")}'` : part;
15485
15495
 
@@ -15637,8 +15647,8 @@ var concatenateShell = (file, commandArguments, options) => options.shell && com
15637
15647
  var bufferOutput = (stream, { state }, streamName) => {
15638
15648
  if (stream) {
15639
15649
  stream.setEncoding("utf8");
15640
- if (!state.isIterating) {
15641
- state.isIterating = false;
15650
+ if (!state.isIterating[streamName]) {
15651
+ state.isIterating[streamName] = false;
15642
15652
  stream.on("data", (chunk) => {
15643
15653
  state[streamName] += chunk;
15644
15654
  state.output += chunk;
@@ -15683,16 +15693,20 @@ var closeStdin = async (nodeChildProcess) => {
15683
15693
 
15684
15694
  // node_modules/nano-spawn/source/iterable.js
15685
15695
  import * as readline from "node:readline/promises";
15686
- var lineIterator = async function* (subprocess, { state }, streamName) {
15687
- if (state.isIterating === false) {
15696
+ var lineIterator = async function* (subprocess, { state }, streamName, index) {
15697
+ if (state.isIterating[streamName] === false) {
15688
15698
  throw new Error(`The subprocess must be iterated right away, for example:
15689
15699
  for await (const line of spawn(...)) { ... }`);
15690
15700
  }
15691
- state.isIterating = true;
15701
+ state.isIterating[streamName] = true;
15692
15702
  try {
15693
15703
  const { [streamName]: stream } = await subprocess.nodeChildProcess;
15694
15704
  if (!stream) {
15695
- return;
15705
+ state.nonIterable[index] = true;
15706
+ const message = state.nonIterable.every(Boolean) ? "either the option `stdout` or `stderr`" : `the option \`${streamName}\``;
15707
+ throw new TypeError(
15708
+ `The subprocess cannot be iterated unless ${message} is 'pipe'.`
15709
+ );
15696
15710
  }
15697
15711
  handleErrors(subprocess);
15698
15712
  yield* readline.createInterface({ input: stream });
@@ -15706,11 +15720,11 @@ var handleErrors = async (subprocess) => {
15706
15720
  } catch {
15707
15721
  }
15708
15722
  };
15709
- var combineAsyncIterators = async function* (...iterators) {
15723
+ var combineAsyncIterators = async function* ({ state }, ...iterators) {
15710
15724
  try {
15711
15725
  let promises = [];
15712
15726
  while (iterators.length > 0) {
15713
- promises = iterators.map((iterator2, index2) => promises[index2] ?? getNext(iterator2));
15727
+ promises = iterators.map((iterator2, index2) => promises[index2] ?? getNext(iterator2, index2, state));
15714
15728
  const [{ value, done }, index] = await Promise.race(promises.map((promise, index2) => Promise.all([promise, index2])));
15715
15729
  const [iterator] = iterators.splice(index, 1);
15716
15730
  promises.splice(index, 1);
@@ -15723,13 +15737,14 @@ var combineAsyncIterators = async function* (...iterators) {
15723
15737
  await Promise.all(iterators.map((iterator) => iterator.return()));
15724
15738
  }
15725
15739
  };
15726
- var getNext = async (iterator) => {
15740
+ var getNext = async (iterator, index, { nonIterable }) => {
15727
15741
  try {
15728
15742
  return await iterator.next();
15729
15743
  } catch (error) {
15730
- await iterator.throw(error);
15744
+ return shouldIgnoreError(nonIterable, index) ? iterator.return() : iterator.throw(error);
15731
15745
  }
15732
15746
  };
15747
+ var shouldIgnoreError = (nonIterable, index) => nonIterable.every(Boolean) ? index !== nonIterable.length - 1 : nonIterable[index];
15733
15748
 
15734
15749
  // node_modules/nano-spawn/source/index.js
15735
15750
  function spawn2(file, second, third, previous) {
@@ -15740,13 +15755,13 @@ function spawn2(file, second, third, previous) {
15740
15755
  let subprocess = getResult(nodeChildProcess, spawnOptions, context);
15741
15756
  Object.assign(subprocess, { nodeChildProcess });
15742
15757
  subprocess = previous ? handlePipe([previous, subprocess]) : subprocess;
15743
- const stdout = lineIterator(subprocess, context, "stdout");
15744
- const stderr = lineIterator(subprocess, context, "stderr");
15758
+ const stdout = lineIterator(subprocess, context, "stdout", 0);
15759
+ const stderr = lineIterator(subprocess, context, "stderr", 1);
15745
15760
  return Object.assign(subprocess, {
15746
15761
  nodeChildProcess,
15747
15762
  stdout,
15748
15763
  stderr,
15749
- [Symbol.asyncIterator]: () => combineAsyncIterators(stdout, stderr),
15764
+ [Symbol.asyncIterator]: () => combineAsyncIterators(context, stdout, stderr),
15750
15765
  pipe: (file2, second2, third2) => spawn2(file2, second2, third2, subprocess)
15751
15766
  });
15752
15767
  }
@@ -15807,8 +15822,26 @@ async function npmInfo(pkg, options = { ignoreUnpublished: false }) {
15807
15822
  }
15808
15823
  }
15809
15824
 
15825
+ // src/rules/conflicting-types-typings.ts
15826
+ var ruleId2 = "conflicting-types-typings";
15827
+ var severity = Severity.ERROR;
15828
+ function* conflictingTypesTypings(pkg, pkgAst) {
15829
+ if (!pkg.types || !pkg.typings) {
15830
+ return;
15831
+ }
15832
+ const { line, column } = jsonLocation(pkgAst, "member", "typings");
15833
+ yield {
15834
+ ruleId: ruleId2,
15835
+ severity,
15836
+ message: `Duplicate "typings" and "types" field`,
15837
+ line,
15838
+ column
15839
+ };
15840
+ }
15841
+
15810
15842
  // src/rules/deprecated-dependency.ts
15811
- var ruleId2 = "no-deprecated-dependency";
15843
+ var import_semver = __toESM(require_semver2(), 1);
15844
+ var ruleId3 = "no-deprecated-dependency";
15812
15845
  function createEntry(key, version2, source) {
15813
15846
  if (version2.startsWith("file:")) {
15814
15847
  return null;
@@ -15864,7 +15897,7 @@ async function deprecatedDependency(pkg, pkgAst, options) {
15864
15897
  }
15865
15898
  const { line, column } = jsonLocation(pkgAst, "member", dependency.source, dependency.name);
15866
15899
  messages.push({
15867
- ruleId: ruleId2,
15900
+ ruleId: ruleId3,
15868
15901
  severity: 2,
15869
15902
  message: `"${dependency.spec}" is deprecated and must not be used`,
15870
15903
  line,
@@ -15877,7 +15910,7 @@ async function deprecatedDependency(pkg, pkgAst, options) {
15877
15910
  }
15878
15911
  const { line, column } = jsonLocation(pkgAst, "member", dependency.source, dependency.name);
15879
15912
  messages.push({
15880
- ruleId: ruleId2,
15913
+ ruleId: ruleId3,
15881
15914
  severity: 1,
15882
15915
  message: `"${dependency.spec}" is not published to the NPM registry`,
15883
15916
  line,
@@ -15977,8 +16010,8 @@ function isDisallowedDependency(pkg, dependency) {
15977
16010
  }
15978
16011
 
15979
16012
  // src/rules/exports-types-order.ts
15980
- var ruleId3 = "exports-types-order";
15981
- var severity = Severity.ERROR;
16013
+ var ruleId4 = "exports-types-order";
16014
+ var severity2 = Severity.ERROR;
15982
16015
  function* validateOrder(pkgAst, value, path15) {
15983
16016
  if (!value || typeof value === "string") {
15984
16017
  return;
@@ -15991,8 +16024,8 @@ function* validateOrder(pkgAst, value, path15) {
15991
16024
  const { line, column } = jsonLocation(pkgAst, "member", "exports", ...path15, "types");
15992
16025
  const property = path15.map((it) => `["${it}"]`).join("");
15993
16026
  yield {
15994
- ruleId: ruleId3,
15995
- severity,
16027
+ ruleId: ruleId4,
16028
+ severity: severity2,
15996
16029
  message: `"types" must be the first condition in "exports${property}"`,
15997
16030
  line,
15998
16031
  column
@@ -16048,14 +16081,14 @@ var nodeVersions = [
16048
16081
  ];
16049
16082
 
16050
16083
  // src/rules/outdated-engines.ts
16051
- var ruleId4 = "outdated-engines";
16052
- var severity2 = Severity.ERROR;
16084
+ var ruleId5 = "outdated-engines";
16085
+ var severity3 = Severity.ERROR;
16053
16086
  function* outdatedEngines(pkg, pkgAst, ignoreNodeVersion) {
16054
16087
  if (!pkg.engines?.node) {
16055
16088
  const { line: line2, column: column2 } = pkg.engines ? jsonLocation(pkgAst, "member", "engines") : { line: 1, column: 1 };
16056
16089
  yield {
16057
- ruleId: ruleId4,
16058
- severity: severity2,
16090
+ ruleId: ruleId5,
16091
+ severity: severity3,
16059
16092
  message: "Missing engines.node field",
16060
16093
  line: line2,
16061
16094
  column: column2
@@ -16066,8 +16099,8 @@ function* outdatedEngines(pkg, pkgAst, ignoreNodeVersion) {
16066
16099
  const range = pkg.engines.node;
16067
16100
  if (!import_semver2.default.validRange(range)) {
16068
16101
  yield {
16069
- ruleId: ruleId4,
16070
- severity: severity2,
16102
+ ruleId: ruleId5,
16103
+ severity: severity3,
16071
16104
  message: `engines.node "${range}" is not a valid semver range`,
16072
16105
  line,
16073
16106
  column
@@ -16093,8 +16126,8 @@ function* outdatedEngines(pkg, pkgAst, ignoreNodeVersion) {
16093
16126
  const nodeRelease = major > 0 ? major : `0.${String(minor)}`;
16094
16127
  const message = `engines.node is satisfied by Node ${String(nodeRelease)} (EOL since ${descriptor.eol})`;
16095
16128
  yield {
16096
- ruleId: ruleId4,
16097
- severity: severity2,
16129
+ ruleId: ruleId5,
16130
+ severity: severity3,
16098
16131
  message,
16099
16132
  line,
16100
16133
  column
@@ -16106,8 +16139,8 @@ function* outdatedEngines(pkg, pkgAst, ignoreNodeVersion) {
16106
16139
  const version2 = `v${String(ignoreNodeVersion)}.x`;
16107
16140
  const message = `--ignore-node-version=${option} used but engines.node="${range}" does not match ${version2} or the version is not EOL yet`;
16108
16141
  yield {
16109
- ruleId: ruleId4,
16110
- severity: severity2,
16142
+ ruleId: ruleId5,
16143
+ severity: severity3,
16111
16144
  message,
16112
16145
  line,
16113
16146
  column
@@ -16115,10 +16148,75 @@ function* outdatedEngines(pkg, pkgAst, ignoreNodeVersion) {
16115
16148
  }
16116
16149
  }
16117
16150
 
16151
+ // src/rules/prefer-types.ts
16152
+ var ruleId6 = "prefer-types";
16153
+ var severity4 = Severity.ERROR;
16154
+ function* preferTypes(pkg, pkgAst) {
16155
+ if (!pkg.typings || pkg.types) {
16156
+ return;
16157
+ }
16158
+ const { line, column } = jsonLocation(pkgAst, "member", "typings");
16159
+ yield {
16160
+ ruleId: ruleId6,
16161
+ severity: severity4,
16162
+ message: `Prefer "types" over "typings"`,
16163
+ line,
16164
+ column
16165
+ };
16166
+ }
16167
+
16168
+ // src/rules/shadowed-types.ts
16169
+ var ruleId7 = "shadowed-types";
16170
+ var severity5 = Severity.ERROR;
16171
+ function findDotTypes(exports) {
16172
+ if (typeof exports === "string") {
16173
+ return null;
16174
+ }
16175
+ const dot = exports["."];
16176
+ if (!dot || typeof dot === "string") {
16177
+ return null;
16178
+ }
16179
+ const types2 = dot.types;
16180
+ if (typeof types2 === "string") {
16181
+ return types2;
16182
+ } else {
16183
+ return null;
16184
+ }
16185
+ }
16186
+ function* validateTypeSubpath(pkgAst, subpath, field, value) {
16187
+ if (value.startsWith("./") && subpath === value) {
16188
+ return;
16189
+ }
16190
+ if (subpath === `./${value}`) {
16191
+ return;
16192
+ }
16193
+ const { line, column } = jsonLocation(pkgAst, "member", field);
16194
+ yield {
16195
+ ruleId: ruleId7,
16196
+ severity: severity5,
16197
+ message: `"${field}" cannot be resolved when respecting "exports" field`,
16198
+ line,
16199
+ column
16200
+ };
16201
+ }
16202
+ function* shadowedTypes(pkg, pkgAst) {
16203
+ const { exports } = pkg;
16204
+ if (!exports) {
16205
+ return;
16206
+ }
16207
+ const subpath = findDotTypes(exports);
16208
+ if (pkg.types) {
16209
+ yield* validateTypeSubpath(pkgAst, subpath, "types", pkg.types);
16210
+ }
16211
+ if (pkg.typings) {
16212
+ yield* validateTypeSubpath(pkgAst, subpath, "typings", pkg.typings);
16213
+ }
16214
+ }
16215
+
16118
16216
  // src/rules/types-node-matching-engine.ts
16119
16217
  var import_semver3 = __toESM(require_semver2(), 1);
16120
- var ruleId5 = "types-node-matching-engine";
16121
- var severity3 = Severity.ERROR;
16218
+ var ruleId8 = "types-node-matching-engine";
16219
+ var severity6 = Severity.ERROR;
16122
16220
  function* typesNodeMatchingEngine(pkg, pkgAst) {
16123
16221
  if (!pkg.engines?.node) {
16124
16222
  return;
@@ -16142,8 +16240,8 @@ function* typesNodeMatchingEngine(pkg, pkgAst) {
16142
16240
  const actualVersion = `v${String(typesVersion.major)}`;
16143
16241
  const expectedVersion = `v${String(nodeVersion.major)}`;
16144
16242
  yield {
16145
- ruleId: ruleId5,
16146
- severity: severity3,
16243
+ ruleId: ruleId8,
16244
+ severity: severity6,
16147
16245
  message: `@types/node ${actualVersion} does not equal engines.node ${expectedVersion}`,
16148
16246
  line,
16149
16247
  column
@@ -16154,7 +16252,7 @@ function* typesNodeMatchingEngine(pkg, pkgAst) {
16154
16252
 
16155
16253
  // src/rules/verify-engine-constraint.ts
16156
16254
  var import_semver4 = __toESM(require_semver2(), 1);
16157
- var ruleId6 = "invalid-engine-constraint";
16255
+ var ruleId9 = "invalid-engine-constraint";
16158
16256
  async function* getDeepDependencies(pkg, visited, dependency) {
16159
16257
  if (dependency) {
16160
16258
  if (visited.has(dependency)) {
@@ -16192,7 +16290,7 @@ async function verifyDependency(dependency, minDeclared, declaredConstraint) {
16192
16290
  }
16193
16291
  if (!import_semver4.default.satisfies(minDeclared, constraint)) {
16194
16292
  return {
16195
- ruleId: ruleId6,
16293
+ ruleId: ruleId9,
16196
16294
  severity: 2,
16197
16295
  message: `the transitive dependency "${dependency}" (node ${constraint}) does not satisfy the declared node engine "${declaredConstraint}"`,
16198
16296
  line: 1,
@@ -16221,7 +16319,7 @@ async function verifyEngineConstraint(pkg) {
16221
16319
  } catch (err) {
16222
16320
  if (isNpmInfoError(err) && err.code === "E404") {
16223
16321
  messages.push({
16224
- ruleId: ruleId6,
16322
+ ruleId: ruleId9,
16225
16323
  severity: 1,
16226
16324
  message: `the transitive dependency "${dependency}" is not published to the NPM registry`,
16227
16325
  line: 1,
@@ -16476,12 +16574,15 @@ function verifyDependencies(pkg, pkgAst, options) {
16476
16574
  async function verifyPackageJson(pkg, pkgAst, filePath, options = { allowedDependencies: /* @__PURE__ */ new Set(), ignoreNodeVersion: false }) {
16477
16575
  const { ignoreNodeVersion } = options;
16478
16576
  const messages = [
16577
+ ...conflictingTypesTypings(pkg, pkgAst),
16479
16578
  ...await deprecatedDependency(pkg, pkgAst, options),
16480
16579
  ...await verifyEngineConstraint(pkg),
16481
16580
  ...exportsTypesOrder(pkg, pkgAst),
16482
16581
  ...verifyFields(pkg, pkgAst, options),
16483
16582
  ...verifyDependencies(pkg, pkgAst, options),
16484
16583
  ...outdatedEngines(pkg, pkgAst, ignoreNodeVersion),
16584
+ ...preferTypes(pkg, pkgAst),
16585
+ ...shadowedTypes(pkg, pkgAst),
16485
16586
  ...typesNodeMatchingEngine(pkg, pkgAst)
16486
16587
  ];
16487
16588
  if (messages.length === 0) {