@codluv/versionguard 0.6.0 → 0.7.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/changelog.d.ts +21 -2
- package/dist/changelog.d.ts.map +1 -1
- package/dist/chunks/{index-DeZAx4Le.js → index-DWiw8Nps.js} +47 -5
- package/dist/chunks/index-DWiw8Nps.js.map +1 -0
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tag/index.d.ts.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/chunks/index-DeZAx4Le.js.map +0 -1
package/dist/changelog.d.ts
CHANGED
|
@@ -19,6 +19,18 @@ export interface ChangelogValidationResult {
|
|
|
19
19
|
*/
|
|
20
20
|
hasEntryForVersion: boolean;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Options for changelog structure enforcement.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
* @since 0.7.0
|
|
27
|
+
*/
|
|
28
|
+
export interface ChangelogStructureOptions {
|
|
29
|
+
/** Validate section headers against an allowed list. */
|
|
30
|
+
enforceStructure?: boolean;
|
|
31
|
+
/** Allowed section names. Defaults to Keep a Changelog standard sections. */
|
|
32
|
+
sections?: string[];
|
|
33
|
+
}
|
|
22
34
|
/**
|
|
23
35
|
* Validates a changelog file for release readiness.
|
|
24
36
|
*
|
|
@@ -28,19 +40,26 @@ export interface ChangelogValidationResult {
|
|
|
28
40
|
* The validator checks for a top-level changelog heading, an `[Unreleased]`
|
|
29
41
|
* section, and optionally a dated entry for the requested version.
|
|
30
42
|
*
|
|
43
|
+
* When `structure.enforceStructure` is `true`, section headers (`### Name`)
|
|
44
|
+
* are validated against the allowed list and empty sections produce warnings.
|
|
45
|
+
*
|
|
31
46
|
* @param changelogPath - Path to the changelog file.
|
|
32
47
|
* @param version - Version that must be present in the changelog.
|
|
33
48
|
* @param strict - Whether to require compare links and dated release headings.
|
|
34
49
|
* @param requireEntry - Whether the requested version must already have an entry.
|
|
50
|
+
* @param structure - Optional structure enforcement options.
|
|
35
51
|
* @returns The result of validating the changelog file.
|
|
36
52
|
* @example
|
|
37
53
|
* ```ts
|
|
38
54
|
* import { validateChangelog } from 'versionguard';
|
|
39
55
|
*
|
|
40
|
-
* const result = validateChangelog('CHANGELOG.md', '1.2.0', true, true
|
|
56
|
+
* const result = validateChangelog('CHANGELOG.md', '1.2.0', true, true, {
|
|
57
|
+
* enforceStructure: true,
|
|
58
|
+
* sections: ['Added', 'Changed', 'Fixed'],
|
|
59
|
+
* });
|
|
41
60
|
* ```
|
|
42
61
|
*/
|
|
43
|
-
export declare function validateChangelog(changelogPath: string, version: string, strict?: boolean, requireEntry?: boolean): ChangelogValidationResult;
|
|
62
|
+
export declare function validateChangelog(changelogPath: string, version: string, strict?: boolean, requireEntry?: boolean, structure?: ChangelogStructureOptions): ChangelogValidationResult;
|
|
44
63
|
/**
|
|
45
64
|
* Gets the most recent released version from a changelog.
|
|
46
65
|
*
|
package/dist/changelog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../src/changelog.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../src/changelog.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAcD;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,OAAc,EACtB,YAAY,GAAE,OAAc,EAC5B,SAAS,CAAC,EAAE,yBAAyB,GACpC,yBAAyB,CAuD3B;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAA8C,GACnD,IAAI,CAmBN;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAMjE;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE,MAA8C,GACnD,OAAO,CAoET"}
|
|
@@ -323,7 +323,15 @@ const calver = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
323
323
|
validate: validate$2
|
|
324
324
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
325
325
|
const CHANGELOG_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
326
|
-
|
|
326
|
+
const KEEP_A_CHANGELOG_SECTIONS = [
|
|
327
|
+
"Added",
|
|
328
|
+
"Changed",
|
|
329
|
+
"Deprecated",
|
|
330
|
+
"Removed",
|
|
331
|
+
"Fixed",
|
|
332
|
+
"Security"
|
|
333
|
+
];
|
|
334
|
+
function validateChangelog(changelogPath, version, strict = true, requireEntry = true, structure) {
|
|
327
335
|
if (!fs.existsSync(changelogPath)) {
|
|
328
336
|
return {
|
|
329
337
|
valid: !requireEntry,
|
|
@@ -360,12 +368,36 @@ function validateChangelog(changelogPath, version, strict = true, requireEntry =
|
|
|
360
368
|
}
|
|
361
369
|
}
|
|
362
370
|
}
|
|
371
|
+
if (structure?.enforceStructure) {
|
|
372
|
+
const allowed = structure.sections ?? KEEP_A_CHANGELOG_SECTIONS;
|
|
373
|
+
const sectionErrors = validateSections(content, allowed);
|
|
374
|
+
errors.push(...sectionErrors);
|
|
375
|
+
}
|
|
363
376
|
return {
|
|
364
377
|
valid: errors.length === 0,
|
|
365
378
|
errors,
|
|
366
379
|
hasEntryForVersion
|
|
367
380
|
};
|
|
368
381
|
}
|
|
382
|
+
function validateSections(content, allowed) {
|
|
383
|
+
const errors = [];
|
|
384
|
+
const lines = content.split("\n");
|
|
385
|
+
for (let i = 0; i < lines.length; i++) {
|
|
386
|
+
const sectionMatch = lines[i].match(/^### (.+)/);
|
|
387
|
+
if (!sectionMatch) continue;
|
|
388
|
+
const sectionName = sectionMatch[1].trim();
|
|
389
|
+
if (!allowed.includes(sectionName)) {
|
|
390
|
+
errors.push(
|
|
391
|
+
`Invalid changelog section "### ${sectionName}" (line ${i + 1}). Allowed: ${allowed.join(", ")}`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
const nextContentLine = lines.slice(i + 1).find((l) => l.trim().length > 0);
|
|
395
|
+
if (!nextContentLine || nextContentLine.startsWith("#")) {
|
|
396
|
+
errors.push(`Empty changelog section "### ${sectionName}" (line ${i + 1})`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return errors;
|
|
400
|
+
}
|
|
369
401
|
function addVersionEntry(changelogPath, version, date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)) {
|
|
370
402
|
if (!fs.existsSync(changelogPath)) {
|
|
371
403
|
throw new Error(`Changelog not found: ${changelogPath}`);
|
|
@@ -1775,7 +1807,9 @@ const DEFAULT_CONFIG = {
|
|
|
1775
1807
|
enabled: true,
|
|
1776
1808
|
file: "CHANGELOG.md",
|
|
1777
1809
|
strict: true,
|
|
1778
|
-
requireEntry: true
|
|
1810
|
+
requireEntry: true,
|
|
1811
|
+
enforceStructure: false,
|
|
1812
|
+
sections: ["Added", "Changed", "Deprecated", "Removed", "Fixed", "Security"]
|
|
1779
1813
|
},
|
|
1780
1814
|
git: {
|
|
1781
1815
|
hooks: {
|
|
@@ -2690,7 +2724,11 @@ function getTagPreflightError(config, cwd, expectedVersion, allowAutoFix = false
|
|
|
2690
2724
|
path.join(cwd, config.changelog.file),
|
|
2691
2725
|
version,
|
|
2692
2726
|
config.changelog.strict,
|
|
2693
|
-
config.changelog.requireEntry
|
|
2727
|
+
config.changelog.requireEntry,
|
|
2728
|
+
{
|
|
2729
|
+
enforceStructure: config.changelog.enforceStructure,
|
|
2730
|
+
sections: config.changelog.sections
|
|
2731
|
+
}
|
|
2694
2732
|
);
|
|
2695
2733
|
if (!changelogResult.valid) {
|
|
2696
2734
|
return changelogResult.errors[0] ?? "Changelog validation failed";
|
|
@@ -2798,7 +2836,11 @@ function validate(config, cwd = process.cwd()) {
|
|
|
2798
2836
|
changelogPath,
|
|
2799
2837
|
version,
|
|
2800
2838
|
config.changelog.strict,
|
|
2801
|
-
config.changelog.requireEntry
|
|
2839
|
+
config.changelog.requireEntry,
|
|
2840
|
+
{
|
|
2841
|
+
enforceStructure: config.changelog.enforceStructure,
|
|
2842
|
+
sections: config.changelog.sections
|
|
2843
|
+
}
|
|
2802
2844
|
);
|
|
2803
2845
|
if (!changelogResult.valid) {
|
|
2804
2846
|
changelogValid = false;
|
|
@@ -2937,4 +2979,4 @@ export {
|
|
|
2937
2979
|
canBump as y,
|
|
2938
2980
|
checkEnforceHooksPolicy as z
|
|
2939
2981
|
};
|
|
2940
|
-
//# sourceMappingURL=index-
|
|
2982
|
+
//# sourceMappingURL=index-DWiw8Nps.js.map
|