Skip to content

Commit d6cce44

Browse files
authored
feat(cli): Add additional-properties-defaults-to setting for OpenAPI specs in generators.yml. (#6621)
* Add setting for OpenAPI specs in generators.yml. * chore: update changelog
1 parent 639b889 commit d6cce44

File tree

22 files changed

+2448
-16
lines changed

22 files changed

+2448
-16
lines changed

fern/apis/generators-yml/definition/generators.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ types:
277277
example-generation:
278278
type: optional<OpenAPIExampleGenerationSchema>
279279
docs: Fine-tune your example generation
280+
additional-properties-defaults-to:
281+
type: optional<boolean>
282+
docs: Configure what `additionalProperties` should default to when not explicitly defined on a schema. Defaults to `false`.
283+
default: false
280284

281285
FormParameterEncoding:
282286
enum:
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## 0.57.12
2+
**`(feat):`** Add `additional-properties-defaults-to` setting for OpenAPI specs in generators.yml.
3+
This setting lets you change the default value for the `additionalProperties` field in the generated IR.
4+
5+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 1.15.13
2+
**`(chore):`** Mark `AdditionalProperties` property as experiment using XML docs.
3+
4+

generators-yml.schema.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,16 @@
15121512
"type": "null"
15131513
}
15141514
]
1515+
},
1516+
"additional-properties-defaults-to": {
1517+
"oneOf": [
1518+
{
1519+
"type": "boolean"
1520+
},
1521+
{
1522+
"type": "null"
1523+
}
1524+
]
15151525
}
15161526
},
15171527
"additionalProperties": false

packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/endpoint/convertRequest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ export function convertRequest({
260260
fullExamples: jsonMediaObject.examples,
261261
additionalProperties:
262262
!isReferenceObject(jsonMediaObject.schema) &&
263-
isAdditionalPropertiesAny(jsonMediaObject.schema.additionalProperties),
263+
isAdditionalPropertiesAny(jsonMediaObject.schema.additionalProperties, context.options),
264264
source
265265
});
266266
}

packages/cli/api-importers/openapi/openapi-ir-parser/src/options.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ export interface ParseOpenAPIOptions {
4747
asyncApiNaming: "v1" | "v2";
4848

4949
exampleGeneration: generatorsYml.OpenApiExampleGenerationSchema | undefined;
50+
51+
/**
52+
* Configure what `additionalProperties` should default to when not explicitly defined on a schema. Defaults to `false`.
53+
*/
54+
additionalPropertiesDefaultsTo: boolean;
5055
}
5156

5257
export const DEFAULT_PARSE_OPENAPI_SETTINGS: ParseOpenAPIOptions = {
@@ -69,7 +74,8 @@ export const DEFAULT_PARSE_OPENAPI_SETTINGS: ParseOpenAPIOptions = {
6974
exampleGeneration: undefined,
7075
defaultFormParameterEncoding: "json",
7176
useBytesForBinaryResponse: false,
72-
respectForwardCompatibleEnums: false
77+
respectForwardCompatibleEnums: false,
78+
additionalPropertiesDefaultsTo: false
7379
};
7480

7581
export function getParseOptions({
@@ -138,6 +144,10 @@ export function getParseOptions({
138144
respectForwardCompatibleEnums:
139145
overrides?.respectForwardCompatibleEnums ??
140146
options?.respectForwardCompatibleEnums ??
141-
DEFAULT_PARSE_OPENAPI_SETTINGS.respectForwardCompatibleEnums
147+
DEFAULT_PARSE_OPENAPI_SETTINGS.respectForwardCompatibleEnums,
148+
additionalPropertiesDefaultsTo:
149+
overrides?.additionalPropertiesDefaultsTo ??
150+
options?.additionalPropertiesDefaultsTo ??
151+
DEFAULT_PARSE_OPENAPI_SETTINGS.additionalPropertiesDefaultsTo
142152
};
143153
}

packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertAdditionalProperties.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Source
1212
} from "@fern-api/openapi-ir";
1313

14+
import { ParseOpenAPIOptions } from "../options";
1415
import { SchemaParserContext } from "./SchemaParserContext";
1516
import { convertSchema } from "./convertSchemas";
1617
import { isReferenceObject } from "./utils/isReferenceObject";
@@ -35,7 +36,7 @@ export function convertAdditionalProperties({
3536
generatedName: string;
3637
title: string | undefined;
3738
breadcrumbs: string[];
38-
additionalProperties: boolean | OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject;
39+
additionalProperties: undefined | boolean | OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject;
3940
description: string | undefined;
4041
availability: Availability | undefined;
4142
wrapAsNullable: boolean;
@@ -46,7 +47,11 @@ export function convertAdditionalProperties({
4647
source: Source;
4748
namespace: string | undefined;
4849
}): SchemaWithExample {
49-
if (typeof additionalProperties === "boolean" || isAdditionalPropertiesAny(additionalProperties)) {
50+
if (additionalProperties === undefined) {
51+
additionalProperties = context.options.additionalPropertiesDefaultsTo;
52+
}
53+
54+
if (typeof additionalProperties === "boolean" || isAdditionalPropertiesAny(additionalProperties, context.options)) {
5055
return wrapMap({
5156
nameOverride,
5257
generatedName,
@@ -222,10 +227,11 @@ export function wrapMap({
222227
}
223228

224229
export function isAdditionalPropertiesAny(
225-
additionalProperties: boolean | OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | undefined
230+
additionalProperties: boolean | OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | undefined,
231+
options: ParseOpenAPIOptions
226232
): boolean {
227233
if (additionalProperties == null) {
228-
return false;
234+
return options.additionalPropertiesDefaultsTo;
229235
}
230236
if (typeof additionalProperties === "boolean") {
231237
return additionalProperties;

packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertObject.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ export function convertObject({
260260
fullExamples,
261261
additionalProperties,
262262
availability,
263-
source
263+
source,
264+
context
264265
});
265266
}
266267

@@ -277,7 +278,8 @@ export function wrapObject({
277278
fullExamples,
278279
additionalProperties,
279280
availability,
280-
source
281+
source,
282+
context
281283
}: {
282284
nameOverride: string | undefined;
283285
generatedName: string;
@@ -292,6 +294,7 @@ export function wrapObject({
292294
additionalProperties: boolean | OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | undefined;
293295
availability: Availability | undefined;
294296
source: Source;
297+
context: SchemaParserContext;
295298
}): SchemaWithExample {
296299
if (wrapAsNullable) {
297300
return SchemaWithExample.nullable({
@@ -308,7 +311,7 @@ export function wrapObject({
308311
allOfPropertyConflicts,
309312
groupName,
310313
fullExamples,
311-
additionalProperties: isAdditionalPropertiesAny(additionalProperties),
314+
additionalProperties: isAdditionalPropertiesAny(additionalProperties, context.options),
312315
availability: undefined,
313316
source,
314317
inline: undefined
@@ -329,7 +332,7 @@ export function wrapObject({
329332
allOfPropertyConflicts,
330333
groupName,
331334
fullExamples,
332-
additionalProperties: isAdditionalPropertiesAny(additionalProperties),
335+
additionalProperties: isAdditionalPropertiesAny(additionalProperties, context.options),
333336
availability,
334337
source,
335338
inline: undefined

0 commit comments

Comments
 (0)