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 +19 -0
- package/dist/index.js +157 -56
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
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: {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
15981
|
-
var
|
|
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:
|
|
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
|
|
16052
|
-
var
|
|
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:
|
|
16058
|
-
severity:
|
|
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:
|
|
16070
|
-
severity:
|
|
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:
|
|
16097
|
-
severity:
|
|
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:
|
|
16110
|
-
severity:
|
|
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
|
|
16121
|
-
var
|
|
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:
|
|
16146
|
-
severity:
|
|
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
|
|
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:
|
|
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:
|
|
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) {
|