pmsec 0.5.2 → 0.6.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/package.json +1 -1
- package/src/cli.mjs +2 -2
- package/src/tools/pnpm.mjs +20 -4
- package/src/util/version.mjs +19 -4
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -105,8 +105,8 @@ function renderHuman(rows, min) {
|
|
|
105
105
|
const tail = r.warn ? `\n ⚠ ${r.warn}` : "";
|
|
106
106
|
lines.push(`${status} ${r.tool.padEnd(4)} ${r.key} = ${value} [${r.path}]${tail}`);
|
|
107
107
|
for (const e of r.extras) {
|
|
108
|
-
const exStatus = e.
|
|
109
|
-
const exValue = e.configured ?? "(unset)";
|
|
108
|
+
const exStatus = e.ok ? "OK " : e.configured === null ? "MISSING" : "STALE ";
|
|
109
|
+
const exValue = e.defaultEnforced ? `(default — runtime enforces ${e.expected})` : (e.configured ?? "(unset)");
|
|
110
110
|
lines.push(`${exStatus} ${r.tool.padEnd(4)} ${e.key} = ${exValue} [${r.path}]`);
|
|
111
111
|
}
|
|
112
112
|
}
|
package/src/tools/pnpm.mjs
CHANGED
|
@@ -8,15 +8,22 @@ export const name = "pnpm";
|
|
|
8
8
|
export const key = "minimum-release-age";
|
|
9
9
|
export const docs = "https://pnpm.io/settings#minimumreleaseage";
|
|
10
10
|
export const minBin = [10, 6, 0];
|
|
11
|
+
// `defaultSinceMajor`: pnpm major version where the value became the default.
|
|
12
|
+
// Once detected, an absent line in `.npmrc` is still effectively in force, so
|
|
13
|
+
// `read()` reports it as ok with `defaultEnforced: true`.
|
|
11
14
|
export const extras = [
|
|
12
15
|
{ key: "trust-policy", expected: "no-downgrade", line: "trust-policy=no-downgrade" },
|
|
13
|
-
{ key: "block-exotic-subdeps", expected: "true", line: "block-exotic-subdeps=true" }
|
|
16
|
+
{ key: "block-exotic-subdeps", expected: "true", line: "block-exotic-subdeps=true", defaultSinceMajor: 11 }
|
|
14
17
|
];
|
|
15
18
|
|
|
16
19
|
export function path(env, home) { return npmrcPath(env, home); }
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
function pnpmVersion(env) {
|
|
22
|
+
return detectVersion("pnpm", ["--version"], { env, overrideKey: "PMSEC_PNPM_VERSION" });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function preflight(env) {
|
|
26
|
+
const v = pnpmVersion(env);
|
|
20
27
|
if (v === null) return { ok: true, message: null };
|
|
21
28
|
if (gte(v, minBin)) return { ok: true, version: v.raw, message: null };
|
|
22
29
|
return { ok: true, warn: true, version: v.raw, message: `pnpm ${v.raw} < ${minBin.join(".")}: minimum-release-age is silently ignored. Upgrade pnpm to enforce the cooldown.` };
|
|
@@ -27,10 +34,19 @@ export async function read(env, home) {
|
|
|
27
34
|
const raw = await readSafe(p);
|
|
28
35
|
const value = readKey(raw, key);
|
|
29
36
|
const minutes = value === null ? null : Number(value);
|
|
37
|
+
const v = pnpmVersion(env);
|
|
38
|
+
const defaults = new Map(extras.filter(x => x.defaultSinceMajor).map(x => [x.key, x.defaultSinceMajor]));
|
|
39
|
+
const evaluated = readExtras(raw, extras).map(e => {
|
|
40
|
+
const def = defaults.get(e.key);
|
|
41
|
+
if (e.configured === null && def && v && v.major >= def) {
|
|
42
|
+
return { ...e, ok: true, defaultEnforced: true };
|
|
43
|
+
}
|
|
44
|
+
return e;
|
|
45
|
+
});
|
|
30
46
|
return {
|
|
31
47
|
path: p, configured: value,
|
|
32
48
|
days: minutes === null || Number.isNaN(minutes) ? null : Math.floor(minutes / (60 * 24)),
|
|
33
|
-
extras:
|
|
49
|
+
extras: evaluated
|
|
34
50
|
};
|
|
35
51
|
}
|
|
36
52
|
|
package/src/util/version.mjs
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function parseSemver(s) {
|
|
4
|
+
const m = String(s || "").match(/(\d+)\.(\d+)\.(\d+)/);
|
|
5
|
+
if (!m) return null;
|
|
6
|
+
return { major: +m[1], minor: +m[2], patch: +m[3], raw: m[0] };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// `env[overrideKey]` ("X.Y.Z" or "none") forces the result without spawning the
|
|
10
|
+
// real binary — used by tests to make pnpm 11 default-enforcement behavior
|
|
11
|
+
// deterministic regardless of what's installed locally.
|
|
12
|
+
export function detectVersion(bin, args = ["--version"], { env, overrideKey } = {}) {
|
|
13
|
+
if (env && overrideKey) {
|
|
14
|
+
const o = env[overrideKey];
|
|
15
|
+
if (o === "none") return null;
|
|
16
|
+
if (o) {
|
|
17
|
+
const p = parseSemver(o);
|
|
18
|
+
if (p) return p;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
4
21
|
try {
|
|
5
22
|
const res = spawnSync(bin, args, { encoding: "utf8" });
|
|
6
23
|
if (res.status !== 0) return null;
|
|
7
|
-
|
|
8
|
-
if (!m) return null;
|
|
9
|
-
return { major: +m[1], minor: +m[2], patch: +m[3], raw: m[0] };
|
|
24
|
+
return parseSemver(res.stdout);
|
|
10
25
|
} catch { return null; }
|
|
11
26
|
}
|
|
12
27
|
|