ts-repo-utils 9.0.1 → 10.0.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.
Files changed (91) hide show
  1. package/README.md +195 -214
  2. package/dist/cmd/assert-repo-is-clean.mjs +4 -4
  3. package/dist/cmd/assert-repo-is-clean.mjs.map +1 -1
  4. package/dist/cmd/check-should-run-type-checks.mjs +4 -4
  5. package/dist/cmd/check-should-run-type-checks.mjs.map +1 -1
  6. package/dist/cmd/format-diff-from.mjs +4 -4
  7. package/dist/cmd/format-diff-from.mjs.map +1 -1
  8. package/dist/cmd/format-uncommitted.mjs +4 -4
  9. package/dist/cmd/format-uncommitted.mjs.map +1 -1
  10. package/dist/cmd/gen-index-ts.mjs +4 -4
  11. package/dist/cmd/gen-index-ts.mjs.map +1 -1
  12. package/dist/functions/assert-ext.d.mts +3 -3
  13. package/dist/functions/assert-ext.d.mts.map +1 -1
  14. package/dist/functions/assert-ext.mjs +5 -4
  15. package/dist/functions/assert-ext.mjs.map +1 -1
  16. package/dist/functions/assert-path-exists.d.mts +0 -1
  17. package/dist/functions/assert-path-exists.d.mts.map +1 -1
  18. package/dist/functions/assert-path-exists.mjs +2 -2
  19. package/dist/functions/assert-path-exists.mjs.map +1 -1
  20. package/dist/functions/assert-repo-is-clean.d.mts +0 -1
  21. package/dist/functions/assert-repo-is-clean.d.mts.map +1 -1
  22. package/dist/functions/assert-repo-is-clean.mjs +2 -2
  23. package/dist/functions/assert-repo-is-clean.mjs.map +1 -1
  24. package/dist/functions/create-result-assert.d.mts +1 -1
  25. package/dist/functions/create-result-assert.d.mts.map +1 -1
  26. package/dist/functions/create-result-assert.mjs +1 -2
  27. package/dist/functions/create-result-assert.mjs.map +1 -1
  28. package/dist/functions/diff.d.mts +1 -1
  29. package/dist/functions/diff.d.mts.map +1 -1
  30. package/dist/functions/diff.mjs +1 -1
  31. package/dist/functions/exec-async.d.mts +1 -0
  32. package/dist/functions/exec-async.d.mts.map +1 -1
  33. package/dist/functions/exec-async.mjs +2 -2
  34. package/dist/functions/exec-async.mjs.map +1 -1
  35. package/dist/functions/format.d.mts +1 -1
  36. package/dist/functions/format.d.mts.map +1 -1
  37. package/dist/functions/format.mjs +8 -4
  38. package/dist/functions/format.mjs.map +1 -1
  39. package/dist/functions/gen-index.d.mts +2 -1
  40. package/dist/functions/gen-index.d.mts.map +1 -1
  41. package/dist/functions/gen-index.mjs +8 -3
  42. package/dist/functions/gen-index.mjs.map +1 -1
  43. package/dist/functions/glob.d.mts +2 -0
  44. package/dist/functions/glob.d.mts.map +1 -1
  45. package/dist/functions/glob.mjs +1 -1
  46. package/dist/functions/glob.mjs.map +1 -1
  47. package/dist/functions/should-run.d.mts +0 -1
  48. package/dist/functions/should-run.d.mts.map +1 -1
  49. package/dist/functions/should-run.mjs +3 -1
  50. package/dist/functions/should-run.mjs.map +1 -1
  51. package/dist/functions/workspace-utils/execute-parallel.d.mts +0 -1
  52. package/dist/functions/workspace-utils/execute-parallel.d.mts.map +1 -1
  53. package/dist/functions/workspace-utils/execute-parallel.mjs +0 -1
  54. package/dist/functions/workspace-utils/execute-parallel.mjs.map +1 -1
  55. package/dist/functions/workspace-utils/get-workspace-packages.d.mts +0 -1
  56. package/dist/functions/workspace-utils/get-workspace-packages.d.mts.map +1 -1
  57. package/dist/functions/workspace-utils/get-workspace-packages.mjs +9 -3
  58. package/dist/functions/workspace-utils/get-workspace-packages.mjs.map +1 -1
  59. package/dist/functions/workspace-utils/types.d.mts +1 -0
  60. package/dist/functions/workspace-utils/types.d.mts.map +1 -1
  61. package/dist/types.d.mts +1 -2
  62. package/package.json +23 -23
  63. package/src/cmd/assert-repo-is-clean.mts +1 -1
  64. package/src/cmd/check-should-run-type-checks.mts +1 -1
  65. package/src/cmd/format-diff-from.mts +1 -1
  66. package/src/cmd/format-uncommitted.mts +1 -1
  67. package/src/cmd/gen-index-ts.mts +2 -1
  68. package/src/functions/assert-ext.mts +7 -6
  69. package/src/functions/assert-path-exists.mts +2 -2
  70. package/src/functions/assert-repo-is-clean.mts +2 -2
  71. package/src/functions/create-result-assert.mts +1 -2
  72. package/src/functions/diff.mts +1 -1
  73. package/src/functions/diff.test.mts +21 -2
  74. package/src/functions/exec-async.mts +2 -2
  75. package/src/functions/exec-async.test.mts +6 -11
  76. package/src/functions/format.mts +8 -4
  77. package/src/functions/format.test.mts +24 -1
  78. package/src/functions/gen-index.mts +10 -3
  79. package/src/functions/glob.mts +2 -1
  80. package/src/functions/should-run.mts +3 -1
  81. package/src/functions/workspace-utils/execute-parallel.mts +0 -1
  82. package/src/functions/workspace-utils/get-workspace-packages.mts +6 -1
  83. package/src/functions/workspace-utils/run-cmd-in-stages.test.mts +0 -1
  84. package/src/functions/workspace-utils/types.mts +2 -0
  85. package/dist/globals.d.mts +0 -1
  86. package/dist/node-global.d.mts +0 -20
  87. package/dist/node-global.d.mts.map +0 -1
  88. package/dist/node-global.mjs +0 -27
  89. package/dist/node-global.mjs.map +0 -1
  90. package/src/globals.d.mts +0 -1
  91. package/src/node-global.mts +0 -49
package/README.md CHANGED
@@ -215,9 +215,6 @@ Executes a shell command asynchronously with type-safe results.
215
215
  ```tsx
216
216
  import { $, Result } from 'ts-repo-utils';
217
217
 
218
- // or
219
- // import "ts-repo-utils"; // $ and Result are globally defined in ts-repo-utils
220
-
221
218
  const result = await $('npm test');
222
219
 
223
220
  if (Result.isOk(result)) {
@@ -236,6 +233,7 @@ if (Result.isOk(result)) {
236
233
 
237
234
  ```tsx
238
235
  import { type ExecException } from 'node:child_process';
236
+ import { type Result } from 'ts-data-forge';
239
237
 
240
238
  type Ret = Promise<
241
239
  Result<
@@ -254,9 +252,6 @@ Determines whether a script is being executed directly via CLI or imported as a
254
252
  ```tsx
255
253
  import { isDirectlyExecuted } from 'ts-repo-utils';
256
254
 
257
- // or
258
- // import "ts-repo-utils"; // isDirectlyExecuted is globally defined in ts-repo-utils
259
-
260
255
  // calculator.mjs
261
256
  export const add = (a: number, b: number): number => a + b;
262
257
 
@@ -312,6 +307,28 @@ await assertPathExists('./src/index.ts', 'Entry point file');
312
307
 
313
308
  Runs the extension validation and reports findings without exiting the process. Useful when you want to combine extension checks with other validations or surface the failure information in a custom way.
314
309
 
310
+ ```tsx
311
+ import { Result } from 'ts-data-forge';
312
+ import { checkExt } from 'ts-repo-utils';
313
+
314
+ const result = await checkExt({
315
+ directories: [
316
+ { path: './src', extension: '.ts' },
317
+ { path: './scripts', extension: '.mjs' },
318
+ ],
319
+ });
320
+
321
+ if (Result.isErr(result)) {
322
+ console.error(result.value.message);
323
+
324
+ console.error('Files with wrong extensions:', result.value.files);
325
+ }
326
+ ```
327
+
328
+ #### `assertExt(config: CheckExtConfig): Promise<void>`
329
+
330
+ Validates that all files in specified directories have the correct extensions. Exits with code 1 if any files have incorrect extensions.
331
+
315
332
  ```tsx
316
333
  import { assertExt } from 'ts-repo-utils';
317
334
 
@@ -330,9 +347,7 @@ await assertExt({
330
347
  });
331
348
  ```
332
349
 
333
- #### `assertExt(config: CheckExtConfig): Promise<void>`
334
-
335
- Validates that all files in specified directories have the correct extensions. Exits with code 1 if any files have incorrect extensions.
350
+ **Configuration Type:**
336
351
 
337
352
  ```tsx
338
353
  type CheckExtConfig = Readonly<{
@@ -344,15 +359,6 @@ type CheckExtConfig = Readonly<{
344
359
  }>;
345
360
  ```
346
361
 
347
- **Configuration Type:**
348
-
349
- ```tsx
350
- import { makeEmptyDir } from 'ts-repo-utils';
351
-
352
- // Reset ./tmp/build before writing artifacts
353
- await makeEmptyDir('./tmp/build');
354
- ```
355
-
356
362
  ### Result Utilities
357
363
 
358
364
  #### `createResultAssert(options): (config) => Promise<TOk>`
@@ -360,13 +366,43 @@ await makeEmptyDir('./tmp/build');
360
366
  Creates an assert-style wrapper around a function that returns a `Result`, exiting the process with a non-zero code when the underlying function yields an error. The wrapper keeps success handling customizable while reusing the composable Result-based variant elsewhere.
361
367
 
362
368
  ```tsx
363
- import { repoIsDirty } from 'ts-repo-utils';
369
+ import { hasKey, isNumber, isRecord, isString, Result } from 'ts-data-forge';
370
+ import { createResultAssert } from 'ts-repo-utils';
371
+
372
+ type AppConfig = Readonly<{ port: number; host: string }>;
373
+
374
+ const parseConfig = (
375
+ raw: string,
376
+ ): Promise<Result<AppConfig, Readonly<{ message: string }>>> => {
377
+ const parsed: unknown = ((): unknown => {
378
+ try {
379
+ return JSON.parse(raw);
380
+ } catch {
381
+ return undefined;
382
+ }
383
+ })();
384
+
385
+ if (
386
+ !isRecord(parsed) ||
387
+ !hasKey(parsed, 'port') ||
388
+ !hasKey(parsed, 'host') ||
389
+ !isNumber(parsed.port) ||
390
+ !isString(parsed.host)
391
+ ) {
392
+ return Promise.resolve(Result.err({ message: 'Invalid config shape' }));
393
+ }
364
394
 
365
- const isDirty = await repoIsDirty();
395
+ return Promise.resolve(Result.ok({ port: parsed.port, host: parsed.host }));
396
+ };
366
397
 
367
- if (isDirty) {
368
- console.log('Repository has uncommitted changes');
369
- }
398
+ const assertValidConfig = createResultAssert({
399
+ run: parseConfig,
400
+ onSuccess: (config) => {
401
+ console.log(`✓ Config loaded: ${config.host}:${config.port}`);
402
+ },
403
+ });
404
+
405
+ await assertValidConfig('{"port":3000,"host":"localhost"}');
370
406
  ```
371
407
 
372
408
  **Options:**
@@ -381,10 +417,10 @@ if (isDirty) {
381
417
  Removes any existing directory at `dir` and recreates it, ensuring a clean target for generated assets or build output.
382
418
 
383
419
  ```tsx
384
- import { assertRepoIsClean } from 'ts-repo-utils';
420
+ import { makeEmptyDir } from 'ts-repo-utils';
385
421
 
386
- // Use in CI/build scripts to ensure clean state
387
- await assertRepoIsClean();
422
+ // Reset ./tmp/build before writing artifacts
423
+ await makeEmptyDir('./tmp/build');
388
424
  ```
389
425
 
390
426
  This helper uses `fs.rm` with `recursive` cleanup before calling `fs.mkdir`, so prefer it over manual `rimraf` + `mkdir` sequences when scripting workflows.
@@ -396,12 +432,13 @@ This helper uses `fs.rm` with `recursive` cleanup before calling `fs.mkdir`, so
396
432
  Checks if the repository has uncommitted changes.
397
433
 
398
434
  ```tsx
399
- import { type ExecException } from 'node:child_process';
435
+ import { repoIsDirty } from 'ts-repo-utils';
400
436
 
401
- type Ret = Result<
402
- readonly string[],
403
- ExecException | Readonly<{ message: string }>
404
- >;
437
+ const isDirty = await repoIsDirty();
438
+
439
+ if (isDirty) {
440
+ console.log('Repository has uncommitted changes');
441
+ }
405
442
  ```
406
443
 
407
444
  #### `assertRepoIsClean(): Promise<void>`
@@ -410,20 +447,10 @@ Checks if the repository is clean and exits with code 1 if it has uncommitted ch
410
447
  (Function version of the `assert-repo-is-clean` command)
411
448
 
412
449
  ```tsx
413
- import { checkShouldRunTypeChecks } from 'ts-repo-utils';
414
-
415
- // Use default settings (compare against origin/main)
416
- const shouldRun = await checkShouldRunTypeChecks();
417
-
418
- if (shouldRun) {
419
- await $('npm run type-check');
420
- }
450
+ import { assertRepoIsClean } from 'ts-repo-utils';
421
451
 
422
- // Custom ignore patterns and base branch
423
- const shouldRun2 = await checkShouldRunTypeChecks({
424
- pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
425
- baseBranch: 'origin/develop',
426
- });
452
+ // Use in CI/build scripts to ensure clean state
453
+ await assertRepoIsClean();
427
454
  ```
428
455
 
429
456
  **Options:**
@@ -460,19 +487,13 @@ Runs `git diff --name-only <base> [--diff-filter=d]`
460
487
  **Common Return Type:**
461
488
 
462
489
  ```tsx
463
- import { formatFilesGlob } from 'ts-repo-utils';
464
-
465
- // Format all TypeScript files in src
466
- await formatFilesGlob('src/**/*.ts');
467
-
468
- // Format specific files
469
- await formatFilesGlob('src/{index,utils}.ts');
490
+ import { type ExecException } from 'node:child_process';
491
+ import { type Result } from 'ts-data-forge';
470
492
 
471
- // With custom ignore function
472
- await formatFilesGlob('src/**/*.ts', {
473
- ignore: (filePath) => filePath.includes('generated'),
474
- ignoreUnknown: false, // Error on files without parser
475
- });
493
+ type Ret = Result<
494
+ readonly string[],
495
+ ExecException | Readonly<{ message: string }>
496
+ >;
476
497
  ```
477
498
 
478
499
  #### Build Optimization Utilities
@@ -483,15 +504,19 @@ Checks whether TypeScript type checks should run based on file changes from the
483
504
  (Function version of the `check-should-run-type-checks` command)
484
505
 
485
506
  ```tsx
486
- import { formatUncommittedFiles } from 'ts-repo-utils';
507
+ import { $, checkShouldRunTypeChecks } from 'ts-repo-utils';
487
508
 
488
- // Format only modified files
489
- await formatUncommittedFiles();
509
+ // Use default settings (compare against origin/main)
510
+ const shouldRun = await checkShouldRunTypeChecks();
490
511
 
491
- // With custom options
492
- await formatUncommittedFiles({
493
- untracked: false, // Skip untracked files
494
- ignore: (filePath) => filePath.includes('test'),
512
+ if (shouldRun) {
513
+ await $('npm run type-check');
514
+ }
515
+
516
+ // Custom ignore patterns and base branch
517
+ const shouldRun2 = await checkShouldRunTypeChecks({
518
+ pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
519
+ baseBranch: 'origin/develop',
495
520
  });
496
521
  ```
497
522
 
@@ -511,14 +536,19 @@ await formatUncommittedFiles({
511
536
  Formats files matching a glob pattern using Prettier.
512
537
 
513
538
  ```tsx
514
- import { type ExecException } from 'node:child_process';
539
+ import { formatFilesGlob } from 'ts-repo-utils';
515
540
 
516
- type Ret = Promise<
517
- Result<
518
- undefined,
519
- ExecException | Readonly<{ message: string }> | readonly unknown[]
520
- >
521
- >;
541
+ // Format all TypeScript files in src
542
+ await formatFilesGlob('src/**/*.ts');
543
+
544
+ // Format specific files
545
+ await formatFilesGlob('src/{index,utils}.ts');
546
+
547
+ // With custom ignore function
548
+ await formatFilesGlob('src/**/*.ts', {
549
+ ignore: (filePath) => filePath.includes('generated'),
550
+ ignoreUnknown: false, // Error on files without parser
551
+ });
522
552
  ```
523
553
 
524
554
  **Options:**
@@ -533,19 +563,15 @@ Formats only files that have been changed according to git status.
533
563
  (Function version of the `format-uncommitted` command)
534
564
 
535
565
  ```tsx
536
- import { formatDiffFrom } from 'ts-repo-utils';
537
-
538
- // Format files different from main branch
539
- await formatDiffFrom('main');
566
+ import { formatUncommittedFiles } from 'ts-repo-utils';
540
567
 
541
- // Format files different from specific commit
542
- await formatDiffFrom('abc123');
568
+ // Format only modified files
569
+ await formatUncommittedFiles();
543
570
 
544
571
  // With custom options
545
- await formatDiffFrom('main', {
546
- includeUntracked: false,
547
- ignore: (filePath) => filePath.includes('vendor'),
548
- ignoreUnknown: false, // Error on files without parser
572
+ await formatUncommittedFiles({
573
+ untracked: false, // Skip untracked files
574
+ ignore: (filePath) => filePath.includes('test'),
549
575
  });
550
576
  ```
551
577
 
@@ -562,6 +588,7 @@ await formatDiffFrom('main', {
562
588
 
563
589
  ```tsx
564
590
  import { type ExecException } from 'node:child_process';
591
+ import { type Result } from 'ts-data-forge';
565
592
 
566
593
  type Ret = Promise<
567
594
  Result<
@@ -577,11 +604,19 @@ Formats only files that differ from the specified base branch or commit.
577
604
  (Function version of the `format-diff-from` command)
578
605
 
579
606
  ```tsx
580
- import { genIndex } from 'ts-repo-utils';
607
+ import { formatDiffFrom } from 'ts-repo-utils';
581
608
 
582
- await genIndex({
583
- targetDirectory: './src',
584
- exclude: ['*.test.ts', '*.spec.ts'],
609
+ // Format files different from main branch
610
+ await formatDiffFrom('main');
611
+
612
+ // Format files different from specific commit
613
+ await formatDiffFrom('abc123');
614
+
615
+ // With custom options
616
+ await formatDiffFrom('main', {
617
+ includeUntracked: false,
618
+ ignore: (filePath) => filePath.includes('vendor'),
619
+ ignoreUnknown: false, // Error on files without parser
585
620
  });
586
621
  ```
587
622
 
@@ -596,6 +631,36 @@ await genIndex({
596
631
 
597
632
  **Return Type:**
598
633
 
634
+ ```tsx
635
+ import { type ExecException } from 'node:child_process';
636
+ import { type Result } from 'ts-data-forge';
637
+
638
+ type Ret = Promise<
639
+ Result<
640
+ undefined,
641
+ ExecException | Readonly<{ message: string }> | readonly unknown[]
642
+ >
643
+ >;
644
+ ```
645
+
646
+ ### Index File Generation
647
+
648
+ #### `genIndex(config: GenIndexConfig): Promise<Result<undefined, unknown>>`
649
+
650
+ Generates index files recursively in target directories with automatic barrel exports.
651
+ (Function version of the `gen-index-ts` command)
652
+
653
+ ```tsx
654
+ import { genIndex } from 'ts-repo-utils';
655
+
656
+ await genIndex({
657
+ targetDirectory: './src',
658
+ exclude: ['*.test.ts', '*.spec.ts'],
659
+ });
660
+ ```
661
+
662
+ **Configuration Type:**
663
+
599
664
  ```tsx
600
665
  type GenIndexConfig = Readonly<{
601
666
  /** Target directories to generate index files for (string or array of strings) */
@@ -636,39 +701,6 @@ type GenIndexConfig = Readonly<{
636
701
  }>;
637
702
  ```
638
703
 
639
- ### Index File Generation
640
-
641
- #### `genIndex(config: GenIndexConfig): Promise<Result<undefined, unknown>>`
642
-
643
- Generates index files recursively in target directories with automatic barrel exports.
644
- (Function version of the `gen-index-ts` command)
645
-
646
- ```tsx
647
- import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
648
-
649
- // Run build in dependency order
650
- await runCmdInStagesAcrossWorkspaces({
651
- rootPackageJsonDir: '../',
652
- cmd: 'build',
653
- concurrency: 3,
654
- filterWorkspacePattern: (name) => !name.includes('experimental'),
655
- });
656
- ```
657
-
658
- **Configuration Type:**
659
-
660
- ```tsx
661
- import { runCmdInParallelAcrossWorkspaces } from 'ts-repo-utils';
662
-
663
- // Run tests in parallel across all packages
664
- await runCmdInParallelAcrossWorkspaces({
665
- rootPackageJsonDir: '../',
666
- cmd: 'test',
667
- concurrency: 5,
668
- filterWorkspacePattern: (name) => !name.includes('experimental'),
669
- });
670
- ```
671
-
672
704
  **Features:**
673
705
 
674
706
  - Creates barrel exports for all subdirectories
@@ -689,12 +721,15 @@ await runCmdInParallelAcrossWorkspaces({
689
721
  Executes an npm script command across all workspace packages in dependency order stages. Packages are grouped into stages where each stage contains packages whose dependencies have been completed in previous stages. Uses fail-fast behavior.
690
722
 
691
723
  ```tsx
692
- import { getWorkspacePackages } from 'ts-repo-utils';
693
-
694
- const packages = await getWorkspacePackages('.');
724
+ import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
695
725
 
696
- console.log(packages.map((pkg) => pkg.name));
697
- // ['@myorg/package-a', '@myorg/package-b', ...]
726
+ // Run build in dependency order
727
+ await runCmdInStagesAcrossWorkspaces({
728
+ rootPackageJsonDir: '../',
729
+ cmd: 'build',
730
+ concurrency: 3,
731
+ filterWorkspacePattern: (name) => !name.includes('experimental'),
732
+ });
698
733
  ```
699
734
 
700
735
  **Options:**
@@ -709,12 +744,15 @@ console.log(packages.map((pkg) => pkg.name));
709
744
  Executes an npm script command across all workspace packages in parallel. Uses fail-fast behavior - stops execution immediately when any package fails.
710
745
 
711
746
  ```tsx
712
- type Package = Readonly<{
713
- name: string;
714
- path: string;
715
- packageJson: JsonValue;
716
- dependencies: Readonly<Record<string, string>>;
717
- }>;
747
+ import { runCmdInParallelAcrossWorkspaces } from 'ts-repo-utils';
748
+
749
+ // Run tests in parallel across all packages
750
+ await runCmdInParallelAcrossWorkspaces({
751
+ rootPackageJsonDir: '../',
752
+ cmd: 'test',
753
+ concurrency: 5,
754
+ filterWorkspacePattern: (name) => !name.includes('experimental'),
755
+ });
718
756
  ```
719
757
 
720
758
  **Options:**
@@ -729,21 +767,25 @@ type Package = Readonly<{
729
767
  Retrieves all workspace packages from a monorepo based on the workspace patterns defined in the root package.json file.
730
768
 
731
769
  ```tsx
732
- import { executeParallel, getWorkspacePackages } from 'ts-repo-utils';
770
+ import { getWorkspacePackages } from 'ts-repo-utils';
733
771
 
734
772
  const packages = await getWorkspacePackages('.');
735
773
 
736
- await executeParallel(packages, 'lint', 4);
774
+ console.log(packages.map((pkg) => pkg.name));
775
+ // ['@myorg/package-a', '@myorg/package-b', ...]
737
776
  ```
738
777
 
739
778
  **Return Type:**
740
779
 
741
780
  ```tsx
742
- import { executeStages, getWorkspacePackages } from 'ts-repo-utils';
781
+ import { type JsonValue } from 'ts-type-forge';
743
782
 
744
- const packages = await getWorkspacePackages('.');
745
-
746
- await executeStages(packages, 'build', 3);
783
+ type Package = Readonly<{
784
+ name: string;
785
+ path: string;
786
+ packageJson: JsonValue;
787
+ dependencies: Readonly<Record<string, string>>;
788
+ }>;
747
789
  ```
748
790
 
749
791
  #### `executeParallel(packages, scriptName, concurrency?): Promise<readonly Result[]>`
@@ -751,31 +793,11 @@ await executeStages(packages, 'build', 3);
751
793
  Executes an npm script across multiple packages in parallel with a concurrency limit. Lower-level function used by `runCmdInParallelAcrossWorkspaces`.
752
794
 
753
795
  ```tsx
754
- import 'ts-repo-utils';
755
-
756
- // Now these functions are globally available
757
-
758
- const result = await $('npm test');
759
-
760
- if (Result.isErr(result)) {
761
- console.error(result.value);
762
- }
763
-
764
- echo('Building project...');
765
-
766
- const filePath: string = path.join('src', 'index.ts');
767
-
768
- const configJson: string = await fs.readFile('./config.json', {
769
- encoding: 'utf8',
770
- });
771
-
772
- const home = os.homedir();
796
+ import { executeParallel, getWorkspacePackages } from 'ts-repo-utils';
773
797
 
774
- const files: readonly string[] = await glob('**/*.ts');
798
+ const packages = await getWorkspacePackages('.');
775
799
 
776
- if (isDirectlyExecuted(import.meta.url)) {
777
- echo('Running as CLI');
778
- }
800
+ await executeParallel(packages, 'lint', 4);
779
801
  ```
780
802
 
781
803
  #### `executeStages(packages, scriptName, concurrency?): Promise<void>`
@@ -783,22 +805,11 @@ if (isDirectlyExecuted(import.meta.url)) {
783
805
  Executes an npm script across packages in dependency order stages. Lower-level function used by `runCmdInStagesAcrossWorkspaces`.
784
806
 
785
807
  ```tsx
786
- import {
787
- assertExt,
788
- assertRepoIsClean,
789
- formatUncommittedFiles,
790
- } from 'ts-repo-utils';
791
-
792
- // Validate file extensions
793
- await assertExt({
794
- directories: [{ path: './src', extension: '.ts' }],
795
- });
808
+ import { executeStages, getWorkspacePackages } from 'ts-repo-utils';
796
809
 
797
- // Format changed files
798
- await formatUncommittedFiles();
810
+ const packages = await getWorkspacePackages('.');
799
811
 
800
- // Ensure repository is clean (exits if dirty)
801
- await assertRepoIsClean();
812
+ await executeStages(packages, 'build', 3);
802
813
  ```
803
814
 
804
815
  **Features:**
@@ -809,64 +820,33 @@ await assertRepoIsClean();
809
820
  - Fail-fast behavior on errors
810
821
  - Circular dependency detection
811
822
 
812
- ### Globals
813
-
814
- When you import `ts-repo-utils` without destructuring, several utilities become globally available. This is useful for scripts where you want quick access to common functions without explicit imports.
815
-
816
- ```tsx
817
- import { formatFilesGlob, genIndex } from 'ts-repo-utils';
818
-
819
- // Generate barrel exports
820
- await genIndex({ targetDirectory: './src' });
821
-
822
- // Type check
823
- await $('tsc --noEmit');
824
-
825
- // Build
826
- await $('rollup -c');
827
-
828
- // Format output
829
- await formatFilesGlob('dist/**/*.js');
830
- ```
831
-
832
- - `$` - The command execution utility described above.
833
- - `Result` - A utility for Result pattern (from [ts-data-forge](https://github.com/noshiro-pf/ts-data-forge#readme))
834
- - `echo` - Equivalent to `console.log`
835
- - `cd` - Equivalent to `process.chdir`
836
- - `path` - `node:path`
837
- - `fs` - `node:fs/promises`
838
- - `os` - `node:os`
839
- - `glob` - `fast-glob`
840
- - `isDirectlyExecuted` - The script execution utility described above.
841
-
842
823
  ## Common Patterns
843
824
 
844
825
  ### Pre-commit Hook
845
826
 
846
827
  ```tsx
847
- import { assertExt, assertPathExists, assertRepoIsClean } from 'ts-repo-utils';
848
-
849
- // Check required files exist (exits with code 1 if files don't exist)
850
- await assertPathExists('./package.json', 'Package manifest');
851
-
852
- await assertPathExists('./tsconfig.json', 'TypeScript config');
828
+ import {
829
+ assertExt,
830
+ assertRepoIsClean,
831
+ formatUncommittedFiles,
832
+ } from 'ts-repo-utils';
853
833
 
854
- // Validate extensions
834
+ // Validate file extensions
855
835
  await assertExt({
856
- directories: [
857
- { path: './src', extension: '.ts' },
858
- { path: './scripts', extension: '.mjs' },
859
- ],
836
+ directories: [{ path: './src', extension: '.ts' }],
860
837
  });
861
838
 
862
- // Verify clean repository state (exits with code 1 if repo is dirty)
839
+ // Format changed files
840
+ await formatUncommittedFiles();
841
+
842
+ // Ensure repository is clean (exits if dirty)
863
843
  await assertRepoIsClean();
864
844
  ```
865
845
 
866
846
  ### Build Pipeline
867
847
 
868
848
  ```tsx
869
- import { formatFilesGlob, genIndex } from 'ts-repo-utils';
849
+ import { $, formatFilesGlob, genIndex } from 'ts-repo-utils';
870
850
 
871
851
  // Generate barrel exports
872
852
  await genIndex({ targetDirectory: './src' });
@@ -888,6 +868,7 @@ import { assertExt, assertPathExists, assertRepoIsClean } from 'ts-repo-utils';
888
868
 
889
869
  // Check required files exist (exits with code 1 if files don't exist)
890
870
  await assertPathExists('./package.json', 'Package manifest');
871
+
891
872
  await assertPathExists('./tsconfig.json', 'TypeScript config');
892
873
 
893
874
  // Validate extensions
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import * as cmd from 'cmd-ts';
3
+ import 'node:path';
3
4
  import 'ts-data-forge';
4
- import '../node-global.mjs';
5
+ import 'node:fs/promises';
6
+ import 'fast-glob';
5
7
  import { assertRepoIsClean } from '../functions/assert-repo-is-clean.mjs';
6
8
  import 'node:child_process';
7
9
  import 'prettier';
8
10
  import 'micromatch';
9
- import 'fast-glob';
10
11
  import 'node:fs';
11
12
  import 'node:url';
12
- import 'node:fs/promises';
13
13
  import '@sindresorhus/is';
14
14
 
15
15
  const cmdDef = cmd.command({
16
16
  name: 'assert-repo-is-clean-cli',
17
- version: '9.0.1',
17
+ version: '10.0.1',
18
18
  args: {
19
19
  silent: cmd.flag({
20
20
  long: 'silent',
@@ -1 +1 @@
1
- {"version":3,"file":"assert-repo-is-clean.mjs","sources":["../../src/cmd/assert-repo-is-clean.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;AAKA,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;AACzB,IAAA,IAAI,EAAE,0BAA0B;AAChC,IAAA,OAAO,EAAE,OAAO;AAChB,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC;AACf,YAAA,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/B,YAAA,WAAW,EAAE,sDAAsD;SACpE,CAAC;AACH,KAAA;AACD,IAAA,OAAO,EAAE,CAAC,IAAI,KAAI;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,KAAI;AAClC,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC;AAE1C,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjB,QAAA,CAAC,CAAC;IACJ,CAAC;AACF,CAAA,CAAC;AAEF,MAAM,IAAI,GAAG,OAAO,IAAoC,KAAmB;IACzE,MAAM,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"assert-repo-is-clean.mjs","sources":["../../src/cmd/assert-repo-is-clean.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;AAKA,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;AACzB,IAAA,IAAI,EAAE,0BAA0B;AAChC,IAAA,OAAO,EAAE,QAAQ;AACjB,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC;AACf,YAAA,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/B,YAAA,WAAW,EAAE,sDAAsD;SACpE,CAAC;AACH,KAAA;AACD,IAAA,OAAO,EAAE,CAAC,IAAI,KAAI;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,KAAI;AAClC,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC;AAE1C,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjB,QAAA,CAAC,CAAC;IACJ,CAAC;AACF,CAAA,CAAC;AAEF,MAAM,IAAI,GAAG,OAAO,IAAoC,KAAmB;IACzE,MAAM,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import * as cmd from 'cmd-ts';
3
+ import 'node:path';
3
4
  import 'ts-data-forge';
4
- import '../node-global.mjs';
5
+ import 'node:fs/promises';
6
+ import 'fast-glob';
5
7
  import 'node:child_process';
6
8
  import 'prettier';
7
9
  import 'micromatch';
8
- import 'fast-glob';
9
10
  import 'node:fs';
10
11
  import 'node:url';
11
- import 'node:fs/promises';
12
12
  import { checkShouldRunTypeChecks } from '../functions/should-run.mjs';
13
13
  import '@sindresorhus/is';
14
14
 
15
15
  const cmdDef = cmd.command({
16
16
  name: 'check-should-run-type-checks-cli',
17
- version: '9.0.1',
17
+ version: '10.0.1',
18
18
  args: {
19
19
  pathsIgnore: cmd.multioption({
20
20
  long: 'paths-ignore',
@@ -1 +1 @@
1
- {"version":3,"file":"check-should-run-type-checks.mjs","sources":["../../src/cmd/check-should-run-type-checks.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;AAKA,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;AACzB,IAAA,IAAI,EAAE,kCAAkC;AACxC,IAAA,OAAO,EAAE,OAAO;AAChB,IAAA,IAAI,EAAE;AACJ,QAAA,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC;AAC3B,YAAA,IAAI,EAAE,cAAc;AACpB,YAAA,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACzC,YAAA,WAAW,EACT,0KAA0K;SAC7K,CAAC;AACF,QAAA,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC;AACrB,YAAA,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;AAC9B,YAAA,WAAW,EACT,yFAAyF;SAC5F,CAAC;AACH,KAAA;AACD,IAAA,OAAO,EAAE,CAAC,IAAI,KAAI;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,KAAI;AAClC,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC;AAE1C,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjB,QAAA,CAAC,CAAC;IACJ,CAAC;AACF,CAAA,CAAC;AAEF,MAAM,IAAI,GAAG,OACX,IAGE,KACe;AACjB,IAAA,MAAM,wBAAwB,CAAC;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;AAC5B,KAAA,CAAC;AACJ,CAAC;AAED,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"check-should-run-type-checks.mjs","sources":["../../src/cmd/check-should-run-type-checks.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;AAKA,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;AACzB,IAAA,IAAI,EAAE,kCAAkC;AACxC,IAAA,OAAO,EAAE,QAAQ;AACjB,IAAA,IAAI,EAAE;AACJ,QAAA,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC;AAC3B,YAAA,IAAI,EAAE,cAAc;AACpB,YAAA,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACzC,YAAA,WAAW,EACT,0KAA0K;SAC7K,CAAC;AACF,QAAA,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC;AACrB,YAAA,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;AAC9B,YAAA,WAAW,EACT,yFAAyF;SAC5F,CAAC;AACH,KAAA;AACD,IAAA,OAAO,EAAE,CAAC,IAAI,KAAI;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,KAAI;AAClC,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC;AAE1C,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjB,QAAA,CAAC,CAAC;IACJ,CAAC;AACF,CAAA,CAAC;AAEF,MAAM,IAAI,GAAG,OACX,IAGE,KACe;AACjB,IAAA,MAAM,wBAAwB,CAAC;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;AAC5B,KAAA,CAAC;AACJ,CAAC;AAED,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}