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.
- package/README.md +195 -214
- 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 +3 -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 +1 -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 +1 -1
- package/dist/functions/diff.d.mts.map +1 -1
- package/dist/functions/diff.mjs +1 -1
- package/dist/functions/exec-async.d.mts +1 -0
- package/dist/functions/exec-async.d.mts.map +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 +1 -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 +2 -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.d.mts +2 -0
- package/dist/functions/glob.d.mts.map +1 -1
- package/dist/functions/glob.mjs +1 -1
- package/dist/functions/glob.mjs.map +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/functions/workspace-utils/types.d.mts +1 -0
- package/dist/functions/workspace-utils/types.d.mts.map +1 -1
- package/dist/types.d.mts +1 -2
- package/package.json +23 -23
- 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 +2 -1
- package/src/functions/assert-ext.mts +7 -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 +10 -3
- package/src/functions/glob.mts +2 -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 +6 -1
- package/src/functions/workspace-utils/run-cmd-in-stages.test.mts +0 -1
- package/src/functions/workspace-utils/types.mts +2 -0
- 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)) {
|
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
395
|
+
return Promise.resolve(Result.ok({ port: parsed.port, host: parsed.host }));
|
|
396
|
+
};
|
|
366
397
|
|
|
367
|
-
|
|
368
|
-
|
|
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 {
|
|
420
|
+
import { makeEmptyDir } from 'ts-repo-utils';
|
|
385
421
|
|
|
386
|
-
//
|
|
387
|
-
await
|
|
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 {
|
|
435
|
+
import { repoIsDirty } from 'ts-repo-utils';
|
|
400
436
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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 {
|
|
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
|
-
//
|
|
423
|
-
|
|
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 {
|
|
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
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
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 {
|
|
507
|
+
import { $, checkShouldRunTypeChecks } from 'ts-repo-utils';
|
|
487
508
|
|
|
488
|
-
//
|
|
489
|
-
await
|
|
509
|
+
// Use default settings (compare against origin/main)
|
|
510
|
+
const shouldRun = await checkShouldRunTypeChecks();
|
|
490
511
|
|
|
491
|
-
|
|
492
|
-
await
|
|
493
|
-
|
|
494
|
-
|
|
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 {
|
|
539
|
+
import { formatFilesGlob } from 'ts-repo-utils';
|
|
515
540
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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 {
|
|
537
|
-
|
|
538
|
-
// Format files different from main branch
|
|
539
|
-
await formatDiffFrom('main');
|
|
566
|
+
import { formatUncommittedFiles } from 'ts-repo-utils';
|
|
540
567
|
|
|
541
|
-
// Format
|
|
542
|
-
await
|
|
568
|
+
// Format only modified files
|
|
569
|
+
await formatUncommittedFiles();
|
|
543
570
|
|
|
544
571
|
// With custom options
|
|
545
|
-
await
|
|
546
|
-
|
|
547
|
-
ignore: (filePath) => filePath.includes('
|
|
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 {
|
|
607
|
+
import { formatDiffFrom } from 'ts-repo-utils';
|
|
581
608
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
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 {
|
|
693
|
-
|
|
694
|
-
const packages = await getWorkspacePackages('.');
|
|
724
|
+
import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
|
|
695
725
|
|
|
696
|
-
|
|
697
|
-
|
|
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
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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 {
|
|
770
|
+
import { getWorkspacePackages } from 'ts-repo-utils';
|
|
733
771
|
|
|
734
772
|
const packages = await getWorkspacePackages('.');
|
|
735
773
|
|
|
736
|
-
|
|
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 {
|
|
781
|
+
import { type JsonValue } from 'ts-type-forge';
|
|
743
782
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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
|
|
798
|
+
const packages = await getWorkspacePackages('.');
|
|
775
799
|
|
|
776
|
-
|
|
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
|
-
|
|
798
|
-
await formatUncommittedFiles();
|
|
810
|
+
const packages = await getWorkspacePackages('.');
|
|
799
811
|
|
|
800
|
-
|
|
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 {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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
|
-
//
|
|
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 '
|
|
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.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,
|
|
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.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,
|
|
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"}
|