diff --git a/packages/parsers/package.json b/packages/parsers/package.json index f7a48384ff..5870a6321b 100644 --- a/packages/parsers/package.json +++ b/packages/parsers/package.json @@ -1,6 +1,6 @@ { "name": "@fern-api/docs-parsers", - "version": "0.0.27", + "version": "0.0.28", "repository": { "type": "git", "url": "https://github.com/fern-api/fern-platform.git", diff --git a/packages/parsers/src/openapi/3.1/OpenApiDocumentConverter.node.ts b/packages/parsers/src/openapi/3.1/OpenApiDocumentConverter.node.ts index 1d42c7717b..b84547a5f4 100644 --- a/packages/parsers/src/openapi/3.1/OpenApiDocumentConverter.node.ts +++ b/packages/parsers/src/openapi/3.1/OpenApiDocumentConverter.node.ts @@ -10,6 +10,7 @@ import { import { coalesceServers } from "../utils/3.1/coalesceServers"; import { SecurityRequirementObjectConverterNode } from "./auth/SecurityRequirementObjectConverter.node"; import { XFernBasePathConverterNode } from "./extensions/XFernBasePathConverter.node"; +import { XFernGlobalHeadersConverterNode } from "./extensions/XFernGlobalHeadersConverter.node"; import { XFernGroupsConverterNode } from "./extensions/XFernGroupsConverter.node"; import { PathsObjectConverterNode } from "./paths/PathsObjectConverter.node"; import { ServerObjectConverterNode } from "./paths/ServerObjectConverter.node"; @@ -29,6 +30,7 @@ export class OpenApiDocumentConverterNode extends BaseOpenApiV3_1ConverterNode< basePath: XFernBasePathConverterNode | undefined; fernGroups: XFernGroupsConverterNode | undefined; tags: TagObjectConverterNode[] | undefined; + globalHeaders: XFernGlobalHeadersConverterNode | undefined; constructor( args: BaseOpenApiV3_1ConverterNodeConstructorArgs @@ -128,6 +130,13 @@ export class OpenApiDocumentConverterNode extends BaseOpenApiV3_1ConverterNode< pathId: "components", }); } + + this.globalHeaders = new XFernGlobalHeadersConverterNode({ + input: this.input, + context: this.context, + accessPath: this.accessPath, + pathId: "x-fern-global-headers", + }); } convert(): FernRegistry.api.latest.ApiDefinition | undefined { @@ -188,8 +197,7 @@ export class OpenApiDocumentConverterNode extends BaseOpenApiV3_1ConverterNode< // This is not necessary and will be removed subpackages, auths: this.auth?.convert() ?? {}, - // TODO: Implement globalHeaders - globalHeaders: undefined, + globalHeaders: this.globalHeaders?.convert(), }; } } diff --git a/packages/parsers/src/openapi/3.1/extensions/XFernGlobalHeadersConverter.node.ts b/packages/parsers/src/openapi/3.1/extensions/XFernGlobalHeadersConverter.node.ts new file mode 100644 index 0000000000..61e3b58827 --- /dev/null +++ b/packages/parsers/src/openapi/3.1/extensions/XFernGlobalHeadersConverter.node.ts @@ -0,0 +1,65 @@ +import { isNonNullish } from "@fern-api/ui-core-utils"; +import { OpenAPIV3_1 } from "openapi-types"; +import { FernRegistry } from "../../../client/generated"; +import { + BaseOpenApiV3_1ConverterNode, + BaseOpenApiV3_1ConverterNodeConstructorArgs, +} from "../../BaseOpenApiV3_1Converter.node"; +import { extendType } from "../../utils/extendType"; +import { maybeSingleValueToArray } from "../../utils/maybeSingleValueToArray"; +import { SchemaConverterNode } from "../schemas"; +import { X_FERN_GLOBAL_HEADERS } from "./fernExtension.consts"; + +export declare namespace XFernGlobalHeadersConverterNode { + export interface Input { + [X_FERN_GLOBAL_HEADERS]?: (( + | OpenAPIV3_1.SchemaObject + | OpenAPIV3_1.ReferenceObject + ) & { + header: string; + })[]; + } +} + +export class XFernGlobalHeadersConverterNode extends BaseOpenApiV3_1ConverterNode< + unknown, + FernRegistry.api.latest.ObjectProperty[] +> { + globalHeaders?: Record | undefined; + + constructor(args: BaseOpenApiV3_1ConverterNodeConstructorArgs) { + super(args); + this.safeParse(); + } + + // This would be used to set a member on the node + parse(): void { + extendType(this.input)[ + X_FERN_GLOBAL_HEADERS + ]?.forEach((header) => { + const { header: headerName, ...schema } = header; + this.globalHeaders ??= {}; + this.globalHeaders[headerName] = new SchemaConverterNode({ + input: schema, + context: this.context, + accessPath: this.accessPath, + pathId: this.pathId, + }); + }); + } + + convert(): FernRegistry.api.latest.ObjectProperty[] | undefined { + return Object.entries(this.globalHeaders ?? {}) + .flatMap(([headerName, headerSchema]) => { + const convertedSchema = maybeSingleValueToArray(headerSchema.convert()); + + return convertedSchema?.map((schema) => ({ + key: FernRegistry.PropertyKey(headerName), + valueShape: schema, + description: headerSchema.description, + availability: headerSchema.availability?.convert(), + })); + }) + .filter(isNonNullish); + } +} diff --git a/packages/parsers/src/openapi/3.1/extensions/fernExtension.consts.ts b/packages/parsers/src/openapi/3.1/extensions/fernExtension.consts.ts index ec8d1c6c93..0338a16332 100644 --- a/packages/parsers/src/openapi/3.1/extensions/fernExtension.consts.ts +++ b/packages/parsers/src/openapi/3.1/extensions/fernExtension.consts.ts @@ -1,6 +1,7 @@ export const X_FERN_BASE_PATH = "x-fern-base-path"; export const X_FERN_AVAILABILITY = "x-fern-availability"; export const X_FERN_GROUP_NAME = "x-fern-sdk-group-name"; +export const X_FERN_GLOBAL_HEADERS = "x-fern-global-headers"; export const X_FERN_SDK_METHOD_NAME = "x-fern-sdk-method-name"; export const X_FERN_GROUPS = "x-fern-groups"; export const X_FERN_WEBHOOK = "x-fern-webhook";