pob 40.2.0 → 40.3.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.
@@ -1,4 +1,4 @@
1
- import { existsSync, readdirSync } from "node:fs";
1
+ import { readdirSync } from "node:fs";
2
2
  import Generator from "yeoman-generator";
3
3
  import { latestLTS } from "../../../utils/nodeVersions.js";
4
4
  import * as packageUtils from "../../../utils/package.js";
@@ -6,6 +6,9 @@ import { packageManagerRun } from "../../../utils/packageManagerUtils.js";
6
6
  import { copyAndFormatTpl } from "../../../utils/writeAndFormat.js";
7
7
 
8
8
  const rootConfigExtensionsRegex = /\.config\.(?:ts|mts|cts)$/;
9
+ // .js scripts count too: tsc then fails on them, which flags their migration
10
+ // to typescript
11
+ const scriptExtensionsRegex = /\.[cm]?[jt]s$/;
9
12
 
10
13
  const hasRootConfigFiles = (rootPath) => {
11
14
  try {
@@ -17,6 +20,17 @@ const hasRootConfigFiles = (rootPath) => {
17
20
  }
18
21
  };
19
22
 
23
+ // a scripts/ dir with only shell scripts gives tsc no input (TS18003)
24
+ const hasScriptFiles = (scriptsPath) => {
25
+ try {
26
+ return readdirSync(scriptsPath, { recursive: true }).some((name) =>
27
+ scriptExtensionsRegex.test(name),
28
+ );
29
+ } catch {
30
+ return false;
31
+ }
32
+ };
33
+
20
34
  export default class MonorepoTypescriptGenerator extends Generator {
21
35
  constructor(args, opts) {
22
36
  super(args, opts);
@@ -75,7 +89,7 @@ export default class MonorepoTypescriptGenerator extends Generator {
75
89
  #hasTools() {
76
90
  return (
77
91
  hasRootConfigFiles(this.destinationPath()) ||
78
- existsSync(this.destinationPath("scripts"))
92
+ hasScriptFiles(this.destinationPath("scripts"))
79
93
  );
80
94
  }
81
95
 
@@ -1,3 +1,4 @@
1
+ import pobDependencies from "pob-dependencies";
1
2
  import semver from "semver";
2
3
  import { latestLTS, maintenanceLTS } from "./nodeVersions.js";
3
4
  import * as packageUtils from "./package.js";
@@ -26,22 +27,31 @@ export const getEnvsMinNodeMajor = (envs, onlyLatestLTS) => {
26
27
  };
27
28
 
28
29
  /**
29
- * Min node major of a range, undefined when missing or not parseable
30
+ * Min version of a range, undefined when missing or not parseable
30
31
  * (workspace:*, catalog:, npm: alias...).
31
32
  */
32
- export const getMinMajor = (range) => {
33
+ const getMinVersion = (range) => {
33
34
  if (!range) return undefined;
34
35
  try {
35
- const minVersion = semver.minVersion(range);
36
- return minVersion ? semver.major(minVersion) : undefined;
36
+ return semver.minVersion(range) ?? undefined;
37
37
  } catch {
38
38
  return undefined;
39
39
  }
40
40
  };
41
41
 
42
42
  /**
43
- * engines.node value for a min node major. When envs are not defined, an
44
- * already higher engines.node is kept.
43
+ * Min node major of a range, undefined when missing or not parseable
44
+ * (workspace:*, catalog:, npm: alias...).
45
+ */
46
+ export const getMinMajor = (range) => {
47
+ const minVersion = getMinVersion(range);
48
+ return minVersion ? semver.major(minVersion) : undefined;
49
+ };
50
+
51
+ /**
52
+ * engines.node value for a min node major. An engines.node with a higher min
53
+ * version is kept, to guarantee a node version with a security fix: within
54
+ * the min major when envs are defined, any higher version otherwise.
45
55
  */
46
56
  export const resolveEnginesNode = (
47
57
  currentEnginesNode,
@@ -56,11 +66,13 @@ export const resolveEnginesNode = (
56
66
  throw new Error(`Invalid min node version: ${minNodeMajor}`);
57
67
  }
58
68
 
59
- if (!hasEnvs) {
60
- const currentMinMajor = getMinMajor(currentEnginesNode);
61
- if (currentMinMajor !== undefined && currentMinMajor > Number(major)) {
62
- return currentEnginesNode;
63
- }
69
+ const currentMinVersion = getMinVersion(currentEnginesNode);
70
+ if (
71
+ currentMinVersion &&
72
+ semver.gt(currentMinVersion, minVersion) &&
73
+ (!hasEnvs || semver.major(currentMinVersion) === Number(major))
74
+ ) {
75
+ return currentEnginesNode;
64
76
  }
65
77
 
66
78
  return `>=${minVersion}`;
@@ -68,7 +80,9 @@ export const resolveEnginesNode = (
68
80
 
69
81
  /**
70
82
  * Updates "@types/node" when it is lower than engines.node min major.
71
- * Never adds it, never lowers devDependencies.
83
+ * Never adds it, never lowers devDependencies. A pinned devDependency stays
84
+ * pinned (check-package-dependencies/require-pinned-versions), with the
85
+ * pob-dependencies version when it satisfies the min major.
72
86
  */
73
87
  export const updateTypesNodeFromEngines = (pkg) => {
74
88
  const minMajor = getMinMajor(pkg.engines?.node);
@@ -83,7 +97,12 @@ export const updateTypesNodeFromEngines = (pkg) => {
83
97
  if (currentDevVersion) {
84
98
  const currentMinMajor = getMinMajor(currentDevVersion);
85
99
  if (currentMinMajor !== undefined && currentMinMajor < minMajor) {
86
- pkg.devDependencies["@types/node"] = range;
100
+ const pinnedVersion = pobDependencies["@types/node"];
101
+ pkg.devDependencies["@types/node"] =
102
+ semver.valid(currentDevVersion) &&
103
+ semver.major(pinnedVersion) >= minMajor
104
+ ? pinnedVersion
105
+ : range;
87
106
  }
88
107
  }
89
108
  };
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
+ import pobDependencies from "pob-dependencies";
2
3
  import {
3
4
  resolveEnginesNode,
4
5
  updateNodeEngines,
@@ -6,13 +7,24 @@ import {
6
7
  } from "./nodeEngines.js";
7
8
 
8
9
  describe("updateTypesNodeFromEngines", () => {
9
- it("updates devDependencies when lower than engines min major", () => {
10
+ it("keeps pinned devDependencies pinned when lower than engines min major", () => {
10
11
  const pkg = {
11
12
  engines: { node: ">=24.14.1" },
12
13
  devDependencies: { "@types/node": "22.5.0" },
13
14
  };
14
15
  updateTypesNodeFromEngines(pkg);
15
- expect(pkg.devDependencies["@types/node"]).toBe(">=24.0.0");
16
+ expect(pkg.devDependencies["@types/node"]).toBe(
17
+ pobDependencies["@types/node"],
18
+ );
19
+ });
20
+
21
+ it("uses a range when the pinned version is lower than engines min major", () => {
22
+ const pkg = {
23
+ engines: { node: ">=99.0.0" },
24
+ devDependencies: { "@types/node": "22.5.0" },
25
+ };
26
+ updateTypesNodeFromEngines(pkg);
27
+ expect(pkg.devDependencies["@types/node"]).toBe(">=99.0.0");
16
28
  });
17
29
 
18
30
  it("keeps devDependencies with the same major", () => {
@@ -114,6 +126,17 @@ describe("resolveEnginesNode", () => {
114
126
  it("lets envs lower engines.node", () => {
115
127
  expect(resolveEnginesNode(">=24.14.1", "22", true)).toBe(">=22.18.0");
116
128
  });
129
+
130
+ it.each([true, false])(
131
+ "keeps a higher min version of the same major (hasEnvs: %s)",
132
+ (hasEnvs) => {
133
+ expect(resolveEnginesNode(">=24.15.3", "24", hasEnvs)).toBe(">=24.15.3");
134
+ },
135
+ );
136
+
137
+ it("raises a lower min version of the same major", () => {
138
+ expect(resolveEnginesNode(">=24.0.0", "24", true)).toBe(">=24.14.1");
139
+ });
117
140
  });
118
141
 
119
142
  describe("updateNodeEngines", () => {
@@ -124,7 +147,9 @@ describe("updateNodeEngines", () => {
124
147
  };
125
148
  updateNodeEngines(pkg, {});
126
149
  expect(pkg.engines.node).toBe(">=24.14.1");
127
- expect(pkg.devDependencies["@types/node"]).toBe(">=24.0.0");
150
+ expect(pkg.devDependencies["@types/node"]).toBe(
151
+ pobDependencies["@types/node"],
152
+ );
128
153
  });
129
154
 
130
155
  it("supports babelEnvs", () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "40.2.0",
3
+ "version": "40.3.0",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/vitest",
5
5
  "keywords": [
6
6
  "skeleton"
@@ -37,7 +37,7 @@
37
37
  "@pob/sort-object": "11.2.0",
38
38
  "@pob/sort-pkg": "13.2.0",
39
39
  "@types/inquirer": "9.0.10",
40
- "@yeoman/adapter": "4.0.2",
40
+ "@yeoman/adapter": "4.0.3",
41
41
  "eslint": "10.12.0",
42
42
  "findup-sync": "^5.0.0",
43
43
  "git-remote-url": "^1.0.1",
@@ -56,10 +56,10 @@
56
56
  "typescript": "npm:@typescript/typescript6@6.0.2",
57
57
  "validate-npm-package-name": "^8.0.0",
58
58
  "yeoman-environment": "6.3.0",
59
- "yeoman-generator": "10.0.1"
59
+ "yeoman-generator": "10.3.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@pob/root": "28.2.0",
62
+ "@pob/root": "28.2.1",
63
63
  "@types/node": "24.19.1",
64
64
  "@typescript/native": "npm:typescript@7.0.2",
65
65
  "@yeoman/types": "1.13.1",