pob 40.6.0 → 40.7.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/lib/generators/core/bun/CoreBunGenerator.js +2 -1
- package/lib/generators/core/bun/templates/bunfig.toml.ejs +3 -15
- package/lib/generators/core/pnpm/CorePnpmGenerator.js +2 -12
- package/lib/generators/core/yarn/CoreYarnGenerator.js +2 -10
- package/lib/utils/minimumReleaseAgeExcludes.js +44 -0
- package/lib/utils/minimumReleaseAgeExcludes.test.js +42 -0
- package/lib/utils/nodeEngines.js +19 -10
- package/lib/utils/nodeEngines.test.js +18 -7
- package/package.json +8 -9
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Generator from "yeoman-generator";
|
|
2
|
+
import { minimumReleaseAgeExcludeNames } from "../../../utils/minimumReleaseAgeExcludes.js";
|
|
2
3
|
|
|
3
4
|
export default class CoreBunGenerator extends Generator {
|
|
4
5
|
constructor(args, opts) {
|
|
@@ -30,7 +31,7 @@ export default class CoreBunGenerator extends Generator {
|
|
|
30
31
|
this.fs.copyTpl(
|
|
31
32
|
this.templatePath("bunfig.toml.ejs"),
|
|
32
33
|
this.destinationPath("bunfig.toml"),
|
|
33
|
-
{},
|
|
34
|
+
{ minimumReleaseAgeExcludes: minimumReleaseAgeExcludeNames },
|
|
34
35
|
);
|
|
35
36
|
} else {
|
|
36
37
|
this.fs.delete("bun.lock");
|
|
@@ -3,19 +3,7 @@
|
|
|
3
3
|
# Only install package versions published at least 2.5 days ago
|
|
4
4
|
minimumReleaseAge = 216000 # seconds
|
|
5
5
|
minimumReleaseAgeExcludes = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"@pob/rollup-esbuild",
|
|
10
|
-
"@pob/rollup-typescript",
|
|
11
|
-
"@pob/sort-object",
|
|
12
|
-
"@pob/sort-pkg",
|
|
13
|
-
"@pob/version",
|
|
14
|
-
"pob-dependencies",
|
|
15
|
-
"alouette",
|
|
16
|
-
"alouette-icons",
|
|
17
|
-
"nightingale",
|
|
18
|
-
"nightingale-logger",
|
|
19
|
-
"nightingale-levels",
|
|
20
|
-
"nightingale-types",
|
|
6
|
+
<% for (const name of minimumReleaseAgeExcludes) { -%>
|
|
7
|
+
<%- JSON.stringify(name) %>,
|
|
8
|
+
<% } -%>
|
|
21
9
|
]
|
|
@@ -3,6 +3,7 @@ import sortObject from "@pob/sort-object";
|
|
|
3
3
|
import { FAILSAFE_SCHEMA, dump, load, loadAll } from "js-yaml";
|
|
4
4
|
import { satisfies } from "semver";
|
|
5
5
|
import Generator from "yeoman-generator";
|
|
6
|
+
import { minimumReleaseAgeExcludePatterns } from "../../../utils/minimumReleaseAgeExcludes.js";
|
|
6
7
|
import { writeAndFormat } from "../../../utils/writeAndFormat.js";
|
|
7
8
|
|
|
8
9
|
const pnpmVersionRange = "^12.0.0";
|
|
@@ -40,17 +41,6 @@ const getRunningPnpmVersion = (cwd) => {
|
|
|
40
41
|
}
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
const minimumReleaseAgeExcludePackages = [
|
|
44
|
-
"@pob/*",
|
|
45
|
-
"pob",
|
|
46
|
-
"pob-dependencies",
|
|
47
|
-
"check-package-dependencies",
|
|
48
|
-
"alouette",
|
|
49
|
-
"alouette-icons",
|
|
50
|
-
"nightingale",
|
|
51
|
-
"nightingale-logger",
|
|
52
|
-
];
|
|
53
|
-
|
|
54
44
|
const trustedBuilds = ["esbuild"];
|
|
55
45
|
|
|
56
46
|
export default class CorePnpmGenerator extends Generator {
|
|
@@ -134,7 +124,7 @@ export default class CorePnpmGenerator extends Generator {
|
|
|
134
124
|
// keep the entries added by renovate for security updates, or manually
|
|
135
125
|
config.minimumReleaseAgeExclude = [
|
|
136
126
|
...new Set([
|
|
137
|
-
...
|
|
127
|
+
...minimumReleaseAgeExcludePatterns,
|
|
138
128
|
...(config.minimumReleaseAgeExclude ?? []),
|
|
139
129
|
]),
|
|
140
130
|
];
|
|
@@ -6,6 +6,7 @@ import { lt } from "semver";
|
|
|
6
6
|
import Generator from "yeoman-generator";
|
|
7
7
|
import { ensureJsonFileFormatted } from "../../../utils/ensureJsonFileFormatted.js";
|
|
8
8
|
import inMonorepo from "../../../utils/inMonorepo.js";
|
|
9
|
+
import { minimumReleaseAgeExcludePatterns } from "../../../utils/minimumReleaseAgeExcludes.js";
|
|
9
10
|
import * as packageUtils from "../../../utils/package.js";
|
|
10
11
|
import { writeAndFormat } from "../../../utils/writeAndFormat.js";
|
|
11
12
|
|
|
@@ -188,16 +189,7 @@ export default class CoreYarnGenerator extends Generator {
|
|
|
188
189
|
delete config.enableMessageNames; // was a config for yarn < 4
|
|
189
190
|
config.nodeLinker = this.options.yarnNodeLinker;
|
|
190
191
|
config.npmMinimalAgeGate = 1440 * 2.5; // 2.5 days
|
|
191
|
-
config.npmPreapprovedPackages = [
|
|
192
|
-
"@pob/*",
|
|
193
|
-
"pob-dependencies",
|
|
194
|
-
"alouette",
|
|
195
|
-
"alouette-icons",
|
|
196
|
-
"nightingale",
|
|
197
|
-
"nightingale-logger",
|
|
198
|
-
"nightingale-levels",
|
|
199
|
-
"nightingale-types",
|
|
200
|
-
];
|
|
192
|
+
config.npmPreapprovedPackages = [...minimumReleaseAgeExcludePatterns];
|
|
201
193
|
|
|
202
194
|
if (config.yarnPath) {
|
|
203
195
|
this.fs.delete(config.yarnPath);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Packages exempt from the minimum release age, so a repository can use a
|
|
2
|
+
// release of pob or of its own dependencies right away. Lockstep releases are
|
|
3
|
+
// listed together: nightingale-logger pins nightingale-levels and
|
|
4
|
+
// nightingale-types to the version published with it.
|
|
5
|
+
const otherPackages = [
|
|
6
|
+
"pob",
|
|
7
|
+
"pob-dependencies",
|
|
8
|
+
"check-package-dependencies",
|
|
9
|
+
"alouette",
|
|
10
|
+
"alouette-icons",
|
|
11
|
+
"nightingale",
|
|
12
|
+
"nightingale-logger",
|
|
13
|
+
"nightingale-levels",
|
|
14
|
+
"nightingale-types",
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
// bun matches exact names only (no glob): every published @pob package,
|
|
18
|
+
// including @pob/eslint-config-typescript, no longer in this repository.
|
|
19
|
+
const pobScopePackages = [
|
|
20
|
+
"@pob/codemods",
|
|
21
|
+
"@pob/commitlint-config",
|
|
22
|
+
"@pob/esbuild",
|
|
23
|
+
"@pob/eslint-config",
|
|
24
|
+
"@pob/eslint-config-typescript",
|
|
25
|
+
"@pob/eslint-config-typescript-react",
|
|
26
|
+
"@pob/eslint-plugin",
|
|
27
|
+
"@pob/pretty-pkg",
|
|
28
|
+
"@pob/rollup",
|
|
29
|
+
"@pob/rollup-esbuild",
|
|
30
|
+
"@pob/rollup-typescript",
|
|
31
|
+
"@pob/root",
|
|
32
|
+
"@pob/sort-object",
|
|
33
|
+
"@pob/sort-pkg",
|
|
34
|
+
"@pob/version",
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
/** pnpm `minimumReleaseAgeExclude`, yarn `npmPreapprovedPackages` (globs) */
|
|
38
|
+
export const minimumReleaseAgeExcludePatterns = ["@pob/*", ...otherPackages];
|
|
39
|
+
|
|
40
|
+
/** bun `minimumReleaseAgeExcludes` (exact names) */
|
|
41
|
+
export const minimumReleaseAgeExcludeNames = [
|
|
42
|
+
...pobScopePackages,
|
|
43
|
+
...otherPackages,
|
|
44
|
+
];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
minimumReleaseAgeExcludeNames,
|
|
7
|
+
minimumReleaseAgeExcludePatterns,
|
|
8
|
+
} from "./minimumReleaseAgeExcludes.js";
|
|
9
|
+
|
|
10
|
+
const rootPath = fileURLToPath(new URL("../../../../", import.meta.url));
|
|
11
|
+
|
|
12
|
+
const readPublishedPackageNames = (directory) =>
|
|
13
|
+
fs
|
|
14
|
+
.readdirSync(path.join(rootPath, directory), { withFileTypes: true })
|
|
15
|
+
.filter((entry) => entry.isDirectory())
|
|
16
|
+
.map((entry) => path.join(rootPath, directory, entry.name, "package.json"))
|
|
17
|
+
.filter((packageJsonPath) => fs.existsSync(packageJsonPath))
|
|
18
|
+
.map((packageJsonPath) => JSON.parse(fs.readFileSync(packageJsonPath)))
|
|
19
|
+
.filter((pkg) => !pkg.private)
|
|
20
|
+
.map((pkg) => pkg.name);
|
|
21
|
+
|
|
22
|
+
describe("minimumReleaseAgeExcludes", () => {
|
|
23
|
+
it("lists every published @pob package by name for bun", () => {
|
|
24
|
+
for (const name of readPublishedPackageNames("@pob")) {
|
|
25
|
+
expect(minimumReleaseAgeExcludeNames).toContain(name);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("excludes the same packages with globs and with exact names", () => {
|
|
30
|
+
expect(
|
|
31
|
+
minimumReleaseAgeExcludeNames.filter((name) => !name.startsWith("@pob/")),
|
|
32
|
+
).toStrictEqual(
|
|
33
|
+
minimumReleaseAgeExcludePatterns.filter((name) => name !== "@pob/*"),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("uses no glob in exact names", () => {
|
|
38
|
+
for (const name of minimumReleaseAgeExcludeNames) {
|
|
39
|
+
expect(name).not.toContain("*");
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
package/lib/utils/nodeEngines.js
CHANGED
|
@@ -3,13 +3,19 @@ import semver from "semver";
|
|
|
3
3
|
import { latestLTS, maintenanceLTS } from "./nodeVersions.js";
|
|
4
4
|
import * as packageUtils from "./package.js";
|
|
5
5
|
|
|
6
|
-
// 22.18.0 is the version with strip typescript out of experimental status
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
["
|
|
10
|
-
["
|
|
6
|
+
// 22.18.0 is the version with strip typescript out of experimental status.
|
|
7
|
+
// 22 skips node 23: features backported to 22 are experimental there.
|
|
8
|
+
const enginesNodeForMajor = new Map([
|
|
9
|
+
["22", "^22.18.0 || >=24.14.1"],
|
|
10
|
+
["24", ">=24.14.1"],
|
|
11
|
+
["26", ">=26.0.0"],
|
|
11
12
|
]);
|
|
12
13
|
|
|
14
|
+
const minVersionForMajor = (major) => {
|
|
15
|
+
const enginesNode = enginesNodeForMajor.get(major);
|
|
16
|
+
return enginesNode && semver.minVersion(enginesNode).version;
|
|
17
|
+
};
|
|
18
|
+
|
|
13
19
|
const legacyMajors = ["4", "6", "8", "10", "12", "14", "16", "18", "20"];
|
|
14
20
|
|
|
15
21
|
/**
|
|
@@ -61,7 +67,7 @@ export const resolveEnginesNode = (
|
|
|
61
67
|
const major = legacyMajors.includes(String(minNodeMajor))
|
|
62
68
|
? maintenanceLTS
|
|
63
69
|
: String(minNodeMajor);
|
|
64
|
-
const minVersion = minVersionForMajor
|
|
70
|
+
const minVersion = minVersionForMajor(major);
|
|
65
71
|
if (!minVersion) {
|
|
66
72
|
throw new Error(`Invalid min node version: ${minNodeMajor}`);
|
|
67
73
|
}
|
|
@@ -75,7 +81,7 @@ export const resolveEnginesNode = (
|
|
|
75
81
|
return currentEnginesNode;
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
return
|
|
84
|
+
return enginesNodeForMajor.get(major);
|
|
79
85
|
};
|
|
80
86
|
|
|
81
87
|
/**
|
|
@@ -129,15 +135,18 @@ export const updateNodeEngines = (pkg, { onlyLatestLTS } = {}) => {
|
|
|
129
135
|
packageUtils.removeDevDependencies(pkg, ["@types/node"]);
|
|
130
136
|
|
|
131
137
|
// Supports oldest current or active LTS version of node
|
|
132
|
-
const
|
|
138
|
+
const enginesNode = enginesNodeForMajor.get(
|
|
133
139
|
onlyLatestLTS ? latestLTS : maintenanceLTS,
|
|
134
140
|
);
|
|
135
141
|
|
|
136
142
|
if (
|
|
137
143
|
!pkg.engines.node ||
|
|
138
|
-
semver.
|
|
144
|
+
semver.lte(
|
|
145
|
+
semver.minVersion(pkg.engines.node),
|
|
146
|
+
semver.minVersion(enginesNode),
|
|
147
|
+
)
|
|
139
148
|
) {
|
|
140
|
-
pkg.engines.node =
|
|
149
|
+
pkg.engines.node = enginesNode;
|
|
141
150
|
}
|
|
142
151
|
}
|
|
143
152
|
};
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
updateTypesNodeFromEngines,
|
|
7
7
|
} from "./nodeEngines.js";
|
|
8
8
|
|
|
9
|
+
const NODE_22 = "^22.18.0 || >=24.14.1";
|
|
10
|
+
|
|
9
11
|
describe("updateTypesNodeFromEngines", () => {
|
|
10
12
|
it("keeps pinned devDependencies pinned when lower than engines min major", () => {
|
|
11
13
|
const pkg = {
|
|
@@ -97,8 +99,8 @@ describe("updateTypesNodeFromEngines", () => {
|
|
|
97
99
|
|
|
98
100
|
describe("resolveEnginesNode", () => {
|
|
99
101
|
it.each([
|
|
100
|
-
["18",
|
|
101
|
-
["22",
|
|
102
|
+
["18", NODE_22],
|
|
103
|
+
["22", NODE_22],
|
|
102
104
|
["24", ">=24.14.1"],
|
|
103
105
|
["26", ">=26.0.0"],
|
|
104
106
|
])("resolves min major %s from envs", (minMajor, expected) => {
|
|
@@ -112,11 +114,11 @@ describe("resolveEnginesNode", () => {
|
|
|
112
114
|
});
|
|
113
115
|
|
|
114
116
|
it("migrates >=22.11.x", () => {
|
|
115
|
-
expect(resolveEnginesNode(">=22.11.0", "22", false)).toBe(
|
|
117
|
+
expect(resolveEnginesNode(">=22.11.0", "22", false)).toBe(NODE_22);
|
|
116
118
|
});
|
|
117
119
|
|
|
118
120
|
it("raises a lower engines.node without envs", () => {
|
|
119
|
-
expect(resolveEnginesNode(">=18.0.0", "22", false)).toBe(
|
|
121
|
+
expect(resolveEnginesNode(">=18.0.0", "22", false)).toBe(NODE_22);
|
|
120
122
|
});
|
|
121
123
|
|
|
122
124
|
it("keeps a higher engines.node without envs", () => {
|
|
@@ -124,7 +126,7 @@ describe("resolveEnginesNode", () => {
|
|
|
124
126
|
});
|
|
125
127
|
|
|
126
128
|
it("lets envs lower engines.node", () => {
|
|
127
|
-
expect(resolveEnginesNode(">=24.14.1", "22", true)).toBe(
|
|
129
|
+
expect(resolveEnginesNode(">=24.14.1", "22", true)).toBe(NODE_22);
|
|
128
130
|
});
|
|
129
131
|
|
|
130
132
|
it.each([true, false])(
|
|
@@ -161,7 +163,7 @@ describe("updateNodeEngines", () => {
|
|
|
161
163
|
it("uses the maintenance LTS without envs", () => {
|
|
162
164
|
const pkg = {};
|
|
163
165
|
updateNodeEngines(pkg, {});
|
|
164
|
-
expect(pkg.engines.node).toBe(
|
|
166
|
+
expect(pkg.engines.node).toBe(NODE_22);
|
|
165
167
|
});
|
|
166
168
|
|
|
167
169
|
it("uses the latest LTS without envs when onlyLatestLTS", () => {
|
|
@@ -179,7 +181,16 @@ describe("updateNodeEngines", () => {
|
|
|
179
181
|
updateNodeEngines(pkg, {});
|
|
180
182
|
expect(pkg.dependencies).toBeUndefined();
|
|
181
183
|
expect(pkg.devDependencies["@types/node"]).toBeUndefined();
|
|
182
|
-
expect(pkg.engines.node).toBe(
|
|
184
|
+
expect(pkg.engines.node).toBe(NODE_22);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("migrates >=22.18.0 when there is no node target", () => {
|
|
188
|
+
const pkg = {
|
|
189
|
+
pob: { envs: [{ target: "browser" }] },
|
|
190
|
+
engines: { node: ">=22.18.0" },
|
|
191
|
+
};
|
|
192
|
+
updateNodeEngines(pkg, {});
|
|
193
|
+
expect(pkg.engines.node).toBe(NODE_22);
|
|
183
194
|
});
|
|
184
195
|
|
|
185
196
|
it("keeps a higher engines.node when there is no node target", () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pob",
|
|
3
|
-
"version": "40.
|
|
3
|
+
"version": "40.7.1",
|
|
4
4
|
"description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/vitest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"skeleton"
|
|
@@ -32,11 +32,10 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@pob/codemods": "0.18.2",
|
|
35
|
-
"@pob/eslint-config": "68.
|
|
36
|
-
"@pob/eslint-config-typescript-react": "68.
|
|
37
|
-
"@pob/sort-object": "11.
|
|
38
|
-
"@pob/sort-pkg": "13.
|
|
39
|
-
"@types/inquirer": "9.0.10",
|
|
35
|
+
"@pob/eslint-config": "68.3.0",
|
|
36
|
+
"@pob/eslint-config-typescript-react": "68.4.0",
|
|
37
|
+
"@pob/sort-object": "11.3.0",
|
|
38
|
+
"@pob/sort-pkg": "13.3.0",
|
|
40
39
|
"@yeoman/adapter": "4.0.3",
|
|
41
40
|
"eslint": "10.14.0",
|
|
42
41
|
"findup-sync": "^5.0.0",
|
|
@@ -49,9 +48,9 @@
|
|
|
49
48
|
"mem-fs": "4.1.5",
|
|
50
49
|
"mem-fs-editor": "12.1.0",
|
|
51
50
|
"minimist": "1.2.8",
|
|
52
|
-
"oxfmt": "0.
|
|
51
|
+
"oxfmt": "0.75.0",
|
|
53
52
|
"parse-author": "2.0.0",
|
|
54
|
-
"pob-dependencies": "28.
|
|
53
|
+
"pob-dependencies": "28.6.0",
|
|
55
54
|
"semver": "7.8.5",
|
|
56
55
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
57
56
|
"validate-npm-package-name": "^8.0.0",
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"yeoman-generator": "10.3.0"
|
|
60
59
|
},
|
|
61
60
|
"devDependencies": {
|
|
62
|
-
"@pob/root": "28.
|
|
61
|
+
"@pob/root": "28.6.0",
|
|
63
62
|
"@types/node": "24.19.1",
|
|
64
63
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
65
64
|
"@yeoman/types": "1.13.1",
|