@doccov/cli 0.15.1 → 0.17.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/cli.js +247 -8
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +10 -2
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/config/doccov-config.ts
|
|
4
|
-
import { access } from "node:fs/promises";
|
|
4
|
+
import { access, readFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { parse as parseYaml } from "yaml";
|
|
7
8
|
|
|
8
9
|
// src/config/schema.ts
|
|
9
10
|
import { z } from "zod";
|
|
@@ -95,7 +96,9 @@ var DOCCOV_CONFIG_FILENAMES = [
|
|
|
95
96
|
"doccov.config.cts",
|
|
96
97
|
"doccov.config.js",
|
|
97
98
|
"doccov.config.mjs",
|
|
98
|
-
"doccov.config.cjs"
|
|
99
|
+
"doccov.config.cjs",
|
|
100
|
+
"doccov.yml",
|
|
101
|
+
"doccov.yaml"
|
|
99
102
|
];
|
|
100
103
|
var fileExists = async (filePath) => {
|
|
101
104
|
try {
|
|
@@ -122,6 +125,11 @@ var findConfigFile = async (cwd) => {
|
|
|
122
125
|
}
|
|
123
126
|
};
|
|
124
127
|
var importConfigModule = async (absolutePath) => {
|
|
128
|
+
const ext = path.extname(absolutePath);
|
|
129
|
+
if (ext === ".yml" || ext === ".yaml") {
|
|
130
|
+
const content = await readFile(absolutePath, "utf-8");
|
|
131
|
+
return parseYaml(content);
|
|
132
|
+
}
|
|
125
133
|
const fileUrl = pathToFileURL(absolutePath);
|
|
126
134
|
fileUrl.searchParams.set("t", Date.now().toString());
|
|
127
135
|
const module = await import(fileUrl.href);
|
|
@@ -557,6 +565,205 @@ function renderHtml(stats, options = {}) {
|
|
|
557
565
|
</body>
|
|
558
566
|
</html>`;
|
|
559
567
|
}
|
|
568
|
+
// src/reports/pr-comment.ts
|
|
569
|
+
function renderPRComment(data, opts = {}) {
|
|
570
|
+
const { diff, headSpec } = data;
|
|
571
|
+
const limit = opts.limit ?? 10;
|
|
572
|
+
const lines = [];
|
|
573
|
+
const hasIssues = diff.newUndocumented.length > 0 || diff.driftIntroduced > 0 || diff.breaking.length > 0 || opts.minCoverage !== undefined && diff.newCoverage < opts.minCoverage;
|
|
574
|
+
const statusIcon = hasIssues ? diff.coverageDelta < 0 ? "❌" : "⚠️" : "✅";
|
|
575
|
+
lines.push(`## ${statusIcon} DocCov — Documentation Coverage`);
|
|
576
|
+
lines.push("");
|
|
577
|
+
const targetStr = opts.minCoverage !== undefined ? ` (target: ${opts.minCoverage}%) ${diff.newCoverage >= opts.minCoverage ? "✅" : "❌"}` : "";
|
|
578
|
+
lines.push(`**Patch coverage:** ${diff.newCoverage}%${targetStr}`);
|
|
579
|
+
if (diff.newUndocumented.length > 0) {
|
|
580
|
+
lines.push(`**New undocumented exports:** ${diff.newUndocumented.length}`);
|
|
581
|
+
}
|
|
582
|
+
if (diff.driftIntroduced > 0) {
|
|
583
|
+
lines.push(`**Doc drift issues:** ${diff.driftIntroduced}`);
|
|
584
|
+
}
|
|
585
|
+
if (diff.newUndocumented.length > 0) {
|
|
586
|
+
lines.push("");
|
|
587
|
+
lines.push("### Undocumented exports in this PR");
|
|
588
|
+
lines.push("");
|
|
589
|
+
renderUndocumentedExports(lines, diff.newUndocumented, headSpec, opts, limit);
|
|
590
|
+
}
|
|
591
|
+
if (diff.driftIntroduced > 0 && headSpec) {
|
|
592
|
+
lines.push("");
|
|
593
|
+
lines.push("### Doc drift detected");
|
|
594
|
+
lines.push("");
|
|
595
|
+
renderDriftIssues(lines, diff.newUndocumented, headSpec, opts, limit);
|
|
596
|
+
}
|
|
597
|
+
const fixGuidance = renderFixGuidance(diff);
|
|
598
|
+
if (fixGuidance) {
|
|
599
|
+
lines.push("");
|
|
600
|
+
lines.push("### How to fix");
|
|
601
|
+
lines.push("");
|
|
602
|
+
lines.push(fixGuidance);
|
|
603
|
+
}
|
|
604
|
+
lines.push("");
|
|
605
|
+
lines.push("<details>");
|
|
606
|
+
lines.push("<summary>View full report</summary>");
|
|
607
|
+
lines.push("");
|
|
608
|
+
renderDetailsTable(lines, diff);
|
|
609
|
+
lines.push("");
|
|
610
|
+
lines.push("</details>");
|
|
611
|
+
return lines.join(`
|
|
612
|
+
`);
|
|
613
|
+
}
|
|
614
|
+
function renderUndocumentedExports(lines, undocumented, headSpec, opts, limit) {
|
|
615
|
+
if (!headSpec) {
|
|
616
|
+
for (const name of undocumented.slice(0, limit)) {
|
|
617
|
+
lines.push(`- \`${name}\``);
|
|
618
|
+
}
|
|
619
|
+
if (undocumented.length > limit) {
|
|
620
|
+
lines.push(`- _...and ${undocumented.length - limit} more_`);
|
|
621
|
+
}
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const byFile = new Map;
|
|
625
|
+
const undocSet = new Set(undocumented);
|
|
626
|
+
for (const exp of headSpec.exports) {
|
|
627
|
+
if (undocSet.has(exp.name)) {
|
|
628
|
+
const file = exp.source?.file ?? "unknown";
|
|
629
|
+
const list = byFile.get(file) ?? [];
|
|
630
|
+
list.push(exp);
|
|
631
|
+
byFile.set(file, list);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
let count = 0;
|
|
635
|
+
for (const [file, exports] of byFile) {
|
|
636
|
+
if (count >= limit)
|
|
637
|
+
break;
|
|
638
|
+
const fileLink = buildFileLink(file, opts);
|
|
639
|
+
lines.push(`\uD83D\uDCC1 ${fileLink}`);
|
|
640
|
+
for (const exp of exports) {
|
|
641
|
+
if (count >= limit) {
|
|
642
|
+
lines.push(`- _...and more_`);
|
|
643
|
+
break;
|
|
644
|
+
}
|
|
645
|
+
const sig = formatExportSignature(exp);
|
|
646
|
+
lines.push(`- \`${sig}\``);
|
|
647
|
+
const missing = getMissingSignals(exp);
|
|
648
|
+
if (missing.length > 0) {
|
|
649
|
+
lines.push(` - Missing: ${missing.join(", ")}`);
|
|
650
|
+
}
|
|
651
|
+
count++;
|
|
652
|
+
}
|
|
653
|
+
lines.push("");
|
|
654
|
+
}
|
|
655
|
+
if (undocumented.length > count) {
|
|
656
|
+
lines.push(`_...and ${undocumented.length - count} more undocumented exports_`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
function renderDriftIssues(lines, _undocumented, headSpec, opts, limit) {
|
|
660
|
+
const driftIssues = [];
|
|
661
|
+
for (const exp of headSpec.exports) {
|
|
662
|
+
const drifts = exp.docs?.drift;
|
|
663
|
+
if (drifts) {
|
|
664
|
+
for (const d of drifts) {
|
|
665
|
+
driftIssues.push({
|
|
666
|
+
exportName: exp.name,
|
|
667
|
+
file: exp.source?.file,
|
|
668
|
+
drift: d
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (driftIssues.length === 0) {
|
|
674
|
+
lines.push("_No specific drift details available_");
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
for (const issue of driftIssues.slice(0, limit)) {
|
|
678
|
+
const fileRef = issue.file ? `\`${issue.file}\`` : "unknown file";
|
|
679
|
+
const fileLink = issue.file ? buildFileLink(issue.file, opts) : fileRef;
|
|
680
|
+
lines.push(`⚠️ ${fileLink}: \`${issue.exportName}\``);
|
|
681
|
+
lines.push(`- ${issue.drift.issue}`);
|
|
682
|
+
if (issue.drift.suggestion) {
|
|
683
|
+
lines.push(`- Fix: ${issue.drift.suggestion}`);
|
|
684
|
+
}
|
|
685
|
+
lines.push("");
|
|
686
|
+
}
|
|
687
|
+
if (driftIssues.length > limit) {
|
|
688
|
+
lines.push(`_...and ${driftIssues.length - limit} more drift issues_`);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
function buildFileLink(file, opts) {
|
|
692
|
+
if (opts.repoUrl && opts.sha) {
|
|
693
|
+
const url = `${opts.repoUrl}/blob/${opts.sha}/${file}`;
|
|
694
|
+
return `[\`${file}\`](${url})`;
|
|
695
|
+
}
|
|
696
|
+
return `\`${file}\``;
|
|
697
|
+
}
|
|
698
|
+
function formatExportSignature(exp) {
|
|
699
|
+
const prefix = `export ${exp.kind === "type" ? "type" : exp.kind === "interface" ? "interface" : exp.kind === "class" ? "class" : "function"}`;
|
|
700
|
+
if (exp.kind === "function" && exp.signatures?.[0]) {
|
|
701
|
+
const sig = exp.signatures[0];
|
|
702
|
+
const params = sig.parameters?.map((p) => `${p.name}${p.required === false ? "?" : ""}`).join(", ") ?? "";
|
|
703
|
+
const ret = sig.returns?.tsType ?? "void";
|
|
704
|
+
return `${prefix} ${exp.name}(${params}): ${ret}`;
|
|
705
|
+
}
|
|
706
|
+
if (exp.kind === "type" || exp.kind === "interface") {
|
|
707
|
+
return `${prefix} ${exp.name}`;
|
|
708
|
+
}
|
|
709
|
+
if (exp.kind === "class") {
|
|
710
|
+
return `${prefix} ${exp.name}`;
|
|
711
|
+
}
|
|
712
|
+
return `export ${exp.kind} ${exp.name}`;
|
|
713
|
+
}
|
|
714
|
+
function getMissingSignals(exp) {
|
|
715
|
+
const missing = [];
|
|
716
|
+
if (!exp.description) {
|
|
717
|
+
missing.push("description");
|
|
718
|
+
}
|
|
719
|
+
if (exp.kind === "function" && exp.signatures?.[0]) {
|
|
720
|
+
const sig = exp.signatures[0];
|
|
721
|
+
const undocParams = sig.parameters?.filter((p) => !p.description) ?? [];
|
|
722
|
+
if (undocParams.length > 0) {
|
|
723
|
+
missing.push(`\`@param ${undocParams.map((p) => p.name).join(", ")}\``);
|
|
724
|
+
}
|
|
725
|
+
if (!sig.returns?.description && sig.returns?.tsType !== "void") {
|
|
726
|
+
missing.push("`@returns`");
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return missing;
|
|
730
|
+
}
|
|
731
|
+
function renderFixGuidance(diff) {
|
|
732
|
+
const sections = [];
|
|
733
|
+
if (diff.newUndocumented.length > 0) {
|
|
734
|
+
sections.push(`**For undocumented exports:**
|
|
735
|
+
` + "Add JSDoc/TSDoc blocks with description, `@param`, and `@returns` tags.");
|
|
736
|
+
}
|
|
737
|
+
if (diff.driftIntroduced > 0) {
|
|
738
|
+
sections.push(`**For doc drift:**
|
|
739
|
+
` + "Update the code examples in your markdown files to match current signatures.");
|
|
740
|
+
}
|
|
741
|
+
if (diff.breaking.length > 0) {
|
|
742
|
+
sections.push(`**For breaking changes:**
|
|
743
|
+
` + "Consider adding a migration guide or updating changelog.");
|
|
744
|
+
}
|
|
745
|
+
if (sections.length === 0) {
|
|
746
|
+
return "";
|
|
747
|
+
}
|
|
748
|
+
sections.push(`
|
|
749
|
+
Push your changes — DocCov re-checks automatically.`);
|
|
750
|
+
return sections.join(`
|
|
751
|
+
|
|
752
|
+
`);
|
|
753
|
+
}
|
|
754
|
+
function renderDetailsTable(lines, diff) {
|
|
755
|
+
const delta = (n) => n > 0 ? `+${n}` : n === 0 ? "0" : String(n);
|
|
756
|
+
lines.push("| Metric | Before | After | Delta |");
|
|
757
|
+
lines.push("|--------|--------|-------|-------|");
|
|
758
|
+
lines.push(`| Coverage | ${diff.oldCoverage}% | ${diff.newCoverage}% | ${delta(diff.coverageDelta)}% |`);
|
|
759
|
+
lines.push(`| Breaking changes | - | ${diff.breaking.length} | - |`);
|
|
760
|
+
lines.push(`| New exports | - | ${diff.nonBreaking.length} | - |`);
|
|
761
|
+
lines.push(`| Undocumented | - | ${diff.newUndocumented.length} | - |`);
|
|
762
|
+
if (diff.driftIntroduced > 0 || diff.driftResolved > 0) {
|
|
763
|
+
const driftDelta = diff.driftIntroduced - diff.driftResolved;
|
|
764
|
+
lines.push(`| Drift | - | - | ${delta(driftDelta)} |`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
560
767
|
// src/reports/stats.ts
|
|
561
768
|
import { isFixableDrift } from "@doccov/sdk";
|
|
562
769
|
import {
|
|
@@ -1308,7 +1515,7 @@ function registerDiffCommand(program, dependencies = {}) {
|
|
|
1308
1515
|
...defaultDependencies2,
|
|
1309
1516
|
...dependencies
|
|
1310
1517
|
};
|
|
1311
|
-
program.command("diff [base] [head]").description("Compare two OpenPkg specs and detect breaking changes").option("--base <file>", 'Base spec file (the "before" state)').option("--head <file>", 'Head spec file (the "after" state)').option("--format <format>", "Output format: text, json, markdown, html, github", "text").option("--stdout", "Output to stdout instead of writing to .doccov/").option("-o, --output <file>", "Custom output path").option("--cwd <dir>", "Working directory", process.cwd()).option("--limit <n>", "Max items to show in terminal/reports", "10").option("--min-coverage <n>", "Minimum coverage % for HEAD spec (0-100)").option("--max-drift <n>", "Maximum drift % for HEAD spec (0-100)").option("--strict <preset>", "Fail on conditions: ci, release, quality").option("--docs <glob>", "Glob pattern for markdown docs to check for impact", collect, []).option("--ai", "Use AI for deeper analysis and fix suggestions").option("--no-cache", "Bypass cache and force regeneration").action(async (baseArg, headArg, options) => {
|
|
1518
|
+
program.command("diff [base] [head]").description("Compare two OpenPkg specs and detect breaking changes").option("--base <file>", 'Base spec file (the "before" state)').option("--head <file>", 'Head spec file (the "after" state)').option("--format <format>", "Output format: text, json, markdown, html, github, pr-comment", "text").option("--stdout", "Output to stdout instead of writing to .doccov/").option("-o, --output <file>", "Custom output path").option("--cwd <dir>", "Working directory", process.cwd()).option("--limit <n>", "Max items to show in terminal/reports", "10").option("--repo-url <url>", "GitHub repo URL for file links (pr-comment format)").option("--sha <sha>", "Commit SHA for file links (pr-comment format)").option("--min-coverage <n>", "Minimum coverage % for HEAD spec (0-100)").option("--max-drift <n>", "Maximum drift % for HEAD spec (0-100)").option("--strict <preset>", "Fail on conditions: ci, release, quality").option("--docs <glob>", "Glob pattern for markdown docs to check for impact", collect, []).option("--ai", "Use AI for deeper analysis and fix suggestions").option("--no-cache", "Bypass cache and force regeneration").action(async (baseArg, headArg, options) => {
|
|
1312
1519
|
try {
|
|
1313
1520
|
const baseFile = options.base ?? baseArg;
|
|
1314
1521
|
const headFile = options.head ?? headArg;
|
|
@@ -1418,6 +1625,16 @@ function registerDiffCommand(program, dependencies = {}) {
|
|
|
1418
1625
|
case "github":
|
|
1419
1626
|
printGitHubAnnotations(diff, log);
|
|
1420
1627
|
break;
|
|
1628
|
+
case "pr-comment": {
|
|
1629
|
+
const content = renderPRComment({ diff, baseName, headName, headSpec }, {
|
|
1630
|
+
repoUrl: options.repoUrl,
|
|
1631
|
+
sha: options.sha,
|
|
1632
|
+
minCoverage,
|
|
1633
|
+
limit
|
|
1634
|
+
});
|
|
1635
|
+
log(content);
|
|
1636
|
+
break;
|
|
1637
|
+
}
|
|
1421
1638
|
}
|
|
1422
1639
|
const failures = validateDiff(diff, headSpec, {
|
|
1423
1640
|
minCoverage,
|
|
@@ -1669,11 +1886,11 @@ function registerInitCommand(program, dependencies = {}) {
|
|
|
1669
1886
|
...defaultDependencies3,
|
|
1670
1887
|
...dependencies
|
|
1671
1888
|
};
|
|
1672
|
-
program.command("init").description("Create a DocCov configuration file").option("--cwd <dir>", "Working directory", process.cwd()).option("--format <format>", "Config format: auto, mjs, js, cjs", "auto").action((options) => {
|
|
1889
|
+
program.command("init").description("Create a DocCov configuration file").option("--cwd <dir>", "Working directory", process.cwd()).option("--format <format>", "Config format: auto, mjs, js, cjs, yaml", "auto").action((options) => {
|
|
1673
1890
|
const cwd = path6.resolve(options.cwd);
|
|
1674
1891
|
const formatOption = String(options.format ?? "auto").toLowerCase();
|
|
1675
1892
|
if (!isValidFormat(formatOption)) {
|
|
1676
|
-
error(chalk6.red(`Invalid format "${formatOption}". Use auto, mjs, js, or
|
|
1893
|
+
error(chalk6.red(`Invalid format "${formatOption}". Use auto, mjs, js, cjs, or yaml.`));
|
|
1677
1894
|
process.exitCode = 1;
|
|
1678
1895
|
return;
|
|
1679
1896
|
}
|
|
@@ -1688,7 +1905,7 @@ function registerInitCommand(program, dependencies = {}) {
|
|
|
1688
1905
|
if (targetFormat === "js" && packageType !== "module") {
|
|
1689
1906
|
log(chalk6.yellow('Package is not marked as "type": "module"; creating doccov.config.js may require enabling ESM.'));
|
|
1690
1907
|
}
|
|
1691
|
-
const fileName = `doccov.config.${targetFormat}`;
|
|
1908
|
+
const fileName = targetFormat === "yaml" ? "doccov.yml" : `doccov.config.${targetFormat}`;
|
|
1692
1909
|
const outputPath = path6.join(cwd, fileName);
|
|
1693
1910
|
if (fileExists2(outputPath)) {
|
|
1694
1911
|
error(chalk6.red(`Cannot create ${fileName}; file already exists.`));
|
|
@@ -1701,7 +1918,7 @@ function registerInitCommand(program, dependencies = {}) {
|
|
|
1701
1918
|
});
|
|
1702
1919
|
}
|
|
1703
1920
|
var isValidFormat = (value) => {
|
|
1704
|
-
return
|
|
1921
|
+
return ["auto", "mjs", "js", "cjs", "yaml"].includes(value);
|
|
1705
1922
|
};
|
|
1706
1923
|
var findExistingConfig = (cwd, fileExists2) => {
|
|
1707
1924
|
let current = path6.resolve(cwd);
|
|
@@ -1753,12 +1970,34 @@ var findNearestPackageJson = (cwd, fileExists2) => {
|
|
|
1753
1970
|
return null;
|
|
1754
1971
|
};
|
|
1755
1972
|
var resolveFormat = (format, packageType) => {
|
|
1973
|
+
if (format === "yaml")
|
|
1974
|
+
return "yaml";
|
|
1756
1975
|
if (format === "auto") {
|
|
1757
1976
|
return packageType === "module" ? "js" : "mjs";
|
|
1758
1977
|
}
|
|
1759
1978
|
return format;
|
|
1760
1979
|
};
|
|
1761
1980
|
var buildTemplate = (format) => {
|
|
1981
|
+
if (format === "yaml") {
|
|
1982
|
+
return `# doccov.yml
|
|
1983
|
+
# include:
|
|
1984
|
+
# - "MyClass"
|
|
1985
|
+
# - "myFunction"
|
|
1986
|
+
# exclude:
|
|
1987
|
+
# - "internal*"
|
|
1988
|
+
|
|
1989
|
+
check:
|
|
1990
|
+
# minCoverage: 80
|
|
1991
|
+
# maxDrift: 20
|
|
1992
|
+
# examples: typecheck
|
|
1993
|
+
|
|
1994
|
+
quality:
|
|
1995
|
+
rules:
|
|
1996
|
+
# has-description: warn
|
|
1997
|
+
# has-params: off
|
|
1998
|
+
# has-returns: off
|
|
1999
|
+
`;
|
|
2000
|
+
}
|
|
1762
2001
|
const configBody = `{
|
|
1763
2002
|
// Filter which exports to analyze
|
|
1764
2003
|
// include: ['MyClass', 'myFunction'],
|
|
@@ -1813,7 +2052,7 @@ import { DocCov as DocCov3, NodeFileSystem as NodeFileSystem3, resolveTarget as
|
|
|
1813
2052
|
import { normalize, validateSpec } from "@openpkg-ts/spec";
|
|
1814
2053
|
import chalk8 from "chalk";
|
|
1815
2054
|
// package.json
|
|
1816
|
-
var version = "0.
|
|
2055
|
+
var version = "0.16.0";
|
|
1817
2056
|
|
|
1818
2057
|
// src/utils/filter-options.ts
|
|
1819
2058
|
import { mergeFilters, parseListFlag } from "@doccov/sdk";
|
package/dist/config/index.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ declare const docCovConfigSchema: z.ZodObject<{
|
|
|
38
38
|
}>;
|
|
39
39
|
type DocCovConfigInput = z.infer<typeof docCovConfigSchema>;
|
|
40
40
|
type NormalizedDocCovConfig = DocCovConfig;
|
|
41
|
-
declare const DOCCOV_CONFIG_FILENAMES: readonly ["doccov.config.ts", "doccov.config.mts", "doccov.config.cts", "doccov.config.js", "doccov.config.mjs", "doccov.config.cjs"];
|
|
41
|
+
declare const DOCCOV_CONFIG_FILENAMES: readonly ["doccov.config.ts", "doccov.config.mts", "doccov.config.cts", "doccov.config.js", "doccov.config.mjs", "doccov.config.cjs", "doccov.yml", "doccov.yaml"];
|
|
42
42
|
interface LoadedDocCovConfig extends NormalizedDocCovConfig {
|
|
43
43
|
filePath: string;
|
|
44
44
|
}
|
package/dist/config/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/config/doccov-config.ts
|
|
2
|
-
import { access } from "node:fs/promises";
|
|
2
|
+
import { access, readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { parse as parseYaml } from "yaml";
|
|
5
6
|
|
|
6
7
|
// src/config/schema.ts
|
|
7
8
|
import { z } from "zod";
|
|
@@ -93,7 +94,9 @@ var DOCCOV_CONFIG_FILENAMES = [
|
|
|
93
94
|
"doccov.config.cts",
|
|
94
95
|
"doccov.config.js",
|
|
95
96
|
"doccov.config.mjs",
|
|
96
|
-
"doccov.config.cjs"
|
|
97
|
+
"doccov.config.cjs",
|
|
98
|
+
"doccov.yml",
|
|
99
|
+
"doccov.yaml"
|
|
97
100
|
];
|
|
98
101
|
var fileExists = async (filePath) => {
|
|
99
102
|
try {
|
|
@@ -120,6 +123,11 @@ var findConfigFile = async (cwd) => {
|
|
|
120
123
|
}
|
|
121
124
|
};
|
|
122
125
|
var importConfigModule = async (absolutePath) => {
|
|
126
|
+
const ext = path.extname(absolutePath);
|
|
127
|
+
if (ext === ".yml" || ext === ".yaml") {
|
|
128
|
+
const content = await readFile(absolutePath, "utf-8");
|
|
129
|
+
return parseYaml(content);
|
|
130
|
+
}
|
|
123
131
|
const fileUrl = pathToFileURL(absolutePath);
|
|
124
132
|
fileUrl.searchParams.set("t", Date.now().toString());
|
|
125
133
|
const module = await import(fileUrl.href);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doccov/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "DocCov CLI - Documentation coverage and drift detection for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"commander": "^14.0.0",
|
|
57
57
|
"glob": "^11.0.0",
|
|
58
58
|
"simple-git": "^3.27.0",
|
|
59
|
+
"yaml": "^2.8.2",
|
|
59
60
|
"zod": "^3.25.0"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|