@driftdev/cli 0.36.0 → 0.38.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/drift.js +624 -47
- package/package.json +1 -1
package/dist/drift.js
CHANGED
|
@@ -175286,6 +175286,25 @@ function validateConfig(raw) {
|
|
|
175286
175286
|
if (docs.exclude !== undefined && (!Array.isArray(docs.exclude) || !docs.exclude.every((i) => typeof i === "string"))) {
|
|
175287
175287
|
errors.push('"docs.exclude" must be an array of strings');
|
|
175288
175288
|
}
|
|
175289
|
+
if (docs.remote !== undefined) {
|
|
175290
|
+
if (!Array.isArray(docs.remote)) {
|
|
175291
|
+
errors.push('"docs.remote" must be an array');
|
|
175292
|
+
} else {
|
|
175293
|
+
for (let i = 0;i < docs.remote.length; i++) {
|
|
175294
|
+
const target = docs.remote[i];
|
|
175295
|
+
if (typeof target !== "object" || target === null) {
|
|
175296
|
+
errors.push(`"docs.remote[${i}]" must be an object`);
|
|
175297
|
+
continue;
|
|
175298
|
+
}
|
|
175299
|
+
if (typeof target.repo !== "string" || !/^[^/]+\/[^/]+$/.test(target.repo)) {
|
|
175300
|
+
errors.push(`"docs.remote[${i}].repo" must be in "owner/repo" format`);
|
|
175301
|
+
}
|
|
175302
|
+
if (target.branch !== undefined && typeof target.branch !== "string") {
|
|
175303
|
+
errors.push(`"docs.remote[${i}].branch" must be a string`);
|
|
175304
|
+
}
|
|
175305
|
+
}
|
|
175306
|
+
}
|
|
175307
|
+
}
|
|
175289
175308
|
}
|
|
175290
175309
|
}
|
|
175291
175310
|
if (errors.length > 0)
|
|
@@ -175651,14 +175670,17 @@ function renderBatchLint(data) {
|
|
|
175651
175670
|
function renderBatchList(data) {
|
|
175652
175671
|
const lines = [""];
|
|
175653
175672
|
const rows = data.packages;
|
|
175673
|
+
const columnLabel = data.filter === "undocumented" ? "UNDOCUMENTED" : "EXPORTS";
|
|
175654
175674
|
const nameW = Math.max(7, ...rows.map((r) => r.name.length));
|
|
175655
|
-
lines.push(indent(`${c.gray(pad("PACKAGE", nameW))} ${c.gray(
|
|
175675
|
+
lines.push(indent(`${c.gray(pad("PACKAGE", nameW))} ${c.gray(columnLabel)}`));
|
|
175656
175676
|
for (const r of rows) {
|
|
175657
|
-
|
|
175677
|
+
const countStr = data.filter === "undocumented" ? r.count === 0 ? c.green("0") : c.yellow(String(r.count)) : String(r.count);
|
|
175678
|
+
lines.push(indent(`${pad(r.name, nameW)} ${countStr}`));
|
|
175658
175679
|
}
|
|
175659
175680
|
const total = rows.reduce((s, r) => s + r.count, 0);
|
|
175660
175681
|
lines.push("");
|
|
175661
|
-
|
|
175682
|
+
const label = data.filter === "undocumented" ? "undocumented exports" : "exports";
|
|
175683
|
+
lines.push(indent(`${c.bold("Total")}: ${total} ${label} across ${rows.length} packages`));
|
|
175662
175684
|
lines.push("");
|
|
175663
175685
|
return lines.join(`
|
|
175664
175686
|
`);
|
|
@@ -175681,6 +175703,54 @@ function renderBatchExamples(data) {
|
|
|
175681
175703
|
return lines.join(`
|
|
175682
175704
|
`);
|
|
175683
175705
|
}
|
|
175706
|
+
function renderBatchDiff(data) {
|
|
175707
|
+
const lines = [""];
|
|
175708
|
+
const rows = data.packages;
|
|
175709
|
+
const nameW = Math.max(7, ...rows.map((r) => r.name.length));
|
|
175710
|
+
lines.push(indent(`${c.gray(pad("PACKAGE", nameW))} ${c.gray(pad("BREAKING", 8))} ${c.gray(pad("ADDED", 5))} ${c.gray("CHANGED")}`));
|
|
175711
|
+
for (const r of rows) {
|
|
175712
|
+
const bStr = pad(String(r.breaking), 8);
|
|
175713
|
+
const aStr = pad(String(r.added), 5);
|
|
175714
|
+
const cStr = String(r.changed);
|
|
175715
|
+
const breaking = r.breaking === 0 ? c.green(bStr) : c.red(bStr);
|
|
175716
|
+
const added = r.added === 0 ? aStr : c.green(aStr);
|
|
175717
|
+
const changed = r.changed === 0 ? cStr : c.yellow(cStr);
|
|
175718
|
+
lines.push(indent(`${pad(r.name, nameW)} ${breaking} ${added} ${changed}`));
|
|
175719
|
+
}
|
|
175720
|
+
lines.push("");
|
|
175721
|
+
const parts = [];
|
|
175722
|
+
if (data.aggregate.breaking > 0)
|
|
175723
|
+
parts.push(`${data.aggregate.breaking} breaking`);
|
|
175724
|
+
if (data.aggregate.added > 0)
|
|
175725
|
+
parts.push(`${data.aggregate.added} added`);
|
|
175726
|
+
if (data.aggregate.changed > 0)
|
|
175727
|
+
parts.push(`${data.aggregate.changed} changed`);
|
|
175728
|
+
lines.push(indent(`${c.bold("Total")}: ${parts.length > 0 ? parts.join(", ") : "no changes"}`));
|
|
175729
|
+
if (data.skipped && data.skipped.length > 0) {
|
|
175730
|
+
lines.push(indent(`${c.gray(`Skipped ${data.skipped.length} private: ${data.skipped.join(", ")}`)}`));
|
|
175731
|
+
}
|
|
175732
|
+
lines.push("");
|
|
175733
|
+
return lines.join(`
|
|
175734
|
+
`);
|
|
175735
|
+
}
|
|
175736
|
+
function renderBatchBreaking(data) {
|
|
175737
|
+
const lines = [""];
|
|
175738
|
+
const rows = data.packages;
|
|
175739
|
+
const nameW = Math.max(7, ...rows.map((r) => r.name.length));
|
|
175740
|
+
lines.push(indent(`${c.gray(pad("PACKAGE", nameW))} ${c.gray("BREAKING")}`));
|
|
175741
|
+
for (const r of rows) {
|
|
175742
|
+
const count = r.count === 0 ? c.green("0") : c.red(String(r.count));
|
|
175743
|
+
lines.push(indent(`${pad(r.name, nameW)} ${count}`));
|
|
175744
|
+
}
|
|
175745
|
+
lines.push("");
|
|
175746
|
+
lines.push(indent(`${c.bold("Total")}: ${data.aggregate.count} breaking change${data.aggregate.count === 1 ? "" : "s"}`));
|
|
175747
|
+
if (data.skipped && data.skipped.length > 0) {
|
|
175748
|
+
lines.push(indent(`${c.gray(`Skipped ${data.skipped.length} private: ${data.skipped.join(", ")}`)}`));
|
|
175749
|
+
}
|
|
175750
|
+
lines.push("");
|
|
175751
|
+
return lines.join(`
|
|
175752
|
+
`);
|
|
175753
|
+
}
|
|
175684
175754
|
function pad(s, w) {
|
|
175685
175755
|
return s + " ".repeat(Math.max(0, w - s.length));
|
|
175686
175756
|
}
|
|
@@ -176013,7 +176083,7 @@ function getPackageInfo(cwd) {
|
|
|
176013
176083
|
}
|
|
176014
176084
|
}
|
|
176015
176085
|
function registerHealthCommand(program) {
|
|
176016
|
-
program.command("health [entry]"
|
|
176086
|
+
program.command("health [entry]").description("Show documentation health score (default command)").option("--min <n>", "Minimum health threshold (exit 1 if below)").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").action(async (entry, options) => {
|
|
176017
176087
|
const startTime = Date.now();
|
|
176018
176088
|
const version = getVersion();
|
|
176019
176089
|
try {
|
|
@@ -176105,7 +176175,7 @@ function registerHealthCommand(program) {
|
|
|
176105
176175
|
import { readFileSync as readFileSync15 } from "node:fs";
|
|
176106
176176
|
import * as path19 from "node:path";
|
|
176107
176177
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
176108
|
-
import { diffSpec as diffSpec3, categorizeBreakingChanges as categorizeBreakingChanges2 } from "@openpkg-ts/spec";
|
|
176178
|
+
import { diffSpec as diffSpec3, categorizeBreakingChanges as categorizeBreakingChanges2, normalize as normalize4 } from "@openpkg-ts/spec";
|
|
176109
176179
|
|
|
176110
176180
|
// src/formatters/breaking.ts
|
|
176111
176181
|
function renderBreaking(data) {
|
|
@@ -176128,17 +176198,20 @@ function renderBreaking(data) {
|
|
|
176128
176198
|
`);
|
|
176129
176199
|
}
|
|
176130
176200
|
|
|
176131
|
-
// src/utils/resolve-specs.ts
|
|
176132
|
-
import { readFileSync as readFileSync14 } from "node:fs";
|
|
176133
|
-
import * as path18 from "node:path";
|
|
176134
|
-
import { normalize as normalize3 } from "@openpkg-ts/spec";
|
|
176135
|
-
|
|
176136
176201
|
// src/utils/git-extract.ts
|
|
176137
176202
|
import { execSync } from "node:child_process";
|
|
176138
176203
|
import { existsSync as existsSync14, mkdirSync as mkdirSync4, mkdtempSync, rmSync as rmSync2, symlinkSync, writeFileSync as writeFileSync4, cpSync } from "node:fs";
|
|
176139
176204
|
import * as os4 from "node:os";
|
|
176140
176205
|
import * as path17 from "node:path";
|
|
176141
176206
|
import { normalize as normalize2 } from "@openpkg-ts/spec";
|
|
176207
|
+
function getGitRoot(cwd) {
|
|
176208
|
+
return execSync("git rev-parse --show-toplevel", {
|
|
176209
|
+
encoding: "utf-8",
|
|
176210
|
+
cwd,
|
|
176211
|
+
timeout: 5000,
|
|
176212
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
176213
|
+
}).trim();
|
|
176214
|
+
}
|
|
176142
176215
|
function listFilesAtRef(ref, prefix, cwd) {
|
|
176143
176216
|
try {
|
|
176144
176217
|
const output = execSync(`git ls-tree -r --name-only ${ref} -- ${prefix}`, {
|
|
@@ -176178,19 +176251,21 @@ function validateRef(ref, cwd = process.cwd()) {
|
|
|
176178
176251
|
}
|
|
176179
176252
|
}
|
|
176180
176253
|
async function extractSpecFromRef(ref, entry, cwd = process.cwd()) {
|
|
176181
|
-
const
|
|
176182
|
-
const
|
|
176254
|
+
const gitRoot = getGitRoot(cwd);
|
|
176255
|
+
const absEntry = path17.resolve(cwd, entry);
|
|
176256
|
+
const repoRelEntry = path17.relative(gitRoot, absEntry);
|
|
176257
|
+
const entryDir = path17.dirname(repoRelEntry);
|
|
176183
176258
|
const srcPrefix = entryDir.includes("/") ? entryDir.split("/").slice(0, 2).join("/") : ".";
|
|
176184
176259
|
const tmpDir = mkdtempSync(path17.join(os4.tmpdir(), "drift-git-"));
|
|
176185
176260
|
try {
|
|
176186
176261
|
const prefixes = srcPrefix === "." ? [""] : [srcPrefix];
|
|
176187
176262
|
const rootFiles = ["tsconfig.json", "tsconfig.base.json", "package.json"];
|
|
176188
176263
|
for (const prefix of prefixes) {
|
|
176189
|
-
const files = listFilesAtRef(ref, prefix || ".",
|
|
176264
|
+
const files = listFilesAtRef(ref, prefix || ".", gitRoot);
|
|
176190
176265
|
for (const file of files) {
|
|
176191
176266
|
if (!file.match(/\.(ts|tsx|json|js|mjs|cjs)$/))
|
|
176192
176267
|
continue;
|
|
176193
|
-
const content = getFileAtRef(ref, file,
|
|
176268
|
+
const content = getFileAtRef(ref, file, gitRoot);
|
|
176194
176269
|
if (content === null)
|
|
176195
176270
|
continue;
|
|
176196
176271
|
const destPath = path17.join(tmpDir, file);
|
|
@@ -176201,7 +176276,7 @@ async function extractSpecFromRef(ref, entry, cwd = process.cwd()) {
|
|
|
176201
176276
|
for (const rootFile of rootFiles) {
|
|
176202
176277
|
const dest = path17.join(tmpDir, rootFile);
|
|
176203
176278
|
if (!existsSync14(dest)) {
|
|
176204
|
-
const content = getFileAtRef(ref, rootFile,
|
|
176279
|
+
const content = getFileAtRef(ref, rootFile, gitRoot);
|
|
176205
176280
|
if (content) {
|
|
176206
176281
|
writeFileSync4(dest, content);
|
|
176207
176282
|
}
|
|
@@ -176212,8 +176287,15 @@ async function extractSpecFromRef(ref, entry, cwd = process.cwd()) {
|
|
|
176212
176287
|
if (existsSync14(nmSrc) && !existsSync14(nmDest)) {
|
|
176213
176288
|
symlinkSync(nmSrc, nmDest, "dir");
|
|
176214
176289
|
}
|
|
176290
|
+
if (cwd !== gitRoot) {
|
|
176291
|
+
const rootNm = path17.join(gitRoot, "node_modules");
|
|
176292
|
+
const rootNmDest = path17.join(tmpDir, "node_modules");
|
|
176293
|
+
if (existsSync14(rootNm) && !existsSync14(rootNmDest)) {
|
|
176294
|
+
symlinkSync(rootNm, rootNmDest, "dir");
|
|
176295
|
+
}
|
|
176296
|
+
}
|
|
176215
176297
|
if (srcPrefix !== ".") {
|
|
176216
|
-
const nestedNm = path17.join(
|
|
176298
|
+
const nestedNm = path17.join(gitRoot, srcPrefix, "node_modules");
|
|
176217
176299
|
const nestedDest = path17.join(tmpDir, srcPrefix, "node_modules");
|
|
176218
176300
|
if (existsSync14(nestedNm) && !existsSync14(nestedDest)) {
|
|
176219
176301
|
symlinkSync(nestedNm, nestedDest, "dir");
|
|
@@ -176224,9 +176306,9 @@ async function extractSpecFromRef(ref, entry, cwd = process.cwd()) {
|
|
|
176224
176306
|
if (existsSync14(tsconfigSrc) && !existsSync14(tsconfigDest)) {
|
|
176225
176307
|
cpSync(tsconfigSrc, tsconfigDest);
|
|
176226
176308
|
}
|
|
176227
|
-
const entryFile = path17.join(tmpDir,
|
|
176309
|
+
const entryFile = path17.join(tmpDir, repoRelEntry);
|
|
176228
176310
|
if (!existsSync14(entryFile)) {
|
|
176229
|
-
throw new Error(`Entry file not found at ref ${ref}: ${
|
|
176311
|
+
throw new Error(`Entry file not found at ref ${ref}: ${repoRelEntry}`);
|
|
176230
176312
|
}
|
|
176231
176313
|
const result = await extract({ entryFile });
|
|
176232
176314
|
return normalize2(result.spec);
|
|
@@ -176236,6 +176318,9 @@ async function extractSpecFromRef(ref, entry, cwd = process.cwd()) {
|
|
|
176236
176318
|
}
|
|
176237
176319
|
|
|
176238
176320
|
// src/utils/resolve-specs.ts
|
|
176321
|
+
import { readFileSync as readFileSync14 } from "node:fs";
|
|
176322
|
+
import * as path18 from "node:path";
|
|
176323
|
+
import { normalize as normalize3 } from "@openpkg-ts/spec";
|
|
176239
176324
|
function loadSpec(filePath) {
|
|
176240
176325
|
return JSON.parse(readFileSync14(path18.resolve(process.cwd(), filePath), "utf-8"));
|
|
176241
176326
|
}
|
|
@@ -176294,10 +176379,52 @@ function getVersion2() {
|
|
|
176294
176379
|
}
|
|
176295
176380
|
}
|
|
176296
176381
|
function registerBreakingCommand(program) {
|
|
176297
|
-
program.command("breaking [old] [new]").description("Detect breaking changes between two specs").option("--base <ref>", "Git ref for old spec").option("--head <ref>", "Git ref for new spec (default: working tree)").option("--entry <file>", "Entry file for git ref extraction").action(async (oldPath, newPath, options) => {
|
|
176382
|
+
program.command("breaking [old] [new]").description("Detect breaking changes between two specs").option("--base <ref>", "Git ref for old spec").option("--head <ref>", "Git ref for new spec (default: working tree)").option("--entry <file>", "Entry file for git ref extraction").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").action(async (oldPath, newPath, options) => {
|
|
176298
176383
|
const startTime = Date.now();
|
|
176299
176384
|
const version = getVersion2();
|
|
176300
176385
|
try {
|
|
176386
|
+
const cwd = process.cwd();
|
|
176387
|
+
const allPackages = options.all ? discoverPackages(cwd) : null;
|
|
176388
|
+
const autoDetected = !options.all && options.base && !options.entry && !oldPath ? discoverPackages(cwd) : null;
|
|
176389
|
+
const batchPackages = allPackages ?? autoDetected;
|
|
176390
|
+
if (batchPackages && batchPackages.length > 0 && options.base) {
|
|
176391
|
+
const skipped = options.private ? [] : batchPackages.filter((p) => p.private).map((p) => p.name);
|
|
176392
|
+
const packages = options.private ? batchPackages : filterPublic(batchPackages);
|
|
176393
|
+
if (packages.length === 0) {
|
|
176394
|
+
formatError("breaking", "No workspace packages found", startTime, version);
|
|
176395
|
+
return;
|
|
176396
|
+
}
|
|
176397
|
+
const rows = [];
|
|
176398
|
+
let totalBreaking = 0;
|
|
176399
|
+
for (const pkg of packages) {
|
|
176400
|
+
const relEntry = path19.relative(cwd, pkg.entry);
|
|
176401
|
+
const oldSpec2 = await extractSpecFromRef(options.base, relEntry, cwd);
|
|
176402
|
+
let newSpec2;
|
|
176403
|
+
if (options.head) {
|
|
176404
|
+
newSpec2 = await extractSpecFromRef(options.head, relEntry, cwd);
|
|
176405
|
+
} else {
|
|
176406
|
+
const result = await extract({ entryFile: pkg.entry });
|
|
176407
|
+
newSpec2 = normalize4(result.spec);
|
|
176408
|
+
}
|
|
176409
|
+
const diff2 = diffSpec3(oldSpec2, newSpec2);
|
|
176410
|
+
const breaking2 = categorizeBreakingChanges2(diff2.breaking, oldSpec2, newSpec2);
|
|
176411
|
+
rows.push({ name: pkg.name, breaking: breaking2, count: breaking2.length });
|
|
176412
|
+
totalBreaking += breaking2.length;
|
|
176413
|
+
}
|
|
176414
|
+
const data2 = { packages: rows, aggregate: { count: totalBreaking }, ...skipped.length > 0 ? { skipped } : {} };
|
|
176415
|
+
formatOutput("breaking", data2, startTime, version, renderBatchBreaking);
|
|
176416
|
+
if (totalBreaking > 0) {
|
|
176417
|
+
if (!shouldRenderHuman()) {
|
|
176418
|
+
process.stderr.write(`${totalBreaking} breaking change${totalBreaking === 1 ? "" : "s"} found
|
|
176419
|
+
`);
|
|
176420
|
+
}
|
|
176421
|
+
process.exitCode = 1;
|
|
176422
|
+
} else if (!shouldRenderHuman()) {
|
|
176423
|
+
process.stderr.write(`No breaking changes
|
|
176424
|
+
`);
|
|
176425
|
+
}
|
|
176426
|
+
return;
|
|
176427
|
+
}
|
|
176301
176428
|
const args = [oldPath, newPath].filter(Boolean);
|
|
176302
176429
|
const { oldSpec, newSpec } = await resolveSpecs({ args, ...options });
|
|
176303
176430
|
const diff = diffSpec3(oldSpec, newSpec);
|
|
@@ -176517,6 +176644,7 @@ import { existsSync as existsSync17, readFileSync as readFileSync20 } from "node
|
|
|
176517
176644
|
import * as path24 from "node:path";
|
|
176518
176645
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
176519
176646
|
import { computeDrift as computeDrift2 } from "@driftdev/sdk";
|
|
176647
|
+
import { diffSpec as diffSpec6, categorizeBreakingChanges as categorizeBreakingChanges4 } from "@openpkg-ts/spec";
|
|
176520
176648
|
|
|
176521
176649
|
// src/formatters/ci.ts
|
|
176522
176650
|
function renderCi(data) {
|
|
@@ -176771,25 +176899,109 @@ function filterChangedPackages(allDirs, changedFiles) {
|
|
|
176771
176899
|
return changedFiles.some((f) => prefix === "" || f.startsWith(prefix));
|
|
176772
176900
|
});
|
|
176773
176901
|
}
|
|
176774
|
-
function
|
|
176902
|
+
function buildPRComment(results, pass, commit) {
|
|
176775
176903
|
const lines = [];
|
|
176776
|
-
|
|
176904
|
+
const multi = results.length > 1;
|
|
176905
|
+
lines.push(`## Drift CI
|
|
176777
176906
|
`);
|
|
176778
176907
|
lines.push("| Package | Exports | Coverage | Lint | Status |");
|
|
176779
176908
|
lines.push("|---------|---------|----------|------|--------|");
|
|
176780
176909
|
for (const r of results) {
|
|
176781
|
-
const cov = r.coveragePass ? `${r.coverage}%` : `${r.coverage}%
|
|
176782
|
-
const lint = r.lintPass ? `${r.lintIssues}
|
|
176783
|
-
const status = r.pass ? "
|
|
176910
|
+
const cov = r.coveragePass ? `${r.coverage}%` : `${r.coverage}% :x:`;
|
|
176911
|
+
const lint = r.lintPass ? `${r.lintIssues}` : `${r.lintIssues} :x:`;
|
|
176912
|
+
const status = r.pass ? ":white_check_mark:" : ":x:";
|
|
176784
176913
|
lines.push(`| ${r.name} | ${r.exports} | ${cov} | ${lint} | ${status} |`);
|
|
176785
176914
|
}
|
|
176915
|
+
const apiEntries = [];
|
|
176916
|
+
for (const r of results) {
|
|
176917
|
+
if (!r.diff)
|
|
176918
|
+
continue;
|
|
176919
|
+
const { breaking, added, changed } = r.diff;
|
|
176920
|
+
if (breaking.length === 0 && added.length === 0 && changed.length === 0)
|
|
176921
|
+
continue;
|
|
176922
|
+
const pkgLines = [];
|
|
176923
|
+
if (multi)
|
|
176924
|
+
pkgLines.push(`
|
|
176925
|
+
**${r.name}**`);
|
|
176926
|
+
for (const name of added)
|
|
176927
|
+
pkgLines.push(`- :heavy_plus_sign: Added: \`${name}\``);
|
|
176928
|
+
for (const name of changed)
|
|
176929
|
+
pkgLines.push(`- :pencil2: Changed: \`${name}\``);
|
|
176930
|
+
for (const b of breaking)
|
|
176931
|
+
pkgLines.push(`- :x: Removed: \`${b.name}\``);
|
|
176932
|
+
apiEntries.push(pkgLines.join(`
|
|
176933
|
+
`));
|
|
176934
|
+
}
|
|
176935
|
+
if (apiEntries.length > 0) {
|
|
176936
|
+
const total = results.reduce((s, r) => s + (r.diff ? r.diff.breaking.length + r.diff.added.length + r.diff.changed.length : 0), 0);
|
|
176937
|
+
lines.push("");
|
|
176938
|
+
lines.push(`<details>
|
|
176939
|
+
<summary>API Changes (${total})</summary>
|
|
176940
|
+
`);
|
|
176941
|
+
lines.push(apiEntries.join(`
|
|
176942
|
+
`));
|
|
176943
|
+
lines.push(`
|
|
176944
|
+
</details>`);
|
|
176945
|
+
}
|
|
176946
|
+
const breakingEntries = [];
|
|
176947
|
+
for (const r of results) {
|
|
176948
|
+
if (!r.diff?.breaking.length)
|
|
176949
|
+
continue;
|
|
176950
|
+
const pkgLines = [];
|
|
176951
|
+
if (multi)
|
|
176952
|
+
pkgLines.push(`
|
|
176953
|
+
**${r.name}**`);
|
|
176954
|
+
for (const b of r.diff.breaking) {
|
|
176955
|
+
pkgLines.push(`- \`${b.name}\`${b.reason ? `: ${b.reason}` : ""}`);
|
|
176956
|
+
}
|
|
176957
|
+
breakingEntries.push(pkgLines.join(`
|
|
176958
|
+
`));
|
|
176959
|
+
}
|
|
176960
|
+
if (breakingEntries.length > 0) {
|
|
176961
|
+
const total = results.reduce((s, r) => s + (r.diff?.breaking.length ?? 0), 0);
|
|
176962
|
+
lines.push("");
|
|
176963
|
+
lines.push(`<details>
|
|
176964
|
+
<summary>Breaking Changes (${total})</summary>
|
|
176965
|
+
`);
|
|
176966
|
+
lines.push(breakingEntries.join(`
|
|
176967
|
+
`));
|
|
176968
|
+
lines.push(`
|
|
176969
|
+
</details>`);
|
|
176970
|
+
}
|
|
176971
|
+
const undocEntries = [];
|
|
176972
|
+
for (const r of results) {
|
|
176973
|
+
if (!r.undocumented?.length)
|
|
176974
|
+
continue;
|
|
176975
|
+
const pkgLines = [];
|
|
176976
|
+
if (multi)
|
|
176977
|
+
pkgLines.push(`
|
|
176978
|
+
**${r.name}**`);
|
|
176979
|
+
for (const name of r.undocumented)
|
|
176980
|
+
pkgLines.push(`- \`${name}\``);
|
|
176981
|
+
undocEntries.push(pkgLines.join(`
|
|
176982
|
+
`));
|
|
176983
|
+
}
|
|
176984
|
+
if (undocEntries.length > 0) {
|
|
176985
|
+
const total = results.reduce((s, r) => s + (r.undocumented?.length ?? 0), 0);
|
|
176986
|
+
lines.push("");
|
|
176987
|
+
lines.push(`<details>
|
|
176988
|
+
<summary>Undocumented Exports (${total})</summary>
|
|
176989
|
+
`);
|
|
176990
|
+
lines.push(undocEntries.join(`
|
|
176991
|
+
`));
|
|
176992
|
+
lines.push(`
|
|
176993
|
+
</details>`);
|
|
176994
|
+
}
|
|
176786
176995
|
lines.push("");
|
|
176787
|
-
lines.push(
|
|
176996
|
+
lines.push("---");
|
|
176997
|
+
const ts18 = new Date().toISOString();
|
|
176998
|
+
const sha = commit ?? "";
|
|
176999
|
+
lines.push(`*[Drift](https://github.com/driftdev/drift) · ${ts18}${sha ? ` · ${sha}` : ""}*`);
|
|
176788
177000
|
return lines.join(`
|
|
176789
177001
|
`);
|
|
176790
177002
|
}
|
|
176791
177003
|
function registerCiCommand(program) {
|
|
176792
|
-
program.command("ci").description("Run CI checks on changed packages").option("--all", "Check all packages, not just changed ones").option("--private", "Include private packages").action(async (options) => {
|
|
177004
|
+
program.command("ci").description("Run CI checks on changed packages").option("--all", "Check all packages, not just changed ones").option("--private", "Include private packages").option("--min <number>", "Minimum coverage percentage (0-100)").action(async (options) => {
|
|
176793
177005
|
const startTime = Date.now();
|
|
176794
177006
|
const version = getVersion5();
|
|
176795
177007
|
const cwd = process.cwd();
|
|
@@ -176806,7 +177018,7 @@ function registerCiCommand(program) {
|
|
|
176806
177018
|
}
|
|
176807
177019
|
if (packageDirs.length === 0)
|
|
176808
177020
|
packageDirs = allDirs;
|
|
176809
|
-
let minThreshold = config.coverage?.min ?? 0;
|
|
177021
|
+
let minThreshold = options.min ? Number(options.min) : config.coverage?.min ?? 0;
|
|
176810
177022
|
if (minThreshold > 0 && config.coverage?.ratchet) {
|
|
176811
177023
|
const ratchet = computeRatchetMin(minThreshold);
|
|
176812
177024
|
minThreshold = ratchet.effectiveMin;
|
|
@@ -176852,6 +177064,24 @@ function registerCiCommand(program) {
|
|
|
176852
177064
|
lintIssues += drifts.length;
|
|
176853
177065
|
}
|
|
176854
177066
|
const lintPass = config.lint === false || lintIssues === 0;
|
|
177067
|
+
let diff;
|
|
177068
|
+
let undocumented;
|
|
177069
|
+
if (gh.isPR && gh.baseRef) {
|
|
177070
|
+
try {
|
|
177071
|
+
const relEntry = path24.relative(cwd, detectEntry(absDir));
|
|
177072
|
+
const oldSpec = await extractSpecFromRef(`origin/${gh.baseRef}`, relEntry, cwd);
|
|
177073
|
+
const diffResult = diffSpec6(oldSpec, spec);
|
|
177074
|
+
const breaking = categorizeBreakingChanges4(diffResult.breaking, oldSpec, spec);
|
|
177075
|
+
diff = {
|
|
177076
|
+
breaking: breaking.map((b) => ({ name: b.name, reason: b.reason })),
|
|
177077
|
+
added: diffResult.nonBreaking,
|
|
177078
|
+
changed: diffResult.docsOnly
|
|
177079
|
+
};
|
|
177080
|
+
} catch {}
|
|
177081
|
+
const undoc = exports.filter((e) => !e.description?.trim()).map((e) => e.name);
|
|
177082
|
+
if (undoc.length > 0)
|
|
177083
|
+
undocumented = undoc;
|
|
177084
|
+
}
|
|
176855
177085
|
results.push({
|
|
176856
177086
|
name,
|
|
176857
177087
|
coverage,
|
|
@@ -176859,7 +177089,9 @@ function registerCiCommand(program) {
|
|
|
176859
177089
|
lintIssues,
|
|
176860
177090
|
lintPass,
|
|
176861
177091
|
exports: total,
|
|
176862
|
-
pass: coveragePass && lintPass
|
|
177092
|
+
pass: coveragePass && lintPass,
|
|
177093
|
+
diff,
|
|
177094
|
+
undocumented
|
|
176863
177095
|
});
|
|
176864
177096
|
} catch {
|
|
176865
177097
|
results.push({
|
|
@@ -176897,7 +177129,7 @@ function registerCiCommand(program) {
|
|
|
176897
177129
|
});
|
|
176898
177130
|
} catch {}
|
|
176899
177131
|
if (gh.isPR && gh.token && gh.repository) {
|
|
176900
|
-
const md =
|
|
177132
|
+
const md = buildPRComment(results, allPass, commit);
|
|
176901
177133
|
writeStepSummary(md);
|
|
176902
177134
|
const prNumber = getPRNumber(gh.eventPath);
|
|
176903
177135
|
if (prNumber) {
|
|
@@ -177244,7 +177476,7 @@ function registerExamplesCommand(program) {
|
|
|
177244
177476
|
import { readFileSync as readFileSync23 } from "node:fs";
|
|
177245
177477
|
import * as path27 from "node:path";
|
|
177246
177478
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
177247
|
-
import { diffSpec as
|
|
177479
|
+
import { diffSpec as diffSpec7, categorizeBreakingChanges as categorizeBreakingChanges5, normalize as normalize5 } from "@openpkg-ts/spec";
|
|
177248
177480
|
|
|
177249
177481
|
// src/formatters/diff.ts
|
|
177250
177482
|
function renderDiff(data) {
|
|
@@ -177304,14 +177536,62 @@ function getVersion8() {
|
|
|
177304
177536
|
}
|
|
177305
177537
|
}
|
|
177306
177538
|
function registerDiffCommand(program) {
|
|
177307
|
-
program.command("diff [old] [new]").description("Compare two specs and show what changed").option("--base <ref>", "Git ref for old spec").option("--head <ref>", "Git ref for new spec (default: working tree)").option("--entry <file>", "Entry file for git ref extraction").action(async (oldPath, newPath, options) => {
|
|
177539
|
+
program.command("diff [old] [new]").description("Compare two specs and show what changed").option("--base <ref>", "Git ref for old spec").option("--head <ref>", "Git ref for new spec (default: working tree)").option("--entry <file>", "Entry file for git ref extraction").option("--all", "Run across all workspace packages").option("--private", "Include private packages in --all mode").action(async (oldPath, newPath, options) => {
|
|
177308
177540
|
const startTime = Date.now();
|
|
177309
177541
|
const version = getVersion8();
|
|
177310
177542
|
try {
|
|
177543
|
+
const cwd = process.cwd();
|
|
177544
|
+
const allPackages = options.all ? discoverPackages(cwd) : null;
|
|
177545
|
+
const autoDetected = !options.all && options.base && !options.entry && !oldPath ? discoverPackages(cwd) : null;
|
|
177546
|
+
const batchPackages = allPackages ?? autoDetected;
|
|
177547
|
+
if (batchPackages && batchPackages.length > 0 && options.base) {
|
|
177548
|
+
const skipped = options.private ? [] : batchPackages.filter((p) => p.private).map((p) => p.name);
|
|
177549
|
+
const packages = options.private ? batchPackages : filterPublic(batchPackages);
|
|
177550
|
+
if (packages.length === 0) {
|
|
177551
|
+
formatError("diff", "No workspace packages found", startTime, version);
|
|
177552
|
+
return;
|
|
177553
|
+
}
|
|
177554
|
+
const rows = [];
|
|
177555
|
+
let totalBreaking = 0;
|
|
177556
|
+
let totalAdded = 0;
|
|
177557
|
+
let totalChanged = 0;
|
|
177558
|
+
for (const pkg of packages) {
|
|
177559
|
+
const relEntry = path27.relative(cwd, pkg.entry);
|
|
177560
|
+
const oldSpec2 = await extractSpecFromRef(options.base, relEntry, cwd);
|
|
177561
|
+
let newSpec2;
|
|
177562
|
+
if (options.head) {
|
|
177563
|
+
newSpec2 = await extractSpecFromRef(options.head, relEntry, cwd);
|
|
177564
|
+
} else {
|
|
177565
|
+
const result = await extract({ entryFile: pkg.entry });
|
|
177566
|
+
newSpec2 = normalize5(result.spec);
|
|
177567
|
+
}
|
|
177568
|
+
const diff2 = diffSpec7(oldSpec2, newSpec2);
|
|
177569
|
+
rows.push({ name: pkg.name, breaking: diff2.breaking.length, added: diff2.nonBreaking.length, changed: diff2.docsOnly.length });
|
|
177570
|
+
totalBreaking += diff2.breaking.length;
|
|
177571
|
+
totalAdded += diff2.nonBreaking.length;
|
|
177572
|
+
totalChanged += diff2.docsOnly.length;
|
|
177573
|
+
}
|
|
177574
|
+
const data2 = { packages: rows, aggregate: { breaking: totalBreaking, added: totalAdded, changed: totalChanged }, ...skipped.length > 0 ? { skipped } : {} };
|
|
177575
|
+
formatOutput("diff", data2, startTime, version, renderBatchDiff);
|
|
177576
|
+
if (!shouldRenderHuman()) {
|
|
177577
|
+
const parts = [];
|
|
177578
|
+
if (totalBreaking > 0)
|
|
177579
|
+
parts.push(`${totalBreaking} breaking`);
|
|
177580
|
+
if (totalAdded > 0)
|
|
177581
|
+
parts.push(`${totalAdded} added`);
|
|
177582
|
+
if (totalChanged > 0)
|
|
177583
|
+
parts.push(`${totalChanged} changed`);
|
|
177584
|
+
process.stderr.write(`${parts.length > 0 ? parts.join(", ") : "no changes"}
|
|
177585
|
+
`);
|
|
177586
|
+
}
|
|
177587
|
+
if (totalBreaking > 0)
|
|
177588
|
+
process.exitCode = 1;
|
|
177589
|
+
return;
|
|
177590
|
+
}
|
|
177311
177591
|
const args = [oldPath, newPath].filter(Boolean);
|
|
177312
177592
|
const { oldSpec, newSpec } = await resolveSpecs({ args, ...options });
|
|
177313
|
-
const diff =
|
|
177314
|
-
const breaking =
|
|
177593
|
+
const diff = diffSpec7(oldSpec, newSpec);
|
|
177594
|
+
const breaking = categorizeBreakingChanges5(diff.breaking, oldSpec, newSpec);
|
|
177315
177595
|
const data = {
|
|
177316
177596
|
breaking,
|
|
177317
177597
|
added: diff.nonBreaking,
|
|
@@ -177347,7 +177627,7 @@ import { readFileSync as readFileSync24 } from "node:fs";
|
|
|
177347
177627
|
import * as path28 from "node:path";
|
|
177348
177628
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
177349
177629
|
import { DocCov } from "@driftdev/sdk";
|
|
177350
|
-
import { normalize as
|
|
177630
|
+
import { normalize as normalize6 } from "@openpkg-ts/spec";
|
|
177351
177631
|
|
|
177352
177632
|
// src/formatters/extract.ts
|
|
177353
177633
|
function renderExtract(data) {
|
|
@@ -177415,7 +177695,7 @@ function registerExtractCommand(program) {
|
|
|
177415
177695
|
formatError("extract", "Failed to extract spec", startTime, version);
|
|
177416
177696
|
return;
|
|
177417
177697
|
}
|
|
177418
|
-
spec =
|
|
177698
|
+
spec = normalize6(result.spec);
|
|
177419
177699
|
} else {
|
|
177420
177700
|
const result = await cachedExtract(entryFile);
|
|
177421
177701
|
spec = result.spec;
|
|
@@ -177831,7 +178111,7 @@ function flattenConfig(obj, prefix = "") {
|
|
|
177831
178111
|
}
|
|
177832
178112
|
function registerConfigCommand(program) {
|
|
177833
178113
|
const cmd = program.command("config").description("Manage drift configuration");
|
|
177834
|
-
cmd.command("list").description("Show all config values").action(() => {
|
|
178114
|
+
cmd.command("list").alias("show").description("Show all config values").action(() => {
|
|
177835
178115
|
const startTime = Date.now();
|
|
177836
178116
|
const version = getVersion12();
|
|
177837
178117
|
try {
|
|
@@ -178025,17 +178305,18 @@ import { existsSync as existsSync19, mkdirSync as mkdirSync7, readFileSync as re
|
|
|
178025
178305
|
import * as path33 from "node:path";
|
|
178026
178306
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
178027
178307
|
init_global();
|
|
178028
|
-
import { normalize as
|
|
178308
|
+
import { normalize as normalize7 } from "@openpkg-ts/spec";
|
|
178029
178309
|
|
|
178030
178310
|
// src/formatters/init.ts
|
|
178031
178311
|
function renderInit(data) {
|
|
178032
178312
|
const lines = [""];
|
|
178033
178313
|
lines.push(indent(`${data.isMonorepo ? "Monorepo" : "Project"} scan ${c.gray(`${data.packages.length} package${data.packages.length === 1 ? "" : "s"}`)}`));
|
|
178034
178314
|
lines.push("");
|
|
178035
|
-
const header = ["
|
|
178315
|
+
const header = ["Package", "Exports", "Coverage", "Health"];
|
|
178036
178316
|
const rows = data.packages.map((pkg) => {
|
|
178037
|
-
const
|
|
178038
|
-
|
|
178317
|
+
const covColor = coverageColor(pkg.coverage);
|
|
178318
|
+
const healthColor = coverageColor(pkg.health);
|
|
178319
|
+
return [pkg.name, String(pkg.exports), covColor(`${pkg.coverage}%`), healthColor(`${pkg.health}%`)];
|
|
178039
178320
|
});
|
|
178040
178321
|
lines.push(indent(table([header, ...rows])));
|
|
178041
178322
|
lines.push("");
|
|
@@ -178050,6 +178331,277 @@ function renderInit(data) {
|
|
|
178050
178331
|
`);
|
|
178051
178332
|
}
|
|
178052
178333
|
|
|
178334
|
+
// src/utils/progress/spinner.ts
|
|
178335
|
+
import chalk3 from "chalk";
|
|
178336
|
+
|
|
178337
|
+
// src/utils/progress/colors.ts
|
|
178338
|
+
import chalk2 from "chalk";
|
|
178339
|
+
var colors = {
|
|
178340
|
+
success: chalk2.green,
|
|
178341
|
+
error: chalk2.red,
|
|
178342
|
+
warning: chalk2.yellow,
|
|
178343
|
+
info: chalk2.cyan,
|
|
178344
|
+
muted: chalk2.gray,
|
|
178345
|
+
bold: chalk2.bold,
|
|
178346
|
+
dim: chalk2.dim,
|
|
178347
|
+
underline: chalk2.underline,
|
|
178348
|
+
primary: chalk2.cyan,
|
|
178349
|
+
secondary: chalk2.magenta,
|
|
178350
|
+
path: chalk2.cyan,
|
|
178351
|
+
number: chalk2.yellow,
|
|
178352
|
+
code: chalk2.gray
|
|
178353
|
+
};
|
|
178354
|
+
var symbols = {
|
|
178355
|
+
success: "✓",
|
|
178356
|
+
error: "✗",
|
|
178357
|
+
warning: "⚠",
|
|
178358
|
+
info: "ℹ",
|
|
178359
|
+
spinner: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
178360
|
+
bullet: "•",
|
|
178361
|
+
arrow: "→",
|
|
178362
|
+
arrowRight: "›",
|
|
178363
|
+
line: "─",
|
|
178364
|
+
corner: "└",
|
|
178365
|
+
vertical: "│",
|
|
178366
|
+
horizontalLine: "─"
|
|
178367
|
+
};
|
|
178368
|
+
var asciiSymbols = {
|
|
178369
|
+
success: "+",
|
|
178370
|
+
error: "x",
|
|
178371
|
+
warning: "!",
|
|
178372
|
+
info: "i",
|
|
178373
|
+
spinner: ["-", "\\", "|", "/"],
|
|
178374
|
+
bullet: "*",
|
|
178375
|
+
arrow: "->",
|
|
178376
|
+
arrowRight: ">",
|
|
178377
|
+
line: "-",
|
|
178378
|
+
corner: "\\",
|
|
178379
|
+
vertical: "|",
|
|
178380
|
+
horizontalLine: "-"
|
|
178381
|
+
};
|
|
178382
|
+
function getSymbols(unicodeSupport = true) {
|
|
178383
|
+
return unicodeSupport ? symbols : asciiSymbols;
|
|
178384
|
+
}
|
|
178385
|
+
var prefix = {
|
|
178386
|
+
success: colors.success(symbols.success),
|
|
178387
|
+
error: colors.error(symbols.error),
|
|
178388
|
+
warning: colors.warning(symbols.warning),
|
|
178389
|
+
info: colors.info(symbols.info)
|
|
178390
|
+
};
|
|
178391
|
+
|
|
178392
|
+
// src/utils/progress/utils.ts
|
|
178393
|
+
function isTTY2() {
|
|
178394
|
+
return Boolean(process.stdout.isTTY);
|
|
178395
|
+
}
|
|
178396
|
+
function isCI() {
|
|
178397
|
+
return Boolean(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.TRAVIS || process.env.JENKINS_URL || process.env.BUILDKITE || process.env.TEAMCITY_VERSION || process.env.TF_BUILD || process.env.CODEBUILD_BUILD_ID || process.env.BITBUCKET_BUILD_NUMBER);
|
|
178398
|
+
}
|
|
178399
|
+
function isInteractive() {
|
|
178400
|
+
return isTTY2() && !isCI();
|
|
178401
|
+
}
|
|
178402
|
+
function supportsUnicode() {
|
|
178403
|
+
if (process.platform === "win32") {
|
|
178404
|
+
return Boolean(process.env.WT_SESSION) || process.env.TERM_PROGRAM === "vscode";
|
|
178405
|
+
}
|
|
178406
|
+
return process.env.TERM !== "linux";
|
|
178407
|
+
}
|
|
178408
|
+
var MIN_TERMINAL_WIDTH = 40;
|
|
178409
|
+
var DEFAULT_TERMINAL_WIDTH = 80;
|
|
178410
|
+
function getTerminalWidth() {
|
|
178411
|
+
const width = process.stdout.columns || DEFAULT_TERMINAL_WIDTH;
|
|
178412
|
+
return Math.max(width, MIN_TERMINAL_WIDTH);
|
|
178413
|
+
}
|
|
178414
|
+
var cursor = {
|
|
178415
|
+
hide: "\x1B[?25l",
|
|
178416
|
+
show: "\x1B[?25h",
|
|
178417
|
+
up: (n = 1) => `\x1B[${n}A`,
|
|
178418
|
+
down: (n = 1) => `\x1B[${n}B`,
|
|
178419
|
+
forward: (n = 1) => `\x1B[${n}C`,
|
|
178420
|
+
back: (n = 1) => `\x1B[${n}D`,
|
|
178421
|
+
left: "\x1B[G",
|
|
178422
|
+
clearLine: "\x1B[2K",
|
|
178423
|
+
clearDown: "\x1B[J",
|
|
178424
|
+
save: "\x1B[s",
|
|
178425
|
+
restore: "\x1B[u"
|
|
178426
|
+
};
|
|
178427
|
+
function clearLine() {
|
|
178428
|
+
if (isTTY2()) {
|
|
178429
|
+
process.stdout.write(cursor.clearLine + cursor.left);
|
|
178430
|
+
}
|
|
178431
|
+
}
|
|
178432
|
+
function hideCursor() {
|
|
178433
|
+
if (isTTY2()) {
|
|
178434
|
+
process.stdout.write(cursor.hide);
|
|
178435
|
+
}
|
|
178436
|
+
}
|
|
178437
|
+
function showCursor() {
|
|
178438
|
+
if (isTTY2()) {
|
|
178439
|
+
process.stdout.write(cursor.show);
|
|
178440
|
+
}
|
|
178441
|
+
}
|
|
178442
|
+
function truncate(text, maxLength) {
|
|
178443
|
+
if (text.length <= maxLength)
|
|
178444
|
+
return text;
|
|
178445
|
+
return `${text.slice(0, maxLength - 1)}…`;
|
|
178446
|
+
}
|
|
178447
|
+
|
|
178448
|
+
// src/utils/progress/spinner.ts
|
|
178449
|
+
var spinnerColors = {
|
|
178450
|
+
cyan: chalk3.cyan,
|
|
178451
|
+
yellow: chalk3.yellow,
|
|
178452
|
+
green: chalk3.green,
|
|
178453
|
+
red: chalk3.red,
|
|
178454
|
+
magenta: chalk3.magenta,
|
|
178455
|
+
blue: chalk3.blue,
|
|
178456
|
+
white: chalk3.white
|
|
178457
|
+
};
|
|
178458
|
+
var FRAME_SETS = {
|
|
178459
|
+
dots: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
178460
|
+
circle: ["◐", "◓", "◑", "◒"]
|
|
178461
|
+
};
|
|
178462
|
+
var ASCII_FRAME_SET = ["-", "\\", "|", "/"];
|
|
178463
|
+
|
|
178464
|
+
class Spinner {
|
|
178465
|
+
label;
|
|
178466
|
+
detail;
|
|
178467
|
+
frames;
|
|
178468
|
+
interval;
|
|
178469
|
+
colorFn;
|
|
178470
|
+
frameIndex = 0;
|
|
178471
|
+
timer = null;
|
|
178472
|
+
state = "stopped";
|
|
178473
|
+
symbols = getSymbols(supportsUnicode());
|
|
178474
|
+
lastRenderedLines = 0;
|
|
178475
|
+
sigintHandler = null;
|
|
178476
|
+
constructor(options = {}) {
|
|
178477
|
+
this.label = options.label ?? "";
|
|
178478
|
+
this.detail = options.detail;
|
|
178479
|
+
this.interval = options.interval ?? 80;
|
|
178480
|
+
this.colorFn = spinnerColors[options.color ?? "cyan"];
|
|
178481
|
+
const style = options.style ?? "circle";
|
|
178482
|
+
this.frames = supportsUnicode() ? FRAME_SETS[style] : ASCII_FRAME_SET;
|
|
178483
|
+
}
|
|
178484
|
+
start(label) {
|
|
178485
|
+
if (label !== undefined)
|
|
178486
|
+
this.label = label;
|
|
178487
|
+
if (this.state === "spinning")
|
|
178488
|
+
return this;
|
|
178489
|
+
this.state = "spinning";
|
|
178490
|
+
this.frameIndex = 0;
|
|
178491
|
+
this.lastRenderedLines = 0;
|
|
178492
|
+
if (!isInteractive()) {
|
|
178493
|
+
console.log(`${this.symbols.bullet} ${this.label}`);
|
|
178494
|
+
return this;
|
|
178495
|
+
}
|
|
178496
|
+
hideCursor();
|
|
178497
|
+
this.setupSignalHandler();
|
|
178498
|
+
this.render();
|
|
178499
|
+
this.timer = setInterval(() => {
|
|
178500
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
178501
|
+
this.render();
|
|
178502
|
+
}, this.interval);
|
|
178503
|
+
return this;
|
|
178504
|
+
}
|
|
178505
|
+
stop() {
|
|
178506
|
+
if (this.timer) {
|
|
178507
|
+
clearInterval(this.timer);
|
|
178508
|
+
this.timer = null;
|
|
178509
|
+
}
|
|
178510
|
+
this.state = "stopped";
|
|
178511
|
+
this.clearOutput();
|
|
178512
|
+
this.cleanup();
|
|
178513
|
+
return this;
|
|
178514
|
+
}
|
|
178515
|
+
success(label) {
|
|
178516
|
+
if (label !== undefined)
|
|
178517
|
+
this.label = label;
|
|
178518
|
+
this.finish("success");
|
|
178519
|
+
return this;
|
|
178520
|
+
}
|
|
178521
|
+
fail(label) {
|
|
178522
|
+
if (label !== undefined)
|
|
178523
|
+
this.label = label;
|
|
178524
|
+
this.finish("error");
|
|
178525
|
+
return this;
|
|
178526
|
+
}
|
|
178527
|
+
update(label) {
|
|
178528
|
+
this.label = label;
|
|
178529
|
+
if (this.state === "spinning" && isInteractive()) {
|
|
178530
|
+
this.render();
|
|
178531
|
+
}
|
|
178532
|
+
return this;
|
|
178533
|
+
}
|
|
178534
|
+
setDetail(detail) {
|
|
178535
|
+
this.detail = detail;
|
|
178536
|
+
if (this.state === "spinning" && isInteractive()) {
|
|
178537
|
+
this.render();
|
|
178538
|
+
}
|
|
178539
|
+
return this;
|
|
178540
|
+
}
|
|
178541
|
+
get isSpinning() {
|
|
178542
|
+
return this.state === "spinning";
|
|
178543
|
+
}
|
|
178544
|
+
finish(state) {
|
|
178545
|
+
if (this.timer) {
|
|
178546
|
+
clearInterval(this.timer);
|
|
178547
|
+
this.timer = null;
|
|
178548
|
+
}
|
|
178549
|
+
this.state = state;
|
|
178550
|
+
if (!isInteractive()) {
|
|
178551
|
+
const symbol = state === "success" ? this.symbols.success : this.symbols.error;
|
|
178552
|
+
const colorFn = state === "success" ? colors.success : colors.error;
|
|
178553
|
+
console.log(`${colorFn(symbol)} ${this.label}`);
|
|
178554
|
+
} else {
|
|
178555
|
+
this.clearOutput();
|
|
178556
|
+
const symbol = state === "success" ? this.symbols.success : this.symbols.error;
|
|
178557
|
+
const colorFn = state === "success" ? colors.success : colors.error;
|
|
178558
|
+
process.stdout.write(`${colorFn(symbol)} ${this.label}
|
|
178559
|
+
`);
|
|
178560
|
+
}
|
|
178561
|
+
this.cleanup();
|
|
178562
|
+
}
|
|
178563
|
+
render() {
|
|
178564
|
+
if (!isTTY2())
|
|
178565
|
+
return;
|
|
178566
|
+
this.clearOutput();
|
|
178567
|
+
const frame = this.colorFn(this.frames[this.frameIndex]);
|
|
178568
|
+
const width = getTerminalWidth();
|
|
178569
|
+
const mainLine = truncate(`${frame} ${this.label}`, width);
|
|
178570
|
+
process.stdout.write(mainLine);
|
|
178571
|
+
let lines = 1;
|
|
178572
|
+
if (this.detail) {
|
|
178573
|
+
const detailLine = truncate(` ${colors.muted(this.detail)}`, width);
|
|
178574
|
+
process.stdout.write(`
|
|
178575
|
+
${detailLine}`);
|
|
178576
|
+
lines = 2;
|
|
178577
|
+
}
|
|
178578
|
+
this.lastRenderedLines = lines;
|
|
178579
|
+
}
|
|
178580
|
+
clearOutput() {
|
|
178581
|
+
if (!isTTY2())
|
|
178582
|
+
return;
|
|
178583
|
+
for (let i = 0;i < this.lastRenderedLines; i++) {
|
|
178584
|
+
if (i > 0)
|
|
178585
|
+
process.stdout.write(cursor.up(1));
|
|
178586
|
+
clearLine();
|
|
178587
|
+
}
|
|
178588
|
+
}
|
|
178589
|
+
setupSignalHandler() {
|
|
178590
|
+
this.sigintHandler = () => {
|
|
178591
|
+
this.cleanup();
|
|
178592
|
+
process.exit(130);
|
|
178593
|
+
};
|
|
178594
|
+
process.on("SIGINT", this.sigintHandler);
|
|
178595
|
+
}
|
|
178596
|
+
cleanup() {
|
|
178597
|
+
if (this.sigintHandler) {
|
|
178598
|
+
process.removeListener("SIGINT", this.sigintHandler);
|
|
178599
|
+
this.sigintHandler = null;
|
|
178600
|
+
}
|
|
178601
|
+
showCursor();
|
|
178602
|
+
}
|
|
178603
|
+
}
|
|
178604
|
+
|
|
178053
178605
|
// src/commands/init.ts
|
|
178054
178606
|
var __dirname15 = path33.dirname(fileURLToPath14(import.meta.url));
|
|
178055
178607
|
function getVersion14() {
|
|
@@ -178075,7 +178627,7 @@ async function scanPackage(cwd, pkgDir) {
|
|
|
178075
178627
|
try {
|
|
178076
178628
|
const entryFile = detectEntry(absDir);
|
|
178077
178629
|
const result = await extract({ entryFile });
|
|
178078
|
-
const spec =
|
|
178630
|
+
const spec = normalize7(result.spec);
|
|
178079
178631
|
const exports = spec.exports ?? [];
|
|
178080
178632
|
const total = exports.length;
|
|
178081
178633
|
let documented = 0;
|
|
@@ -178084,7 +178636,8 @@ async function scanPackage(cwd, pkgDir) {
|
|
|
178084
178636
|
documented++;
|
|
178085
178637
|
}
|
|
178086
178638
|
const coverage = total > 0 ? Math.round(documented / total * 100) : 100;
|
|
178087
|
-
|
|
178639
|
+
const health = Math.round(coverage * 0.5 + 100 * 0.5);
|
|
178640
|
+
return { name, entry: path33.relative(cwd, entryFile), exports: total, coverage, health };
|
|
178088
178641
|
} catch {
|
|
178089
178642
|
return null;
|
|
178090
178643
|
}
|
|
@@ -178105,12 +178658,16 @@ function registerInitCommand(program) {
|
|
|
178105
178658
|
const workspaces = detectWorkspaces(cwd);
|
|
178106
178659
|
const isMonorepo = workspaces !== null;
|
|
178107
178660
|
const packageDirs = isMonorepo ? resolveGlobs(cwd, workspaces) : ["."];
|
|
178661
|
+
const spin = new Spinner({ style: "dots" });
|
|
178662
|
+
spin.start("Scanning packages…");
|
|
178108
178663
|
const packages = [];
|
|
178109
178664
|
for (const dir of packageDirs) {
|
|
178665
|
+
spin.update(`Scanning ${dir}…`);
|
|
178110
178666
|
const result = await scanPackage(cwd, dir);
|
|
178111
178667
|
if (result)
|
|
178112
178668
|
packages.push(result);
|
|
178113
178669
|
}
|
|
178670
|
+
spin.success(`Scanned ${packages.length} package${packages.length === 1 ? "" : "s"}`);
|
|
178114
178671
|
if (packages.length === 0) {
|
|
178115
178672
|
formatError("init", "No TypeScript packages found", startTime, version);
|
|
178116
178673
|
return;
|
|
@@ -178523,6 +179080,13 @@ function renderList(data) {
|
|
|
178523
179080
|
lines.push(` ${c.bold(`${total} exports`)}`);
|
|
178524
179081
|
}
|
|
178525
179082
|
lines.push("");
|
|
179083
|
+
if (total === 0 && data.filter) {
|
|
179084
|
+
const msg = data.filter === "undocumented" ? `${c.green(sym.ok)} All exports are documented` : `${c.green(sym.ok)} No drifted exports found`;
|
|
179085
|
+
lines.push(indent(msg));
|
|
179086
|
+
lines.push("");
|
|
179087
|
+
return lines.join(`
|
|
179088
|
+
`);
|
|
179089
|
+
}
|
|
178526
179090
|
if (!data.search) {
|
|
178527
179091
|
const kindCounts = new Map;
|
|
178528
179092
|
for (const exp of exports) {
|
|
@@ -178579,9 +179143,14 @@ function registerListCommand(program) {
|
|
|
178579
179143
|
const rows = [];
|
|
178580
179144
|
for (const pkg of packages) {
|
|
178581
179145
|
const res = await listExports({ entryFile: pkg.entry });
|
|
178582
|
-
|
|
179146
|
+
let filtered = res.exports;
|
|
179147
|
+
if (options.undocumented) {
|
|
179148
|
+
filtered = filtered.filter((e) => !e.description || e.description.trim().length === 0);
|
|
179149
|
+
}
|
|
179150
|
+
rows.push({ name: pkg.name, count: filtered.length });
|
|
178583
179151
|
}
|
|
178584
|
-
|
|
179152
|
+
const filter2 = options.undocumented ? "undocumented" : undefined;
|
|
179153
|
+
formatOutput("list", { packages: rows, filter: filter2 }, startTime, version, renderBatchList);
|
|
178585
179154
|
return;
|
|
178586
179155
|
}
|
|
178587
179156
|
let entryFile;
|
|
@@ -178618,6 +179187,7 @@ function registerListCommand(program) {
|
|
|
178618
179187
|
const matches = fuzzySearch(searchTerm, exports);
|
|
178619
179188
|
exports = matches.map((m) => exports.find((e) => e.name === m.name));
|
|
178620
179189
|
}
|
|
179190
|
+
const filter = options.undocumented ? "undocumented" : options.drifted ? "drifted" : undefined;
|
|
178621
179191
|
const data = {
|
|
178622
179192
|
exports: exports.map((e) => ({
|
|
178623
179193
|
name: e.name,
|
|
@@ -178626,7 +179196,8 @@ function registerListCommand(program) {
|
|
|
178626
179196
|
...e.deprecated ? { deprecated: true } : {}
|
|
178627
179197
|
})),
|
|
178628
179198
|
...searchTerm ? { search: searchTerm } : {},
|
|
178629
|
-
showAll: !!options.full
|
|
179199
|
+
showAll: !!options.full,
|
|
179200
|
+
...filter ? { filter } : {}
|
|
178630
179201
|
};
|
|
178631
179202
|
formatOutput("list", data, startTime, version, renderList);
|
|
178632
179203
|
} catch (err) {
|
|
@@ -178968,7 +179539,7 @@ function registerReportCommand(program) {
|
|
|
178968
179539
|
import { readFileSync as readFileSync36 } from "node:fs";
|
|
178969
179540
|
import * as path40 from "node:path";
|
|
178970
179541
|
import { fileURLToPath as fileURLToPath20 } from "node:url";
|
|
178971
|
-
import { diffSpec as
|
|
179542
|
+
import { diffSpec as diffSpec8, recommendSemverBump as recommendSemverBump3 } from "@openpkg-ts/spec";
|
|
178972
179543
|
|
|
178973
179544
|
// src/formatters/semver.ts
|
|
178974
179545
|
function renderSemver(data) {
|
|
@@ -178997,7 +179568,7 @@ function registerSemverCommand(program) {
|
|
|
178997
179568
|
try {
|
|
178998
179569
|
const args = [oldPath, newPath].filter(Boolean);
|
|
178999
179570
|
const { oldSpec, newSpec } = await resolveSpecs({ args, ...options });
|
|
179000
|
-
const diff =
|
|
179571
|
+
const diff = diffSpec8(oldSpec, newSpec);
|
|
179001
179572
|
const recommendation = recommendSemverBump3(diff);
|
|
179002
179573
|
const data = {
|
|
179003
179574
|
bump: recommendation.bump,
|
|
@@ -179158,6 +179729,12 @@ if (process.argv.includes("--capabilities")) {
|
|
|
179158
179729
|
`);
|
|
179159
179730
|
process.exit(0);
|
|
179160
179731
|
}
|
|
179732
|
+
var userArgs = process.argv.slice(2).filter((a) => !a.startsWith("-"));
|
|
179733
|
+
if (userArgs.length === 0) {
|
|
179734
|
+
const { configPath } = loadConfig();
|
|
179735
|
+
const subcommand = configPath ? "health" : "init";
|
|
179736
|
+
process.argv.splice(2, 0, subcommand);
|
|
179737
|
+
}
|
|
179161
179738
|
program.parseAsync().catch(() => {
|
|
179162
179739
|
process.exit(1);
|
|
179163
179740
|
});
|