npm-pkg-lint 4.5.3 → 4.6.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/README.md +20 -0
- package/dist/index.js +121 -37
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -412,3 +412,23 @@ The following `package.json`:
|
|
|
412
412
|
```
|
|
413
413
|
|
|
414
414
|
will yield an error becase `@tsconfig/node14` is for NodeJS v14 but the `engines.node` constraints the version to v12.
|
|
415
|
+
|
|
416
|
+
## `package-lock.json` lockfile
|
|
417
|
+
|
|
418
|
+
Requires `package-lock.json`, if present, to pass the following checks:
|
|
419
|
+
|
|
420
|
+
- Lockfile version must be 3.
|
|
421
|
+
- All packages must be resolved from `https://registry.npmjs.org/`.
|
|
422
|
+
|
|
423
|
+
**Why?** Lockfile version 3 (introduced with npm v7) includes the full dependency tree in a more compact and efficient format.
|
|
424
|
+
Older lockfile versions (1 and 2) are either missing information or include redundant data that version 3 supersedes.
|
|
425
|
+
Using version 3 ensures compatibility with modern npm tooling and avoids the ambiguity of the legacy formats.
|
|
426
|
+
|
|
427
|
+
**Why?** Packages resolved from private registries, git URLs, or local paths indicate non-standard dependencies that may not be reproducible in all environments.
|
|
428
|
+
All published production dependencies should be resolvable from the public npm registry to ensure consumers can reliably install the same code.
|
|
429
|
+
|
|
430
|
+
To upgrade an existing lockfile to version 3 run:
|
|
431
|
+
|
|
432
|
+
```sh
|
|
433
|
+
npm install --lockfile-version 3 --package-lock-only
|
|
434
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -349,7 +349,7 @@ var require_argparse = __commonJS({
|
|
|
349
349
|
var _UNRECOGNIZED_ARGS_ATTR = "_unrecognized_args";
|
|
350
350
|
var assert = __require("assert");
|
|
351
351
|
var util = __require("util");
|
|
352
|
-
var
|
|
352
|
+
var fs8 = __require("fs");
|
|
353
353
|
var sub = require_sub();
|
|
354
354
|
var path8 = __require("path");
|
|
355
355
|
var repr = util.inspect;
|
|
@@ -1838,7 +1838,7 @@ var require_argparse = __commonJS({
|
|
|
1838
1838
|
start,
|
|
1839
1839
|
end,
|
|
1840
1840
|
highWaterMark,
|
|
1841
|
-
|
|
1841
|
+
fs9
|
|
1842
1842
|
] = _parse_opts(arguments, {
|
|
1843
1843
|
flags: "r",
|
|
1844
1844
|
encoding: void 0,
|
|
@@ -1871,7 +1871,7 @@ var require_argparse = __commonJS({
|
|
|
1871
1871
|
if (start !== void 0) this._options.start = start;
|
|
1872
1872
|
if (end !== void 0) this._options.end = end;
|
|
1873
1873
|
if (highWaterMark !== void 0) this._options.highWaterMark = highWaterMark;
|
|
1874
|
-
if (
|
|
1874
|
+
if (fs9 !== void 0) this._options.fs = fs9;
|
|
1875
1875
|
}
|
|
1876
1876
|
call(string) {
|
|
1877
1877
|
if (string === "-") {
|
|
@@ -1886,7 +1886,7 @@ var require_argparse = __commonJS({
|
|
|
1886
1886
|
}
|
|
1887
1887
|
let fd;
|
|
1888
1888
|
try {
|
|
1889
|
-
fd =
|
|
1889
|
+
fd = fs8.openSync(string, this._flags, this._options.mode);
|
|
1890
1890
|
} catch (e) {
|
|
1891
1891
|
let args = { filename: string, error: e.message };
|
|
1892
1892
|
let message = "can't open '%(filename)s': %(error)s";
|
|
@@ -1894,9 +1894,9 @@ var require_argparse = __commonJS({
|
|
|
1894
1894
|
}
|
|
1895
1895
|
let options = Object.assign({ fd, flags: this._flags }, this._options);
|
|
1896
1896
|
if (this._flags.includes("r")) {
|
|
1897
|
-
return
|
|
1897
|
+
return fs8.createReadStream(void 0, options);
|
|
1898
1898
|
} else if (this._flags.includes("w")) {
|
|
1899
|
-
return
|
|
1899
|
+
return fs8.createWriteStream(void 0, options);
|
|
1900
1900
|
} else {
|
|
1901
1901
|
let msg = sub('argument "%s" with mode %r', string, this._flags);
|
|
1902
1902
|
throw new TypeError(msg);
|
|
@@ -2755,7 +2755,7 @@ var require_argparse = __commonJS({
|
|
|
2755
2755
|
new_arg_strings.push(arg_string);
|
|
2756
2756
|
} else {
|
|
2757
2757
|
try {
|
|
2758
|
-
let args_file =
|
|
2758
|
+
let args_file = fs8.readFileSync(arg_string.slice(1), "utf8");
|
|
2759
2759
|
let arg_strings2 = [];
|
|
2760
2760
|
for (let arg_line of splitlines(args_file)) {
|
|
2761
2761
|
for (let arg of this.convert_arg_line_to_args(arg_line)) {
|
|
@@ -3203,11 +3203,11 @@ var require_argparse = __commonJS({
|
|
|
3203
3203
|
// node_modules/tmp/lib/tmp.js
|
|
3204
3204
|
var require_tmp = __commonJS({
|
|
3205
3205
|
"node_modules/tmp/lib/tmp.js"(exports, module) {
|
|
3206
|
-
var
|
|
3206
|
+
var fs8 = __require("fs");
|
|
3207
3207
|
var os3 = __require("os");
|
|
3208
3208
|
var path8 = __require("path");
|
|
3209
3209
|
var crypto2 = __require("crypto");
|
|
3210
|
-
var _c = { fs:
|
|
3210
|
+
var _c = { fs: fs8.constants, os: os3.constants };
|
|
3211
3211
|
var RANDOM_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
3212
3212
|
var TEMPLATE_PATTERN = /XXXXXX/;
|
|
3213
3213
|
var DEFAULT_TRIES = 3;
|
|
@@ -3219,13 +3219,13 @@ var require_tmp = __commonJS({
|
|
|
3219
3219
|
var FILE_MODE = 384;
|
|
3220
3220
|
var EXIT = "exit";
|
|
3221
3221
|
var _removeObjects = [];
|
|
3222
|
-
var FN_RMDIR_SYNC =
|
|
3222
|
+
var FN_RMDIR_SYNC = fs8.rmdirSync.bind(fs8);
|
|
3223
3223
|
var _gracefulCleanup = false;
|
|
3224
3224
|
function rimraf(dirPath, callback) {
|
|
3225
|
-
return
|
|
3225
|
+
return fs8.rm(dirPath, { recursive: true }, callback);
|
|
3226
3226
|
}
|
|
3227
3227
|
function FN_RIMRAF_SYNC(dirPath) {
|
|
3228
|
-
return
|
|
3228
|
+
return fs8.rmSync(dirPath, { recursive: true });
|
|
3229
3229
|
}
|
|
3230
3230
|
function tmpName(options, callback) {
|
|
3231
3231
|
const args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
@@ -3235,7 +3235,7 @@ var require_tmp = __commonJS({
|
|
|
3235
3235
|
(function _getUniqueName() {
|
|
3236
3236
|
try {
|
|
3237
3237
|
const name = _generateTmpName(sanitizedOptions);
|
|
3238
|
-
|
|
3238
|
+
fs8.stat(name, function(err2) {
|
|
3239
3239
|
if (!err2) {
|
|
3240
3240
|
if (tries-- > 0) return _getUniqueName();
|
|
3241
3241
|
return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
|
|
@@ -3255,7 +3255,7 @@ var require_tmp = __commonJS({
|
|
|
3255
3255
|
do {
|
|
3256
3256
|
const name = _generateTmpName(sanitizedOptions);
|
|
3257
3257
|
try {
|
|
3258
|
-
|
|
3258
|
+
fs8.statSync(name);
|
|
3259
3259
|
} catch (e) {
|
|
3260
3260
|
return name;
|
|
3261
3261
|
}
|
|
@@ -3266,10 +3266,10 @@ var require_tmp = __commonJS({
|
|
|
3266
3266
|
const args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
3267
3267
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
3268
3268
|
if (err) return cb(err);
|
|
3269
|
-
|
|
3269
|
+
fs8.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
|
|
3270
3270
|
if (err2) return cb(err2);
|
|
3271
3271
|
if (opts.discardDescriptor) {
|
|
3272
|
-
return
|
|
3272
|
+
return fs8.close(fd, function _discardCallback(possibleErr) {
|
|
3273
3273
|
return cb(possibleErr, name, void 0, _prepareTmpFileRemoveCallback(name, -1, opts, false));
|
|
3274
3274
|
});
|
|
3275
3275
|
} else {
|
|
@@ -3283,9 +3283,9 @@ var require_tmp = __commonJS({
|
|
|
3283
3283
|
const args = _parseArguments(options), opts = args[0];
|
|
3284
3284
|
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
|
|
3285
3285
|
const name = tmpNameSync(opts);
|
|
3286
|
-
let fd =
|
|
3286
|
+
let fd = fs8.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
|
|
3287
3287
|
if (opts.discardDescriptor) {
|
|
3288
|
-
|
|
3288
|
+
fs8.closeSync(fd);
|
|
3289
3289
|
fd = void 0;
|
|
3290
3290
|
}
|
|
3291
3291
|
return {
|
|
@@ -3298,7 +3298,7 @@ var require_tmp = __commonJS({
|
|
|
3298
3298
|
const args = _parseArguments(options, callback), opts = args[0], cb = args[1];
|
|
3299
3299
|
tmpName(opts, function _tmpNameCreated(err, name) {
|
|
3300
3300
|
if (err) return cb(err);
|
|
3301
|
-
|
|
3301
|
+
fs8.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
|
|
3302
3302
|
if (err2) return cb(err2);
|
|
3303
3303
|
cb(null, name, _prepareTmpDirRemoveCallback(name, opts, false));
|
|
3304
3304
|
});
|
|
@@ -3307,7 +3307,7 @@ var require_tmp = __commonJS({
|
|
|
3307
3307
|
function dirSync(options) {
|
|
3308
3308
|
const args = _parseArguments(options), opts = args[0];
|
|
3309
3309
|
const name = tmpNameSync(opts);
|
|
3310
|
-
|
|
3310
|
+
fs8.mkdirSync(name, opts.mode || DIR_MODE);
|
|
3311
3311
|
return {
|
|
3312
3312
|
name,
|
|
3313
3313
|
removeCallback: _prepareTmpDirRemoveCallback(name, opts, true)
|
|
@@ -3321,20 +3321,20 @@ var require_tmp = __commonJS({
|
|
|
3321
3321
|
next();
|
|
3322
3322
|
};
|
|
3323
3323
|
if (0 <= fdPath[0])
|
|
3324
|
-
|
|
3325
|
-
|
|
3324
|
+
fs8.close(fdPath[0], function() {
|
|
3325
|
+
fs8.unlink(fdPath[1], _handler);
|
|
3326
3326
|
});
|
|
3327
|
-
else
|
|
3327
|
+
else fs8.unlink(fdPath[1], _handler);
|
|
3328
3328
|
}
|
|
3329
3329
|
function _removeFileSync(fdPath) {
|
|
3330
3330
|
let rethrownException = null;
|
|
3331
3331
|
try {
|
|
3332
|
-
if (0 <= fdPath[0])
|
|
3332
|
+
if (0 <= fdPath[0]) fs8.closeSync(fdPath[0]);
|
|
3333
3333
|
} catch (e) {
|
|
3334
3334
|
if (!_isEBADF(e) && !_isENOENT(e)) throw e;
|
|
3335
3335
|
} finally {
|
|
3336
3336
|
try {
|
|
3337
|
-
|
|
3337
|
+
fs8.unlinkSync(fdPath[1]);
|
|
3338
3338
|
} catch (e) {
|
|
3339
3339
|
if (!_isENOENT(e)) rethrownException = e;
|
|
3340
3340
|
}
|
|
@@ -3350,7 +3350,7 @@ var require_tmp = __commonJS({
|
|
|
3350
3350
|
return sync ? removeCallbackSync : removeCallback;
|
|
3351
3351
|
}
|
|
3352
3352
|
function _prepareTmpDirRemoveCallback(name, opts, sync) {
|
|
3353
|
-
const removeFunction = opts.unsafeCleanup ? rimraf :
|
|
3353
|
+
const removeFunction = opts.unsafeCleanup ? rimraf : fs8.rmdir.bind(fs8);
|
|
3354
3354
|
const removeFunctionSync = opts.unsafeCleanup ? FN_RIMRAF_SYNC : FN_RMDIR_SYNC;
|
|
3355
3355
|
const removeCallbackSync = _prepareRemoveCallback(removeFunctionSync, name, sync);
|
|
3356
3356
|
const removeCallback = _prepareRemoveCallback(removeFunction, name, sync, removeCallbackSync);
|
|
@@ -3413,24 +3413,24 @@ var require_tmp = __commonJS({
|
|
|
3413
3413
|
}
|
|
3414
3414
|
function _resolvePath(name, tmpDir, cb) {
|
|
3415
3415
|
const pathToResolve = path8.isAbsolute(name) ? name : path8.join(tmpDir, name);
|
|
3416
|
-
|
|
3416
|
+
fs8.stat(pathToResolve, function(err) {
|
|
3417
3417
|
if (err) {
|
|
3418
|
-
|
|
3418
|
+
fs8.realpath(path8.dirname(pathToResolve), function(err2, parentDir) {
|
|
3419
3419
|
if (err2) return cb(err2);
|
|
3420
3420
|
cb(null, path8.join(parentDir, path8.basename(pathToResolve)));
|
|
3421
3421
|
});
|
|
3422
3422
|
} else {
|
|
3423
|
-
|
|
3423
|
+
fs8.realpath(pathToResolve, cb);
|
|
3424
3424
|
}
|
|
3425
3425
|
});
|
|
3426
3426
|
}
|
|
3427
3427
|
function _resolvePathSync(name, tmpDir) {
|
|
3428
3428
|
const pathToResolve = path8.isAbsolute(name) ? name : path8.join(tmpDir, name);
|
|
3429
3429
|
try {
|
|
3430
|
-
|
|
3431
|
-
return
|
|
3430
|
+
fs8.statSync(pathToResolve);
|
|
3431
|
+
return fs8.realpathSync(pathToResolve);
|
|
3432
3432
|
} catch (_err) {
|
|
3433
|
-
const parentDir =
|
|
3433
|
+
const parentDir = fs8.realpathSync(path8.dirname(pathToResolve));
|
|
3434
3434
|
return path8.join(parentDir, path8.basename(pathToResolve));
|
|
3435
3435
|
}
|
|
3436
3436
|
}
|
|
@@ -3535,10 +3535,10 @@ var require_tmp = __commonJS({
|
|
|
3535
3535
|
_gracefulCleanup = true;
|
|
3536
3536
|
}
|
|
3537
3537
|
function _getTmpDir(options, cb) {
|
|
3538
|
-
return
|
|
3538
|
+
return fs8.realpath(options && options.tmpdir || os3.tmpdir(), cb);
|
|
3539
3539
|
}
|
|
3540
3540
|
function _getTmpDirSync(options) {
|
|
3541
|
-
return
|
|
3541
|
+
return fs8.realpathSync(options && options.tmpdir || os3.tmpdir());
|
|
3542
3542
|
}
|
|
3543
3543
|
process.addListener(EXIT, _garbageCollector);
|
|
3544
3544
|
Object.defineProperty(module.exports, "tmpdir", {
|
|
@@ -5489,7 +5489,7 @@ var require_semver2 = __commonJS({
|
|
|
5489
5489
|
});
|
|
5490
5490
|
|
|
5491
5491
|
// src/index.ts
|
|
5492
|
-
import { createWriteStream, existsSync, promises as
|
|
5492
|
+
import { createWriteStream, existsSync, promises as fs7, readFileSync } from "node:fs";
|
|
5493
5493
|
import path7 from "node:path";
|
|
5494
5494
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
5495
5495
|
|
|
@@ -12152,6 +12152,89 @@ async function verifyPackageJson(pkg, pkgAst, filePath, options = { allowedDepen
|
|
|
12152
12152
|
];
|
|
12153
12153
|
}
|
|
12154
12154
|
|
|
12155
|
+
// src/package-lock.ts
|
|
12156
|
+
import { promises as fs6 } from "node:fs";
|
|
12157
|
+
var REGISTRY_URL = "https://registry.npmjs.org/";
|
|
12158
|
+
function isErrnoException(err) {
|
|
12159
|
+
return err instanceof Error && "code" in err;
|
|
12160
|
+
}
|
|
12161
|
+
function isPackageLockVersion3(lockfile) {
|
|
12162
|
+
return lockfile.lockfileVersion === 3;
|
|
12163
|
+
}
|
|
12164
|
+
function isValidResolved(pkg) {
|
|
12165
|
+
return pkg.resolved === void 0 || pkg.resolved.startsWith(REGISTRY_URL);
|
|
12166
|
+
}
|
|
12167
|
+
async function readLockfile(lockfilePath) {
|
|
12168
|
+
try {
|
|
12169
|
+
return await fs6.readFile(lockfilePath, "utf-8");
|
|
12170
|
+
} catch (err) {
|
|
12171
|
+
if (isErrnoException(err) && err.code === "ENOENT") {
|
|
12172
|
+
return null;
|
|
12173
|
+
}
|
|
12174
|
+
throw err;
|
|
12175
|
+
}
|
|
12176
|
+
}
|
|
12177
|
+
async function verifyPackageLock() {
|
|
12178
|
+
const lockfilePath = await findUp("package-lock.json");
|
|
12179
|
+
if (!lockfilePath) {
|
|
12180
|
+
return [];
|
|
12181
|
+
}
|
|
12182
|
+
const content = await readLockfile(lockfilePath);
|
|
12183
|
+
if (content === null) {
|
|
12184
|
+
return [];
|
|
12185
|
+
}
|
|
12186
|
+
const lockfile = JSON.parse(content);
|
|
12187
|
+
const ast = parse(content);
|
|
12188
|
+
if (!isPackageLockVersion3(lockfile)) {
|
|
12189
|
+
const { line, column } = jsonLocation(ast, "value", "lockfileVersion");
|
|
12190
|
+
return [
|
|
12191
|
+
{
|
|
12192
|
+
messages: [
|
|
12193
|
+
{
|
|
12194
|
+
ruleId: "package-lock-version",
|
|
12195
|
+
severity: 2,
|
|
12196
|
+
message: `package-lock.json has lockfileVersion ${lockfile.lockfileVersion} but expected 3`,
|
|
12197
|
+
line,
|
|
12198
|
+
column
|
|
12199
|
+
}
|
|
12200
|
+
],
|
|
12201
|
+
filePath: lockfilePath,
|
|
12202
|
+
errorCount: 1,
|
|
12203
|
+
warningCount: 0,
|
|
12204
|
+
fixableErrorCount: 0,
|
|
12205
|
+
fixableWarningCount: 0
|
|
12206
|
+
}
|
|
12207
|
+
];
|
|
12208
|
+
}
|
|
12209
|
+
const { packages } = lockfile;
|
|
12210
|
+
const results = [];
|
|
12211
|
+
for (const [name, pkg] of Object.entries(packages)) {
|
|
12212
|
+
if (pkg.link) {
|
|
12213
|
+
continue;
|
|
12214
|
+
}
|
|
12215
|
+
if (!isValidResolved(pkg)) {
|
|
12216
|
+
const { line, column } = jsonLocation(ast, "value", "packages", name, "resolved");
|
|
12217
|
+
results.push({
|
|
12218
|
+
messages: [
|
|
12219
|
+
{
|
|
12220
|
+
ruleId: "package-lock-registry",
|
|
12221
|
+
severity: 2,
|
|
12222
|
+
message: `package "${name}" is resolved from "${String(pkg.resolved)}" instead of the npm registry`,
|
|
12223
|
+
line,
|
|
12224
|
+
column
|
|
12225
|
+
}
|
|
12226
|
+
],
|
|
12227
|
+
filePath: lockfilePath,
|
|
12228
|
+
errorCount: 1,
|
|
12229
|
+
warningCount: 0,
|
|
12230
|
+
fixableErrorCount: 0,
|
|
12231
|
+
fixableWarningCount: 0
|
|
12232
|
+
});
|
|
12233
|
+
}
|
|
12234
|
+
}
|
|
12235
|
+
return results;
|
|
12236
|
+
}
|
|
12237
|
+
|
|
12155
12238
|
// src/shebang.ts
|
|
12156
12239
|
function getBinaries(pkg) {
|
|
12157
12240
|
if (!pkg.bin) {
|
|
@@ -12193,6 +12276,7 @@ async function verify(pkg, pkgAst, pkgPath, tarball, options) {
|
|
|
12193
12276
|
return [
|
|
12194
12277
|
...await verifyTarball(pkg, tarball),
|
|
12195
12278
|
...await verifyPackageJson(pkg, pkgAst, pkgPath, options),
|
|
12279
|
+
...await verifyPackageLock(),
|
|
12196
12280
|
...await verifyShebang(pkg, tarball)
|
|
12197
12281
|
];
|
|
12198
12282
|
}
|
|
@@ -12221,7 +12305,7 @@ async function preloadStdin() {
|
|
|
12221
12305
|
}
|
|
12222
12306
|
async function getPackageJson(args, regenerateReportName) {
|
|
12223
12307
|
if (args.pkgfile) {
|
|
12224
|
-
const content = await
|
|
12308
|
+
const content = await fs7.readFile(args.pkgfile, "utf-8");
|
|
12225
12309
|
const pkg = JSON.parse(content);
|
|
12226
12310
|
const pkgAst = parse(content);
|
|
12227
12311
|
return {
|
|
@@ -12246,7 +12330,7 @@ async function getPackageJson(args, regenerateReportName) {
|
|
|
12246
12330
|
}
|
|
12247
12331
|
const pkgPath = await findUp(PACKAGE_JSON);
|
|
12248
12332
|
if (pkgPath) {
|
|
12249
|
-
const content = await
|
|
12333
|
+
const content = await fs7.readFile(pkgPath, "utf-8");
|
|
12250
12334
|
const pkg = JSON.parse(content);
|
|
12251
12335
|
const pkgAst = parse(content);
|
|
12252
12336
|
return {
|