Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): docs dev v2 with new OpenApi Parser #5454

Merged
merged 14 commits into from
Jan 8, 2025
2 changes: 1 addition & 1 deletion packages/cli/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@fern-api/configuration-loader": "workspace:*",
"@fern-api/core": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/docs-parsers": "^0.0.12",
"@fern-api/docs-parsers": "^0.0.14",
"@fern-api/docs-preview": "workspace:*",
"@fern-api/docs-resolver": "workspace:*",
"@fern-api/docs-validator": "workspace:*",
Expand Down
8 changes: 7 additions & 1 deletion packages/cli/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,10 @@ function addDocsPreviewCommand(cli: Argv<GlobalCliOptions>, cliContext: CliConte
string: true,
hidden: true,
description: "Path of the local docs bundle to use"
})
.option("v2", {
boolean: true,
description: "Use openapi parser v2"
RohinBhargava marked this conversation as resolved.
Show resolved Hide resolved
}),
async (argv) => {
let port: number;
Expand All @@ -1001,6 +1005,7 @@ function addDocsPreviewCommand(cli: Argv<GlobalCliOptions>, cliContext: CliConte
port = await getPort({ port: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010] });
}
const bundlePath: string | undefined = argv.bundlePath;
const v2 = argv.v2;
await previewDocsWorkspace({
loadProject: () =>
loadProjectAndRegisterWorkspacesWithContext(cliContext, {
Expand All @@ -1009,7 +1014,8 @@ function addDocsPreviewCommand(cli: Argv<GlobalCliOptions>, cliContext: CliConte
}),
cliContext,
port,
bundlePath
bundlePath,
v2
});
}
);
Expand Down
7 changes: 5 additions & 2 deletions packages/cli/cli/src/commands/docs-dev/devDocsWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ export async function previewDocsWorkspace({
loadProject,
cliContext,
port,
bundlePath
bundlePath,
v2
}: {
loadProject: () => Promise<Project>;
cliContext: CliContext;
port: number;
bundlePath?: string;
v2?: boolean;
}): Promise<void> {
const project = await loadProject();
const docsWorkspace = project.docsWorkspaces;
Expand Down Expand Up @@ -58,7 +60,8 @@ export async function previewDocsWorkspace({
},
context,
port,
bundlePath
bundlePath,
v2
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { Project } from "@fern-api/project-loader";
import { writeFile } from "fs/promises";
import path from "path";
import { CliContext } from "../../cli-context/CliContext";
import { getAllOpenAPISpecs, LazyFernWorkspace, OSSWorkspace, OpenAPILoader } from "@fern-api/lazy-fern-workspace";
// TODO: clean up imports
import { OpenApiDocumentConverterNode } from "@fern-api/docs-parsers";
import { ErrorCollector } from "@fern-api/docs-parsers";
import { BaseOpenApiV3_1ConverterNodeContext } from "@fern-api/docs-parsers";
import { OpenAPIV3_1 } from "openapi-types";
import { merge } from "lodash-es";
import { generateFdrFromOpenApiWorkspace } from "@fern-api/docs-resolver";

export async function generateOpenApiToFdrApiDefinitionForWorkspaces({
project,
Expand All @@ -23,49 +17,11 @@ export async function generateOpenApiToFdrApiDefinitionForWorkspaces({
await Promise.all(
project.apiWorkspaces.map(async (workspace) => {
await cliContext.runTaskForWorkspace(workspace, async (context) => {
await cliContext.runTaskForWorkspace(workspace, async (context) => {
if (workspace instanceof LazyFernWorkspace) {
context.logger.info("Skipping, API is specified as a Fern Definition.");
return;
} else if (!(workspace instanceof OSSWorkspace)) {
return;
}
const fdrApiDefinition = await generateFdrFromOpenApiWorkspace(workspace, context);

const openApiLoader = new OpenAPILoader(workspace.absoluteFilePath);
const openApiSpecs = await getAllOpenAPISpecs({ context, specs: workspace.specs });

const openApiDocuments = await openApiLoader.loadDocuments({ context, specs: openApiSpecs });

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let fdrApiDefinition: any;
for (const openApi of openApiDocuments) {
if (openApi.type !== "openapi") {
continue;
}

const oasContext: BaseOpenApiV3_1ConverterNodeContext = {
document: openApi.value as OpenAPIV3_1.Document,
logger: context.logger,
errors: new ErrorCollector()
};

const openApiFdrJson = new OpenApiDocumentConverterNode({
input: openApi.value as OpenAPIV3_1.Document,
context: oasContext,
accessPath: [],
pathId: workspace.workspaceName ?? "openapi parser"
});

fdrApiDefinition = merge(fdrApiDefinition, openApiFdrJson.convert());
}

const resolvedOutputFilePath = path.resolve(outputFilepath);
await writeFile(
resolvedOutputFilePath,
await stringifyLargeObject(fdrApiDefinition, { pretty: true })
);
context.logger.info(`Wrote FDR API definition to ${resolvedOutputFilePath}`);
});
const resolvedOutputFilePath = path.resolve(outputFilepath);
await writeFile(resolvedOutputFilePath, await stringifyLargeObject(fdrApiDefinition, { pretty: true }));
context.logger.info(`Wrote FDR API definition to ${resolvedOutputFilePath}`);
});
})
);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/configuration-loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@fern-api/fs-utils": "workspace:*",
"@fern-api/task-context": "workspace:*",
"@fern-api/fern-definition-schema": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"@fern-fern/fiddle-sdk": "0.0.584",
"@fern-fern/generators-sdk": "0.114.0-5745f9e74",
"find-up": "^6.3.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/configuration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@fern-api/core-utils": "workspace:*",
"@fern-api/path-utils": "workspace:*",
"@fern-api/fern-definition-schema": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"@fern-fern/fiddle-sdk": "0.0.584",
"zod": "^3.22.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/docs-importers/commons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@fern-api/configuration": "workspace:*",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/task-context": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"js-yaml": "^4.1.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/docs-importers/mintlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@fern-api/task-context": "workspace:*",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/logger": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"gray-matter": "^4.0.3"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/docs-markdown-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"dependencies": {
"@fern-api/fs-utils": "workspace:*",
"@fern-api/task-context": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"gray-matter": "^4.0.3",
"mdast-util-from-markdown": "^2.0.1",
"mdast-util-mdx": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/docs-preview/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"@fern-api/docs-resolver": "workspace:*",
"@fern-api/fdr-sdk": "0.126.1-444264056",
"@fern-api/fdr-sdk": "0.127.3-6479103bd",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/ir-sdk": "workspace:*",
"@fern-api/logger": "workspace:*",
Expand Down
29 changes: 26 additions & 3 deletions packages/cli/docs-preview/src/previewDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ import { Project } from "@fern-api/project-loader";
import { convertIrToFdrApi } from "@fern-api/register";
import { TaskContext } from "@fern-api/task-context";
import { v4 as uuidv4 } from "uuid";
import { generateFdrFromOpenApiWorkspace } from "@fern-api/docs-resolver";
import { isNonNullish } from "../../../commons/core-utils/src";

export async function getPreviewDocsDefinition({
domain,
project,
context
context,
v2
}: {
domain: string;
project: Project;
context: TaskContext;
v2?: boolean;
}): Promise<DocsV1Read.DocsDefinition> {
const docsWorkspace = project.docsWorkspaces;
const apiWorkspaces = project.apiWorkspaces;
Expand All @@ -44,6 +48,9 @@ export async function getPreviewDocsDefinition({
)
);

// TODO: remove this once we remove V1 API generation
const apiDefinitionIds: FdrAPI.ApiDefinitionId[] = [];

const apiCollector = new ReferencedAPICollector(context);

const filesV2: Record<string, DocsV1Read.File_> = {};
Expand All @@ -67,7 +74,11 @@ export async function getPreviewDocsDefinition({
fileId
};
}),
async (opts) => apiCollector.addReferencedAPI(opts)
async (opts) => {
const id = apiCollector.addReferencedAPI(opts);
apiDefinitionIds.push(FdrAPI.ApiDefinitionId(id));
return id;
}
);

const writeDocsDefinition = await resolver.resolve();
Expand All @@ -80,7 +91,19 @@ export async function getPreviewDocsDefinition({
});

return {
apis: apiCollector.getAPIsForDefinition(),
apis: v2 ? {} : apiCollector.getAPIsForDefinition(),
apisV2: v2
? Object.fromEntries(
(
await Promise.all(
project.apiWorkspaces.map(async (workspace, i) => [
apiDefinitionIds[i],
await generateFdrFromOpenApiWorkspace(workspace, context)
])
)
).filter(isNonNullish)
)
: {},
config: readDocsConfig,
files: {},
filesV2,
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/docs-preview/src/runPreviewServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getPreviewDocsDefinition } from "./previewDocs";
const EMPTY_DOCS_DEFINITION: DocsV1Read.DocsDefinition = {
pages: {},
apis: {},
apisV2: {},
files: {},
filesV2: {},
config: {
Expand Down Expand Up @@ -54,14 +55,16 @@ export async function runPreviewServer({
validateProject,
context,
port,
bundlePath
bundlePath,
v2
}: {
initialProject: Project;
reloadProject: () => Promise<Project>;
validateProject: (project: Project) => Promise<void>;
context: TaskContext;
port: number;
bundlePath?: string;
v2?: boolean;
}): Promise<void> {
if (bundlePath != null) {
context.logger.info(`Using bundle from path: ${bundlePath}`);
Expand Down Expand Up @@ -128,7 +131,8 @@ export async function runPreviewServer({
const newDocsDefinition = await getPreviewDocsDefinition({
domain: `${instance.host}${instance.pathname}`,
project,
context
context,
v2
});
context.logger.info(`Reload completed in ${Date.now() - startTime}ms`);
return newDocsDefinition;
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/docs-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@
"depcheck": "depcheck"
},
"dependencies": {
"@fern-api/api-workspace-commons": "workspace:*",
"@fern-api/cli-source-resolver": "workspace:*",
"@fern-api/configuration-loader": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/docs-markdown-utils": "workspace:*",
"@fern-api/fdr-sdk": "0.126.1-444264056",
"@fern-api/ui-core-utils": "0.126.1-444264056",
"@fern-api/docs-parsers": "^0.0.14",
"@fern-api/fdr-sdk": "0.127.3-6479103bd",
"@fern-api/lazy-fern-workspace": "workspace:*",
"@fern-api/ui-core-utils": "0.127.3-6479103bd",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/ir-generator": "workspace:*",
"@fern-api/ir-sdk": "workspace:*",
Expand All @@ -49,6 +52,7 @@
"@types/node": "18.7.18",
"depcheck": "^1.4.6",
"eslint": "^8.56.0",
"openapi-types": "^10.0.0",
"organize-imports-cli": "^0.10.0",
"prettier": "^2.7.1",
"typescript": "4.6.4",
Expand Down
1 change: 1 addition & 0 deletions packages/cli/docs-resolver/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { DocsDefinitionResolver, type UploadedFile } from "./DocsDefinitionResolver";
export { wrapWithHttps } from "./wrapWithHttps";
export { generateFdrFromOpenApiWorkspace } from "./utils/generateFdrFromOpenApiWorkspace";
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getAllOpenAPISpecs, LazyFernWorkspace, OSSWorkspace, OpenAPILoader } from "@fern-api/lazy-fern-workspace";
import {
ErrorCollector,
OpenApiDocumentConverterNode,
BaseOpenApiV3_1ConverterNodeContext
} from "@fern-api/docs-parsers";
import { OpenAPIV3_1 } from "openapi-types";
import { merge } from "lodash-es";
import { AbstractAPIWorkspace } from "@fern-api/api-workspace-commons";
import { TaskContext } from "@fern-api/task-context";

export async function generateFdrFromOpenApiWorkspace(
workspace: AbstractAPIWorkspace<unknown>,
context: TaskContext
): Promise<ReturnType<OpenApiDocumentConverterNode["convert"]>> {
if (workspace instanceof LazyFernWorkspace) {
context.logger.info("Skipping, API is specified as a Fern Definition.");
return;
} else if (!(workspace instanceof OSSWorkspace)) {
return;
}

const openApiLoader = new OpenAPILoader(workspace.absoluteFilePath);
const openApiSpecs = await getAllOpenAPISpecs({ context, specs: workspace.specs });

const openApiDocuments = await openApiLoader.loadDocuments({ context, specs: openApiSpecs });

// // eslint-disable-next-line @typescript-eslint/no-explicit-any
let fdrApiDefinition: ReturnType<OpenApiDocumentConverterNode["convert"]>;
for (const openApi of openApiDocuments) {
if (openApi.type !== "openapi") {
continue;
}

const oasContext: BaseOpenApiV3_1ConverterNodeContext = {
document: openApi.value as OpenAPIV3_1.Document,
logger: context.logger,
errors: new ErrorCollector()
};

const openApiFdrJson = new OpenApiDocumentConverterNode({
input: openApi.value as OpenAPIV3_1.Document,
context: oasContext,
accessPath: [],
pathId: workspace.workspaceName ?? "openapi parser"
});

fdrApiDefinition = merge(fdrApiDefinition, openApiFdrJson.convert());
}

return fdrApiDefinition;
}
2 changes: 1 addition & 1 deletion packages/cli/ete-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"@fern-api/configuration": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/logging-execa": "workspace:*",
"@fern-typescript/fetcher": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@fern-api/core-utils": "workspace:*",
"@fern-api/docs-resolver": "workspace:*",
"@fern-api/logging-execa": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/ir-generator": "workspace:*",
"@fern-api/ir-migrations": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/register/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@fern-api/configuration": "workspace:*",
"@fern-api/core": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-fern/fdr-cjs-sdk": "0.126.1-444264056",
"@fern-fern/fdr-cjs-sdk": "0.127.3-6479103bd",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/ir-generator": "workspace:*",
"@fern-api/ir-sdk": "workspace:*",
Expand Down
Loading
Loading