Skip to content

Commit

Permalink
feat(cli): init the conjure importer (#4790)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsinghvi authored Oct 2, 2024
1 parent 20f3c3b commit e3cddc4
Show file tree
Hide file tree
Showing 199 changed files with 7,384 additions and 185 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ generated
bundle.c?js
.pnp*
packages/ir-sdk/**
packages/cli/api-importers/conjure/conjure-sdk/**
packages/docs-config/**
packages/cli/openapi-ir-sdk/**
packages/cli/configuration/src/docs-yml/schemas/**
Expand Down
5 changes: 5 additions & 0 deletions fern/pages/changelogs/cli/2024-09-30.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## 0.43.8
**`(fix):`** Any markdown files that have custom components are also pushed up to the Fern Docs
platform.


7 changes: 7 additions & 0 deletions fern/pages/changelogs/cli/2024-10-02.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## 0.44.0-rc0
**`(feat):`** The Fern CLI now supports parsing [Conjure](https://github.com/palantir/conjure), Palantir's
home-grown API Definition format.

If you know a company that is using Conjure that wants API Docs + SDKs, send them our way!


3 changes: 3 additions & 0 deletions fern/pages/changelogs/go-sdk/2024-09-29.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.27.0
**`(feat):`** Add support for SSE (Server-Sent Events) streaming responses. The user-facing interface for streaming responses remains the same between standard HTTP streaming and SSE.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"seed:local": "pnpm --filter @fern-api/seed-cli dist:cli && node packages/seed/dist/bundle.cjs",
"ir:generate": "pnpm --filter @fern-api/ir-sdk generate",
"openapi-ir:generate": "pnpm --filter @fern-api/openapi-ir-sdk generate",
"conjure-sdk:generate": "pnpm --filter @fern-api/conjure-sdk generate",
"seed-config:generate": "pnpm --filter @fern-api/seed-cli generate",
"docs-config:generate": "pnpm --filter @fern-api/configuration generate",
"prepare": "husky"
Expand Down
10 changes: 10 additions & 0 deletions packages/cli/api-importers/commons/.depcheckrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"ignores": [
"@types/jest",
"globals",
"@types/node"
],
"ignore-patterns": [
"lib"
]
}
1 change: 1 addition & 0 deletions packages/cli/api-importers/commons/.prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("../../../../.prettierrc.json");
47 changes: 47 additions & 0 deletions packages/cli/api-importers/commons/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@fern-api/importer-commons",
"version": "0.0.0",
"repository": {
"type": "git",
"url": "https://github.com/fern-api/fern.git",
"directory": "packages/cli/generation/remote-generation/remote-workspace-runner"
},
"private": true,
"files": [
"lib"
],
"type": "module",
"source": "src/index.ts",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"sideEffects": false,
"scripts": {
"clean": "rm -rf ./lib && tsc --build --clean",
"compile": "tsc --build",
"test": "vitest --passWithNoTests --run",
"test:update": "vitest --passWithNoTests --run -u",
"lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../../../.eslintignore",
"lint:eslint:fix": "yarn lint:eslint --fix",
"format": "prettier --write --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"",
"format:check": "prettier --check --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"",
"organize-imports": "organize-imports-cli tsconfig.json",
"depcheck": "depcheck"
},
"dependencies": {
"@fern-api/fern-definition-schema": "workspace:*",
"@fern-api/configuration": "workspace:*",
"@fern-api/task-context": "workspace:*",
"@fern-api/fs-utils": "workspace:*",
"lodash-es": "^4.17.21"
},
"devDependencies": {
"@types/node": "^18.7.18",
"depcheck": "^1.4.6",
"globals": "link:@types/vitest/globals",
"organize-imports-cli": "^0.10.0",
"prettier": "^2.7.1",
"typescript": "4.6.4",
"vitest": "^2.0.5",
"@types/lodash-es": "^4.17.12"
}
}
17 changes: 17 additions & 0 deletions packages/cli/api-importers/commons/src/APIDefinitionImporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DefinitionFileSchema, PackageMarkerFileSchema, RootApiFileSchema } from "@fern-api/fern-definition-schema";
import { RelativeFilePath } from "@fern-api/fs-utils";
import { TaskContext } from "@fern-api/task-context";

export declare namespace APIDefinitionImporter {
interface Return {
rootApiFile: RootApiFileSchema;
packageMarkerFile: PackageMarkerFileSchema;
definitionFiles: Record<RelativeFilePath, DefinitionFileSchema>;
}
}

export abstract class APIDefinitionImporter<T> {
public constructor(protected readonly context?: TaskContext) {}

public abstract import(input: T): Promise<APIDefinitionImporter.Return>;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FERN_PACKAGE_MARKER_FILENAME, ROOT_API_FILENAME } from "@fern-api/configuration";
import { AbsoluteFilePath, dirname, relative, RelativeFilePath } from "@fern-api/fs-utils";
import { OpenApiIntermediateRepresentation, Source } from "@fern-api/openapi-ir-sdk";
import { RawSchemas, RootApiFileSchema, visitRawEnvironmentDeclaration } from "@fern-api/fern-definition-schema";
import { camelCase, isEqual } from "lodash-es";
import path, { basename, extname } from "path";
import { convertToSourceSchema } from "./utils/convertToSourceSchema";
import { FernDefinitionDirectory } from "./FernDefinitionDirectory";
import { FernDefinitionDirectory } from "./utils/FernDefinitionDirectory";

export interface FernDefinitionBuilder {
setDisplayName({ displayName }: { displayName: string }): void;

addNavigation({ navigation }: { navigation: string[] }): void;

addAuthScheme({ name, schema }: { name: string; schema: RawSchemas.AuthSchemeDeclarationSchema }): void;
Expand Down Expand Up @@ -40,8 +40,17 @@ export interface FernDefinitionBuilder {
* Adds an import and returns the prefix for the import. Returns undefined if no prefix.
* @param file the file to add the import to
* @param fileToImport the file to import
* @param alias import the file with this alias
*/
addImport({ file, fileToImport }: { file: RelativeFilePath; fileToImport: RelativeFilePath }): string | undefined;
addImport({
file,
fileToImport,
alias
}: {
file: RelativeFilePath;
fileToImport: RelativeFilePath;
alias?: string;
}): string | undefined;

addType(file: RelativeFilePath, { name, schema }: { name: string; schema: RawSchemas.TypeDeclarationSchema }): void;

Expand All @@ -57,7 +66,11 @@ export interface FernDefinitionBuilder {

addEndpoint(
file: RelativeFilePath,
{ name, schema, source }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: Source | undefined }
{
name,
schema,
source
}: { name: string; schema: RawSchemas.HttpEndpointSchema; source: RawSchemas.SourceSchema | undefined }
): void;

addWebhook(file: RelativeFilePath, { name, schema }: { name: string; schema: RawSchemas.WebhookSchema }): void;
Expand Down Expand Up @@ -92,28 +105,25 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder {
private packageMarkerFile: RawSchemas.PackageMarkerFileSchema = {};
private basePath: string | undefined = undefined;

public constructor(
ir: OpenApiIntermediateRepresentation,
private readonly modifyBasePaths: boolean,
public readonly enableUniqueErrorsPerEndpoint: boolean
) {
public constructor(public readonly enableUniqueErrorsPerEndpoint: boolean) {
this.root = new FernDefinitionDirectory();
this.rootApiFile = {
name: "api",
"error-discrimination": {
strategy: "status-code"
}
};
if (ir.title != null) {
this.rootApiFile["display-name"] = ir.title;
}
}

public setDisplayName({ displayName }: { displayName: string }): void {
this.rootApiFile["display-name"] = displayName;
}

public addNavigation({ navigation }: { navigation: string[] }): void {
this.packageMarkerFile.navigation = navigation;
}

setServiceInfo(
public setServiceInfo(
file: RelativeFilePath,
{ displayName, docs }: { displayName?: string | undefined; docs?: string | undefined }
): void {
Expand Down Expand Up @@ -223,20 +233,24 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder {

public addImport({
file,
fileToImport
fileToImport,
alias
}: {
file: RelativeFilePath;
fileToImport: RelativeFilePath;
alias?: string;
}): string | undefined {
if (file === fileToImport) {
return undefined;
}
const importPrefix = camelCase(
(dirname(fileToImport) + "/" + basename(fileToImport, extname(fileToImport))).replaceAll(
"__package__",
"root"
)
);
const importPrefix =
alias ??
camelCase(
(dirname(fileToImport) + "/" + basename(fileToImport, extname(fileToImport))).replaceAll(
"__package__",
"root"
)
);

if (file === RelativeFilePath.of(ROOT_API_FILENAME)) {
if (this.rootApiFile.imports == null) {
Expand Down Expand Up @@ -336,7 +350,11 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder {

public addEndpoint(
file: RelativeFilePath,
{ name, schema, source }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: Source | undefined }
{
name,
schema,
source
}: { name: string; schema: RawSchemas.HttpEndpointSchema; source: RawSchemas.SourceSchema | undefined }
): void {
const fernFile = this.getOrCreateFile(file);
if (fernFile.service == null) {
Expand All @@ -347,7 +365,7 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder {
};
}
if (source != null) {
fernFile.service.source = convertToSourceSchema(source);
fernFile.service.source = source;
}
fernFile.service.endpoints[name] = schema;
}
Expand Down Expand Up @@ -412,78 +430,6 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder {

public build(): FernDefinition {
const definitionFiles = this.root.getAllFiles();
if (this.modifyBasePaths) {
const basePath = getSharedEnvironmentBasePath(this.rootApiFile);

// substitute package marker file
if (this.packageMarkerFile.service != null) {
this.packageMarkerFile.service = {
...this.packageMarkerFile.service,
endpoints: Object.fromEntries(
Object.entries(this.packageMarkerFile.service.endpoints).map(([id, endpoint]) => {
return [
id,
{
...endpoint,
path: `${basePath}${endpoint.path}`
}
];
})
)
};
}

// subsitute definition files
for (const file of Object.values(definitionFiles)) {
if (file.service != null) {
file.service = {
...file.service,
endpoints: Object.fromEntries(
Object.entries(file.service.endpoints).map(([id, endpoint]) => {
return [
id,
{
...endpoint,
path: `${basePath}${endpoint.path}`
}
];
})
)
};
}
}

if (this.rootApiFile.environments != null) {
this.rootApiFile.environments = {
...Object.fromEntries(
Object.entries(this.rootApiFile.environments).map(([env, url]) => {
if (typeof url === "string") {
return [env, url.substring(0, url.length - basePath.length)];
} else if (isSingleBaseUrl(url)) {
return [
env,
{
url: url.url.substring(0, url.url.length - basePath.length)
}
];
} else {
return [
env,
{
urls: Object.fromEntries(
Object.entries(url.urls).map(([name, url]) => {
return [name, url.substring(0, url.length - basePath.length)];
})
)
}
];
}
})
)
};
}
}

const basePath = this.basePath;
if (basePath != null) {
// substitute package marker file
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RawSchemas } from "@fern-api/fern-definition-schema";
import { RelativeFilePath } from "@fern-api/fs-utils";
import { FernDefinitionDirectory } from "../FernDefinitionDirectory";
import { FernDefinitionDirectory } from "../utils/FernDefinitionDirectory";

interface TestCase {
description: string;
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/api-importers/commons/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { APIDefinitionImporter } from "./APIDefinitionImporter";
export { type FernDefinitionBuilder, FernDefinitionBuilderImpl, type FernDefinition } from "./FernDefnitionBuilder";
11 changes: 11 additions & 0 deletions packages/cli/api-importers/commons/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../../../shared/tsconfig.shared.json",
"compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" },
"include": ["./src/**/*"],
"references": [
{ "path": "../../../cli/fern-definition/schema" },
{ "path": "../../../commons/core-utils" },
{ "path": "../../task-context" },
{ "path": "../../../commons/fs-utils" },
]
}
1 change: 1 addition & 0 deletions packages/cli/api-importers/commons/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "../../../../shared/vitest.config";
10 changes: 10 additions & 0 deletions packages/cli/api-importers/conjure/conjure-sdk/.depcheckrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"ignores": [
"@types/jest",
"globals",
"@types/node"
],
"ignore-patterns": [
"lib"
]
}
1 change: 1 addition & 0 deletions packages/cli/api-importers/conjure/conjure-sdk/.fernignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("../../../../../.prettierrc.json");
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: conjure
docs: |
This API Definition captures the Conjure API Schema.
This schema is built for Fern's Conjure importer, which
error-discrimination:
strategy: status-code
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
types:
WithDocs:
properties:
docs: optional<string>
Loading

0 comments on commit e3cddc4

Please sign in to comment.