alex-c-line 2.10.3 → 2.11.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.
@@ -65,6 +65,7 @@ declare let scripts: {
65
65
  command: string;
66
66
  "create-local-package": string;
67
67
  "create-release-note": string;
68
+ dev: string;
68
69
  format: string;
69
70
  "format-eslint": string;
70
71
  "format-markdownlint": string;
@@ -65,6 +65,7 @@ declare let scripts: {
65
65
  command: string;
66
66
  "create-local-package": string;
67
67
  "create-release-note": string;
68
+ dev: string;
68
69
  format: string;
69
70
  "format-eslint": string;
70
71
  "format-markdownlint": string;
package/dist/index.cjs CHANGED
@@ -1101,6 +1101,58 @@ function root(program) {
1101
1101
  });
1102
1102
  }
1103
1103
  //#endregion
1104
+ //#region src/cli/commands/template/changeRequest/helpers/resolveBasename.ts
1105
+ function resolveBasename(basename) {
1106
+ return basename.trim().replace(/[.!?/]+$/, "").toLowerCase().replace(/\s+/g, "_");
1107
+ }
1108
+ //#endregion
1109
+ //#region src/utility/fileSystem/getNextFileName.ts
1110
+ function getNextFileName(directoryContents, newFileName) {
1111
+ const extension = node_path.default.extname(newFileName);
1112
+ const baseName = node_path.default.basename(newFileName, extension);
1113
+ const fileRegex = new RegExp(String.raw`^${(0, _alextheman_utility.escapeRegexPattern)(baseName)}(?:_(\d+))?${(0, _alextheman_utility.escapeRegexPattern)(extension)}$`);
1114
+ const matches = directoryContents.map((fileName) => {
1115
+ return fileName.match(fileRegex);
1116
+ }).filter((match) => {
1117
+ return match !== null;
1118
+ });
1119
+ if (matches.length === 0) return newFileName;
1120
+ const highestSuffix = Math.max(...matches.map((match) => {
1121
+ return match[1] === void 0 ? 0 : (0, _alextheman_utility.parseIntStrict)(match[1]);
1122
+ }));
1123
+ return highestSuffix === 0 ? `${baseName}_1${extension}` : `${baseName}_${highestSuffix + 1}${extension}`;
1124
+ }
1125
+ //#endregion
1126
+ //#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
1127
+ function replaceMarkdownPlaceholders(rawContent, templateVariables) {
1128
+ const { content, data } = (0, gray_matter.default)(rawContent);
1129
+ const placeholders = _alextheman_utility.az.with(zod.default.array(zod.default.string()).default([])).parse(data.placeholders);
1130
+ let finalContent = content;
1131
+ for (const placeholder of placeholders) {
1132
+ if (!(placeholder in templateVariables)) throw new _alextheman_utility_v6.DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
1133
+ finalContent = finalContent.replaceAll(`{{${placeholder}}}`, templateVariables[placeholder]);
1134
+ }
1135
+ return finalContent;
1136
+ }
1137
+ //#endregion
1138
+ //#region src/cli/commands/template/changeRequest/create.ts
1139
+ function templateChangeRequestCreate(program) {
1140
+ program.command("create").description("Generate a change request document.").requiredOption("-p, --project-name <projectName>", "The project to request a change for.").requiredOption("-r, --reason <reason>", "The reason for the change.").option("-d, --description <description>", "A further description of the change.", "Redeploy the service.").requiredOption("-q, --requested-by <requestedBy>", "The user making the change request.").option("-o, --output-directory <outputDirectory>", "The directory to output the document in. The name of the document is determined by the reason.", node_path.default.join("docs", "changeRequests")).action(async ({ outputDirectory, ...templateVariables }) => {
1141
+ const resolvedOutputDirectory = node_path.default.resolve(outputDirectory);
1142
+ const newDocumentContents = replaceMarkdownPlaceholders(await (0, node_fs_promises.readFile)(node_path.default.join(await ALEX_C_LINE_PACKAGE_ROOT, "templates", "changeRequest", "template.md"), "utf-8"), templateVariables);
1143
+ await (0, node_fs_promises.mkdir)(resolvedOutputDirectory, { recursive: true });
1144
+ const newFileName = getNextFileName(await (0, node_fs_promises.readdir)(resolvedOutputDirectory), `${resolveBasename(templateVariables.reason)}.md`);
1145
+ const outputPath = node_path.default.join(resolvedOutputDirectory, newFileName);
1146
+ await (0, node_fs_promises.writeFile)(outputPath, newDocumentContents);
1147
+ console.info(outputPath);
1148
+ });
1149
+ }
1150
+ //#endregion
1151
+ //#region src/cli/commands/template/changeRequest/index.ts
1152
+ function templateChangeRequest(program) {
1153
+ loadCommands(program.command("change-request").description("Manage change request documents."), { templateChangeRequestCreate });
1154
+ }
1155
+ //#endregion
1104
1156
  //#region src/utility/markdownTemplates/pullRequest/createPullRequestTemplatesFromTemplates.ts
1105
1157
  const __filename$2 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
1106
1158
  function getTemplateVariables$1(config) {
@@ -1297,18 +1349,6 @@ async function getEditableSectionFromTemplate(version) {
1297
1349
  return await (0, node_fs_promises.readFile)(node_path.default.join(templatesPath, version.type === "major" ? "editableSectionMajor.md" : "editableSection.md"), "utf-8");
1298
1350
  }
1299
1351
  //#endregion
1300
- //#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
1301
- function replaceMarkdownPlaceholders(rawContent, templateVariables) {
1302
- const { content, data } = (0, gray_matter.default)(rawContent);
1303
- const placeholders = _alextheman_utility.az.with(zod.default.array(zod.default.string()).default([])).parse(data.placeholders);
1304
- let finalContent = content;
1305
- for (const placeholder of placeholders) {
1306
- if (!(placeholder in templateVariables)) throw new _alextheman_utility_v6.DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
1307
- finalContent = finalContent.replaceAll(`{{${placeholder}}}`, templateVariables[placeholder]);
1308
- }
1309
- return finalContent;
1310
- }
1311
- //#endregion
1312
1352
  //#region src/utility/markdownTemplates/releaseNote/createReleaseNoteFromTemplates.ts
1313
1353
  async function getTemplateVariables(projectName, version, templateVariables) {
1314
1354
  if ("editableSection" in templateVariables && templateVariables.editableSection) {
@@ -1436,6 +1476,7 @@ function templateReleaseNote(program) {
1436
1476
  //#region src/cli/commands/template/index.ts
1437
1477
  function template(program) {
1438
1478
  loadCommands(program.command("template").description("Manage the automatically-generatable template files."), {
1479
+ templateChangeRequest,
1439
1480
  templatePullRequest,
1440
1481
  templateReleaseNote
1441
1482
  });
@@ -1443,7 +1484,7 @@ function template(program) {
1443
1484
  //#endregion
1444
1485
  //#region package.json
1445
1486
  var name = "alex-c-line";
1446
- var version$1 = "2.10.3";
1487
+ var version$1 = "2.11.1";
1447
1488
  var description = "Command-line tool with commands to streamline the developer workflow.";
1448
1489
  //#endregion
1449
1490
  //#region src/utility/updates/checkUpdate.ts
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import boxen from "boxen";
7
7
  import figlet from "figlet";
8
8
  import envPaths from "env-paths";
9
9
  import path from "node:path";
10
- import { ONE_DAY_IN_MILLISECONDS, VersionNumber, az, escapeHTML, fillArray, getStringsAndInterpolations, interpolate, isTemplateStringsArray, kebabToCamel, normaliseIndents, omitProperties, parseBoolean, parseVersionType, removeDuplicates, removeUndefinedFromObject, sortBy, stringifyDotenv } from "@alextheman/utility";
10
+ import { ONE_DAY_IN_MILLISECONDS, VersionNumber, az, escapeHTML, escapeRegexPattern, fillArray, getStringsAndInterpolations, interpolate, isTemplateStringsArray, kebabToCamel, normaliseIndents, omitProperties, parseBoolean, parseIntStrict, parseVersionType, removeDuplicates, removeUndefinedFromObject, sortBy, stringifyDotenv } from "@alextheman/utility";
11
11
  import { confirm, input, password, select } from "@inquirer/prompts";
12
12
  import { access, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
13
13
  import { parse } from "dotenv";
@@ -1070,6 +1070,58 @@ function root(program) {
1070
1070
  });
1071
1071
  }
1072
1072
  //#endregion
1073
+ //#region src/cli/commands/template/changeRequest/helpers/resolveBasename.ts
1074
+ function resolveBasename(basename) {
1075
+ return basename.trim().replace(/[.!?/]+$/, "").toLowerCase().replace(/\s+/g, "_");
1076
+ }
1077
+ //#endregion
1078
+ //#region src/utility/fileSystem/getNextFileName.ts
1079
+ function getNextFileName(directoryContents, newFileName) {
1080
+ const extension = path.extname(newFileName);
1081
+ const baseName = path.basename(newFileName, extension);
1082
+ const fileRegex = new RegExp(String.raw`^${escapeRegexPattern(baseName)}(?:_(\d+))?${escapeRegexPattern(extension)}$`);
1083
+ const matches = directoryContents.map((fileName) => {
1084
+ return fileName.match(fileRegex);
1085
+ }).filter((match) => {
1086
+ return match !== null;
1087
+ });
1088
+ if (matches.length === 0) return newFileName;
1089
+ const highestSuffix = Math.max(...matches.map((match) => {
1090
+ return match[1] === void 0 ? 0 : parseIntStrict(match[1]);
1091
+ }));
1092
+ return highestSuffix === 0 ? `${baseName}_1${extension}` : `${baseName}_${highestSuffix + 1}${extension}`;
1093
+ }
1094
+ //#endregion
1095
+ //#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
1096
+ function replaceMarkdownPlaceholders(rawContent, templateVariables) {
1097
+ const { content, data } = matter(rawContent);
1098
+ const placeholders = az.with(z.array(z.string()).default([])).parse(data.placeholders);
1099
+ let finalContent = content;
1100
+ for (const placeholder of placeholders) {
1101
+ if (!(placeholder in templateVariables)) throw new DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
1102
+ finalContent = finalContent.replaceAll(`{{${placeholder}}}`, templateVariables[placeholder]);
1103
+ }
1104
+ return finalContent;
1105
+ }
1106
+ //#endregion
1107
+ //#region src/cli/commands/template/changeRequest/create.ts
1108
+ function templateChangeRequestCreate(program) {
1109
+ program.command("create").description("Generate a change request document.").requiredOption("-p, --project-name <projectName>", "The project to request a change for.").requiredOption("-r, --reason <reason>", "The reason for the change.").option("-d, --description <description>", "A further description of the change.", "Redeploy the service.").requiredOption("-q, --requested-by <requestedBy>", "The user making the change request.").option("-o, --output-directory <outputDirectory>", "The directory to output the document in. The name of the document is determined by the reason.", path.join("docs", "changeRequests")).action(async ({ outputDirectory, ...templateVariables }) => {
1110
+ const resolvedOutputDirectory = path.resolve(outputDirectory);
1111
+ const newDocumentContents = replaceMarkdownPlaceholders(await readFile(path.join(await ALEX_C_LINE_PACKAGE_ROOT, "templates", "changeRequest", "template.md"), "utf-8"), templateVariables);
1112
+ await mkdir(resolvedOutputDirectory, { recursive: true });
1113
+ const newFileName = getNextFileName(await readdir(resolvedOutputDirectory), `${resolveBasename(templateVariables.reason)}.md`);
1114
+ const outputPath = path.join(resolvedOutputDirectory, newFileName);
1115
+ await writeFile(outputPath, newDocumentContents);
1116
+ console.info(outputPath);
1117
+ });
1118
+ }
1119
+ //#endregion
1120
+ //#region src/cli/commands/template/changeRequest/index.ts
1121
+ function templateChangeRequest(program) {
1122
+ loadCommands(program.command("change-request").description("Manage change request documents."), { templateChangeRequestCreate });
1123
+ }
1124
+ //#endregion
1073
1125
  //#region src/utility/markdownTemplates/pullRequest/createPullRequestTemplatesFromTemplates.ts
1074
1126
  const __filename$1 = fileURLToPath(import.meta.url);
1075
1127
  function getTemplateVariables$1(config) {
@@ -1266,18 +1318,6 @@ async function getEditableSectionFromTemplate(version) {
1266
1318
  return await readFile(path.join(templatesPath, version.type === "major" ? "editableSectionMajor.md" : "editableSection.md"), "utf-8");
1267
1319
  }
1268
1320
  //#endregion
1269
- //#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
1270
- function replaceMarkdownPlaceholders(rawContent, templateVariables) {
1271
- const { content, data } = matter(rawContent);
1272
- const placeholders = az.with(z.array(z.string()).default([])).parse(data.placeholders);
1273
- let finalContent = content;
1274
- for (const placeholder of placeholders) {
1275
- if (!(placeholder in templateVariables)) throw new DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
1276
- finalContent = finalContent.replaceAll(`{{${placeholder}}}`, templateVariables[placeholder]);
1277
- }
1278
- return finalContent;
1279
- }
1280
- //#endregion
1281
1321
  //#region src/utility/markdownTemplates/releaseNote/createReleaseNoteFromTemplates.ts
1282
1322
  async function getTemplateVariables(projectName, version, templateVariables) {
1283
1323
  if ("editableSection" in templateVariables && templateVariables.editableSection) {
@@ -1405,6 +1445,7 @@ function templateReleaseNote(program) {
1405
1445
  //#region src/cli/commands/template/index.ts
1406
1446
  function template(program) {
1407
1447
  loadCommands(program.command("template").description("Manage the automatically-generatable template files."), {
1448
+ templateChangeRequest,
1408
1449
  templatePullRequest,
1409
1450
  templateReleaseNote
1410
1451
  });
@@ -1412,7 +1453,7 @@ function template(program) {
1412
1453
  //#endregion
1413
1454
  //#region package.json
1414
1455
  var name = "alex-c-line";
1415
- var version$1 = "2.10.3";
1456
+ var version$1 = "2.11.1";
1416
1457
  var description = "Command-line tool with commands to streamline the developer workflow.";
1417
1458
  //#endregion
1418
1459
  //#region src/utility/updates/checkUpdate.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alex-c-line",
3
- "version": "2.10.3",
3
+ "version": "2.11.1",
4
4
  "description": "Command-line tool with commands to streamline the developer workflow.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "dependencies": {
37
37
  "@alextheman/utility": "5.23.0",
38
38
  "@inquirer/prompts": "8.5.2",
39
- "axios": "1.18.0",
39
+ "axios": "1.18.1",
40
40
  "boxen": "8.0.1",
41
41
  "chalk": "5.6.2",
42
42
  "commander": "15.0.0",
@@ -46,16 +46,17 @@
46
46
  "execa": "9.6.1",
47
47
  "figlet": "1.11.0",
48
48
  "gray-matter": "4.0.3",
49
- "semver": "7.8.4",
49
+ "semver": "7.8.5",
50
50
  "supports-color": "10.2.2",
51
51
  "toml": "4.1.1",
52
52
  "zod": "4.4.3"
53
53
  },
54
54
  "devDependencies": {
55
- "@alextheman/eslint-plugin": "5.17.1",
55
+ "@alextheman/eslint-plugin": "5.18.0",
56
56
  "@commander-js/extra-typings": "15.0.0",
57
+ "@faker-js/faker": "10.5.0",
57
58
  "@types/eslint": "9.6.1",
58
- "@types/node": "25.9.3",
59
+ "@types/node": "26.0.1",
59
60
  "@types/semver": "7.7.1",
60
61
  "@types/update-notifier": "6.0.8",
61
62
  "cross-env": "10.1.0",
@@ -67,9 +68,10 @@
67
68
  "tempy": "3.2.0",
68
69
  "ts-node": "10.9.2",
69
70
  "tsdown": "0.22.3",
71
+ "tsx": "4.22.4",
70
72
  "typescript": "6.0.3",
71
- "typescript-eslint": "8.61.1",
72
- "vite": "8.0.16",
73
+ "typescript-eslint": "8.62.0",
74
+ "vite": "8.1.0",
73
75
  "vitest": "4.1.9"
74
76
  },
75
77
  "engines": {
@@ -80,6 +82,7 @@
80
82
  "command": "bash -c 'pnpm run build && echo && echo \"Command output:\" && node dist/index.js \"$@\"' --",
81
83
  "create-local-package": "pnpm run build && rm -f alex-c-line-*.tgz && pnpm pack",
82
84
  "create-release-note": "bash -c 'git pull origin main && pnpm run command template release-note create $@' --",
85
+ "dev": "tsx src/cli/index.ts",
83
86
  "format": "pnpm run format-prettier && pnpm run format-eslint && pnpm run format-markdownlint",
84
87
  "format-eslint": "eslint --fix --suppress-all \"package.json\" \"{src,tests}/**/*.ts\" && rm -f eslint-suppressions.json",
85
88
  "format-markdownlint": "pnpm exec markdownlint-cli2 --fix \"**/*.md\" \"!{node_modules,dist}/**\" | grep -v \"^Finding:\"",
@@ -0,0 +1,18 @@
1
+ ---
2
+ placeholders:
3
+ - projectName
4
+ - requestedBy
5
+ - reason
6
+ - description
7
+ ---
8
+ # Change Request
9
+
10
+ This is a request for a change to {{projectName}} by {{requestedBy}}. If this gets accepted it will trigger a new deployment to apply the change. Please see more details below
11
+
12
+ ## Change reason
13
+
14
+ {{reason}}
15
+
16
+ ## Change description
17
+
18
+ {{description}}