pob 35.6.0 → 36.0.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/README.md +2 -21
- package/lib/generators/app/ignorePaths.js +1 -1
- package/lib/generators/common/babel/CommonBabelGenerator.js +7 -12
- package/lib/generators/common/format-lint/CommonLintGenerator.js +6 -0
- package/lib/generators/common/release/templates/workflow-release.yml.ejs +1 -1
- package/lib/generators/common/testing/CommonTestingGenerator.js +26 -19
- package/lib/generators/common/transpiler/CommonTranspilerGenerator.js +0 -1
- package/lib/generators/core/ci/templates/github-action-documentation-workflow.yml.ejs +1 -1
- package/lib/generators/core/ci/templates/github-action-push-workflow-split.yml.ejs +6 -6
- package/lib/generators/core/ci/templates/github-action-push-workflow.yml.ejs +1 -1
- package/lib/generators/core/claude/CoreClaudeGenerator.js +73 -0
- package/lib/generators/core/package/CorePackageGenerator.js +20 -63
- package/lib/generators/core/pnpm/CorePnpmGenerator.js +7 -6
- package/lib/generators/core/vscode/CoreVSCodeGenerator.js +1 -1
- package/lib/generators/core/vscode/templates/settings.json.ejs +0 -6
- package/lib/generators/core/yarn/CoreYarnGenerator.js +7 -7
- package/lib/generators/monorepo/PobMonorepoGenerator.js +8 -14
- package/lib/generators/monorepo/typescript/MonorepoTypescriptGenerator.js +36 -0
- package/lib/generators/monorepo/typescript/templates/tsconfig.json.ejs +3 -0
- package/lib/generators/monorepo/typescript/templates/tsconfig.root-configs.json.ejs +13 -0
- package/lib/generators/monorepo/workspaces/MonorepoWorkspacesGenerator.js +4 -1
- package/lib/generators/pob/PobBaseGenerator.js +4 -0
- package/lib/pob.js +6 -0
- package/lib/utils/package.js +0 -26
- package/package.json +11 -11
- package/lib/generators/common/testing/templates/babel.config.cjs.ejs +0 -26
- package/lib/generators/core/package/templates/check-package.js.ejs +0 -3
- package/lib/generators/core/package/templates/check-packages.js.ejs +0 -7
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
Pile of bones, library generator with git/babel/typescript/typedoc/readme/
|
|
6
|
+
Pile of bones, library generator with git/babel/typescript/typedoc/readme/vitest
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -28,30 +28,11 @@ You can now use `yarn run watch` !
|
|
|
28
28
|
|
|
29
29
|
### How this works
|
|
30
30
|
|
|
31
|
-
#### Babel
|
|
32
|
-
|
|
33
|
-
Write code in the `src` directory, it's then transpiled with babel and rollup to `dist`.
|
|
34
|
-
Use the task `yarn run build` or `yarn run watch` to transpile the code.
|
|
35
|
-
|
|
36
|
-
There are several environments: `node`, `browser`.
|
|
37
|
-
For each of these environments, there is also a `dev` version that add flow runtime checks.
|
|
38
|
-
|
|
39
31
|
#### Coding Rules
|
|
40
32
|
|
|
41
33
|
Eslint is used to ensure a common coding style. I mostly follow the [Airbnb coding style](https://github.com/airbnb/javascript/blob/master/README.md).
|
|
42
34
|
You can check the code by running the task `yarn run lint`. With an editor, install the plugins to validate the code as you type !
|
|
43
35
|
|
|
44
|
-
#### Documentation
|
|
45
|
-
|
|
46
|
-
[typedoc](https://typedoc.org/) allows to document the code and generate the api.
|
|
47
|
-
[jest](https://www.npmjs.com/package/jest) is used to generate the coverage.
|
|
48
|
-
|
|
49
|
-
Documentation can be generated by github actions and pushed to github-pages.
|
|
50
|
-
|
|
51
|
-
#### Tests
|
|
52
|
-
|
|
53
|
-
Tests are in the directory `src` with jest. Use the task `yarn test` to run the tests with jest.
|
|
54
|
-
|
|
55
36
|
### Available tasks with `yarn run`
|
|
56
37
|
|
|
57
38
|
#### Code, Transpile, Lint
|
|
@@ -59,7 +40,7 @@ Tests are in the directory `src` with jest. Use the task `yarn test` to run the
|
|
|
59
40
|
- `build`: `clean` the directory, build `src` to `dist` with rollup
|
|
60
41
|
- `watch`: `clean` then build and watch with rollup
|
|
61
42
|
- `lint`: execute `eslint`
|
|
62
|
-
- `test`: run tests
|
|
43
|
+
- `test`: run tests
|
|
63
44
|
|
|
64
45
|
### Generate documentation
|
|
65
46
|
|
|
@@ -20,10 +20,10 @@ export const appIgnorePaths = {
|
|
|
20
20
|
storybook: (config) => ["/.storybook/storybook.requires.ts"],
|
|
21
21
|
expo: (config) => [
|
|
22
22
|
"/.expo/",
|
|
23
|
-
"/src/tamagui-web.css",
|
|
24
23
|
"/android/",
|
|
25
24
|
"/ios/",
|
|
26
25
|
"/dist/",
|
|
26
|
+
"/dist-native/",
|
|
27
27
|
"*.jks",
|
|
28
28
|
"*.p8",
|
|
29
29
|
"*.p12",
|
|
@@ -304,6 +304,12 @@ export default class CommonBabelGenerator extends Generator {
|
|
|
304
304
|
(env) => env.target === "browser",
|
|
305
305
|
);
|
|
306
306
|
|
|
307
|
+
if (useBabel) {
|
|
308
|
+
throw new Error(
|
|
309
|
+
"pob-babel is deprecated. Use @pob/rollup-esbuild or @pob/rollup-typescript instead.",
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
307
313
|
/* dependencies */
|
|
308
314
|
|
|
309
315
|
if (
|
|
@@ -324,11 +330,6 @@ export default class CommonBabelGenerator extends Generator {
|
|
|
324
330
|
if (pkg.dependencies && pkg.dependencies["pob-babel"]) {
|
|
325
331
|
throw new Error("pob-babel is deprecated.");
|
|
326
332
|
}
|
|
327
|
-
if (pkg.dependencies && pkg.dependencies["@babel/runtime"]) {
|
|
328
|
-
// update pob-babel in alp-dev
|
|
329
|
-
packageUtils.addDependencies(pkg, ["@babel/runtime"], "^");
|
|
330
|
-
}
|
|
331
|
-
|
|
332
333
|
const isLibraryRollupPlugin = pkg.name.includes("rollup-plugin");
|
|
333
334
|
|
|
334
335
|
packageUtils.addOrRemoveDevDependencies(
|
|
@@ -440,13 +441,7 @@ export default class CommonBabelGenerator extends Generator {
|
|
|
440
441
|
this.fs.delete(".babelrc");
|
|
441
442
|
this.fs.delete("babel.config.json");
|
|
442
443
|
this.fs.delete("babel.config.mjs");
|
|
443
|
-
|
|
444
|
-
this.fs.move(
|
|
445
|
-
this.destinationPath("babel.config.js"),
|
|
446
|
-
this.destinationPath("babel.config.cjs"),
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
|
|
444
|
+
this.fs.delete("babel.config.js");
|
|
450
445
|
this.fs.writeJSON(this.destinationPath("package.json"), pkg);
|
|
451
446
|
}
|
|
452
447
|
}
|
|
@@ -409,6 +409,12 @@ export default class CommonFormatLintGenerator extends Generator {
|
|
|
409
409
|
};
|
|
410
410
|
})();
|
|
411
411
|
|
|
412
|
+
const isMonorepoRoot =
|
|
413
|
+
this.options.monorepo || Boolean(inMonorepo && inMonorepo.root);
|
|
414
|
+
if (isMonorepoRoot && useTypescript) {
|
|
415
|
+
flatCascade.push("...pobConfig(import.meta.url).configs.monorepo");
|
|
416
|
+
}
|
|
417
|
+
|
|
412
418
|
const eslintrcBadPath = this.destinationPath(".eslintrc");
|
|
413
419
|
this.fs.delete(eslintrcBadPath);
|
|
414
420
|
this.fs.delete(`${eslintrcBadPath}.yml`);
|
|
@@ -30,7 +30,7 @@ export default class CommonTestingGenerator extends Generator {
|
|
|
30
30
|
this.option("runner", {
|
|
31
31
|
type: String,
|
|
32
32
|
default: "node",
|
|
33
|
-
description: "test runner (
|
|
33
|
+
description: "test runner (vitest or node)",
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
this.option("ci", {
|
|
@@ -157,14 +157,14 @@ export default class CommonTestingGenerator extends Generator {
|
|
|
157
157
|
(inMonorepo && inMonorepo.pobMonorepoConfig) || {};
|
|
158
158
|
const globalTesting = yoConfigPobMonorepo && yoConfigPobMonorepo.testing;
|
|
159
159
|
const enableForMonorepo = this.options.monorepo && globalTesting;
|
|
160
|
-
const transpileWithEsbuild =
|
|
160
|
+
const transpileWithEsbuild = false;
|
|
161
161
|
const transpileWithBabel = transpileWithEsbuild
|
|
162
162
|
? false
|
|
163
163
|
: // eslint-disable-next-line unicorn/no-nested-ternary
|
|
164
164
|
this.options.monorepo
|
|
165
165
|
? yoConfigPobMonorepo.typescript &&
|
|
166
166
|
yoConfigPobMonorepo.typescript !== "check-only"
|
|
167
|
-
:
|
|
167
|
+
: false;
|
|
168
168
|
const withTypescript =
|
|
169
169
|
transpileWithBabel ||
|
|
170
170
|
pkg.pob?.bundler === "tsc" ||
|
|
@@ -259,21 +259,28 @@ export default class CommonTestingGenerator extends Generator {
|
|
|
259
259
|
}
|
|
260
260
|
const experimentalTestCoverage =
|
|
261
261
|
pkg.name === "check-package-dependencies";
|
|
262
|
-
return
|
|
263
|
-
|
|
264
|
-
?
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
262
|
+
return [
|
|
263
|
+
experimentalTestCoverage && coverage === "generate"
|
|
264
|
+
? "mkdir -p docs && "
|
|
265
|
+
: "",
|
|
266
|
+
`TZ=UTC ${
|
|
267
|
+
coverage && !experimentalTestCoverage
|
|
268
|
+
? `npx c8${
|
|
269
|
+
coverage === "generate"
|
|
270
|
+
? ` --reporter=${coverage === "generate" ? "json" : "lcov"}`
|
|
271
|
+
: ""
|
|
272
|
+
} --all --src ./${this.options.srcDirectory} `
|
|
273
|
+
: ""
|
|
274
|
+
}node ${
|
|
275
|
+
this.options.typescript
|
|
276
|
+
? `${tsTestLoaderOption ? `${tsTestLoaderOption} ` : ""}`
|
|
277
|
+
: ""
|
|
278
|
+
}${this.fs.exists("src/test-setup.ts") ? "--import ./src/test-setup.ts " : ""}--test${experimentalTestCoverage && coverage ? ` --experimental-test-coverage${coverage === "generate" ? " --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=docs/coverage.lcov" : ""} --test-coverage-include="${this.options.srcDirectory}/**/*.ts"` : ""} '${this.options.monorepo ? `${workspacesPattern}/*/` : ""}${`${
|
|
279
|
+
hasTestFolder
|
|
280
|
+
? "test/*"
|
|
281
|
+
: `${this.options.srcDirectory}/**/*.test`
|
|
282
|
+
}.${this.options.typescript ? "ts" : "js"}`}'`,
|
|
283
|
+
].join("");
|
|
277
284
|
}
|
|
278
285
|
case "bun": {
|
|
279
286
|
if (this.options.packageManager !== "bun") {
|
|
@@ -389,7 +396,7 @@ export default class CommonTestingGenerator extends Generator {
|
|
|
389
396
|
}),
|
|
390
397
|
"test:coverage:generate": createTestCommand({
|
|
391
398
|
workspacesPattern,
|
|
392
|
-
|
|
399
|
+
coverage: "generate",
|
|
393
400
|
}),
|
|
394
401
|
});
|
|
395
402
|
} else {
|
|
@@ -160,7 +160,6 @@ export default class CommonTranspilerGenerator extends Generator {
|
|
|
160
160
|
const cleanCommand = (() => {
|
|
161
161
|
if (bundler === "rollup-typescript") return "pob-typescript-clean-out";
|
|
162
162
|
if (bundler === "rollup-esbuild") return "pob-esbuild-clean-out";
|
|
163
|
-
if (bundler === "rollup-babel") return "pob-babel-clean-out";
|
|
164
163
|
if (bundler === "esbuild") return "pob-esbuild-clean-out";
|
|
165
164
|
if (bundler === "tsc") return "rm -Rf";
|
|
166
165
|
if (bundler) throw new Error(`Invalid bundler: ${bundler}`);
|
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
version: 11
|
|
29
29
|
|
|
30
30
|
<% } -%>
|
|
31
|
-
- uses: actions/setup-node@
|
|
31
|
+
- uses: actions/setup-node@v7
|
|
32
32
|
with:
|
|
33
33
|
node-version: <%= nodeLatestMajorVersion %>
|
|
34
34
|
|
|
@@ -73,7 +73,7 @@ jobs:
|
|
|
73
73
|
version: 11
|
|
74
74
|
|
|
75
75
|
<% } -%>
|
|
76
|
-
- uses: actions/setup-node@
|
|
76
|
+
- uses: actions/setup-node@v7
|
|
77
77
|
with:
|
|
78
78
|
node-version: <%= nodeLatestMajorVersion %>
|
|
79
79
|
|
|
@@ -120,7 +120,7 @@ jobs:
|
|
|
120
120
|
version: 11
|
|
121
121
|
|
|
122
122
|
<% } -%>
|
|
123
|
-
- uses: actions/setup-node@
|
|
123
|
+
- uses: actions/setup-node@v7
|
|
124
124
|
with:
|
|
125
125
|
node-version: <%= nodeLatestMajorVersion %>
|
|
126
126
|
|
|
@@ -178,7 +178,7 @@ jobs:
|
|
|
178
178
|
version: 11
|
|
179
179
|
|
|
180
180
|
<% } -%>
|
|
181
|
-
- uses: actions/setup-node@
|
|
181
|
+
- uses: actions/setup-node@v7
|
|
182
182
|
with:
|
|
183
183
|
node-version: ${{ matrix.node-version }}
|
|
184
184
|
|
|
@@ -249,7 +249,7 @@ jobs:
|
|
|
249
249
|
version: 11
|
|
250
250
|
|
|
251
251
|
<% } -%>
|
|
252
|
-
- uses: actions/setup-node@
|
|
252
|
+
- uses: actions/setup-node@v7
|
|
253
253
|
with:
|
|
254
254
|
node-version: ${{ matrix.node-version }}
|
|
255
255
|
|
|
@@ -280,7 +280,7 @@ jobs:
|
|
|
280
280
|
steps:
|
|
281
281
|
- uses: actions/checkout@v7
|
|
282
282
|
|
|
283
|
-
- uses: actions/setup-node@
|
|
283
|
+
- uses: actions/setup-node@v7
|
|
284
284
|
with:
|
|
285
285
|
node-version: <%= nodeLatestMajorVersion %>
|
|
286
286
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Generator from "yeoman-generator";
|
|
2
|
+
import { writeAndFormatJson } from "../../../utils/writeAndFormat.js";
|
|
3
|
+
|
|
4
|
+
export default class CoreClaudeGenerator extends Generator {
|
|
5
|
+
constructor(args, opts) {
|
|
6
|
+
super(args, opts);
|
|
7
|
+
|
|
8
|
+
this.option("root", {
|
|
9
|
+
type: Boolean,
|
|
10
|
+
required: false,
|
|
11
|
+
default: true,
|
|
12
|
+
description: "Root package.",
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async writing() {
|
|
17
|
+
const pkg = this.fs.readJSON(this.destinationPath("package.json"), {});
|
|
18
|
+
const claudeGitignorePath = this.destinationPath(".claude/.gitignore");
|
|
19
|
+
const claudeSettingsPath = this.destinationPath(".claude/settings.json");
|
|
20
|
+
|
|
21
|
+
if (!this.options.root) {
|
|
22
|
+
this.fs.delete(claudeGitignorePath);
|
|
23
|
+
this.fs.delete(claudeSettingsPath);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.fs.write(
|
|
28
|
+
claudeGitignorePath,
|
|
29
|
+
"/settings.local.json\n/skills/local.*\n",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const command =
|
|
33
|
+
pkg.name === "pob-monorepo"
|
|
34
|
+
? "node ./@pob/root/bin/pob-claude-run-lint-staged.js"
|
|
35
|
+
: "./node_modules/.bin/pob-claude-run-lint-staged";
|
|
36
|
+
|
|
37
|
+
const claudePostToolUseHook = {
|
|
38
|
+
matcher: "Edit|Write|MultiEdit",
|
|
39
|
+
hooks: [{ type: "command", command }],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const existing = this.fs.readJSON(claudeSettingsPath, {
|
|
43
|
+
hooks: {
|
|
44
|
+
PostToolUse: [claudePostToolUseHook],
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Find or create the PostToolUse hook entry for our matcher
|
|
49
|
+
const postToolUse = existing.hooks?.PostToolUse ?? [];
|
|
50
|
+
|
|
51
|
+
const existingEntry = postToolUse.find(
|
|
52
|
+
(entry) => entry.matcher === claudePostToolUseHook.matcher,
|
|
53
|
+
);
|
|
54
|
+
if (existingEntry) {
|
|
55
|
+
// Add any of our hooks not already present
|
|
56
|
+
for (const hook of claudePostToolUseHook.hooks) {
|
|
57
|
+
if (!existingEntry.hooks?.some((h) => h.command === hook.command)) {
|
|
58
|
+
(existingEntry.hooks ??= []).push(hook);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
postToolUse.push(claudePostToolUseHook);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await writeAndFormatJson(this.fs, claudeSettingsPath, {
|
|
66
|
+
...existing,
|
|
67
|
+
hooks: {
|
|
68
|
+
...existing.hooks,
|
|
69
|
+
PostToolUse: postToolUse,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -221,28 +221,29 @@ export default class CorePackageGenerator extends Generator {
|
|
|
221
221
|
fs.unlinkSync(this.destinationPath("yarn-error.log"));
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
if (
|
|
225
|
-
packageUtils.removeScripts(pkg, ["checks"]);
|
|
224
|
+
if (pkg.name !== "@pob/root") {
|
|
226
225
|
packageUtils.removeDevDependencies(pkg, ["check-package-dependencies"]);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
226
|
+
}
|
|
227
|
+
if (this.fs.exists(this.destinationPath("scripts/check-packages.mjs"))) {
|
|
228
|
+
this.fs.delete(this.destinationPath("scripts/check-packages.mjs"));
|
|
229
|
+
}
|
|
230
|
+
if (this.fs.exists(this.destinationPath("scripts/check-packages.js"))) {
|
|
231
|
+
this.fs.delete(this.destinationPath("scripts/check-packages.js"));
|
|
232
|
+
}
|
|
234
233
|
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
if (this.options.inMonorepo && !this.options.isRoot) {
|
|
235
|
+
packageUtils.removeScripts(pkg, ["checks"]);
|
|
236
|
+
} else if (this.options.isRoot) {
|
|
237
|
+
const checksScript = pkg.scripts?.checks;
|
|
238
|
+
if (checksScript && checksScript.includes("node scripts/check-package")) {
|
|
239
|
+
pkg.scripts.checks = checksScript.replace(
|
|
240
|
+
/( && )?node scripts\/check-package\.(mjs|js)( && )?/,
|
|
241
|
+
"",
|
|
242
|
+
);
|
|
243
|
+
if (pkg.scripts.checks === "") {
|
|
244
|
+
delete pkg.scripts.checks;
|
|
245
|
+
}
|
|
237
246
|
}
|
|
238
|
-
|
|
239
|
-
packageUtils.addOrRemoveScripts(
|
|
240
|
-
pkg,
|
|
241
|
-
doesMjsCheckPackagesExists || doesJsCheckPackagesExists,
|
|
242
|
-
{
|
|
243
|
-
checks: `node scripts/check-packages.${doesMjsCheckPackagesExists ? "mjs" : "js"}`,
|
|
244
|
-
},
|
|
245
|
-
);
|
|
246
247
|
} else if (inMonorepo && !inMonorepo.root) {
|
|
247
248
|
if (this.fs.exists("scripts/check-package.js")) {
|
|
248
249
|
this.fs.delete("scripts/check-package.js");
|
|
@@ -251,50 +252,6 @@ export default class CorePackageGenerator extends Generator {
|
|
|
251
252
|
this.fs.delete("scripts/check-package.mjs");
|
|
252
253
|
}
|
|
253
254
|
packageUtils.removeScripts(pkg, ["checks"]);
|
|
254
|
-
} else {
|
|
255
|
-
const doesMjsCheckPackageExists = this.fs.exists(
|
|
256
|
-
this.destinationPath("scripts/check-package.mjs"),
|
|
257
|
-
);
|
|
258
|
-
let doesJsCheckPackageExists = this.fs.exists(
|
|
259
|
-
this.destinationPath("scripts/check-package.js"),
|
|
260
|
-
);
|
|
261
|
-
const doesTsCheckPackageExists = this.fs.exists(
|
|
262
|
-
this.destinationPath("scripts/check-package.ts"),
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
if (pkg.type === "module") {
|
|
266
|
-
if (!doesJsCheckPackageExists && !doesTsCheckPackageExists) {
|
|
267
|
-
doesJsCheckPackageExists = true;
|
|
268
|
-
this.fs.copyTpl(
|
|
269
|
-
this.templatePath("check-package.js.ejs"),
|
|
270
|
-
this.destinationPath("scripts/check-package.ts"),
|
|
271
|
-
{
|
|
272
|
-
isLibrary: pkg.private !== true,
|
|
273
|
-
},
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
if (
|
|
278
|
-
doesJsCheckPackageExists ||
|
|
279
|
-
doesMjsCheckPackageExists ||
|
|
280
|
-
doesTsCheckPackageExists
|
|
281
|
-
) {
|
|
282
|
-
packageUtils.addDevDependencies(pkg, ["check-package-dependencies"]);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
packageUtils.addOrRemoveScripts(
|
|
286
|
-
pkg,
|
|
287
|
-
doesMjsCheckPackageExists ||
|
|
288
|
-
doesJsCheckPackageExists ||
|
|
289
|
-
doesTsCheckPackageExists,
|
|
290
|
-
{
|
|
291
|
-
checks: `node scripts/check-package.${(() => {
|
|
292
|
-
if (doesMjsCheckPackageExists) return "mjs";
|
|
293
|
-
if (doesTsCheckPackageExists) return "ts";
|
|
294
|
-
return "js";
|
|
295
|
-
})()}`,
|
|
296
|
-
},
|
|
297
|
-
);
|
|
298
255
|
}
|
|
299
256
|
|
|
300
257
|
if (!pkg.authors) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sortObject from "@pob/sort-object";
|
|
2
|
-
import
|
|
2
|
+
import { FAILSAFE_SCHEMA, dump, loadAll } from "js-yaml";
|
|
3
3
|
import { lt } from "semver";
|
|
4
4
|
import Generator from "yeoman-generator";
|
|
5
5
|
import { writeAndFormat } from "../../../utils/writeAndFormat.js";
|
|
@@ -47,10 +47,10 @@ export default class CorePnpmGenerator extends Generator {
|
|
|
47
47
|
this.destinationPath("pnpm-workspace.yaml"),
|
|
48
48
|
{ defaults: "" },
|
|
49
49
|
);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const [loadedConfig] = loadAll(configString, {
|
|
51
|
+
schema: FAILSAFE_SCHEMA,
|
|
52
|
+
});
|
|
53
|
+
const config = loadedConfig ?? {};
|
|
54
54
|
|
|
55
55
|
if (config.allowBuilds) {
|
|
56
56
|
config.allowBuilds = Object.fromEntries(
|
|
@@ -70,11 +70,12 @@ export default class CorePnpmGenerator extends Generator {
|
|
|
70
70
|
config.minimumReleaseAge = 1440 * 3; // 3 days in minutes
|
|
71
71
|
config.minimumReleaseAgeExclude = minimumReleaseAgeExcludePackages;
|
|
72
72
|
config.dedupePeerDependents = true;
|
|
73
|
+
config.nodeLinker = "hoisted";
|
|
73
74
|
|
|
74
75
|
await writeAndFormat(
|
|
75
76
|
this.fs,
|
|
76
77
|
this.destinationPath("pnpm-workspace.yaml"),
|
|
77
|
-
|
|
78
|
+
dump(sortObject(config), { lineWidth: 9999 }),
|
|
78
79
|
);
|
|
79
80
|
} else {
|
|
80
81
|
if (pkg.packageManager?.startsWith("pnpm@")) {
|
|
@@ -37,7 +37,7 @@ export default class CoreVSCodeGenerator extends Generator {
|
|
|
37
37
|
this.option("testRunner", {
|
|
38
38
|
type: String,
|
|
39
39
|
required: false,
|
|
40
|
-
description: "Test runner (
|
|
40
|
+
description: "Test runner (node, vitest, ...)",
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
this.option("yarnNodeLinker", {
|
|
@@ -40,12 +40,6 @@
|
|
|
40
40
|
"source.organizeImports": "never"
|
|
41
41
|
},
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
<% if (testing && module && (!testRunner || testRunner === 'jest')) { -%>
|
|
45
|
-
// jest
|
|
46
|
-
"jest.jestCommandLine": "NODE_OPTIONS=--experimental-vm-modules node_modules/.bin/jest",
|
|
47
|
-
<% } -%>
|
|
48
|
-
|
|
49
43
|
// extension eslint config
|
|
50
44
|
"eslint.workingDirectories": ["."],
|
|
51
45
|
"eslint.useFlatConfig": true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { isDeepStrictEqual } from "node:util";
|
|
3
3
|
import sortObject from "@pob/sort-object";
|
|
4
|
-
import
|
|
4
|
+
import { FAILSAFE_SCHEMA, dump, loadAll } from "js-yaml";
|
|
5
5
|
import { lt } from "semver";
|
|
6
6
|
import Generator from "yeoman-generator";
|
|
7
7
|
import { ensureJsonFileFormatted } from "../../../utils/ensureJsonFileFormatted.js";
|
|
@@ -154,11 +154,11 @@ export default class CoreYarnGenerator extends Generator {
|
|
|
154
154
|
|
|
155
155
|
// must be done after plugins installed
|
|
156
156
|
const configString = this.fs.read(".yarnrc.yml", { defaults: "" });
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
const [loadedConfig] = loadAll(configString, {
|
|
158
|
+
schema: FAILSAFE_SCHEMA,
|
|
159
|
+
json: true,
|
|
160
|
+
});
|
|
161
|
+
const config = loadedConfig ?? {};
|
|
162
162
|
if (config.enableScripts === "true") {
|
|
163
163
|
config.enableScripts = true;
|
|
164
164
|
}
|
|
@@ -204,7 +204,7 @@ export default class CoreYarnGenerator extends Generator {
|
|
|
204
204
|
await writeAndFormat(
|
|
205
205
|
this.fs,
|
|
206
206
|
".yarnrc.yml",
|
|
207
|
-
|
|
207
|
+
dump(sortObject(config), {
|
|
208
208
|
lineWidth: 9999,
|
|
209
209
|
}),
|
|
210
210
|
);
|
|
@@ -61,11 +61,7 @@ const hasData = (packages, configs) =>
|
|
|
61
61
|
const hasTamagui = (packages, configs) =>
|
|
62
62
|
packages.some(
|
|
63
63
|
(pkg) =>
|
|
64
|
-
!!(
|
|
65
|
-
pkg.dependencies?.tamagui ||
|
|
66
|
-
pkg.dependencies?.["@tamagui/core"] ||
|
|
67
|
-
pkg.dependencies?.alouette
|
|
68
|
-
),
|
|
64
|
+
!!(pkg.dependencies?.tamagui || pkg.dependencies?.["@tamagui/core"]),
|
|
69
65
|
);
|
|
70
66
|
|
|
71
67
|
export default class PobMonorepoGenerator extends Generator {
|
|
@@ -269,9 +265,13 @@ export default class PobMonorepoGenerator extends Generator {
|
|
|
269
265
|
`${this.pobLernaConfig.e2eTesting === "." || this.pobLernaConfig.e2eTesting === true ? "" : `/${this.pobLernaConfig.e2eTesting}`}/test-results/`,
|
|
270
266
|
].filter(Boolean);
|
|
271
267
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
if (hasTamagui(this.packages, this.packageConfigs)) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
"Tamagui is no longer supported. Please migrate to native-wind.",
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const gitignorePaths = [].filter(Boolean);
|
|
275
275
|
|
|
276
276
|
this.composeWith("pob:common:format-lint", {
|
|
277
277
|
monorepo: true,
|
|
@@ -406,12 +406,6 @@ export default class PobMonorepoGenerator extends Generator {
|
|
|
406
406
|
build: `${packageManagerRun(this.options.packageManager, "clean:build")} && rollup --config rollup.config.mjs`,
|
|
407
407
|
watch: `${packageManagerRun(this.options.packageManager, "clean:build")} && rollup --config rollup.config.mjs --watch`,
|
|
408
408
|
});
|
|
409
|
-
packageUtils.addOrRemoveDevDependencies(
|
|
410
|
-
pkg,
|
|
411
|
-
rollupConfigs.length > 0 &&
|
|
412
|
-
(rollupKinds.size === 0 || rollupKinds.has("babel")),
|
|
413
|
-
["@babel/core", "pob-babel"],
|
|
414
|
-
);
|
|
415
409
|
|
|
416
410
|
packageUtils.addOrRemoveDevDependencies(pkg, rollupKinds.has("esbuild"), [
|
|
417
411
|
"@pob/rollup-esbuild",
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
1
2
|
import Generator from "yeoman-generator";
|
|
3
|
+
import { latestLTS } from "../../../utils/nodeVersions.js";
|
|
2
4
|
import * as packageUtils from "../../../utils/package.js";
|
|
3
5
|
import { packageManagerRun } from "../../../utils/packageManagerUtils.js";
|
|
4
6
|
import { copyAndFormatTpl } from "../../../utils/writeAndFormat.js";
|
|
5
7
|
|
|
8
|
+
const rootConfigExtensionsRegex = /\.config\.(?:ts|mts|cts)$/;
|
|
9
|
+
|
|
10
|
+
const hasRootConfigFiles = (rootPath) => {
|
|
11
|
+
try {
|
|
12
|
+
return readdirSync(rootPath).some((name) =>
|
|
13
|
+
rootConfigExtensionsRegex.test(name),
|
|
14
|
+
);
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
6
20
|
export default class MonorepoTypescriptGenerator extends Generator {
|
|
7
21
|
constructor(args, opts) {
|
|
8
22
|
super(args, opts);
|
|
@@ -121,15 +135,36 @@ export default class MonorepoTypescriptGenerator extends Generator {
|
|
|
121
135
|
const tsconfigCheckPath = this.destinationPath("tsconfig.check.json");
|
|
122
136
|
const tsconfigBuildPath = this.destinationPath("tsconfig.build.json");
|
|
123
137
|
const tsconfigTestPath = this.destinationPath("tsconfig.test.json");
|
|
138
|
+
const tsconfigRootConfigsPath = this.destinationPath(
|
|
139
|
+
"tsconfig.root-configs.json",
|
|
140
|
+
);
|
|
124
141
|
this.fs.delete(tsconfigTestPath);
|
|
125
142
|
|
|
126
143
|
if (!this.options.enable) {
|
|
127
144
|
this.fs.delete(tsconfigPath);
|
|
128
145
|
this.fs.delete(tsconfigCheckPath);
|
|
129
146
|
this.fs.delete(tsconfigBuildPath);
|
|
147
|
+
this.fs.delete(tsconfigRootConfigsPath);
|
|
130
148
|
} else {
|
|
131
149
|
const packagePaths = JSON.parse(this.options.packagePaths);
|
|
132
150
|
|
|
151
|
+
// root config files written in typescript (e.g. vitest.config.ts) are not
|
|
152
|
+
// part of any package tsconfig, so they need a dedicated project for
|
|
153
|
+
// type-aware linting and tsc -b
|
|
154
|
+
const hasRootConfigs = hasRootConfigFiles(this.destinationPath());
|
|
155
|
+
if (hasRootConfigs) {
|
|
156
|
+
await copyAndFormatTpl(
|
|
157
|
+
this.fs,
|
|
158
|
+
this.templatePath("tsconfig.root-configs.json.ejs"),
|
|
159
|
+
tsconfigRootConfigsPath,
|
|
160
|
+
{
|
|
161
|
+
nodeVersion: latestLTS,
|
|
162
|
+
},
|
|
163
|
+
);
|
|
164
|
+
} else {
|
|
165
|
+
this.fs.delete(tsconfigRootConfigsPath);
|
|
166
|
+
}
|
|
167
|
+
|
|
133
168
|
await copyAndFormatTpl(
|
|
134
169
|
this.fs,
|
|
135
170
|
this.templatePath("tsconfig.json.ejs"),
|
|
@@ -137,6 +172,7 @@ export default class MonorepoTypescriptGenerator extends Generator {
|
|
|
137
172
|
{
|
|
138
173
|
packagePaths,
|
|
139
174
|
tsConfigSuffix: false,
|
|
175
|
+
hasRootConfigs,
|
|
140
176
|
},
|
|
141
177
|
);
|
|
142
178
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": [],
|
|
3
3
|
"references": [
|
|
4
|
+
<% if (hasRootConfigs) { -%>
|
|
5
|
+
{ "path": "tsconfig.root-configs.json" }<%= packagePaths.length > 0 ? ',' : '' %>
|
|
6
|
+
<% } -%>
|
|
4
7
|
<% packagePaths.forEach((packagePath, index) => { -%>
|
|
5
8
|
{ "path": "<%= packagePath %>/tsconfig<%= tsConfigSuffix ? `.${tsConfigSuffix}` : '' %>.json" }<%= index === packagePaths.length -1 ? '' : ',' %>
|
|
6
9
|
<% }) -%>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"@pob/root/tsconfigs/strict.json",
|
|
4
|
+
"@pob/root/tsconfigs/targets/node-<%= nodeVersion %>.json"
|
|
5
|
+
],
|
|
6
|
+
"include": ["*.config.ts", "*.config.mts", "*.config.cts"],
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"tsBuildInfoFile": "node_modules/.cache/tsc/tsbuildinfo-root-configs",
|
|
10
|
+
"incremental": true,
|
|
11
|
+
"resolveJsonModule": true
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -63,12 +63,15 @@ export default class MonorepoWorkspacesGenerator extends Generator {
|
|
|
63
63
|
writing() {
|
|
64
64
|
const getPackagePobConfig = (config) => ({
|
|
65
65
|
babelEnvs: [],
|
|
66
|
+
envs: [],
|
|
66
67
|
...(config && config.pob),
|
|
67
68
|
});
|
|
68
69
|
const withBundler = this.packages.some((config) => {
|
|
69
70
|
const pobConfig = getPackagePobConfig(config);
|
|
70
71
|
return (
|
|
71
|
-
pobConfig.
|
|
72
|
+
pobConfig.envs.length > 0 ||
|
|
73
|
+
pobConfig.babelEnvs.length > 0 ||
|
|
74
|
+
pobConfig.bundler === "rollup-babel"
|
|
72
75
|
);
|
|
73
76
|
});
|
|
74
77
|
|
|
@@ -199,6 +199,10 @@ export default class PobBaseGenerator extends Generator {
|
|
|
199
199
|
|
|
200
200
|
this.composeWith("pob:core:editorconfig");
|
|
201
201
|
|
|
202
|
+
this.composeWith("pob:core:claude", {
|
|
203
|
+
root: this.isRoot,
|
|
204
|
+
});
|
|
205
|
+
|
|
202
206
|
this.composeWith("pob:core:clean", {
|
|
203
207
|
root: this.isRoot,
|
|
204
208
|
});
|
package/lib/pob.js
CHANGED
|
@@ -24,6 +24,7 @@ import CommonTranspilerGenerator from "./generators/common/transpiler/CommonTran
|
|
|
24
24
|
import CommonTypescriptGenerator from "./generators/common/typescript/CommonTypescriptGenerator.js";
|
|
25
25
|
import CoreBunGenerator from "./generators/core/bun/CoreBunGenerator.js";
|
|
26
26
|
import CoreCIGenerator from "./generators/core/ci/CoreCIGenerator.js";
|
|
27
|
+
import CoreClaudeGenerator from "./generators/core/claude/CoreClaudeGenerator.js";
|
|
27
28
|
import CoreCleanGenerator from "./generators/core/clean/CoreCleanGenerator.js";
|
|
28
29
|
import CoreEditorConfigGenerator from "./generators/core/editorconfig/CoreEditorConfigGenerator.js";
|
|
29
30
|
import CoreGitGenerator from "./generators/core/git/CoreGitGenerator.js";
|
|
@@ -156,6 +157,11 @@ env.registerStub(
|
|
|
156
157
|
"pob:core:editorconfig",
|
|
157
158
|
`${__dirname}/generators/core/editorconfig/CoreEditorConfigGenerator.js`,
|
|
158
159
|
);
|
|
160
|
+
env.registerStub(
|
|
161
|
+
CoreClaudeGenerator,
|
|
162
|
+
"pob:core:claude",
|
|
163
|
+
`${__dirname}/generators/core/claude/CoreClaudeGenerator.js`,
|
|
164
|
+
);
|
|
159
165
|
env.registerStub(
|
|
160
166
|
CoreGitGenerator,
|
|
161
167
|
"pob:core:git",
|
package/lib/utils/package.js
CHANGED
|
@@ -16,32 +16,6 @@ export { default as parseAuthor } from "parse-author";
|
|
|
16
16
|
export const parsePkgAuthor = (pkg) =>
|
|
17
17
|
typeof pkg.author === "string" ? parseAuthor(pkg.author) : pkg.author;
|
|
18
18
|
|
|
19
|
-
export const hasLerna = (pkg) =>
|
|
20
|
-
!!(pkg.devDependencies && pkg.devDependencies.lerna);
|
|
21
|
-
|
|
22
|
-
export const hasBabel = (pkg) =>
|
|
23
|
-
!!(
|
|
24
|
-
pkg.devDependencies &&
|
|
25
|
-
(pkg.devDependencies["pob-babel"] || pkg.devDependencies["@babel/core"])
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
export const transpileWithEsbuild = (pkg) =>
|
|
29
|
-
!!(pkg.devDependencies && pkg.devDependencies["jest-esbuild"]);
|
|
30
|
-
|
|
31
|
-
export const transpileWithBabel = (pkg) =>
|
|
32
|
-
!!(
|
|
33
|
-
(pkg.devDependencies &&
|
|
34
|
-
(pkg.devDependencies["pob-babel"] ||
|
|
35
|
-
pkg.devDependencies.next ||
|
|
36
|
-
pkg.devDependencies["@yarnpkg/builder"] ||
|
|
37
|
-
pkg.devDependencies["alp-dev"])) ||
|
|
38
|
-
// alp-dev has pob-babel in dependencies
|
|
39
|
-
(pkg.dependencies &&
|
|
40
|
-
(pkg.dependencies["pob-babel"] ||
|
|
41
|
-
pkg.dependencies.next ||
|
|
42
|
-
pkg.dependencies["alp-dev"]))
|
|
43
|
-
);
|
|
44
|
-
|
|
45
19
|
export const hasReact = (pkg) =>
|
|
46
20
|
!!(
|
|
47
21
|
(pkg.dependencies && pkg.dependencies.react) ||
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pob",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/
|
|
3
|
+
"version": "36.0.0",
|
|
4
|
+
"description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/vitest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"skeleton"
|
|
7
7
|
],
|
|
@@ -28,20 +28,17 @@
|
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pob/eslint-config": "65.6.0",
|
|
32
|
-
"@pob/eslint-config-typescript-react": "65.6.0",
|
|
33
31
|
"@types/inquirer": "9.0.10",
|
|
34
32
|
"@yeoman/adapter": "4.0.2",
|
|
35
|
-
"
|
|
36
|
-
"eslint": "10.4.0",
|
|
33
|
+
"eslint": "10.7.0",
|
|
37
34
|
"findup-sync": "^5.0.0",
|
|
38
35
|
"git-remote-url": "^1.0.1",
|
|
39
36
|
"github-username": "^9.0.0",
|
|
40
|
-
"js-yaml": "^
|
|
37
|
+
"js-yaml": "^5.2.1",
|
|
41
38
|
"json5": "^2.2.3",
|
|
42
39
|
"lodash.camelcase": "^4.3.0",
|
|
43
40
|
"lodash.kebabcase": "^4.1.1",
|
|
44
|
-
"mem-fs": "4.1.
|
|
41
|
+
"mem-fs": "4.1.5",
|
|
45
42
|
"mem-fs-editor": "12.0.4",
|
|
46
43
|
"minimist": "1.2.8",
|
|
47
44
|
"oxfmt": "0.54.0",
|
|
@@ -51,13 +48,16 @@
|
|
|
51
48
|
"validate-npm-package-name": "^8.0.0",
|
|
52
49
|
"yeoman-environment": "6.1.0",
|
|
53
50
|
"yeoman-generator": "8.2.2",
|
|
51
|
+
"@pob/eslint-config": "65.7.0",
|
|
54
52
|
"@pob/sort-object": "11.1.1",
|
|
55
|
-
"@pob/sort-pkg": "13.1.
|
|
56
|
-
"pob-dependencies": "
|
|
53
|
+
"@pob/sort-pkg": "13.1.2",
|
|
54
|
+
"pob-dependencies": "25.0.0",
|
|
55
|
+
"@pob/eslint-config-typescript-react": "65.7.0"
|
|
57
56
|
},
|
|
58
57
|
"devDependencies": {
|
|
59
58
|
"@types/node": "24.13.3",
|
|
60
|
-
"@
|
|
59
|
+
"@yeoman/types": "1.11.1",
|
|
60
|
+
"@pob/root": "25.0.0"
|
|
61
61
|
},
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=22.18.0"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = function babelConfig(api) {
|
|
4
|
-
const isTest = api.env('test');
|
|
5
|
-
|
|
6
|
-
if (!isTest) return {};
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
only: [<%- only %>],
|
|
10
|
-
presets: [
|
|
11
|
-
['pob-babel/preset.js', { modules: <%- jestExperimentalESM ? 'false' : "'commonjs'" %> }]
|
|
12
|
-
<% if (hasReact) { %>, [
|
|
13
|
-
'@babel/preset-react',
|
|
14
|
-
{
|
|
15
|
-
runtime: 'automatic',
|
|
16
|
-
development: false,
|
|
17
|
-
useBuiltIns: true,
|
|
18
|
-
useSpread: true,
|
|
19
|
-
},
|
|
20
|
-
]<% } %>
|
|
21
|
-
<% if (hasLinaria) { %>, [
|
|
22
|
-
'@linaria/babel-preset'
|
|
23
|
-
]<% } %>
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
};
|