ts-repo-utils 9.0.1 → 10.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 +190 -215
- package/dist/cmd/assert-repo-is-clean.mjs +4 -4
- package/dist/cmd/assert-repo-is-clean.mjs.map +1 -1
- package/dist/cmd/check-should-run-type-checks.mjs +4 -4
- package/dist/cmd/check-should-run-type-checks.mjs.map +1 -1
- package/dist/cmd/format-diff-from.mjs +4 -4
- package/dist/cmd/format-diff-from.mjs.map +1 -1
- package/dist/cmd/format-uncommitted.mjs +4 -4
- package/dist/cmd/format-uncommitted.mjs.map +1 -1
- package/dist/cmd/gen-index-ts.mjs +4 -4
- package/dist/cmd/gen-index-ts.mjs.map +1 -1
- package/dist/functions/assert-ext.d.mts +1 -3
- package/dist/functions/assert-ext.d.mts.map +1 -1
- package/dist/functions/assert-ext.mjs +5 -4
- package/dist/functions/assert-ext.mjs.map +1 -1
- package/dist/functions/assert-path-exists.d.mts +0 -1
- package/dist/functions/assert-path-exists.d.mts.map +1 -1
- package/dist/functions/assert-path-exists.mjs +2 -2
- package/dist/functions/assert-path-exists.mjs.map +1 -1
- package/dist/functions/assert-repo-is-clean.d.mts +0 -1
- package/dist/functions/assert-repo-is-clean.d.mts.map +1 -1
- package/dist/functions/assert-repo-is-clean.mjs +2 -2
- package/dist/functions/assert-repo-is-clean.mjs.map +1 -1
- package/dist/functions/create-result-assert.d.mts +0 -1
- package/dist/functions/create-result-assert.d.mts.map +1 -1
- package/dist/functions/create-result-assert.mjs +1 -2
- package/dist/functions/create-result-assert.mjs.map +1 -1
- package/dist/functions/diff.d.mts +0 -1
- package/dist/functions/diff.d.mts.map +1 -1
- package/dist/functions/diff.mjs +1 -1
- package/dist/functions/exec-async.mjs +2 -2
- package/dist/functions/exec-async.mjs.map +1 -1
- package/dist/functions/format.d.mts +0 -1
- package/dist/functions/format.d.mts.map +1 -1
- package/dist/functions/format.mjs +8 -4
- package/dist/functions/format.mjs.map +1 -1
- package/dist/functions/gen-index.d.mts +0 -1
- package/dist/functions/gen-index.d.mts.map +1 -1
- package/dist/functions/gen-index.mjs +8 -3
- package/dist/functions/gen-index.mjs.map +1 -1
- package/dist/functions/glob.mjs +1 -1
- package/dist/functions/should-run.d.mts +0 -1
- package/dist/functions/should-run.d.mts.map +1 -1
- package/dist/functions/should-run.mjs +3 -1
- package/dist/functions/should-run.mjs.map +1 -1
- package/dist/functions/workspace-utils/execute-parallel.d.mts +0 -1
- package/dist/functions/workspace-utils/execute-parallel.d.mts.map +1 -1
- package/dist/functions/workspace-utils/execute-parallel.mjs +0 -1
- package/dist/functions/workspace-utils/execute-parallel.mjs.map +1 -1
- package/dist/functions/workspace-utils/get-workspace-packages.d.mts +0 -1
- package/dist/functions/workspace-utils/get-workspace-packages.d.mts.map +1 -1
- package/dist/functions/workspace-utils/get-workspace-packages.mjs +9 -3
- package/dist/functions/workspace-utils/get-workspace-packages.mjs.map +1 -1
- package/dist/types.d.mts +1 -2
- package/package.json +19 -19
- package/src/cmd/assert-repo-is-clean.mts +1 -1
- package/src/cmd/check-should-run-type-checks.mts +1 -1
- package/src/cmd/format-diff-from.mts +1 -1
- package/src/cmd/format-uncommitted.mts +1 -1
- package/src/cmd/gen-index-ts.mts +1 -1
- package/src/functions/assert-ext.mts +6 -6
- package/src/functions/assert-path-exists.mts +2 -2
- package/src/functions/assert-repo-is-clean.mts +2 -2
- package/src/functions/create-result-assert.mts +1 -2
- package/src/functions/diff.mts +1 -1
- package/src/functions/diff.test.mts +21 -2
- package/src/functions/exec-async.mts +2 -2
- package/src/functions/exec-async.test.mts +6 -11
- package/src/functions/format.mts +8 -4
- package/src/functions/format.test.mts +24 -1
- package/src/functions/gen-index.mts +9 -3
- package/src/functions/glob.mts +1 -1
- package/src/functions/should-run.mts +3 -1
- package/src/functions/workspace-utils/execute-parallel.mts +0 -1
- package/src/functions/workspace-utils/get-workspace-packages.mts +5 -1
- package/src/functions/workspace-utils/run-cmd-in-stages.test.mts +0 -1
- package/dist/globals.d.mts +0 -1
- package/dist/node-global.d.mts +0 -20
- package/dist/node-global.d.mts.map +0 -1
- package/dist/node-global.mjs +0 -27
- package/dist/node-global.mjs.map +0 -1
- package/src/globals.d.mts +0 -1
- 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)) {
|
|
@@ -254,9 +251,6 @@ Determines whether a script is being executed directly via CLI or imported as a
|
|
|
254
251
|
```tsx
|
|
255
252
|
import { isDirectlyExecuted } from 'ts-repo-utils';
|
|
256
253
|
|
|
257
|
-
// or
|
|
258
|
-
// import "ts-repo-utils"; // isDirectlyExecuted is globally defined in ts-repo-utils
|
|
259
|
-
|
|
260
254
|
// calculator.mjs
|
|
261
255
|
export const add = (a: number, b: number): number => a + b;
|
|
262
256
|
|
|
@@ -312,6 +306,28 @@ await assertPathExists('./src/index.ts', 'Entry point file');
|
|
|
312
306
|
|
|
313
307
|
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
308
|
|
|
309
|
+
```tsx
|
|
310
|
+
import { Result } from 'ts-data-forge';
|
|
311
|
+
import { checkExt } from 'ts-repo-utils';
|
|
312
|
+
|
|
313
|
+
const result = await checkExt({
|
|
314
|
+
directories: [
|
|
315
|
+
{ path: './src', extension: '.ts' },
|
|
316
|
+
{ path: './scripts', extension: '.mjs' },
|
|
317
|
+
],
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
if (Result.isErr(result)) {
|
|
321
|
+
console.error(result.value.message);
|
|
322
|
+
|
|
323
|
+
console.error('Files with wrong extensions:', result.value.files);
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `assertExt(config: CheckExtConfig): Promise<void>`
|
|
328
|
+
|
|
329
|
+
Validates that all files in specified directories have the correct extensions. Exits with code 1 if any files have incorrect extensions.
|
|
330
|
+
|
|
315
331
|
```tsx
|
|
316
332
|
import { assertExt } from 'ts-repo-utils';
|
|
317
333
|
|
|
@@ -330,9 +346,7 @@ await assertExt({
|
|
|
330
346
|
});
|
|
331
347
|
```
|
|
332
348
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
Validates that all files in specified directories have the correct extensions. Exits with code 1 if any files have incorrect extensions.
|
|
349
|
+
**Configuration Type:**
|
|
336
350
|
|
|
337
351
|
```tsx
|
|
338
352
|
type CheckExtConfig = Readonly<{
|
|
@@ -344,15 +358,6 @@ type CheckExtConfig = Readonly<{
|
|
|
344
358
|
}>;
|
|
345
359
|
```
|
|
346
360
|
|
|
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
361
|
### Result Utilities
|
|
357
362
|
|
|
358
363
|
#### `createResultAssert(options): (config) => Promise<TOk>`
|
|
@@ -360,13 +365,43 @@ await makeEmptyDir('./tmp/build');
|
|
|
360
365
|
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
366
|
|
|
362
367
|
```tsx
|
|
363
|
-
import {
|
|
368
|
+
import { hasKey, isNumber, isRecord, isString, Result } from 'ts-data-forge';
|
|
369
|
+
import { createResultAssert } from 'ts-repo-utils';
|
|
370
|
+
|
|
371
|
+
type AppConfig = Readonly<{ port: number; host: string }>;
|
|
372
|
+
|
|
373
|
+
const parseConfig = (
|
|
374
|
+
raw: string,
|
|
375
|
+
): Promise<Result<AppConfig, Readonly<{ message: string }>>> => {
|
|
376
|
+
const parsed: unknown = ((): unknown => {
|
|
377
|
+
try {
|
|
378
|
+
return JSON.parse(raw);
|
|
379
|
+
} catch {
|
|
380
|
+
return undefined;
|
|
381
|
+
}
|
|
382
|
+
})();
|
|
383
|
+
|
|
384
|
+
if (
|
|
385
|
+
!isRecord(parsed) ||
|
|
386
|
+
!hasKey(parsed, 'port') ||
|
|
387
|
+
!hasKey(parsed, 'host') ||
|
|
388
|
+
!isNumber(parsed.port) ||
|
|
389
|
+
!isString(parsed.host)
|
|
390
|
+
) {
|
|
391
|
+
return Promise.resolve(Result.err({ message: 'Invalid config shape' }));
|
|
392
|
+
}
|
|
364
393
|
|
|
365
|
-
|
|
394
|
+
return Promise.resolve(Result.ok({ port: parsed.port, host: parsed.host }));
|
|
395
|
+
};
|
|
366
396
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
397
|
+
const assertValidConfig = createResultAssert({
|
|
398
|
+
run: parseConfig,
|
|
399
|
+
onSuccess: (config) => {
|
|
400
|
+
console.log(`✓ Config loaded: ${config.host}:${config.port}`);
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
await assertValidConfig('{"port":3000,"host":"localhost"}');
|
|
370
405
|
```
|
|
371
406
|
|
|
372
407
|
**Options:**
|
|
@@ -381,10 +416,10 @@ if (isDirty) {
|
|
|
381
416
|
Removes any existing directory at `dir` and recreates it, ensuring a clean target for generated assets or build output.
|
|
382
417
|
|
|
383
418
|
```tsx
|
|
384
|
-
import {
|
|
419
|
+
import { makeEmptyDir } from 'ts-repo-utils';
|
|
385
420
|
|
|
386
|
-
//
|
|
387
|
-
await
|
|
421
|
+
// Reset ./tmp/build before writing artifacts
|
|
422
|
+
await makeEmptyDir('./tmp/build');
|
|
388
423
|
```
|
|
389
424
|
|
|
390
425
|
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 +431,13 @@ This helper uses `fs.rm` with `recursive` cleanup before calling `fs.mkdir`, so
|
|
|
396
431
|
Checks if the repository has uncommitted changes.
|
|
397
432
|
|
|
398
433
|
```tsx
|
|
399
|
-
import {
|
|
434
|
+
import { repoIsDirty } from 'ts-repo-utils';
|
|
400
435
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
436
|
+
const isDirty = await repoIsDirty();
|
|
437
|
+
|
|
438
|
+
if (isDirty) {
|
|
439
|
+
console.log('Repository has uncommitted changes');
|
|
440
|
+
}
|
|
405
441
|
```
|
|
406
442
|
|
|
407
443
|
#### `assertRepoIsClean(): Promise<void>`
|
|
@@ -410,20 +446,10 @@ Checks if the repository is clean and exits with code 1 if it has uncommitted ch
|
|
|
410
446
|
(Function version of the `assert-repo-is-clean` command)
|
|
411
447
|
|
|
412
448
|
```tsx
|
|
413
|
-
import {
|
|
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
|
-
}
|
|
449
|
+
import { assertRepoIsClean } from 'ts-repo-utils';
|
|
421
450
|
|
|
422
|
-
//
|
|
423
|
-
|
|
424
|
-
pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
|
|
425
|
-
baseBranch: 'origin/develop',
|
|
426
|
-
});
|
|
451
|
+
// Use in CI/build scripts to ensure clean state
|
|
452
|
+
await assertRepoIsClean();
|
|
427
453
|
```
|
|
428
454
|
|
|
429
455
|
**Options:**
|
|
@@ -460,19 +486,12 @@ Runs `git diff --name-only <base> [--diff-filter=d]`
|
|
|
460
486
|
**Common Return Type:**
|
|
461
487
|
|
|
462
488
|
```tsx
|
|
463
|
-
import {
|
|
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');
|
|
489
|
+
import { type ExecException } from 'node:child_process';
|
|
470
490
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
});
|
|
491
|
+
type Ret = Result<
|
|
492
|
+
readonly string[],
|
|
493
|
+
ExecException | Readonly<{ message: string }>
|
|
494
|
+
>;
|
|
476
495
|
```
|
|
477
496
|
|
|
478
497
|
#### Build Optimization Utilities
|
|
@@ -483,15 +502,19 @@ Checks whether TypeScript type checks should run based on file changes from the
|
|
|
483
502
|
(Function version of the `check-should-run-type-checks` command)
|
|
484
503
|
|
|
485
504
|
```tsx
|
|
486
|
-
import {
|
|
505
|
+
import { $, checkShouldRunTypeChecks } from 'ts-repo-utils';
|
|
487
506
|
|
|
488
|
-
//
|
|
489
|
-
await
|
|
507
|
+
// Use default settings (compare against origin/main)
|
|
508
|
+
const shouldRun = await checkShouldRunTypeChecks();
|
|
490
509
|
|
|
491
|
-
|
|
492
|
-
await
|
|
493
|
-
|
|
494
|
-
|
|
510
|
+
if (shouldRun) {
|
|
511
|
+
await $('npm run type-check');
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Custom ignore patterns and base branch
|
|
515
|
+
const shouldRun2 = await checkShouldRunTypeChecks({
|
|
516
|
+
pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
|
|
517
|
+
baseBranch: 'origin/develop',
|
|
495
518
|
});
|
|
496
519
|
```
|
|
497
520
|
|
|
@@ -511,14 +534,19 @@ await formatUncommittedFiles({
|
|
|
511
534
|
Formats files matching a glob pattern using Prettier.
|
|
512
535
|
|
|
513
536
|
```tsx
|
|
514
|
-
import {
|
|
537
|
+
import { formatFilesGlob } from 'ts-repo-utils';
|
|
515
538
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
539
|
+
// Format all TypeScript files in src
|
|
540
|
+
await formatFilesGlob('src/**/*.ts');
|
|
541
|
+
|
|
542
|
+
// Format specific files
|
|
543
|
+
await formatFilesGlob('src/{index,utils}.ts');
|
|
544
|
+
|
|
545
|
+
// With custom ignore function
|
|
546
|
+
await formatFilesGlob('src/**/*.ts', {
|
|
547
|
+
ignore: (filePath) => filePath.includes('generated'),
|
|
548
|
+
ignoreUnknown: false, // Error on files without parser
|
|
549
|
+
});
|
|
522
550
|
```
|
|
523
551
|
|
|
524
552
|
**Options:**
|
|
@@ -533,19 +561,15 @@ Formats only files that have been changed according to git status.
|
|
|
533
561
|
(Function version of the `format-uncommitted` command)
|
|
534
562
|
|
|
535
563
|
```tsx
|
|
536
|
-
import {
|
|
537
|
-
|
|
538
|
-
// Format files different from main branch
|
|
539
|
-
await formatDiffFrom('main');
|
|
564
|
+
import { formatUncommittedFiles } from 'ts-repo-utils';
|
|
540
565
|
|
|
541
|
-
// Format
|
|
542
|
-
await
|
|
566
|
+
// Format only modified files
|
|
567
|
+
await formatUncommittedFiles();
|
|
543
568
|
|
|
544
569
|
// With custom options
|
|
545
|
-
await
|
|
546
|
-
|
|
547
|
-
ignore: (filePath) => filePath.includes('
|
|
548
|
-
ignoreUnknown: false, // Error on files without parser
|
|
570
|
+
await formatUncommittedFiles({
|
|
571
|
+
untracked: false, // Skip untracked files
|
|
572
|
+
ignore: (filePath) => filePath.includes('test'),
|
|
549
573
|
});
|
|
550
574
|
```
|
|
551
575
|
|
|
@@ -577,11 +601,19 @@ Formats only files that differ from the specified base branch or commit.
|
|
|
577
601
|
(Function version of the `format-diff-from` command)
|
|
578
602
|
|
|
579
603
|
```tsx
|
|
580
|
-
import {
|
|
604
|
+
import { formatDiffFrom } from 'ts-repo-utils';
|
|
581
605
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
606
|
+
// Format files different from main branch
|
|
607
|
+
await formatDiffFrom('main');
|
|
608
|
+
|
|
609
|
+
// Format files different from specific commit
|
|
610
|
+
await formatDiffFrom('abc123');
|
|
611
|
+
|
|
612
|
+
// With custom options
|
|
613
|
+
await formatDiffFrom('main', {
|
|
614
|
+
includeUntracked: false,
|
|
615
|
+
ignore: (filePath) => filePath.includes('vendor'),
|
|
616
|
+
ignoreUnknown: false, // Error on files without parser
|
|
585
617
|
});
|
|
586
618
|
```
|
|
587
619
|
|
|
@@ -596,6 +628,35 @@ await genIndex({
|
|
|
596
628
|
|
|
597
629
|
**Return Type:**
|
|
598
630
|
|
|
631
|
+
```tsx
|
|
632
|
+
import { type ExecException } from 'node:child_process';
|
|
633
|
+
|
|
634
|
+
type Ret = Promise<
|
|
635
|
+
Result<
|
|
636
|
+
undefined,
|
|
637
|
+
ExecException | Readonly<{ message: string }> | readonly unknown[]
|
|
638
|
+
>
|
|
639
|
+
>;
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Index File Generation
|
|
643
|
+
|
|
644
|
+
#### `genIndex(config: GenIndexConfig): Promise<Result<undefined, unknown>>`
|
|
645
|
+
|
|
646
|
+
Generates index files recursively in target directories with automatic barrel exports.
|
|
647
|
+
(Function version of the `gen-index-ts` command)
|
|
648
|
+
|
|
649
|
+
```tsx
|
|
650
|
+
import { genIndex } from 'ts-repo-utils';
|
|
651
|
+
|
|
652
|
+
await genIndex({
|
|
653
|
+
targetDirectory: './src',
|
|
654
|
+
exclude: ['*.test.ts', '*.spec.ts'],
|
|
655
|
+
});
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Configuration Type:**
|
|
659
|
+
|
|
599
660
|
```tsx
|
|
600
661
|
type GenIndexConfig = Readonly<{
|
|
601
662
|
/** Target directories to generate index files for (string or array of strings) */
|
|
@@ -636,39 +697,6 @@ type GenIndexConfig = Readonly<{
|
|
|
636
697
|
}>;
|
|
637
698
|
```
|
|
638
699
|
|
|
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
700
|
**Features:**
|
|
673
701
|
|
|
674
702
|
- Creates barrel exports for all subdirectories
|
|
@@ -689,12 +717,15 @@ await runCmdInParallelAcrossWorkspaces({
|
|
|
689
717
|
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
718
|
|
|
691
719
|
```tsx
|
|
692
|
-
import {
|
|
693
|
-
|
|
694
|
-
const packages = await getWorkspacePackages('.');
|
|
720
|
+
import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
|
|
695
721
|
|
|
696
|
-
|
|
697
|
-
|
|
722
|
+
// Run build in dependency order
|
|
723
|
+
await runCmdInStagesAcrossWorkspaces({
|
|
724
|
+
rootPackageJsonDir: '../',
|
|
725
|
+
cmd: 'build',
|
|
726
|
+
concurrency: 3,
|
|
727
|
+
filterWorkspacePattern: (name) => !name.includes('experimental'),
|
|
728
|
+
});
|
|
698
729
|
```
|
|
699
730
|
|
|
700
731
|
**Options:**
|
|
@@ -709,12 +740,15 @@ console.log(packages.map((pkg) => pkg.name));
|
|
|
709
740
|
Executes an npm script command across all workspace packages in parallel. Uses fail-fast behavior - stops execution immediately when any package fails.
|
|
710
741
|
|
|
711
742
|
```tsx
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
743
|
+
import { runCmdInParallelAcrossWorkspaces } from 'ts-repo-utils';
|
|
744
|
+
|
|
745
|
+
// Run tests in parallel across all packages
|
|
746
|
+
await runCmdInParallelAcrossWorkspaces({
|
|
747
|
+
rootPackageJsonDir: '../',
|
|
748
|
+
cmd: 'test',
|
|
749
|
+
concurrency: 5,
|
|
750
|
+
filterWorkspacePattern: (name) => !name.includes('experimental'),
|
|
751
|
+
});
|
|
718
752
|
```
|
|
719
753
|
|
|
720
754
|
**Options:**
|
|
@@ -729,21 +763,23 @@ type Package = Readonly<{
|
|
|
729
763
|
Retrieves all workspace packages from a monorepo based on the workspace patterns defined in the root package.json file.
|
|
730
764
|
|
|
731
765
|
```tsx
|
|
732
|
-
import {
|
|
766
|
+
import { getWorkspacePackages } from 'ts-repo-utils';
|
|
733
767
|
|
|
734
768
|
const packages = await getWorkspacePackages('.');
|
|
735
769
|
|
|
736
|
-
|
|
770
|
+
console.log(packages.map((pkg) => pkg.name));
|
|
771
|
+
// ['@myorg/package-a', '@myorg/package-b', ...]
|
|
737
772
|
```
|
|
738
773
|
|
|
739
774
|
**Return Type:**
|
|
740
775
|
|
|
741
776
|
```tsx
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
777
|
+
type Package = Readonly<{
|
|
778
|
+
name: string;
|
|
779
|
+
path: string;
|
|
780
|
+
packageJson: JsonValue;
|
|
781
|
+
dependencies: Readonly<Record<string, string>>;
|
|
782
|
+
}>;
|
|
747
783
|
```
|
|
748
784
|
|
|
749
785
|
#### `executeParallel(packages, scriptName, concurrency?): Promise<readonly Result[]>`
|
|
@@ -751,31 +787,11 @@ await executeStages(packages, 'build', 3);
|
|
|
751
787
|
Executes an npm script across multiple packages in parallel with a concurrency limit. Lower-level function used by `runCmdInParallelAcrossWorkspaces`.
|
|
752
788
|
|
|
753
789
|
```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();
|
|
790
|
+
import { executeParallel, getWorkspacePackages } from 'ts-repo-utils';
|
|
773
791
|
|
|
774
|
-
const
|
|
792
|
+
const packages = await getWorkspacePackages('.');
|
|
775
793
|
|
|
776
|
-
|
|
777
|
-
echo('Running as CLI');
|
|
778
|
-
}
|
|
794
|
+
await executeParallel(packages, 'lint', 4);
|
|
779
795
|
```
|
|
780
796
|
|
|
781
797
|
#### `executeStages(packages, scriptName, concurrency?): Promise<void>`
|
|
@@ -783,22 +799,11 @@ if (isDirectlyExecuted(import.meta.url)) {
|
|
|
783
799
|
Executes an npm script across packages in dependency order stages. Lower-level function used by `runCmdInStagesAcrossWorkspaces`.
|
|
784
800
|
|
|
785
801
|
```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
|
-
});
|
|
802
|
+
import { executeStages, getWorkspacePackages } from 'ts-repo-utils';
|
|
796
803
|
|
|
797
|
-
|
|
798
|
-
await formatUncommittedFiles();
|
|
804
|
+
const packages = await getWorkspacePackages('.');
|
|
799
805
|
|
|
800
|
-
|
|
801
|
-
await assertRepoIsClean();
|
|
806
|
+
await executeStages(packages, 'build', 3);
|
|
802
807
|
```
|
|
803
808
|
|
|
804
809
|
**Features:**
|
|
@@ -809,64 +814,33 @@ await assertRepoIsClean();
|
|
|
809
814
|
- Fail-fast behavior on errors
|
|
810
815
|
- Circular dependency detection
|
|
811
816
|
|
|
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
817
|
## Common Patterns
|
|
843
818
|
|
|
844
819
|
### Pre-commit Hook
|
|
845
820
|
|
|
846
821
|
```tsx
|
|
847
|
-
import {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
await assertPathExists('./tsconfig.json', 'TypeScript config');
|
|
822
|
+
import {
|
|
823
|
+
assertExt,
|
|
824
|
+
assertRepoIsClean,
|
|
825
|
+
formatUncommittedFiles,
|
|
826
|
+
} from 'ts-repo-utils';
|
|
853
827
|
|
|
854
|
-
// Validate extensions
|
|
828
|
+
// Validate file extensions
|
|
855
829
|
await assertExt({
|
|
856
|
-
directories: [
|
|
857
|
-
{ path: './src', extension: '.ts' },
|
|
858
|
-
{ path: './scripts', extension: '.mjs' },
|
|
859
|
-
],
|
|
830
|
+
directories: [{ path: './src', extension: '.ts' }],
|
|
860
831
|
});
|
|
861
832
|
|
|
862
|
-
//
|
|
833
|
+
// Format changed files
|
|
834
|
+
await formatUncommittedFiles();
|
|
835
|
+
|
|
836
|
+
// Ensure repository is clean (exits if dirty)
|
|
863
837
|
await assertRepoIsClean();
|
|
864
838
|
```
|
|
865
839
|
|
|
866
840
|
### Build Pipeline
|
|
867
841
|
|
|
868
842
|
```tsx
|
|
869
|
-
import { formatFilesGlob, genIndex } from 'ts-repo-utils';
|
|
843
|
+
import { $, formatFilesGlob, genIndex } from 'ts-repo-utils';
|
|
870
844
|
|
|
871
845
|
// Generate barrel exports
|
|
872
846
|
await genIndex({ targetDirectory: './src' });
|
|
@@ -888,6 +862,7 @@ import { assertExt, assertPathExists, assertRepoIsClean } from 'ts-repo-utils';
|
|
|
888
862
|
|
|
889
863
|
// Check required files exist (exits with code 1 if files don't exist)
|
|
890
864
|
await assertPathExists('./package.json', 'Package manifest');
|
|
865
|
+
|
|
891
866
|
await assertPathExists('./tsconfig.json', 'TypeScript config');
|
|
892
867
|
|
|
893
868
|
// 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 '
|
|
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: '
|
|
17
|
+
version: '10.0.0',
|
|
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,
|
|
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 '
|
|
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: '
|
|
17
|
+
version: '10.0.0',
|
|
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,
|
|
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"}
|