eslint-plugin-package-json 1.7.1 → 1.8.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
|
@@ -46,6 +46,7 @@ See [Getting Started](https://eslint-plugin-package-json.dev/getting-started) fo
|
|
|
46
46
|
| [no-redundant-files](https://eslint-plugin-package-json.dev/rules/no-redundant-files) | Prevents adding unnecessary / redundant files. | ✅ | | 💡 |
|
|
47
47
|
| [no-redundant-publishConfig](https://eslint-plugin-package-json.dev/rules/no-redundant-publishConfig) | Warns when publishConfig.access is used in unscoped packages. | ✅ | | 💡 |
|
|
48
48
|
| [order-properties](https://eslint-plugin-package-json.dev/rules/order-properties) | Enforces that package properties are declared in a consistent order. | 🎨 | 🔧 | |
|
|
49
|
+
| [prefer-rolling-workspace-spec](https://eslint-plugin-package-json.dev/rules/prefer-rolling-workspace-spec) | Require that dependencies declared with workspace protocol use a rolling workspace spec instead of a specific semver range. | | | 💡 |
|
|
49
50
|
| [repository-shorthand](https://eslint-plugin-package-json.dev/rules/repository-shorthand) | Enforce either object or shorthand declaration for repository. | ✅ | 🔧 | |
|
|
50
51
|
| [require-attribution](https://eslint-plugin-package-json.dev/rules/require-attribution) | Ensures that proper attribution is included, requiring that either `author` or `contributors` is defined, and that if `contributors` is present, it should include at least one contributor. | ✅ | | 💡 |
|
|
51
52
|
| [restrict-dependency-ranges](https://eslint-plugin-package-json.dev/rules/restrict-dependency-ranges) | Restricts the range of dependencies to allow or disallow specific types of ranges. | | | 💡 |
|
package/dist/index.mjs
CHANGED
|
@@ -6,8 +6,8 @@ import detectIndent from "detect-indent";
|
|
|
6
6
|
import { detectNewlineGraceful } from "detect-newline";
|
|
7
7
|
import sortObjectKeys from "sort-object-keys";
|
|
8
8
|
import sortPackageJson, { sortOrder } from "sort-package-json";
|
|
9
|
-
import { execFileSync } from "node:child_process";
|
|
10
9
|
import semver from "semver";
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
11
|
import { validateAuthor, validateBin, validateBrowser, validateBugs, validateBundleDependencies, validateConfig, validateContributors, validateCpu, validateDependencies, validateDescription, validateDevEngines, validateDirectories, validateEngines, validateExports, validateFiles, validateFunding, validateGypfile, validateHomepage, validateKeywords, validateLibc, validateLicense, validateMain, validateMan, validateName, validateOs, validatePackageManager, validatePeerDependenciesMeta, validatePrivate, validatePublishConfig, validateRepository, validateScripts, validateSideEffects, validateType, validateVersion, validateWorkspaces } from "package-json-validator";
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
@@ -50,7 +50,7 @@ function createRule(rule) {
|
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/rules/bin-name-casing.ts
|
|
53
|
-
const rule$
|
|
53
|
+
const rule$19 = createRule({
|
|
54
54
|
create(context) {
|
|
55
55
|
return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=bin]"(node) {
|
|
56
56
|
if (node.value.type === "JSONObjectExpression") for (const property of node.value.properties) {
|
|
@@ -92,7 +92,7 @@ function isImplicitFormat(node) {
|
|
|
92
92
|
if (node.type === "JSONLiteral") return true;
|
|
93
93
|
return node.properties.every((property) => !isJSONStringLiteral(property.key) || !property.key.value.startsWith("."));
|
|
94
94
|
}
|
|
95
|
-
const rule$
|
|
95
|
+
const rule$18 = createRule({
|
|
96
96
|
create(context) {
|
|
97
97
|
const [{ prefer = "explicit" } = {}] = context.options;
|
|
98
98
|
function validateForExplicit(node) {
|
|
@@ -193,7 +193,7 @@ const getTopLevelProperty = (node) => {
|
|
|
193
193
|
return n.type === "JSONProperty" ? n.key : void 0;
|
|
194
194
|
};
|
|
195
195
|
const defaultIgnoreProperties = ["files"];
|
|
196
|
-
const rule$
|
|
196
|
+
const rule$17 = createRule({
|
|
197
197
|
create(context) {
|
|
198
198
|
const ignoreProperties = new Set(context.options[0]?.ignoreProperties ?? defaultIgnoreProperties);
|
|
199
199
|
return {
|
|
@@ -249,7 +249,7 @@ const getBundledDependencyNames = (value) => {
|
|
|
249
249
|
if (value?.type === "JSONArrayExpression") for (const element of value.elements.filter(isNotNullish).filter(isJSONStringLiteral)) names.add(element.value);
|
|
250
250
|
return names;
|
|
251
251
|
};
|
|
252
|
-
const rule$
|
|
252
|
+
const rule$16 = createRule({
|
|
253
253
|
create(context) {
|
|
254
254
|
const ignorePrivate = context.options[0]?.ignorePrivate ?? true;
|
|
255
255
|
let isPrivate = false;
|
|
@@ -320,7 +320,7 @@ const getCachedLocalFileRegex = (filename) => {
|
|
|
320
320
|
return regex;
|
|
321
321
|
}
|
|
322
322
|
};
|
|
323
|
-
const rule$
|
|
323
|
+
const rule$15 = createRule({
|
|
324
324
|
create(context) {
|
|
325
325
|
const entryCache = {
|
|
326
326
|
bin: [],
|
|
@@ -397,7 +397,7 @@ const rule$14 = createRule({
|
|
|
397
397
|
});
|
|
398
398
|
//#endregion
|
|
399
399
|
//#region src/rules/no-redundant-publishConfig.ts
|
|
400
|
-
const rule$
|
|
400
|
+
const rule$14 = createRule({
|
|
401
401
|
create(context) {
|
|
402
402
|
let packageName;
|
|
403
403
|
let publishConfigAccessProperty;
|
|
@@ -443,7 +443,7 @@ const rule$13 = createRule({
|
|
|
443
443
|
});
|
|
444
444
|
//#endregion
|
|
445
445
|
//#region src/rules/order-properties.ts
|
|
446
|
-
const rule$
|
|
446
|
+
const rule$13 = createRule({
|
|
447
447
|
create(context) {
|
|
448
448
|
return { "Program:exit"() {
|
|
449
449
|
const { ast, text } = context.sourceCode;
|
|
@@ -500,6 +500,73 @@ const rule$12 = createRule({
|
|
|
500
500
|
name: "order-properties"
|
|
501
501
|
});
|
|
502
502
|
//#endregion
|
|
503
|
+
//#region src/rules/prefer-rolling-workspace-spec.ts
|
|
504
|
+
const rollingWorkspaceSpecRegex = /^workspace:[*^~]?$/;
|
|
505
|
+
const convertibleSpecRegex = /^(workspace:[~^])/;
|
|
506
|
+
const rule$12 = createRule({
|
|
507
|
+
create(context) {
|
|
508
|
+
const { ignoreDependencies = [], ignorePatterns = [] } = context.options[0] ?? {};
|
|
509
|
+
const ignoreRegexes = ignorePatterns.map((pattern) => new RegExp(pattern));
|
|
510
|
+
const isIgnored = (name) => ignoreDependencies.includes(name) || ignoreRegexes.some((regex) => regex.test(name));
|
|
511
|
+
return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.type=JSONLiteral]:matches([key.value=dependencies], [key.value=devDependencies])"(node) {
|
|
512
|
+
if (node.value.type === "JSONObjectExpression") for (const property of node.value.properties) {
|
|
513
|
+
const key = property.key.value;
|
|
514
|
+
if (isIgnored(key)) continue;
|
|
515
|
+
const valueNode = property.value;
|
|
516
|
+
if (!isJSONStringLiteral(valueNode) || !valueNode.value.startsWith("workspace:")) continue;
|
|
517
|
+
const dependencySpec = valueNode.value;
|
|
518
|
+
if (!rollingWorkspaceSpecRegex.test(dependencySpec)) {
|
|
519
|
+
let conversion;
|
|
520
|
+
const convertibleMatch = convertibleSpecRegex.exec(dependencySpec);
|
|
521
|
+
const rawVersion = dependencySpec.replace("workspace:", "");
|
|
522
|
+
if (convertibleMatch) conversion = convertibleMatch[1];
|
|
523
|
+
else if (semver.parse(rawVersion)) conversion = "workspace:*";
|
|
524
|
+
context.report({
|
|
525
|
+
messageId: "nonRollingWorkspaceSpec",
|
|
526
|
+
node: valueNode,
|
|
527
|
+
suggest: conversion ? [{
|
|
528
|
+
fix: (fixer) => {
|
|
529
|
+
return fixer.replaceText(valueNode, JSON.stringify(conversion));
|
|
530
|
+
},
|
|
531
|
+
messageId: "convertToRolling"
|
|
532
|
+
}] : void 0
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
} };
|
|
537
|
+
},
|
|
538
|
+
meta: {
|
|
539
|
+
defaultOptions: [{}],
|
|
540
|
+
docs: {
|
|
541
|
+
category: "Best Practices",
|
|
542
|
+
description: "Require that dependencies declared with workspace protocol use a rolling workspace spec instead of a specific semver range."
|
|
543
|
+
},
|
|
544
|
+
hasSuggestions: true,
|
|
545
|
+
messages: {
|
|
546
|
+
convertToRolling: "Convert to rolling workspace spec",
|
|
547
|
+
nonRollingWorkspaceSpec: "Workspace spec should not include specific semver range. Use a rolling workspace spec instead."
|
|
548
|
+
},
|
|
549
|
+
schema: [{
|
|
550
|
+
additionalProperties: false,
|
|
551
|
+
properties: {
|
|
552
|
+
ignoreDependencies: {
|
|
553
|
+
items: { type: ["string"] },
|
|
554
|
+
type: ["array"],
|
|
555
|
+
description: "Specific dependencies to ignore."
|
|
556
|
+
},
|
|
557
|
+
ignorePatterns: {
|
|
558
|
+
items: { type: ["string"] },
|
|
559
|
+
type: ["array"],
|
|
560
|
+
description: "Regex patterns for dependency names to ignore."
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
type: "object"
|
|
564
|
+
}],
|
|
565
|
+
type: "suggestion"
|
|
566
|
+
},
|
|
567
|
+
name: "prefer-rolling-workspace-spec"
|
|
568
|
+
});
|
|
569
|
+
//#endregion
|
|
503
570
|
//#region src/utils/findPropertyWithKeyValue.ts
|
|
504
571
|
function findPropertyWithKeyValue(properties, value) {
|
|
505
572
|
return properties.find((property) => property.key.type === "JSONLiteral" && property.key.value === value);
|
|
@@ -1864,13 +1931,14 @@ const rule = createRule({
|
|
|
1864
1931
|
//#region src/plugin.ts
|
|
1865
1932
|
const require = createRequire(import.meta.url);
|
|
1866
1933
|
const rules = {
|
|
1867
|
-
"bin-name-casing": rule$
|
|
1868
|
-
"exports-subpaths-style": rule$
|
|
1869
|
-
"no-empty-fields": rule$
|
|
1870
|
-
"no-local-dependencies": rule$
|
|
1871
|
-
"no-redundant-files": rule$
|
|
1872
|
-
"no-redundant-publishConfig": rule$
|
|
1873
|
-
"order-properties": rule$
|
|
1934
|
+
"bin-name-casing": rule$19,
|
|
1935
|
+
"exports-subpaths-style": rule$18,
|
|
1936
|
+
"no-empty-fields": rule$17,
|
|
1937
|
+
"no-local-dependencies": rule$16,
|
|
1938
|
+
"no-redundant-files": rule$15,
|
|
1939
|
+
"no-redundant-publishConfig": rule$14,
|
|
1940
|
+
"order-properties": rule$13,
|
|
1941
|
+
"prefer-rolling-workspace-spec": rule$12,
|
|
1874
1942
|
"require-attribution": rule$10,
|
|
1875
1943
|
...rules$2,
|
|
1876
1944
|
"repository-shorthand": rule$11,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-package-json",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Rules for consistent, readable, and valid package.json files. 🗂️",
|
|
5
5
|
"homepage": "https://github.com/michaelfaith/eslint-plugin-package-json#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -73,22 +73,23 @@
|
|
|
73
73
|
"@vitest/eslint-plugin": "1.6.20",
|
|
74
74
|
"astro": "7.2.0",
|
|
75
75
|
"astro-og-canvas": "0.13.0",
|
|
76
|
-
"canvaskit-wasm": "0.
|
|
76
|
+
"canvaskit-wasm": "0.42.0",
|
|
77
77
|
"console-fail-test": "0.6.0",
|
|
78
|
-
"eslint": "10.
|
|
78
|
+
"eslint": "10.9.0",
|
|
79
79
|
"eslint-doc-generator": "3.7.0",
|
|
80
80
|
"eslint-plugin-eslint-plugin": "7.6.0",
|
|
81
|
-
"eslint-plugin-jsdoc": "64.
|
|
81
|
+
"eslint-plugin-jsdoc": "64.2.0",
|
|
82
82
|
"eslint-plugin-jsonc": "3.4.0",
|
|
83
|
-
"eslint-plugin-n": "18.
|
|
83
|
+
"eslint-plugin-n": "18.3.0",
|
|
84
84
|
"eslint-plugin-node-dependencies": "2.2.0",
|
|
85
85
|
"eslint-plugin-perfectionist": "5.10.0",
|
|
86
|
-
"eslint-plugin-regexp": "3.
|
|
86
|
+
"eslint-plugin-regexp": "3.2.0",
|
|
87
87
|
"eslint-plugin-unicorn": "73.0.0",
|
|
88
88
|
"eslint-plugin-yml": "3.8.0",
|
|
89
89
|
"jiti": "2.7.0",
|
|
90
90
|
"json-schema-to-ts": "3.1.1",
|
|
91
91
|
"knip": "6.32.0",
|
|
92
|
+
"pkg-pr-new": "0.0.87",
|
|
92
93
|
"prettier": "3.9.0",
|
|
93
94
|
"prettier-plugin-curly": "0.4.1",
|
|
94
95
|
"prettier-plugin-packagejson": "3.0.2",
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"starlight-auto-sidebar": "0.4.0",
|
|
100
101
|
"tsdown": "0.22.2",
|
|
101
102
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
102
|
-
"typescript-eslint": "8.
|
|
103
|
+
"typescript-eslint": "8.68.0",
|
|
103
104
|
"vitest": "4.1.8"
|
|
104
105
|
},
|
|
105
106
|
"peerDependencies": {
|