eslint-plugin-package-json 1.6.1 → 1.6.3

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.
@@ -1,4 +1,4 @@
1
- import { t as plugin$1 } from "../plugin-C-Z8sf5g.mjs";
1
+ import { t as plugin$1 } from "../plugin-X4SuFW5t.mjs";
2
2
  import { toCompatRule } from "eslint-json-compat-utils";
3
3
  //#region src/experimental/plugin.ts
4
4
  const language = "json/json";
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as plugin } from "./plugin-C-Z8sf5g.mjs";
1
+ import { t as plugin } from "./plugin-X4SuFW5t.mjs";
2
2
  //#region src/index.ts
3
3
  const rules = plugin.rules;
4
4
  const configs = plugin.configs;
@@ -9,7 +9,9 @@ import sortPackageJson, { sortOrder } from "sort-package-json";
9
9
  import { execFileSync } from "node:child_process";
10
10
  import semver from "semver";
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
+ import fs from "node:fs";
12
13
  import path from "node:path";
14
+ import process from "node:process";
13
15
  import { sep } from "node:path/posix";
14
16
  import { findRootSync } from "@altano/repository-tools";
15
17
  //#region src/utils/predicates/isJSONStringLiteral.ts
@@ -1099,7 +1101,7 @@ const rule$7 = createRule({
1099
1101
  });
1100
1102
  //#endregion
1101
1103
  //#region src/rules/scripts-name-casing.ts
1102
- const BUILT_IN_SCRIPTS_IN_CAMEL_CASE = /* @__PURE__ */ new Set(["prepublishOnly"]);
1104
+ const BUILT_IN_SCRIPTS_IN_CAMEL_CASE = /* @__PURE__ */ new Set(["prepublishOnly", "pnpm:devPreinstall"]);
1103
1105
  const rule$6 = createRule({
1104
1106
  create(context) {
1105
1107
  return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=scripts]"(node) {
@@ -1107,15 +1109,15 @@ const rule$6 = createRule({
1107
1109
  const keyNode = property.key;
1108
1110
  const key = keyNode.value;
1109
1111
  if (BUILT_IN_SCRIPTS_IN_CAMEL_CASE.has(key)) continue;
1110
- const kebabCaseKey = key.split(":").map((segment) => kebabCase(segment)).join(":");
1111
- if (kebabCaseKey !== key) context.report({
1112
+ const kebabCaseKey = (key.startsWith(".") ? key.slice(1) : key).split(":").map((segment) => kebabCase(segment)).join(":");
1113
+ if (kebabCaseKey !== (key.startsWith(".") ? key.slice(1) : key)) context.report({
1112
1114
  data: { property: key },
1113
1115
  messageId: "invalidCase",
1114
1116
  node: keyNode,
1115
1117
  suggest: [{
1116
1118
  data: { property: key },
1117
1119
  fix: (fixer) => {
1118
- return fixer.replaceText(keyNode, JSON.stringify(kebabCaseKey));
1120
+ return fixer.replaceText(keyNode, JSON.stringify(key.startsWith(".") ? `.${kebabCaseKey}` : kebabCaseKey));
1119
1121
  },
1120
1122
  messageId: "convertToKebabCase"
1121
1123
  }]
@@ -1543,6 +1545,130 @@ const createSimpleValidPropertyRule = (propertyName, validationFunction, aliases
1543
1545
  ruleName
1544
1546
  };
1545
1547
  };
1548
+ //#endregion
1549
+ //#region src/utils/packageManager/constants.ts
1550
+ const AGENTS = [
1551
+ "npm",
1552
+ "yarn",
1553
+ "pnpm",
1554
+ "bun",
1555
+ "deno",
1556
+ "nub",
1557
+ "aube"
1558
+ ];
1559
+ const LOCK_FILES = {
1560
+ "aube-lock.yaml": "aube",
1561
+ "aube-workspace.yaml": "aube",
1562
+ "bun.lock": "bun",
1563
+ "bun.lockb": "bun",
1564
+ "deno.lock": "deno",
1565
+ "nub.lock": "nub",
1566
+ "pnpm-lock.yaml": "pnpm",
1567
+ "pnpm-workspace.yaml": "pnpm",
1568
+ "yarn.lock": "yarn",
1569
+ "package-lock.json": "npm",
1570
+ "npm-shrinkwrap.json": "npm"
1571
+ };
1572
+ //#endregion
1573
+ //#region src/utils/packageManager/detectPackageManager.ts
1574
+ let packageManagerCache;
1575
+ const userAgentRegex = /^(.+?)\/(\S+)?/;
1576
+ function getPackageManagerFromUserAgent() {
1577
+ const userAgentMatch = process.env.npm_config_user_agent?.match(userAgentRegex);
1578
+ if (userAgentMatch) {
1579
+ const name = userAgentMatch[1];
1580
+ const version = userAgentMatch[2];
1581
+ if (AGENTS.includes(name)) return {
1582
+ name,
1583
+ version
1584
+ };
1585
+ }
1586
+ return null;
1587
+ }
1588
+ function setPackageManagerCache(result) {
1589
+ packageManagerCache = result;
1590
+ return packageManagerCache;
1591
+ }
1592
+ function* lookup(cwd = process.cwd()) {
1593
+ let directory = path.resolve(cwd);
1594
+ const { root } = path.parse(directory);
1595
+ while (directory && directory !== root) {
1596
+ yield directory;
1597
+ directory = path.dirname(directory);
1598
+ }
1599
+ }
1600
+ function parsePackageJson(filepath) {
1601
+ if (!filepath || !fs.existsSync(filepath)) return null;
1602
+ return handlePackageManager(filepath);
1603
+ }
1604
+ /**
1605
+ * Detects the package manager used in the project.
1606
+ * @returns The detected package manager or `null` if not found.
1607
+ */
1608
+ function detectPackageManager() {
1609
+ if (packageManagerCache) return packageManagerCache;
1610
+ const cwd = process.cwd();
1611
+ const strategies = [
1612
+ "lockfile",
1613
+ "packageManager-field",
1614
+ "user-agent"
1615
+ ];
1616
+ for (const directory of lookup(cwd)) for (const strategy of strategies) switch (strategy) {
1617
+ case "lockfile":
1618
+ if (fs.existsSync(path.join(directory, "rush.json"))) return setPackageManagerCache({ name: "pnpm" });
1619
+ for (const lock of Object.keys(LOCK_FILES)) if (fs.existsSync(path.join(directory, lock))) {
1620
+ const name = LOCK_FILES[lock];
1621
+ return setPackageManagerCache(parsePackageJson(path.join(directory, "package.json")) ?? { name });
1622
+ }
1623
+ break;
1624
+ case "packageManager-field": {
1625
+ const result = parsePackageJson(path.join(directory, "package.json"));
1626
+ if (result) return setPackageManagerCache(result);
1627
+ break;
1628
+ }
1629
+ case "user-agent": {
1630
+ const result = getPackageManagerFromUserAgent();
1631
+ if (result) return setPackageManagerCache(result);
1632
+ break;
1633
+ }
1634
+ }
1635
+ return null;
1636
+ }
1637
+ function getNameAndVersion(pkg) {
1638
+ const normalizeVersion = (version) => version?.match(/\d+(?:\.\d+){0,2}/)?.[0] ?? version;
1639
+ if (typeof pkg.packageManager === "string") {
1640
+ const [name, version] = pkg.packageManager.replace(/^\^/, "").split("@", 2);
1641
+ return {
1642
+ name,
1643
+ version: normalizeVersion(version)
1644
+ };
1645
+ }
1646
+ if (typeof pkg.devEngines?.packageManager?.name === "string") return {
1647
+ name: pkg.devEngines.packageManager.name,
1648
+ version: normalizeVersion(pkg.devEngines.packageManager.version)
1649
+ };
1650
+ }
1651
+ function handlePackageManager(filepath) {
1652
+ try {
1653
+ const content = fs.readFileSync(filepath, "utf8");
1654
+ const nameAndVer = getNameAndVersion(JSON.parse(content));
1655
+ if (nameAndVer) return {
1656
+ name: nameAndVer.name,
1657
+ version: nameAndVer.version
1658
+ };
1659
+ } catch {}
1660
+ return null;
1661
+ }
1662
+ //#endregion
1663
+ //#region src/rules/valid-properties.ts
1664
+ const packageManagerAwareValidateDependencies = (value) => {
1665
+ const result = detectPackageManager();
1666
+ if (result?.name === "pnpm") {
1667
+ const version = result.version;
1668
+ if (!version || semver.gte(version, "11.1.0")) return validateDependencies(value, { allowNamedRegistries: true });
1669
+ }
1670
+ return validateDependencies(value);
1671
+ };
1546
1672
  /** All basic valid- flavor rules */
1547
1673
  const rules$1 = Object.fromEntries([
1548
1674
  ["bin", validateBin],
@@ -1556,8 +1682,8 @@ const rules$1 = Object.fromEntries([
1556
1682
  ["contributors", validateContributors],
1557
1683
  ["cpu", validateCpu],
1558
1684
  ["description", validateDescription],
1559
- ["dependencies", validateDependencies],
1560
- ["devDependencies", validateDependencies],
1685
+ ["dependencies", packageManagerAwareValidateDependencies],
1686
+ ["devDependencies", packageManagerAwareValidateDependencies],
1561
1687
  ["devEngines", validateDevEngines],
1562
1688
  ["directories", validateDirectories],
1563
1689
  ["engines", validateEngines],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-package-json",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
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": {
@@ -44,13 +44,14 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "@altano/repository-tools": "^2.0.1",
47
+ "@types/estree": "^1.0.0",
47
48
  "change-case": "^5.4.4",
48
49
  "detect-indent": "^7.0.2",
49
50
  "detect-newline": "^4.0.1",
50
51
  "eslint-fix-utils": "~0.4.3",
51
52
  "eslint-json-compat-utils": "^0.2.3",
52
53
  "jsonc-eslint-parser": "^3.1.0",
53
- "package-json-validator": "^1.5.0",
54
+ "package-json-validator": "^1.6.0",
54
55
  "semver": "^7.7.3",
55
56
  "sort-object-keys": "^2.0.0",
56
57
  "sort-package-json": "^4.0.0"
@@ -65,9 +66,8 @@
65
66
  "@eslint/json": "2.0.0",
66
67
  "@eslint/markdown": "8.0.1",
67
68
  "@ianvs/prettier-plugin-sort-imports": "4.7.1",
68
- "@types/estree": "1.0.8",
69
69
  "@types/node": "24.13.0",
70
- "@types/semver": "7.7.1",
70
+ "@types/semver": "7.8.0",
71
71
  "@typescript/native": "npm:typescript@7.0.2",
72
72
  "@vitest/coverage-v8": "4.1.8",
73
73
  "@vitest/eslint-plugin": "1.6.20",
@@ -75,20 +75,20 @@
75
75
  "astro-og-canvas": "0.13.0",
76
76
  "canvaskit-wasm": "0.41.1",
77
77
  "console-fail-test": "0.6.0",
78
- "eslint": "10.7.0",
78
+ "eslint": "10.8.0",
79
79
  "eslint-doc-generator": "3.7.0",
80
- "eslint-plugin-eslint-plugin": "7.5.0",
81
- "eslint-plugin-jsdoc": "63.2.0",
80
+ "eslint-plugin-eslint-plugin": "7.6.0",
81
+ "eslint-plugin-jsdoc": "63.3.0",
82
82
  "eslint-plugin-jsonc": "3.3.0",
83
83
  "eslint-plugin-n": "18.2.1",
84
84
  "eslint-plugin-node-dependencies": "2.2.0",
85
85
  "eslint-plugin-perfectionist": "5.10.0",
86
86
  "eslint-plugin-regexp": "3.1.0",
87
87
  "eslint-plugin-unicorn": "72.0.0",
88
- "eslint-plugin-yml": "3.6.0",
88
+ "eslint-plugin-yml": "3.7.0",
89
89
  "jiti": "2.7.0",
90
90
  "json-schema-to-ts": "3.1.1",
91
- "knip": "6.27.0",
91
+ "knip": "6.31.0",
92
92
  "prettier": "3.9.0",
93
93
  "prettier-plugin-curly": "0.4.1",
94
94
  "prettier-plugin-packagejson": "3.0.2",
@@ -104,15 +104,11 @@
104
104
  },
105
105
  "peerDependencies": {
106
106
  "@eslint/json": ">=1.0.0",
107
- "@types/estree": ">=1.0.0",
108
107
  "eslint": ">=9.0.0"
109
108
  },
110
109
  "peerDependenciesMeta": {
111
110
  "@eslint/json": {
112
111
  "optional": true
113
- },
114
- "@types/estree": {
115
- "optional": true
116
112
  }
117
113
  },
118
114
  "engines": {