Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions fern/apis/generators-yml/definition/generators.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,24 @@ types:
- v1
- v2

OverridesSchema:
discriminated: false
docs: |
Path(s) to override file(s). Can be a single path or an array of paths.
When multiple paths are provided, overrides are applied sequentially in order.
union:
- string
- list<string>

APIDefinitionWithOverridesSchema:
properties:
path: APIDefinitionPathSchema
origin:
type: optional<string>
docs: The URL of the API definition origin, from which the file should be polled.
overrides:
type: optional<string>
docs: Path to the OpenAPI or AsyncAPI overrides
type: optional<OverridesSchema>
docs: Path(s) to the OpenAPI or AsyncAPI overrides. Can be a single path or an array of paths applied sequentially.
audiences:
type: optional<list<string>>
docs: Audiences that you would like to filter to
Expand All @@ -276,8 +285,8 @@ types:
type: string
docs: The path to the `.proto` directory root (e.g. `proto`).
overrides:
type: optional<string>
docs: Path to the overrides configuration
type: optional<OverridesSchema>
docs: Path(s) to the overrides configuration. Can be a single path or an array of paths applied sequentially.
local-generation:
type: optional<boolean>
docs: Whether to compile the `.proto` files locally. By default, we generate remotely.
Expand Down Expand Up @@ -510,14 +519,14 @@ types:
properties:
openapi: string
origin: optional<string>
overrides: optional<string>
overrides: optional<OverridesSchema>
namespace: optional<string>
settings: optional<OpenAPISettingsSchema>

OpenRPCSpecSchema:
properties:
openrpc: string
overrides: optional<string>
overrides: optional<OverridesSchema>
namespace: optional<string>

AsyncAPISettingsSchema:
Expand All @@ -532,7 +541,7 @@ types:
properties:
asyncapi: string
origin: optional<string>
overrides: optional<string>
overrides: optional<OverridesSchema>
namespace: optional<string>
settings: optional<AsyncAPISettingsSchema>

Expand Down
6 changes: 6 additions & 0 deletions fern/apis/generators-yml/definition/group.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ types:
api:
type: optional<GeneratorAPISettingsSchema>
docs: Override API import settings (this is applied across all specs)
overrides:
type: optional<generators.OverridesSchema>
docs: |
Additional override file(s) to apply for this generator.
These overrides are applied after the top-level spec overrides.
Can be a single path or an array of paths applied sequentially.
disable-examples:
type: optional<boolean>
docs: Temporary way to unblock example serialization.
Expand Down
33 changes: 28 additions & 5 deletions generators-yml.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,19 @@
"generators.APIDefinitionPathSchema": {
"type": "string"
},
"generators.OverridesSchema": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"generators.UnionSettingsSchema": {
"type": "string",
"enum": [
Expand Down Expand Up @@ -916,7 +929,7 @@
"overrides": {
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
Expand Down Expand Up @@ -971,7 +984,7 @@
"overrides": {
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
Expand Down Expand Up @@ -1961,7 +1974,7 @@
"overrides": {
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
Expand Down Expand Up @@ -2129,7 +2142,7 @@
"overrides": {
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
Expand Down Expand Up @@ -2183,7 +2196,7 @@
"overrides": {
"oneOf": [
{
"type": "string"
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
Expand Down Expand Up @@ -3791,6 +3804,16 @@
}
]
},
"overrides": {
"oneOf": [
{
"$ref": "#/definitions/generators.OverridesSchema"
},
{
"type": "null"
}
]
},
"disable-examples": {
"oneOf": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ async function writeDefinitionForOpenAPIWorkspace({
// biome-ignore lint/suspicious/noExplicitAny: allow explicit any
let existingOverrides: any = {};
if (spec.absoluteFilepathToOverrides !== undefined) {
existingOverrides = await readExistingOverrides(spec.absoluteFilepathToOverrides, context);
// Use the first override file if an array is provided
const overridesPath = Array.isArray(spec.absoluteFilepathToOverrides)
? spec.absoluteFilepathToOverrides[0]
: spec.absoluteFilepathToOverrides;
if (overridesPath !== undefined) {
existingOverrides = await readExistingOverrides(overridesPath, context);
}
}

const paths: Record<string, Record<string, unknown>> = "path" in existingOverrides
Expand Down
10 changes: 10 additions & 0 deletions packages/cli/cli/versions.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# yaml-language-server: $schema=../../../fern-versions-yml.schema.json
- version: 3.38.0
changelogEntry:
- summary: |
Add support for multiple override files in OpenAPI spec configuration. The `overrides` field now accepts either a single path or an array of paths. When multiple paths are provided, overrides are applied sequentially in order, allowing for layered customization of OpenAPI specs.
type: feat
- summary: |
Add support for generator-level overrides. Each generator invocation can now specify its own `overrides` field, which applies additional override files after the top-level spec overrides. This allows for generator-specific customizations without affecting other generators.
type: feat
createdAt: "2026-01-09"
irVersion: 62

- version: 3.37.3
changelogEntry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ async function convertGenerator({
publishMetadata: getPublishMetadata({ generatorInvocation: generator }),
readme,
settings: generator.api?.settings ?? undefined,
overrides: generator.overrides,
apiOverride:
generator.api?.specs != null || generator.api?.auth != null || generator.api?.["auth-schemes"] != null
? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export interface APIDefinitionSettings {
export interface APIDefinitionLocation {
schema: APIDefinitionSchema;
origin: string | undefined;
overrides: string | undefined;
overrides: string | string[] | undefined;
audiences: string[] | undefined;
settings: APIDefinitionSettings | undefined;
}
Expand Down Expand Up @@ -158,6 +158,11 @@ export interface GeneratorInvocation {
publishMetadata: FernFiddle.remoteGen.PublishingMetadata | undefined;
readme: ReadmeSchema | undefined;
settings: ApiDefinitionSettingsSchema | undefined;
/**
* Additional override file(s) to apply for this generator.
* These overrides are applied after the top-level spec overrides.
*/
overrides: string | string[] | undefined;
/**
* Override the API configuration for this generator.
* When provided, these values take precedence over the top-level api configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export interface ApiDefinitionWithOverridesSchema {
path: GeneratorsYml.ApiDefinitionPathSchema;
/** The URL of the API definition origin, from which the file should be polled. */
origin?: string;
/** Path to the OpenAPI or AsyncAPI overrides */
overrides?: string;
/** Path(s) to the OpenAPI or AsyncAPI overrides. Can be a single path or an array of paths applied sequentially. */
overrides?: GeneratorsYml.OverridesSchema;
/** Audiences that you would like to filter to */
audiences?: string[];
settings?: GeneratorsYml.ApiDefinitionSettingsSchema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as GeneratorsYml from "../../../index";
export interface AsyncApiSpecSchema {
asyncapi: string;
origin?: string;
overrides?: string;
overrides?: GeneratorsYml.OverridesSchema;
namespace?: string;
settings?: GeneratorsYml.AsyncApiSettingsSchema;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as GeneratorsYml from "../../../index";
export interface OpenApiSpecSchema {
openapi: string;
origin?: string;
overrides?: string;
overrides?: GeneratorsYml.OverridesSchema;
namespace?: string;
settings?: GeneratorsYml.OpenApiSettingsSchema;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
* This file was auto-generated by Fern from our API Definition.
*/

import * as GeneratorsYml from "../../../index";

export interface OpenRpcSpecSchema {
openrpc: string;
overrides?: string;
overrides?: GeneratorsYml.OverridesSchema;
namespace?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

/**
* Path(s) to override file(s). Can be a single path or an array of paths.
* When multiple paths are provided, overrides are applied sequentially in order.
*/
export type OverridesSchema = string | string[];
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
* This file was auto-generated by Fern from our API Definition.
*/

import * as GeneratorsYml from "../../../index";

export interface ProtobufDefinitionSchema {
/** The path to the target `.proto` file that defines the API (e.g. `proto/user/v1/user.proto`). */
target?: string;
/** The path to the `.proto` directory root (e.g. `proto`). */
root: string;
/** Path to the overrides configuration */
overrides?: string;
/** Path(s) to the overrides configuration. Can be a single path or an array of paths applied sequentially. */
overrides?: GeneratorsYml.OverridesSchema;
/** Whether to compile the `.proto` files locally. By default, we generate remotely. */
"local-generation"?: boolean;
/** Whether to convert to OpenAPI before generating */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from "./RemoveDiscriminantsFromSchemas";
export * from "./PathParameterOrder";
export * from "./UnionSettingsSchema";
export * from "./MessageNamingSettingsSchema";
export * from "./OverridesSchema";
export * from "./ApiDefinitionWithOverridesSchema";
export * from "./ProtobufDefinitionSchema";
export * from "./ProtobufApiDefinitionSchema";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export interface GeneratorInvocationSchema {
"smart-casing"?: boolean;
/** Override API import settings (this is applied across all specs) */
api?: GeneratorsYml.GeneratorApiSettingsSchema;
/**
* Additional override file(s) to apply for this generator.
* These overrides are applied after the top-level spec overrides.
* Can be a single path or an array of paths applied sequentially.
*/
overrides?: GeneratorsYml.OverridesSchema;
/** Temporary way to unblock example serialization. */
"disable-examples"?: boolean;
/** Deprecated, use `metadata` on the output block instead. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as serializers from "../../../index";
import * as GeneratorsYml from "../../../../api/index";
import * as core from "../../../../core";
import { ApiDefinitionPathSchema } from "./ApiDefinitionPathSchema";
import { OverridesSchema } from "./OverridesSchema";
import { ApiDefinitionSettingsSchema } from "./ApiDefinitionSettingsSchema";

export const ApiDefinitionWithOverridesSchema: core.serialization.ObjectSchema<
Expand All @@ -14,7 +15,7 @@ export const ApiDefinitionWithOverridesSchema: core.serialization.ObjectSchema<
> = core.serialization.object({
path: ApiDefinitionPathSchema,
origin: core.serialization.string().optional(),
overrides: core.serialization.string().optional(),
overrides: OverridesSchema.optional(),
audiences: core.serialization.list(core.serialization.string()).optional(),
settings: ApiDefinitionSettingsSchema.optional(),
});
Expand All @@ -23,7 +24,7 @@ export declare namespace ApiDefinitionWithOverridesSchema {
export interface Raw {
path: ApiDefinitionPathSchema.Raw;
origin?: string | null;
overrides?: string | null;
overrides?: OverridesSchema.Raw | null;
audiences?: string[] | null;
settings?: ApiDefinitionSettingsSchema.Raw | null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import * as serializers from "../../../index";
import * as GeneratorsYml from "../../../../api/index";
import * as core from "../../../../core";
import { OverridesSchema } from "./OverridesSchema";
import { AsyncApiSettingsSchema } from "./AsyncApiSettingsSchema";

export const AsyncApiSpecSchema: core.serialization.ObjectSchema<
Expand All @@ -13,7 +14,7 @@ export const AsyncApiSpecSchema: core.serialization.ObjectSchema<
> = core.serialization.object({
asyncapi: core.serialization.string(),
origin: core.serialization.string().optional(),
overrides: core.serialization.string().optional(),
overrides: OverridesSchema.optional(),
namespace: core.serialization.string().optional(),
settings: AsyncApiSettingsSchema.optional(),
});
Expand All @@ -22,7 +23,7 @@ export declare namespace AsyncApiSpecSchema {
export interface Raw {
asyncapi: string;
origin?: string | null;
overrides?: string | null;
overrides?: OverridesSchema.Raw | null;
namespace?: string | null;
settings?: AsyncApiSettingsSchema.Raw | null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import * as serializers from "../../../index";
import * as GeneratorsYml from "../../../../api/index";
import * as core from "../../../../core";
import { OverridesSchema } from "./OverridesSchema";
import { OpenApiSettingsSchema } from "./OpenApiSettingsSchema";

export const OpenApiSpecSchema: core.serialization.ObjectSchema<
Expand All @@ -13,7 +14,7 @@ export const OpenApiSpecSchema: core.serialization.ObjectSchema<
> = core.serialization.object({
openapi: core.serialization.string(),
origin: core.serialization.string().optional(),
overrides: core.serialization.string().optional(),
overrides: OverridesSchema.optional(),
namespace: core.serialization.string().optional(),
settings: OpenApiSettingsSchema.optional(),
});
Expand All @@ -22,7 +23,7 @@ export declare namespace OpenApiSpecSchema {
export interface Raw {
openapi: string;
origin?: string | null;
overrides?: string | null;
overrides?: OverridesSchema.Raw | null;
namespace?: string | null;
settings?: OpenApiSettingsSchema.Raw | null;
}
Expand Down
Loading
Loading