@pnpm/config.version-policy 1100.1.4 → 1100.1.6

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/lib/index.d.ts CHANGED
@@ -21,4 +21,13 @@ export interface PublishedByPolicy {
21
21
  * instant and surfaces invalid exclude patterns under the same error code.
22
22
  */
23
23
  export declare function getPublishedByPolicy(opts: PublishedByPolicyOptions): PublishedByPolicy;
24
+ /**
25
+ * Merges a list of package version policy specs (e.g. `minimumReleaseAgeExclude`
26
+ * entries) into one canonical entry per package. Specs for the same package are
27
+ * combined: a bare name/pattern (no version) excludes every version and absorbs
28
+ * any version-specific specs for that package, otherwise the exact versions are
29
+ * deduplicated, sorted by semver, and joined into a single `name@v1 || v2` entry.
30
+ * Packages keep their first-seen order so the output is stable.
31
+ */
32
+ export declare function mergePackageVersionSpecs(specs: string[]): string[];
24
33
  export declare function expandPackageVersionSpecs(specs: string[]): Set<string>;
package/lib/index.js CHANGED
@@ -40,6 +40,34 @@ export function getPublishedByPolicy(opts) {
40
40
  : undefined,
41
41
  };
42
42
  }
43
+ /**
44
+ * Merges a list of package version policy specs (e.g. `minimumReleaseAgeExclude`
45
+ * entries) into one canonical entry per package. Specs for the same package are
46
+ * combined: a bare name/pattern (no version) excludes every version and absorbs
47
+ * any version-specific specs for that package, otherwise the exact versions are
48
+ * deduplicated, sorted by semver, and joined into a single `name@v1 || v2` entry.
49
+ * Packages keep their first-seen order so the output is stable.
50
+ */
51
+ export function mergePackageVersionSpecs(specs) {
52
+ const byPackage = new Map();
53
+ for (const spec of specs) {
54
+ const { packageName, exactVersions } = parseVersionPolicyRule(spec);
55
+ const existing = byPackage.get(packageName);
56
+ if (existing === undefined) {
57
+ byPackage.set(packageName, exactVersions.length === 0 ? null : new Set(exactVersions));
58
+ }
59
+ else if (existing === null || exactVersions.length === 0) {
60
+ byPackage.set(packageName, null);
61
+ }
62
+ else {
63
+ for (const version of exactVersions)
64
+ existing.add(version);
65
+ }
66
+ }
67
+ return Array.from(byPackage.entries()).map(([packageName, versions]) => versions == null
68
+ ? packageName
69
+ : `${packageName}@${Array.from(versions).sort(semver.compare).join(' || ')}`);
70
+ }
43
71
  export function expandPackageVersionSpecs(specs) {
44
72
  const expandedSpecs = new Set();
45
73
  for (const spec of specs) {
@@ -56,16 +84,27 @@ export function expandPackageVersionSpecs(specs) {
56
84
  return expandedSpecs;
57
85
  }
58
86
  function evaluateVersionPolicy(rules, pkgName) {
87
+ let matchedVersions;
88
+ let seen;
59
89
  for (const { nameMatcher, exactVersions } of rules) {
60
90
  if (!nameMatcher(pkgName)) {
61
91
  continue;
62
92
  }
63
93
  if (exactVersions.length === 0) {
64
- return true;
94
+ return matchedVersions ?? true;
95
+ }
96
+ if (matchedVersions == null) {
97
+ matchedVersions = [];
98
+ seen = new Set();
99
+ }
100
+ for (const version of exactVersions) {
101
+ if (!seen.has(version)) {
102
+ seen.add(version);
103
+ matchedVersions.push(version);
104
+ }
65
105
  }
66
- return exactVersions;
67
106
  }
68
- return false;
107
+ return matchedVersions ?? false;
69
108
  }
70
109
  function parseVersionPolicyRule(pattern) {
71
110
  const isScoped = pattern.startsWith('@');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/config.version-policy",
3
- "version": "1100.1.4",
3
+ "version": "1100.1.6",
4
4
  "description": "Parses and evaluates package version policy specs and produces package-version matchers",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -10,9 +10,9 @@
10
10
  "funding": "https://opencollective.com/pnpm",
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "https://github.com/pnpm/pnpm/tree/main/config/version-policy"
13
+ "url": "https://github.com/pnpm/pnpm/tree/main/pnpm11/config/version-policy"
14
14
  },
15
- "homepage": "https://github.com/pnpm/pnpm/tree/main/config/version-policy#readme",
15
+ "homepage": "https://github.com/pnpm/pnpm/tree/main/pnpm11/config/version-policy#readme",
16
16
  "bugs": {
17
17
  "url": "https://github.com/pnpm/pnpm/issues"
18
18
  },
@@ -27,15 +27,15 @@
27
27
  "!*.map"
28
28
  ],
29
29
  "dependencies": {
30
- "semver": "^7.8.1",
30
+ "semver": "^7.8.4",
31
+ "@pnpm/error": "1100.0.1",
31
32
  "@pnpm/config.matcher": "1100.0.1",
32
- "@pnpm/types": "1101.3.1",
33
- "@pnpm/error": "1100.0.0"
33
+ "@pnpm/types": "1101.3.2"
34
34
  },
35
35
  "devDependencies": {
36
- "@jest/globals": "30.3.0",
36
+ "@jest/globals": "30.4.1",
37
37
  "@types/semver": "7.7.1",
38
- "@pnpm/config.version-policy": "1100.1.4"
38
+ "@pnpm/config.version-policy": "1100.1.6"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=22.13"