ts-repo-utils 7.3.0 → 7.4.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 CHANGED
@@ -236,6 +236,39 @@ type Ret = Promise<
236
236
 
237
237
  ### Script Execution Utilities
238
238
 
239
+ #### `isDirectlyExecuted(fileUrl: string): boolean`
240
+
241
+ Determines whether a script is being executed directly via CLI or imported as a module. This is useful for creating scripts that can both be imported as libraries and executed directly.
242
+
243
+ ```typescript
244
+ import { isDirectlyExecuted } from 'ts-repo-utils';
245
+
246
+ // or
247
+ // import "ts-repo-utils"; // isDirectlyExecuted is globally defined in ts-repo-utils
248
+
249
+ // calculator.mjs
250
+ export const add = (a: number, b: number): number => a + b;
251
+ export const multiply = (a: number, b: number): number => a * b;
252
+
253
+ // Only run main logic when executed directly: node calculator.mjs (or tsx calculator.mts)
254
+ // When imported elsewhere, only the functions are available
255
+ if (isDirectlyExecuted(import.meta.url)) {
256
+ console.log('Calculator CLI');
257
+ console.log('2 + 3 =', add(2, 3));
258
+ console.log('4 × 5 =', multiply(4, 5));
259
+ }
260
+ ```
261
+
262
+ When executed directly (`node calculator.mjs`), it runs the main function and prints the results. When imported (`import { add } from './calculator.mjs'`), it only provides the functions without executing the main logic.
263
+
264
+ NOTE: If you use [tsx](https://www.npmjs.com/package/tsx) or [ts-node](https://www.npmjs.com/package/ts-node), run your scripts with the extension `.(m)ts` instead of `.(m)js` so that `isDirectlyExecuted` can correctly determine if the script is executed directly.
265
+
266
+ **Use Cases:**
267
+
268
+ - Creating CLI tools that can also be used as libraries
269
+ - Preventing automatic execution when a file is imported
270
+ - Running initialization code only during direct execution
271
+
239
272
  ### Path and File System Utilities
240
273
 
241
274
  #### `pathExists(filePath: string): Promise<boolean>`
@@ -361,6 +394,39 @@ type Ret = Result<
361
394
  >;
362
395
  ```
363
396
 
397
+ #### Build Optimization Utilities
398
+
399
+ ##### `checkShouldRunTypeChecks(options?): Promise<boolean>`
400
+
401
+ Checks whether TypeScript type checks should run based on file changes from the base branch. Optimizes CI/CD pipelines by skipping type checks when only non-TypeScript files have changed.
402
+ (Function version of the `check-should-run-type-checks` command)
403
+
404
+ ```typescript
405
+ import { checkShouldRunTypeChecks } from 'ts-repo-utils';
406
+
407
+ // Use default settings (compare against origin/main)
408
+ const shouldRun = await checkShouldRunTypeChecks();
409
+
410
+ if (shouldRun) {
411
+ await $('npm run type-check');
412
+ }
413
+
414
+ // Custom ignore patterns and base branch
415
+ const shouldRun2 = await checkShouldRunTypeChecks({
416
+ pathsIgnore: ['.eslintrc.json', 'docs/', '**.md', 'scripts/'],
417
+ baseBranch: 'origin/develop',
418
+ });
419
+ ```
420
+
421
+ **Options:**
422
+
423
+ - `pathsIgnore?` - Patterns to ignore when checking if type checks should run:
424
+ - Exact file matches: `.cspell.json`
425
+ - Directory prefixes: `docs/` (matches any file in docs directory)
426
+ - File extensions: `**.md` (matches any markdown file)
427
+ - Default: `['LICENSE', '.editorconfig', '.gitignore', '.cspell.json', '.markdownlint-cli2.mjs', '.npmignore', '.prettierignore', '.prettierrc', 'docs/', '**.md', '**.txt']`
428
+ - `baseBranch?` - Base branch to compare against (default: `origin/main`)
429
+
364
430
  ### Code Formatting Utilities
365
431
 
366
432
  #### `formatFilesGlob(pathGlob: string, options?): Promise<Result<undefined, unknown>>`
@@ -668,6 +734,10 @@ const configJson: string = await fs.readFile('./config.json', {
668
734
  });
669
735
 
670
736
  const files: readonly string[] = await glob('**/*.ts');
737
+
738
+ if (isDirectlyExecuted(import.meta.url)) {
739
+ echo('Running as CLI');
740
+ }
671
741
  ```
672
742
 
673
743
  - `$` - The command execution utility described above.
@@ -675,6 +745,7 @@ const files: readonly string[] = await glob('**/*.ts');
675
745
  - `path` - `node:path`
676
746
  - `fs` - `node:fs/promises`
677
747
  - `glob` - `fast-glob`
748
+ - `isDirectlyExecuted` - The script execution utility described above.
678
749
 
679
750
  ## Common Patterns
680
751
 
@@ -11,7 +11,7 @@ import 'child_process';
11
11
 
12
12
  const cmdDef = cmd.command({
13
13
  name: 'assert-repo-is-clean-cli',
14
- version: '7.3.0',
14
+ version: '7.4.0',
15
15
  args: {
16
16
  silent: cmd.flag({
17
17
  long: 'silent',
@@ -11,7 +11,7 @@ import 'child_process';
11
11
 
12
12
  const cmdDef = cmd.command({
13
13
  name: 'check-should-run-type-checks-cli',
14
- version: '7.3.0',
14
+ version: '7.4.0',
15
15
  args: {
16
16
  pathsIgnore: cmd.multioption({
17
17
  long: 'paths-ignore',
@@ -10,7 +10,7 @@ import 'child_process';
10
10
 
11
11
  const cmdDef = cmd.command({
12
12
  name: 'format-diff-from-cli',
13
- version: '7.3.0',
13
+ version: '7.4.0',
14
14
  args: {
15
15
  base: cmd.positional({
16
16
  type: cmd.string,
@@ -10,7 +10,7 @@ import 'child_process';
10
10
 
11
11
  const cmdDef = cmd.command({
12
12
  name: 'format-uncommitted-cli',
13
- version: '7.3.0',
13
+ version: '7.4.0',
14
14
  args: {
15
15
  excludeUntracked: cmd.flag({
16
16
  long: 'exclude-untracked',
@@ -29,7 +29,7 @@ const nonEmptyArray = (t, commandName) => cmd.extendType(cmd.array(t), {
29
29
  });
30
30
  const cmdDef = cmd.command({
31
31
  name: 'gen-index-ts-cli',
32
- version: '7.3.0',
32
+ version: '7.4.0',
33
33
  args: {
34
34
  // required args
35
35
  targetDirectory: cmd.positional({
@@ -56,5 +56,5 @@ import '../node-global.mjs';
56
56
  export declare const checkShouldRunTypeChecks: (options?: Readonly<{
57
57
  pathsIgnore?: readonly string[];
58
58
  baseBranch?: string;
59
- }>) => Promise<void>;
59
+ }>) => Promise<boolean>;
60
60
  //# sourceMappingURL=should-run.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"should-run.d.mts","sourceRoot":"","sources":["../../src/functions/should-run.mts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,QAAQ,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,KACD,OAAO,CAAC,IAAI,CAmDd,CAAC"}
1
+ {"version":3,"file":"should-run.d.mts","sourceRoot":"","sources":["../../src/functions/should-run.mts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,QAAQ,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,KACD,OAAO,CAAC,OAAO,CAqDjB,CAAC"}
@@ -96,6 +96,7 @@ const checkShouldRunTypeChecks = async (options) => {
96
96
  if (GITHUB_OUTPUT !== undefined) {
97
97
  await fs.appendFile(GITHUB_OUTPUT, `should_run=${shouldRunTsChecks}\n`);
98
98
  }
99
+ return shouldRunTsChecks;
99
100
  };
100
101
 
101
102
  export { checkShouldRunTypeChecks };
@@ -1 +1 @@
1
- {"version":3,"file":"should-run.mjs","sources":["../../src/functions/should-run.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;MACU,wBAAwB,GAAG,OACtC,OAGE,KACe;AACjB,IAAA,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI;QAC1C,SAAS;QACT,eAAe;QACf,YAAY;QACZ,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,iBAAiB;QACjB,aAAa;QACb,OAAO;QACP,OAAO;QACP,QAAQ;KACT;AAED,IAAA,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,aAAa;IAEvD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAElD,IAAA,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC;AAE3C,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,KAAK,CAAC;AACjD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;IAEA,MAAM,iBAAiB,GAAY,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,KACzD,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,KAAI;;AAE3B,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;AACrD,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChD;AAEA,QAAA,OAAO,KAAK;IACd,CAAC,CAAC,CACH;AAED,IAAA,IAAI,aAAa,KAAK,SAAS,EAAE;QAC/B,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,CAAA,WAAA,EAAc,iBAAiB,CAAA,EAAA,CAAI,CAAC;IACzE;AACF;;;;"}
1
+ {"version":3,"file":"should-run.mjs","sources":["../../src/functions/should-run.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;MACU,wBAAwB,GAAG,OACtC,OAGE,KACkB;AACpB,IAAA,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI;QAC1C,SAAS;QACT,eAAe;QACf,YAAY;QACZ,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,iBAAiB;QACjB,aAAa;QACb,OAAO;QACP,OAAO;QACP,QAAQ;KACT;AAED,IAAA,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,aAAa;IAEvD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAElD,IAAA,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC;AAE3C,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,KAAK,CAAC;AACjD,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;IAEA,MAAM,iBAAiB,GAAY,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,KACzD,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,KAAI;;AAE3B,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;AACrD,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChD;AAEA,QAAA,OAAO,KAAK;IACd,CAAC,CAAC,CACH;AAED,IAAA,IAAI,aAAa,KAAK,SAAS,EAAE;QAC/B,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,CAAA,WAAA,EAAc,iBAAiB,CAAA,EAAA,CAAI,CAAC;IACzE;AAEA,IAAA,OAAO,iBAAiB;AAC1B;;;;"}
@@ -2,11 +2,13 @@ import { default as glob_ } from 'fast-glob';
2
2
  import * as fs_ from 'node:fs/promises';
3
3
  import * as path_ from 'node:path';
4
4
  import { $ as $_ } from './functions/exec-async.mjs';
5
+ import { isDirectlyExecuted as isDirectlyExecuted_ } from './functions/is-directly-executed.mjs';
5
6
  declare global {
6
7
  const $: typeof $_;
7
8
  const echo: typeof console.log;
8
9
  const path: typeof path_;
9
10
  const fs: typeof fs_;
10
11
  const glob: typeof glob_;
12
+ const isDirectlyExecuted: typeof isDirectlyExecuted_;
11
13
  }
12
14
  //# sourceMappingURL=node-global.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-global.d.mts","sourceRoot":"","sources":["../src/node-global.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,MAAM,4BAA4B,CAAC;AAgBrD,OAAO,CAAC,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,IAAI,EAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IAE/B,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,EAAE,EAAE,OAAO,GAAG,CAAC;IACrB,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;CAE1B"}
1
+ {"version":3,"file":"node-global.d.mts","sourceRoot":"","sources":["../src/node-global.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,kBAAkB,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAejG,OAAO,CAAC,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,IAAI,EAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IAE/B,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,EAAE,EAAE,OAAO,GAAG,CAAC;IACrB,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,kBAAkB,EAAE,OAAO,mBAAmB,CAAC;CACtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-repo-utils",
3
- "version": "7.3.0",
3
+ "version": "7.4.0",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "typescript"
@@ -5,7 +5,7 @@ import { assertRepoIsClean } from '../functions/index.mjs';
5
5
 
6
6
  const cmdDef = cmd.command({
7
7
  name: 'assert-repo-is-clean-cli',
8
- version: '7.3.0',
8
+ version: '7.4.0',
9
9
  args: {
10
10
  silent: cmd.flag({
11
11
  long: 'silent',
@@ -5,7 +5,7 @@ import { checkShouldRunTypeChecks } from '../functions/index.mjs';
5
5
 
6
6
  const cmdDef = cmd.command({
7
7
  name: 'check-should-run-type-checks-cli',
8
- version: '7.3.0',
8
+ version: '7.4.0',
9
9
  args: {
10
10
  pathsIgnore: cmd.multioption({
11
11
  long: 'paths-ignore',
@@ -6,7 +6,7 @@ import { formatDiffFrom } from '../functions/index.mjs';
6
6
 
7
7
  const cmdDef = cmd.command({
8
8
  name: 'format-diff-from-cli',
9
- version: '7.3.0',
9
+ version: '7.4.0',
10
10
  args: {
11
11
  base: cmd.positional({
12
12
  type: cmd.string,
@@ -6,7 +6,7 @@ import { formatUncommittedFiles } from '../functions/index.mjs';
6
6
 
7
7
  const cmdDef = cmd.command({
8
8
  name: 'format-uncommitted-cli',
9
- version: '7.3.0',
9
+ version: '7.4.0',
10
10
  args: {
11
11
  excludeUntracked: cmd.flag({
12
12
  long: 'exclude-untracked',
@@ -38,7 +38,7 @@ const nonEmptyArray = <T extends cmd.Type<any, any>>(
38
38
 
39
39
  const cmdDef = cmd.command({
40
40
  name: 'gen-index-ts-cli',
41
- version: '7.3.0',
41
+ version: '7.4.0',
42
42
  args: {
43
43
  // required args
44
44
  targetDirectory: cmd.positional({
@@ -61,7 +61,7 @@ export const checkShouldRunTypeChecks = async (
61
61
  pathsIgnore?: readonly string[];
62
62
  baseBranch?: string;
63
63
  }>,
64
- ): Promise<void> => {
64
+ ): Promise<boolean> => {
65
65
  const pathsIgnore = options?.pathsIgnore ?? [
66
66
  'LICENSE',
67
67
  '.editorconfig',
@@ -112,4 +112,6 @@ export const checkShouldRunTypeChecks = async (
112
112
  if (GITHUB_OUTPUT !== undefined) {
113
113
  await fs.appendFile(GITHUB_OUTPUT, `should_run=${shouldRunTsChecks}\n`);
114
114
  }
115
+
116
+ return shouldRunTsChecks;
115
117
  };
@@ -25,5 +25,5 @@ declare global {
25
25
  const path: typeof path_;
26
26
  const fs: typeof fs_;
27
27
  const glob: typeof glob_;
28
- // const isDirectlyExecuted: typeof isDirectlyExecuted_;
28
+ const isDirectlyExecuted: typeof isDirectlyExecuted_;
29
29
  }