pob 22.5.0 → 23.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/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [23.0.0](https://github.com/christophehurpeau/pob/compare/pob@22.5.0...pob@23.0.0) (2024-08-11)
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * update to eslint flat config
11
+
12
+ ### Features
13
+
14
+ * update to eslint flat config ([9e9b530](https://github.com/christophehurpeau/pob/commit/9e9b530e1c89ad4f0fafa1af8f4a13816544f16c))
15
+
16
+ Version bump for dependency: @pob/sort-eslint-config
17
+ Version bump for dependency: @pob/sort-object
18
+ Version bump for dependency: @pob/sort-pkg
19
+ Version bump for dependency: yarn-workspace-utils
20
+ Version bump for dependency: @pob/root
21
+
22
+
6
23
  ## [22.5.0](https://github.com/christophehurpeau/pob/compare/pob@22.4.1...pob@22.5.0) (2024-08-11)
7
24
 
8
25
  Version bump for dependency: @pob/root
@@ -1,12 +1,8 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
2
  import Generator from "yeoman-generator";
4
- import ensureJsonFileFormatted from "../../../utils/ensureJsonFileFormatted.js";
5
3
  import inMonorepo from "../../../utils/inMonorepo.js";
6
4
  import * as packageUtils from "../../../utils/package.js";
7
- import { writeAndFormatJson } from "../../../utils/writeAndFormat.js";
8
5
  import { appIgnorePaths } from "../../app/ignorePaths.js";
9
- import updateEslintConfig from "./updateEslintConfig.js";
10
6
 
11
7
  export default class CommonLintGenerator extends Generator {
12
8
  constructor(args, opts) {
@@ -59,6 +55,12 @@ export default class CommonLintGenerator extends Generator {
59
55
  description: "Typescript enabled",
60
56
  });
61
57
 
58
+ this.option("build", {
59
+ type: Boolean,
60
+ required: false,
61
+ description: "Build",
62
+ });
63
+
62
64
  this.option("enableSrcResolver", {
63
65
  type: Boolean,
64
66
  required: false,
@@ -132,7 +134,7 @@ export default class CommonLintGenerator extends Generator {
132
134
  this.options.babel !== "undefined"
133
135
  ? this.options.babel === "true"
134
136
  : babelEnvs.length > 0;
135
- const useTypescript = useBabel || pkg.pob?.typescript;
137
+ const useTypescript = this.options.typescript;
136
138
  const hasReact = useTypescript && packageUtils.hasReact(pkg);
137
139
  const useNode = !useBabel || babelEnvs.some((env) => env.target === "node");
138
140
  const useNodeOnly =
@@ -243,7 +245,6 @@ export default class CommonLintGenerator extends Generator {
243
245
  const globalEslint =
244
246
  this.options.monorepo ||
245
247
  (yoConfigPobMonorepo && yoConfigPobMonorepo.eslint !== false);
246
- const globalTesting = yoConfigPobMonorepo && yoConfigPobMonorepo.testing;
247
248
  const composite = yoConfigPobMonorepo && yoConfigPobMonorepo.typescript;
248
249
  const { rootPackageManager, rootYarnNodeLinker } = inMonorepo || {};
249
250
  const lernaProjectType =
@@ -259,7 +260,10 @@ export default class CommonLintGenerator extends Generator {
259
260
  globalEslint &&
260
261
  !((inMonorepo && inMonorepo.root) || this.options.monorepo)
261
262
  ) {
262
- if (!pkg.name.startsWith("@pob/eslint-config")) {
263
+ if (
264
+ !pkg.name.startsWith("@pob/eslint-config") &&
265
+ !pkg.name.startsWith("@pob/eslint-plugin")
266
+ ) {
263
267
  packageUtils.removeDevDependencies(
264
268
  pkg,
265
269
  [
@@ -348,113 +352,71 @@ export default class CommonLintGenerator extends Generator {
348
352
  }
349
353
  }
350
354
 
351
- const isPobEslintConfig =
352
- pkg.name === "eslint-config-pob" ||
353
- pkg.name.startsWith("@pob/eslint-config") ||
354
- pkg.name === "@pob/use-eslint-plugin";
355
-
356
- const extendsConfigRoot = (() => {
357
- if (isPobEslintConfig) {
358
- if (pkg.name === "@pob/eslint-config-monorepo") {
359
- return [
360
- pkg.type === "commonjs"
361
- ? "./@pob/eslint-config/lib/root-commonjs.js"
362
- : "./@pob/eslint-config/lib/root-module.js",
363
- ];
364
- }
365
- return [
366
- pkg.type === "commonjs"
367
- ? "../eslint-config/lib/root-commonjs.js"
368
- : "../eslint-config/lib/root-module.js",
369
- ];
355
+ const { imports, flatCascade } = (() => {
356
+ if (pkg.name === "@pob/eslint-config-monorepo") {
357
+ return {
358
+ imports: [
359
+ 'import pobTypescriptConfig from "@pob/eslint-config-typescript"',
360
+ 'import pobTypescriptConfigReact from "@pob/eslint-config-typescript-react"',
361
+ ],
362
+ flatCascade: [
363
+ // TODO
364
+ ],
365
+ };
370
366
  }
371
367
 
372
- return [
373
- pkg.type === "commonjs"
374
- ? "@pob/eslint-config/root-commonjs"
375
- : "@pob/eslint-config/root-module",
376
- ];
377
- })();
378
-
379
- const extendsConfigSrc = (() => {
380
- if (isPobEslintConfig) {
381
- return [
382
- pkg.type === "commonjs"
383
- ? "../../eslint-config/lib/node-commonjs"
384
- : "../../eslint-config/lib/node-module",
385
- ];
386
- }
368
+ return {
369
+ imports: [
370
+ useTypescript
371
+ ? 'import pobTypescriptConfig from "@pob/eslint-config-typescript"'
372
+ : 'import pobConfig from "@pob/eslint-config"',
373
+ useTypescript &&
374
+ hasReact &&
375
+ 'import pobTypescriptConfigReact from "@pob/eslint-config-typescript-react"',
376
+ ].filter(Boolean),
377
+ flatCascade: (() => {
378
+ // TODO do something with useNodeOnly ?
379
+ console.log({ useNodeOnly });
380
+
381
+ if (!useTypescript) {
382
+ return [
383
+ useNode
384
+ ? "...pobConfig(import.meta.url).configs.nodeModule"
385
+ : "...pobConfig(import.meta.url).configs.baseModule",
386
+ ];
387
+ }
388
+ if (!hasReact) {
389
+ return [
390
+ useNode
391
+ ? "...pobTypescriptConfig(import.meta.url).configs.node"
392
+ : "...pobTypescriptConfig(import.meta.url).configs.base",
393
+ ];
394
+ }
387
395
 
388
- if (useTypescript) {
389
- return [
390
- "@pob/eslint-config-typescript",
391
- useNodeOnly && "@pob/eslint-config-typescript/node",
392
- // useTypescript &&
393
- // pkg.pob?.rollup === false &&
394
- // '@pob/eslint-config-typescript/tsc-emit',
395
- this.options.isApp && "@pob/eslint-config-typescript/app",
396
- hasReact &&
397
- `@pob/eslint-config-typescript-react${
396
+ return [
397
+ useNode
398
+ ? "...pobTypescriptConfig(import.meta.url).configs.node"
399
+ : "...pobTypescriptConfig(import.meta.url).configs.base",
400
+ `...pobTypescriptReactConfig(import.meta.url).configs.${
398
401
  pkg.dependencies?.["react-native-web"] ? "/react-native-web" : ""
399
402
  }`,
400
- ].filter(Boolean);
401
- }
402
-
403
- return [
404
- pkg.type === "commonjs"
405
- ? "@pob/eslint-config/node-commonjs"
406
- : "@pob/eslint-config/node-module",
407
- ];
403
+ this.options.isApp &&
404
+ "...pobTypescriptConfig(import.meta.url).configs.app",
405
+ ];
406
+ })().filter(Boolean),
407
+ };
408
408
  })();
409
409
 
410
- const ext = !useTypescript
411
- ? `{${pkg.type === "commonjs" ? "mjs" : "cjs"},js}`
412
- : `${hasReact ? "{ts,tsx}" : "ts"}`;
413
-
414
- const testRunner = globalTesting
415
- ? inMonorepo.pobConfig.monorepo.testRunner
416
- : this.options.testRunner;
417
- const testsOverride =
418
- this.options.testing || globalTesting
419
- ? {
420
- files: [
421
- `**/*.test.${ext}`,
422
- `__tests__/**/*.${ext}`,
423
- `**/__mocks__/**/*.${ext}`,
424
- ],
425
- ...(testRunner == null || testRunner === "jest"
426
- ? { env: { jest: true } }
427
- : {}),
428
- rules: {
429
- "import/no-extraneous-dependencies": [
430
- "error",
431
- { devDependencies: true },
432
- ],
433
- },
434
- }
435
- : null;
436
-
437
- if (testsOverride) {
438
- // if (!useBabel) {
439
- // testsOverride.extends = ['pob/babel'];
440
- // }
441
-
442
- if (useTypescript) {
443
- testsOverride.extends = ["@pob/eslint-config-typescript/test"];
444
- delete testsOverride.rules["import/no-extraneous-dependencies"];
445
- }
446
- }
447
-
448
410
  const eslintrcBadPath = this.destinationPath(".eslintrc");
449
411
  this.fs.delete(eslintrcBadPath);
450
412
  this.fs.delete(`${eslintrcBadPath}.yml`);
451
413
  this.fs.delete(`${eslintrcBadPath}.js`);
452
414
 
453
- const rootEslintrcPath = this.options.rootAsSrc
415
+ const rootLegacyEslintrcPath = this.options.rootAsSrc
454
416
  ? false
455
417
  : this.destinationPath(".eslintrc.json");
456
418
 
457
- const srcEslintrcPath = this.options.rootAsSrc
419
+ const srcLegacyEslintrcPath = this.options.rootAsSrc
458
420
  ? this.destinationPath(".eslintrc.json")
459
421
  : this.destinationPath(
460
422
  `${
@@ -462,96 +424,68 @@ export default class CommonLintGenerator extends Generator {
462
424
  }.eslintrc.json`,
463
425
  );
464
426
 
465
- const getRootIgnorePatterns = () => {
466
- const ignorePatterns = new Set();
427
+ if (rootLegacyEslintrcPath) this.fs.delete(rootLegacyEslintrcPath);
428
+ this.fs.delete(srcLegacyEslintrcPath);
467
429
 
468
- if (inMonorepo && !inMonorepo.root && (useTypescript || pkg.types)) {
469
- ignorePatterns.add("*.d.ts");
470
- }
430
+ const eslintConfigPath = this.destinationPath("eslint.config.js");
471
431
 
472
- if (inMonorepo && inMonorepo.root && this.options.documentation) {
473
- ignorePatterns.add("/docs");
474
- }
432
+ if (!inMonorepo || inMonorepo.root) {
433
+ const getRootIgnorePatterns = () => {
434
+ const ignorePatterns = new Set();
475
435
 
476
- if ((!inMonorepo || !inMonorepo.root) && useTypescript) {
477
- const buildPath = `/${this.options.buildDirectory}`;
478
- if (
479
- !this.options.rootIgnorePaths ||
480
- !this.options.rootIgnorePaths.includes(buildPath)
481
- ) {
482
- ignorePatterns.add(buildPath);
436
+ if (useTypescript) {
437
+ ignorePatterns.add("*.d.ts");
483
438
  }
484
- }
485
- if (inMonorepo && inMonorepo.root && this.options.typescript) {
486
- ignorePatterns.add("/rollup.config.mjs");
487
- }
488
439
 
489
- if (this.options.rootIgnorePaths) {
490
- this.options.rootIgnorePaths
491
- .split("\n")
492
- .filter(Boolean)
493
- .forEach((ignorePath) => {
494
- if (ignorePath.startsWith("#")) return;
495
- ignorePatterns.add(ignorePath);
496
- });
497
- }
440
+ if (inMonorepo && inMonorepo.root && this.options.documentation) {
441
+ ignorePatterns.add("/docs");
442
+ }
498
443
 
499
- return ignorePatterns;
500
- };
444
+ if ((!inMonorepo || !inMonorepo.root) && useTypescript) {
445
+ const buildPath = `/${this.options.buildDirectory}`;
446
+ if (
447
+ !this.options.rootIgnorePaths ||
448
+ !this.options.rootIgnorePaths.includes(buildPath)
449
+ ) {
450
+ ignorePatterns.add(buildPath);
451
+ }
452
+ }
453
+ if (inMonorepo && inMonorepo.root && this.options.build) {
454
+ ignorePatterns.add("/rollup.config.mjs");
455
+ }
501
456
 
502
- if (rootEslintrcPath) {
503
- try {
504
- if (this.fs.exists(rootEslintrcPath)) {
505
- ensureJsonFileFormatted(rootEslintrcPath);
457
+ if (this.options.rootIgnorePaths) {
458
+ this.options.rootIgnorePaths
459
+ .split("\n")
460
+ .filter(Boolean)
461
+ .forEach((ignorePath) => {
462
+ if (ignorePath.startsWith("#")) return;
463
+ ignorePatterns.add(ignorePath);
464
+ });
506
465
  }
507
466
 
508
- const rootIgnorePatterns = getRootIgnorePatterns();
467
+ return ignorePatterns;
468
+ };
469
+
470
+ const ignorePatterns = getRootIgnorePatterns();
471
+ const srcDirectory =
472
+ useBabel || this.options.typescript ? this.options.srcDirectory : "lib";
509
473
 
510
- const rootEslintrcConfig = updateEslintConfig(
511
- this.fs.readJSON(rootEslintrcPath, {}),
474
+ if (this.fs.exists(eslintConfigPath)) {
475
+ // TODO update config !
476
+ } else {
477
+ this.fs.copyTpl(
478
+ this.templatePath("eslint.config.js.ejs"),
479
+ eslintConfigPath,
512
480
  {
513
- extendsConfig: extendsConfigRoot,
514
- ignorePatterns:
515
- rootIgnorePatterns.size === 0
516
- ? undefined
517
- : [...rootIgnorePatterns],
481
+ imports,
482
+ flatCascade,
483
+ srcDirectory,
484
+ ignorePatterns: [...ignorePatterns],
518
485
  },
519
486
  );
520
-
521
- writeAndFormatJson(this.fs, rootEslintrcPath, rootEslintrcConfig);
522
- } catch (error) {
523
- console.warn(`Could not parse/edit ${rootEslintrcPath}: `, error);
524
- }
525
- }
526
- // no else: dont delete root eslintrc, src is root
527
-
528
- if ((inMonorepo && inMonorepo.root) || this.options.monorepo) {
529
- if (this.fs.exists(srcEslintrcPath)) {
530
- this.fs.delete(srcEslintrcPath);
531
- }
532
- } else {
533
- try {
534
- if (this.fs.exists(srcEslintrcPath)) {
535
- ensureJsonFileFormatted(srcEslintrcPath);
536
- }
537
-
538
- const ignorePatterns = this.options.rootAsSrc
539
- ? getRootIgnorePatterns()
540
- : new Set();
541
- if (useTypescript || pkg.types) {
542
- ignorePatterns.add("*.d.ts");
543
- }
544
-
545
- const srcEslintrcConfig = updateEslintConfig(
546
- this.fs.readJSON(srcEslintrcPath, {}),
547
- {
548
- extendsConfig: extendsConfigSrc,
549
- testsOverride,
550
- useTypescript,
551
- globalEslint,
552
- ignorePatterns:
553
- ignorePatterns.size === 0 ? undefined : [...ignorePatterns],
554
- settings: {
487
+ // TODO
488
+ /* settings: {
555
489
  "import/resolver": this.options.enableSrcResolver
556
490
  ? {
557
491
  node: {
@@ -563,39 +497,22 @@ export default class CommonLintGenerator extends Generator {
563
497
  }
564
498
  : false,
565
499
  },
566
- relativePath: inMonorepo ? inMonorepo.relative : undefined,
567
- },
568
- );
569
-
570
- writeAndFormatJson(this.fs, srcEslintrcPath, srcEslintrcConfig);
571
- } catch (error) {
572
- console.warn(`Could not parse/edit ${srcEslintrcPath}: `, error);
500
+ */
573
501
  }
502
+ } else {
503
+ this.fs.delete(eslintConfigPath);
574
504
  }
575
505
 
576
506
  // see monorepo/lerna/index.js
577
507
  if (!(inMonorepo && inMonorepo.root) && !this.options.monorepo) {
578
- const srcDirectory =
579
- useBabel || this.options.typescript ? this.options.srcDirectory : "lib";
580
- const lintRootJsFiles = (useBabel && useNode) || !inMonorepo;
581
-
582
- const lintPaths = [srcDirectory, "bin", "scripts", "migrations"].filter(
583
- (dir) => fs.existsSync(this.destinationPath(dir)),
584
- );
585
-
586
- if (lintRootJsFiles) {
587
- lintPaths.unshift("*.{js,cjs,mjs}");
588
- }
589
-
590
- const args =
591
- "--report-unused-disable-directives --resolve-plugins-relative-to . --quiet";
508
+ const args = "--quiet";
592
509
 
593
510
  packageUtils.addScripts(pkg, {
594
511
  "lint:eslint": globalEslint
595
512
  ? `yarn ../.. run eslint ${args} ${path
596
513
  .relative("../..", ".")
597
514
  .replace("\\", "/")}`
598
- : `eslint ${args} ${lintPaths.join(" ")}`,
515
+ : `eslint ${args} .`,
599
516
  lint: `${
600
517
  useTypescript && !composite ? "tsc && " : ""
601
518
  }yarn run lint:eslint`,
@@ -0,0 +1,5 @@
1
+ <%- imports.map(v => `${v};\n`).join('') -%>
2
+
3
+ export default [
4
+ <%- flatCascade.map(v => ` ${v},\n`).join('') -%>
5
+ ];
@@ -50,6 +50,9 @@ export default class CoreNpmGenerator extends Generator {
50
50
 
51
51
  if (pkg.exports) {
52
52
  Object.values(pkg.exports).forEach((value) => {
53
+ if (typeof value === "string" && value.startsWith("./tsconfigs/")) {
54
+ files.add("tsconfigs");
55
+ }
53
56
  if (
54
57
  typeof value === "string" &&
55
58
  value.startsWith("./") &&
@@ -42,11 +42,14 @@
42
42
 
43
43
  // eslint config
44
44
  "eslint.workingDirectories": ["."],
45
- "eslint.options": {
46
- "resolvePluginsRelativeTo": ".",
47
- "reportUnusedDisableDirectives": "error"
48
- },
45
+ "eslint.useFlatConfig": true,
49
46
  "eslint.lintTask.enable": true,
47
+ "eslint.validate": [
48
+ "javascript",
49
+ "javascriptreact",
50
+ "typescript",
51
+ "typescriptreact"
52
+ ],
50
53
 
51
54
  // eslint & prettier formatter
52
55
  "eslint.format.enable": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pob",
3
- "version": "22.5.0",
3
+ "version": "23.0.0",
4
4
  "description": "Pile of bones, library generator with git/babel/typescript/typedoc/readme/jest",
5
5
  "keywords": [
6
6
  "skeleton"
@@ -40,12 +40,12 @@
40
40
  "pob": {},
41
41
  "prettier": "@pob/root/prettier-config",
42
42
  "dependencies": {
43
- "@pob/eslint-config": "56.1.0",
44
- "@pob/eslint-config-typescript": "56.1.0",
45
- "@pob/eslint-config-typescript-react": "56.1.0",
46
- "@pob/sort-eslint-config": "5.3.1",
47
- "@pob/sort-object": "6.3.1",
48
- "@pob/sort-pkg": "7.3.0",
43
+ "@pob/eslint-config": "57.3.0",
44
+ "@pob/eslint-config-typescript": "57.3.0",
45
+ "@pob/eslint-config-typescript-react": "57.3.0",
46
+ "@pob/sort-eslint-config": "6.0.0",
47
+ "@pob/sort-object": "7.0.0",
48
+ "@pob/sort-pkg": "8.0.0",
49
49
  "@prettier/sync": "0.5.2",
50
50
  "@types/inquirer": "9.0.7",
51
51
  "@yarnpkg/cli": "4.4.0",
@@ -64,16 +64,16 @@
64
64
  "mem-fs-editor": "11.0.1",
65
65
  "minimist": "1.2.8",
66
66
  "parse-author": "2.0.0",
67
- "pob-dependencies": "13.4.1",
67
+ "pob-dependencies": "14.0.0",
68
68
  "prettier": "3.3.3",
69
69
  "semver": "7.6.3",
70
70
  "validate-npm-package-name": "^5.0.0",
71
- "yarn-workspace-utils": "5.2.0",
71
+ "yarn-workspace-utils": "6.0.0",
72
72
  "yeoman-environment": "4.4.1",
73
73
  "yeoman-generator": "7.3.2"
74
74
  },
75
75
  "devDependencies": {
76
- "@pob/root": "12.4.0",
76
+ "@pob/root": "13.0.0",
77
77
  "@types/node": "20.14.15",
78
78
  "typescript": "5.5.4"
79
79
  }
@@ -1,27 +0,0 @@
1
- {
2
- "root": true,
3
- "extends": ["@pob/eslint-config/node-module"],
4
- "rules": {
5
- "max-lines": "off",
6
- "no-multi-assign": "off",
7
- "no-nested-ternary": "off",
8
- "no-console": "off",
9
- "complexity": "off"
10
- },
11
- "overrides": [
12
- {
13
- "files": ["**/*.test.{cjs,js}", "__tests__/**/*.{cjs,js}"],
14
- "env": {
15
- "jest": true
16
- },
17
- "rules": {
18
- "import/no-extraneous-dependencies": [
19
- "error",
20
- {
21
- "devDependencies": true
22
- }
23
- ]
24
- }
25
- }
26
- ]
27
- }