@doccov/cli 0.4.4 → 0.4.5

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.
Files changed (2) hide show
  1. package/dist/cli.js +151 -149
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -933,8 +933,8 @@ function registerFixCommand(program, dependencies = {}) {
933
933
  }
934
934
 
935
935
  // src/commands/generate.ts
936
- import * as fs5 from "node:fs";
937
- import * as path6 from "node:path";
936
+ import * as fs6 from "node:fs";
937
+ import * as path7 from "node:path";
938
938
  import { DocCov as DocCov3 } from "@doccov/sdk";
939
939
  import { normalize, validateSpec } from "@openpkg-ts/spec";
940
940
  import chalk5 from "chalk";
@@ -990,10 +990,118 @@ var mergeFilterOptions = (config, cliOptions) => {
990
990
  };
991
991
  };
992
992
 
993
+ // src/utils/entry-detection.ts
994
+ import * as fs5 from "node:fs";
995
+ import * as path6 from "node:path";
996
+ function detectEntryPoint(repoDir) {
997
+ const pkgPath = path6.join(repoDir, "package.json");
998
+ if (!fs5.existsSync(pkgPath)) {
999
+ throw new Error("No package.json found - not a valid npm package");
1000
+ }
1001
+ let pkg;
1002
+ try {
1003
+ pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
1004
+ } catch {
1005
+ throw new Error("Failed to parse package.json");
1006
+ }
1007
+ if (typeof pkg.types === "string") {
1008
+ const resolved = resolveToTs(repoDir, pkg.types);
1009
+ if (resolved) {
1010
+ return { entryPath: resolved, source: "types" };
1011
+ }
1012
+ }
1013
+ if (typeof pkg.typings === "string") {
1014
+ const resolved = resolveToTs(repoDir, pkg.typings);
1015
+ if (resolved) {
1016
+ return { entryPath: resolved, source: "types" };
1017
+ }
1018
+ }
1019
+ const exports = pkg.exports;
1020
+ if (exports) {
1021
+ const mainExport = exports["."];
1022
+ if (typeof mainExport === "object" && mainExport !== null) {
1023
+ const exportObj = mainExport;
1024
+ if (typeof exportObj.types === "string") {
1025
+ const resolved = resolveToTs(repoDir, exportObj.types);
1026
+ if (resolved) {
1027
+ return { entryPath: resolved, source: "exports" };
1028
+ }
1029
+ }
1030
+ }
1031
+ }
1032
+ if (typeof pkg.main === "string") {
1033
+ const resolved = resolveToTs(repoDir, pkg.main);
1034
+ if (resolved) {
1035
+ return { entryPath: resolved, source: "main" };
1036
+ }
1037
+ }
1038
+ if (typeof pkg.module === "string") {
1039
+ const resolved = resolveToTs(repoDir, pkg.module);
1040
+ if (resolved) {
1041
+ return { entryPath: resolved, source: "module" };
1042
+ }
1043
+ }
1044
+ const commonPaths = [
1045
+ "src/index.ts",
1046
+ "src/index.tsx",
1047
+ "src/main.ts",
1048
+ "index.ts",
1049
+ "lib/index.ts",
1050
+ "source/index.ts"
1051
+ ];
1052
+ for (const p of commonPaths) {
1053
+ if (fs5.existsSync(path6.join(repoDir, p))) {
1054
+ return { entryPath: p, source: "fallback" };
1055
+ }
1056
+ }
1057
+ throw new Error("Could not detect TypeScript entry point. No types field in package.json and no common entry paths found.");
1058
+ }
1059
+ function resolveToTs(baseDir, filePath) {
1060
+ const normalized = filePath.replace(/^\.\//, "");
1061
+ const isSourceTs = normalized.endsWith(".ts") && !normalized.endsWith(".d.ts") || normalized.endsWith(".tsx");
1062
+ if (isSourceTs) {
1063
+ if (fs5.existsSync(path6.join(baseDir, normalized))) {
1064
+ return normalized;
1065
+ }
1066
+ }
1067
+ const candidates = [];
1068
+ if (normalized.startsWith("dist/")) {
1069
+ const srcPath = normalized.replace(/^dist\//, "src/");
1070
+ candidates.push(srcPath.replace(/\.js$/, ".ts"));
1071
+ candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1072
+ candidates.push(srcPath.replace(/\.js$/, ".tsx"));
1073
+ }
1074
+ if (normalized.startsWith("build/")) {
1075
+ const srcPath = normalized.replace(/^build\//, "src/");
1076
+ candidates.push(srcPath.replace(/\.js$/, ".ts"));
1077
+ candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1078
+ }
1079
+ if (normalized.startsWith("lib/")) {
1080
+ const srcPath = normalized.replace(/^lib\//, "src/");
1081
+ candidates.push(srcPath.replace(/\.js$/, ".ts"));
1082
+ candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1083
+ }
1084
+ candidates.push(normalized.replace(/\.js$/, ".ts"));
1085
+ candidates.push(normalized.replace(/\.d\.ts$/, ".ts"));
1086
+ candidates.push(normalized.replace(/\.js$/, ".tsx"));
1087
+ if (normalized.endsWith(".d.ts")) {
1088
+ const baseName = path6.basename(normalized, ".d.ts");
1089
+ candidates.push(`src/${baseName}.ts`);
1090
+ }
1091
+ for (const candidate of candidates) {
1092
+ if (candidate.endsWith(".d.ts"))
1093
+ continue;
1094
+ if (fs5.existsSync(path6.join(baseDir, candidate))) {
1095
+ return candidate;
1096
+ }
1097
+ }
1098
+ return;
1099
+ }
1100
+
993
1101
  // src/commands/generate.ts
994
1102
  var defaultDependencies4 = {
995
1103
  createDocCov: (options) => new DocCov3(options),
996
- writeFileSync: fs5.writeFileSync,
1104
+ writeFileSync: fs6.writeFileSync,
997
1105
  spinner: (text) => ora3(text),
998
1106
  log: console.log,
999
1107
  error: console.error
@@ -1013,7 +1121,7 @@ function stripDocsFields(spec) {
1013
1121
  }
1014
1122
  function formatDiagnosticOutput(prefix, diagnostic, baseDir) {
1015
1123
  const location = diagnostic.location;
1016
- const relativePath = location?.file ? path6.relative(baseDir, location.file) || location.file : undefined;
1124
+ const relativePath = location?.file ? path7.relative(baseDir, location.file) || location.file : undefined;
1017
1125
  const locationText = location && relativePath ? chalk5.gray(`${relativePath}:${location.line ?? 1}:${location.column ?? 1}`) : null;
1018
1126
  const locationPrefix = locationText ? `${locationText} ` : "";
1019
1127
  return `${prefix} ${locationPrefix}${diagnostic.message}`;
@@ -1033,16 +1141,18 @@ function registerGenerateCommand(program, dependencies = {}) {
1033
1141
  throw new Error(`Package "${options.package}" not found in monorepo`);
1034
1142
  }
1035
1143
  targetDir = packageDir;
1036
- log(chalk5.gray(`Found package at ${path6.relative(options.cwd, packageDir)}`));
1144
+ log(chalk5.gray(`Found package at ${path7.relative(options.cwd, packageDir)}`));
1037
1145
  }
1038
1146
  if (!entryFile) {
1039
- entryFile = await findEntryPoint(targetDir, true);
1040
- log(chalk5.gray(`Auto-detected entry point: ${path6.relative(targetDir, entryFile)}`));
1147
+ const detected = detectEntryPoint(targetDir);
1148
+ entryFile = path7.join(targetDir, detected.entryPath);
1149
+ log(chalk5.gray(`Auto-detected entry point: ${detected.entryPath} (from ${detected.source})`));
1041
1150
  } else {
1042
- entryFile = path6.resolve(targetDir, entryFile);
1043
- if (fs5.existsSync(entryFile) && fs5.statSync(entryFile).isDirectory()) {
1044
- entryFile = await findEntryPoint(entryFile, true);
1045
- log(chalk5.gray(`Auto-detected entry point: ${entryFile}`));
1151
+ entryFile = path7.resolve(targetDir, entryFile);
1152
+ if (fs6.existsSync(entryFile) && fs6.statSync(entryFile).isDirectory()) {
1153
+ const detected = detectEntryPoint(entryFile);
1154
+ entryFile = path7.join(entryFile, detected.entryPath);
1155
+ log(chalk5.gray(`Auto-detected entry point: ${detected.entryPath} (from ${detected.source})`));
1046
1156
  }
1047
1157
  }
1048
1158
  const resolveExternalTypes = !options.skipResolve;
@@ -1054,7 +1164,7 @@ function registerGenerateCommand(program, dependencies = {}) {
1054
1164
  try {
1055
1165
  config = await loadDocCovConfig(targetDir);
1056
1166
  if (config?.filePath) {
1057
- log(chalk5.gray(`Loaded configuration from ${path6.relative(targetDir, config.filePath)}`));
1167
+ log(chalk5.gray(`Loaded configuration from ${path7.relative(targetDir, config.filePath)}`));
1058
1168
  }
1059
1169
  } catch (configError) {
1060
1170
  error(chalk5.red("Failed to load DocCov config:"), configError instanceof Error ? configError.message : configError);
@@ -1086,7 +1196,7 @@ function registerGenerateCommand(program, dependencies = {}) {
1086
1196
  if (!result) {
1087
1197
  throw new Error("Failed to produce an OpenPkg spec.");
1088
1198
  }
1089
- const outputPath = path6.resolve(process.cwd(), options.output);
1199
+ const outputPath = path7.resolve(process.cwd(), options.output);
1090
1200
  let normalized = normalize(result.spec);
1091
1201
  if (options.docs === false) {
1092
1202
  normalized = stripDocsFields(normalized);
@@ -1119,23 +1229,23 @@ function registerGenerateCommand(program, dependencies = {}) {
1119
1229
  }
1120
1230
 
1121
1231
  // src/commands/init.ts
1122
- import * as fs6 from "node:fs";
1123
- import * as path7 from "node:path";
1232
+ import * as fs7 from "node:fs";
1233
+ import * as path8 from "node:path";
1124
1234
  import chalk6 from "chalk";
1125
1235
  var defaultDependencies5 = {
1126
- fileExists: fs6.existsSync,
1127
- writeFileSync: fs6.writeFileSync,
1128
- readFileSync: fs6.readFileSync,
1236
+ fileExists: fs7.existsSync,
1237
+ writeFileSync: fs7.writeFileSync,
1238
+ readFileSync: fs7.readFileSync,
1129
1239
  log: console.log,
1130
1240
  error: console.error
1131
1241
  };
1132
1242
  function registerInitCommand(program, dependencies = {}) {
1133
- const { fileExists: fileExists2, writeFileSync: writeFileSync3, readFileSync: readFileSync4, log, error } = {
1243
+ const { fileExists: fileExists2, writeFileSync: writeFileSync3, readFileSync: readFileSync5, log, error } = {
1134
1244
  ...defaultDependencies5,
1135
1245
  ...dependencies
1136
1246
  };
1137
1247
  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) => {
1138
- const cwd = path7.resolve(options.cwd);
1248
+ const cwd = path8.resolve(options.cwd);
1139
1249
  const formatOption = String(options.format ?? "auto").toLowerCase();
1140
1250
  if (!isValidFormat(formatOption)) {
1141
1251
  error(chalk6.red(`Invalid format "${formatOption}". Use auto, mjs, js, or cjs.`));
@@ -1144,17 +1254,17 @@ function registerInitCommand(program, dependencies = {}) {
1144
1254
  }
1145
1255
  const existing = findExistingConfig(cwd, fileExists2);
1146
1256
  if (existing) {
1147
- error(chalk6.red(`A DocCov config already exists at ${path7.relative(cwd, existing) || "./doccov.config.*"}.`));
1257
+ error(chalk6.red(`A DocCov config already exists at ${path8.relative(cwd, existing) || "./doccov.config.*"}.`));
1148
1258
  process.exitCode = 1;
1149
1259
  return;
1150
1260
  }
1151
- const packageType = detectPackageType(cwd, fileExists2, readFileSync4);
1261
+ const packageType = detectPackageType(cwd, fileExists2, readFileSync5);
1152
1262
  const targetFormat = resolveFormat(formatOption, packageType);
1153
1263
  if (targetFormat === "js" && packageType !== "module") {
1154
1264
  log(chalk6.yellow('Package is not marked as "type": "module"; creating doccov.config.js may require enabling ESM.'));
1155
1265
  }
1156
1266
  const fileName = `doccov.config.${targetFormat}`;
1157
- const outputPath = path7.join(cwd, fileName);
1267
+ const outputPath = path8.join(cwd, fileName);
1158
1268
  if (fileExists2(outputPath)) {
1159
1269
  error(chalk6.red(`Cannot create ${fileName}; file already exists.`));
1160
1270
  process.exitCode = 1;
@@ -1162,18 +1272,18 @@ function registerInitCommand(program, dependencies = {}) {
1162
1272
  }
1163
1273
  const template = buildTemplate(targetFormat);
1164
1274
  writeFileSync3(outputPath, template, { encoding: "utf8" });
1165
- log(chalk6.green(`✓ Created ${path7.relative(process.cwd(), outputPath)}`));
1275
+ log(chalk6.green(`✓ Created ${path8.relative(process.cwd(), outputPath)}`));
1166
1276
  });
1167
1277
  }
1168
1278
  var isValidFormat = (value) => {
1169
1279
  return value === "auto" || value === "mjs" || value === "js" || value === "cjs";
1170
1280
  };
1171
1281
  var findExistingConfig = (cwd, fileExists2) => {
1172
- let current = path7.resolve(cwd);
1173
- const { root } = path7.parse(current);
1282
+ let current = path8.resolve(cwd);
1283
+ const { root } = path8.parse(current);
1174
1284
  while (true) {
1175
1285
  for (const candidate of DOCCOV_CONFIG_FILENAMES) {
1176
- const candidatePath = path7.join(current, candidate);
1286
+ const candidatePath = path8.join(current, candidate);
1177
1287
  if (fileExists2(candidatePath)) {
1178
1288
  return candidatePath;
1179
1289
  }
@@ -1181,17 +1291,17 @@ var findExistingConfig = (cwd, fileExists2) => {
1181
1291
  if (current === root) {
1182
1292
  break;
1183
1293
  }
1184
- current = path7.dirname(current);
1294
+ current = path8.dirname(current);
1185
1295
  }
1186
1296
  return null;
1187
1297
  };
1188
- var detectPackageType = (cwd, fileExists2, readFileSync4) => {
1298
+ var detectPackageType = (cwd, fileExists2, readFileSync5) => {
1189
1299
  const packageJsonPath = findNearestPackageJson(cwd, fileExists2);
1190
1300
  if (!packageJsonPath) {
1191
1301
  return;
1192
1302
  }
1193
1303
  try {
1194
- const raw = readFileSync4(packageJsonPath, "utf8");
1304
+ const raw = readFileSync5(packageJsonPath, "utf8");
1195
1305
  const parsed = JSON.parse(raw);
1196
1306
  if (parsed.type === "module") {
1197
1307
  return "module";
@@ -1203,17 +1313,17 @@ var detectPackageType = (cwd, fileExists2, readFileSync4) => {
1203
1313
  return;
1204
1314
  };
1205
1315
  var findNearestPackageJson = (cwd, fileExists2) => {
1206
- let current = path7.resolve(cwd);
1207
- const { root } = path7.parse(current);
1316
+ let current = path8.resolve(cwd);
1317
+ const { root } = path8.parse(current);
1208
1318
  while (true) {
1209
- const candidate = path7.join(current, "package.json");
1319
+ const candidate = path8.join(current, "package.json");
1210
1320
  if (fileExists2(candidate)) {
1211
1321
  return candidate;
1212
1322
  }
1213
1323
  if (current === root) {
1214
1324
  break;
1215
1325
  }
1216
- current = path7.dirname(current);
1326
+ current = path8.dirname(current);
1217
1327
  }
1218
1328
  return null;
1219
1329
  };
@@ -1249,8 +1359,8 @@ var buildTemplate = (format) => {
1249
1359
  };
1250
1360
 
1251
1361
  // src/commands/report.ts
1252
- import * as fs7 from "node:fs";
1253
- import * as path8 from "node:path";
1362
+ import * as fs8 from "node:fs";
1363
+ import * as path9 from "node:path";
1254
1364
  import { DocCov as DocCov4 } from "@doccov/sdk";
1255
1365
  import chalk7 from "chalk";
1256
1366
  import ora4 from "ora";
@@ -1430,8 +1540,8 @@ function registerReportCommand(program) {
1430
1540
  try {
1431
1541
  let spec;
1432
1542
  if (options.spec) {
1433
- const specPath = path8.resolve(options.cwd, options.spec);
1434
- spec = JSON.parse(fs7.readFileSync(specPath, "utf-8"));
1543
+ const specPath = path9.resolve(options.cwd, options.spec);
1544
+ spec = JSON.parse(fs8.readFileSync(specPath, "utf-8"));
1435
1545
  } else {
1436
1546
  let targetDir = options.cwd;
1437
1547
  let entryFile = entry;
@@ -1444,7 +1554,7 @@ function registerReportCommand(program) {
1444
1554
  if (!entryFile) {
1445
1555
  entryFile = await findEntryPoint(targetDir, true);
1446
1556
  } else {
1447
- entryFile = path8.resolve(targetDir, entryFile);
1557
+ entryFile = path9.resolve(targetDir, entryFile);
1448
1558
  }
1449
1559
  const spinner = ora4("Analyzing...").start();
1450
1560
  const resolveExternalTypes = !options.skipResolve;
@@ -1465,8 +1575,8 @@ function registerReportCommand(program) {
1465
1575
  output = renderMarkdown(stats, { limit });
1466
1576
  }
1467
1577
  if (options.out) {
1468
- const outPath = path8.resolve(options.cwd, options.out);
1469
- fs7.writeFileSync(outPath, output);
1578
+ const outPath = path9.resolve(options.cwd, options.out);
1579
+ fs8.writeFileSync(outPath, output);
1470
1580
  console.log(chalk7.green(`Report written to ${outPath}`));
1471
1581
  } else {
1472
1582
  console.log(output);
@@ -1487,114 +1597,6 @@ import chalk8 from "chalk";
1487
1597
  import ora5 from "ora";
1488
1598
  import { simpleGit } from "simple-git";
1489
1599
 
1490
- // src/utils/entry-detection.ts
1491
- import * as fs8 from "node:fs";
1492
- import * as path9 from "node:path";
1493
- function detectEntryPoint(repoDir) {
1494
- const pkgPath = path9.join(repoDir, "package.json");
1495
- if (!fs8.existsSync(pkgPath)) {
1496
- throw new Error("No package.json found - not a valid npm package");
1497
- }
1498
- let pkg;
1499
- try {
1500
- pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf-8"));
1501
- } catch {
1502
- throw new Error("Failed to parse package.json");
1503
- }
1504
- if (typeof pkg.types === "string") {
1505
- const resolved = resolveToTs(repoDir, pkg.types);
1506
- if (resolved) {
1507
- return { entryPath: resolved, source: "types" };
1508
- }
1509
- }
1510
- if (typeof pkg.typings === "string") {
1511
- const resolved = resolveToTs(repoDir, pkg.typings);
1512
- if (resolved) {
1513
- return { entryPath: resolved, source: "types" };
1514
- }
1515
- }
1516
- const exports = pkg.exports;
1517
- if (exports) {
1518
- const mainExport = exports["."];
1519
- if (typeof mainExport === "object" && mainExport !== null) {
1520
- const exportObj = mainExport;
1521
- if (typeof exportObj.types === "string") {
1522
- const resolved = resolveToTs(repoDir, exportObj.types);
1523
- if (resolved) {
1524
- return { entryPath: resolved, source: "exports" };
1525
- }
1526
- }
1527
- }
1528
- }
1529
- if (typeof pkg.main === "string") {
1530
- const resolved = resolveToTs(repoDir, pkg.main);
1531
- if (resolved) {
1532
- return { entryPath: resolved, source: "main" };
1533
- }
1534
- }
1535
- if (typeof pkg.module === "string") {
1536
- const resolved = resolveToTs(repoDir, pkg.module);
1537
- if (resolved) {
1538
- return { entryPath: resolved, source: "module" };
1539
- }
1540
- }
1541
- const commonPaths = [
1542
- "src/index.ts",
1543
- "src/index.tsx",
1544
- "src/main.ts",
1545
- "index.ts",
1546
- "lib/index.ts",
1547
- "source/index.ts"
1548
- ];
1549
- for (const p of commonPaths) {
1550
- if (fs8.existsSync(path9.join(repoDir, p))) {
1551
- return { entryPath: p, source: "fallback" };
1552
- }
1553
- }
1554
- throw new Error("Could not detect TypeScript entry point. No types field in package.json and no common entry paths found.");
1555
- }
1556
- function resolveToTs(baseDir, filePath) {
1557
- const normalized = filePath.replace(/^\.\//, "");
1558
- const isSourceTs = normalized.endsWith(".ts") && !normalized.endsWith(".d.ts") || normalized.endsWith(".tsx");
1559
- if (isSourceTs) {
1560
- if (fs8.existsSync(path9.join(baseDir, normalized))) {
1561
- return normalized;
1562
- }
1563
- }
1564
- const candidates = [];
1565
- if (normalized.startsWith("dist/")) {
1566
- const srcPath = normalized.replace(/^dist\//, "src/");
1567
- candidates.push(srcPath.replace(/\.js$/, ".ts"));
1568
- candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1569
- candidates.push(srcPath.replace(/\.js$/, ".tsx"));
1570
- }
1571
- if (normalized.startsWith("build/")) {
1572
- const srcPath = normalized.replace(/^build\//, "src/");
1573
- candidates.push(srcPath.replace(/\.js$/, ".ts"));
1574
- candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1575
- }
1576
- if (normalized.startsWith("lib/")) {
1577
- const srcPath = normalized.replace(/^lib\//, "src/");
1578
- candidates.push(srcPath.replace(/\.js$/, ".ts"));
1579
- candidates.push(srcPath.replace(/\.d\.ts$/, ".ts"));
1580
- }
1581
- candidates.push(normalized.replace(/\.js$/, ".ts"));
1582
- candidates.push(normalized.replace(/\.d\.ts$/, ".ts"));
1583
- candidates.push(normalized.replace(/\.js$/, ".tsx"));
1584
- if (normalized.endsWith(".d.ts")) {
1585
- const baseName = path9.basename(normalized, ".d.ts");
1586
- candidates.push(`src/${baseName}.ts`);
1587
- }
1588
- for (const candidate of candidates) {
1589
- if (candidate.endsWith(".d.ts"))
1590
- continue;
1591
- if (fs8.existsSync(path9.join(baseDir, candidate))) {
1592
- return candidate;
1593
- }
1594
- }
1595
- return;
1596
- }
1597
-
1598
1600
  // src/utils/github-url.ts
1599
1601
  function parseGitHubUrl(input, defaultRef = "main") {
1600
1602
  const trimmed = input.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doccov/cli",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "DocCov CLI - Documentation coverage and drift detection for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",