alex-c-line 2.0.0 → 2.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  [![CI](https://github.com/alextheman231/alex-c-line/actions/workflows/ci.yml/badge.svg)](https://github.com/alextheman231/alex-c-line/actions/workflows/ci.yml)
8
8
  [![Publish to NPM Registry and GitHub Releases](https://github.com/alextheman231/alex-c-line/actions/workflows/publish.yml/badge.svg)](https://github.com/alextheman231/alex-c-line/actions/workflows/publish.yml)
9
9
 
10
- <img src="./artwork/alex-c-line.png" alt="alex-c-line artwork" width=250 height=250>
10
+ <img src="./media/alex-c-line.png" alt="alex-c-line artwork" width=250 height=250>
11
11
 
12
12
  This is my command-line tool, which serves as a developer toolkit that can be used in any repository to streamline the developer workflow. It provides a flexible configuration system so you can customise its behaviour to match your workflow.
13
13
 
@@ -40,24 +40,24 @@ alex-c-line say-hello
40
40
  Some commands may even take extra arguments. For example:
41
41
 
42
42
  ```bash
43
- alex-c-line increment-version v1.2.3 major
43
+ alex-c-line version increment v1.2.3 major
44
44
  ```
45
45
 
46
46
  Flags may also be passed through in the following way.
47
47
 
48
48
  ```bash
49
- alex-c-line increment-version v1.2.3 major --no-prefix
49
+ alex-c-line version increment v1.2.3 major --no-prefix
50
50
  ```
51
51
 
52
- Note that for `use-local-package` specifically, you will need to add `--` before the local `alex-c-line` arguments to ensure that all flags get passed through correctly. Example:
52
+ Note that for `local-package use` specifically, you will need to add `--` before the local `alex-c-line` arguments to ensure that all flags get passed through correctly. Example:
53
53
 
54
54
  ```bash
55
- alex-c-line use-local-package alex-c-line -- increment-version v1.2.3 major --no-prefix
55
+ alex-c-line local-package use alex-c-line -- version increment v1.2.3 major --no-prefix
56
56
  ```
57
57
 
58
58
  ## Configs
59
59
 
60
- Some commands also support usage of the config system. For example, `pre-commit-2` supports the `alex-c-line.config.js` file, and `use-local-package` supports the more user-specific `.alex-c-line.private.config.js` file. `alex-c-line.config.js` is intended for shared configurations per repository, whereas `.alex-c-line.private.config.js` are for configurations specific to the user's usage.
60
+ Some commands also support usage of the config system. For example, `pre-commit` supports the `alex-c-line.config.js` file, and `local-package use` supports the more user-specific `.alex-c-line.private.config.js` file. `alex-c-line.config.js` is intended for shared configurations per repository, whereas `.alex-c-line.private.config.js` are for configurations specific to the user's usage.
61
61
 
62
62
  The `configs` subpath provides some helper functions and types that may be helpful when constructing these configs. Namely, `defineAlexCLineConfig` can be used as a type helper, so that you get better type hints in the editor.
63
63
 
@@ -65,9 +65,11 @@ The `configs` subpath provides some helper functions and types that may be helpf
65
65
  import { defineAlexCLineConfig } from "alex-c-line/configs";
66
66
 
67
67
  export default defineAlexCLineConfig({
68
- createPullRequestTemplate: {
69
- category: "general",
70
- projectType: "package",
68
+ template: {
69
+ pullRequest: {
70
+ category: "general",
71
+ projectType: "package",
72
+ }
71
73
  },
72
74
  preCommit: {
73
75
  packageManager: "pnpm",
@@ -84,9 +86,11 @@ import type { AlexCLineConfig } from "alex-c-line/configs";
84
86
  import { scripts } from "./package.json" with { type: "json" };
85
87
 
86
88
  const alexCLineConfig: AlexCLineConfig<keyof typeof scripts> = {
87
- createPullRequestTemplate: {
88
- category: "general",
89
- projectType: "package",
89
+ template: {
90
+ pullRequest: {
91
+ category: "general",
92
+ projectType: "package",
93
+ }
90
94
  },
91
95
  preCommit: {
92
96
  packageManager: "pnpm",
@@ -9,14 +9,14 @@ interface BaseOptions {
9
9
  }
10
10
  interface StepRunner<ExecaOptions extends Options = BaseOptions> {
11
11
  <NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
12
- (command: string, args?: readonly string[]): Promise<Result<ExecaOptions>>;
13
- (strings: TemplateStringsArray, ...interpolations: TemplateExpression[]): Promise<Result<ExecaOptions>>;
12
+ (command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
13
+ (strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
14
14
  }
15
15
  //#endregion
16
16
  //#region src/configs/types/preCommit/PreCommitConfig.d.ts
17
17
  interface PreCommitStepOptions {
18
18
  /** Arguments to pass to the given script */
19
- arguments?: string[];
19
+ arguments?: Array<string>;
20
20
  }
21
21
  type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
22
22
  interface PreCommitConfig<ScriptName extends string = string> {
@@ -25,7 +25,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
25
25
  /** Allow the hook to run even if there are no staged changes. */
26
26
  allowNoStagedChanges?: boolean;
27
27
  /** The steps to run in the pre-commit hook. */
28
- steps: (StepFunction | ScriptName | [ScriptName, PreCommitStepOptions])[];
28
+ steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
29
29
  /** Update the git index after the run */
30
30
  updateIndex?: boolean;
31
31
  }
@@ -96,7 +96,7 @@ declare function definePreCommitConfig<ScriptName extends string = string>(confi
96
96
  //#region src/configs/types/preCommit/PreCommitPrivateConfig.d.ts
97
97
  interface PreCommitPrivateConfig<ScriptName extends string = string> {
98
98
  /** List of script names to skip */
99
- disableSteps?: ScriptName[];
99
+ disableSteps?: Array<ScriptName>;
100
100
  }
101
101
  //#endregion
102
102
  //#region src/configs/helpers/preCommit/definePreCommitPrivateConfig.d.ts
@@ -10,14 +10,14 @@ interface BaseOptions {
10
10
  }
11
11
  interface StepRunner<ExecaOptions extends Options = BaseOptions> {
12
12
  <NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
13
- (command: string, args?: readonly string[]): Promise<Result<ExecaOptions>>;
14
- (strings: TemplateStringsArray, ...interpolations: TemplateExpression[]): Promise<Result<ExecaOptions>>;
13
+ (command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
14
+ (strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
15
15
  }
16
16
  //#endregion
17
17
  //#region src/configs/types/preCommit/PreCommitConfig.d.ts
18
18
  interface PreCommitStepOptions {
19
19
  /** Arguments to pass to the given script */
20
- arguments?: string[];
20
+ arguments?: Array<string>;
21
21
  }
22
22
  type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
23
23
  interface PreCommitConfig<ScriptName extends string = string> {
@@ -26,7 +26,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
26
26
  /** Allow the hook to run even if there are no staged changes. */
27
27
  allowNoStagedChanges?: boolean;
28
28
  /** The steps to run in the pre-commit hook. */
29
- steps: (StepFunction | ScriptName | [ScriptName, PreCommitStepOptions])[];
29
+ steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
30
30
  /** Update the git index after the run */
31
31
  updateIndex?: boolean;
32
32
  }
@@ -97,7 +97,7 @@ declare function definePreCommitConfig<ScriptName extends string = string>(confi
97
97
  //#region src/configs/types/preCommit/PreCommitPrivateConfig.d.ts
98
98
  interface PreCommitPrivateConfig<ScriptName extends string = string> {
99
99
  /** List of script names to skip */
100
- disableSteps?: ScriptName[];
100
+ disableSteps?: Array<ScriptName>;
101
101
  }
102
102
  //#endregion
103
103
  //#region src/configs/helpers/preCommit/definePreCommitPrivateConfig.d.ts
@@ -8,14 +8,14 @@ interface BaseOptions {
8
8
  }
9
9
  interface StepRunner<ExecaOptions extends Options = BaseOptions> {
10
10
  <NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
11
- (command: string, args?: readonly string[]): Promise<Result<ExecaOptions>>;
12
- (strings: TemplateStringsArray, ...interpolations: TemplateExpression[]): Promise<Result<ExecaOptions>>;
11
+ (command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
12
+ (strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
13
13
  }
14
14
  //#endregion
15
15
  //#region src/configs/types/preCommit/PreCommitConfig.d.ts
16
16
  interface PreCommitStepOptions {
17
17
  /** Arguments to pass to the given script */
18
- arguments?: string[];
18
+ arguments?: Array<string>;
19
19
  }
20
20
  type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
21
21
  interface PreCommitConfig<ScriptName extends string = string> {
@@ -24,7 +24,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
24
24
  /** Allow the hook to run even if there are no staged changes. */
25
25
  allowNoStagedChanges?: boolean;
26
26
  /** The steps to run in the pre-commit hook. */
27
- steps: (StepFunction | ScriptName | [ScriptName, PreCommitStepOptions])[];
27
+ steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
28
28
  /** Update the git index after the run */
29
29
  updateIndex?: boolean;
30
30
  }
@@ -114,7 +114,7 @@ declare const PreCommitStep: {
114
114
  type PreCommitStep = "build" | "format" | "lint" | "test";
115
115
  //#endregion
116
116
  //#region src/configs/internal/packageConfig.d.ts
117
- declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: (StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions])[]): AlexCLineConfig<PreCommitStep>;
117
+ declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: Array<StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions]>): AlexCLineConfig<PreCommitStep>;
118
118
  //#endregion
119
119
  //#region src/configs/internal/testConfig.d.ts
120
120
  declare const testConfig: AlexCLineConfig<"artwork">;
@@ -1,6 +1,5 @@
1
1
  import { PackageManager } from "@alextheman/utility/internal";
2
2
  import { Options, Result, TemplateExpression } from "execa";
3
- import "@alextheman/utility";
4
3
 
5
4
  //#region src/cli/commands/root/pre-commit/createStepRunner.d.ts
6
5
  interface BaseOptions {
@@ -9,14 +8,14 @@ interface BaseOptions {
9
8
  }
10
9
  interface StepRunner<ExecaOptions extends Options = BaseOptions> {
11
10
  <NewOpts extends Options>(options: NewOpts): StepRunner<ExecaOptions & NewOpts>;
12
- (command: string, args?: readonly string[]): Promise<Result<ExecaOptions>>;
13
- (strings: TemplateStringsArray, ...interpolations: TemplateExpression[]): Promise<Result<ExecaOptions>>;
11
+ (command: string, args?: ReadonlyArray<string>): Promise<Result<ExecaOptions>>;
12
+ (strings: TemplateStringsArray, ...interpolations: Array<TemplateExpression>): Promise<Result<ExecaOptions>>;
14
13
  }
15
14
  //#endregion
16
15
  //#region src/configs/types/preCommit/PreCommitConfig.d.ts
17
16
  interface PreCommitStepOptions {
18
17
  /** Arguments to pass to the given script */
19
- arguments?: string[];
18
+ arguments?: Array<string>;
20
19
  }
21
20
  type StepFunction = (stepRunner: StepRunner) => void | Promise<void>;
22
21
  interface PreCommitConfig<ScriptName extends string = string> {
@@ -25,7 +24,7 @@ interface PreCommitConfig<ScriptName extends string = string> {
25
24
  /** Allow the hook to run even if there are no staged changes. */
26
25
  allowNoStagedChanges?: boolean;
27
26
  /** The steps to run in the pre-commit hook. */
28
- steps: (StepFunction | ScriptName | [ScriptName, PreCommitStepOptions])[];
27
+ steps: Array<StepFunction | ScriptName | [ScriptName, PreCommitStepOptions]>;
29
28
  /** Update the git index after the run */
30
29
  updateIndex?: boolean;
31
30
  }
@@ -115,7 +114,7 @@ declare const PreCommitStep: {
115
114
  type PreCommitStep = "build" | "format" | "lint" | "test";
116
115
  //#endregion
117
116
  //#region src/configs/internal/packageConfig.d.ts
118
- declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: (StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions])[]): AlexCLineConfig<PreCommitStep>;
117
+ declare function packageConfig<ScriptName extends string = PreCommitStep>(steps?: Array<StepFunction | ScriptName | PreCommitStep | [ScriptName | PreCommitStep, PreCommitStepOptions]>): AlexCLineConfig<PreCommitStep>;
119
118
  //#endregion
120
119
  //#region src/configs/internal/testConfig.d.ts
121
120
  declare const testConfig: AlexCLineConfig<"artwork">;
package/dist/index.cjs CHANGED
@@ -192,7 +192,7 @@ function cache(program) {
192
192
 
193
193
  //#endregion
194
194
  //#region src/utility/constants/errorPrefix.ts
195
- const errorPrefix = "❌ ERROR";
195
+ const errorPrefix = "❌ ERROR:";
196
196
 
197
197
  //#endregion
198
198
  //#region src/utility/envFile/upsertDotenvFile.ts
@@ -205,14 +205,14 @@ async function upsertDotenvFile(contents, envFilePath) {
205
205
  async function addVariable(program, envFileContents, file) {
206
206
  const newVariableName = await (0, _inquirer_prompts.input)({ message: "Please enter the name of the environment variable you would like to add." });
207
207
  if (newVariableName in envFileContents) program.error(`
208
- ${errorPrefix}: Error with chosen environment variable name ${newVariableName}.
208
+ ${errorPrefix} Error with chosen environment variable name ${newVariableName}.
209
209
  Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
210
210
  `, {
211
211
  exitCode: 2,
212
212
  code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
213
213
  });
214
214
  if (/[ \t\r\n]/.test(newVariableName)) program.error(_alextheman_utility.normaliseIndents`
215
- ${errorPrefix}: Error with chosen environment variable name ${newVariableName}.
215
+ ${errorPrefix} Error with chosen environment variable name ${newVariableName}.
216
216
  Environment variables are not allowed to have whitespace.
217
217
  `, {
218
218
  exitCode: 2,
@@ -355,7 +355,7 @@ function checkLockfileVersionDiscrepancy(program) {
355
355
  const { version: packageVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package.json"), "utf-8"));
356
356
  const { version: packageLockVersion } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.resolve(process.cwd(), "package-lock.json"), "utf-8"));
357
357
  if (packageVersion !== packageLockVersion) {
358
- console.error("❌ ERROR: package.json and package-lock.json out of sync. Please run `npm install` to fix this.");
358
+ console.error(`${errorPrefix} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
359
359
  process.exitCode = 1;
360
360
  return;
361
361
  }
@@ -369,7 +369,7 @@ function gitPostMergeCleanup(program) {
369
369
  program.command("git-post-merge-cleanup").alias("git-cleanup").description("Run after merging into a given branch to quickly clean up").argument("[branch]", "The branch you want to merge into", "main").option("--rebase", "Enable if your repository mainly rebases into main", true).action(async (branch, { rebase }) => {
370
370
  console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
371
371
  const { stdout: currentBranch } = await execa.execa`git branch --show-current`;
372
- if (currentBranch === branch) program.error(`❌ ERROR: Cannot run cleanup on ${branch} branch!`, {
372
+ if (currentBranch === branch) program.error(`${errorPrefix} Cannot run cleanup on ${branch} branch!`, {
373
373
  exitCode: 1,
374
374
  code: "INVALID_BRANCH"
375
375
  });
@@ -385,7 +385,7 @@ function gitPostMergeCleanup(program) {
385
385
  const { stdout: changes } = await execa.execa`git diff ${branch}..${currentBranch}`;
386
386
  if (changes) {
387
387
  await execa.execa`git checkout ${currentBranch}`;
388
- program.error("❌ ERROR: Changes on branch not fully merged!", {
388
+ program.error(`${errorPrefix} Changes on branch not fully merged!`, {
389
389
  exitCode: 1,
390
390
  code: "CHANGES_NOT_MERGED"
391
391
  });
@@ -395,7 +395,7 @@ function gitPostMergeCleanup(program) {
395
395
  const { stdout: branchDeletedMessage, exitCode } = await (0, execa.execa)({ reject: false })`git branch --delete ${currentBranch}`;
396
396
  if (exitCode !== 0) {
397
397
  await execa.execa`git checkout ${currentBranch}`;
398
- program.error("❌ ERROR: Changes on branch not fully merged!", {
398
+ program.error(`${errorPrefix} Changes on branch not fully merged!`, {
399
399
  exitCode: 1,
400
400
  code: "CHANGES_NOT_MERGED"
401
401
  });
@@ -653,10 +653,7 @@ function localPackageUse(program) {
653
653
  PrivateConfigFileName.ES_MODULES_JAVASCRIPT,
654
654
  PrivateConfigFileName.STANDARD_JAVASCRIPT
655
655
  ]);
656
- if (!configPath) program.error("Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?", {
657
- exitCode: 1,
658
- code: "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND"
659
- });
656
+ if (!configPath) throw new _alextheman_utility.DataError({ configPath }, "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?");
660
657
  const { localPackage: { enableCache, localPackages } } = await loadAlexCLinePrivateConfig(configPath);
661
658
  const localPackage = localPackages[packageName];
662
659
  if (!localPackage) throw new _alextheman_utility.DataError({
@@ -693,8 +690,8 @@ function localPackageUse(program) {
693
690
  stdio: "inherit",
694
691
  reject: false
695
692
  });
696
- if (exitCode !== 0 && args.length !== 0) program.error("❌ ERROR: An error occurred during the local `alex-c-line` run.", {
697
- exitCode: 1,
693
+ if (exitCode !== 0) program.error(`${errorPrefix} An error occurred during the local \`alex-c-line\` run.`, {
694
+ exitCode,
698
695
  code: "LOCAL_ALEX_C_LINE_ERROR"
699
696
  });
700
697
  } else {
@@ -764,7 +761,7 @@ function encryptWithKey(program) {
764
761
  try {
765
762
  console.info(await (0, _alextheman_utility.encryptWithKey)(publicKey, plaintextValue));
766
763
  } catch {
767
- program.error("Encryption failed. Please double-check that the given key is a valid base 64 string.", {
764
+ program.error(`${errorPrefix} Encryption failed. Please double-check that the given key is a valid base 64 string.`, {
768
765
  exitCode: 1,
769
766
  code: "ENCRYPTION_FAILED"
770
767
  });
@@ -811,7 +808,7 @@ function createStepRunner(program) {
811
808
  //#endregion
812
809
  //#region src/cli/commands/root/pre-commit/getCommandArguments.ts
813
810
  function getCommandArguments(program, script, scripts, args) {
814
- if (!(script in (scripts ?? {}))) program.error(`Could not find script \`${script}\` in package.json.`, {
811
+ if (!(script in (scripts ?? {}))) program.error(`${errorPrefix} Could not find script \`${script}\` in package.json.`, {
815
812
  exitCode: 1,
816
813
  code: "SCRIPT_NOT_FOUND"
817
814
  });
@@ -837,19 +834,16 @@ async function loadAlexCLineConfig(filePath) {
837
834
  function preCommit(program) {
838
835
  program.command("pre-commit").description("Run the pre-commit scripts specified in the alex-c-line config (v2 experiment).").option("--allow-no-staged-changes", "Run even if nothing is staged").option("--no-update-index").option("--update-index", "Update the git index after the run").action(async (options) => {
839
836
  const configPath = await findAlexCLineConfig(process.cwd());
840
- if (!configPath) program.error("Could not find the path to the alex-c-line config file. Does it exist?", {
841
- exitCode: 1,
842
- code: "ALEX_C_LINE_CONFIG_NOT_FOUND"
843
- });
837
+ if (!configPath) throw new _alextheman_utility.DataError({ configPath }, "ALEX_C_LINE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line config file. Does it exist?");
844
838
  const { preCommit: preCommitConfig } = await loadAlexCLineConfig(configPath);
845
- if (!preCommitConfig) program.error("Could not find the pre-commit config in alex-c-line config.", {
846
- exitCode: 1,
847
- code: "PRE_COMMIT_CONFIG_NOT_FOUND"
848
- });
839
+ if (!preCommitConfig) throw new _alextheman_utility.DataError({
840
+ configPath,
841
+ preCommitConfig
842
+ }, "PRE_COMMIT_CONFIG_NOT_FOUND", "Could not find the pre-commit config in alex-c-line config.");
849
843
  const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
850
844
  const { exitCode: diffExitCode } = await (0, execa.execa)({ reject: false })`git diff --cached --quiet`;
851
845
  switch (diffExitCode) {
852
- case 128: program.error("Not currently in a Git repository", {
846
+ case 128: program.error(`${errorPrefix} Not currently in a Git repository`, {
853
847
  exitCode: 1,
854
848
  code: "GIT_DIFF_FAILED"
855
849
  });
@@ -939,12 +933,7 @@ function templatePullRequestCreate(program) {
939
933
  const configPath = await findAlexCLineConfig(process.cwd());
940
934
  const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
941
935
  const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
942
- const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo, () => {
943
- program.error("Invalid package.json - expected package.json to contain a `name` property.", {
944
- exitCode: 1,
945
- code: "INVALID_PACKAGE_JSON"
946
- });
947
- });
936
+ const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo);
948
937
  if (!projectName) throw new _alextheman_utility.DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
949
938
  const parsedOptions = parseTemplatePullRequestConfig((0, _alextheman_utility.removeUndefinedFromObject)({
950
939
  category: commandLineOptions.category ?? config?.category ?? "general",
@@ -976,6 +965,15 @@ function templatePullRequest(program) {
976
965
  //#region src/utility/constants/successPrefix.ts
977
966
  const successPrefix = chalk.default.green("✓");
978
967
 
968
+ //#endregion
969
+ //#region src/utility/errors/convertDataErrorToProgramError.ts
970
+ function convertDataErrorToProgramError(dataError, program, options) {
971
+ program.error(`${errorPrefix} ${dataError.message}`, {
972
+ exitCode: options?.exitCode ?? 1,
973
+ code: dataError.code
974
+ });
975
+ }
976
+
979
977
  //#endregion
980
978
  //#region src/utility/markdownTemplates/releaseNote/types/ReleaseStatus.ts
981
979
  const ReleaseStatus = {
@@ -1082,10 +1080,7 @@ function templateReleaseNoteCheck(program) {
1082
1080
  await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
1083
1081
  console.info(`${successPrefix} Release document is valid!`);
1084
1082
  } catch (error) {
1085
- if (_alextheman_utility.DataError.check(error)) program.error(`${errorPrefix}: ${error.message}`, {
1086
- exitCode: 1,
1087
- code: error.code
1088
- });
1083
+ if (_alextheman_utility.DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
1089
1084
  else throw error;
1090
1085
  }
1091
1086
  });
@@ -1173,12 +1168,7 @@ function templateReleaseNoteCreate(program) {
1173
1168
  const { name, version: packageVersion } = (0, _alextheman_utility.parseZodSchema)(zod.default.object({
1174
1169
  name: zod.default.string(),
1175
1170
  version: zod.default.string()
1176
- }), packageInfo, () => {
1177
- program.error("Invalid package.json - expected package.json to contain a `name` and `version` property.", {
1178
- exitCode: 1,
1179
- code: "INVALID_PACKAGE_JSON"
1180
- });
1181
- });
1171
+ }), packageInfo);
1182
1172
  const versionNumber = target instanceof _alextheman_utility.VersionNumber ? target : target ? new _alextheman_utility.VersionNumber(packageVersion).increment(target) : new _alextheman_utility.VersionNumber(packageVersion);
1183
1173
  const releaseNotePath = getReleaseNotePath(versionNumber);
1184
1174
  const releaseNoteTemplate = await getReleaseNoteTemplateFromMarkdown(name, versionNumber, { status: "In progress" });
@@ -1186,7 +1176,7 @@ function templateReleaseNoteCreate(program) {
1186
1176
  await (0, node_fs_promises.mkdir)(node_path.default.dirname(releaseNotePath), { recursive: true });
1187
1177
  await (0, node_fs_promises.writeFile)(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
1188
1178
  } catch (error) {
1189
- if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error("❌ ERROR: Release notes already exist.", {
1179
+ if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${errorPrefix} Release notes already exist.`, {
1190
1180
  exitCode: 1,
1191
1181
  code: "RELEASE_NOTE_EXISTS"
1192
1182
  });
@@ -1273,10 +1263,7 @@ function templateReleaseNoteSetStatus(program) {
1273
1263
  program.command("set-status").description("Change the release status on a given release document initially generated from the `create-release-note` command.").argument("<documentPath>", "The path to the document").argument("[status]", "The status to set the document to", parseReleaseStatus, ReleaseStatus.RELEASED).action(async (documentPath, status) => {
1274
1264
  const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
1275
1265
  const { name } = (0, _alextheman_utility.parseZodSchema)(zod.default.object({ name: zod.default.string() }), packageInfo, new _alextheman_utility.DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
1276
- if (!documentPath.endsWith("md")) program.error(" ERROR: Invalid file path. Path must lead to a .md file.", {
1277
- exitCode: 1,
1278
- code: "INVALID_FILE_PATH"
1279
- });
1266
+ if (!documentPath.endsWith("md")) throw new _alextheman_utility.DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
1280
1267
  const versionNumber = new _alextheman_utility.VersionNumber(node_path.default.basename(documentPath).split(".").filter((part) => {
1281
1268
  return part !== "md";
1282
1269
  }).join("."));
@@ -1321,7 +1308,7 @@ function template(program) {
1321
1308
  //#endregion
1322
1309
  //#region package.json
1323
1310
  var name = "alex-c-line";
1324
- var version$1 = "2.0.0";
1311
+ var version$1 = "2.0.1";
1325
1312
  var description = "Command-line tool with commands to streamline the developer workflow.";
1326
1313
 
1327
1314
  //#endregion
@@ -1387,15 +1374,6 @@ function uuid(program) {
1387
1374
  loadCommands(program.command("uuid").description("Commands to help manage UUIDs"), { generateUUID });
1388
1375
  }
1389
1376
 
1390
- //#endregion
1391
- //#region src/utility/errors/convertDataErrorToProgramError.ts
1392
- function convertDataErrorToProgramError(dataError, program, options) {
1393
- program.error(dataError.message, {
1394
- exitCode: options?.exitCode ?? 1,
1395
- code: dataError.code
1396
- });
1397
- }
1398
-
1399
1377
  //#endregion
1400
1378
  //#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
1401
1379
  function parseZodSchemaForProgram(program, schema, data) {
@@ -1487,7 +1465,7 @@ async function noFileDependencies(program) {
1487
1465
  };
1488
1466
  if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
1489
1467
  if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
1490
- if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix}: File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
1468
+ if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
1491
1469
  `, {
1492
1470
  exitCode: 2,
1493
1471
  code: "FILE_DEPENDENCIES_FOUND"
@@ -1511,7 +1489,7 @@ async function noPreReleaseDependencies(program) {
1511
1489
  for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
1512
1490
  for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
1513
1491
  if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(_alextheman_utility.normaliseIndents`
1514
- ${errorPrefix}: Pre-release version pinning is not allowed. Found the following violations:
1492
+ ${errorPrefix} Pre-release version pinning is not allowed. Found the following violations:
1515
1493
 
1516
1494
  ` + JSON.stringify({
1517
1495
  dependencies: preReleaseDependencies,
package/dist/index.js CHANGED
@@ -157,7 +157,7 @@ function cache(program) {
157
157
 
158
158
  //#endregion
159
159
  //#region src/utility/constants/errorPrefix.ts
160
- const errorPrefix = "❌ ERROR";
160
+ const errorPrefix = "❌ ERROR:";
161
161
 
162
162
  //#endregion
163
163
  //#region src/utility/envFile/upsertDotenvFile.ts
@@ -170,14 +170,14 @@ async function upsertDotenvFile(contents, envFilePath) {
170
170
  async function addVariable(program, envFileContents, file) {
171
171
  const newVariableName = await input({ message: "Please enter the name of the environment variable you would like to add." });
172
172
  if (newVariableName in envFileContents) program.error(`
173
- ${errorPrefix}: Error with chosen environment variable name ${newVariableName}.
173
+ ${errorPrefix} Error with chosen environment variable name ${newVariableName}.
174
174
  Variable name already exists. If you wish to edit this variable, please select it from the initial menu instead.
175
175
  `, {
176
176
  exitCode: 2,
177
177
  code: "DUPLICATE_ENVIRONMENT_VARIABLE_NAME"
178
178
  });
179
179
  if (/[ \t\r\n]/.test(newVariableName)) program.error(normaliseIndents`
180
- ${errorPrefix}: Error with chosen environment variable name ${newVariableName}.
180
+ ${errorPrefix} Error with chosen environment variable name ${newVariableName}.
181
181
  Environment variables are not allowed to have whitespace.
182
182
  `, {
183
183
  exitCode: 2,
@@ -320,7 +320,7 @@ function checkLockfileVersionDiscrepancy(program) {
320
320
  const { version: packageVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package.json"), "utf-8"));
321
321
  const { version: packageLockVersion } = JSON.parse(await readFile(path.resolve(process.cwd(), "package-lock.json"), "utf-8"));
322
322
  if (packageVersion !== packageLockVersion) {
323
- console.error("❌ ERROR: package.json and package-lock.json out of sync. Please run `npm install` to fix this.");
323
+ console.error(`${errorPrefix} package.json and package-lock.json out of sync. Please run \`npm install\` to fix this.`);
324
324
  process.exitCode = 1;
325
325
  return;
326
326
  }
@@ -334,7 +334,7 @@ function gitPostMergeCleanup(program) {
334
334
  program.command("git-post-merge-cleanup").alias("git-cleanup").description("Run after merging into a given branch to quickly clean up").argument("[branch]", "The branch you want to merge into", "main").option("--rebase", "Enable if your repository mainly rebases into main", true).action(async (branch, { rebase }) => {
335
335
  console.info(`Running git-post-merge-cleanup in ${rebase ? "rebase" : "merge"} mode...`);
336
336
  const { stdout: currentBranch } = await execa`git branch --show-current`;
337
- if (currentBranch === branch) program.error(`❌ ERROR: Cannot run cleanup on ${branch} branch!`, {
337
+ if (currentBranch === branch) program.error(`${errorPrefix} Cannot run cleanup on ${branch} branch!`, {
338
338
  exitCode: 1,
339
339
  code: "INVALID_BRANCH"
340
340
  });
@@ -350,7 +350,7 @@ function gitPostMergeCleanup(program) {
350
350
  const { stdout: changes } = await execa`git diff ${branch}..${currentBranch}`;
351
351
  if (changes) {
352
352
  await execa`git checkout ${currentBranch}`;
353
- program.error("❌ ERROR: Changes on branch not fully merged!", {
353
+ program.error(`${errorPrefix} Changes on branch not fully merged!`, {
354
354
  exitCode: 1,
355
355
  code: "CHANGES_NOT_MERGED"
356
356
  });
@@ -360,7 +360,7 @@ function gitPostMergeCleanup(program) {
360
360
  const { stdout: branchDeletedMessage, exitCode } = await execa({ reject: false })`git branch --delete ${currentBranch}`;
361
361
  if (exitCode !== 0) {
362
362
  await execa`git checkout ${currentBranch}`;
363
- program.error("❌ ERROR: Changes on branch not fully merged!", {
363
+ program.error(`${errorPrefix} Changes on branch not fully merged!`, {
364
364
  exitCode: 1,
365
365
  code: "CHANGES_NOT_MERGED"
366
366
  });
@@ -618,10 +618,7 @@ function localPackageUse(program) {
618
618
  PrivateConfigFileName.ES_MODULES_JAVASCRIPT,
619
619
  PrivateConfigFileName.STANDARD_JAVASCRIPT
620
620
  ]);
621
- if (!configPath) program.error("Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?", {
622
- exitCode: 1,
623
- code: "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND"
624
- });
621
+ if (!configPath) throw new DataError({ configPath }, "ALEX_C_LINE_PRIVATE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line private config file (should be `.alex-c-line.private.config.js`). Does it exist?");
625
622
  const { localPackage: { enableCache, localPackages } } = await loadAlexCLinePrivateConfig(configPath);
626
623
  const localPackage = localPackages[packageName];
627
624
  if (!localPackage) throw new DataError({
@@ -658,8 +655,8 @@ function localPackageUse(program) {
658
655
  stdio: "inherit",
659
656
  reject: false
660
657
  });
661
- if (exitCode !== 0 && args.length !== 0) program.error("❌ ERROR: An error occurred during the local `alex-c-line` run.", {
662
- exitCode: 1,
658
+ if (exitCode !== 0) program.error(`${errorPrefix} An error occurred during the local \`alex-c-line\` run.`, {
659
+ exitCode,
663
660
  code: "LOCAL_ALEX_C_LINE_ERROR"
664
661
  });
665
662
  } else {
@@ -729,7 +726,7 @@ function encryptWithKey$1(program) {
729
726
  try {
730
727
  console.info(await encryptWithKey(publicKey, plaintextValue));
731
728
  } catch {
732
- program.error("Encryption failed. Please double-check that the given key is a valid base 64 string.", {
729
+ program.error(`${errorPrefix} Encryption failed. Please double-check that the given key is a valid base 64 string.`, {
733
730
  exitCode: 1,
734
731
  code: "ENCRYPTION_FAILED"
735
732
  });
@@ -776,7 +773,7 @@ function createStepRunner(program) {
776
773
  //#endregion
777
774
  //#region src/cli/commands/root/pre-commit/getCommandArguments.ts
778
775
  function getCommandArguments(program, script, scripts, args) {
779
- if (!(script in (scripts ?? {}))) program.error(`Could not find script \`${script}\` in package.json.`, {
776
+ if (!(script in (scripts ?? {}))) program.error(`${errorPrefix} Could not find script \`${script}\` in package.json.`, {
780
777
  exitCode: 1,
781
778
  code: "SCRIPT_NOT_FOUND"
782
779
  });
@@ -802,19 +799,16 @@ async function loadAlexCLineConfig(filePath) {
802
799
  function preCommit(program) {
803
800
  program.command("pre-commit").description("Run the pre-commit scripts specified in the alex-c-line config (v2 experiment).").option("--allow-no-staged-changes", "Run even if nothing is staged").option("--no-update-index").option("--update-index", "Update the git index after the run").action(async (options) => {
804
801
  const configPath = await findAlexCLineConfig(process.cwd());
805
- if (!configPath) program.error("Could not find the path to the alex-c-line config file. Does it exist?", {
806
- exitCode: 1,
807
- code: "ALEX_C_LINE_CONFIG_NOT_FOUND"
808
- });
802
+ if (!configPath) throw new DataError({ configPath }, "ALEX_C_LINE_CONFIG_NOT_FOUND", "Could not find the path to the alex-c-line config file. Does it exist?");
809
803
  const { preCommit: preCommitConfig } = await loadAlexCLineConfig(configPath);
810
- if (!preCommitConfig) program.error("Could not find the pre-commit config in alex-c-line config.", {
811
- exitCode: 1,
812
- code: "PRE_COMMIT_CONFIG_NOT_FOUND"
813
- });
804
+ if (!preCommitConfig) throw new DataError({
805
+ configPath,
806
+ preCommitConfig
807
+ }, "PRE_COMMIT_CONFIG_NOT_FOUND", "Could not find the pre-commit config in alex-c-line config.");
814
808
  const { allowNoStagedChanges = options?.allowNoStagedChanges, updateIndex = options?.updateIndex } = preCommitConfig;
815
809
  const { exitCode: diffExitCode } = await execa({ reject: false })`git diff --cached --quiet`;
816
810
  switch (diffExitCode) {
817
- case 128: program.error("Not currently in a Git repository", {
811
+ case 128: program.error(`${errorPrefix} Not currently in a Git repository`, {
818
812
  exitCode: 1,
819
813
  code: "GIT_DIFF_FAILED"
820
814
  });
@@ -904,12 +898,7 @@ function templatePullRequestCreate(program) {
904
898
  const configPath = await findAlexCLineConfig(process.cwd());
905
899
  const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
906
900
  const packageInfo = await getPackageJsonContents(process.cwd());
907
- const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : parseZodSchema(z.object({ name: z.string() }), packageInfo, () => {
908
- program.error("Invalid package.json - expected package.json to contain a `name` property.", {
909
- exitCode: 1,
910
- code: "INVALID_PACKAGE_JSON"
911
- });
912
- });
901
+ const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : parseZodSchema(z.object({ name: z.string() }), packageInfo);
913
902
  if (!projectName) throw new DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
914
903
  const parsedOptions = parseTemplatePullRequestConfig(removeUndefinedFromObject({
915
904
  category: commandLineOptions.category ?? config?.category ?? "general",
@@ -941,6 +930,15 @@ function templatePullRequest(program) {
941
930
  //#region src/utility/constants/successPrefix.ts
942
931
  const successPrefix = chalk.green("✓");
943
932
 
933
+ //#endregion
934
+ //#region src/utility/errors/convertDataErrorToProgramError.ts
935
+ function convertDataErrorToProgramError(dataError, program, options) {
936
+ program.error(`${errorPrefix} ${dataError.message}`, {
937
+ exitCode: options?.exitCode ?? 1,
938
+ code: dataError.code
939
+ });
940
+ }
941
+
944
942
  //#endregion
945
943
  //#region src/utility/markdownTemplates/releaseNote/types/ReleaseStatus.ts
946
944
  const ReleaseStatus = {
@@ -1047,10 +1045,7 @@ function templateReleaseNoteCheck(program) {
1047
1045
  await validateReleaseDocument(name, documentVersion, fileContents, expectedReleaseStatus);
1048
1046
  console.info(`${successPrefix} Release document is valid!`);
1049
1047
  } catch (error) {
1050
- if (DataError.check(error)) program.error(`${errorPrefix}: ${error.message}`, {
1051
- exitCode: 1,
1052
- code: error.code
1053
- });
1048
+ if (DataError.check(error)) convertDataErrorToProgramError(error, program, { exitCode: 2 });
1054
1049
  else throw error;
1055
1050
  }
1056
1051
  });
@@ -1138,12 +1133,7 @@ function templateReleaseNoteCreate(program) {
1138
1133
  const { name, version: packageVersion } = parseZodSchema(z.object({
1139
1134
  name: z.string(),
1140
1135
  version: z.string()
1141
- }), packageInfo, () => {
1142
- program.error("Invalid package.json - expected package.json to contain a `name` and `version` property.", {
1143
- exitCode: 1,
1144
- code: "INVALID_PACKAGE_JSON"
1145
- });
1146
- });
1136
+ }), packageInfo);
1147
1137
  const versionNumber = target instanceof VersionNumber ? target : target ? new VersionNumber(packageVersion).increment(target) : new VersionNumber(packageVersion);
1148
1138
  const releaseNotePath = getReleaseNotePath(versionNumber);
1149
1139
  const releaseNoteTemplate = await getReleaseNoteTemplateFromMarkdown(name, versionNumber, { status: "In progress" });
@@ -1151,7 +1141,7 @@ function templateReleaseNoteCreate(program) {
1151
1141
  await mkdir(path.dirname(releaseNotePath), { recursive: true });
1152
1142
  await writeFile(releaseNotePath, releaseNoteTemplate, { flag: "wx" });
1153
1143
  } catch (error) {
1154
- if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error("❌ ERROR: Release notes already exist.", {
1144
+ if (error instanceof Error && "code" in error && error.code === "EEXIST") program.error(`${errorPrefix} Release notes already exist.`, {
1155
1145
  exitCode: 1,
1156
1146
  code: "RELEASE_NOTE_EXISTS"
1157
1147
  });
@@ -1238,10 +1228,7 @@ function templateReleaseNoteSetStatus(program) {
1238
1228
  program.command("set-status").description("Change the release status on a given release document initially generated from the `create-release-note` command.").argument("<documentPath>", "The path to the document").argument("[status]", "The status to set the document to", parseReleaseStatus, ReleaseStatus.RELEASED).action(async (documentPath, status) => {
1239
1229
  const packageInfo = await getPackageJsonContents(process.cwd());
1240
1230
  const { name } = parseZodSchema(z.object({ name: z.string() }), packageInfo, new DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
1241
- if (!documentPath.endsWith("md")) program.error(" ERROR: Invalid file path. Path must lead to a .md file.", {
1242
- exitCode: 1,
1243
- code: "INVALID_FILE_PATH"
1244
- });
1231
+ if (!documentPath.endsWith("md")) throw new DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
1245
1232
  const versionNumber = new VersionNumber(path.basename(documentPath).split(".").filter((part) => {
1246
1233
  return part !== "md";
1247
1234
  }).join("."));
@@ -1286,7 +1273,7 @@ function template(program) {
1286
1273
  //#endregion
1287
1274
  //#region package.json
1288
1275
  var name = "alex-c-line";
1289
- var version$1 = "2.0.0";
1276
+ var version$1 = "2.0.1";
1290
1277
  var description = "Command-line tool with commands to streamline the developer workflow.";
1291
1278
 
1292
1279
  //#endregion
@@ -1352,15 +1339,6 @@ function uuid(program) {
1352
1339
  loadCommands(program.command("uuid").description("Commands to help manage UUIDs"), { generateUUID });
1353
1340
  }
1354
1341
 
1355
- //#endregion
1356
- //#region src/utility/errors/convertDataErrorToProgramError.ts
1357
- function convertDataErrorToProgramError(dataError, program, options) {
1358
- program.error(dataError.message, {
1359
- exitCode: options?.exitCode ?? 1,
1360
- code: dataError.code
1361
- });
1362
- }
1363
-
1364
1342
  //#endregion
1365
1343
  //#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
1366
1344
  function parseZodSchemaForProgram(program, schema, data) {
@@ -1452,7 +1430,7 @@ async function noFileDependencies(program) {
1452
1430
  };
1453
1431
  if (Object.keys(allFileDependencies.dependencies ?? {}).length === 0) delete allFileDependencies.dependencies;
1454
1432
  if (Object.keys(allFileDependencies.devDependencies ?? {}).length === 0) delete allFileDependencies.devDependencies;
1455
- if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix}: File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
1433
+ if (Object.keys(allFileDependencies).length !== 0) program.error(`${errorPrefix} File dependencies found:\n\n${JSON.stringify(allFileDependencies, void 0, 2)}
1456
1434
  `, {
1457
1435
  exitCode: 2,
1458
1436
  code: "FILE_DEPENDENCIES_FOUND"
@@ -1476,7 +1454,7 @@ async function noPreReleaseDependencies(program) {
1476
1454
  for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
1477
1455
  for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
1478
1456
  if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(normaliseIndents`
1479
- ${errorPrefix}: Pre-release version pinning is not allowed. Found the following violations:
1457
+ ${errorPrefix} Pre-release version pinning is not allowed. Found the following violations:
1480
1458
 
1481
1459
  ` + JSON.stringify({
1482
1460
  dependencies: preReleaseDependencies,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alex-c-line",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Command-line tool with commands to streamline the developer workflow.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -52,7 +52,7 @@
52
52
  "zod": "^4.3.6"
53
53
  },
54
54
  "devDependencies": {
55
- "@alextheman/eslint-plugin": "^5.9.1",
55
+ "@alextheman/eslint-plugin": "^5.10.0",
56
56
  "@commander-js/extra-typings": "^14.0.0",
57
57
  "@types/eslint": "^9.6.1",
58
58
  "@types/node": "^25.3.2",