@fern-api/fern-api-dev 3.27.3 → 3.29.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/cli.cjs +515 -15
- package/package.json +1 -1
package/cli.cjs
CHANGED
|
@@ -1413817,7 +1413817,7 @@ var AccessTokenPosthogManager = class {
|
|
|
1413817
1413817
|
properties: {
|
|
1413818
1413818
|
...event,
|
|
1413819
1413819
|
...event.properties,
|
|
1413820
|
-
version: "3.
|
|
1413820
|
+
version: "3.29.0",
|
|
1413821
1413821
|
usingAccessToken: true
|
|
1413822
1413822
|
}
|
|
1413823
1413823
|
});
|
|
@@ -1413916,7 +1413916,7 @@ var UserPosthogManager = class {
|
|
|
1413916
1413916
|
distinctId: this.userId ?? await this.getPersistedDistinctId(),
|
|
1413917
1413917
|
event: "CLI",
|
|
1413918
1413918
|
properties: {
|
|
1413919
|
-
version: "3.
|
|
1413919
|
+
version: "3.29.0",
|
|
1413920
1413920
|
...event,
|
|
1413921
1413921
|
...event.properties,
|
|
1413922
1413922
|
usingAccessToken: false,
|
|
@@ -1493982,7 +1493982,7 @@ var CliContext = class {
|
|
|
1493982
1493982
|
if (false) {
|
|
1493983
1493983
|
this.logger.error("CLI_VERSION is not defined");
|
|
1493984
1493984
|
}
|
|
1493985
|
-
return "3.
|
|
1493985
|
+
return "3.29.0";
|
|
1493986
1493986
|
}
|
|
1493987
1493987
|
getCliName() {
|
|
1493988
1493988
|
if (false) {
|
|
@@ -1588481,7 +1588481,7 @@ var import_path35 = __toESM(require("path"), 1);
|
|
|
1588481
1588481
|
var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
|
|
1588482
1588482
|
var LOGS_FOLDER_NAME = "logs";
|
|
1588483
1588483
|
function getCliSource() {
|
|
1588484
|
-
const version6 = "3.
|
|
1588484
|
+
const version6 = "3.29.0";
|
|
1588485
1588485
|
return `cli@${version6}`;
|
|
1588486
1588486
|
}
|
|
1588487
1588487
|
var DebugLogger = class {
|
|
@@ -1604996,7 +1604996,8 @@ function logViolationsGroup({
|
|
|
1604996
1604996
|
if (title5 === "") {
|
|
1604997
1604997
|
title5 = violation.relativeFilepath;
|
|
1604998
1604998
|
}
|
|
1604999
|
-
|
|
1604999
|
+
const severityLabel = getSeverityLabel(violation.severity);
|
|
1605000
|
+
return `${severityLabel} ${violation.message}`;
|
|
1605000
1605001
|
}).filter((message) => message != null).join("\n");
|
|
1605001
1605002
|
context2.logger.log(
|
|
1605002
1605003
|
getLogLevelForSeverity(severity),
|
|
@@ -1605032,6 +1605033,18 @@ function getLogLevelForSeverity(severity) {
|
|
|
1605032
1605033
|
assertNever(severity);
|
|
1605033
1605034
|
}
|
|
1605034
1605035
|
}
|
|
1605036
|
+
function getSeverityLabel(severity) {
|
|
1605037
|
+
switch (severity) {
|
|
1605038
|
+
case "fatal":
|
|
1605039
|
+
return source_default.red("[error]");
|
|
1605040
|
+
case "error":
|
|
1605041
|
+
return source_default.red("[error]");
|
|
1605042
|
+
case "warning":
|
|
1605043
|
+
return source_default.yellow("[warning]");
|
|
1605044
|
+
default:
|
|
1605045
|
+
assertNever(severity);
|
|
1605046
|
+
}
|
|
1605047
|
+
}
|
|
1605035
1605048
|
function logViolationsSummary({
|
|
1605036
1605049
|
stats,
|
|
1605037
1605050
|
context: context2,
|
|
@@ -1605079,6 +1605092,39 @@ function getViolationStats(violations) {
|
|
|
1605079
1605092
|
}
|
|
1605080
1605093
|
|
|
1605081
1605094
|
// src/commands/validate/validateDocsWorkspaceAndLogIssues.ts
|
|
1605095
|
+
async function collectDocsWorkspaceViolations({
|
|
1605096
|
+
workspace,
|
|
1605097
|
+
apiWorkspaces,
|
|
1605098
|
+
ossWorkspaces,
|
|
1605099
|
+
context: context2,
|
|
1605100
|
+
errorOnBrokenLinks,
|
|
1605101
|
+
excludeRules
|
|
1605102
|
+
}) {
|
|
1605103
|
+
if (workspace.config.settings?.substituteEnvVars) {
|
|
1605104
|
+
workspace.config = replaceEnvVariables(workspace.config, {
|
|
1605105
|
+
onError: (e6) => context2.failAndThrow(e6)
|
|
1605106
|
+
});
|
|
1605107
|
+
}
|
|
1605108
|
+
const startTime = performance.now();
|
|
1605109
|
+
const violations = await validateDocsWorkspace(
|
|
1605110
|
+
workspace,
|
|
1605111
|
+
context2,
|
|
1605112
|
+
apiWorkspaces,
|
|
1605113
|
+
ossWorkspaces,
|
|
1605114
|
+
false,
|
|
1605115
|
+
excludeRules
|
|
1605116
|
+
);
|
|
1605117
|
+
const elapsedMillis = performance.now() - startTime;
|
|
1605118
|
+
let hasErrors = violations.some((v21) => v21.severity === "fatal" || v21.severity === "error");
|
|
1605119
|
+
if (errorOnBrokenLinks) {
|
|
1605120
|
+
hasErrors = hasErrors || violations.some((violation) => violation.name === "valid-markdown-links");
|
|
1605121
|
+
}
|
|
1605122
|
+
return {
|
|
1605123
|
+
violations,
|
|
1605124
|
+
elapsedMillis,
|
|
1605125
|
+
hasErrors
|
|
1605126
|
+
};
|
|
1605127
|
+
}
|
|
1605082
1605128
|
async function validateDocsWorkspaceWithoutExiting({
|
|
1605083
1605129
|
workspace,
|
|
1605084
1605130
|
apiWorkspaces,
|
|
@@ -1605251,6 +1605297,110 @@ async function previewDocsWorkspace({
|
|
|
1605251
1605297
|
return;
|
|
1605252
1605298
|
}
|
|
1605253
1605299
|
|
|
1605300
|
+
// src/commands/docs-preview/deleteDocsPreview.ts
|
|
1605301
|
+
var PREVIEW_URL_PATTERN = /^[a-z0-9-]+-preview-[a-z0-9]+\.docs\.buildwithfern\.com$/i;
|
|
1605302
|
+
function isPreviewUrl(url2) {
|
|
1605303
|
+
let hostname = url2.toLowerCase().trim();
|
|
1605304
|
+
if (hostname.startsWith("https://")) {
|
|
1605305
|
+
hostname = hostname.slice(8);
|
|
1605306
|
+
} else if (hostname.startsWith("http://")) {
|
|
1605307
|
+
hostname = hostname.slice(7);
|
|
1605308
|
+
}
|
|
1605309
|
+
const slashIndex = hostname.indexOf("/");
|
|
1605310
|
+
if (slashIndex !== -1) {
|
|
1605311
|
+
hostname = hostname.slice(0, slashIndex);
|
|
1605312
|
+
}
|
|
1605313
|
+
return PREVIEW_URL_PATTERN.test(hostname);
|
|
1605314
|
+
}
|
|
1605315
|
+
async function deleteDocsPreview({
|
|
1605316
|
+
cliContext,
|
|
1605317
|
+
previewUrl
|
|
1605318
|
+
}) {
|
|
1605319
|
+
if (!isPreviewUrl(previewUrl)) {
|
|
1605320
|
+
cliContext.failAndThrow(
|
|
1605321
|
+
`Invalid preview URL: ${previewUrl}
|
|
1605322
|
+
Only preview sites can be deleted with this command.
|
|
1605323
|
+
Preview URLs follow the pattern: {org}-preview-{hash}.docs.buildwithfern.com
|
|
1605324
|
+
Example: acme-preview-abc123.docs.buildwithfern.com`
|
|
1605325
|
+
);
|
|
1605326
|
+
return;
|
|
1605327
|
+
}
|
|
1605328
|
+
const token = await cliContext.runTask(async (context2) => {
|
|
1605329
|
+
return askToLogin(context2);
|
|
1605330
|
+
});
|
|
1605331
|
+
if (token == null) {
|
|
1605332
|
+
cliContext.failAndThrow("Failed to authenticate. Please run 'fern login' first.");
|
|
1605333
|
+
return;
|
|
1605334
|
+
}
|
|
1605335
|
+
await cliContext.runTask(async (context2) => {
|
|
1605336
|
+
context2.logger.info(`Deleting preview site: ${previewUrl}`);
|
|
1605337
|
+
const fdr = createFdrService({ token: token.value });
|
|
1605338
|
+
const deleteResponse = await fdr.docs.v2.write.deleteDocsSite({
|
|
1605339
|
+
url: previewUrl
|
|
1605340
|
+
});
|
|
1605341
|
+
if (deleteResponse.ok) {
|
|
1605342
|
+
context2.logger.info(source_default.green(`Successfully deleted preview site: ${previewUrl}`));
|
|
1605343
|
+
} else {
|
|
1605344
|
+
switch (deleteResponse.error.error) {
|
|
1605345
|
+
case "UnauthorizedError":
|
|
1605346
|
+
return context2.failAndThrow(
|
|
1605347
|
+
"You do not have permissions to delete this preview site. Reach out to support@buildwithfern.com"
|
|
1605348
|
+
);
|
|
1605349
|
+
case "DocsNotFoundError":
|
|
1605350
|
+
return context2.failAndThrow(`Preview site not found: ${previewUrl}`);
|
|
1605351
|
+
default:
|
|
1605352
|
+
return context2.failAndThrow(`Failed to delete preview site: ${previewUrl}`, deleteResponse.error);
|
|
1605353
|
+
}
|
|
1605354
|
+
}
|
|
1605355
|
+
});
|
|
1605356
|
+
}
|
|
1605357
|
+
|
|
1605358
|
+
// src/commands/docs-preview/listDocsPreview.ts
|
|
1605359
|
+
async function listDocsPreview({
|
|
1605360
|
+
cliContext,
|
|
1605361
|
+
limit,
|
|
1605362
|
+
page
|
|
1605363
|
+
}) {
|
|
1605364
|
+
const token = await cliContext.runTask(async (context2) => {
|
|
1605365
|
+
return askToLogin(context2);
|
|
1605366
|
+
});
|
|
1605367
|
+
if (token == null) {
|
|
1605368
|
+
cliContext.failAndThrow("Failed to authenticate. Please run 'fern login' first.");
|
|
1605369
|
+
return;
|
|
1605370
|
+
}
|
|
1605371
|
+
await cliContext.runTask(async (context2) => {
|
|
1605372
|
+
context2.logger.info("Fetching preview deployments...");
|
|
1605373
|
+
const fdr = createFdrService({ token: token.value });
|
|
1605374
|
+
const listResponse = await fdr.docs.v2.read.listAllDocsUrls({
|
|
1605375
|
+
page,
|
|
1605376
|
+
limit: limit ?? 100
|
|
1605377
|
+
});
|
|
1605378
|
+
if (!listResponse.ok) {
|
|
1605379
|
+
return context2.failAndThrow("Failed to fetch docs URLs", listResponse.error);
|
|
1605380
|
+
}
|
|
1605381
|
+
const previewUrlPattern = /-preview-[a-f0-9]+\.docs\.buildwithfern\.com$/;
|
|
1605382
|
+
const previewDeployments = listResponse.body.urls.filter((item) => previewUrlPattern.test(item.domain)).map((item) => ({
|
|
1605383
|
+
url: item.basePath != null ? `${item.domain}${item.basePath}` : item.domain,
|
|
1605384
|
+
organizationId: item.organizationId,
|
|
1605385
|
+
updatedAt: item.updatedAt
|
|
1605386
|
+
}));
|
|
1605387
|
+
if (previewDeployments.length === 0) {
|
|
1605388
|
+
context2.logger.info("No preview deployments found.");
|
|
1605389
|
+
return;
|
|
1605390
|
+
}
|
|
1605391
|
+
context2.logger.info(source_default.bold(`
|
|
1605392
|
+
Found ${previewDeployments.length} preview deployment(s):
|
|
1605393
|
+
`));
|
|
1605394
|
+
for (const deployment of previewDeployments) {
|
|
1605395
|
+
const updatedDate = new Date(deployment.updatedAt).toLocaleString();
|
|
1605396
|
+
context2.logger.info(` ${source_default.cyan(deployment.url)}`);
|
|
1605397
|
+
context2.logger.info(` Organization: ${deployment.organizationId}`);
|
|
1605398
|
+
context2.logger.info(` Updated: ${updatedDate}
|
|
1605399
|
+
`);
|
|
1605400
|
+
}
|
|
1605401
|
+
});
|
|
1605402
|
+
}
|
|
1605403
|
+
|
|
1605254
1605404
|
// src/commands/downgrade/downgrade.ts
|
|
1605255
1605405
|
var import_promises80 = require("fs/promises");
|
|
1605256
1605406
|
|
|
@@ -1638023,6 +1638173,30 @@ async function runRulesOnOSSWorkspace({ workspace, context: context2, rules }) {
|
|
|
1638023
1638173
|
|
|
1638024
1638174
|
// src/commands/validate/validateAPIWorkspaceAndLogIssues.ts
|
|
1638025
1638175
|
var import_validate_npm_package_name = __toESM(require_lib20(), 1);
|
|
1638176
|
+
async function collectAPIWorkspaceViolations({
|
|
1638177
|
+
workspace,
|
|
1638178
|
+
context: context2,
|
|
1638179
|
+
ossWorkspace
|
|
1638180
|
+
}) {
|
|
1638181
|
+
if (!(0, import_validate_npm_package_name.default)(workspace.definition.rootApiFile.contents.name).validForNewPackages) {
|
|
1638182
|
+
context2.failAndThrow("API name is not valid.");
|
|
1638183
|
+
}
|
|
1638184
|
+
const startTime = performance.now();
|
|
1638185
|
+
const apiViolations = validateFernWorkspace(workspace, context2.logger);
|
|
1638186
|
+
const generatorViolations = await validateGeneratorsWorkspace(workspace, context2.logger);
|
|
1638187
|
+
const violations = [...apiViolations, ...generatorViolations];
|
|
1638188
|
+
if (ossWorkspace) {
|
|
1638189
|
+
violations.push(...await validateOSSWorkspace(ossWorkspace, context2));
|
|
1638190
|
+
}
|
|
1638191
|
+
const elapsedMillis = performance.now() - startTime;
|
|
1638192
|
+
const hasErrors = violations.some((v21) => v21.severity === "fatal" || v21.severity === "error");
|
|
1638193
|
+
return {
|
|
1638194
|
+
apiName: workspace.definition.rootApiFile.contents.name,
|
|
1638195
|
+
violations,
|
|
1638196
|
+
elapsedMillis,
|
|
1638197
|
+
hasErrors
|
|
1638198
|
+
};
|
|
1638199
|
+
}
|
|
1638026
1638200
|
async function validateAPIWorkspaceWithoutExiting({
|
|
1638027
1638201
|
workspace,
|
|
1638028
1638202
|
context: context2,
|
|
@@ -1643812,6 +1643986,230 @@ async function validateDocsBrokenLinks({
|
|
|
1643812
1643986
|
});
|
|
1643813
1643987
|
}
|
|
1643814
1643988
|
|
|
1643989
|
+
// src/commands/validate/printCheckReport.ts
|
|
1643990
|
+
function printCheckReport({ apiResults, docsResult, logWarnings, context: context2 }) {
|
|
1643991
|
+
const startTime = performance.now();
|
|
1643992
|
+
let hasErrors = false;
|
|
1643993
|
+
const apiResultsWithViolations = apiResults.filter((result) => {
|
|
1643994
|
+
const stats = getViolationStats2(result.violations);
|
|
1643995
|
+
return stats.numErrors > 0 || logWarnings && stats.numWarnings > 0;
|
|
1643996
|
+
});
|
|
1643997
|
+
if (apiResultsWithViolations.length > 0) {
|
|
1643998
|
+
const totalSdkStats = getTotalStats(apiResults.map((r23) => r23.violations).flat());
|
|
1643999
|
+
const showApiNesting = apiResults.length > 1;
|
|
1644000
|
+
if (showApiNesting) {
|
|
1644001
|
+
context2.logger.info(source_default.cyan(source_default.bold("[sdk]")));
|
|
1644002
|
+
for (const apiResult of apiResults) {
|
|
1644003
|
+
const stats = getViolationStats2(apiResult.violations);
|
|
1644004
|
+
if (stats.numErrors > 0 || logWarnings && stats.numWarnings > 0) {
|
|
1644005
|
+
hasErrors = hasErrors || stats.numErrors > 0;
|
|
1644006
|
+
printApiSection({
|
|
1644007
|
+
apiName: apiResult.apiName,
|
|
1644008
|
+
violations: apiResult.violations,
|
|
1644009
|
+
stats,
|
|
1644010
|
+
logWarnings,
|
|
1644011
|
+
context: context2,
|
|
1644012
|
+
indent: " "
|
|
1644013
|
+
});
|
|
1644014
|
+
}
|
|
1644015
|
+
}
|
|
1644016
|
+
} else {
|
|
1644017
|
+
hasErrors = hasErrors || totalSdkStats.numErrors > 0;
|
|
1644018
|
+
printSdkSectionFlat({
|
|
1644019
|
+
violations: apiResults[0]?.violations ?? [],
|
|
1644020
|
+
stats: totalSdkStats,
|
|
1644021
|
+
logWarnings,
|
|
1644022
|
+
context: context2
|
|
1644023
|
+
});
|
|
1644024
|
+
}
|
|
1644025
|
+
}
|
|
1644026
|
+
if (docsResult != null) {
|
|
1644027
|
+
const docsStats = getViolationStats2(docsResult.violations);
|
|
1644028
|
+
if (docsStats.numErrors > 0 || logWarnings && docsStats.numWarnings > 0) {
|
|
1644029
|
+
hasErrors = hasErrors || docsStats.numErrors > 0;
|
|
1644030
|
+
printDocsSection({
|
|
1644031
|
+
violations: docsResult.violations,
|
|
1644032
|
+
stats: docsStats,
|
|
1644033
|
+
logWarnings,
|
|
1644034
|
+
context: context2
|
|
1644035
|
+
});
|
|
1644036
|
+
}
|
|
1644037
|
+
}
|
|
1644038
|
+
const totalElapsedMillis = performance.now() - startTime;
|
|
1644039
|
+
const allViolations = [...apiResults.map((r23) => r23.violations).flat(), ...docsResult?.violations ?? []];
|
|
1644040
|
+
const totalStats = getViolationStats2(allViolations);
|
|
1644041
|
+
printSummary({
|
|
1644042
|
+
stats: totalStats,
|
|
1644043
|
+
logWarnings,
|
|
1644044
|
+
elapsedMillis: totalElapsedMillis,
|
|
1644045
|
+
context: context2
|
|
1644046
|
+
});
|
|
1644047
|
+
return { hasErrors };
|
|
1644048
|
+
}
|
|
1644049
|
+
function printSdkSectionFlat({
|
|
1644050
|
+
violations,
|
|
1644051
|
+
stats,
|
|
1644052
|
+
logWarnings,
|
|
1644053
|
+
context: context2
|
|
1644054
|
+
}) {
|
|
1644055
|
+
const statsStr = formatStats(stats, logWarnings);
|
|
1644056
|
+
context2.logger.info(source_default.cyan(source_default.bold(`[sdk]`)) + ` ${statsStr}`);
|
|
1644057
|
+
printViolationsByType({
|
|
1644058
|
+
violations,
|
|
1644059
|
+
logWarnings,
|
|
1644060
|
+
context: context2,
|
|
1644061
|
+
indent: " "
|
|
1644062
|
+
});
|
|
1644063
|
+
}
|
|
1644064
|
+
function printApiSection({
|
|
1644065
|
+
apiName,
|
|
1644066
|
+
violations,
|
|
1644067
|
+
stats,
|
|
1644068
|
+
logWarnings,
|
|
1644069
|
+
context: context2,
|
|
1644070
|
+
indent: indent3
|
|
1644071
|
+
}) {
|
|
1644072
|
+
const statsStr = formatStats(stats, logWarnings);
|
|
1644073
|
+
context2.logger.info(`${indent3}${source_default.bold(`[${apiName}]`)} ${statsStr}`);
|
|
1644074
|
+
printViolationsByType({
|
|
1644075
|
+
violations,
|
|
1644076
|
+
logWarnings,
|
|
1644077
|
+
context: context2,
|
|
1644078
|
+
indent: indent3 + " "
|
|
1644079
|
+
});
|
|
1644080
|
+
}
|
|
1644081
|
+
function printDocsSection({
|
|
1644082
|
+
violations,
|
|
1644083
|
+
stats,
|
|
1644084
|
+
logWarnings,
|
|
1644085
|
+
context: context2
|
|
1644086
|
+
}) {
|
|
1644087
|
+
const statsStr = formatStats(stats, logWarnings);
|
|
1644088
|
+
context2.logger.info(source_default.magenta(source_default.bold(`[docs]`)) + ` ${statsStr}`);
|
|
1644089
|
+
printViolationsByType({
|
|
1644090
|
+
violations,
|
|
1644091
|
+
logWarnings,
|
|
1644092
|
+
context: context2,
|
|
1644093
|
+
indent: " "
|
|
1644094
|
+
});
|
|
1644095
|
+
}
|
|
1644096
|
+
function printViolationsByType({
|
|
1644097
|
+
violations,
|
|
1644098
|
+
logWarnings,
|
|
1644099
|
+
context: context2,
|
|
1644100
|
+
indent: indent3
|
|
1644101
|
+
}) {
|
|
1644102
|
+
const errors4 = violations.filter((v21) => v21.severity === "fatal" || v21.severity === "error");
|
|
1644103
|
+
const warnings = violations.filter((v21) => v21.severity === "warning");
|
|
1644104
|
+
if (logWarnings) {
|
|
1644105
|
+
for (const violation of warnings.sort(sortViolations)) {
|
|
1644106
|
+
printViolation({ violation, context: context2, indent: indent3 });
|
|
1644107
|
+
}
|
|
1644108
|
+
}
|
|
1644109
|
+
for (const violation of errors4.sort(sortViolations)) {
|
|
1644110
|
+
printViolation({ violation, context: context2, indent: indent3 });
|
|
1644111
|
+
}
|
|
1644112
|
+
}
|
|
1644113
|
+
function printViolation({
|
|
1644114
|
+
violation,
|
|
1644115
|
+
context: context2,
|
|
1644116
|
+
indent: indent3
|
|
1644117
|
+
}) {
|
|
1644118
|
+
const severityLabel = getSeverityLabel2(violation.severity);
|
|
1644119
|
+
const path68 = formatViolationPath(violation);
|
|
1644120
|
+
if (path68 === "") {
|
|
1644121
|
+
context2.logger.info(`${indent3}${severityLabel} ${violation.message}`);
|
|
1644122
|
+
} else {
|
|
1644123
|
+
context2.logger.info(`${indent3}${severityLabel}`);
|
|
1644124
|
+
context2.logger.info(`${indent3} path: ${source_default.blue(path68)}`);
|
|
1644125
|
+
context2.logger.info(`${indent3} issue: ${violation.message}`);
|
|
1644126
|
+
}
|
|
1644127
|
+
context2.logger.info("");
|
|
1644128
|
+
}
|
|
1644129
|
+
function formatViolationPath(violation) {
|
|
1644130
|
+
const parts = [];
|
|
1644131
|
+
if (violation.relativeFilepath !== "") {
|
|
1644132
|
+
parts.push(violation.relativeFilepath);
|
|
1644133
|
+
}
|
|
1644134
|
+
for (const nodePathItem of violation.nodePath) {
|
|
1644135
|
+
let itemStr = typeof nodePathItem === "string" ? nodePathItem : nodePathItem.key;
|
|
1644136
|
+
if (typeof nodePathItem !== "string" && nodePathItem.arrayIndex != null) {
|
|
1644137
|
+
itemStr += `[${nodePathItem.arrayIndex}]`;
|
|
1644138
|
+
}
|
|
1644139
|
+
parts.push(itemStr);
|
|
1644140
|
+
}
|
|
1644141
|
+
return parts.join(" -> ");
|
|
1644142
|
+
}
|
|
1644143
|
+
function getSeverityLabel2(severity) {
|
|
1644144
|
+
switch (severity) {
|
|
1644145
|
+
case "fatal":
|
|
1644146
|
+
return source_default.red("[error]");
|
|
1644147
|
+
case "error":
|
|
1644148
|
+
return source_default.red("[error]");
|
|
1644149
|
+
case "warning":
|
|
1644150
|
+
return source_default.yellow("[warning]");
|
|
1644151
|
+
default:
|
|
1644152
|
+
assertNever(severity);
|
|
1644153
|
+
}
|
|
1644154
|
+
}
|
|
1644155
|
+
function formatStats(stats, logWarnings) {
|
|
1644156
|
+
const parts = [];
|
|
1644157
|
+
if (stats.numErrors > 0) {
|
|
1644158
|
+
parts.push(`${stats.numErrors} error${stats.numErrors !== 1 ? "s" : ""}`);
|
|
1644159
|
+
}
|
|
1644160
|
+
if (logWarnings && stats.numWarnings > 0) {
|
|
1644161
|
+
parts.push(`${stats.numWarnings} warning${stats.numWarnings !== 1 ? "s" : ""}`);
|
|
1644162
|
+
}
|
|
1644163
|
+
return parts.join(", ");
|
|
1644164
|
+
}
|
|
1644165
|
+
function getViolationStats2(violations) {
|
|
1644166
|
+
let numErrors = 0;
|
|
1644167
|
+
let numWarnings = 0;
|
|
1644168
|
+
for (const violation of violations) {
|
|
1644169
|
+
switch (violation.severity) {
|
|
1644170
|
+
case "fatal":
|
|
1644171
|
+
case "error":
|
|
1644172
|
+
numErrors += 1;
|
|
1644173
|
+
break;
|
|
1644174
|
+
case "warning":
|
|
1644175
|
+
numWarnings += 1;
|
|
1644176
|
+
break;
|
|
1644177
|
+
default:
|
|
1644178
|
+
assertNever(violation.severity);
|
|
1644179
|
+
}
|
|
1644180
|
+
}
|
|
1644181
|
+
return { numErrors, numWarnings };
|
|
1644182
|
+
}
|
|
1644183
|
+
function getTotalStats(violations) {
|
|
1644184
|
+
return getViolationStats2(violations);
|
|
1644185
|
+
}
|
|
1644186
|
+
function sortViolations(a10, b18) {
|
|
1644187
|
+
const pathCompare = a10.relativeFilepath.localeCompare(b18.relativeFilepath);
|
|
1644188
|
+
if (pathCompare !== 0) {
|
|
1644189
|
+
return pathCompare;
|
|
1644190
|
+
}
|
|
1644191
|
+
return JSON.stringify(a10.nodePath).localeCompare(JSON.stringify(b18.nodePath));
|
|
1644192
|
+
}
|
|
1644193
|
+
function printSummary({
|
|
1644194
|
+
stats,
|
|
1644195
|
+
logWarnings,
|
|
1644196
|
+
elapsedMillis,
|
|
1644197
|
+
context: context2
|
|
1644198
|
+
}) {
|
|
1644199
|
+
const suffix = elapsedMillis > 0 ? ` in ${(elapsedMillis / 1e3).toFixed(3)} seconds.` : ".";
|
|
1644200
|
+
let message = `Found ${stats.numErrors} error${stats.numErrors !== 1 ? "s" : ""} and ${stats.numWarnings} warning${stats.numWarnings !== 1 ? "s" : ""}` + suffix;
|
|
1644201
|
+
if (!logWarnings && stats.numWarnings > 0) {
|
|
1644202
|
+
message += " Run fern check --warnings to print out the warnings not shown.";
|
|
1644203
|
+
}
|
|
1644204
|
+
if (stats.numErrors > 0) {
|
|
1644205
|
+
context2.logger.error(message);
|
|
1644206
|
+
} else if (stats.numWarnings > 0) {
|
|
1644207
|
+
context2.logger.warn(message);
|
|
1644208
|
+
} else {
|
|
1644209
|
+
context2.logger.info(source_default.green("All checks passed"));
|
|
1644210
|
+
}
|
|
1644211
|
+
}
|
|
1644212
|
+
|
|
1643815
1644213
|
// src/commands/validate/validateWorkspaces.ts
|
|
1643816
1644214
|
async function validateWorkspaces({
|
|
1643817
1644215
|
project,
|
|
@@ -1643822,28 +1644220,41 @@ async function validateWorkspaces({
|
|
|
1643822
1644220
|
isLocal,
|
|
1643823
1644221
|
directFromOpenapi
|
|
1643824
1644222
|
}) {
|
|
1644223
|
+
const apiResults = [];
|
|
1644224
|
+
let docsResult;
|
|
1644225
|
+
let hasAnyErrors = false;
|
|
1643825
1644226
|
const docsWorkspace = project.docsWorkspaces;
|
|
1643826
1644227
|
if (docsWorkspace != null) {
|
|
1644228
|
+
const excludeRules = brokenLinks || errorOnBrokenLinks ? [] : ["valid-markdown-links"];
|
|
1644229
|
+
const ossWorkspaces = await filterOssWorkspaces(project);
|
|
1644230
|
+
let collected;
|
|
1643827
1644231
|
await cliContext.runTaskForWorkspace(docsWorkspace, async (context2) => {
|
|
1643828
|
-
|
|
1643829
|
-
await validateDocsWorkspaceAndLogIssues({
|
|
1644232
|
+
collected = await collectDocsWorkspaceViolations({
|
|
1643830
1644233
|
workspace: docsWorkspace,
|
|
1643831
1644234
|
context: context2,
|
|
1643832
|
-
logWarnings,
|
|
1643833
1644235
|
apiWorkspaces: project.apiWorkspaces,
|
|
1643834
|
-
ossWorkspaces
|
|
1644236
|
+
ossWorkspaces,
|
|
1643835
1644237
|
errorOnBrokenLinks,
|
|
1643836
1644238
|
excludeRules
|
|
1643837
1644239
|
});
|
|
1643838
1644240
|
});
|
|
1644241
|
+
if (collected != null) {
|
|
1644242
|
+
docsResult = {
|
|
1644243
|
+
violations: collected.violations,
|
|
1644244
|
+
elapsedMillis: collected.elapsedMillis
|
|
1644245
|
+
};
|
|
1644246
|
+
if (collected.hasErrors) {
|
|
1644247
|
+
hasAnyErrors = true;
|
|
1644248
|
+
}
|
|
1644249
|
+
}
|
|
1643839
1644250
|
}
|
|
1643840
1644251
|
await Promise.all(
|
|
1643841
1644252
|
project.apiWorkspaces.map(async (workspace) => {
|
|
1643842
|
-
if (workspace.generatorsConfiguration?.groups.length === 0 && workspace.type
|
|
1644253
|
+
if (workspace.generatorsConfiguration?.groups.length === 0 && workspace.type !== "fern") {
|
|
1643843
1644254
|
return;
|
|
1643844
1644255
|
}
|
|
1643845
|
-
|
|
1643846
|
-
|
|
1644256
|
+
if (workspace instanceof OSSWorkspace && directFromOpenapi) {
|
|
1644257
|
+
await cliContext.runTaskForWorkspace(workspace, async (context2) => {
|
|
1643847
1644258
|
await workspace.getIntermediateRepresentation({
|
|
1643848
1644259
|
context: context2,
|
|
1643849
1644260
|
audiences: { type: "all" },
|
|
@@ -1643851,18 +1644262,56 @@ async function validateWorkspaces({
|
|
|
1643851
1644262
|
generateV1Examples: false,
|
|
1643852
1644263
|
logWarnings
|
|
1643853
1644264
|
});
|
|
1644265
|
+
});
|
|
1644266
|
+
return;
|
|
1644267
|
+
}
|
|
1644268
|
+
if (workspace instanceof LazyFernWorkspace) {
|
|
1644269
|
+
const absolutePathToApiYml = join2(
|
|
1644270
|
+
workspace.absoluteFilePath,
|
|
1644271
|
+
RelativeFilePath2.of(DEFINITION_DIRECTORY),
|
|
1644272
|
+
RelativeFilePath2.of(ROOT_API_FILENAME)
|
|
1644273
|
+
);
|
|
1644274
|
+
const apiYmlExists = await doesPathExist(absolutePathToApiYml);
|
|
1644275
|
+
if (!apiYmlExists) {
|
|
1644276
|
+
await cliContext.runTask(async (context2) => {
|
|
1644277
|
+
context2.logger.error(`Missing file: ${ROOT_API_FILENAME}`);
|
|
1644278
|
+
return context2.failAndThrow();
|
|
1644279
|
+
});
|
|
1643854
1644280
|
return;
|
|
1643855
1644281
|
}
|
|
1644282
|
+
}
|
|
1644283
|
+
let collected;
|
|
1644284
|
+
await cliContext.runTaskForWorkspace(workspace, async (context2) => {
|
|
1643856
1644285
|
const fernWorkspace = await workspace.toFernWorkspace({ context: context2 });
|
|
1643857
|
-
await
|
|
1644286
|
+
collected = await collectAPIWorkspaceViolations({
|
|
1643858
1644287
|
workspace: fernWorkspace,
|
|
1643859
1644288
|
context: context2,
|
|
1643860
|
-
logWarnings,
|
|
1643861
1644289
|
ossWorkspace: workspace instanceof OSSWorkspace ? workspace : void 0
|
|
1643862
1644290
|
});
|
|
1643863
1644291
|
});
|
|
1644292
|
+
if (collected != null) {
|
|
1644293
|
+
apiResults.push({
|
|
1644294
|
+
apiName: collected.apiName,
|
|
1644295
|
+
violations: collected.violations,
|
|
1644296
|
+
elapsedMillis: collected.elapsedMillis
|
|
1644297
|
+
});
|
|
1644298
|
+
if (collected.hasErrors) {
|
|
1644299
|
+
hasAnyErrors = true;
|
|
1644300
|
+
}
|
|
1644301
|
+
}
|
|
1643864
1644302
|
})
|
|
1643865
1644303
|
);
|
|
1644304
|
+
const { hasErrors } = await cliContext.runTask((context2) => {
|
|
1644305
|
+
return printCheckReport({
|
|
1644306
|
+
apiResults,
|
|
1644307
|
+
docsResult,
|
|
1644308
|
+
logWarnings,
|
|
1644309
|
+
context: context2
|
|
1644310
|
+
});
|
|
1644311
|
+
});
|
|
1644312
|
+
if (hasErrors || hasAnyErrors) {
|
|
1644313
|
+
cliContext.failAndThrow();
|
|
1644314
|
+
}
|
|
1643866
1644315
|
}
|
|
1643867
1644316
|
|
|
1643868
1644317
|
// src/commands/write-definition/writeDefinitionForWorkspaces.ts
|
|
@@ -1646365,12 +1646814,63 @@ function addWriteDefinitionCommand(cli, cliContext) {
|
|
|
1646365
1646814
|
}
|
|
1646366
1646815
|
function addDocsCommand(cli, cliContext) {
|
|
1646367
1646816
|
cli.command("docs", "Commands for managing your docs", (yargs) => {
|
|
1646368
|
-
|
|
1646817
|
+
addDocsDevCommand(yargs, cliContext);
|
|
1646369
1646818
|
addDocsBrokenLinksCommand(yargs, cliContext);
|
|
1646819
|
+
addDocsPreviewCommand(yargs, cliContext);
|
|
1646370
1646820
|
return yargs;
|
|
1646371
1646821
|
});
|
|
1646372
1646822
|
}
|
|
1646373
1646823
|
function addDocsPreviewCommand(cli, cliContext) {
|
|
1646824
|
+
cli.command("preview", "Commands for managing preview deployments", (yargs) => {
|
|
1646825
|
+
addDocsPreviewListCommand(yargs, cliContext);
|
|
1646826
|
+
addDocsPreviewDeleteCommand(yargs, cliContext);
|
|
1646827
|
+
return yargs;
|
|
1646828
|
+
});
|
|
1646829
|
+
}
|
|
1646830
|
+
function addDocsPreviewListCommand(cli, cliContext) {
|
|
1646831
|
+
cli.command(
|
|
1646832
|
+
"list",
|
|
1646833
|
+
"List all preview deployments",
|
|
1646834
|
+
(yargs) => yargs.option("limit", {
|
|
1646835
|
+
type: "number",
|
|
1646836
|
+
description: "Maximum number of preview deployments to display"
|
|
1646837
|
+
}).option("page", {
|
|
1646838
|
+
type: "number",
|
|
1646839
|
+
description: "Page number for pagination (starts at 1)"
|
|
1646840
|
+
}),
|
|
1646841
|
+
async (argv) => {
|
|
1646842
|
+
await cliContext.instrumentPostHogEvent({
|
|
1646843
|
+
command: "fern docs preview list"
|
|
1646844
|
+
});
|
|
1646845
|
+
await listDocsPreview({
|
|
1646846
|
+
cliContext,
|
|
1646847
|
+
limit: argv.limit,
|
|
1646848
|
+
page: argv.page
|
|
1646849
|
+
});
|
|
1646850
|
+
}
|
|
1646851
|
+
);
|
|
1646852
|
+
}
|
|
1646853
|
+
function addDocsPreviewDeleteCommand(cli, cliContext) {
|
|
1646854
|
+
cli.command(
|
|
1646855
|
+
"delete <url>",
|
|
1646856
|
+
"Delete a preview deployment",
|
|
1646857
|
+
(yargs) => yargs.positional("url", {
|
|
1646858
|
+
type: "string",
|
|
1646859
|
+
description: "The FQDN of the preview deployment to delete (e.g. acme-preview-abc123.docs.buildwithfern.com)",
|
|
1646860
|
+
demandOption: true
|
|
1646861
|
+
}),
|
|
1646862
|
+
async (argv) => {
|
|
1646863
|
+
await cliContext.instrumentPostHogEvent({
|
|
1646864
|
+
command: "fern docs preview delete"
|
|
1646865
|
+
});
|
|
1646866
|
+
await deleteDocsPreview({
|
|
1646867
|
+
cliContext,
|
|
1646868
|
+
previewUrl: argv.url
|
|
1646869
|
+
});
|
|
1646870
|
+
}
|
|
1646871
|
+
);
|
|
1646872
|
+
}
|
|
1646873
|
+
function addDocsDevCommand(cli, cliContext) {
|
|
1646374
1646874
|
cli.command(
|
|
1646375
1646875
|
"dev",
|
|
1646376
1646876
|
"Run a local development server to preview your docs",
|
package/package.json
CHANGED