alex-c-line 2.7.1 → 2.7.2
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 +22 -22
- package/dist/index.js +23 -23
- package/package.json +10 -10
package/dist/index.cjs
CHANGED
|
@@ -476,7 +476,7 @@ const templatePullRequestSchema = zod.default.discriminatedUnion("category", [te
|
|
|
476
476
|
requireConfirmationFrom: zod.default.string()
|
|
477
477
|
})]);
|
|
478
478
|
function parseTemplatePullRequestConfig(input) {
|
|
479
|
-
return
|
|
479
|
+
return _alextheman_utility.az.with(templatePullRequestSchema).parse(input);
|
|
480
480
|
}
|
|
481
481
|
//#endregion
|
|
482
482
|
//#region src/configs/helpers/defineAlexCLineConfig.ts
|
|
@@ -485,7 +485,7 @@ const alexCLineConfigSchema = zod.default.strictObject({
|
|
|
485
485
|
template: zod.default.object({ pullRequest: templatePullRequestSchema })
|
|
486
486
|
}).partial();
|
|
487
487
|
async function parseAlexCLineConfig(input) {
|
|
488
|
-
return await
|
|
488
|
+
return await _alextheman_utility.az.with(alexCLineConfigSchema).parseAsync(input);
|
|
489
489
|
}
|
|
490
490
|
//#endregion
|
|
491
491
|
//#region src/configs/types/ConfigFileName.ts
|
|
@@ -518,7 +518,7 @@ const alexCLinePrivateConfigSchema = zod.default.object({ localPackage: zod.defa
|
|
|
518
518
|
}))
|
|
519
519
|
}) });
|
|
520
520
|
function parseAlexCLinePrivateConfig(data) {
|
|
521
|
-
return
|
|
521
|
+
return _alextheman_utility.az.with(alexCLinePrivateConfigSchema).parse(data);
|
|
522
522
|
}
|
|
523
523
|
//#endregion
|
|
524
524
|
//#region src/cache/project/types/AlexCLineProjectCache.ts
|
|
@@ -532,7 +532,7 @@ const alexCLineProjectCacheSchema = zod.default.object({ useLocalPackage: zod.de
|
|
|
532
532
|
//#endregion
|
|
533
533
|
//#region src/cache/project/parseAlexCLineProjectCache.ts
|
|
534
534
|
function parseAlexCLineProjectCache(data) {
|
|
535
|
-
return
|
|
535
|
+
return _alextheman_utility.az.with(alexCLineProjectCacheSchema).parse(data);
|
|
536
536
|
}
|
|
537
537
|
//#endregion
|
|
538
538
|
//#region src/cache/project/loadAlexCLineProjectCache.ts
|
|
@@ -639,7 +639,7 @@ function localPackageUse(program) {
|
|
|
639
639
|
const localPackagePath = node_path.default.resolve(process.cwd(), localPackage.path);
|
|
640
640
|
const localPackageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(localPackagePath);
|
|
641
641
|
if (localPackageInfo === null) throw new _alextheman_utility_v6.DataError({ localPackagePath }, "MISSING_PACKAGE_REPOSITORY_PACKAGE_JSON", "Could not find package.json in the package repository.");
|
|
642
|
-
const localPackageRepositoryName =
|
|
642
|
+
const localPackageRepositoryName = _alextheman_utility.az.with(zod.default.string()).parse(localPackageInfo.name);
|
|
643
643
|
if (localPackageRepositoryName !== packageName) throw new _alextheman_utility_v6.DataError({
|
|
644
644
|
providedPackageName: packageName,
|
|
645
645
|
localPackagePath,
|
|
@@ -729,7 +729,7 @@ const pyprojectSchema = zod.default.object({
|
|
|
729
729
|
"dependency-groups": zod.default.object({ dev: zod.default.array(zod.default.string()).optional() })
|
|
730
730
|
}).partial();
|
|
731
731
|
async function preferExactDependencyVersions(program) {
|
|
732
|
-
const data =
|
|
732
|
+
const data = _alextheman_utility.az.with(pyprojectSchema).parse((0, toml.parse)(await (0, node_fs_promises.readFile)("pyproject.toml", "utf-8")));
|
|
733
733
|
const sections = [data.project?.dependencies ?? [], data["dependency-groups"]?.dev ?? []];
|
|
734
734
|
const violations = [];
|
|
735
735
|
for (const dependencies of sections) for (const dependency of dependencies) if (!dependency.includes("==")) violations.push(dependency);
|
|
@@ -745,7 +745,7 @@ const RuleName$1 = { PREFER_EXACT_DEPENDENCY_VERSIONS: "prefer-exact-dependency-
|
|
|
745
745
|
function pyprojectCheck(program) {
|
|
746
746
|
program.command("check").description("Run checks on your pyproject.toml file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
747
747
|
const rawRuleNamesArray = rawRules.split(",");
|
|
748
|
-
return
|
|
748
|
+
return _alextheman_utility.az.with(zod.default.array(zod.default.enum(RuleName$1))).parse(rawRuleNamesArray);
|
|
749
749
|
}).action(async ({ rules }) => {
|
|
750
750
|
if (rules?.includes("prefer-exact-dependency-versions")) await preferExactDependencyVersions(program);
|
|
751
751
|
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
@@ -838,7 +838,7 @@ function preCommit(program) {
|
|
|
838
838
|
}
|
|
839
839
|
const { packageManager: packagePackageManager, scripts } = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.join(process.cwd(), "package.json"), "utf8"));
|
|
840
840
|
const rawPackageManager = preCommitConfig.packageManager ?? (typeof packagePackageManager === "string" ? packagePackageManager.split("@")[0] : void 0);
|
|
841
|
-
const packageManager =
|
|
841
|
+
const packageManager = _alextheman_utility.az.with(zod.default.enum(_alextheman_utility_internal.PackageManager)).parse(rawPackageManager, new _alextheman_utility_v6.DataError({ packageManager: rawPackageManager }, "UNSUPPORTED_PACKAGE_MANAGER", `This package manager is not currently supported. Only the following are supported: ${Object.values(_alextheman_utility_internal.PackageManager).join(", ")}`));
|
|
842
842
|
const stepRunner = createStepRunner(program);
|
|
843
843
|
for (const step of preCommitConfig.steps) if (typeof step === "function") await step(stepRunner);
|
|
844
844
|
else if (typeof step === "string") await stepRunner(packageManager, getCommandArguments(program, step, scripts));
|
|
@@ -890,8 +890,8 @@ async function createPullRequestTemplatesFromTemplates(config) {
|
|
|
890
890
|
const allTemplates = {};
|
|
891
891
|
for (const templateFileName of allCategoryTemplateNames) {
|
|
892
892
|
const { content, data } = (0, gray_matter.default)(await (0, node_fs_promises.readFile)(node_path.default.join(categoryPath, templateFileName), "utf-8"));
|
|
893
|
-
const templateName =
|
|
894
|
-
const placeholders =
|
|
893
|
+
const templateName = _alextheman_utility.az.with(zod.default.string()).parse(data.id === "base" ? "pull_request_template" : data.id);
|
|
894
|
+
const placeholders = _alextheman_utility.az.with(zod.default.array(zod.default.string()).default([])).parse(data.placeholders);
|
|
895
895
|
let finalContent = content;
|
|
896
896
|
for (const placeholder of placeholders) {
|
|
897
897
|
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.");
|
|
@@ -905,14 +905,14 @@ async function createPullRequestTemplatesFromTemplates(config) {
|
|
|
905
905
|
//#region src/cli/commands/template/pullRequest/create.ts
|
|
906
906
|
function templatePullRequestCreate(program) {
|
|
907
907
|
program.command("create").option("--category <category>", "The category of pull request templates to get (can be either `general` or `infrastructure`)", (rawValue) => {
|
|
908
|
-
return
|
|
908
|
+
return _alextheman_utility.az.with(zod.default.enum(PullRequestTemplateCategory)).parse(rawValue, () => {
|
|
909
909
|
program.error(`Invalid template category ${rawValue}. The category must be one of \`general\` or \`infrastructure\``);
|
|
910
910
|
});
|
|
911
911
|
}).option("--project-name <projectName>", "The name of the package to use in the templates (leave blank to default to name found in package.json)").option("--project-type <projectType>", "The type of project, used in phrases such as 'adds a new feature to the {{projectType}}'. This option must not be specified if category is `infrastructure`").option("--infrastructure-provider <infrastructureProvider>", "If category is `infrastructure`, this would be the name of the Infrastructure provider (e.g. Terraform)").option("--require-confirmation-from <requireConfirmationFrom>", "If category is `infrastructure`, this would be the name of the user to get approval from if a manual change was required").description("Create pull request template files for a category (currently generates all templates in that category).").action(async (commandLineOptions) => {
|
|
912
912
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
913
913
|
const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
|
|
914
914
|
const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
|
|
915
|
-
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } :
|
|
915
|
+
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : _alextheman_utility.az.with(zod.default.object({ name: zod.default.string() })).parse(packageInfo);
|
|
916
916
|
if (!projectName) throw new _alextheman_utility_v6.DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
|
|
917
917
|
const parsedOptions = parseTemplatePullRequestConfig((0, _alextheman_utility.removeUndefinedFromObject)({
|
|
918
918
|
category: commandLineOptions.category ?? config?.category ?? "general",
|
|
@@ -990,7 +990,7 @@ function normaliseMarkdown(markdownString) {
|
|
|
990
990
|
function getReleaseStatus(content) {
|
|
991
991
|
const releaseStatus = getMarkdownBlock(content, ...getMarkdownCommentPair("alex-c-line-release-status"));
|
|
992
992
|
if (releaseStatus === null) throw new _alextheman_utility_v6.DataError({ releaseStatus }, "RELEASE_STATUS_NOT_FOUND", "Could not find release status in document.");
|
|
993
|
-
return
|
|
993
|
+
return _alextheman_utility.az.with(zod.default.enum(ReleaseStatus)).parse(normaliseMarkdown(releaseStatus.split(":")[1]));
|
|
994
994
|
}
|
|
995
995
|
//#endregion
|
|
996
996
|
//#region src/utility/markdownTemplates/releaseNote/validateReleaseDocument.ts
|
|
@@ -1034,7 +1034,7 @@ async function validateReleaseDocument(projectName, version, content, allowedRel
|
|
|
1034
1034
|
function templateReleaseNoteCheck(program) {
|
|
1035
1035
|
program.command("check").argument("<documentPath>", "The path to the document", _alextheman_utility_node.parseFilePath).option("--expected-release-status <expectedReleaseStatus>", "The expected release status of the document once we read it in.", parseReleaseStatus).description("Check whether a given release note is valid according to the templates or not. Returns exit code 0 for valid release note and non-zero otherwise.").action(async (documentPath, { expectedReleaseStatus }) => {
|
|
1036
1036
|
const fileContents = await (0, node_fs_promises.readFile)(node_path.default.join(process.cwd(), documentPath.fullPath), "utf-8");
|
|
1037
|
-
const { name } =
|
|
1037
|
+
const { name } = _alextheman_utility.az.with(zod.default.object({ name: zod.default.string() })).parse(await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd()), () => {
|
|
1038
1038
|
program.error("Your package.json is invalid");
|
|
1039
1039
|
});
|
|
1040
1040
|
const documentVersion = new _alextheman_utility.VersionNumber(documentPath.base.split(".").filter((part) => {
|
|
@@ -1064,7 +1064,7 @@ async function getEditableSectionFromTemplate(version) {
|
|
|
1064
1064
|
//#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
|
|
1065
1065
|
function replaceMarkdownPlaceholders(rawContent, templateVariables) {
|
|
1066
1066
|
const { content, data } = (0, gray_matter.default)(rawContent);
|
|
1067
|
-
const placeholders =
|
|
1067
|
+
const placeholders = _alextheman_utility.az.with(zod.default.array(zod.default.string()).default([])).parse(data.placeholders);
|
|
1068
1068
|
let finalContent = content;
|
|
1069
1069
|
for (const placeholder of placeholders) {
|
|
1070
1070
|
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.");
|
|
@@ -1123,10 +1123,10 @@ function templateReleaseNoteCreate(program) {
|
|
|
1123
1123
|
}
|
|
1124
1124
|
}).description("Create release notes based on the current version in package.json.").action(async (target) => {
|
|
1125
1125
|
const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
|
|
1126
|
-
const { name, version: packageVersion } =
|
|
1126
|
+
const { name, version: packageVersion } = _alextheman_utility.az.with(zod.default.object({
|
|
1127
1127
|
name: zod.default.string(),
|
|
1128
1128
|
version: zod.default.string()
|
|
1129
|
-
})
|
|
1129
|
+
})).parse(packageInfo);
|
|
1130
1130
|
const versionNumber = target instanceof _alextheman_utility.VersionNumber ? target : target ? new _alextheman_utility.VersionNumber(packageVersion).increment(target) : new _alextheman_utility.VersionNumber(packageVersion);
|
|
1131
1131
|
const releaseNotePath = getReleaseNotePath(versionNumber);
|
|
1132
1132
|
const releaseNoteTemplate = await createReleaseNoteFromTemplates(name, versionNumber, { status: "In progress" });
|
|
@@ -1162,7 +1162,7 @@ function templateReleaseNotePath(program) {
|
|
|
1162
1162
|
function templateReleaseNoteSetStatus(program) {
|
|
1163
1163
|
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) => {
|
|
1164
1164
|
const packageInfo = await (0, _alextheman_utility_internal.getPackageJsonContents)(process.cwd());
|
|
1165
|
-
const { name } =
|
|
1165
|
+
const { name } = _alextheman_utility.az.with(zod.default.object({ name: zod.default.string() })).parse(packageInfo, new _alextheman_utility_v6.DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
|
|
1166
1166
|
if (!documentPath.endsWith("md")) throw new _alextheman_utility_v6.DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
|
|
1167
1167
|
const versionNumber = new _alextheman_utility.VersionNumber(node_path.default.basename(documentPath).split(".").filter((part) => {
|
|
1168
1168
|
return part !== "md";
|
|
@@ -1204,7 +1204,7 @@ function template(program) {
|
|
|
1204
1204
|
//#endregion
|
|
1205
1205
|
//#region package.json
|
|
1206
1206
|
var name = "alex-c-line";
|
|
1207
|
-
var version$1 = "2.7.
|
|
1207
|
+
var version$1 = "2.7.2";
|
|
1208
1208
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1209
1209
|
//#endregion
|
|
1210
1210
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1271,7 +1271,7 @@ function uuid(program) {
|
|
|
1271
1271
|
//#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
|
|
1272
1272
|
function parseZodSchemaForProgram(program, schema, data) {
|
|
1273
1273
|
try {
|
|
1274
|
-
return
|
|
1274
|
+
return _alextheman_utility.az.with(schema).parse(data);
|
|
1275
1275
|
} catch (error) {
|
|
1276
1276
|
if (_alextheman_utility_v6.DataError.check(error)) convertDataErrorToProgramError(error, program);
|
|
1277
1277
|
throw error;
|
|
@@ -1396,7 +1396,7 @@ const RuleName = {
|
|
|
1396
1396
|
function packageJsonCheck(program) {
|
|
1397
1397
|
program.command("check").description("Run checks on your package.json file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
1398
1398
|
const rawRuleNamesArray = rawRules.split(",");
|
|
1399
|
-
return
|
|
1399
|
+
return _alextheman_utility.az.with(zod.default.array(zod.default.enum(RuleName))).parse(rawRuleNamesArray);
|
|
1400
1400
|
}).action(async ({ rules }) => {
|
|
1401
1401
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1402
1402
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
@@ -1481,7 +1481,7 @@ const alexCLineGlobalCacheSchema = zod.default.looseObject({ updateChecks: zod.d
|
|
|
1481
1481
|
//#endregion
|
|
1482
1482
|
//#region src/cache/global/parseAlexCLineGlobalCache.ts
|
|
1483
1483
|
function parseAlexCLineGlobalCache(input) {
|
|
1484
|
-
return
|
|
1484
|
+
return _alextheman_utility.az.with(alexCLineGlobalCacheSchema).parse(input);
|
|
1485
1485
|
}
|
|
1486
1486
|
//#endregion
|
|
1487
1487
|
//#region src/cache/global/loadAlexCLineGlobalCache.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, fillArray, getStringsAndInterpolations, interpolate, isTemplateStringsArray, kebabToCamel, normaliseIndents, omitProperties, parseBoolean, parseVersionType,
|
|
10
|
+
import { ONE_DAY_IN_MILLISECONDS, VersionNumber, az, fillArray, getStringsAndInterpolations, interpolate, isTemplateStringsArray, kebabToCamel, normaliseIndents, omitProperties, parseBoolean, parseVersionType, removeDuplicates, removeUndefinedFromObject, 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";
|
|
@@ -445,7 +445,7 @@ const templatePullRequestSchema = z.discriminatedUnion("category", [templatePull
|
|
|
445
445
|
requireConfirmationFrom: z.string()
|
|
446
446
|
})]);
|
|
447
447
|
function parseTemplatePullRequestConfig(input) {
|
|
448
|
-
return
|
|
448
|
+
return az.with(templatePullRequestSchema).parse(input);
|
|
449
449
|
}
|
|
450
450
|
//#endregion
|
|
451
451
|
//#region src/configs/helpers/defineAlexCLineConfig.ts
|
|
@@ -454,7 +454,7 @@ const alexCLineConfigSchema = z.strictObject({
|
|
|
454
454
|
template: z.object({ pullRequest: templatePullRequestSchema })
|
|
455
455
|
}).partial();
|
|
456
456
|
async function parseAlexCLineConfig(input) {
|
|
457
|
-
return await
|
|
457
|
+
return await az.with(alexCLineConfigSchema).parseAsync(input);
|
|
458
458
|
}
|
|
459
459
|
//#endregion
|
|
460
460
|
//#region src/configs/types/ConfigFileName.ts
|
|
@@ -487,7 +487,7 @@ const alexCLinePrivateConfigSchema = z.object({ localPackage: z.strictObject({
|
|
|
487
487
|
}))
|
|
488
488
|
}) });
|
|
489
489
|
function parseAlexCLinePrivateConfig(data) {
|
|
490
|
-
return
|
|
490
|
+
return az.with(alexCLinePrivateConfigSchema).parse(data);
|
|
491
491
|
}
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region src/cache/project/types/AlexCLineProjectCache.ts
|
|
@@ -501,7 +501,7 @@ const alexCLineProjectCacheSchema = z.object({ useLocalPackage: z.object({ depen
|
|
|
501
501
|
//#endregion
|
|
502
502
|
//#region src/cache/project/parseAlexCLineProjectCache.ts
|
|
503
503
|
function parseAlexCLineProjectCache(data) {
|
|
504
|
-
return
|
|
504
|
+
return az.with(alexCLineProjectCacheSchema).parse(data);
|
|
505
505
|
}
|
|
506
506
|
//#endregion
|
|
507
507
|
//#region src/cache/project/loadAlexCLineProjectCache.ts
|
|
@@ -608,7 +608,7 @@ function localPackageUse(program) {
|
|
|
608
608
|
const localPackagePath = path.resolve(process.cwd(), localPackage.path);
|
|
609
609
|
const localPackageInfo = await getPackageJsonContents(localPackagePath);
|
|
610
610
|
if (localPackageInfo === null) throw new DataError({ localPackagePath }, "MISSING_PACKAGE_REPOSITORY_PACKAGE_JSON", "Could not find package.json in the package repository.");
|
|
611
|
-
const localPackageRepositoryName =
|
|
611
|
+
const localPackageRepositoryName = az.with(z.string()).parse(localPackageInfo.name);
|
|
612
612
|
if (localPackageRepositoryName !== packageName) throw new DataError({
|
|
613
613
|
providedPackageName: packageName,
|
|
614
614
|
localPackagePath,
|
|
@@ -698,7 +698,7 @@ const pyprojectSchema = z.object({
|
|
|
698
698
|
"dependency-groups": z.object({ dev: z.array(z.string()).optional() })
|
|
699
699
|
}).partial();
|
|
700
700
|
async function preferExactDependencyVersions(program) {
|
|
701
|
-
const data =
|
|
701
|
+
const data = az.with(pyprojectSchema).parse(parse$1(await readFile("pyproject.toml", "utf-8")));
|
|
702
702
|
const sections = [data.project?.dependencies ?? [], data["dependency-groups"]?.dev ?? []];
|
|
703
703
|
const violations = [];
|
|
704
704
|
for (const dependencies of sections) for (const dependency of dependencies) if (!dependency.includes("==")) violations.push(dependency);
|
|
@@ -714,7 +714,7 @@ const RuleName$1 = { PREFER_EXACT_DEPENDENCY_VERSIONS: "prefer-exact-dependency-
|
|
|
714
714
|
function pyprojectCheck(program) {
|
|
715
715
|
program.command("check").description("Run checks on your pyproject.toml file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
716
716
|
const rawRuleNamesArray = rawRules.split(",");
|
|
717
|
-
return
|
|
717
|
+
return az.with(z.array(z.enum(RuleName$1))).parse(rawRuleNamesArray);
|
|
718
718
|
}).action(async ({ rules }) => {
|
|
719
719
|
if (rules?.includes("prefer-exact-dependency-versions")) await preferExactDependencyVersions(program);
|
|
720
720
|
console.info(`${SUCCESS_PREFIX} Success! All checks passed!`);
|
|
@@ -807,7 +807,7 @@ function preCommit(program) {
|
|
|
807
807
|
}
|
|
808
808
|
const { packageManager: packagePackageManager, scripts } = JSON.parse(await readFile(path.join(process.cwd(), "package.json"), "utf8"));
|
|
809
809
|
const rawPackageManager = preCommitConfig.packageManager ?? (typeof packagePackageManager === "string" ? packagePackageManager.split("@")[0] : void 0);
|
|
810
|
-
const packageManager =
|
|
810
|
+
const packageManager = az.with(z.enum(PackageManager)).parse(rawPackageManager, new DataError({ packageManager: rawPackageManager }, "UNSUPPORTED_PACKAGE_MANAGER", `This package manager is not currently supported. Only the following are supported: ${Object.values(PackageManager).join(", ")}`));
|
|
811
811
|
const stepRunner = createStepRunner(program);
|
|
812
812
|
for (const step of preCommitConfig.steps) if (typeof step === "function") await step(stepRunner);
|
|
813
813
|
else if (typeof step === "string") await stepRunner(packageManager, getCommandArguments(program, step, scripts));
|
|
@@ -859,8 +859,8 @@ async function createPullRequestTemplatesFromTemplates(config) {
|
|
|
859
859
|
const allTemplates = {};
|
|
860
860
|
for (const templateFileName of allCategoryTemplateNames) {
|
|
861
861
|
const { content, data } = matter(await readFile(path.join(categoryPath, templateFileName), "utf-8"));
|
|
862
|
-
const templateName =
|
|
863
|
-
const placeholders =
|
|
862
|
+
const templateName = az.with(z.string()).parse(data.id === "base" ? "pull_request_template" : data.id);
|
|
863
|
+
const placeholders = az.with(z.array(z.string()).default([])).parse(data.placeholders);
|
|
864
864
|
let finalContent = content;
|
|
865
865
|
for (const placeholder of placeholders) {
|
|
866
866
|
if (!(placeholder in templateVariables)) throw new DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
|
|
@@ -874,14 +874,14 @@ async function createPullRequestTemplatesFromTemplates(config) {
|
|
|
874
874
|
//#region src/cli/commands/template/pullRequest/create.ts
|
|
875
875
|
function templatePullRequestCreate(program) {
|
|
876
876
|
program.command("create").option("--category <category>", "The category of pull request templates to get (can be either `general` or `infrastructure`)", (rawValue) => {
|
|
877
|
-
return
|
|
877
|
+
return az.with(z.enum(PullRequestTemplateCategory)).parse(rawValue, () => {
|
|
878
878
|
program.error(`Invalid template category ${rawValue}. The category must be one of \`general\` or \`infrastructure\``);
|
|
879
879
|
});
|
|
880
880
|
}).option("--project-name <projectName>", "The name of the package to use in the templates (leave blank to default to name found in package.json)").option("--project-type <projectType>", "The type of project, used in phrases such as 'adds a new feature to the {{projectType}}'. This option must not be specified if category is `infrastructure`").option("--infrastructure-provider <infrastructureProvider>", "If category is `infrastructure`, this would be the name of the Infrastructure provider (e.g. Terraform)").option("--require-confirmation-from <requireConfirmationFrom>", "If category is `infrastructure`, this would be the name of the user to get approval from if a manual change was required").description("Create pull request template files for a category (currently generates all templates in that category).").action(async (commandLineOptions) => {
|
|
881
881
|
const configPath = await findAlexCLineConfig(process.cwd());
|
|
882
882
|
const { template: { pullRequest: config } = {} } = configPath ? await loadAlexCLineConfig(configPath) : {};
|
|
883
883
|
const packageInfo = await getPackageJsonContents(process.cwd());
|
|
884
|
-
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } :
|
|
884
|
+
const { name: projectName } = commandLineOptions.projectName || config?.projectName ? { name: commandLineOptions.projectName ?? config?.projectName } : az.with(z.object({ name: z.string() })).parse(packageInfo);
|
|
885
885
|
if (!projectName) throw new DataError({ projectName }, "PROJECT_NAME_NOT_FOUND", "Could not resolve project name.");
|
|
886
886
|
const parsedOptions = parseTemplatePullRequestConfig(removeUndefinedFromObject({
|
|
887
887
|
category: commandLineOptions.category ?? config?.category ?? "general",
|
|
@@ -959,7 +959,7 @@ function normaliseMarkdown(markdownString) {
|
|
|
959
959
|
function getReleaseStatus(content) {
|
|
960
960
|
const releaseStatus = getMarkdownBlock(content, ...getMarkdownCommentPair("alex-c-line-release-status"));
|
|
961
961
|
if (releaseStatus === null) throw new DataError({ releaseStatus }, "RELEASE_STATUS_NOT_FOUND", "Could not find release status in document.");
|
|
962
|
-
return
|
|
962
|
+
return az.with(z.enum(ReleaseStatus)).parse(normaliseMarkdown(releaseStatus.split(":")[1]));
|
|
963
963
|
}
|
|
964
964
|
//#endregion
|
|
965
965
|
//#region src/utility/markdownTemplates/releaseNote/validateReleaseDocument.ts
|
|
@@ -1003,7 +1003,7 @@ async function validateReleaseDocument(projectName, version, content, allowedRel
|
|
|
1003
1003
|
function templateReleaseNoteCheck(program) {
|
|
1004
1004
|
program.command("check").argument("<documentPath>", "The path to the document", parseFilePath).option("--expected-release-status <expectedReleaseStatus>", "The expected release status of the document once we read it in.", parseReleaseStatus).description("Check whether a given release note is valid according to the templates or not. Returns exit code 0 for valid release note and non-zero otherwise.").action(async (documentPath, { expectedReleaseStatus }) => {
|
|
1005
1005
|
const fileContents = await readFile(path.join(process.cwd(), documentPath.fullPath), "utf-8");
|
|
1006
|
-
const { name } =
|
|
1006
|
+
const { name } = az.with(z.object({ name: z.string() })).parse(await getPackageJsonContents(process.cwd()), () => {
|
|
1007
1007
|
program.error("Your package.json is invalid");
|
|
1008
1008
|
});
|
|
1009
1009
|
const documentVersion = new VersionNumber(documentPath.base.split(".").filter((part) => {
|
|
@@ -1033,7 +1033,7 @@ async function getEditableSectionFromTemplate(version) {
|
|
|
1033
1033
|
//#region src/utility/markdownTemplates/replaceMarkdownPlaceholders.ts
|
|
1034
1034
|
function replaceMarkdownPlaceholders(rawContent, templateVariables) {
|
|
1035
1035
|
const { content, data } = matter(rawContent);
|
|
1036
|
-
const placeholders =
|
|
1036
|
+
const placeholders = az.with(z.array(z.string()).default([])).parse(data.placeholders);
|
|
1037
1037
|
let finalContent = content;
|
|
1038
1038
|
for (const placeholder of placeholders) {
|
|
1039
1039
|
if (!(placeholder in templateVariables)) throw new DataError({ placeholder }, "INVALID_PLACEHOLDER", "The placeholder found in frontmatter can not be found in the metadata.");
|
|
@@ -1092,10 +1092,10 @@ function templateReleaseNoteCreate(program) {
|
|
|
1092
1092
|
}
|
|
1093
1093
|
}).description("Create release notes based on the current version in package.json.").action(async (target) => {
|
|
1094
1094
|
const packageInfo = await getPackageJsonContents(process.cwd());
|
|
1095
|
-
const { name, version: packageVersion } =
|
|
1095
|
+
const { name, version: packageVersion } = az.with(z.object({
|
|
1096
1096
|
name: z.string(),
|
|
1097
1097
|
version: z.string()
|
|
1098
|
-
})
|
|
1098
|
+
})).parse(packageInfo);
|
|
1099
1099
|
const versionNumber = target instanceof VersionNumber ? target : target ? new VersionNumber(packageVersion).increment(target) : new VersionNumber(packageVersion);
|
|
1100
1100
|
const releaseNotePath = getReleaseNotePath(versionNumber);
|
|
1101
1101
|
const releaseNoteTemplate = await createReleaseNoteFromTemplates(name, versionNumber, { status: "In progress" });
|
|
@@ -1131,7 +1131,7 @@ function templateReleaseNotePath(program) {
|
|
|
1131
1131
|
function templateReleaseNoteSetStatus(program) {
|
|
1132
1132
|
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) => {
|
|
1133
1133
|
const packageInfo = await getPackageJsonContents(process.cwd());
|
|
1134
|
-
const { name } =
|
|
1134
|
+
const { name } = az.with(z.object({ name: z.string() })).parse(packageInfo, new DataError({ name: packageInfo?.name }, "INVALID_PACKAGE_JSON", "Invalid package.json - expected package.json to contain a `name` property."));
|
|
1135
1135
|
if (!documentPath.endsWith("md")) throw new DataError({ documentPath }, "INVALID_FILE_PATH", "Invalid file path. Path must lead to a .md file.");
|
|
1136
1136
|
const versionNumber = new VersionNumber(path.basename(documentPath).split(".").filter((part) => {
|
|
1137
1137
|
return part !== "md";
|
|
@@ -1173,7 +1173,7 @@ function template(program) {
|
|
|
1173
1173
|
//#endregion
|
|
1174
1174
|
//#region package.json
|
|
1175
1175
|
var name = "alex-c-line";
|
|
1176
|
-
var version$1 = "2.7.
|
|
1176
|
+
var version$1 = "2.7.2";
|
|
1177
1177
|
var description = "Command-line tool with commands to streamline the developer workflow.";
|
|
1178
1178
|
//#endregion
|
|
1179
1179
|
//#region src/utility/updates/checkUpdate.ts
|
|
@@ -1240,7 +1240,7 @@ function uuid(program) {
|
|
|
1240
1240
|
//#region src/utility/miscellaneous/parseZodSchemaForProgram.ts
|
|
1241
1241
|
function parseZodSchemaForProgram(program, schema, data) {
|
|
1242
1242
|
try {
|
|
1243
|
-
return
|
|
1243
|
+
return az.with(schema).parse(data);
|
|
1244
1244
|
} catch (error) {
|
|
1245
1245
|
if (DataError.check(error)) convertDataErrorToProgramError(error, program);
|
|
1246
1246
|
throw error;
|
|
@@ -1365,7 +1365,7 @@ const RuleName = {
|
|
|
1365
1365
|
function packageJsonCheck(program) {
|
|
1366
1366
|
program.command("check").description("Run checks on your package.json file").option("--rules <rules>", "The name of the rule to check", (rawRules) => {
|
|
1367
1367
|
const rawRuleNamesArray = rawRules.split(",");
|
|
1368
|
-
return
|
|
1368
|
+
return az.with(z.array(z.enum(RuleName))).parse(rawRuleNamesArray);
|
|
1369
1369
|
}).action(async ({ rules }) => {
|
|
1370
1370
|
if (rules?.includes("no-pre-release-dependencies")) await noPreReleaseDependencies(program);
|
|
1371
1371
|
if (rules?.includes("no-file-dependencies")) await noFileDependencies(program);
|
|
@@ -1450,7 +1450,7 @@ const alexCLineGlobalCacheSchema = z.looseObject({ updateChecks: z.record(z.stri
|
|
|
1450
1450
|
//#endregion
|
|
1451
1451
|
//#region src/cache/global/parseAlexCLineGlobalCache.ts
|
|
1452
1452
|
function parseAlexCLineGlobalCache(input) {
|
|
1453
|
-
return
|
|
1453
|
+
return az.with(alexCLineGlobalCacheSchema).parse(input);
|
|
1454
1454
|
}
|
|
1455
1455
|
//#endregion
|
|
1456
1456
|
//#region src/cache/global/loadAlexCLineGlobalCache.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alex-c-line",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Command-line tool with commands to streamline the developer workflow.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"templates"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@alextheman/utility": "5.
|
|
38
|
-
"@inquirer/prompts": "8.4.
|
|
39
|
-
"axios": "1.15.
|
|
37
|
+
"@alextheman/utility": "5.14.0",
|
|
38
|
+
"@inquirer/prompts": "8.4.2",
|
|
39
|
+
"axios": "1.15.2",
|
|
40
40
|
"boxen": "8.0.1",
|
|
41
41
|
"chalk": "5.6.2",
|
|
42
42
|
"commander": "14.0.3",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"zod": "4.3.6"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@alextheman/eslint-plugin": "5.13.
|
|
55
|
+
"@alextheman/eslint-plugin": "5.13.1",
|
|
56
56
|
"@commander-js/extra-typings": "14.0.0",
|
|
57
57
|
"@types/eslint": "9.6.1",
|
|
58
58
|
"@types/node": "25.6.0",
|
|
@@ -62,15 +62,15 @@
|
|
|
62
62
|
"dotenv-cli": "11.0.0",
|
|
63
63
|
"eslint": "10.2.1",
|
|
64
64
|
"husky": "9.1.7",
|
|
65
|
-
"markdownlint-cli2": "0.22.
|
|
65
|
+
"markdownlint-cli2": "0.22.1",
|
|
66
66
|
"prettier": "3.8.3",
|
|
67
67
|
"tempy": "3.2.0",
|
|
68
68
|
"ts-node": "10.9.2",
|
|
69
|
-
"tsdown": "0.21.
|
|
69
|
+
"tsdown": "0.21.10",
|
|
70
70
|
"typescript": "6.0.3",
|
|
71
|
-
"typescript-eslint": "8.
|
|
72
|
-
"vite": "8.0.
|
|
73
|
-
"vitest": "4.1.
|
|
71
|
+
"typescript-eslint": "8.59.0",
|
|
72
|
+
"vite": "8.0.10",
|
|
73
|
+
"vitest": "4.1.5"
|
|
74
74
|
},
|
|
75
75
|
"engines": {
|
|
76
76
|
"node": ">=22.0.0"
|