Skip to content

Commit

Permalink
added new openapi-fdr command
Browse files Browse the repository at this point in the history
  • Loading branch information
fern-bot committed Nov 27, 2024
1 parent 6c29f1f commit 15cef7a
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 5 deletions.
4 changes: 3 additions & 1 deletion packages/cli/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@
"publish:cli:prod": "cd dist/prod && npm publish"
},
"devDependencies": {
"@fern-api/docs-resolver": "workspace:*",
"@fern-api/api-workspace-commons": "workspace:*",
"@fern-api/auth": "workspace:*",
"@fern-api/cli-logger": "workspace:*",
"@fern-api/cli-migrations": "workspace:*",
"@fern-api/configuration": "workspace:*",
"@fern-api/core": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/docs-parsers": "^0.0.2",
"@fern-api/docs-preview": "workspace:*",
"@fern-api/docs-resolver": "workspace:*",
"@fern-api/docs-validator": "workspace:*",
"@fern-api/fern-definition-formatter": "workspace:*",
"@fern-api/fern-definition-schema": "workspace:*",
Expand Down Expand Up @@ -102,6 +103,7 @@
"js-yaml": "^4.1.0",
"latest-version": "^9.0.0",
"lodash-es": "^4.17.21",
"openapi-types": "^12.1.3",
"ora": "^7.0.1",
"organize-imports-cli": "^0.10.0",
"prettier": "^2.7.1",
Expand Down
30 changes: 30 additions & 0 deletions packages/cli/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { generateJsonschemaForWorkspaces } from "./commands/jsonschema/generateJ
import { generateDynamicIrForWorkspaces } from "./commands/generate-dynamic-ir/generateDynamicIrForWorkspaces";
import { writeDocsDefinitionForProject } from "./commands/write-docs-definition/writeDocsDefinitionForProject";
import { RUNTIME } from "@fern-typescript/fetcher";
import { generateOpenApiToFdrApiDefinitionForWorkspaces } from "./commands/generate-openapi-fdr/generateOpenApiToFdrApiDefinitionForWorkspaces";

void runCli();

Expand Down Expand Up @@ -152,6 +153,7 @@ async function tryRunCli(cliContext: CliContext) {
addGenerateCommand(cli, cliContext);
addIrCommand(cli, cliContext);
addFdrCommand(cli, cliContext);
addOpenAPIFdrCommand(cli, cliContext);
addOpenAPIIrCommand(cli, cliContext);
addDynamicIrCommand(cli, cliContext);
addValidateCommand(cli, cliContext);
Expand Down Expand Up @@ -618,6 +620,34 @@ function addFdrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext) {
);
}

function addOpenAPIFdrCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext) {
cli.command(
"openapi-fdr <path-to-output>",
false,
(yargs) =>
yargs
.positional("path-to-output", {
type: "string",
description: "Path to write fern definition registry shape (FDR)",
demandOption: true
})
.option("api", {
string: true,
description: "Only run the command on the provided API"
}),
async (argv) => {
await generateOpenApiToFdrApiDefinitionForWorkspaces({
project: await loadProjectAndRegisterWorkspacesWithContext(cliContext, {
commandLineApiWorkspace: argv.api,
defaultToAllApiWorkspaces: false
}),
outputFilepath: resolve(cwd(), argv.pathToOutput),
cliContext
});
}
);
}

function addRegisterCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext) {
cli.command(
["register"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { AbsoluteFilePath, stringifyLargeObject } from "@fern-api/fs-utils";
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 } from "@fern-api/lazy-fern-workspace";
import { OpenApiDocumentConverterNode } from "@fern-api/docs-parsers/dist/openapi/3.1/OpenApiDocumentConverter.node";
import { ErrorCollector } from "@fern-api/docs-parsers/dist/ErrorCollector";
import fs from "fs";
import yaml from "js-yaml";
import { BaseOpenApiV3_1ConverterNodeContext } from "@fern-api/docs-parsers/dist/openapi/BaseOpenApiV3_1Converter.node";
import { OpenAPIV3_1 } from "openapi-types";

export async function generateOpenApiToFdrApiDefinitionForWorkspaces({
project,
outputFilepath,
cliContext
}: {
project: Project;
outputFilepath: AbsoluteFilePath;
cliContext: CliContext;
}): Promise<void> {
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 openAPISpecs = await getAllOpenAPISpecs({ context, specs: workspace.specs });

const openApi = openAPISpecs[0];

if (openApi != null) {
const input = yaml.load(
fs.readFileSync(openApi.absoluteFilepath, "utf8")
) as OpenAPIV3_1.Document;

const oasContext: BaseOpenApiV3_1ConverterNodeContext = {
document: input,
logger: context.logger,
errors: new ErrorCollector()
};

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

const fdrApiDefinition = await openApiFdrJson.convert();

const resolvedOutputFilePath = path.resolve(outputFilepath);
await writeFile(
resolvedOutputFilePath,
await stringifyLargeObject(fdrApiDefinition, { pretty: true })
);
context.logger.info(`Wrote FDR API definition to ${resolvedOutputFilePath}`);
} else {
context.logger.error("No OpenAPI spec found in the workspace");
}
});
});
})
);
}
100 changes: 96 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 15cef7a

Please sign in to comment.