alex-c-line 1.31.0 → 1.33.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/dist/index.cjs CHANGED
@@ -59,6 +59,7 @@ let _alextheman_utility_node = require("@alextheman/utility/node");
59
59
  let supports_color = require("supports-color");
60
60
  supports_color = __toESM(supports_color);
61
61
  let node_crypto = require("node:crypto");
62
+ let semver = require("semver");
62
63
 
63
64
  //#region src/utility/miscellaneous/asciiToPng.ts
64
65
  async function asciiToPng(ascii, options) {
@@ -627,35 +628,35 @@ async function parseDotenvFile(envFilePath) {
627
628
  //#endregion
628
629
  //#region src/cli/commands/edit-env-file/index.ts
629
630
  function editEnvFile(program) {
630
- program.command("edit-env-file").description("Edit properties in a .env file").option("--interactive", "Enable interactive mode", true).option("--file <filePath>", "The path to the .env file you want to edit, relative to the working directory this command is run", ".env").action(async ({ interactive, file }) => {
631
+ program.command("edit-env-file").description("Edit properties in a .env file").option("--interactive", "Enable interactive mode", true).option("--file <filePath>", "The path to the .env file you want to edit, relative to the working directory this command is run", ".env").action(async ({ file, interactive }) => {
631
632
  if (interactive) {
632
633
  let exitInteractiveMode = false;
633
634
  while (!exitInteractiveMode) {
634
635
  const envFileContents = await parseDotenvFile(file);
635
636
  const variableToEdit = await (0, _inquirer_prompts.select)({
636
- message: _alextheman_utility.normaliseIndents`
637
- Please select the environment variable you wish to edit
638
- Currently editing file: ${file}
639
- `,
640
637
  choices: [
641
638
  ...Object.keys(envFileContents).map((key) => {
642
639
  return {
640
+ description: envFileContents[key] === "" ? "<empty>" : "<redacted for safety>",
643
641
  name: key,
644
- value: key,
645
- description: envFileContents[key] === "" ? "<empty>" : "<redacted for safety>"
642
+ value: key
646
643
  };
647
644
  }),
648
645
  {
646
+ description: `Add a new environment variable to .env.`,
649
647
  name: `${chalk.default.green("+")} Add new environment variable`,
650
- value: "Add new",
651
- description: `Add a new environment variable to .env.`
648
+ value: "Add new"
652
649
  },
653
650
  {
651
+ description: "Exit the .env file interactive editor.",
654
652
  name: `${chalk.default.dim("⏎")} Exit editor`,
655
- value: "Exit editor",
656
- description: "Exit the .env file interactive editor."
653
+ value: "Exit editor"
657
654
  }
658
- ]
655
+ ],
656
+ message: _alextheman_utility.normaliseIndents`
657
+ Please select the environment variable you wish to edit
658
+ Currently editing file: ${file}
659
+ `
659
660
  });
660
661
  switch (variableToEdit) {
661
662
  case "Add new":
@@ -735,6 +736,31 @@ function gitPostMergeCleanup(program) {
735
736
  });
736
737
  }
737
738
 
739
+ //#endregion
740
+ //#region src/cli/commands/internal/outdated-dependencies.ts
741
+ function outdatedDependencies(program) {
742
+ program.command("outdated-dependencies").action(async () => {
743
+ const { exitCode, stdout, stderr } = await (0, execa.execa)({ reject: false })`pnpm outdated`;
744
+ if (![0, 1].includes(exitCode)) program.error(stderr ?? stdout, {
745
+ exitCode,
746
+ code: "PNPM_OUDATED_ERROR"
747
+ });
748
+ console.info(stdout);
749
+ });
750
+ }
751
+
752
+ //#endregion
753
+ //#region src/utility/miscellaneous/loadCommands.ts
754
+ function loadCommands(program, commandMap) {
755
+ for (const loader of Object.values(commandMap)) loader(program);
756
+ }
757
+
758
+ //#endregion
759
+ //#region src/cli/commands/internal/index.ts
760
+ function internal(program) {
761
+ loadCommands(program.command("internal").description("Commands meant more for internal use by me and is not recommended for production usage."), { outdatedDependencies });
762
+ }
763
+
738
764
  //#endregion
739
765
  //#region src/cli/commands/pre-commit/createStepRunner.ts
740
766
  const runCommandAndLogToConsole = (0, execa.execa)({
@@ -1316,7 +1342,7 @@ function parseZodSchemaForProgram(programError, schema, data) {
1316
1342
  //#endregion
1317
1343
  //#region package.json
1318
1344
  var name = "alex-c-line";
1319
- var version = "1.31.0";
1345
+ var version = "1.33.0";
1320
1346
  var description = "Command-line tool with commands to streamline the developer workflow.";
1321
1347
 
1322
1348
  //#endregion
@@ -1561,12 +1587,6 @@ function generateUUID(program) {
1561
1587
  });
1562
1588
  }
1563
1589
 
1564
- //#endregion
1565
- //#region src/utility/miscellaneous/loadCommands.ts
1566
- function loadCommands(program, commandMap) {
1567
- for (const loader of Object.values(commandMap)) loader(program);
1568
- }
1569
-
1570
1590
  //#endregion
1571
1591
  //#region src/cli/commands/uuid/index.ts
1572
1592
  function uuid(program) {
@@ -1619,6 +1639,50 @@ function incrementVersion(program) {
1619
1639
  });
1620
1640
  }
1621
1641
 
1642
+ //#endregion
1643
+ //#region src/utility/constants/successPrefix.ts
1644
+ const successPrefix = chalk.default.green("✓");
1645
+
1646
+ //#endregion
1647
+ //#region src/cli/commands/package-json/noPreReleaseDependencies.ts
1648
+ function isPreRelease(dependencyVersionRange) {
1649
+ const minimumFromRange = (0, semver.minVersion)(dependencyVersionRange);
1650
+ return minimumFromRange !== null && (0, semver.prerelease)(minimumFromRange) !== null;
1651
+ }
1652
+ async function noPreReleaseDependencies(program) {
1653
+ const packageJson = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
1654
+ if (packageJson === null) throw (0, _alextheman_utility_internal.packageJsonNotFoundError)(process.cwd());
1655
+ const dependencies = (0, _alextheman_utility_internal.getDependenciesFromGroup)(packageJson, "dependencies");
1656
+ const devDependencies = (0, _alextheman_utility_internal.getDependenciesFromGroup)(packageJson, "devDependencies");
1657
+ const preReleaseDependencies = {};
1658
+ const preReleaseDevDependencies = {};
1659
+ for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
1660
+ for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
1661
+ if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(_alextheman_utility.normaliseIndents`
1662
+ ${errorPrefix}: Pre-release version pinning is not allowed. Found the following violations:
1663
+
1664
+ ${JSON.stringify({
1665
+ dependencies: preReleaseDependencies,
1666
+ devDependencies: preReleaseDevDependencies
1667
+ }, null, 2)}
1668
+ `, {
1669
+ exitCode: 2,
1670
+ code: "UNEXPECTED_PRE_RELEASE_VERSION"
1671
+ });
1672
+ console.info(`${successPrefix} No pre-release versions found!`);
1673
+ }
1674
+
1675
+ //#endregion
1676
+ //#region src/cli/commands/package-json/index.ts
1677
+ const RuleName = { NO_PRE_RELEASE_DEPENDENCIES: "no-pre-release-dependencies" };
1678
+ function packageJson(program) {
1679
+ program.command("package-json").description("Run checks on your package.json file").argument("[ruleName]", "The name of the rule to check", (rawRuleName) => {
1680
+ return (0, _alextheman_utility.parseZodSchema)(zod.default.enum(RuleName), rawRuleName);
1681
+ }).action(async (ruleName) => {
1682
+ if (ruleName === "no-pre-release-dependencies") return await noPreReleaseDependencies(program);
1683
+ });
1684
+ }
1685
+
1622
1686
  //#endregion
1623
1687
  //#region src/cli/commands/index.ts
1624
1688
  function createCommands(program) {
@@ -1641,7 +1705,9 @@ function createCommands(program) {
1641
1705
  getVersionType,
1642
1706
  gitPostMergeCleanup,
1643
1707
  incrementVersion,
1708
+ internal,
1644
1709
  migrateReleaseNotes,
1710
+ packageJson,
1645
1711
  preCommit,
1646
1712
  preCommit2,
1647
1713
  sayHello,
package/dist/index.js CHANGED
@@ -15,12 +15,13 @@ import dotenvStringify from "dotenv-stringify";
15
15
  import z from "zod";
16
16
  import { confirm, input, password, select } from "@inquirer/prompts";
17
17
  import os from "node:os";
18
- import { PackageManager, getDependenciesFromGroup, getExpectedTgzName, getPackageJsonContents } from "@alextheman/utility/internal";
18
+ import { PackageManager, getDependenciesFromGroup, getExpectedTgzName, getPackageJsonContents, packageJsonNotFoundError } from "@alextheman/utility/internal";
19
19
  import { fileURLToPath, pathToFileURL } from "node:url";
20
20
  import matter from "gray-matter";
21
21
  import { parseFilePath } from "@alextheman/utility/node";
22
22
  import supportsColor from "supports-color";
23
23
  import { randomUUID } from "node:crypto";
24
+ import { minVersion, prerelease } from "semver";
24
25
 
25
26
  //#region src/utility/miscellaneous/asciiToPng.ts
26
27
  async function asciiToPng(ascii, options) {
@@ -589,35 +590,35 @@ async function parseDotenvFile(envFilePath) {
589
590
  //#endregion
590
591
  //#region src/cli/commands/edit-env-file/index.ts
591
592
  function editEnvFile(program) {
592
- program.command("edit-env-file").description("Edit properties in a .env file").option("--interactive", "Enable interactive mode", true).option("--file <filePath>", "The path to the .env file you want to edit, relative to the working directory this command is run", ".env").action(async ({ interactive, file }) => {
593
+ program.command("edit-env-file").description("Edit properties in a .env file").option("--interactive", "Enable interactive mode", true).option("--file <filePath>", "The path to the .env file you want to edit, relative to the working directory this command is run", ".env").action(async ({ file, interactive }) => {
593
594
  if (interactive) {
594
595
  let exitInteractiveMode = false;
595
596
  while (!exitInteractiveMode) {
596
597
  const envFileContents = await parseDotenvFile(file);
597
598
  const variableToEdit = await select({
598
- message: normaliseIndents`
599
- Please select the environment variable you wish to edit
600
- Currently editing file: ${file}
601
- `,
602
599
  choices: [
603
600
  ...Object.keys(envFileContents).map((key) => {
604
601
  return {
602
+ description: envFileContents[key] === "" ? "<empty>" : "<redacted for safety>",
605
603
  name: key,
606
- value: key,
607
- description: envFileContents[key] === "" ? "<empty>" : "<redacted for safety>"
604
+ value: key
608
605
  };
609
606
  }),
610
607
  {
608
+ description: `Add a new environment variable to .env.`,
611
609
  name: `${chalk.green("+")} Add new environment variable`,
612
- value: "Add new",
613
- description: `Add a new environment variable to .env.`
610
+ value: "Add new"
614
611
  },
615
612
  {
613
+ description: "Exit the .env file interactive editor.",
616
614
  name: `${chalk.dim("⏎")} Exit editor`,
617
- value: "Exit editor",
618
- description: "Exit the .env file interactive editor."
615
+ value: "Exit editor"
619
616
  }
620
- ]
617
+ ],
618
+ message: normaliseIndents`
619
+ Please select the environment variable you wish to edit
620
+ Currently editing file: ${file}
621
+ `
621
622
  });
622
623
  switch (variableToEdit) {
623
624
  case "Add new":
@@ -697,6 +698,31 @@ function gitPostMergeCleanup(program) {
697
698
  });
698
699
  }
699
700
 
701
+ //#endregion
702
+ //#region src/cli/commands/internal/outdated-dependencies.ts
703
+ function outdatedDependencies(program) {
704
+ program.command("outdated-dependencies").action(async () => {
705
+ const { exitCode, stdout, stderr } = await execa({ reject: false })`pnpm outdated`;
706
+ if (![0, 1].includes(exitCode)) program.error(stderr ?? stdout, {
707
+ exitCode,
708
+ code: "PNPM_OUDATED_ERROR"
709
+ });
710
+ console.info(stdout);
711
+ });
712
+ }
713
+
714
+ //#endregion
715
+ //#region src/utility/miscellaneous/loadCommands.ts
716
+ function loadCommands(program, commandMap) {
717
+ for (const loader of Object.values(commandMap)) loader(program);
718
+ }
719
+
720
+ //#endregion
721
+ //#region src/cli/commands/internal/index.ts
722
+ function internal(program) {
723
+ loadCommands(program.command("internal").description("Commands meant more for internal use by me and is not recommended for production usage."), { outdatedDependencies });
724
+ }
725
+
700
726
  //#endregion
701
727
  //#region src/cli/commands/pre-commit/createStepRunner.ts
702
728
  const runCommandAndLogToConsole = execa({
@@ -1278,7 +1304,7 @@ function parseZodSchemaForProgram(programError, schema, data) {
1278
1304
  //#endregion
1279
1305
  //#region package.json
1280
1306
  var name = "alex-c-line";
1281
- var version = "1.31.0";
1307
+ var version = "1.33.0";
1282
1308
  var description = "Command-line tool with commands to streamline the developer workflow.";
1283
1309
 
1284
1310
  //#endregion
@@ -1523,12 +1549,6 @@ function generateUUID(program) {
1523
1549
  });
1524
1550
  }
1525
1551
 
1526
- //#endregion
1527
- //#region src/utility/miscellaneous/loadCommands.ts
1528
- function loadCommands(program, commandMap) {
1529
- for (const loader of Object.values(commandMap)) loader(program);
1530
- }
1531
-
1532
1552
  //#endregion
1533
1553
  //#region src/cli/commands/uuid/index.ts
1534
1554
  function uuid(program) {
@@ -1581,6 +1601,50 @@ function incrementVersion(program) {
1581
1601
  });
1582
1602
  }
1583
1603
 
1604
+ //#endregion
1605
+ //#region src/utility/constants/successPrefix.ts
1606
+ const successPrefix = chalk.green("✓");
1607
+
1608
+ //#endregion
1609
+ //#region src/cli/commands/package-json/noPreReleaseDependencies.ts
1610
+ function isPreRelease(dependencyVersionRange) {
1611
+ const minimumFromRange = minVersion(dependencyVersionRange);
1612
+ return minimumFromRange !== null && prerelease(minimumFromRange) !== null;
1613
+ }
1614
+ async function noPreReleaseDependencies(program) {
1615
+ const packageJson = await getPackageJsonContents(process.cwd());
1616
+ if (packageJson === null) throw packageJsonNotFoundError(process.cwd());
1617
+ const dependencies = getDependenciesFromGroup(packageJson, "dependencies");
1618
+ const devDependencies = getDependenciesFromGroup(packageJson, "devDependencies");
1619
+ const preReleaseDependencies = {};
1620
+ const preReleaseDevDependencies = {};
1621
+ for (const [dependencyName, dependencyVersionRange] of Object.entries(dependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDependencies[dependencyName] = dependencyVersionRange;
1622
+ for (const [dependencyName, dependencyVersionRange] of Object.entries(devDependencies)) if (isPreRelease(dependencyVersionRange)) preReleaseDevDependencies[dependencyName] = dependencyVersionRange;
1623
+ if (Object.keys(preReleaseDependencies).length !== 0 || Object.keys(preReleaseDevDependencies).length !== 0) program.error(normaliseIndents`
1624
+ ${errorPrefix}: Pre-release version pinning is not allowed. Found the following violations:
1625
+
1626
+ ${JSON.stringify({
1627
+ dependencies: preReleaseDependencies,
1628
+ devDependencies: preReleaseDevDependencies
1629
+ }, null, 2)}
1630
+ `, {
1631
+ exitCode: 2,
1632
+ code: "UNEXPECTED_PRE_RELEASE_VERSION"
1633
+ });
1634
+ console.info(`${successPrefix} No pre-release versions found!`);
1635
+ }
1636
+
1637
+ //#endregion
1638
+ //#region src/cli/commands/package-json/index.ts
1639
+ const RuleName = { NO_PRE_RELEASE_DEPENDENCIES: "no-pre-release-dependencies" };
1640
+ function packageJson(program) {
1641
+ program.command("package-json").description("Run checks on your package.json file").argument("[ruleName]", "The name of the rule to check", (rawRuleName) => {
1642
+ return parseZodSchema(z.enum(RuleName), rawRuleName);
1643
+ }).action(async (ruleName) => {
1644
+ if (ruleName === "no-pre-release-dependencies") return await noPreReleaseDependencies(program);
1645
+ });
1646
+ }
1647
+
1584
1648
  //#endregion
1585
1649
  //#region src/cli/commands/index.ts
1586
1650
  function createCommands(program) {
@@ -1603,7 +1667,9 @@ function createCommands(program) {
1603
1667
  getVersionType,
1604
1668
  gitPostMergeCleanup,
1605
1669
  incrementVersion,
1670
+ internal,
1606
1671
  migrateReleaseNotes,
1672
+ packageJson,
1607
1673
  preCommit,
1608
1674
  preCommit2,
1609
1675
  sayHello,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alex-c-line",
3
- "version": "1.31.0",
3
+ "version": "1.33.0",
4
4
  "description": "Command-line tool with commands to streamline the developer workflow.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,8 +34,8 @@
34
34
  "templates"
35
35
  ],
36
36
  "dependencies": {
37
- "@alextheman/utility": "^5.4.1",
38
- "@inquirer/prompts": "^8.2.1",
37
+ "@alextheman/utility": "^5.5.0",
38
+ "@inquirer/prompts": "^8.3.0",
39
39
  "boxen": "^8.0.1",
40
40
  "canvas": "^3.2.1",
41
41
  "chalk": "^5.6.2",
@@ -47,24 +47,27 @@
47
47
  "figlet": "^1.10.0",
48
48
  "gray-matter": "^4.0.3",
49
49
  "libsodium-wrappers": "^0.8.2",
50
+ "semver": "^7.7.4",
50
51
  "supports-color": "^10.2.2",
51
52
  "zod": "^4.3.6"
52
53
  },
53
54
  "devDependencies": {
54
- "@alextheman/eslint-plugin": "^5.8.1",
55
+ "@alextheman/eslint-plugin": "^5.9.1",
55
56
  "@commander-js/extra-typings": "^14.0.0",
56
57
  "@types/eslint": "^9.6.1",
57
- "@types/node": "^25.3.0",
58
+ "@types/node": "^25.3.2",
59
+ "@types/semver": "^7.7.1",
58
60
  "@types/update-notifier": "^6.0.8",
61
+ "cross-env": "^10.1.0",
59
62
  "dotenv-cli": "^11.0.0",
60
- "eslint": "^10.0.1",
63
+ "eslint": "^10.0.2",
61
64
  "husky": "^9.1.7",
62
65
  "prettier": "^3.8.1",
63
66
  "tempy": "^3.2.0",
64
67
  "ts-node": "^10.9.2",
65
68
  "tsdown": "^0.20.3",
66
69
  "typescript": "^5.9.3",
67
- "typescript-eslint": "^8.56.0",
70
+ "typescript-eslint": "^8.56.1",
68
71
  "vite-tsconfig-paths": "^6.1.1",
69
72
  "vitest": "^4.0.18"
70
73
  },
@@ -95,7 +98,7 @@
95
98
  "prepare-local-eslint-plugin": "dotenv -e .env -- sh -c 'ESLINT_PLUGIN_PATH=${LOCAL_ESLINT_PLUGIN_PATH:-../eslint-plugin}; pnpm --prefix \"$ESLINT_PLUGIN_PATH\" run build && pnpm uninstall @alextheman/eslint-plugin && pnpm install --save-dev file:\"$ESLINT_PLUGIN_PATH\"'",
96
99
  "prepare-local-utility": "dotenv -e .env -- sh -c 'UTILITY_PATH=${LOCAL_UTILITY_PATH:-../utility}; pnpm --prefix \"$UTILITY_PATH\" run build && pnpm uninstall @alextheman/utility && pnpm install file:\"$UTILITY_PATH\"'",
97
100
  "test": "vitest run",
98
- "test-end-to-end": "RUN_END_TO_END=true vitest run tests/end-to-end --reporter verbose",
101
+ "test-end-to-end": "cross-env RUN_END_TO_END=true vitest run tests/end-to-end --reporter verbose",
99
102
  "test-watch": "vitest",
100
103
  "update-dependencies": "pnpm update --latest && pnpm update",
101
104
  "use-live-eslint-plugin": "pnpm run prepare-live-eslint-plugin && pnpm run lint",