pob 35.0.0 → 35.2.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.
Files changed (29) hide show
  1. package/lib/generators/app/PobAppGenerator.js +6 -9
  2. package/lib/generators/common/format-lint/CommonLintGenerator.js +4 -1
  3. package/lib/generators/common/format-lint/templates/oxfmtrc.jsonc.ejs +2 -2
  4. package/lib/generators/common/release/CommonReleaseGenerator.js +8 -2
  5. package/lib/generators/common/release/templates/workflow-release.yml.ejs +20 -3
  6. package/lib/generators/common/testing/CommonTestingGenerator.js +13 -8
  7. package/lib/generators/common/transpiler/CommonTranspilerGenerator.js +23 -8
  8. package/lib/generators/common/typescript/CommonTypescriptGenerator.js +2 -6
  9. package/lib/generators/common/typescript/templates/tsconfig.json.ejs +1 -0
  10. package/lib/generators/core/ci/CoreCIGenerator.js +6 -0
  11. package/lib/generators/core/ci/templates/github-action-documentation-workflow.yml.ejs +9 -0
  12. package/lib/generators/core/ci/templates/github-action-push-workflow-split.yml.ejs +87 -2
  13. package/lib/generators/core/ci/templates/github-action-push-workflow.yml.ejs +11 -2
  14. package/lib/generators/core/git/CoreGitGenerator.js +3 -3
  15. package/lib/generators/core/package/CorePackageGenerator.js +3 -0
  16. package/lib/generators/core/pnpm/CorePnpmGenerator.js +103 -0
  17. package/lib/generators/core/vscode/CoreVSCodeGenerator.js +1 -0
  18. package/lib/generators/core/vscode/templates/settings.json.ejs +3 -0
  19. package/lib/generators/core/yarn/CoreYarnGenerator.js +6 -3
  20. package/lib/generators/lib/PobLibGenerator.js +8 -6
  21. package/lib/generators/monorepo/PobMonorepoGenerator.js +9 -4
  22. package/lib/generators/monorepo/lerna/MonorepoLernaGenerator.js +1 -1
  23. package/lib/generators/monorepo/workspaces/MonorepoWorkspacesGenerator.js +19 -17
  24. package/lib/generators/pob/PobBaseGenerator.js +25 -11
  25. package/lib/pob.js +7 -0
  26. package/lib/utils/packageManagerUtils.js +20 -0
  27. package/lib/utils/packageManagerWorkspacesUtils.js +75 -0
  28. package/package.json +22 -21
  29. package/CHANGELOG.md +0 -5892
@@ -0,0 +1,103 @@
1
+ import sortObject from "@pob/sort-object";
2
+ import yml from "js-yaml";
3
+ import { lt } from "semver";
4
+ import Generator from "yeoman-generator";
5
+ import { writeAndFormat } from "../../../utils/writeAndFormat.js";
6
+
7
+ const minimumReleaseAgeExcludePackages = [
8
+ "@pob/*",
9
+ "pob-dependencies",
10
+ "alouette",
11
+ "alouette-icons",
12
+ "nightingale",
13
+ "nightingale-logger",
14
+ ];
15
+
16
+ export default class CorePnpmGenerator extends Generator {
17
+ constructor(args, opts) {
18
+ super(args, opts);
19
+
20
+ this.option("type", {
21
+ type: String,
22
+ required: false,
23
+ default: "lib",
24
+ description: "Project type (app or lib)",
25
+ });
26
+
27
+ this.option("enable", {
28
+ type: Boolean,
29
+ required: true,
30
+ description: "Enable pnpm",
31
+ });
32
+ }
33
+
34
+ async writing() {
35
+ const pkg = this.fs.readJSON(this.destinationPath("package.json"));
36
+
37
+ if (this.options.enable) {
38
+ if (
39
+ pkg.packageManager &&
40
+ (!pkg.packageManager.startsWith("pnpm@") ||
41
+ lt(pkg.packageManager.slice("pnpm@".length), "11.0.0"))
42
+ ) {
43
+ pkg.packageManager = "pnpm@11.0.0";
44
+ }
45
+
46
+ const configString = this.fs.read(
47
+ this.destinationPath("pnpm-workspace.yaml"),
48
+ { defaults: "" },
49
+ );
50
+ const config =
51
+ yml.load(configString, {
52
+ schema: yml.FAILSAFE_SCHEMA,
53
+ json: true,
54
+ }) || {};
55
+
56
+ if (pkg.workspaces) {
57
+ config.packages = pkg.workspaces;
58
+ } else {
59
+ delete config.packages;
60
+ }
61
+ config.savePrefix = this.options.type === "app" ? "" : "^";
62
+ config.minimumReleaseAge = 1440 * 3; // 3 days in minutes
63
+ config.minimumReleaseAgeExclude = minimumReleaseAgeExcludePackages;
64
+ config.dedupePeerDependents = true;
65
+
66
+ await writeAndFormat(
67
+ this.fs,
68
+ this.destinationPath("pnpm-workspace.yaml"),
69
+ yml.dump(sortObject(config), { lineWidth: 9999, noCompatMode: true }),
70
+ );
71
+ } else {
72
+ if (pkg.packageManager?.startsWith("pnpm@")) {
73
+ delete pkg.packageManager;
74
+ }
75
+ this.fs.delete("pnpm-lock.yaml");
76
+ this.fs.delete("pnpm-workspace.yaml");
77
+ }
78
+
79
+ this.fs.writeJSON(this.destinationPath("package.json"), pkg);
80
+ }
81
+
82
+ end() {
83
+ if (this.options.enable) {
84
+ this.spawnSync("pnpm", ["install"], {});
85
+ this.spawnSync("pnpm", ["dedupe"], {});
86
+
87
+ this.fs.delete("package-lock.json");
88
+ this.fs.delete("yarn.lock");
89
+
90
+ const pkg = this.fs.readJSON(this.destinationPath("package.json"));
91
+
92
+ if (pkg.scripts?.preversion) {
93
+ try {
94
+ this.spawnSync("pnpm", ["run", "preversion"]);
95
+ } catch {}
96
+ } else if (pkg.scripts?.build) {
97
+ try {
98
+ this.spawnSync("pnpm", ["run", "build"]);
99
+ } catch {}
100
+ }
101
+ }
102
+ }
103
+ }
@@ -87,6 +87,7 @@ export default class CoreVSCodeGenerator extends Generator {
87
87
  pnp: this.options.yarnNodeLinker === "pnp",
88
88
  npm: this.options.packageManager === "npm",
89
89
  bun: this.options.packageManager === "bun",
90
+ pnpm: this.options.packageManager === "pnpm",
90
91
  typescript: this.options.typescript,
91
92
  testing: this.options.testing,
92
93
  testRunner: this.options.testRunner,
@@ -27,6 +27,9 @@
27
27
  <% } else if (bun) { -%>
28
28
  // set bun as package manager to run scripts and tasks
29
29
  "npm.packageManager": "bun",
30
+ <% } else if (pnpm) { -%>
31
+ // set pnpm as package manager to run scripts and tasks
32
+ "npm.packageManager": "pnpm",
30
33
  <% } -%>
31
34
 
32
35
  // save config
@@ -91,7 +91,10 @@ export default class CoreYarnGenerator extends Generator {
91
91
  ["plugin", "runtime", "--json"],
92
92
  { stdio: "pipe" },
93
93
  );
94
- const installedPlugins = stdout.split("\n").map(JSON.parse);
94
+ const installedPlugins = stdout
95
+ .split("\n")
96
+ .filter(Boolean)
97
+ .map(JSON.parse);
95
98
 
96
99
  const isPluginInstalled = (name) =>
97
100
  installedPlugins.some((plugin) => plugin.name === name);
@@ -144,9 +147,9 @@ export default class CoreYarnGenerator extends Generator {
144
147
  if (
145
148
  !pkg.packageManager ||
146
149
  !pkg.packageManager.startsWith("yarn@") ||
147
- lt(pkg.packageManager.slice("yarn@".length), "4.14.1")
150
+ lt(pkg.packageManager.slice("yarn@".length), "4.15.0")
148
151
  ) {
149
- pkg.packageManager = "yarn@4.14.1";
152
+ pkg.packageManager = "yarn@4.15.0";
150
153
  }
151
154
 
152
155
  // must be done after plugins installed
@@ -23,7 +23,7 @@ export default class PobLibGenerator extends Generator {
23
23
 
24
24
  this.option("packageManager", {
25
25
  type: String,
26
- default: "yarn",
26
+ required: true,
27
27
  description: "yarn, bun or npm",
28
28
  });
29
29
 
@@ -252,12 +252,14 @@ export default class PobLibGenerator extends Generator {
252
252
  fromPob: this.options.fromPob,
253
253
  onlyLatestLTS: this.onlyLatestLTS,
254
254
  });
255
+
255
256
  this.composeWith("pob:common:transpiler", {
256
257
  updateOnly: this.options.updateOnly,
257
258
  testing: !!this.pobjson.testing,
258
259
  documentation: !!this.pobjson.documentation,
259
260
  fromPob: this.options.fromPob,
260
261
  onlyLatestLTS: this.onlyLatestLTS,
262
+ packageManager: this.options.packageManager,
261
263
  });
262
264
  }
263
265
 
@@ -270,14 +272,14 @@ export default class PobLibGenerator extends Generator {
270
272
  pkg.pob.envs) ||
271
273
  [];
272
274
 
273
- const packageManager =
274
- inMonorepo && !inMonorepo.root
275
- ? inMonorepo.rootPackageManager
276
- : this.options.packageManager;
275
+ const packageManager = this.options.packageManager;
277
276
 
278
277
  const withBabel = babelEnvs.length > 0;
279
278
  const withTypescript =
280
- withBabel || pkg.pob.typescript === true || pkg.pob.bundler === "tsc";
279
+ withBabel ||
280
+ pkg.pob.typescript === true ||
281
+ pkg.pob.bundler === "tsc" ||
282
+ pkg.pob.bundler === "rollup-esbuild";
281
283
  const jsx = (withBabel || withTypescript) && pkg.pob.jsx === true;
282
284
  const browser = pkg.pob.envs?.some((env) => env.target === "browser");
283
285
 
@@ -3,6 +3,8 @@ import fs from "node:fs";
3
3
  import { platform } from "node:process";
4
4
  import Generator from "yeoman-generator";
5
5
  import * as packageUtils from "../../utils/package.js";
6
+ import { packageManagerRun } from "../../utils/packageManagerUtils.js";
7
+ import { workspacesRun } from "../../utils/packageManagerWorkspacesUtils.js";
6
8
  import {
7
9
  buildDependenciesMaps,
8
10
  buildTopologicalOrderBatches,
@@ -87,7 +89,7 @@ export default class PobMonorepoGenerator extends Generator {
87
89
  this.option("packageManager", {
88
90
  type: String,
89
91
  default: "yarn",
90
- description: "yarn, bun or npm",
92
+ description: "yarn, npm, bun, or pnpm",
91
93
  });
92
94
 
93
95
  this.option("yarnNodeLinker", {
@@ -397,9 +399,12 @@ export default class PobMonorepoGenerator extends Generator {
397
399
  this.fs.delete("rollup.config.mjs");
398
400
  }
399
401
  packageUtils.addOrRemoveScripts(pkg, rollupConfigs.length > 0, {
400
- "clean:build": "yarn workspaces foreach --parallel -A run clean:build",
401
- build: "yarn clean:build && rollup --config rollup.config.mjs",
402
- watch: "yarn clean:build && rollup --config rollup.config.mjs --watch",
402
+ "clean:build": workspacesRun(
403
+ this.options.packageManager,
404
+ "clean:build",
405
+ ),
406
+ build: `${packageManagerRun(this.options.packageManager, "clean:build")} && rollup --config rollup.config.mjs`,
407
+ watch: `${packageManagerRun(this.options.packageManager, "clean:build")} && rollup --config rollup.config.mjs --watch`,
403
408
  });
404
409
  packageUtils.addOrRemoveDevDependencies(
405
410
  pkg,
@@ -16,7 +16,7 @@ export default class MonorepoLernaGenerator extends Generator {
16
16
  this.option("packageManager", {
17
17
  type: String,
18
18
  default: "yarn",
19
- description: "yarn or npm",
19
+ description: "yarn, npm, bun, or pnpm",
20
20
  });
21
21
 
22
22
  this.option("disableYarnGitCache", {
@@ -2,6 +2,10 @@ import { spawnSync } from "node:child_process";
2
2
  import { existsSync, readdirSync } from "node:fs";
3
3
  import Generator from "yeoman-generator";
4
4
  import * as packageUtils from "../../../utils/package.js";
5
+ import {
6
+ workspacesRunExcluding,
7
+ workspacesRunTopological,
8
+ } from "../../../utils/packageManagerWorkspacesUtils.js";
5
9
  import { copyAndFormatTpl } from "../../../utils/writeAndFormat.js";
6
10
 
7
11
  export default class MonorepoWorkspacesGenerator extends Generator {
@@ -17,7 +21,7 @@ export default class MonorepoWorkspacesGenerator extends Generator {
17
21
  this.option("packageManager", {
18
22
  type: String,
19
23
  default: "yarn",
20
- description: "yarn or npm",
24
+ description: "yarn, npm, bun, or pnpm",
21
25
  });
22
26
 
23
27
  this.option("disableYarnGitCache", {
@@ -77,6 +81,10 @@ export default class MonorepoWorkspacesGenerator extends Generator {
77
81
  if (!pkg.engines) pkg.engines = {};
78
82
  pkg.engines.yarn = "< 0.0.0";
79
83
  pkg.engines.npm = ">= 6.4.0";
84
+ } else if (this.options.packageManager === "pnpm") {
85
+ if (!pkg.engines) pkg.engines = {};
86
+ pkg.engines.pnpm = ">= 11.0.0";
87
+ delete pkg.engines.yarn;
80
88
  } else if (pkg.engines) {
81
89
  delete pkg.engines.yarn;
82
90
  }
@@ -91,18 +99,11 @@ export default class MonorepoWorkspacesGenerator extends Generator {
91
99
  "lint:eslint":
92
100
  monorepoConfig &&
93
101
  monorepoConfig.eslint &&
94
- this.packagesConfig.length < 50
95
- ? `${
96
- this.packagesConfig.length > 15
97
- ? "NODE_OPTIONS=--max_old_space_size=4096 "
98
- : ""
99
- }eslint --quiet .`
100
- : // eslint-disable-next-line unicorn/no-nested-ternary
101
- this.options.packageManager === "yarn"
102
- ? `NODE_OPTIONS=--max_old_space_size=4096 eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet . --ignore-pattern ${pkg.workspaces.join(
103
- ",",
104
- )} && yarn workspaces foreach --parallel -Av run lint:eslint`
105
- : "npm run lint:eslint --workspaces",
102
+ `${
103
+ this.packagesConfig.length > 15
104
+ ? "NODE_OPTIONS=--max_old_space_size=4096 "
105
+ : ""
106
+ }eslint --quiet .`,
106
107
  });
107
108
 
108
109
  if (
@@ -114,10 +115,8 @@ export default class MonorepoWorkspacesGenerator extends Generator {
114
115
 
115
116
  if (this.options.isAppProject) {
116
117
  packageUtils.addOrRemoveScripts(pkg, withBundler, {
117
- build:
118
- "yarn workspaces foreach --parallel --topological-dev -Av run build",
119
- watch:
120
- 'yarn workspaces foreach --parallel --jobs unlimited --interlaced --exclude "*-example" -Av run watch',
118
+ build: workspacesRunTopological(packageManager, "build"),
119
+ watch: workspacesRunExcluding(packageManager, "watch", "*-example"),
121
120
  });
122
121
  }
123
122
 
@@ -209,6 +208,9 @@ export default class MonorepoWorkspacesGenerator extends Generator {
209
208
  this.spawnCommandSync("npm", ["install"]);
210
209
  this.spawnCommandSync("npm", ["run", "preversion"]);
211
210
  break;
211
+ case "pnpm":
212
+ // see CorePnpmGenerator
213
+ break;
212
214
  case "yarn":
213
215
  // see CoreYarnGenerator
214
216
  break;
@@ -107,7 +107,7 @@ export default class PobBaseGenerator extends Generator {
107
107
  name: "packageManager",
108
108
  message: "Witch package manager do you want to use ?",
109
109
  type: "list",
110
- choices: ["yarn", "npm", "bun"],
110
+ choices: ["yarn", "npm", "bun", "pnpm"],
111
111
  default: config.packageManager || "yarn",
112
112
  },
113
113
  {
@@ -140,15 +140,28 @@ export default class PobBaseGenerator extends Generator {
140
140
  this.config.set("project", this.projectConfig);
141
141
  }
142
142
 
143
+ getPackageManager() {
144
+ return inMonorepo && !inMonorepo.root
145
+ ? inMonorepo.rootPackageManager
146
+ : (this.projectConfig?.packageManager ?? "yarn");
147
+ }
148
+
143
149
  default() {
150
+ const packageManager = this.getPackageManager();
151
+
144
152
  this.composeWith("pob:core:bun", {
145
153
  type: this.projectConfig.type,
146
- enable: this.isRoot && this.projectConfig.packageManager === "bun",
154
+ enable: this.isRoot && packageManager === "bun",
155
+ });
156
+
157
+ this.composeWith("pob:core:pnpm", {
158
+ type: this.projectConfig.type,
159
+ enable: this.isRoot && packageManager === "pnpm",
147
160
  });
148
161
 
149
162
  this.composeWith("pob:core:yarn", {
150
163
  type: this.projectConfig.type,
151
- enable: this.isRoot && this.projectConfig.packageManager === "yarn",
164
+ enable: this.isRoot && packageManager === "yarn",
152
165
  yarnNodeLinker: this.projectConfig.yarnNodeLinker,
153
166
  disableYarnGitCache: this.projectConfig.disableYarnGitCache !== false,
154
167
  });
@@ -160,20 +173,20 @@ export default class PobBaseGenerator extends Generator {
160
173
  inMonorepo: !!inMonorepo,
161
174
  isRoot: this.isRoot,
162
175
  packageType: this.projectConfig.type === "app" ? "module" : undefined,
163
- packageManager: this.projectConfig.packageManager,
176
+ packageManager,
164
177
  });
165
178
 
166
179
  if (this.isMonorepo) {
167
180
  this.composeWith("pob:monorepo:workspaces", {
168
181
  force: this.options.force,
169
182
  isAppProject: this.projectConfig.type === "app",
170
- packageManager: this.projectConfig.packageManager,
183
+ packageManager,
171
184
  disableYarnGitCache: this.projectConfig.disableYarnGitCache !== false,
172
185
  });
173
186
  this.composeWith("pob:monorepo:lerna", {
174
187
  force: this.options.force,
175
188
  isAppProject: this.projectConfig.type === "app",
176
- packageManager: this.projectConfig.packageManager,
189
+ packageManager,
177
190
  disableYarnGitCache: this.projectConfig.disableYarnGitCache !== false,
178
191
  });
179
192
  }
@@ -236,7 +249,7 @@ export default class PobBaseGenerator extends Generator {
236
249
  updateOnly: this.options.updateOnly,
237
250
  disableYarnGitCache: this.projectConfig.disableYarnGitCache !== false,
238
251
  isAppProject: this.projectConfig.type === "app",
239
- packageManager: this.projectConfig.packageManager,
252
+ packageManager,
240
253
  yarnNodeLinker: this.projectConfig.yarnNodeLinker,
241
254
  onlyLatestLTS,
242
255
  },
@@ -251,7 +264,7 @@ export default class PobBaseGenerator extends Generator {
251
264
  this.projectConfig.disableYarnGitCache !== false,
252
265
  updateOnly: this.options.updateOnly,
253
266
  fromPob: this.options.fromPob,
254
- packageManager: this.projectConfig.packageManager,
267
+ packageManager,
255
268
  yarnNodeLinker: this.projectConfig.yarnNodeLinker,
256
269
  ci: this.projectConfig.ci,
257
270
  });
@@ -264,7 +277,7 @@ export default class PobBaseGenerator extends Generator {
264
277
  this.projectConfig.disableYarnGitCache !== false,
265
278
  updateOnly: this.options.updateOnly,
266
279
  fromPob: this.options.fromPob,
267
- packageManager: this.projectConfig.packageManager,
280
+ packageManager,
268
281
  yarnNodeLinker: this.projectConfig.yarnNodeLinker,
269
282
  ci: this.projectConfig.ci,
270
283
  });
@@ -278,13 +291,14 @@ export default class PobBaseGenerator extends Generator {
278
291
  install() {
279
292
  if (this.options.fromPob) return;
280
293
 
281
- switch (this.projectConfig.packageManager) {
294
+ switch (this.getPackageManager()) {
282
295
  case "npm":
283
296
  this.spawnCommandSync("npm", ["install"]);
284
297
  break;
298
+ case "pnpm":
285
299
  case "yarn":
286
300
  default:
287
- // see CoreYarnGenerator
301
+ // see CorePnpmGenerator / CoreYarnGenerator
288
302
  break;
289
303
  }
290
304
  }
package/lib/pob.js CHANGED
@@ -31,6 +31,7 @@ import CoreGitGithubGenerator from "./generators/core/git/generators/github/Core
31
31
  import CoreGitignoreGenerator from "./generators/core/gitignore/CoreGitignoreGenerator.js";
32
32
  import CoreNpmGenerator from "./generators/core/npm/CoreNpmGenerator.js";
33
33
  import CorePackageGenerator from "./generators/core/package/CorePackageGenerator.js";
34
+ import CorePnpmGenerator from "./generators/core/pnpm/CorePnpmGenerator.js";
34
35
  import CoreRenovateGenerator from "./generators/core/renovate/CoreRenovateGenerator.js";
35
36
  import CoreSortPackageGenerator from "./generators/core/sort-package/CoreSortPackageGenerator.js";
36
37
  import CoreVSCodeGenerator from "./generators/core/vscode/CoreVSCodeGenerator.js";
@@ -205,6 +206,11 @@ env.registerStub(
205
206
  "pob:core:bun",
206
207
  `${__dirname}/generators/core/bun/CoreBunGenerator.js`,
207
208
  );
209
+ env.registerStub(
210
+ CorePnpmGenerator,
211
+ "pob:core:pnpm",
212
+ `${__dirname}/generators/core/pnpm/CorePnpmGenerator.js`,
213
+ );
208
214
  env.registerStub(
209
215
  PobLibGenerator,
210
216
  "pob:lib",
@@ -299,6 +305,7 @@ if (action === "migrate-to-monorepo") {
299
305
  ".yarnrc.yml",
300
306
  "eslint.config.js",
301
307
  "bun.lock",
308
+ "pnpm-lock.yaml",
302
309
  ".prettierignore",
303
310
  "renovate.json",
304
311
  "packages",
@@ -9,6 +9,24 @@ export const packageManagerRun = (packageManager, script) => {
9
9
  return `npm run ${script}`;
10
10
  case "bun":
11
11
  return `bun run ${script}`;
12
+ case "pnpm":
13
+ return `pnpm run ${script}`;
14
+ default:
15
+ throw new Error(`Unsupported package manager: ${packageManager}`);
16
+ }
17
+ };
18
+
19
+ export const packageManagerExec = (packageManager, command) => {
20
+ switch (packageManager) {
21
+ case undefined:
22
+ case "yarn":
23
+ return `yarn ${command}`;
24
+ case "npm":
25
+ return `npx ${command}`;
26
+ case "bun":
27
+ return `bun run ${command}`;
28
+ case "pnpm":
29
+ return `pnpm exec ${command}`;
12
30
  default:
13
31
  throw new Error(`Unsupported package manager: ${packageManager}`);
14
32
  }
@@ -23,6 +41,8 @@ export const packageManagerRunWithCwd = (packageManager, cwd, script) => {
23
41
  return `npm --prefix ${quoteArg(cwd)} run ${script}`;
24
42
  case "bun":
25
43
  return `bun run --cwd ${quoteArg(cwd)} ${script}`;
44
+ case "pnpm":
45
+ return `pnpm run --dir ${quoteArg(cwd)} ${script}`;
26
46
  default:
27
47
  throw new Error(`Unsupported package manager: ${packageManager}`);
28
48
  }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Run a script in all workspaces in parallel.
3
+ * Use for independent operations like lint, test, clean.
4
+ */
5
+ export const workspacesRun = (packageManager, script) => {
6
+ switch (packageManager) {
7
+ case undefined:
8
+ case "yarn":
9
+ return `yarn workspaces foreach --parallel -Av run ${script}`;
10
+ case "pnpm":
11
+ return `pnpm -r --parallel run ${script}`;
12
+ case "npm":
13
+ return `npm run ${script} --workspaces`;
14
+ case "bun":
15
+ return `bun --filter '*' run ${script}`;
16
+ default:
17
+ throw new Error(`Unsupported package manager: ${packageManager}`);
18
+ }
19
+ };
20
+
21
+ /**
22
+ * Run a script in all workspaces in topological dependency order.
23
+ * Use for build where packages may depend on each other.
24
+ */
25
+ export const workspacesRunTopological = (packageManager, script) => {
26
+ switch (packageManager) {
27
+ case undefined:
28
+ case "yarn":
29
+ return `yarn workspaces foreach --parallel --topological-dev -Av run ${script}`;
30
+ case "pnpm":
31
+ return `pnpm -r run ${script}`; // pnpm respects topological order by default (without --parallel)
32
+ case "npm":
33
+ return `npm run ${script} --workspaces`;
34
+ case "bun":
35
+ return `bun --filter '*' run ${script}`;
36
+ default:
37
+ throw new Error(`Unsupported package manager: ${packageManager}`);
38
+ }
39
+ };
40
+
41
+ /**
42
+ * Run a script in all workspaces in parallel, excluding packages matching the given patterns.
43
+ * Use for watch commands where example/demo packages should be skipped.
44
+ */
45
+ export const workspacesRunExcluding = (
46
+ packageManager,
47
+ script,
48
+ ...excludePatterns
49
+ ) => {
50
+ switch (packageManager) {
51
+ case undefined:
52
+ case "yarn": {
53
+ const excludeArgs = excludePatterns
54
+ .map((p) => `--exclude "${p}"`)
55
+ .join(" ");
56
+ return `yarn workspaces foreach --parallel --jobs unlimited --interlaced ${excludeArgs} -Av run ${script}`;
57
+ }
58
+ case "pnpm": {
59
+ const filterArgs = excludePatterns
60
+ .map((p) => `--filter "!${p}"`)
61
+ .join(" ");
62
+ return `pnpm -r --parallel ${filterArgs} run ${script}`;
63
+ }
64
+ case "npm":
65
+ return `npm run ${script} --workspaces`;
66
+ case "bun": {
67
+ const filterArgs = excludePatterns
68
+ .map((p) => `--filter '!${p}'`)
69
+ .join(" ");
70
+ return `bun ${filterArgs} run ${script}`;
71
+ }
72
+ default:
73
+ throw new Error(`Unsupported package manager: ${packageManager}`);
74
+ }
75
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "35.0.0",
3
+ "version": "35.2.0",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/jest",
5
5
  "keywords": [
6
6
  "skeleton"
@@ -16,7 +16,6 @@
16
16
  "url": "https://github.com/christophehurpeau/pob.git",
17
17
  "directory": "packages/pob"
18
18
  },
19
- "bin": "./lib/pob.js",
20
19
  "files": [
21
20
  "lib",
22
21
  "bin"
@@ -28,21 +27,12 @@
28
27
  ".": "./lib/index.js",
29
28
  "./package.json": "./package.json"
30
29
  },
31
- "scripts": {
32
- "build": "yarn run build:definitions",
33
- "build:definitions": "tsc -p tsconfig.json",
34
- "format": "prettier --write",
35
- "lint": "yarn run lint:eslint",
36
- "lint:eslint": "yarn '../..' run eslint --quiet 'packages/pob'"
37
- },
38
30
  "dependencies": {
39
31
  "@pob/eslint-config": "65.4.3",
40
32
  "@pob/eslint-config-typescript-react": "65.4.3",
41
- "@pob/sort-object": "11.0.0",
42
- "@pob/sort-pkg": "13.0.0",
43
33
  "@types/inquirer": "9.0.9",
44
- "@yeoman/adapter": "3.1.0",
45
- "@yeoman/types": "1.8.0",
34
+ "@yeoman/adapter": "4.0.2",
35
+ "@yeoman/types": "1.11.1",
46
36
  "eslint": "10.4.0",
47
37
  "findup-sync": "^5.0.0",
48
38
  "git-remote-url": "^1.0.1",
@@ -52,25 +42,36 @@
52
42
  "lodash.camelcase": "^4.3.0",
53
43
  "lodash.kebabcase": "^4.1.1",
54
44
  "mem-fs": "4.1.4",
55
- "mem-fs-editor": "11.1.4",
45
+ "mem-fs-editor": "12.0.4",
56
46
  "minimist": "1.2.8",
57
- "oxfmt": "0.50.0",
47
+ "oxfmt": "0.51.0",
58
48
  "parse-author": "2.0.0",
59
- "pob-dependencies": "24.0.0",
60
49
  "semver": "7.8.0",
61
50
  "typescript": "6.0.3",
62
- "validate-npm-package-name": "^7.0.0",
63
- "yeoman-environment": "5.0.0",
64
- "yeoman-generator": "7.5.1"
51
+ "validate-npm-package-name": "^8.0.0",
52
+ "yeoman-environment": "6.1.0",
53
+ "yeoman-generator": "8.2.2",
54
+ "pob-dependencies": "24.1.0",
55
+ "@pob/sort-pkg": "13.1.0",
56
+ "@pob/sort-object": "11.1.0"
65
57
  },
66
58
  "devDependencies": {
67
- "@pob/root": "24.0.0",
68
- "@types/node": "24.12.4"
59
+ "@types/node": "24.12.4",
60
+ "@pob/root": "24.2.0"
69
61
  },
70
62
  "engines": {
71
63
  "node": ">=22.18.0"
72
64
  },
73
65
  "pob": {
74
66
  "typescript": "check-only"
67
+ },
68
+ "scripts": {
69
+ "build": "pnpm run build:definitions",
70
+ "build:definitions": "tsc -p tsconfig.json",
71
+ "lint": "pnpm run lint:eslint",
72
+ "lint:eslint": "pnpm run --dir '../..' eslint --quiet 'packages/pob'"
73
+ },
74
+ "bin": {
75
+ "pob": "./lib/pob.js"
75
76
  }
76
77
  }