ts-repo-utils 9.0.0 → 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 +194 -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 +28 -28
- 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
|
@@ -130,6 +130,9 @@ npm exec -- gen-index-ts ./src --target-ext .mts --target-ext .tsx --index-ext .
|
|
|
130
130
|
# With exclude patterns
|
|
131
131
|
npm exec -- gen-index-ts ./src --target-ext .ts --index-ext .ts --export-ext .js --exclude '*.test.ts' --exclude '*.spec.ts'
|
|
132
132
|
|
|
133
|
+
# Skip generating index files at the root level (depth 0), only generate from depth 1 onwards
|
|
134
|
+
npm exec -- gen-index-ts ./src --target-ext .mts --index-ext .mts --export-ext .mjs --min-depth 1
|
|
135
|
+
|
|
133
136
|
# Example in npm scripts
|
|
134
137
|
"gi": "gen-index-ts ./src --index-ext .mts --export-ext .mjs --target-ext .mts --target-ext .tsx --fmt 'npm run fmt'"
|
|
135
138
|
```
|
|
@@ -155,6 +158,7 @@ npm exec -- gen-index-ts ./src --target-ext .ts --index-ext .ts --export-ext .js
|
|
|
155
158
|
- `--export-ext` - Extension of the export statements in the index file (required, or 'none')
|
|
156
159
|
- `--exclude` - Glob patterns of files to exclude (optional, can be specified multiple times)
|
|
157
160
|
- `--fmt` - Command to format after generating the index file (optional)
|
|
161
|
+
- `--min-depth` - Minimum depth to start generating index files (default: 0)
|
|
158
162
|
- `--silent` - Suppress output messages (optional)
|
|
159
163
|
|
|
160
164
|
### `check-should-run-type-checks`
|
|
@@ -211,9 +215,6 @@ Executes a shell command asynchronously with type-safe results.
|
|
|
211
215
|
```tsx
|
|
212
216
|
import { $, Result } from 'ts-repo-utils';
|
|
213
217
|
|
|
214
|
-
// or
|
|
215
|
-
// import "ts-repo-utils"; // $ and Result are globally defined in ts-repo-utils
|
|
216
|
-
|
|
217
218
|
const result = await $('npm test');
|
|
218
219
|
|
|
219
220
|
if (Result.isOk(result)) {
|
|
@@ -250,9 +251,6 @@ Determines whether a script is being executed directly via CLI or imported as a
|
|
|
250
251
|
```tsx
|
|
251
252
|
import { isDirectlyExecuted } from 'ts-repo-utils';
|
|
252
253
|
|
|
253
|
-
// or
|
|
254
|
-
// import "ts-repo-utils"; // isDirectlyExecuted is globally defined in ts-repo-utils
|
|
255
|
-
|
|
256
254
|
// calculator.mjs
|
|
257
255
|
export const add = (a: number, b: number): number => a + b;
|
|
258
256
|
|
|
@@ -308,6 +306,28 @@ await assertPathExists('./src/index.ts', 'Entry point file');
|
|
|
308
306
|
|
|
309
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.
|
|
310
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
|
+
|
|
311
331
|
```tsx
|
|
312
332
|
import { assertExt } from 'ts-repo-utils';
|
|
313
333
|
|
|
@@ -326,9 +346,7 @@ await assertExt({
|
|
|
326
346
|
});
|
|
327
347
|
```
|
|
328
348
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
Validates that all files in specified directories have the correct extensions. Exits with code 1 if any files have incorrect extensions.
|
|
349
|
+
**Configuration Type:**
|
|
332
350
|
|
|
333
351
|
```tsx
|
|
334
352
|
type CheckExtConfig = Readonly<{
|
|
@@ -340,15 +358,6 @@ type CheckExtConfig = Readonly<{
|
|
|
340
358
|
}>;
|
|
341
359
|
```
|
|
342
360
|
|
|
343
|
-
**Configuration Type:**
|
|
344
|
-
|
|
345
|
-
```tsx
|
|
346
|
-
import { makeEmptyDir } from 'ts-repo-utils';
|
|
347
|
-
|
|
348
|
-
// Reset ./tmp/build before writing artifacts
|
|
349
|
-
await makeEmptyDir('./tmp/build');
|
|
350
|
-
```
|
|
351
|
-
|
|
352
361
|
### Result Utilities
|
|
353
362
|
|
|
354
363
|
#### `createResultAssert(options): (config) => Promise<TOk>`
|
|
@@ -356,13 +365,43 @@ await makeEmptyDir('./tmp/build');
|
|
|
356
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.
|
|
357
366
|
|
|
358
367
|
```tsx
|
|
359
|
-
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
|
+
}
|
|
360
393
|
|
|
361
|
-
|
|
394
|
+
return Promise.resolve(Result.ok({ port: parsed.port, host: parsed.host }));
|
|
395
|
+
};
|
|
362
396
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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"}');
|
|
366
405
|
```
|
|
367
406
|
|
|
368
407
|
**Options:**
|
|
@@ -377,10 +416,10 @@ if (isDirty) {
|
|
|
377
416
|
Removes any existing directory at `dir` and recreates it, ensuring a clean target for generated assets or build output.
|
|
378
417
|
|
|
379
418
|
```tsx
|
|
380
|
-
import {
|
|
419
|
+
import { makeEmptyDir } from 'ts-repo-utils';
|
|
381
420
|
|
|
382
|
-
//
|
|
383
|
-
await
|
|
421
|
+
// Reset ./tmp/build before writing artifacts
|
|
422
|
+
await makeEmptyDir('./tmp/build');
|
|
384
423
|
```
|
|
385
424
|
|
|
386
425
|
This helper uses `fs.rm` with `recursive` cleanup before calling `fs.mkdir`, so prefer it over manual `rimraf` + `mkdir` sequences when scripting workflows.
|
|
@@ -392,12 +431,13 @@ This helper uses `fs.rm` with `recursive` cleanup before calling `fs.mkdir`, so
|
|
|
392
431
|
Checks if the repository has uncommitted changes.
|
|
393
432
|
|
|
394
433
|
```tsx
|
|
395
|
-
import {
|
|
434
|
+
import { repoIsDirty } from 'ts-repo-utils';
|
|
396
435
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
436
|
+
const isDirty = await repoIsDirty();
|
|
437
|
+
|
|
438
|
+
if (isDirty) {
|
|
439
|
+
console.log('Repository has uncommitted changes');
|
|
440
|
+
}
|
|
401
441
|
```
|
|
402
442
|
|
|
403
443
|
#### `assertRepoIsClean(): Promise<void>`
|
|
@@ -406,20 +446,10 @@ Checks if the repository is clean and exits with code 1 if it has uncommitted ch
|
|
|
406
446
|
(Function version of the `assert-repo-is-clean` command)
|
|
407
447
|
|
|
408
448
|
```tsx
|
|
409
|
-
import {
|
|
410
|
-
|
|
411
|
-
// Use default settings (compare against origin/main)
|
|
412
|
-
const shouldRun = await checkShouldRunTypeChecks();
|
|
413
|
-
|
|
414
|
-
if (shouldRun) {
|
|
415
|
-
await $('npm run type-check');
|
|
416
|
-
}
|
|
449
|
+
import { assertRepoIsClean } from 'ts-repo-utils';
|
|
417
450
|
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
|
|
421
|
-
baseBranch: 'origin/develop',
|
|
422
|
-
});
|
|
451
|
+
// Use in CI/build scripts to ensure clean state
|
|
452
|
+
await assertRepoIsClean();
|
|
423
453
|
```
|
|
424
454
|
|
|
425
455
|
**Options:**
|
|
@@ -456,19 +486,12 @@ Runs `git diff --name-only <base> [--diff-filter=d]`
|
|
|
456
486
|
**Common Return Type:**
|
|
457
487
|
|
|
458
488
|
```tsx
|
|
459
|
-
import {
|
|
460
|
-
|
|
461
|
-
// Format all TypeScript files in src
|
|
462
|
-
await formatFilesGlob('src/**/*.ts');
|
|
463
|
-
|
|
464
|
-
// Format specific files
|
|
465
|
-
await formatFilesGlob('src/{index,utils}.ts');
|
|
489
|
+
import { type ExecException } from 'node:child_process';
|
|
466
490
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
});
|
|
491
|
+
type Ret = Result<
|
|
492
|
+
readonly string[],
|
|
493
|
+
ExecException | Readonly<{ message: string }>
|
|
494
|
+
>;
|
|
472
495
|
```
|
|
473
496
|
|
|
474
497
|
#### Build Optimization Utilities
|
|
@@ -479,15 +502,19 @@ Checks whether TypeScript type checks should run based on file changes from the
|
|
|
479
502
|
(Function version of the `check-should-run-type-checks` command)
|
|
480
503
|
|
|
481
504
|
```tsx
|
|
482
|
-
import {
|
|
505
|
+
import { $, checkShouldRunTypeChecks } from 'ts-repo-utils';
|
|
483
506
|
|
|
484
|
-
//
|
|
485
|
-
await
|
|
507
|
+
// Use default settings (compare against origin/main)
|
|
508
|
+
const shouldRun = await checkShouldRunTypeChecks();
|
|
486
509
|
|
|
487
|
-
|
|
488
|
-
await
|
|
489
|
-
|
|
490
|
-
|
|
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',
|
|
491
518
|
});
|
|
492
519
|
```
|
|
493
520
|
|
|
@@ -507,14 +534,19 @@ await formatUncommittedFiles({
|
|
|
507
534
|
Formats files matching a glob pattern using Prettier.
|
|
508
535
|
|
|
509
536
|
```tsx
|
|
510
|
-
import {
|
|
537
|
+
import { formatFilesGlob } from 'ts-repo-utils';
|
|
511
538
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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
|
+
});
|
|
518
550
|
```
|
|
519
551
|
|
|
520
552
|
**Options:**
|
|
@@ -529,19 +561,15 @@ Formats only files that have been changed according to git status.
|
|
|
529
561
|
(Function version of the `format-uncommitted` command)
|
|
530
562
|
|
|
531
563
|
```tsx
|
|
532
|
-
import {
|
|
533
|
-
|
|
534
|
-
// Format files different from main branch
|
|
535
|
-
await formatDiffFrom('main');
|
|
564
|
+
import { formatUncommittedFiles } from 'ts-repo-utils';
|
|
536
565
|
|
|
537
|
-
// Format
|
|
538
|
-
await
|
|
566
|
+
// Format only modified files
|
|
567
|
+
await formatUncommittedFiles();
|
|
539
568
|
|
|
540
569
|
// With custom options
|
|
541
|
-
await
|
|
542
|
-
|
|
543
|
-
ignore: (filePath) => filePath.includes('
|
|
544
|
-
ignoreUnknown: false, // Error on files without parser
|
|
570
|
+
await formatUncommittedFiles({
|
|
571
|
+
untracked: false, // Skip untracked files
|
|
572
|
+
ignore: (filePath) => filePath.includes('test'),
|
|
545
573
|
});
|
|
546
574
|
```
|
|
547
575
|
|
|
@@ -573,11 +601,19 @@ Formats only files that differ from the specified base branch or commit.
|
|
|
573
601
|
(Function version of the `format-diff-from` command)
|
|
574
602
|
|
|
575
603
|
```tsx
|
|
576
|
-
import {
|
|
604
|
+
import { formatDiffFrom } from 'ts-repo-utils';
|
|
577
605
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
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
|
|
581
617
|
});
|
|
582
618
|
```
|
|
583
619
|
|
|
@@ -592,6 +628,35 @@ await genIndex({
|
|
|
592
628
|
|
|
593
629
|
**Return Type:**
|
|
594
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
|
+
|
|
595
660
|
```tsx
|
|
596
661
|
type GenIndexConfig = Readonly<{
|
|
597
662
|
/** Target directories to generate index files for (string or array of strings) */
|
|
@@ -632,39 +697,6 @@ type GenIndexConfig = Readonly<{
|
|
|
632
697
|
}>;
|
|
633
698
|
```
|
|
634
699
|
|
|
635
|
-
### Index File Generation
|
|
636
|
-
|
|
637
|
-
#### `genIndex(config: GenIndexConfig): Promise<Result<undefined, unknown>>`
|
|
638
|
-
|
|
639
|
-
Generates index files recursively in target directories with automatic barrel exports.
|
|
640
|
-
(Function version of the `gen-index-ts` command)
|
|
641
|
-
|
|
642
|
-
```tsx
|
|
643
|
-
import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
|
|
644
|
-
|
|
645
|
-
// Run build in dependency order
|
|
646
|
-
await runCmdInStagesAcrossWorkspaces({
|
|
647
|
-
rootPackageJsonDir: '../',
|
|
648
|
-
cmd: 'build',
|
|
649
|
-
concurrency: 3,
|
|
650
|
-
filterWorkspacePattern: (name) => !name.includes('experimental'),
|
|
651
|
-
});
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
**Configuration Type:**
|
|
655
|
-
|
|
656
|
-
```tsx
|
|
657
|
-
import { runCmdInParallelAcrossWorkspaces } from 'ts-repo-utils';
|
|
658
|
-
|
|
659
|
-
// Run tests in parallel across all packages
|
|
660
|
-
await runCmdInParallelAcrossWorkspaces({
|
|
661
|
-
rootPackageJsonDir: '../',
|
|
662
|
-
cmd: 'test',
|
|
663
|
-
concurrency: 5,
|
|
664
|
-
filterWorkspacePattern: (name) => !name.includes('experimental'),
|
|
665
|
-
});
|
|
666
|
-
```
|
|
667
|
-
|
|
668
700
|
**Features:**
|
|
669
701
|
|
|
670
702
|
- Creates barrel exports for all subdirectories
|
|
@@ -685,12 +717,15 @@ await runCmdInParallelAcrossWorkspaces({
|
|
|
685
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.
|
|
686
718
|
|
|
687
719
|
```tsx
|
|
688
|
-
import {
|
|
689
|
-
|
|
690
|
-
const packages = await getWorkspacePackages('.');
|
|
720
|
+
import { runCmdInStagesAcrossWorkspaces } from 'ts-repo-utils';
|
|
691
721
|
|
|
692
|
-
|
|
693
|
-
|
|
722
|
+
// Run build in dependency order
|
|
723
|
+
await runCmdInStagesAcrossWorkspaces({
|
|
724
|
+
rootPackageJsonDir: '../',
|
|
725
|
+
cmd: 'build',
|
|
726
|
+
concurrency: 3,
|
|
727
|
+
filterWorkspacePattern: (name) => !name.includes('experimental'),
|
|
728
|
+
});
|
|
694
729
|
```
|
|
695
730
|
|
|
696
731
|
**Options:**
|
|
@@ -705,12 +740,15 @@ console.log(packages.map((pkg) => pkg.name));
|
|
|
705
740
|
Executes an npm script command across all workspace packages in parallel. Uses fail-fast behavior - stops execution immediately when any package fails.
|
|
706
741
|
|
|
707
742
|
```tsx
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
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
|
+
});
|
|
714
752
|
```
|
|
715
753
|
|
|
716
754
|
**Options:**
|
|
@@ -725,21 +763,23 @@ type Package = Readonly<{
|
|
|
725
763
|
Retrieves all workspace packages from a monorepo based on the workspace patterns defined in the root package.json file.
|
|
726
764
|
|
|
727
765
|
```tsx
|
|
728
|
-
import {
|
|
766
|
+
import { getWorkspacePackages } from 'ts-repo-utils';
|
|
729
767
|
|
|
730
768
|
const packages = await getWorkspacePackages('.');
|
|
731
769
|
|
|
732
|
-
|
|
770
|
+
console.log(packages.map((pkg) => pkg.name));
|
|
771
|
+
// ['@myorg/package-a', '@myorg/package-b', ...]
|
|
733
772
|
```
|
|
734
773
|
|
|
735
774
|
**Return Type:**
|
|
736
775
|
|
|
737
776
|
```tsx
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
777
|
+
type Package = Readonly<{
|
|
778
|
+
name: string;
|
|
779
|
+
path: string;
|
|
780
|
+
packageJson: JsonValue;
|
|
781
|
+
dependencies: Readonly<Record<string, string>>;
|
|
782
|
+
}>;
|
|
743
783
|
```
|
|
744
784
|
|
|
745
785
|
#### `executeParallel(packages, scriptName, concurrency?): Promise<readonly Result[]>`
|
|
@@ -747,31 +787,11 @@ await executeStages(packages, 'build', 3);
|
|
|
747
787
|
Executes an npm script across multiple packages in parallel with a concurrency limit. Lower-level function used by `runCmdInParallelAcrossWorkspaces`.
|
|
748
788
|
|
|
749
789
|
```tsx
|
|
750
|
-
import 'ts-repo-utils';
|
|
751
|
-
|
|
752
|
-
// Now these functions are globally available
|
|
753
|
-
|
|
754
|
-
const result = await $('npm test');
|
|
755
|
-
|
|
756
|
-
if (Result.isErr(result)) {
|
|
757
|
-
console.error(result.value);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
echo('Building project...');
|
|
761
|
-
|
|
762
|
-
const filePath: string = path.join('src', 'index.ts');
|
|
763
|
-
|
|
764
|
-
const configJson: string = await fs.readFile('./config.json', {
|
|
765
|
-
encoding: 'utf8',
|
|
766
|
-
});
|
|
767
|
-
|
|
768
|
-
const home = os.homedir();
|
|
790
|
+
import { executeParallel, getWorkspacePackages } from 'ts-repo-utils';
|
|
769
791
|
|
|
770
|
-
const
|
|
792
|
+
const packages = await getWorkspacePackages('.');
|
|
771
793
|
|
|
772
|
-
|
|
773
|
-
echo('Running as CLI');
|
|
774
|
-
}
|
|
794
|
+
await executeParallel(packages, 'lint', 4);
|
|
775
795
|
```
|
|
776
796
|
|
|
777
797
|
#### `executeStages(packages, scriptName, concurrency?): Promise<void>`
|
|
@@ -779,22 +799,11 @@ if (isDirectlyExecuted(import.meta.url)) {
|
|
|
779
799
|
Executes an npm script across packages in dependency order stages. Lower-level function used by `runCmdInStagesAcrossWorkspaces`.
|
|
780
800
|
|
|
781
801
|
```tsx
|
|
782
|
-
import {
|
|
783
|
-
assertExt,
|
|
784
|
-
assertRepoIsClean,
|
|
785
|
-
formatUncommittedFiles,
|
|
786
|
-
} from 'ts-repo-utils';
|
|
787
|
-
|
|
788
|
-
// Validate file extensions
|
|
789
|
-
await assertExt({
|
|
790
|
-
directories: [{ path: './src', extension: '.ts' }],
|
|
791
|
-
});
|
|
802
|
+
import { executeStages, getWorkspacePackages } from 'ts-repo-utils';
|
|
792
803
|
|
|
793
|
-
|
|
794
|
-
await formatUncommittedFiles();
|
|
804
|
+
const packages = await getWorkspacePackages('.');
|
|
795
805
|
|
|
796
|
-
|
|
797
|
-
await assertRepoIsClean();
|
|
806
|
+
await executeStages(packages, 'build', 3);
|
|
798
807
|
```
|
|
799
808
|
|
|
800
809
|
**Features:**
|
|
@@ -805,64 +814,33 @@ await assertRepoIsClean();
|
|
|
805
814
|
- Fail-fast behavior on errors
|
|
806
815
|
- Circular dependency detection
|
|
807
816
|
|
|
808
|
-
### Globals
|
|
809
|
-
|
|
810
|
-
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.
|
|
811
|
-
|
|
812
|
-
```tsx
|
|
813
|
-
import { formatFilesGlob, genIndex } from 'ts-repo-utils';
|
|
814
|
-
|
|
815
|
-
// Generate barrel exports
|
|
816
|
-
await genIndex({ targetDirectory: './src' });
|
|
817
|
-
|
|
818
|
-
// Type check
|
|
819
|
-
await $('tsc --noEmit');
|
|
820
|
-
|
|
821
|
-
// Build
|
|
822
|
-
await $('rollup -c');
|
|
823
|
-
|
|
824
|
-
// Format output
|
|
825
|
-
await formatFilesGlob('dist/**/*.js');
|
|
826
|
-
```
|
|
827
|
-
|
|
828
|
-
- `$` - The command execution utility described above.
|
|
829
|
-
- `Result` - A utility for Result pattern (from [ts-data-forge](https://github.com/noshiro-pf/ts-data-forge#readme))
|
|
830
|
-
- `echo` - Equivalent to `console.log`
|
|
831
|
-
- `cd` - Equivalent to `process.chdir`
|
|
832
|
-
- `path` - `node:path`
|
|
833
|
-
- `fs` - `node:fs/promises`
|
|
834
|
-
- `os` - `node:os`
|
|
835
|
-
- `glob` - `fast-glob`
|
|
836
|
-
- `isDirectlyExecuted` - The script execution utility described above.
|
|
837
|
-
|
|
838
817
|
## Common Patterns
|
|
839
818
|
|
|
840
819
|
### Pre-commit Hook
|
|
841
820
|
|
|
842
821
|
```tsx
|
|
843
|
-
import {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
await assertPathExists('./tsconfig.json', 'TypeScript config');
|
|
822
|
+
import {
|
|
823
|
+
assertExt,
|
|
824
|
+
assertRepoIsClean,
|
|
825
|
+
formatUncommittedFiles,
|
|
826
|
+
} from 'ts-repo-utils';
|
|
849
827
|
|
|
850
|
-
// Validate extensions
|
|
828
|
+
// Validate file extensions
|
|
851
829
|
await assertExt({
|
|
852
|
-
directories: [
|
|
853
|
-
{ path: './src', extension: '.ts' },
|
|
854
|
-
{ path: './scripts', extension: '.mjs' },
|
|
855
|
-
],
|
|
830
|
+
directories: [{ path: './src', extension: '.ts' }],
|
|
856
831
|
});
|
|
857
832
|
|
|
858
|
-
//
|
|
833
|
+
// Format changed files
|
|
834
|
+
await formatUncommittedFiles();
|
|
835
|
+
|
|
836
|
+
// Ensure repository is clean (exits if dirty)
|
|
859
837
|
await assertRepoIsClean();
|
|
860
838
|
```
|
|
861
839
|
|
|
862
840
|
### Build Pipeline
|
|
863
841
|
|
|
864
842
|
```tsx
|
|
865
|
-
import { formatFilesGlob, genIndex } from 'ts-repo-utils';
|
|
843
|
+
import { $, formatFilesGlob, genIndex } from 'ts-repo-utils';
|
|
866
844
|
|
|
867
845
|
// Generate barrel exports
|
|
868
846
|
await genIndex({ targetDirectory: './src' });
|
|
@@ -884,6 +862,7 @@ import { assertExt, assertPathExists, assertRepoIsClean } from 'ts-repo-utils';
|
|
|
884
862
|
|
|
885
863
|
// Check required files exist (exits with code 1 if files don't exist)
|
|
886
864
|
await assertPathExists('./package.json', 'Package manifest');
|
|
865
|
+
|
|
887
866
|
await assertPathExists('./tsconfig.json', 'TypeScript config');
|
|
888
867
|
|
|
889
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"}
|