diff --git a/fern/pages/changelogs/cli/2025-01-14.mdx b/fern/pages/changelogs/cli/2025-01-14.mdx new file mode 100644 index 00000000000..9f401bd81d9 --- /dev/null +++ b/fern/pages/changelogs/cli/2025-01-14.mdx @@ -0,0 +1,12 @@ +## 0.48.0 +**`(feat):`** Adds support for nullable types in the Fern definition, such as the following: + +```yaml +types: + User: + properties: + name: string + email: nullable +``` + + diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts index 6e6dadaaab3..9bf93d43dea 100644 --- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts +++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts @@ -280,6 +280,19 @@ export function getSchemaFromFernType({ inline: undefined }) : undefined, + nullable: (itemType) => + itemType != null + ? SchemaWithExample.nullable({ + nameOverride, + generatedName, + title, + value: itemType, + description, + availability, + groupName, + inline: undefined + }) + : undefined, set: (itemType) => itemType != null ? SchemaWithExample.array({ diff --git a/packages/cli/cli/versions.yml b/packages/cli/cli/versions.yml index cee3fef2e15..bfb0777aeab 100644 --- a/packages/cli/cli/versions.yml +++ b/packages/cli/cli/versions.yml @@ -1,3 +1,18 @@ +- changelogEntry: + - summary: | + Adds support for nullable types in the Fern definition, such as the following: + + ```yaml + types: + User: + properties: + name: string + email: nullable + ``` + type: feat + irVersion: 53 + version: 0.48.0 + - changelogEntry: - summary: | The IR now pulls in additional request properties from the OAuth getToken endpoint to support custom OAuth schemas. diff --git a/packages/cli/fern-definition/ir-to-jsonschema/src/converters/containerToJsonSchema.ts b/packages/cli/fern-definition/ir-to-jsonschema/src/converters/containerToJsonSchema.ts index 1c7dfba3d75..d18d28261b0 100644 --- a/packages/cli/fern-definition/ir-to-jsonschema/src/converters/containerToJsonSchema.ts +++ b/packages/cli/fern-definition/ir-to-jsonschema/src/converters/containerToJsonSchema.ts @@ -31,6 +31,13 @@ export function convertContainerToJsonSchema({ { type: "null" } ] }; + case "nullable": + return { + oneOf: [ + convertTypeReferenceToJsonSchema({ typeReference: container.nullable, context }), + { type: "null" } + ] + }; case "set": return { type: "array", diff --git a/packages/cli/fern-definition/schema/src/utils/RawContainerType.ts b/packages/cli/fern-definition/schema/src/utils/RawContainerType.ts index 201d645c5bc..09d60c1cebe 100644 --- a/packages/cli/fern-definition/schema/src/utils/RawContainerType.ts +++ b/packages/cli/fern-definition/schema/src/utils/RawContainerType.ts @@ -1,5 +1,6 @@ export const RawContainerType = { optional: "optional", + nullable: "nullable", set: "set", list: "list", map: "map", diff --git a/packages/cli/fern-definition/schema/src/utils/recursivelyVisitRawTypeReference.ts b/packages/cli/fern-definition/schema/src/utils/recursivelyVisitRawTypeReference.ts index 16368902943..100705a013a 100644 --- a/packages/cli/fern-definition/schema/src/utils/recursivelyVisitRawTypeReference.ts +++ b/packages/cli/fern-definition/schema/src/utils/recursivelyVisitRawTypeReference.ts @@ -9,6 +9,7 @@ export interface RecursiveRawTypeReferenceVisitor { list: (valueType: R) => R; set: (valueType: R) => R; optional: (valueType: R) => R; + nullable: (valueType: R) => R; literal: (literal: Literal) => R; named: (named: string) => R; unknown: () => R; @@ -66,6 +67,8 @@ export function recursivelyVisitRawTypeReference({ ), optional: (valueType) => visitor.optional(recursivelyVisitRawTypeReference({ type: valueType, _default, validation, visitor })), + nullable: (valueType) => + visitor.nullable(recursivelyVisitRawTypeReference({ type: valueType, _default, validation, visitor })), literal: visitor.literal, named: visitor.named, unknown: visitor.unknown diff --git a/packages/cli/fern-definition/schema/src/utils/visitRawTypeReference.ts b/packages/cli/fern-definition/schema/src/utils/visitRawTypeReference.ts index 088940a0d97..a26f082b9a1 100644 --- a/packages/cli/fern-definition/schema/src/utils/visitRawTypeReference.ts +++ b/packages/cli/fern-definition/schema/src/utils/visitRawTypeReference.ts @@ -10,6 +10,7 @@ export const FernContainerRegex = { LIST: /^list<\s*(.*)\s*>$/, SET: /^set<\s*(.*)\s*>$/, OPTIONAL: /^optional<\s*(.*)\s*>$/, + NULLABLE: /^nullable<\s*(.*)\s*>$/, LITERAL: /^literal<\s*(?:"(.*)"|(true|false))\s*>$/ }; @@ -19,6 +20,7 @@ export interface RawTypeReferenceVisitor { list: (valueType: string) => R; set: (valueType: string) => R; optional: (valueType: string) => R; + nullable: (valueType: string) => R; literal: (literal: Literal) => R; named: (named: string) => R; unknown: () => R; @@ -175,6 +177,11 @@ export function visitRawTypeReference({ return visitor.optional(optionalMatch[1]); } + const nullableMatch = type.match(FernContainerRegex.NULLABLE); + if (nullableMatch?.[1] != null) { + return visitor.nullable(nullableMatch[1]); + } + const literalMatch = type.match(FernContainerRegex.LITERAL); if (literalMatch?.[1] != null) { return visitor.literal(Literal.string(literalMatch[1])); diff --git a/packages/cli/fern-definition/validator/src/ComplexQueryParamTypeDetector.ts b/packages/cli/fern-definition/validator/src/ComplexQueryParamTypeDetector.ts index c4e2e2e7a1e..db9a8e56a65 100644 --- a/packages/cli/fern-definition/validator/src/ComplexQueryParamTypeDetector.ts +++ b/packages/cli/fern-definition/validator/src/ComplexQueryParamTypeDetector.ts @@ -113,6 +113,7 @@ export class ComplexQueryParamTypeDetector { ) ); case "optional": + case "nullable": case "list": case "set": return this.isResolvedReferenceComplex({ @@ -254,6 +255,7 @@ export class ComplexQueryParamTypeDetector { }) ); case "optional": + case "nullable": case "list": case "set": return this.isComplex({ diff --git a/packages/cli/fern-definition/validator/src/rules/no-undefined-type-reference/no-undefined-type-reference.ts b/packages/cli/fern-definition/validator/src/rules/no-undefined-type-reference/no-undefined-type-reference.ts index e132b347c54..802154cd077 100644 --- a/packages/cli/fern-definition/validator/src/rules/no-undefined-type-reference/no-undefined-type-reference.ts +++ b/packages/cli/fern-definition/validator/src/rules/no-undefined-type-reference/no-undefined-type-reference.ts @@ -199,6 +199,7 @@ function getAllNamedTypes({ list: (namesInValueType) => namesInValueType, set: (namesInValueType) => namesInValueType, optional: (namesInValueType) => namesInValueType, + nullable: (namesInValueType) => namesInValueType, literal: () => [], named: (named) => { const reference = parseReferenceToTypeName({ diff --git a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertExampleType.ts b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertExampleType.ts index 5fa6c3f8547..1e7b67302ea 100644 --- a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertExampleType.ts +++ b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertExampleType.ts @@ -303,6 +303,25 @@ export function convertTypeReferenceExample({ }) ); }, + nullable: (itemType) => { + return ExampleTypeReferenceShape.container( + ExampleContainer.nullable({ + nullable: + resolvedExample != null + ? convertTypeReferenceExample({ + example: resolvedExample, + fileContainingExample: fileContainingResolvedExample, + rawTypeBeingExemplified: itemType, + fileContainingRawTypeReference, + typeResolver, + exampleResolver, + workspace + }) + : undefined, + valueType: fileContainingRawTypeReference.parseTypeReference(itemType) + }) + ); + }, literal: (literal) => { switch (literal.type) { case "boolean": diff --git a/packages/cli/generation/ir-generator/src/converters/type-declarations/getReferencedTypesFromRawDeclaration.ts b/packages/cli/generation/ir-generator/src/converters/type-declarations/getReferencedTypesFromRawDeclaration.ts index 5961131a90d..16c7ba882cd 100644 --- a/packages/cli/generation/ir-generator/src/converters/type-declarations/getReferencedTypesFromRawDeclaration.ts +++ b/packages/cli/generation/ir-generator/src/converters/type-declarations/getReferencedTypesFromRawDeclaration.ts @@ -117,6 +117,7 @@ export function getReferencedTypesFromRawDeclaration({ map: ({ keyType, valueType }) => [...keyType, ...valueType], list: (valueType) => valueType, optional: (valueType) => valueType, + nullable: (valueType) => valueType, set: (valueType) => valueType, named: (name) => [name], literal: () => [], diff --git a/packages/cli/generation/ir-generator/src/dynamic-snippets/DynamicSnippetsConverter.ts b/packages/cli/generation/ir-generator/src/dynamic-snippets/DynamicSnippetsConverter.ts index 692efb2c52f..e3a028931e1 100644 --- a/packages/cli/generation/ir-generator/src/dynamic-snippets/DynamicSnippetsConverter.ts +++ b/packages/cli/generation/ir-generator/src/dynamic-snippets/DynamicSnippetsConverter.ts @@ -331,6 +331,8 @@ export class DynamicSnippetsConverter { }); case "optional": return DynamicSnippets.TypeReference.optional(this.convertTypeReference(container.optional)); + case "nullable": + return DynamicSnippets.TypeReference.nullable(this.convertTypeReference(container.nullable)); case "set": return DynamicSnippets.TypeReference.set(this.convertTypeReference(container.set)); case "literal": diff --git a/packages/cli/generation/ir-generator/src/examples/generator/generateContainerExample.ts b/packages/cli/generation/ir-generator/src/examples/generator/generateContainerExample.ts index 0fe1b5e15b6..d7d38236761 100644 --- a/packages/cli/generation/ir-generator/src/examples/generator/generateContainerExample.ts +++ b/packages/cli/generation/ir-generator/src/examples/generator/generateContainerExample.ts @@ -96,6 +96,30 @@ export function generateContainerExample({ jsonExample: example.jsonExample }; } + case "nullable": { + if (skipOptionalProperties) { + return generateEmptyContainerExample({ containerType }); + } + const example = generateTypeReferenceExample({ + fieldName, + typeReference: containerType.nullable, + maxDepth, + currentDepth: currentDepth + 1, + typeDeclarations, + skipOptionalProperties + }); + if (example.type === "failure") { + return generateEmptyContainerExample({ containerType }); + } + return { + type: "success", + example: ExampleContainer.nullable({ + nullable: example.example, + valueType: containerType.nullable + }), + jsonExample: example.jsonExample + }; + } case "set": { const example = generateTypeReferenceExample({ fieldName, @@ -206,6 +230,16 @@ export function generateEmptyContainerExample({ jsonExample: undefined }; } + case "nullable": { + return { + type: "success", + example: ExampleContainer.nullable({ + nullable: undefined, + valueType: containerType.nullable + }), + jsonExample: undefined + }; + } case "set": { return { type: "success", diff --git a/packages/cli/generation/ir-generator/src/examples/validateTypeReferenceExample.ts b/packages/cli/generation/ir-generator/src/examples/validateTypeReferenceExample.ts index 9a3d3be4c16..2b53c76c79e 100644 --- a/packages/cli/generation/ir-generator/src/examples/validateTypeReferenceExample.ts +++ b/packages/cli/generation/ir-generator/src/examples/validateTypeReferenceExample.ts @@ -214,6 +214,21 @@ export function validateTypeReferenceExample({ depth: depth + 1 }); }, + nullable: (itemType) => { + if (example == null) { + return []; + } + return validateTypeReferenceExample({ + rawTypeReference: itemType, + example, + typeResolver, + exampleResolver, + file, + workspace, + breadcrumbs, + depth: depth + 1 + }); + }, unknown: () => { return []; }, @@ -488,6 +503,15 @@ function areResolvedTypesEquivalent({ expected, actual }: { expected: ResolvedTy ? actual.container.itemType : actual }); + case "nullable": + // special case: if expected is a nullable but actual is not, that's okay + return areResolvedTypesEquivalent({ + expected: expected.container.itemType, + actual: + actual._type === "container" && actual.container._type === "nullable" + ? actual.container.itemType + : actual + }); case "map": return ( actual._type === "container" && diff --git a/packages/cli/generation/ir-generator/src/filterExamples.ts b/packages/cli/generation/ir-generator/src/filterExamples.ts index 57cc3417c38..02ebd1a5ec1 100644 --- a/packages/cli/generation/ir-generator/src/filterExamples.ts +++ b/packages/cli/generation/ir-generator/src/filterExamples.ts @@ -111,6 +111,23 @@ function filterExampleTypeReference({ } : undefined; }, + nullable: (n) => { + const filteredNullableTypReference = + n.nullable != null + ? filterExampleTypeReference({ filteredIr, exampleTypeReference: n.nullable }) + : undefined; + return filteredNullableTypReference != null + ? { + ...exampleTypeReference, + shape: ExampleTypeReferenceShape.container( + ExampleContainer.nullable({ + nullable: filteredNullableTypReference, + valueType: n.valueType + }) + ) + } + : undefined; + }, map: (m) => ({ ...exampleTypeReference, shape: ExampleTypeReferenceShape.container( diff --git a/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts b/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts index c40e45819f7..81ab74b7b04 100644 --- a/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts +++ b/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts @@ -706,6 +706,9 @@ function populateReferencesFromContainer( optional: (optionalType) => { populateReferencesFromTypeReference(optionalType, referencedTypes, referencedSubpackages); }, + nullable: (nullableType) => { + populateReferencesFromTypeReference(nullableType, referencedTypes, referencedSubpackages); + }, set: (setType) => { populateReferencesFromTypeReference(setType, referencedTypes, referencedSubpackages); }, diff --git a/packages/cli/generation/ir-generator/src/resolvers/ResolvedType.ts b/packages/cli/generation/ir-generator/src/resolvers/ResolvedType.ts index d32f6e669e0..f0ff202c8f7 100644 --- a/packages/cli/generation/ir-generator/src/resolvers/ResolvedType.ts +++ b/packages/cli/generation/ir-generator/src/resolvers/ResolvedType.ts @@ -49,6 +49,7 @@ export declare type ResolvedContainerType = | ResolvedContainerType.Map | ResolvedContainerType.List | ResolvedContainerType.Optional + | ResolvedContainerType.Nullable | ResolvedContainerType.Set | ResolvedContainerType.Literal; @@ -69,6 +70,11 @@ export declare namespace ResolvedContainerType { itemType: ResolvedType; } + interface Nullable { + _type: "nullable"; + itemType: ResolvedType; + } + interface Set { _type: "set"; itemType: ResolvedType; diff --git a/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts b/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts index 2919d382214..f00cb100467 100644 --- a/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts +++ b/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts @@ -181,6 +181,19 @@ export class TypeResolverImpl implements TypeResolver { ) } : undefined, + nullable: (itemType) => + itemType != null + ? { + _type: "container", + container: { + _type: "nullable", + itemType + }, + originalTypeReference: TypeReference.container( + ContainerType.nullable(itemType.originalTypeReference) + ) + } + : undefined, set: (itemType) => itemType != null ? { diff --git a/packages/cli/generation/ir-generator/src/utils/parseInlineType.ts b/packages/cli/generation/ir-generator/src/utils/parseInlineType.ts index ae87a88b41c..409880949af 100644 --- a/packages/cli/generation/ir-generator/src/utils/parseInlineType.ts +++ b/packages/cli/generation/ir-generator/src/utils/parseInlineType.ts @@ -25,6 +25,7 @@ export function parseInlineType({ type, file, _default, validation }: parseInlin list: (valueType) => TypeReference.container(ContainerType.list(valueType)), set: (valueType) => TypeReference.container(ContainerType.set(valueType)), optional: (valueType) => TypeReference.container(ContainerType.optional(valueType)), + nullable: (valueType) => TypeReference.container(ContainerType.nullable(valueType)), literal: (literal) => TypeReference.container(ContainerType.literal(literal)), named: (namedType) => TypeReference.named({ diff --git a/packages/cli/generation/ir-migrations/package.json b/packages/cli/generation/ir-migrations/package.json index ca0f38486c2..3f82c0ab803 100644 --- a/packages/cli/generation/ir-migrations/package.json +++ b/packages/cli/generation/ir-migrations/package.json @@ -86,6 +86,7 @@ "@fern-fern/ir-v51-sdk": "0.0.1", "@fern-fern/ir-v52-sdk": "0.0.1", "@fern-fern/ir-v53-sdk": "0.0.1", + "@fern-fern/ir-v54-sdk": "0.0.1", "@fern-fern/ir-v6-model": "0.0.33", "@fern-fern/ir-v7-model": "0.0.2", "@fern-fern/ir-v8-model": "0.0.1", diff --git a/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts b/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts index f576e89f6fc..8d5cafd6ffa 100644 --- a/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts +++ b/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts @@ -57,6 +57,7 @@ import { V51_TO_V50_MIGRATION } from "./migrations/v51-to-v50/migrateFromV51ToV5 import { V52_TO_V51_MIGRATION } from "./migrations/v52-to-v51/migrateFromV52ToV51"; import { V53_TO_V52_MIGRATION } from "./migrations/v53-to-v52/migrateFromV53ToV52"; import { V54_TO_V53_MIGRATION } from "./migrations/v54-to-v53/migrateFromV54ToV53"; +import { V55_TO_V54_MIGRATION } from "./migrations/v55-to-v54/migrateFromV55ToV54"; import { GeneratorWasNeverUpdatedToConsumeNewIR, GeneratorWasNotCreatedYet, IrMigration } from "./types/IrMigration"; export function getIntermediateRepresentationMigrator(): IntermediateRepresentationMigrator { @@ -298,6 +299,7 @@ const IntermediateRepresentationMigrator = { export const INTERMEDIATE_REPRESENTATION_MIGRATOR = IntermediateRepresentationMigrator.Builder // put new migrations here + .withMigration(V55_TO_V54_MIGRATION) .withMigration(V54_TO_V53_MIGRATION) .withMigration(V53_TO_V52_MIGRATION) .withMigration(V52_TO_V51_MIGRATION) diff --git a/packages/cli/generation/ir-migrations/src/ir-serialization/IrSerialization.ts b/packages/cli/generation/ir-migrations/src/ir-serialization/IrSerialization.ts index d56ae8a7bbd..56328dc8a73 100644 --- a/packages/cli/generation/ir-migrations/src/ir-serialization/IrSerialization.ts +++ b/packages/cli/generation/ir-migrations/src/ir-serialization/IrSerialization.ts @@ -1,4 +1,4 @@ -export { serialization as V54 } from "@fern-api/ir-sdk"; +export { serialization as V55 } from "@fern-api/ir-sdk"; export * as V23 from "@fern-fern/ir-v23-sdk/serialization"; export * as V24 from "@fern-fern/ir-v24-sdk/serialization"; export * as V25 from "@fern-fern/ir-v25-sdk/serialization"; @@ -30,3 +30,4 @@ export * as V50 from "@fern-fern/ir-v50-sdk/serialization"; export * as V51 from "@fern-fern/ir-v51-sdk/serialization"; export * as V52 from "@fern-fern/ir-v52-sdk/serialization"; export * as V53 from "@fern-fern/ir-v53-sdk/serialization"; +export * as V54 from "@fern-fern/ir-v54-sdk/serialization"; diff --git a/packages/cli/generation/ir-migrations/src/ir-versions/IrVersions.ts b/packages/cli/generation/ir-migrations/src/ir-versions/IrVersions.ts index 4644622a225..6f9ff18ce55 100644 --- a/packages/cli/generation/ir-migrations/src/ir-versions/IrVersions.ts +++ b/packages/cli/generation/ir-migrations/src/ir-versions/IrVersions.ts @@ -1,4 +1,4 @@ -export { FernIr as V54 } from "@fern-api/ir-sdk"; +export { FernIr as V55 } from "@fern-api/ir-sdk"; export * as V1 from "@fern-fern/ir-v1-model"; export * as V10 from "@fern-fern/ir-v10-model"; export * as V11 from "@fern-fern/ir-v11-model"; @@ -48,6 +48,7 @@ export { FernIrV50 as V50 } from "@fern-fern/ir-v50-sdk"; export { FernIrV51 as V51 } from "@fern-fern/ir-v51-sdk"; export { FernIrV52 as V52 } from "@fern-fern/ir-v52-sdk"; export { FernIrV53 as V53 } from "@fern-fern/ir-v53-sdk"; +export { FernIrV54 as V54 } from "@fern-fern/ir-v54-sdk"; export * as V6 from "@fern-fern/ir-v6-model"; export * as V7 from "@fern-fern/ir-v7-model"; export * as V8 from "@fern-fern/ir-v8-model"; diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/__snapshots__/migrateFromV55ToV54.test.ts.snap b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/__snapshots__/migrateFromV55ToV54.test.ts.snap new file mode 100644 index 00000000000..d51fccb4f6c --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/__snapshots__/migrateFromV55ToV54.test.ts.snap @@ -0,0 +1,1922 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`migrateFromV55ToV54 > simple 1`] = ` +{ + "apiDisplayName": null, + "apiDocs": null, + "apiName": { + "camelCase": { + "safeName": "simpleAPI", + "unsafeName": "simpleAPI", + }, + "originalName": "simple-api", + "pascalCase": { + "safeName": "SimpleAPI", + "unsafeName": "SimpleAPI", + }, + "screamingSnakeCase": { + "safeName": "SIMPLE_API", + "unsafeName": "SIMPLE_API", + }, + "snakeCase": { + "safeName": "simple_api", + "unsafeName": "simple_api", + }, + }, + "apiVersion": null, + "auth": { + "docs": null, + "requirement": "ALL", + "schemes": [ + { + "_type": "bearer", + "docs": null, + "token": { + "camelCase": { + "safeName": "token", + "unsafeName": "token", + }, + "originalName": "token", + "pascalCase": { + "safeName": "Token", + "unsafeName": "Token", + }, + "screamingSnakeCase": { + "safeName": "TOKEN", + "unsafeName": "TOKEN", + }, + "snakeCase": { + "safeName": "token", + "unsafeName": "token", + }, + }, + "tokenEnvVar": null, + }, + ], + }, + "basePath": null, + "constants": { + "errorInstanceIdKey": { + "name": { + "camelCase": { + "safeName": "errorInstanceID", + "unsafeName": "errorInstanceID", + }, + "originalName": "errorInstanceId", + "pascalCase": { + "safeName": "ErrorInstanceID", + "unsafeName": "ErrorInstanceID", + }, + "screamingSnakeCase": { + "safeName": "ERROR_INSTANCE_ID", + "unsafeName": "ERROR_INSTANCE_ID", + }, + "snakeCase": { + "safeName": "error_instance_id", + "unsafeName": "error_instance_id", + }, + }, + "wireValue": "errorInstanceId", + }, + }, + "dynamic": { + "endpoints": { + "endpoint_service.createUser": { + "auth": { + "token": { + "camelCase": { + "safeName": "token", + "unsafeName": "token", + }, + "originalName": "token", + "pascalCase": { + "safeName": "Token", + "unsafeName": "Token", + }, + "screamingSnakeCase": { + "safeName": "TOKEN", + "unsafeName": "TOKEN", + }, + "snakeCase": { + "safeName": "token", + "unsafeName": "token", + }, + }, + "type": "bearer", + }, + "declaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "createUser", + "unsafeName": "createUser", + }, + "originalName": "createUser", + "pascalCase": { + "safeName": "CreateUser", + "unsafeName": "CreateUser", + }, + "screamingSnakeCase": { + "safeName": "CREATE_USER", + "unsafeName": "CREATE_USER", + }, + "snakeCase": { + "safeName": "create_user", + "unsafeName": "create_user", + }, + }, + }, + "location": { + "method": "POST", + "path": "/users", + }, + "request": { + "body": { + "type": "properties", + "value": [ + { + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "typeReference": { + "type": "primitive", + "value": "STRING", + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "typeReference": { + "type": "optional", + "value": { + "type": "primitive", + "value": "STRING", + }, + }, + }, + ], + }, + "declaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "createUserRequest", + "unsafeName": "createUserRequest", + }, + "originalName": "CreateUserRequest", + "pascalCase": { + "safeName": "CreateUserRequest", + "unsafeName": "CreateUserRequest", + }, + "screamingSnakeCase": { + "safeName": "CREATE_USER_REQUEST", + "unsafeName": "CREATE_USER_REQUEST", + }, + "snakeCase": { + "safeName": "create_user_request", + "unsafeName": "create_user_request", + }, + }, + }, + "headers": [], + "metadata": { + "includePathParameters": false, + "onlyPathParameters": false, + }, + "pathParameters": [], + "queryParameters": [], + "type": "inlined", + }, + "response": { + "type": "json", + }, + }, + }, + "environments": null, + "headers": [], + "types": { + "type_service:User": { + "declaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + }, + "properties": [ + { + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "typeReference": { + "type": "primitive", + "value": "STRING", + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "typeReference": { + "type": "optional", + "value": { + "type": "primitive", + "value": "STRING", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "createdAt", + "unsafeName": "createdAt", + }, + "originalName": "createdAt", + "pascalCase": { + "safeName": "CreatedAt", + "unsafeName": "CreatedAt", + }, + "screamingSnakeCase": { + "safeName": "CREATED_AT", + "unsafeName": "CREATED_AT", + }, + "snakeCase": { + "safeName": "created_at", + "unsafeName": "created_at", + }, + }, + "wireValue": "createdAt", + }, + "typeReference": { + "type": "optional", + "value": { + "type": "primitive", + "value": "STRING", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "updatedAt", + "unsafeName": "updatedAt", + }, + "originalName": "updatedAt", + "pascalCase": { + "safeName": "UpdatedAt", + "unsafeName": "UpdatedAt", + }, + "screamingSnakeCase": { + "safeName": "UPDATED_AT", + "unsafeName": "UPDATED_AT", + }, + "snakeCase": { + "safeName": "updated_at", + "unsafeName": "updated_at", + }, + }, + "wireValue": "updatedAt", + }, + "typeReference": { + "type": "optional", + "value": { + "type": "primitive", + "value": "STRING", + }, + }, + }, + ], + "type": "object", + }, + }, + "version": "1.0.0", + }, + "environments": null, + "errorDiscriminationStrategy": { + "type": "statusCode", + }, + "errors": {}, + "fdrApiDefinitionId": null, + "headers": [], + "idempotencyHeaders": [], + "pathParameters": [], + "publishConfig": null, + "readmeConfig": null, + "rootPackage": { + "docs": null, + "errors": [], + "fernFilepath": { + "allParts": [], + "file": null, + "packagePath": [], + }, + "hasEndpointsInTree": true, + "navigationConfig": null, + "service": null, + "subpackages": [ + "subpackage_service", + ], + "types": [], + "webhooks": null, + "websocket": null, + }, + "sdkConfig": { + "hasFileDownloadEndpoints": false, + "hasPaginatedEndpoints": false, + "hasStreamingEndpoints": false, + "isAuthMandatory": false, + "platformHeaders": { + "language": "X-Fern-Language", + "sdkName": "X-Fern-SDK-Name", + "sdkVersion": "X-Fern-SDK-Version", + "userAgent": null, + }, + }, + "serviceTypeReferenceInfo": { + "sharedTypes": [], + "typesReferencedOnlyByService": { + "service_service": [ + "type_service:User", + ], + }, + }, + "services": { + "service_service": { + "availability": null, + "basePath": { + "head": "/", + "parts": [], + }, + "displayName": null, + "encoding": { + "json": {}, + "proto": null, + }, + "endpoints": [ + { + "allPathParameters": [], + "auth": false, + "autogeneratedExamples": [ + { + "example": { + "docs": null, + "endpointHeaders": [], + "endpointPathParameters": [], + "id": "6bb68f3f", + "name": null, + "queryParameters": [], + "request": { + "jsonExample": { + "email": undefined, + "name": "name", + }, + "properties": [ + { + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "originalTypeDeclaration": null, + "value": { + "jsonExample": "name", + "shape": { + "primitive": { + "string": { + "original": "name", + }, + "type": "string", + }, + "type": "primitive", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "originalTypeDeclaration": null, + "value": { + "jsonExample": undefined, + "shape": { + "container": { + "optional": null, + "type": "optional", + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + "type": "container", + }, + }, + }, + ], + "type": "inlinedRequestBody", + }, + "response": { + "type": "ok", + "value": { + "type": "body", + "value": { + "jsonExample": { + "createdAt": "createdAt", + "email": "email", + "name": "name", + "updatedAt": "updatedAt", + }, + "shape": { + "shape": { + "properties": [ + { + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "originalTypeDeclaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "value": { + "jsonExample": "name", + "shape": { + "primitive": { + "string": { + "original": "name", + }, + "type": "string", + }, + "type": "primitive", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "originalTypeDeclaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "value": { + "jsonExample": "email", + "shape": { + "container": { + "optional": { + "jsonExample": "email", + "shape": { + "primitive": { + "string": { + "original": "email", + }, + "type": "string", + }, + "type": "primitive", + }, + }, + "type": "optional", + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + "type": "container", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "createdAt", + "unsafeName": "createdAt", + }, + "originalName": "createdAt", + "pascalCase": { + "safeName": "CreatedAt", + "unsafeName": "CreatedAt", + }, + "screamingSnakeCase": { + "safeName": "CREATED_AT", + "unsafeName": "CREATED_AT", + }, + "snakeCase": { + "safeName": "created_at", + "unsafeName": "created_at", + }, + }, + "wireValue": "createdAt", + }, + "originalTypeDeclaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "value": { + "jsonExample": "createdAt", + "shape": { + "container": { + "optional": { + "jsonExample": "createdAt", + "shape": { + "primitive": { + "string": { + "original": "createdAt", + }, + "type": "string", + }, + "type": "primitive", + }, + }, + "type": "optional", + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + "type": "container", + }, + }, + }, + { + "name": { + "name": { + "camelCase": { + "safeName": "updatedAt", + "unsafeName": "updatedAt", + }, + "originalName": "updatedAt", + "pascalCase": { + "safeName": "UpdatedAt", + "unsafeName": "UpdatedAt", + }, + "screamingSnakeCase": { + "safeName": "UPDATED_AT", + "unsafeName": "UPDATED_AT", + }, + "snakeCase": { + "safeName": "updated_at", + "unsafeName": "updated_at", + }, + }, + "wireValue": "updatedAt", + }, + "originalTypeDeclaration": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "value": { + "jsonExample": "updatedAt", + "shape": { + "container": { + "optional": { + "jsonExample": "updatedAt", + "shape": { + "primitive": { + "string": { + "original": "updatedAt", + }, + "type": "string", + }, + "type": "primitive", + }, + }, + "type": "optional", + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + "type": "container", + }, + }, + }, + ], + "type": "object", + }, + "type": "named", + "typeName": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + }, + }, + }, + }, + "rootPathParameters": [], + "serviceHeaders": [], + "servicePathParameters": [], + "url": "/users", + }, + }, + ], + "availability": null, + "basePath": null, + "baseUrl": null, + "displayName": null, + "docs": null, + "errors": [], + "fullPath": { + "head": "/users", + "parts": [], + }, + "headers": [], + "id": "endpoint_service.createUser", + "idempotent": false, + "method": "POST", + "name": { + "camelCase": { + "safeName": "createUser", + "unsafeName": "createUser", + }, + "originalName": "createUser", + "pascalCase": { + "safeName": "CreateUser", + "unsafeName": "CreateUser", + }, + "screamingSnakeCase": { + "safeName": "CREATE_USER", + "unsafeName": "CREATE_USER", + }, + "snakeCase": { + "safeName": "create_user", + "unsafeName": "create_user", + }, + }, + "pagination": null, + "path": { + "head": "/users", + "parts": [], + }, + "pathParameters": [], + "queryParameters": [], + "requestBody": { + "contentType": null, + "docs": null, + "extendedProperties": [], + "extends": [], + "extra-properties": false, + "name": { + "camelCase": { + "safeName": "createUserRequest", + "unsafeName": "createUserRequest", + }, + "originalName": "CreateUserRequest", + "pascalCase": { + "safeName": "CreateUserRequest", + "unsafeName": "CreateUserRequest", + }, + "screamingSnakeCase": { + "safeName": "CREATE_USER_REQUEST", + "unsafeName": "CREATE_USER_REQUEST", + }, + "snakeCase": { + "safeName": "create_user_request", + "unsafeName": "create_user_request", + }, + }, + "properties": [ + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "valueType": { + "_type": "container", + "container": { + "_type": "optional", + "optional": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + }, + }, + ], + "type": "inlinedRequestBody", + }, + "response": { + "body": { + "type": "json", + "value": { + "docs": null, + "responseBodyType": { + "_type": "named", + "default": null, + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "inline": null, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "type": "response", + }, + }, + "status-code": null, + }, + "sdkRequest": { + "requestParameterName": { + "camelCase": { + "safeName": "request", + "unsafeName": "request", + }, + "originalName": "request", + "pascalCase": { + "safeName": "Request", + "unsafeName": "Request", + }, + "screamingSnakeCase": { + "safeName": "REQUEST", + "unsafeName": "REQUEST", + }, + "snakeCase": { + "safeName": "request", + "unsafeName": "request", + }, + }, + "shape": { + "bodyKey": { + "camelCase": { + "safeName": "body", + "unsafeName": "body", + }, + "originalName": "body", + "pascalCase": { + "safeName": "Body", + "unsafeName": "Body", + }, + "screamingSnakeCase": { + "safeName": "BODY", + "unsafeName": "BODY", + }, + "snakeCase": { + "safeName": "body", + "unsafeName": "body", + }, + }, + "includePathParameters": false, + "onlyPathParameters": false, + "type": "wrapper", + "wrapperName": { + "camelCase": { + "safeName": "createUserRequest", + "unsafeName": "createUserRequest", + }, + "originalName": "CreateUserRequest", + "pascalCase": { + "safeName": "CreateUserRequest", + "unsafeName": "CreateUserRequest", + }, + "screamingSnakeCase": { + "safeName": "CREATE_USER_REQUEST", + "unsafeName": "CREATE_USER_REQUEST", + }, + "snakeCase": { + "safeName": "create_user_request", + "unsafeName": "create_user_request", + }, + }, + }, + "streamParameter": null, + }, + "transport": null, + "userSpecifiedExamples": [], + }, + ], + "headers": [], + "name": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + }, + "pathParameters": [], + "transport": { + "type": "http", + }, + }, + }, + "sourceConfig": null, + "subpackages": { + "subpackage_service": { + "docs": null, + "errors": [], + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "hasEndpointsInTree": true, + "name": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "navigationConfig": null, + "service": "service_service", + "subpackages": [], + "types": [ + "type_service:User", + ], + "webhooks": null, + "websocket": null, + }, + }, + "types": { + "type_service:User": { + "autogeneratedExamples": [], + "availability": null, + "docs": null, + "encoding": { + "json": {}, + "proto": null, + }, + "inline": null, + "name": { + "fernFilepath": { + "allParts": [ + { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + ], + "file": { + "camelCase": { + "safeName": "service", + "unsafeName": "service", + }, + "originalName": "service", + "pascalCase": { + "safeName": "Service", + "unsafeName": "Service", + }, + "screamingSnakeCase": { + "safeName": "SERVICE", + "unsafeName": "SERVICE", + }, + "snakeCase": { + "safeName": "service", + "unsafeName": "service", + }, + }, + "packagePath": [], + }, + "name": { + "camelCase": { + "safeName": "user", + "unsafeName": "user", + }, + "originalName": "User", + "pascalCase": { + "safeName": "User", + "unsafeName": "User", + }, + "screamingSnakeCase": { + "safeName": "USER", + "unsafeName": "USER", + }, + "snakeCase": { + "safeName": "user", + "unsafeName": "user", + }, + }, + "typeId": "type_service:User", + }, + "referencedTypes": [], + "shape": { + "_type": "object", + "extendedProperties": [], + "extends": [], + "extra-properties": false, + "properties": [ + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "name", + "unsafeName": "name", + }, + "originalName": "name", + "pascalCase": { + "safeName": "Name", + "unsafeName": "Name", + }, + "screamingSnakeCase": { + "safeName": "NAME", + "unsafeName": "NAME", + }, + "snakeCase": { + "safeName": "name", + "unsafeName": "name", + }, + }, + "wireValue": "name", + }, + "valueType": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "email", + "unsafeName": "email", + }, + "originalName": "email", + "pascalCase": { + "safeName": "Email", + "unsafeName": "Email", + }, + "screamingSnakeCase": { + "safeName": "EMAIL", + "unsafeName": "EMAIL", + }, + "snakeCase": { + "safeName": "email", + "unsafeName": "email", + }, + }, + "wireValue": "email", + }, + "valueType": { + "_type": "container", + "container": { + "_type": "optional", + "optional": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + }, + }, + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "createdAt", + "unsafeName": "createdAt", + }, + "originalName": "createdAt", + "pascalCase": { + "safeName": "CreatedAt", + "unsafeName": "CreatedAt", + }, + "screamingSnakeCase": { + "safeName": "CREATED_AT", + "unsafeName": "CREATED_AT", + }, + "snakeCase": { + "safeName": "created_at", + "unsafeName": "created_at", + }, + }, + "wireValue": "createdAt", + }, + "valueType": { + "_type": "container", + "container": { + "_type": "optional", + "optional": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + }, + }, + { + "availability": null, + "docs": null, + "name": { + "name": { + "camelCase": { + "safeName": "updatedAt", + "unsafeName": "updatedAt", + }, + "originalName": "updatedAt", + "pascalCase": { + "safeName": "UpdatedAt", + "unsafeName": "UpdatedAt", + }, + "screamingSnakeCase": { + "safeName": "UPDATED_AT", + "unsafeName": "UPDATED_AT", + }, + "snakeCase": { + "safeName": "updated_at", + "unsafeName": "updated_at", + }, + }, + "wireValue": "updatedAt", + }, + "valueType": { + "_type": "container", + "container": { + "_type": "optional", + "optional": { + "_type": "primitive", + "primitive": { + "v1": "STRING", + "v2": { + "default": null, + "type": "string", + "validation": null, + }, + }, + }, + }, + }, + }, + ], + }, + "source": null, + "userProvidedExamples": [], + }, + }, + "variables": [], + "webhookGroups": {}, + "websocketChannels": {}, +} +`; diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/api.yml b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/api.yml new file mode 100644 index 00000000000..cc1ca43b9bc --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/api.yml @@ -0,0 +1,2 @@ +name: simple-api +auth: bearer \ No newline at end of file diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/service.yml b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/service.yml new file mode 100644 index 00000000000..12cb9c3c165 --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/definition/service.yml @@ -0,0 +1,22 @@ +types: + User: + properties: + name: string + email: nullable + createdAt: optional + updatedAt: optional + +service: + auth: false + base-path: / + endpoints: + createUser: + method: POST + path: /users + request: + name: CreateUserRequest + body: + properties: + name: string + email: nullable + response: User diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/generators.yml b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/generators.yml new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/fixtures/simple/generators.yml @@ -0,0 +1 @@ +{} diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/migrateFromV55ToV54.test.ts b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/migrateFromV55ToV54.test.ts new file mode 100644 index 00000000000..cdc8c049059 --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/__test__/migrateFromV55ToV54.test.ts @@ -0,0 +1,16 @@ +import { AbsoluteFilePath, RelativeFilePath, join } from "@fern-api/fs-utils"; + +import { createMigrationTester } from "../../../__test__/utils/createMigrationTester"; +import { V55_TO_V54_MIGRATION } from "../migrateFromV55ToV54"; + +const runMigration = createMigrationTester(V55_TO_V54_MIGRATION); + +describe("migrateFromV55ToV54", () => { + it("simple", async () => { + const pathToFixture = join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("./fixtures/simple")); + const migrated = await runMigration({ + pathToFixture + }); + expect(await migrated.jsonify()).toMatchSnapshot(); + }); +}); diff --git a/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/migrateFromV55ToV54.ts b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/migrateFromV55ToV54.ts new file mode 100644 index 00000000000..23425d58b3e --- /dev/null +++ b/packages/cli/generation/ir-migrations/src/migrations/v55-to-v54/migrateFromV55ToV54.ts @@ -0,0 +1,1300 @@ +import { mapValues } from "lodash-es"; + +import { GeneratorName } from "@fern-api/configuration-loader"; +import { assertNever } from "@fern-api/core-utils"; + +import { IrSerialization } from "../../ir-serialization"; +import { IrVersions } from "../../ir-versions"; +import { + GeneratorWasNeverUpdatedToConsumeNewIR, + GeneratorWasNotCreatedYet, + IrMigration +} from "../../types/IrMigration"; + +export const V55_TO_V54_MIGRATION: IrMigration< + IrVersions.V55.ir.IntermediateRepresentation, + IrVersions.V54.ir.IntermediateRepresentation +> = { + laterVersion: "v55", + earlierVersion: "v54", + firstGeneratorVersionToConsumeNewIR: { + [GeneratorName.TYPESCRIPT_NODE_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.TYPESCRIPT_BROWSER_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.TYPESCRIPT]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.TYPESCRIPT_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.TYPESCRIPT_EXPRESS]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.JAVA]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.JAVA_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.JAVA_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.JAVA_SPRING]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.PYTHON_FASTAPI]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.PYTHON_PYDANTIC]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.OPENAPI_PYTHON_CLIENT]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.OPENAPI]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.STOPLIGHT]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.POSTMAN]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.PYTHON_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.GO_FIBER]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.GO_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.GO_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.RUBY_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.RUBY_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.CSHARP_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.CSHARP_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.SWIFT_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR, + [GeneratorName.SWIFT_SDK]: GeneratorWasNotCreatedYet, + [GeneratorName.PHP_MODEL]: GeneratorWasNotCreatedYet, + [GeneratorName.PHP_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR + }, + jsonifyEarlierVersion: (ir) => + IrSerialization.V54.IntermediateRepresentation.jsonOrThrow(ir, { + unrecognizedObjectKeys: "strip", + skipValidation: true + }), + migrateBackwards: (v55): IrVersions.V54.ir.IntermediateRepresentation => { + return { + ...v55, + apiVersion: v55.apiVersion != null ? convertApiVersionScheme(v55.apiVersion) : undefined, + auth: convertAuth(v55.auth), + headers: v55.headers.map((header) => convertHttpHeader(header)), + idempotencyHeaders: v55.idempotencyHeaders.map((header) => convertHttpHeader(header)), + types: convertTypes(v55.types), + services: mapValues(v55.services, (service) => convertHttpService(service)), + webhookGroups: mapValues(v55.webhookGroups, (webhookGroup) => convertWebhookGroup(webhookGroup)), + websocketChannels: mapValues(v55.websocketChannels, (websocketChannel) => + convertWebsocketChannel(websocketChannel) + ), + errors: mapValues(v55.errors, (error) => convertErrorDeclaration(error)), + pathParameters: v55.pathParameters.map((pathParameter) => convertPathParameter(pathParameter)), + variables: v55.variables.map((variable) => convertVariable(variable)), + dynamic: v55.dynamic != null ? convertDynamic(v55.dynamic) : undefined + }; + } +}; + +function convertTypes( + types: Record +): Record { + return mapValues(types, (typeDeclaration) => { + return { + ...typeDeclaration, + autogeneratedExamples: typeDeclaration.autogeneratedExamples.map((example) => convertExampleType(example)), + userProvidedExamples: typeDeclaration.userProvidedExamples.map((example) => convertExampleType(example)), + shape: IrVersions.V55.types.Type._visit(typeDeclaration.shape, { + union: (union) => { + return IrVersions.V54.types.Type.union({ + ...union, + baseProperties: union.baseProperties.map((objectProperty) => { + return { + ...objectProperty, + valueType: convertTypeReference(objectProperty.valueType) + }; + }), + types: union.types.map((singleUnionType) => convertSingleUnionType(singleUnionType)) + }); + }, + enum: IrVersions.V54.types.Type.enum, + object: (object) => { + return IrVersions.V54.types.Type.object({ + ...object, + properties: object.properties.map((objectProperty) => { + return { + ...objectProperty, + valueType: convertTypeReference(objectProperty.valueType) + }; + }), + extendedProperties: object.extendedProperties?.map((extendedProperty) => { + return { + ...extendedProperty, + valueType: convertTypeReference(extendedProperty.valueType) + }; + }) + }); + }, + alias: (aliasTypeDeclaration) => { + return IrVersions.V54.types.Type.alias({ + aliasOf: convertTypeReference(aliasTypeDeclaration.aliasOf), + resolvedType: convertResolvedType(aliasTypeDeclaration.resolvedType) + }); + }, + undiscriminatedUnion: (undiscriminatedUnion) => { + return IrVersions.V54.types.Type.undiscriminatedUnion( + convertUndiscriminatedUnion(undiscriminatedUnion) + ); + }, + _other: () => { + throw new Error("Encountered unknown shape"); + } + }) + }; + }); +} + +function convertApiVersionScheme(apiVersionScheme: IrVersions.V55.ApiVersionScheme): IrVersions.V54.ApiVersionScheme { + return IrVersions.V54.ApiVersionScheme.header({ + ...apiVersionScheme, + header: convertHttpHeader(apiVersionScheme.header) + }); +} + +function convertWebsocketChannel( + websocketChannel: IrVersions.V55.websocket.WebSocketChannel +): IrVersions.V54.websocket.WebSocketChannel { + return { + ...websocketChannel, + headers: websocketChannel.headers.map((header) => convertHttpHeader(header)), + queryParameters: websocketChannel.queryParameters.map((queryParameter) => + convertQueryParameter(queryParameter) + ), + pathParameters: websocketChannel.pathParameters.map((pathParameter) => convertPathParameter(pathParameter)), + messages: websocketChannel.messages.map((message) => convertWebsocketMessage(message)), + examples: websocketChannel.examples.map((example) => convertExampleWebsocketSession(example)) + }; +} + +function convertWebsocketMessage( + websocketMessage: IrVersions.V55.websocket.WebSocketMessage +): IrVersions.V54.websocket.WebSocketMessage { + return { + ...websocketMessage, + body: convertWebsocketMessageBody(websocketMessage.body) + }; +} + +function convertWebsocketMessageBody( + body: IrVersions.V55.websocket.WebSocketMessageBody +): IrVersions.V54.websocket.WebSocketMessageBody { + switch (body.type) { + case "inlinedBody": + return IrVersions.V54.websocket.WebSocketMessageBody.inlinedBody({ + ...body, + properties: body.properties.map((property) => { + return { + ...property, + valueType: convertTypeReference(property.valueType) + }; + }) + }); + case "reference": + return IrVersions.V54.websocket.WebSocketMessageBody.reference({ + ...body, + bodyType: convertTypeReference(body.bodyType) + }); + } +} + +function convertWebhookGroup(webhookGroup: IrVersions.V55.webhooks.WebhookGroup): IrVersions.V54.webhooks.WebhookGroup { + return webhookGroup.map((webhook) => convertWebhook(webhook)); +} + +function convertWebhook(webhook: IrVersions.V55.webhooks.Webhook): IrVersions.V54.webhooks.Webhook { + return { + ...webhook, + headers: webhook.headers.map((header) => convertHttpHeader(header)), + payload: convertWebhookPayload(webhook.payload), + examples: + webhook.examples != null ? webhook.examples.map((example) => convertWebhookExampleCall(example)) : undefined + }; +} + +function convertWebhookPayload( + payload: IrVersions.V55.webhooks.WebhookPayload +): IrVersions.V54.webhooks.WebhookPayload { + switch (payload.type) { + case "reference": + return IrVersions.V54.webhooks.WebhookPayload.reference({ + ...payload, + payloadType: convertTypeReference(payload.payloadType) + }); + case "inlinedPayload": + return IrVersions.V54.webhooks.WebhookPayload.inlinedPayload({ + ...payload, + properties: payload.properties.map((property) => { + return { + ...property, + valueType: convertTypeReference(property.valueType) + }; + }) + }); + } +} + +function convertWebhookExampleCall(example: IrVersions.V55.ExampleWebhookCall): IrVersions.V54.ExampleWebhookCall { + return { + ...example, + payload: convertExampleTypeReference(example.payload) + }; +} + +function convertAuth(auth: IrVersions.V55.auth.ApiAuth): IrVersions.V54.auth.ApiAuth { + return { + ...auth, + schemes: auth.schemes.map((scheme) => { + switch (scheme.type) { + case "basic": + return IrVersions.V54.auth.AuthScheme.basic(scheme); + case "bearer": + return IrVersions.V54.auth.AuthScheme.bearer(scheme); + case "header": + return IrVersions.V54.auth.AuthScheme.header(convertHeader(scheme)); + case "oauth": + return IrVersions.V54.auth.AuthScheme.oauth(convertOAuth(scheme)); + } + }) + }; +} + +function convertHeader(header: IrVersions.V55.auth.AuthScheme.Header): IrVersions.V54.auth.HeaderAuthScheme { + return { + ...header, + valueType: convertTypeReference(header.valueType) + }; +} + +function convertOAuth(oauth: IrVersions.V55.auth.AuthScheme.Oauth): IrVersions.V54.auth.OAuthScheme { + return { + ...oauth, + configuration: IrVersions.V54.auth.OAuthConfiguration.clientCredentials({ + ...oauth.configuration, + tokenEndpoint: convertOAuthTokenEndpoint(oauth.configuration.tokenEndpoint), + refreshEndpoint: + oauth.configuration.refreshEndpoint != null + ? convertOAuthRefreshEndpoint(oauth.configuration.refreshEndpoint) + : undefined + }) + }; +} + +function convertOAuthTokenEndpoint( + tokenEndpoint: IrVersions.V55.auth.OAuthTokenEndpoint +): IrVersions.V54.auth.OAuthTokenEndpoint { + return { + ...tokenEndpoint, + requestProperties: { + clientId: convertRequestProperty(tokenEndpoint.requestProperties.clientId), + clientSecret: convertRequestProperty(tokenEndpoint.requestProperties.clientSecret), + scopes: + tokenEndpoint.requestProperties.scopes != null + ? convertRequestProperty(tokenEndpoint.requestProperties.scopes) + : undefined + }, + responseProperties: { + accessToken: convertResponseProperty(tokenEndpoint.responseProperties.accessToken), + expiresIn: + tokenEndpoint.responseProperties.expiresIn != null + ? convertResponseProperty(tokenEndpoint.responseProperties.expiresIn) + : undefined, + refreshToken: + tokenEndpoint.responseProperties.refreshToken != null + ? convertResponseProperty(tokenEndpoint.responseProperties.refreshToken) + : undefined + } + }; +} + +function convertOAuthRefreshEndpoint( + refreshEndpoint: IrVersions.V55.auth.OAuthRefreshEndpoint +): IrVersions.V54.auth.OAuthRefreshEndpoint | undefined { + return { + ...refreshEndpoint, + requestProperties: { + refreshToken: convertRequestProperty(refreshEndpoint.requestProperties.refreshToken) + }, + responseProperties: { + accessToken: convertResponseProperty(refreshEndpoint.responseProperties.accessToken), + expiresIn: + refreshEndpoint.responseProperties.expiresIn != null + ? convertResponseProperty(refreshEndpoint.responseProperties.expiresIn) + : undefined, + refreshToken: + refreshEndpoint.responseProperties.refreshToken != null + ? convertResponseProperty(refreshEndpoint.responseProperties.refreshToken) + : undefined + } + }; +} + +function convertHttpHeader(header: IrVersions.V55.http.HttpHeader): IrVersions.V54.http.HttpHeader { + return { + ...header, + valueType: convertTypeReference(header.valueType) + }; +} + +function convertTypeReference(typeReference: IrVersions.V55.types.TypeReference): IrVersions.V54.types.TypeReference { + return IrVersions.V55.types.TypeReference._visit(typeReference, { + container: (container) => IrVersions.V54.types.TypeReference.container(convertContainerType(container)), + primitive: (primitiveType) => IrVersions.V54.types.TypeReference.primitive(convertPrimitiveType(primitiveType)), + named: IrVersions.V54.types.TypeReference.named, + unknown: IrVersions.V54.types.TypeReference.unknown, + _other: () => { + throw new Error("Unknown type reference: " + typeReference.type); + } + }); +} + +function convertPrimitiveType(primitiveType: IrVersions.V55.types.PrimitiveType): IrVersions.V54.types.PrimitiveType { + return { + v1: convertPrimitiveTypeV1(primitiveType.v1), + v2: primitiveType.v2 != null ? convertPrimitiveTypeV2(primitiveType.v2) : undefined + }; +} + +function convertPrimitiveTypeV1( + primitiveTypeV1: IrVersions.V55.types.PrimitiveTypeV1 +): IrVersions.V54.types.PrimitiveTypeV1 { + return primitiveTypeV1; +} + +function convertPrimitiveTypeV2( + primitiveTypeV2: IrVersions.V55.types.PrimitiveTypeV2 +): IrVersions.V54.types.PrimitiveTypeV2 | undefined { + return primitiveTypeV2; +} + +function convertContainerType(container: IrVersions.V55.types.ContainerType): IrVersions.V54.types.ContainerType { + return IrVersions.V55.types.ContainerType._visit(container, { + list: (itemType) => IrVersions.V54.types.ContainerType.list(convertTypeReference(itemType)), + optional: (itemType) => IrVersions.V54.types.ContainerType.optional(convertTypeReference(itemType)), + nullable: (itemType) => IrVersions.V54.types.ContainerType.optional(convertTypeReference(itemType)), + set: (itemType) => IrVersions.V54.types.ContainerType.set(convertTypeReference(itemType)), + map: ({ keyType, valueType }) => + IrVersions.V54.types.ContainerType.map({ + keyType: convertTypeReference(keyType), + valueType: convertTypeReference(valueType) + }), + literal: IrVersions.V54.types.ContainerType.literal, + _other: () => { + throw new Error("Unknown ContainerType: " + container.type); + } + }); +} + +function convertSingleUnionType( + singleUnionType: IrVersions.V55.types.SingleUnionType +): IrVersions.V54.types.SingleUnionType { + return { + ...singleUnionType, + shape: convertSingleUnionTypeProperties(singleUnionType.shape) + }; +} + +function convertSingleUnionTypeProperties( + properties: IrVersions.V55.types.SingleUnionTypeProperties +): IrVersions.V54.types.SingleUnionTypeProperties { + return IrVersions.V55.types.SingleUnionTypeProperties._visit( + properties, + { + samePropertiesAsObject: (declaredTypeName) => + IrVersions.V54.types.SingleUnionTypeProperties.samePropertiesAsObject(declaredTypeName), + singleProperty: (singleProperty) => + IrVersions.V54.types.SingleUnionTypeProperties.singleProperty({ + ...singleProperty, + type: convertTypeReference(singleProperty.type) + }), + noProperties: IrVersions.V54.types.SingleUnionTypeProperties.noProperties, + _other: () => { + throw new Error(`Unknown SingleUnionTypeProperties: ${JSON.stringify(properties)}`); + } + } + ); +} + +function convertResolvedType( + resolvedType: IrVersions.V55.types.ResolvedTypeReference +): IrVersions.V54.types.ResolvedTypeReference { + return IrVersions.V55.types.ResolvedTypeReference._visit(resolvedType, { + container: (container) => IrVersions.V54.types.ResolvedTypeReference.container(convertContainerType(container)), + named: IrVersions.V54.types.ResolvedTypeReference.named, + primitive: (primitiveType) => + IrVersions.V54.types.ResolvedTypeReference.primitive(convertPrimitiveType(primitiveType)), + unknown: IrVersions.V54.types.ResolvedTypeReference.unknown, + _other: () => { + throw new Error("Unknown ResolvedTypeReference: " + resolvedType.type); + } + }); +} + +function convertUndiscriminatedUnion( + undiscriminatedUnion: IrVersions.V55.types.UndiscriminatedUnionTypeDeclaration +): IrVersions.V54.types.UndiscriminatedUnionTypeDeclaration { + return { + members: undiscriminatedUnion.members.map((member) => { + return { + ...member, + type: convertTypeReference(member.type) + }; + }) + }; +} + +function convertHttpService(service: IrVersions.V55.http.HttpService): IrVersions.V54.http.HttpService { + return { + ...service, + pathParameters: service.pathParameters.map((pathParameter) => convertPathParameter(pathParameter)), + headers: service.headers.map((header) => convertHttpHeader(header)), + endpoints: service.endpoints.map((endpoint) => convertEndpoint(endpoint)) + }; +} + +function convertPathParameter(pathParameter: IrVersions.V55.http.PathParameter): IrVersions.V54.http.PathParameter { + return { + ...pathParameter, + valueType: convertTypeReference(pathParameter.valueType) + }; +} + +function convertVariable(variable: IrVersions.V55.VariableDeclaration): IrVersions.V54.VariableDeclaration { + return { + ...variable, + type: convertTypeReference(variable.type) + }; +} + +function convertEndpoint(endpoint: IrVersions.V55.http.HttpEndpoint): IrVersions.V54.http.HttpEndpoint { + return { + ...endpoint, + pagination: endpoint.pagination != null ? convertPagination(endpoint.pagination) : undefined, + allPathParameters: endpoint.allPathParameters.map((pathParameter) => convertPathParameter(pathParameter)), + pathParameters: endpoint.pathParameters.map((pathParameter) => convertPathParameter(pathParameter)), + sdkRequest: endpoint.sdkRequest != null ? convertSdkRequest(endpoint.sdkRequest) : undefined, + requestBody: endpoint.requestBody != null ? convertRequestBody(endpoint.requestBody) : undefined, + response: endpoint.response != null ? convertHttpResponse(endpoint.response) : undefined, + headers: endpoint.headers.map((header) => convertHttpHeader(header)), + queryParameters: endpoint.queryParameters.map((queryParameter) => convertQueryParameter(queryParameter)), + autogeneratedExamples: endpoint.autogeneratedExamples.map((autogeneratedExample) => ({ + ...autogeneratedExample, + example: convertExampleEndpointCall(autogeneratedExample.example) + })), + userSpecifiedExamples: endpoint.userSpecifiedExamples.map((userSpecifiedExample) => ({ + ...userSpecifiedExample, + example: + userSpecifiedExample.example != null + ? convertExampleEndpointCall(userSpecifiedExample.example) + : undefined + })) + }; +} + +function convertHttpResponse(response: IrVersions.V55.http.HttpResponse): IrVersions.V54.http.HttpResponse { + return { + ...response, + body: response.body != null ? convertResponseBody(response.body) : undefined + }; +} + +function convertResponseBody(responseBody: IrVersions.V55.http.HttpResponseBody): IrVersions.V54.http.HttpResponseBody { + switch (responseBody.type) { + case "json": + return IrVersions.V54.http.HttpResponseBody.json(convertJsonResponse(responseBody.value)); + case "fileDownload": + return IrVersions.V54.http.HttpResponseBody.fileDownload(responseBody); + case "bytes": + return IrVersions.V54.http.HttpResponseBody.bytes(responseBody); + case "text": + return IrVersions.V54.http.HttpResponseBody.text(responseBody); + case "streaming": + return IrVersions.V54.http.HttpResponseBody.streaming(convertStreamingResponse(responseBody.value)); + case "streamParameter": + return IrVersions.V54.http.HttpResponseBody.streamParameter(convertStreamParameter(responseBody)); + default: + assertNever(responseBody); + } +} + +function convertJsonResponse(jsonResponse: IrVersions.V55.http.JsonResponse): IrVersions.V54.http.JsonResponse { + switch (jsonResponse.type) { + case "response": + return IrVersions.V54.http.JsonResponse.response({ + ...jsonResponse, + responseBodyType: convertTypeReference(jsonResponse.responseBodyType) + }); + case "nestedPropertyAsResponse": + return IrVersions.V54.http.JsonResponse.nestedPropertyAsResponse({ + ...jsonResponse, + responseBodyType: convertTypeReference(jsonResponse.responseBodyType), + responseProperty: + jsonResponse.responseProperty != null + ? convertObjectProperty(jsonResponse.responseProperty) + : undefined + }); + } +} + +function convertStreamingResponse( + streamingResponse: IrVersions.V55.http.StreamingResponse +): IrVersions.V54.http.StreamingResponse { + switch (streamingResponse.type) { + case "json": + return IrVersions.V54.http.StreamingResponse.json({ + ...streamingResponse, + payload: convertTypeReference(streamingResponse.payload) + }); + case "text": + return IrVersions.V54.http.StreamingResponse.text(streamingResponse); + case "sse": + return IrVersions.V54.http.StreamingResponse.sse({ + ...streamingResponse, + payload: convertTypeReference(streamingResponse.payload) + }); + } +} + +function convertNonStreamHttpResponse( + nonStreamingResponse: IrVersions.V55.http.NonStreamHttpResponseBody +): IrVersions.V54.http.NonStreamHttpResponseBody { + switch (nonStreamingResponse.type) { + case "json": + return IrVersions.V54.http.NonStreamHttpResponseBody.json(convertJsonResponse(nonStreamingResponse.value)); + case "bytes": + return IrVersions.V54.http.NonStreamHttpResponseBody.bytes(nonStreamingResponse); + case "text": + return IrVersions.V54.http.NonStreamHttpResponseBody.text(nonStreamingResponse); + case "fileDownload": + return IrVersions.V54.http.NonStreamHttpResponseBody.fileDownload(nonStreamingResponse); + default: + assertNever(nonStreamingResponse); + } +} + +function convertStreamParameter( + streamingResponse: IrVersions.V55.http.StreamParameterResponse +): IrVersions.V54.http.StreamParameterResponse { + return { + nonStreamResponse: convertNonStreamHttpResponse(streamingResponse.nonStreamResponse), + streamResponse: convertStreamingResponse(streamingResponse.streamResponse) + }; +} + +function convertPagination(pagination: IrVersions.V55.http.Pagination): IrVersions.V54.http.Pagination { + switch (pagination.type) { + case "cursor": + return IrVersions.V54.http.Pagination.cursor(convertCursorPagination(pagination)); + case "offset": + return IrVersions.V54.http.Pagination.offset(convertOffsetPagination(pagination)); + } +} + +function convertCursorPagination( + cursorPagination: IrVersions.V55.http.CursorPagination +): IrVersions.V54.http.CursorPagination { + return { + ...cursorPagination, + page: convertRequestProperty(cursorPagination.page), + next: convertResponseProperty(cursorPagination.next), + results: convertResponseProperty(cursorPagination.results) + }; +} + +function convertOffsetPagination( + offsetPagination: IrVersions.V55.http.OffsetPagination +): IrVersions.V54.http.OffsetPagination { + return { + ...offsetPagination, + page: convertRequestProperty(offsetPagination.page), + results: convertResponseProperty(offsetPagination.results), + step: offsetPagination.step != null ? convertRequestProperty(offsetPagination.step) : undefined, + hasNextPage: + offsetPagination.hasNextPage != null ? convertResponseProperty(offsetPagination.hasNextPage) : undefined + }; +} + +function convertRequestProperty( + requestProperty: IrVersions.V55.http.RequestProperty +): IrVersions.V54.http.RequestProperty { + return { + ...requestProperty, + property: convertRequestPropertValue(requestProperty.property) + }; +} + +function convertRequestPropertValue( + requestPropertyValue: IrVersions.V55.http.RequestPropertyValue +): IrVersions.V54.http.RequestPropertyValue { + switch (requestPropertyValue.type) { + case "query": + return IrVersions.V54.RequestPropertyValue.query(convertQueryParameter(requestPropertyValue)); + case "body": + return IrVersions.V54.RequestPropertyValue.body(convertObjectProperty(requestPropertyValue)); + } +} + +function convertResponseProperty( + responseProperty: IrVersions.V55.http.ResponseProperty +): IrVersions.V54.http.ResponseProperty { + return { + ...responseProperty, + property: convertObjectProperty(responseProperty.property) + }; +} + +function convertObjectProperty( + objectProperty: IrVersions.V55.types.ObjectProperty +): IrVersions.V54.types.ObjectProperty { + return { + ...objectProperty, + valueType: convertTypeReference(objectProperty.valueType) + }; +} + +function convertQueryParameter(queryParameter: IrVersions.V55.http.QueryParameter): IrVersions.V54.http.QueryParameter { + return { + ...queryParameter, + valueType: convertTypeReference(queryParameter.valueType) + }; +} + +function convertSdkRequest(sdkRequest: IrVersions.V55.http.SdkRequest): IrVersions.V54.http.SdkRequest { + return { + ...sdkRequest, + streamParameter: + sdkRequest.streamParameter != null ? convertRequestProperty(sdkRequest.streamParameter) : undefined, + shape: convertSdkRequestShape(sdkRequest.shape) + }; +} + +function convertSdkRequestShape(shape: IrVersions.V55.http.SdkRequestShape): IrVersions.V54.http.SdkRequestShape { + return IrVersions.V55.http.SdkRequestShape._visit(shape, { + justRequestBody: (reference) => + IrVersions.V54.http.SdkRequestShape.justRequestBody(convertSdkRequestBodyType(reference)), + wrapper: IrVersions.V54.http.SdkRequestShape.wrapper, + _other: () => { + throw new Error("Unknown SdkRequestShape: " + shape.type); + } + }); +} + +function convertSdkRequestBodyType( + shape: IrVersions.V55.http.SdkRequestBodyType +): IrVersions.V54.http.SdkRequestBodyType { + switch (shape.type) { + case "bytes": + return IrVersions.V54.http.SdkRequestBodyType.bytes(shape); + case "typeReference": + return IrVersions.V54.http.SdkRequestBodyType.typeReference({ + ...shape, + requestBodyType: convertTypeReference(shape.requestBodyType) + }); + } +} + +function convertRequestBody(requestBody: IrVersions.V55.http.HttpRequestBody): IrVersions.V54.http.HttpRequestBody { + return IrVersions.V55.http.HttpRequestBody._visit(requestBody, { + inlinedRequestBody: (inlinedRequestBody) => + IrVersions.V54.http.HttpRequestBody.inlinedRequestBody({ + ...inlinedRequestBody, + properties: inlinedRequestBody.properties.map((property) => ({ + ...property, + valueType: convertTypeReference(property.valueType) + })), + extendedProperties: inlinedRequestBody.extendedProperties?.map((property) => ({ + ...property, + valueType: convertTypeReference(property.valueType) + })) + }), + reference: (reference) => + IrVersions.V54.http.HttpRequestBody.reference({ + ...reference, + requestBodyType: convertTypeReference(reference.requestBodyType) + }), + fileUpload: (fileUpload) => + IrVersions.V54.http.HttpRequestBody.fileUpload({ + ...fileUpload, + properties: fileUpload.properties.map((fileUploadRequestProperty) => { + switch (fileUploadRequestProperty.type) { + case "bodyProperty": + return IrVersions.V54.http.FileUploadRequestProperty.bodyProperty({ + ...fileUploadRequestProperty, + valueType: convertTypeReference(fileUploadRequestProperty.valueType) + }); + case "file": + return IrVersions.V54.http.FileUploadRequestProperty.file( + convertFileProperty(fileUploadRequestProperty.value) + ); + } + }) + }), + bytes: (bytes) => { + return IrVersions.V54.http.HttpRequestBody.bytes(bytes); + }, + _other: () => { + throw new Error("Unknown HttpRequestBody: " + requestBody.type); + } + }); +} + +function convertFileProperty(fileProperty: IrVersions.V55.http.FileProperty): IrVersions.V54.http.FileProperty { + switch (fileProperty.type) { + case "file": + return IrVersions.V54.http.FileProperty.file(fileProperty); + case "fileArray": + return IrVersions.V54.http.FileProperty.fileArray(fileProperty); + } +} + +function convertErrorDeclaration( + error: IrVersions.V55.errors.ErrorDeclaration +): IrVersions.V54.errors.ErrorDeclaration { + return { + ...error, + type: error.type != null ? convertTypeReference(error.type) : undefined, + examples: error.examples.map((example) => ({ + ...example, + shape: convertExampleTypeReference(example.shape) + })) + }; +} + +function convertExampleWebsocketSession( + example: IrVersions.V55.ExampleWebSocketSession +): IrVersions.V54.ExampleWebSocketSession { + return { + ...example, + pathParameters: example.pathParameters.map((pathParameter) => convertExamplePathParameter(pathParameter)), + headers: example.headers.map((exampleHeader) => convertExampleHeader(exampleHeader)), + queryParameters: example.queryParameters.map((exampleQueryParameter) => + convertExampleQueryParameter(exampleQueryParameter) + ), + messages: example.messages.map((message) => ({ + ...message, + body: convertExampleWebSocketMessageBody(message.body) + })) + }; +} + +function convertExampleQueryParameter( + exampleQueryParameter: IrVersions.V55.ExampleQueryParameter +): IrVersions.V54.ExampleQueryParameter { + return { + ...exampleQueryParameter, + value: convertExampleTypeReference(exampleQueryParameter.value) + }; +} + +function convertExampleHeader(exampleHeader: IrVersions.V55.ExampleHeader): IrVersions.V54.ExampleHeader { + return { + ...exampleHeader, + value: convertExampleTypeReference(exampleHeader.value) + }; +} + +function convertExamplePathParameter( + pathParameter: IrVersions.V55.ExamplePathParameter +): IrVersions.V54.ExamplePathParameter { + return { + ...pathParameter, + value: convertExampleTypeReference(pathParameter.value) + }; +} + +function convertExampleWebSocketMessageBody( + body: IrVersions.V55.ExampleWebSocketMessageBody +): IrVersions.V54.ExampleWebSocketMessageBody { + switch (body.type) { + case "inlinedBody": + return IrVersions.V54.ExampleWebSocketMessageBody.inlinedBody(convertExampleInlinedRequestBody(body)); + case "reference": + return IrVersions.V54.ExampleWebSocketMessageBody.reference(convertExampleTypeReference(body)); + } +} + +function convertExampleInlinedRequestBody( + inlinedBody: IrVersions.V55.ExampleInlinedRequestBody +): IrVersions.V54.ExampleInlinedRequestBody { + return { + ...inlinedBody, + properties: inlinedBody.properties.map((property) => ({ + ...property, + value: convertExampleTypeReference(property.value) + })) + }; +} + +function convertExampleType(example: IrVersions.V55.ExampleType): IrVersions.V54.ExampleType { + return { + ...example, + shape: convertExampleTypeShape(example.shape) + }; +} + +function convertExampleTypeReferenceShape( + shape: IrVersions.V55.ExampleTypeReferenceShape +): IrVersions.V54.ExampleTypeReferenceShape { + switch (shape.type) { + case "primitive": + return IrVersions.V54.ExampleTypeReferenceShape.primitive(convertExamplePrimitiveTypeReferenceShape(shape)); + case "container": + return IrVersions.V54.ExampleTypeReferenceShape.container(convertExampleContainerTypeReferenceShape(shape)); + case "unknown": + return IrVersions.V54.ExampleTypeReferenceShape.unknown(shape.unknown); + case "named": + return IrVersions.V54.ExampleTypeReferenceShape.named({ + ...shape, + typeName: shape.typeName, + shape: convertExampleTypeShape(shape.shape) + }); + } +} + +function convertExamplePrimitive(primitive: IrVersions.V55.ExamplePrimitive): IrVersions.V54.ExamplePrimitive { + return primitive; +} + +function convertExamplePrimitiveTypeReferenceShape( + shape: IrVersions.V55.ExampleTypeReferenceShape.Primitive +): IrVersions.V54.ExamplePrimitive { + return convertExamplePrimitive(shape.primitive); +} + +function convertExampleContainerTypeReferenceShape( + shape: IrVersions.V55.ExampleTypeReferenceShape.Container +): IrVersions.V54.ExampleContainer { + switch (shape.container.type) { + case "list": + return IrVersions.V54.ExampleContainer.list({ + list: shape.container.list.map((exampleTypeReference) => + convertExampleTypeReference(exampleTypeReference) + ), + itemType: convertTypeReference(shape.container.itemType) + }); + case "set": + return IrVersions.V54.ExampleContainer.set({ + set: shape.container.set.map((exampleTypeReference) => + convertExampleTypeReference(exampleTypeReference) + ), + itemType: convertTypeReference(shape.container.itemType) + }); + case "optional": + return IrVersions.V54.ExampleContainer.optional({ + optional: + shape.container.optional != null + ? convertExampleTypeReference(shape.container.optional) + : undefined, + valueType: convertTypeReference(shape.container.valueType) + }); + case "nullable": + return IrVersions.V54.ExampleContainer.optional({ + optional: + shape.container.nullable != null + ? convertExampleTypeReference(shape.container.nullable) + : undefined, + valueType: convertTypeReference(shape.container.valueType) + }); + case "map": + return IrVersions.V54.ExampleContainer.map({ + map: shape.container.map.map((exampleKeyValuePair) => ({ + key: convertExampleTypeReference(exampleKeyValuePair.key), + value: convertExampleTypeReference(exampleKeyValuePair.value) + })), + keyType: convertTypeReference(shape.container.keyType), + valueType: convertTypeReference(shape.container.valueType) + }); + case "literal": + return IrVersions.V54.ExampleContainer.literal({ + literal: convertExamplePrimitive(shape.container.literal) + }); + } +} + +function convertExampleTypeReference( + exampleTypeReference: IrVersions.V55.ExampleTypeReference +): IrVersions.V54.ExampleTypeReference { + return { + ...exampleTypeReference, + shape: convertExampleTypeReferenceShape(exampleTypeReference.shape) + }; +} + +function convertExampleTypeShape(shape: IrVersions.V55.ExampleTypeShape): IrVersions.V54.ExampleTypeShape { + switch (shape.type) { + case "object": + return IrVersions.V54.ExampleTypeShape.object({ + properties: shape.properties.map((property) => convertExampleObjectProperty(property)) + }); + case "alias": + return IrVersions.V54.ExampleTypeShape.alias({ + value: { ...convertExampleTypeReference(shape.value) } + }); + case "enum": + return IrVersions.V54.ExampleTypeShape.enum(shape); + case "union": + return IrVersions.V54.ExampleTypeShape.union(convertUnionExampleTypeShape(shape)); + case "undiscriminatedUnion": + return IrVersions.V54.ExampleTypeShape.undiscriminatedUnion( + convertUndiscriminatedUnionExampleTypeShape(shape) + ); + } +} + +function convertUndiscriminatedUnionExampleTypeShape( + shape: IrVersions.V55.ExampleTypeShape.UndiscriminatedUnion +): IrVersions.V54.ExampleUndiscriminatedUnionType { + return { + ...shape, + singleUnionType: convertExampleTypeReference(shape.singleUnionType) + }; +} + +function convertUnionExampleTypeShape(shape: IrVersions.V55.ExampleTypeShape.Union): IrVersions.V54.ExampleUnionType { + return { + ...shape, + singleUnionType: convertExampleSingleUnionType(shape.singleUnionType) + }; +} + +function convertExampleSingleUnionType( + singleUnionType: IrVersions.V55.ExampleSingleUnionType +): IrVersions.V54.ExampleSingleUnionType { + return { + ...singleUnionType, + shape: convertExampleSingleUnionTypeProperties(singleUnionType.shape) + }; +} + +function convertExampleSingleUnionTypeProperties( + exampleSingleUnionTypeProperties: IrVersions.V55.ExampleSingleUnionTypeProperties +): IrVersions.V54.ExampleSingleUnionTypeProperties { + switch (exampleSingleUnionTypeProperties.type) { + case "samePropertiesAsObject": + return IrVersions.V54.ExampleSingleUnionTypeProperties.samePropertiesAsObject({ + ...exampleSingleUnionTypeProperties, + object: convertExampleObjectType(exampleSingleUnionTypeProperties.object) + }); + case "singleProperty": + return IrVersions.V54.ExampleSingleUnionTypeProperties.singleProperty({ + ...exampleSingleUnionTypeProperties, + shape: convertExampleTypeReferenceShape(exampleSingleUnionTypeProperties.shape) + }); + case "noProperties": + return IrVersions.V54.ExampleSingleUnionTypeProperties.noProperties(); + } +} + +function convertExampleObjectType(object: IrVersions.V55.ExampleObjectType): IrVersions.V54.ExampleObjectType { + return { + ...object, + properties: object.properties.map((property) => convertExampleObjectProperty(property)) + }; +} + +function convertExampleObjectProperty( + property: IrVersions.V55.ExampleObjectProperty +): IrVersions.V54.ExampleObjectProperty { + return { + ...property, + value: { + ...property.value, + shape: convertExampleTypeReferenceShape(property.value.shape) + } + }; +} + +function convertExampleEndpointCall(example: IrVersions.V55.ExampleEndpointCall): IrVersions.V54.ExampleEndpointCall { + return { + ...example, + rootPathParameters: example.rootPathParameters.map((examplePathParameter) => + convertExamplePathParameter(examplePathParameter) + ), + servicePathParameters: example.servicePathParameters.map((examplePathParameter) => + convertExamplePathParameter(examplePathParameter) + ), + endpointPathParameters: example.endpointPathParameters.map((examplePathParameter) => + convertExamplePathParameter(examplePathParameter) + ), + serviceHeaders: example.serviceHeaders.map((exampleHeader) => convertExampleHeader(exampleHeader)), + endpointHeaders: example.endpointHeaders.map((exampleHeader) => convertExampleHeader(exampleHeader)), + queryParameters: example.queryParameters.map((exampleQueryParameter) => + convertExampleQueryParameter(exampleQueryParameter) + ), + request: example.request != null ? convertExampleRequest(example.request) : undefined, + response: convertExampleResponse(example.response) + }; +} + +function convertExampleResponse(response: IrVersions.V55.ExampleResponse): IrVersions.V54.ExampleResponse { + switch (response.type) { + case "error": + return IrVersions.V54.ExampleResponse.error({ + ...response, + body: response.body != null ? convertExampleTypeReference(response.body) : undefined + }); + case "ok": + return IrVersions.V54.ExampleResponse.ok(convertExampleEndpointSuccessResponse(response)); + } +} + +function convertExampleEndpointSuccessResponse( + response: IrVersions.V55.ExampleResponse.Ok +): IrVersions.V54.ExampleEndpointSuccessResponse { + switch (response.value.type) { + case "body": + return IrVersions.V54.ExampleEndpointSuccessResponse.body( + response.value.value != null ? convertExampleTypeReference(response.value.value) : undefined + ); + case "stream": + return IrVersions.V54.ExampleEndpointSuccessResponse.stream( + response.value.value.map((exampleTypeReference) => convertExampleTypeReference(exampleTypeReference)) + ); + case "sse": + return IrVersions.V54.ExampleEndpointSuccessResponse.sse( + response.value.value.map((exampleServerSideEvent) => ({ + ...exampleServerSideEvent, + data: convertExampleTypeReference(exampleServerSideEvent.data) + })) + ); + } +} + +function convertExampleRequest(request: IrVersions.V55.ExampleRequestBody): IrVersions.V54.ExampleRequestBody { + switch (request.type) { + case "inlinedRequestBody": + return IrVersions.V54.ExampleRequestBody.inlinedRequestBody(convertExampleInlinedRequestBody(request)); + case "reference": + return IrVersions.V54.ExampleRequestBody.reference(convertExampleTypeReference(request)); + } +} + +function convertDynamic( + dynamic: IrVersions.V55.dynamic.DynamicIntermediateRepresentation +): IrVersions.V54.dynamic.DynamicIntermediateRepresentation { + return { + ...dynamic, + types: mapValues(dynamic.types, (type) => convertDynamicType(type)), + endpoints: mapValues(dynamic.endpoints, (endpoint) => convertDynamicEndpoint(endpoint)), + headers: dynamic.headers?.map((header) => convertDynamicNamedParameter(header)) + }; +} + +function convertDynamicType(type: IrVersions.V55.dynamic.NamedType): IrVersions.V54.dynamic.NamedType { + switch (type.type) { + case "alias": + return IrVersions.V54.dynamic.NamedType.alias({ + ...type, + typeReference: convertDynamicTypeReference(type.typeReference) + }); + case "enum": + return IrVersions.V54.dynamic.NamedType.enum(type); + case "object": + return IrVersions.V54.dynamic.NamedType.object({ + ...type, + properties: type.properties.map((property) => convertDynamicNamedParameter(property)) + }); + case "discriminatedUnion": + return IrVersions.V54.dynamic.NamedType.discriminatedUnion({ + ...type, + types: Object.fromEntries( + Object.entries(type.types).map(([discriminant, type]) => [ + discriminant, + convertDynamicSingleDiscriminatedUnionType(type) + ]) + ) + }); + case "undiscriminatedUnion": + return IrVersions.V54.dynamic.NamedType.undiscriminatedUnion({ + ...type, + types: type.types.map((type) => convertDynamicTypeReference(type)) + }); + default: + assertNever(type); + } +} + +function convertDynamicEndpoint(endpoint: IrVersions.V55.dynamic.Endpoint): IrVersions.V54.dynamic.Endpoint { + return { + ...endpoint, + auth: endpoint.auth != null ? convertDynamicAuth(endpoint.auth) : undefined, + request: convertDynamicRequest(endpoint.request) + }; +} + +function convertDynamicAuth(auth: IrVersions.V55.dynamic.Auth): IrVersions.V54.dynamic.Auth { + switch (auth.type) { + case "basic": + return IrVersions.V54.dynamic.Auth.basic(auth); + case "bearer": + return IrVersions.V54.dynamic.Auth.bearer(auth); + case "header": + return IrVersions.V54.dynamic.Auth.header({ + header: convertDynamicNamedParameter(auth.header) + }); + } +} + +function convertDynamicTypeReference( + typeReference: IrVersions.V55.dynamic.TypeReference +): IrVersions.V54.dynamic.TypeReference { + switch (typeReference.type) { + case "list": + return IrVersions.V54.dynamic.TypeReference.list(convertDynamicTypeReference(typeReference.value)); + case "optional": + return IrVersions.V54.dynamic.TypeReference.optional(convertDynamicTypeReference(typeReference.value)); + case "nullable": + return IrVersions.V54.dynamic.TypeReference.optional(convertDynamicTypeReference(typeReference.value)); + case "map": + return IrVersions.V54.dynamic.TypeReference.map({ + ...typeReference, + key: convertDynamicTypeReference(typeReference.key), + value: convertDynamicTypeReference(typeReference.value) + }); + case "literal": + return IrVersions.V54.dynamic.TypeReference.literal(typeReference.value); + case "named": + return IrVersions.V54.dynamic.TypeReference.named(typeReference.value); + case "primitive": + return IrVersions.V54.dynamic.TypeReference.primitive(typeReference.value); + case "set": + return IrVersions.V54.dynamic.TypeReference.set(convertDynamicTypeReference(typeReference.value)); + case "unknown": + return IrVersions.V54.dynamic.TypeReference.unknown(); + default: + assertNever(typeReference); + } +} + +function convertDynamicSingleDiscriminatedUnionType( + singleDiscriminatedUnionType: IrVersions.V55.dynamic.SingleDiscriminatedUnionType +): IrVersions.V54.dynamic.SingleDiscriminatedUnionType { + switch (singleDiscriminatedUnionType.type) { + case "samePropertiesAsObject": + return IrVersions.V54.dynamic.SingleDiscriminatedUnionType.samePropertiesAsObject({ + ...singleDiscriminatedUnionType, + properties: singleDiscriminatedUnionType.properties.map((property) => + convertDynamicNamedParameter(property) + ) + }); + case "singleProperty": + return IrVersions.V54.dynamic.SingleDiscriminatedUnionType.singleProperty({ + ...singleDiscriminatedUnionType, + typeReference: convertDynamicTypeReference(singleDiscriminatedUnionType.typeReference), + properties: singleDiscriminatedUnionType.properties?.map((property) => + convertDynamicNamedParameter(property) + ) + }); + case "noProperties": + return IrVersions.V54.dynamic.SingleDiscriminatedUnionType.noProperties({ + ...singleDiscriminatedUnionType, + properties: singleDiscriminatedUnionType.properties?.map((property) => + convertDynamicNamedParameter(property) + ) + }); + default: + assertNever(singleDiscriminatedUnionType); + } +} + +function convertDynamicNamedParameter( + namedParameter: IrVersions.V55.dynamic.NamedParameter +): IrVersions.V54.dynamic.NamedParameter { + return { + ...namedParameter, + typeReference: convertDynamicTypeReference(namedParameter.typeReference) + }; +} + +function convertDynamicRequest(request: IrVersions.V55.dynamic.Request): IrVersions.V54.dynamic.Request { + switch (request.type) { + case "body": + return IrVersions.V54.dynamic.Request.body(convertDynamicRequestBody(request)); + case "inlined": + return IrVersions.V54.dynamic.Request.inlined(convertDynamicInlinedRequest(request)); + default: + assertNever(request); + } +} + +function convertDynamicRequestBody( + bodyRequest: IrVersions.V55.dynamic.BodyRequest +): IrVersions.V54.dynamic.BodyRequest { + return { + pathParameters: bodyRequest.pathParameters?.map((pathParameter) => convertDynamicNamedParameter(pathParameter)), + body: bodyRequest.body != null ? convertDynamicRequestBodyType(bodyRequest.body) : undefined + }; +} + +function convertDynamicInlinedRequest( + inlinedRequest: IrVersions.V55.dynamic.InlinedRequest +): IrVersions.V54.dynamic.InlinedRequest { + return { + ...inlinedRequest, + pathParameters: inlinedRequest.pathParameters?.map((pathParameter) => + convertDynamicNamedParameter(pathParameter) + ), + queryParameters: inlinedRequest.queryParameters?.map((queryParameter) => + convertDynamicNamedParameter(queryParameter) + ), + headers: inlinedRequest.headers?.map((header) => convertDynamicNamedParameter(header)), + body: inlinedRequest.body != null ? convertDynamicInlinedRequestBody(inlinedRequest.body) : undefined + }; +} + +function convertDynamicInlinedRequestBody( + inlinedRequestBody: IrVersions.V55.dynamic.InlinedRequestBody +): IrVersions.V54.dynamic.InlinedRequestBody { + switch (inlinedRequestBody.type) { + case "properties": + return IrVersions.V54.dynamic.InlinedRequestBody.properties( + inlinedRequestBody.value.map((property) => convertDynamicNamedParameter(property)) + ); + case "referenced": + return IrVersions.V54.dynamic.InlinedRequestBody.referenced( + convertDynamicReferencedRequestBody(inlinedRequestBody) + ); + case "fileUpload": + return IrVersions.V54.dynamic.InlinedRequestBody.fileUpload( + convertFileUploadRequestBody(inlinedRequestBody) + ); + default: + assertNever(inlinedRequestBody); + } +} + +function convertDynamicReferencedRequestBody( + referencedRequestBody: IrVersions.V55.dynamic.ReferencedRequestBody +): IrVersions.V54.dynamic.ReferencedRequestBody { + return { + ...referencedRequestBody, + bodyType: convertDynamicRequestBodyType(referencedRequestBody.bodyType) + }; +} + +function convertDynamicRequestBodyType( + requestBodyType: IrVersions.V55.dynamic.ReferencedRequestBodyType +): IrVersions.V54.dynamic.ReferencedRequestBodyType { + switch (requestBodyType.type) { + case "bytes": + return IrVersions.V54.dynamic.ReferencedRequestBodyType.bytes(); + case "typeReference": + return IrVersions.V54.dynamic.ReferencedRequestBodyType.typeReference( + convertDynamicTypeReference(requestBodyType.value) + ); + default: + assertNever(requestBodyType); + } +} + +function convertFileUploadRequestBody( + fileUploadRequestBody: IrVersions.V55.dynamic.FileUploadRequestBody +): IrVersions.V54.dynamic.FileUploadRequestBody { + return { + properties: fileUploadRequestBody.properties.map((property) => + convertDynamicFileUploadRequestBodyProperty(property) + ) + }; +} + +function convertDynamicFileUploadRequestBodyProperty( + fileUploadRequestBodyProperty: IrVersions.V55.dynamic.FileUploadRequestBodyProperty +): IrVersions.V54.dynamic.FileUploadRequestBodyProperty { + switch (fileUploadRequestBodyProperty.type) { + case "file": + return IrVersions.V54.dynamic.FileUploadRequestBodyProperty.file(fileUploadRequestBodyProperty); + case "fileArray": + return IrVersions.V54.dynamic.FileUploadRequestBodyProperty.fileArray(fileUploadRequestBodyProperty); + case "bodyProperty": + return IrVersions.V54.dynamic.FileUploadRequestBodyProperty.bodyProperty( + convertDynamicNamedParameter(fileUploadRequestBodyProperty) + ); + default: + assertNever(fileUploadRequestBodyProperty); + } +} diff --git a/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/go/DynamicSnippetsGoTestGenerator.ts b/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/go/DynamicSnippetsGoTestGenerator.ts index 3649f07f328..81d56fa5623 100644 --- a/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/go/DynamicSnippetsGoTestGenerator.ts +++ b/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/go/DynamicSnippetsGoTestGenerator.ts @@ -19,7 +19,8 @@ export class DynamicSnippetsGoTestGenerator { private readonly generatorConfig: FernGeneratorExec.GeneratorConfig ) { this.dynamicSnippetsGenerator = new DynamicSnippetsGenerator({ - ir: this.ir, + // TODO: Remove the any cast once the dynamic IR is updated w/ nullable support. + ir: this.ir as any, // eslint-disable-line @typescript-eslint/no-explicit-any config: this.generatorConfig }); } diff --git a/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/typescript/DynamicSnippetsTypeScriptTestGenerator.ts b/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/typescript/DynamicSnippetsTypeScriptTestGenerator.ts index 4f5d7325c40..f1fc874887d 100644 --- a/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/typescript/DynamicSnippetsTypeScriptTestGenerator.ts +++ b/packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/typescript/DynamicSnippetsTypeScriptTestGenerator.ts @@ -19,7 +19,8 @@ export class DynamicSnippetsTypeScriptTestGenerator { private readonly generatorConfig: FernGeneratorExec.GeneratorConfig ) { this.dynamicSnippetsGenerator = new DynamicSnippetsGenerator({ - ir: this.ir, + // TODO: Remove the any cast once the dynamic IR is updated w/ nullable support. + ir: this.ir as any, // eslint-disable-line @typescript-eslint/no-explicit-any config: this.buildGeneratorConfig(this.generatorConfig) }); } diff --git a/packages/cli/register/src/ir-to-fdr-converter/convertTypeShape.ts b/packages/cli/register/src/ir-to-fdr-converter/convertTypeShape.ts index f4b784e0d07..e78c239bfd1 100644 --- a/packages/cli/register/src/ir-to-fdr-converter/convertTypeShape.ts +++ b/packages/cli/register/src/ir-to-fdr-converter/convertTypeShape.ts @@ -145,6 +145,13 @@ export function convertTypeReference(irTypeReference: Ir.types.TypeReference): F defaultValue: undefined }; }, + nullable: (itemType) => { + return { + type: "optional", + itemType: convertTypeReference(itemType), + defaultValue: undefined + }; + }, set: (itemType) => { return { type: "set", diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/VERSION b/packages/ir-sdk/fern/apis/ir-types-latest/VERSION index 5a424af8585..b406fbef67e 100644 --- a/packages/ir-sdk/fern/apis/ir-types-latest/VERSION +++ b/packages/ir-sdk/fern/apis/ir-types-latest/VERSION @@ -1 +1 @@ -54.1.0 +55.0.0 diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md b/packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md index 00951a93941..d229db81af2 100644 --- a/packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md +++ b/packages/ir-sdk/fern/apis/ir-types-latest/changelog/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v55.0.0] - 2024-01-13 + +- Feature: The IR now supports `nullable` types to distinguish if a property should support explicit `null` values. ## [v54.1.0] - 2024-01-10 diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/definition/dynamic/types.yml b/packages/ir-sdk/fern/apis/ir-types-latest/definition/dynamic/types.yml index 635de0246ac..834888ad12c 100644 --- a/packages/ir-sdk/fern/apis/ir-types-latest/definition/dynamic/types.yml +++ b/packages/ir-sdk/fern/apis/ir-types-latest/definition/dynamic/types.yml @@ -24,6 +24,7 @@ types: literal: LiteralType map: MapType named: commons.TypeId + nullable: TypeReference optional: TypeReference primitive: root.PrimitiveTypeV1 set: TypeReference diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/definition/types.yml b/packages/ir-sdk/fern/apis/ir-types-latest/definition/types.yml index 48c0f173782..d2e7a87a923 100644 --- a/packages/ir-sdk/fern/apis/ir-types-latest/definition/types.yml +++ b/packages/ir-sdk/fern/apis/ir-types-latest/definition/types.yml @@ -192,6 +192,9 @@ types: type: TypeReference key: list map: MapType + nullable: + type: TypeReference + key: nullable optional: type: TypeReference key: optional @@ -404,6 +407,7 @@ types: list: ExampleListContainer set: ExampleSetContainer optional: ExampleOptionalContainer + nullable: ExampleNullableContainer map: ExampleMapContainer literal: ExampleLiteralContainer @@ -422,6 +426,11 @@ types: optional: optional valueType: TypeReference + ExampleNullableContainer: + properties: + nullable: optional + valueType: TypeReference + ExampleMapContainer: properties: map: list diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/generators.yml b/packages/ir-sdk/fern/apis/ir-types-latest/generators.yml index b17a7114e03..cbb10b09a0f 100644 --- a/packages/ir-sdk/fern/apis/ir-types-latest/generators.yml +++ b/packages/ir-sdk/fern/apis/ir-types-latest/generators.yml @@ -42,7 +42,7 @@ groups: output: location: maven url: maven.buildwithfern.com - coordinate: com.fern.fern:irV53 + coordinate: com.fern.fern:irV55 config: wrapped-aliases: true enable-forward-compatible-enums: true @@ -53,7 +53,7 @@ groups: output: location: pypi url: pypi.buildwithfern.com - package-name: fern_fern_ir_v53 + package-name: fern_fern_ir_v55 config: # wrapped_aliases: true include_union_utils: true diff --git a/packages/ir-sdk/fern/apis/ir-types-v53/changelog/CHANGELOG.md b/packages/ir-sdk/fern/apis/ir-types-v53/changelog/CHANGELOG.md deleted file mode 100644 index 34631de1847..00000000000 --- a/packages/ir-sdk/fern/apis/ir-types-v53/changelog/CHANGELOG.md +++ /dev/null @@ -1,221 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [v53.23.0] - 2024-11-04 - -- Internal: Update the Dynamic IR discriminator so that the generated types are unaffected - when `noSerdeLayer` is enabled. - -## [v53.22.0] - 2024-11-04 - -- Redacted: Use v53.23.0 instead. -- Internal: Add the `dynamic` property to the IR. This should be - made requried in IRv54. - -## [v53.21.0] - 2024-11-04 - -- Internal: Add the `includePathParameters` and `onlyPathParameters` properties to the dynamic - IR within the `InlinedRequestMetadata` type. - -## [v53.20.0] - 2024-11-04 - -- Internal: Add `includePathParameters` and `onlyPathParameters` property to the wrapped request. - - With this, the generator can determine whether or not the path parameters should be included in - the wrapped request, or if the wrapped request can be omitted entirely. - -## [v53.19.0] - 2024-11-04 - -- Internal: Add errors property to dynamic `EndpointSnippetResponse`. - -## [v53.18.0] - 2024-11-04 - -- Internal: Add `transport` to `HttpEndpoint`. `transport` on the endpoint overrides the `transport` on the `HttpService`. - -## [v53.17.0] - 2024-11-01 - -- Internal: Add dynamic audience to endpoint snippet request and response. - -## [v53.16.0] - 2024-10-31 - -- Internal: Publish @fern-api/dynamic-ir-sdk - -## [v53.15.0] - 2024-10-23 - -- Internal: Introduce dynamic IR types. - -## [v53.14.0] - 2024-10-16 - -- Feature: Add `inline` to type declarations so that generators can nest unnamed types. - -## [v53.13.0] - 2024-10-07 - -- Feature: Add `contentType` to file upload body properties. - -## [v53.12.0] - 2024-09-13 - -- Feature: Add `contentType` to file upload body properties. - -## [v53.11.0] - 2024-09-13 - -- Fix: Add `availability` to inline websocket, webhook, and http body parameter properties. - -## [v53.10.0] - 2024-09-12 - -- Feature: Add `display-name` to discriminated union values for use with displaying docs. - -## [v53.9.0] - 2024-08-29 (TODO: Make required in next major) - -- Feature: Introduce a `PublishingConfig` to the IR instead of trying to go through Fiddle. - -## [v53.8.0] - 2024-08-23 (TODO: Make required in next major) - -- Fix: Include the raw datetime alongside the parsed datetime in `ExamplePrimitive`. - -## [v53.7.2] - 2024-08-12 - -- Fix: Upgrade the Pydantic generator so that `enum_type` is set to `python_enums` - -## [v53.7.1] - 2024-08-12 - -- Fix: Upgrade the Pydantic generator so that `unknown` properties that are missing do not throw. - -## [v53.7.0] - 2024-08-12 - -- Improvement: The IR now contains a `shape` field on the `ExampleQueryParameter` type that denotes whether the parameter - allows multiple values, and if so, whether they should be comma-separated or exploded. - -## [v53.6.0] - 2024-08-05 - -- Internal: Bump to the latest typescript SDK generator. - -## [v53.5.0] - 2024-08-05 \*\* (TODO: Make required in next major) - -- Feature: Support a `hasNextPage` property for offset pagination. - -## [v53.4.0] - 2024-08-05 \*\* (TODO: Make required in next major) - -- Feature: Add `User-Agent` header so that SDK generators can start sending the user agent. - -## [v53.3.0] - 2024-08-05 - -- Feature: Add gRPC/Protobuf types (defined in `proto.yml`) to generate gRPC/Protobuf mappers. - -## [v53.2.0] - 2024-07-30 - -- Improvement: The IR now contains an `extendedProperties` field where all properties from extended types are denormalized. This removes logic - that generator authors were consistently reimplementing. - -## [v53.1.0] - 2024-07-30 - -- Improvement: The IR now contains the API Definition ID such that the generators may specify this ID when uploading snippet templates. This is necessary for resolving union snippets. - -## [v53.0.0] - 2024-07-30 - -- Feature: Add `float` and `bytes` primitive types. -- Feature: Add a `PrimitiveTypeV2` variant for every `PrimitiveTypeV1`. - -## [v52.0.0] - 2024-07-23 - -- Feature: Add `uint` and `uint64` primitive types. -- Feature: Add support for default enum values. -- Feature: Add support for in-lined type references (e.g. enums). - -## [v51.0.0] - 2024-07-18 - -- Improvement: Add `TypeReference`s to `ExampleContainer` types, especially helpful in the case of empty container - examples. -- Improvement: The `TypeDeclaration` type now has `userDefinedExamples` in place of the previous `example` field. It - also now has an `autogeneratedExamples` field that will be populated with autogenerated examples in a future PR. - -## [v50.2.0] - 2024-07-16 - -- Feature: Add `ApiVersionScheme`, which is used to model API version headers as an top-level enum. - -## [v50.1.0] - 2024-07-16 - -- No changes. - -## [v50.0.0] - 2024-06-20 - -- Improvement: add PrimitiveType V2 for Boolean, Long and Big Int types, allowing for default values to be specified - -## [v49.0.0] - 2024-06-20 - -- Feature: Support generating code with `stream` param for endpoints like chat completion. - -## [v48.1.0] - 2024-06-20 - -- Feature: Add an optional `introduction` field to the `ReadmeConfig`, which is configurable - in the user's `generators.yml`. - -## [v48.0.0] - 2024-06-17 - -- Fix: The unique webhook id is now required. -- Improvement: Pagination endpoints now support request body properties. -- Improvement: Offset pagination now supports a configurable `step` size request property, which - is useful for offset values that represent the element's global index (e.g. the 500th element), - rather than the page number (e.g the 5th page). - -## [v47.1.0] - 2024-06-09 - -- Fix: Introduce a unique id for all generated webhooks. This is being added as optional but should - be made required in v48. - -## [v47.0.0] - 2024-06-09 - -- Feature: Introduce `autogeneratedExamples` and `userProvidedExamples` fields on the HTTPEndpoint. In the - `userProvidedExample` its now possible for the user to only provide code samples and no structured - example with input and output. - - Generators should opt to use the code sample provided from the user if that is the case. - -## [v46.2.0] - 2024-06-09 - -- Feature: Add support for webhook examples. - -## [v46.1.1] - 2024-06-09 - -- Fix: Generate the Python SDK for IR using just pydantic v1 - -## [v46] - 2024-06-04 - -- Feature: Add support for README.md configuration. - -## [v45] - 2024-05-15 - -- Feature: Support `bigint` primitive types. -- Feature: Add support for default values and validation rules. - -## [v44] - 2024-05-10 - -- Improvement: Support stream and server-sent event response examples. - -## [v43] - 2024-05-08 - -- Improvement: Support custom status codes for success respones. - -## [v42] - 2024-05-07 - -- Improvement: Update OAuth customizability (e.g. configurable `clientId` property). - -## [v41] - 2024-05-07 - -- Feature: Add error examples. - -## [v40] - 2024-04-23 - -- Feature: Add support for extra properties on objects and in-lined requests. - -## [v39] - 2024-04-19 - -- Feature: Add support for OAuth client credentials flow. - -## [v38] - 2024-04-17 - -- Feature: Add support for Server-Sent-Events to Streaming HTTP Responses - Read more about SSE here: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events. diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/VERSION b/packages/ir-sdk/fern/apis/ir-types-v54/VERSION new file mode 100644 index 00000000000..89d18917ebe --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/VERSION @@ -0,0 +1 @@ +54.0.0 diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/api.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/api.yml new file mode 100644 index 00000000000..370fedef715 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/api.yml @@ -0,0 +1,3 @@ +name: ir-v54 +audiences: + - dynamic \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/auth.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/auth.yml new file mode 100644 index 00000000000..be4c49e7ff4 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/auth.yml @@ -0,0 +1,99 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + http: http.yml + types: types.yml + commons: commons.yml +types: + EnvironmentVariable: string + ApiAuth: + extends: commons.WithDocs + properties: + requirement: AuthSchemesRequirement + schemes: list + AuthSchemesRequirement: + enum: + - ALL + - ANY + AuthScheme: + discriminant: + value: _type + name: type + union: + bearer: BearerAuthScheme + basic: BasicAuthScheme + header: HeaderAuthScheme + oauth: OAuthScheme + BearerAuthScheme: + extends: commons.WithDocs + properties: + token: commons.Name + tokenEnvVar: + type: optional + docs: The environment variable the SDK should use to read the token. + + OAuthScheme: + extends: commons.WithDocs + docs: | + We currently assume the resultant token is leveraged as a bearer token, e.g. "Authorization Bearer" + properties: + configuration: OAuthConfiguration + OAuthConfiguration: + union: + clientCredentials: OAuthClientCredentials + OAuthClientCredentials: + properties: + clientIdEnvVar: optional + clientSecretEnvVar: optional + tokenPrefix: optional + tokenHeader: optional + scopes: optional> + tokenEndpoint: OAuthTokenEndpoint + refreshEndpoint: optional + OAuthTokenEndpoint: + properties: + endpointReference: commons.EndpointReference + requestProperties: OAuthAccessTokenRequestProperties + responseProperties: OAuthAccessTokenResponseProperties + OAuthRefreshEndpoint: + properties: + endpointReference: commons.EndpointReference + requestProperties: OAuthRefreshTokenRequestProperties + responseProperties: OAuthAccessTokenResponseProperties + OAuthAccessTokenRequestProperties: + docs: The properties required to retrieve an OAuth token. + properties: + clientId: http.RequestProperty + clientSecret: http.RequestProperty + scopes: optional + OAuthAccessTokenResponseProperties: + docs: The properties to map to the corresponding OAuth token primitive. + properties: + accessToken: http.ResponseProperty + expiresIn: optional + refreshToken: optional + OAuthRefreshTokenRequestProperties: + docs: The properties required to retrieve an OAuth refresh token. + properties: + refreshToken: http.RequestProperty + + BasicAuthScheme: + extends: commons.WithDocs + properties: + username: commons.Name + usernameEnvVar: + type: optional + docs: The environment variable the SDK should use to read the username. + password: commons.Name + passwordEnvVar: + type: optional + docs: The environment variable the SDK should use to read the password. + HeaderAuthScheme: + extends: commons.WithDocs + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + prefix: optional + headerEnvVar: + type: optional + docs: The environment variable the SDK should use to read the header. diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/commons.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/commons.yml new file mode 100644 index 00000000000..781c25fa1ce --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/commons.yml @@ -0,0 +1,93 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +types: + WithDocs: + properties: + docs: optional + WithDocsAndAvailability: + extends: WithDocs + properties: + availability: optional + FernFilepath: + properties: + allParts: list + packagePath: list + file: optional + + # names + + Name: + properties: + originalName: string + camelCase: SafeAndUnsafeString + pascalCase: SafeAndUnsafeString + snakeCase: SafeAndUnsafeString + screamingSnakeCase: SafeAndUnsafeString + NameAndWireValue: + properties: + wireValue: string + name: Name + SafeAndUnsafeString: + properties: + unsafeName: + docs: this name might overlap with reserved keywords of the language being + generated + type: string + safeName: + docs: this name will NOT overlap with reserved keywords of the language being + generated + type: string + EscapedString: + docs: | + Defines the original string, and its escaped-equivalent (depending on the target programming language). + This is paricularly relevant to example string literals. + + For example, in Python we escape strings that contain single or double quotes by using triple quotes, + in Go we use backticks, etc. + properties: + original: string + + WithJsonExample: + properties: + jsonExample: unknown + + # ids + + SubpackageId: string + ServiceId: string + EndpointId: string + TypeId: string + ErrorId: string + WebhookGroupId: string + WebhookId: string + WebSocketChannelId: string + FeatureId: string + + # declarations + + Declaration: + extends: WithDocs + properties: + availability: optional + Availability: + properties: + status: AvailabilityStatus + message: optional + AvailabilityStatus: + enum: + - IN_DEVELOPMENT + - PRE_RELEASE + - GENERAL_AVAILABILITY + - DEPRECATED + + # references + + EndpointReference: + properties: + endpointId: EndpointId + serviceId: ServiceId + subpackageId: + type: optional + docs: | + The subpackage that defines the endpoint. If empty, the endpoint is + defined in the root package. diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/constants.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/constants.yml new file mode 100644 index 00000000000..8ceb53bb12b --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/constants.yml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json +imports: + commons: commons.yml +types: + Constants: + properties: + errorInstanceIdKey: commons.NameAndWireValue diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/auth.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/auth.yml new file mode 100644 index 00000000000..9df1bc0585c --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/auth.yml @@ -0,0 +1,42 @@ +imports: + commons: ../commons.yml + types: ./types.yml + +types: + Auth: + union: + basic: BasicAuth + bearer: BearerAuth + header: HeaderAuth + + AuthValues: + union: + basic: BasicAuthValues + bearer: BearerAuthValues + header: HeaderAuthValues + + BasicAuth: + properties: + username: commons.Name + password: commons.Name + + BasicAuthValues: + properties: + username: string + password: string + + BearerAuth: + properties: + token: commons.Name + + BearerAuthValues: + properties: + token: string + + HeaderAuth: + properties: + header: types.NamedParameter + + HeaderAuthValues: + properties: + value: unknown \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/declaration.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/declaration.yml new file mode 100644 index 00000000000..903ca06a542 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/declaration.yml @@ -0,0 +1,7 @@ +imports: + commons: ../commons.yml +types: + Declaration: + properties: + fernFilepath: commons.FernFilepath + name: commons.Name diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/endpoints.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/endpoints.yml new file mode 100644 index 00000000000..82b479d5863 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/endpoints.yml @@ -0,0 +1,97 @@ +imports: + auth: ./auth.yml + commons: ../commons.yml + declaration: ./declaration.yml + http: ../http.yml + types: ./types.yml +types: + EndpointLocation: + docs: | + Represents the endpoint location (e.g. "POST /users"). + properties: + method: http.HttpMethod + path: string + + Endpoint: + properties: + auth: optional + declaration: declaration.Declaration + location: EndpointLocation + request: Request + response: Response + + Request: + docs: | + Reperesents the request parameters required to call a specific endpoiont. + union: + body: BodyRequest + inlined: InlinedRequest + + Response: + docs: | + Reperesents the response returned by a specific endpoint. + + For now, we only support json responses, but this is set up to support a + variety of other endpoint response types (e.g. file download, pagination, + streaming, etc). + union: + json: {} + + BodyRequest: + properties: + pathParameters: optional> + body: optional + + InlinedRequest: + properties: + declaration: declaration.Declaration + pathParameters: optional> + queryParameters: optional> + headers: optional> + body: optional + metadata: optional + + InlinedRequestMetadata: + properties: + includePathParameters: + docs: | + If true, the path parameters should be included as properties in the + inlined request type, but only if the generator is explicitly configured + to do so. + + By default, the path parameters are generated as positional parameters. + type: boolean + onlyPathParameters: + docs: | + If true, the path parameters are the only parameters specified in the + inlined request. + + In combination with inludePathParameters, this influences whether or not the + inlined request type should be generated at all. + type: boolean + + InlinedRequestBody: + union: + properties: list + referenced: ReferencedRequestBody + fileUpload: FileUploadRequestBody + + ReferencedRequestBody: + properties: + bodyKey: commons.Name + bodyType: ReferencedRequestBodyType + + ReferencedRequestBodyType: + union: + bytes: {} + typeReference: types.TypeReference + + FileUploadRequestBody: + properties: + properties: list + + FileUploadRequestBodyProperty: + union: + file: commons.NameAndWireValue + fileArray: commons.NameAndWireValue + bodyProperty: types.NamedParameter diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/environment.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/environment.yml new file mode 100644 index 00000000000..130c93a6bbe --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/environment.yml @@ -0,0 +1,21 @@ +imports: + environment: ../environment.yml +types: + EnvironmentValues: + docs: | + Represents the value to use for a specific environment. There are three cases: + + 1. When sent as an EnvironmentId string, the generator assumes the value matches the name of the + environment (e.g. "Staging"), and returns an error otherwise. + + 2. If the API supports multiple environment URLs, send a map of URLs, e.g. + { + "ec2": "https://staging.ec2.aws.com", + "s3": "https://staging.s3.aws.com" + } + discriminated: false + union: + - environment.EnvironmentId + - MultipleEnvironmentUrlValues + + MultipleEnvironmentUrlValues: map \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/ir.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/ir.yml new file mode 100644 index 00000000000..7577bd975d5 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/ir.yml @@ -0,0 +1,28 @@ +imports: + commons: ../commons.yml + endpoints: ./endpoints.yml + environment: ../environment.yml + types: ./types.yml +types: + DynamicIntermediateRepresentation: + audiences: + - dynamic + docs: | + This represents the IR required to generate dynamic snippets. + + This IR minimizes the space required to generate snippets in a variety + of environments (e.g. web, offline, etc). + properties: + version: + docs: | + The version of the dynamic IR. This is independent from the verison + of the primary IR. + type: literal<"1.0.0"> + types: map + endpoints: map + headers: + docs: | + The headers that are required on every request. These headers + are typically included in the SDK's client constructor. + type: optional> + environments: optional diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/snippets.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/snippets.yml new file mode 100644 index 00000000000..c000cc755c0 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/snippets.yml @@ -0,0 +1,57 @@ +imports: + auth: ./auth.yml + endpoints: ./endpoints.yml + environment: ./environment.yml + +types: + ErrorSeverity: + audiences: + - dynamic + enum: + - CRITICAL + - WARNING + + Error: + audiences: + - dynamic + properties: + severity: ErrorSeverity + message: string + + Values: + audiences: + - dynamic + docs: | + Snippet values are represented as arbitrary key, value + pairs (i.e. JSON objects). The keys are expected to be + in the parameter's wire representation. For path parameters, + the name will match the parameter name. + type: map + + EndpointSnippetRequest: + audiences: + - dynamic + docs: | + The user-facing request type used to generate a dynamic snippet. + properties: + endpoint: endpoints.EndpointLocation + baseURL: optional + environment: optional + auth: optional + pathParameters: optional + queryParameters: optional + headers: optional + requestBody: optional + + EndpointSnippetResponse: + audiences: + - dynamic + docs: | + The user-facing response type containing the generated snippet. + + If there are any errors, the snippet will still sometimes represent a + partial and/or valid result. This is useful for rendering a snippet alongside + error messages the user can use to diagnose and resolve the problem. + properties: + snippet: string + errors: optional> diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/types.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/types.yml new file mode 100644 index 00000000000..635de0246ac --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/dynamic/types.yml @@ -0,0 +1,104 @@ +imports: + commons: ../commons.yml + declaration: ./declaration.yml + root: ../types.yml +types: + NamedParameter: + properties: + name: commons.NameAndWireValue + typeReference: TypeReference + + NamedType: + docs: | + Represents the type of a parameter that can be used to generate a dynamic type. + union: + alias: AliasType + enum: EnumType + object: ObjectType + discriminatedUnion: DiscriminatedUnionType + undiscriminatedUnion: UndiscriminatedUnionType + + TypeReference: + union: + list: TypeReference + literal: LiteralType + map: MapType + named: commons.TypeId + optional: TypeReference + primitive: root.PrimitiveTypeV1 + set: TypeReference + unknown: {} + + AliasType: + properties: + declaration: declaration.Declaration + typeReference: TypeReference + + EnumType: + properties: + declaration: declaration.Declaration + values: list + + MapType: + properties: + key: TypeReference + value: TypeReference + + ObjectType: + properties: + declaration: declaration.Declaration + properties: list + + DiscriminatedUnionType: + properties: + declaration: declaration.Declaration + discriminant: commons.NameAndWireValue + types: + docs: | + Map from the discriminant value (e.g. "user") to the type (e.g. User). + type: map + + SingleDiscriminatedUnionType: + union: + samePropertiesAsObject: SingleDiscriminatedUnionTypeObject + singleProperty: SingleDiscriminatedUnionTypeSingleProperty + noProperties: SingleDiscriminatedUnionTypeNoProperties + + SingleDiscriminatedUnionTypeObject: + properties: + typeId: commons.TypeId + discriminantValue: commons.NameAndWireValue + properties: + docs: | + Any properties included here are the base and/or extended properties from the union. + type: list + + SingleDiscriminatedUnionTypeSingleProperty: + properties: + typeReference: TypeReference + discriminantValue: commons.NameAndWireValue + properties: + docs: | + Any properties included here are the base and/or extended properties from the union. + type: optional> + + SingleDiscriminatedUnionTypeNoProperties: + properties: + discriminantValue: commons.NameAndWireValue + properties: + docs: | + Any properties included here are the base and/or extended properties from the union. + type: optional> + + UndiscriminatedUnionType: + properties: + declaration: declaration.Declaration + types: + docs: | + The dynamic type will be rendered with the first type that matches. + type: list + + LiteralType: + union: + boolean: boolean + string: string \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/environment.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/environment.yml new file mode 100644 index 00000000000..3f076c5a466 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/environment.yml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: commons.yml +types: + EnvironmentId: string + EnvironmentBaseUrlId: string + EnvironmentUrl: string + EnvironmentsConfig: + properties: + defaultEnvironment: optional + environments: Environments + Environments: + union: + singleBaseUrl: SingleBaseUrlEnvironments + multipleBaseUrls: MultipleBaseUrlsEnvironments + SingleBaseUrlEnvironments: + properties: + environments: list + SingleBaseUrlEnvironment: + extends: commons.WithDocs + properties: + id: EnvironmentId + name: commons.Name + url: EnvironmentUrl + MultipleBaseUrlsEnvironments: + properties: + baseUrls: list + environments: list + MultipleBaseUrlsEnvironment: + extends: commons.WithDocs + properties: + id: EnvironmentId + name: commons.Name + urls: map + EnvironmentBaseUrlWithId: + properties: + id: EnvironmentBaseUrlId + name: commons.Name diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/errors.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/errors.yml new file mode 100644 index 00000000000..3888562cbc0 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/errors.yml @@ -0,0 +1,34 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: commons.yml + types: types.yml + +types: + ErrorDeclaration: + extends: commons.WithDocs + properties: + name: DeclaredErrorName + discriminantValue: commons.NameAndWireValue + type: optional + statusCode: integer + examples: list + ErrorDeclarationDiscriminantValue: + union: + property: commons.NameAndWireValue + statusCode: {} + DeclaredErrorName: + properties: + errorId: commons.ErrorId + fernFilepath: commons.FernFilepath + name: commons.Name + + # examples + + ExampleError: + extends: + - commons.WithJsonExample + - commons.WithDocs + properties: + name: optional + shape: types.ExampleTypeReference diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/generator-exec/config.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/generator-exec/config.yml new file mode 100644 index 00000000000..22846a5f8fa --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/generator-exec/config.yml @@ -0,0 +1,224 @@ +types: + GeneratorConfig: + audiences: + - dynamic + properties: + dryRun: boolean + irFilepath: string + originalReadmeFilepath: optional + license: optional + output: GeneratorOutputConfig + publish: + type: optional + docs: Deprecated. Use output.mode instead. + workspaceName: string + organization: string + customConfig: unknown + environment: GeneratorEnvironment + whitelabel: boolean + writeUnitTests: boolean + generatePaginatedClients: optional + generateOauthClients: boolean + LicenseConfig: + union: + basic: BasicLicense + custom: CustomLicense + BasicLicense: + properties: + id: LicenseId + LicenseId: + enum: + - MIT + - name: apache2 + value: Apache-2.0 + CustomLicense: + properties: + filename: string + GeneratorOutputConfig: + properties: + path: string + snippetFilepath: optional + snippetTemplateFilepath: optional + publishingMetadata: optional + mode: OutputMode + OutputMode: + union: + publish: GeneratorPublishConfig + downloadFiles: {} + github: GithubOutputMode + GeneratorPublishConfig: + properties: + registries: + type: GeneratorRegistriesConfig + docs: Deprecated, use publishTargets instead. + registriesV2: + type: GeneratorRegistriesConfigV2 + docs: Deprecated, use publishTargets instead. + publishTarget: optional + version: string + GithubOutputMode: + properties: + version: string + repoUrl: + type: string + docs: A full repo url (i.e. https://github.com/fern-api/fern) + installationToken: + type: optional + docs: | + The token scoped to installing the repository. If not specified, the generator + should NOT attempt to clone the repository. + publishInfo: optional + OutputMetadataAuthor: + properties: + name: string + email: string + OutputMetadata: + properties: + description: optional + authors: optional> + PublishingMetadata: + docs: This should effectively be deprecated in favor of a more specific configuration per-output mode (pypi, maven, etc.). + properties: + package_description: optional + publisher_email: optional + reference_url: optional + publisher_name: optional + GithubPublishInfo: + union: + npm: NpmGithubPublishInfo + maven: MavenGithubPublishInfo + postman: PostmanGithubPublishInfo + pypi: PypiGithubPublishInfo + rubygems: RubyGemsGithubPublishInfo + nuget: NugetGithubPublishInfo + EnvironmentVariable: string + NpmGithubPublishInfo: + properties: + registryUrl: string + packageName: string + tokenEnvironmentVariable: EnvironmentVariable + shouldGeneratePublishWorkflow: optional + MavenCentralSignatureGithubInfo: + properties: + keyIdEnvironmentVariable: EnvironmentVariable + passwordEnvironmentVariable: EnvironmentVariable + secretKeyEnvironmentVariable: EnvironmentVariable + MavenGithubPublishInfo: + properties: + registryUrl: string + coordinate: string + usernameEnvironmentVariable: EnvironmentVariable + passwordEnvironmentVariable: EnvironmentVariable + signature: optional + shouldGeneratePublishWorkflow: optional + PostmanGithubPublishInfo: + properties: + apiKeyEnvironmentVariable: EnvironmentVariable + workspaceIdEnvironmentVariable: EnvironmentVariable + PypiMetadata: + extends: OutputMetadata + properties: + keywords: optional> + documentationLink: optional + homepageLink: optional + PypiGithubPublishInfo: + properties: + registryUrl: string + packageName: string + usernameEnvironmentVariable: EnvironmentVariable + passwordEnvironmentVariable: EnvironmentVariable + pypiMetadata: optional + shouldGeneratePublishWorkflow: optional + RubyGemsGithubPublishInfo: + properties: + registryUrl: string + packageName: string + apiKeyEnvironmentVariable: EnvironmentVariable + shouldGeneratePublishWorkflow: optional + NugetGithubPublishInfo: + properties: + registryUrl: string + packageName: string + apiKeyEnvironmentVariable: EnvironmentVariable + shouldGeneratePublishWorkflow: optional + GeneratorRegistriesConfig: + properties: + maven: MavenRegistryConfig + npm: NpmRegistryConfig + MavenCentralSignature: + properties: + keyId: string + password: string + secretKey: string + MavenRegistryConfig: + properties: + registryUrl: string + username: string + password: string + group: string + signature: optional + NpmRegistryConfig: + properties: + registryUrl: string + token: string + scope: string + GeneratorRegistriesConfigV2: + properties: + maven: MavenRegistryConfigV2 + npm: NpmRegistryConfigV2 + pypi: PypiRegistryConfig + rubygems: RubyGemsRegistryConfig + nuget: NugetRegistryConfig + GeneratorPublishTarget: + union: + maven: MavenRegistryConfigV2 + npm: NpmRegistryConfigV2 + pypi: PypiRegistryConfig + postman: PostmanConfig + rubygems: RubyGemsRegistryConfig + nuget: NugetRegistryConfig + MavenRegistryConfigV2: + properties: + registryUrl: string + username: string + password: string + coordinate: string + signature: optional + NpmRegistryConfigV2: + properties: + registryUrl: string + token: string + packageName: string + PypiRegistryConfig: + properties: + registryUrl: string + username: string + password: string + packageName: string + pypiMetadata: optional + RubyGemsRegistryConfig: + properties: + registryUrl: string + apiKey: string + packageName: string + NugetRegistryConfig: + properties: + registryUrl: string + apiKey: string + packageName: string + PostmanConfig: + properties: + apiKey: string + workspaceId: string + GeneratorEnvironment: + discriminant: + value: _type + name: type + union: + local: {} + remote: RemoteGeneratorEnvironment + RemoteGeneratorEnvironment: + properties: + coordinatorUrl: string + coordinatorUrlV2: string + id: string \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/http.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/http.yml new file mode 100644 index 00000000000..820550e8f88 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/http.yml @@ -0,0 +1,478 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: commons.yml + environment: environment.yml + errors: errors.yml + proto: proto.yml + types: types.yml + variables: variables.yml +types: + HttpService: + properties: + availability: optional + name: DeclaredServiceName + displayName: optional + basePath: HttpPath + endpoints: list + headers: list + pathParameters: list + encoding: optional + transport: optional + DeclaredServiceName: + properties: + fernFilepath: commons.FernFilepath + + Transport: + union: + http: {} + grpc: GrpcTransport + + GrpcTransport: + properties: + service: proto.ProtobufService + + HttpEndpoint: + extends: commons.Declaration + properties: + id: commons.EndpointId + name: EndpointName + displayName: optional + method: HttpMethod + headers: list + baseUrl: optional + basePath: + type: optional + docs: Overrides the service and endpoint level base paths + path: HttpPath + fullPath: HttpPath + pathParameters: list + allPathParameters: list + queryParameters: list + requestBody: optional + sdkRequest: optional + response: optional + errors: ResponseErrors + auth: boolean + idempotent: boolean + pagination: optional + userSpecifiedExamples: list + autogeneratedExamples: list + transport: optional + + EndpointName: commons.Name + HttpPath: + properties: + head: string + parts: list + HttpPathPart: + properties: + pathParameter: string + tail: string + HttpMethod: + enum: + - GET + - POST + - PUT + - PATCH + - DELETE + HttpHeader: + extends: commons.Declaration + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + env: optional + PathParameter: + extends: commons.WithDocs + properties: + name: commons.Name + valueType: types.TypeReference + location: PathParameterLocation + variable: optional + PathParameterLocation: + enum: + - ROOT + - SERVICE + - ENDPOINT + QueryParameter: + extends: commons.Declaration + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + allowMultiple: boolean + HttpRequestBody: + union: + inlinedRequestBody: InlinedRequestBody + reference: HttpRequestBodyReference + fileUpload: FileUploadRequest + bytes: BytesRequest + InlinedRequestBody: + extends: commons.WithDocs + properties: + name: commons.Name + extends: list + properties: list + extendedProperties: + type: optional> + docs: A list of properties that all the parents of this request have. + contentType: optional + extra-properties: + docs: Whether to allow extra properties on the request. + type: boolean + InlinedRequestBodyProperty: + extends: commons.WithDocsAndAvailability + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + FileUploadRequest: + extends: commons.WithDocs + properties: + name: commons.Name + properties: list + BytesRequest: + extends: commons.WithDocs + properties: + isOptional: boolean + contentType: optional + FileUploadRequestProperty: + union: + file: FileProperty + bodyProperty: FileUploadBodyProperty + FileUploadBodyProperty: + extends: InlinedRequestBodyProperty + properties: + contentType: optional + FileProperty: + union: + file: FilePropertySingle + fileArray: FilePropertyArray + FilePropertySingle: + properties: + key: commons.NameAndWireValue + isOptional: boolean + contentType: optional + FilePropertyArray: + properties: + key: commons.NameAndWireValue + isOptional: boolean + contentType: optional + HttpRequestBodyReference: + extends: commons.WithDocs + properties: + requestBodyType: types.TypeReference + contentType: optional + SdkRequestBodyType: + union: + typeReference: HttpRequestBodyReference + bytes: BytesRequest + SdkRequest: + properties: + streamParameter: + type: optional + docs: | + The request property that controls whether or not the response is streamed. + requestParameterName: commons.Name + shape: SdkRequestShape + SdkRequestShape: + union: + justRequestBody: SdkRequestBodyType + wrapper: SdkRequestWrapper + SdkRequestWrapper: + properties: + wrapperName: commons.Name + bodyKey: commons.Name + includePathParameters: optional + onlyPathParameters: optional + + HttpResponse: + properties: + status-code: optional + body: optional + + NonStreamHttpResponseBody: + union: + json: JsonResponse + fileDownload: FileDownloadResponse + text: TextResponse + bytes: BytesResponse + + HttpResponseBody: + union: + json: JsonResponse + fileDownload: FileDownloadResponse + text: TextResponse + bytes: BytesResponse + streaming: StreamingResponse + streamParameter: + type: StreamParameterResponse + docs: | + If there is a parameter that controls whether the response is streaming or not. Note + that if this is the response then `sdkRequest.streamParameter` will always be populated. + + JsonResponse: + union: + response: JsonResponseBody + nestedPropertyAsResponse: JsonResponseBodyWithProperty + + JsonResponseBody: + extends: commons.WithDocs + properties: + responseBodyType: types.TypeReference + + JsonResponseBodyWithProperty: + extends: commons.WithDocs + properties: + responseBodyType: types.TypeReference + responseProperty: + docs: | + If set, the SDK will return this property from + the response, rather than the response itself. + + This is particularly useful for JSON API structures + (e.g. configure 'data' to return 'response.data'). + type: optional + + FileDownloadResponse: + extends: commons.WithDocs + + TextResponse: + extends: commons.WithDocs + + BytesResponse: + extends: commons.WithDocs + + StreamParameterResponse: + properties: + nonStreamResponse: NonStreamHttpResponseBody + streamResponse: StreamingResponse + + StreamingResponse: + union: + json: JsonStreamChunk + text: TextStreamChunk + sse: SseStreamChunk + + TextStreamChunk: + extends: commons.WithDocs + properties: {} + + JsonStreamChunk: + extends: commons.WithDocs + properties: + payload: types.TypeReference + terminator: optional + + SseStreamChunk: + extends: commons.WithDocs + properties: + payload: types.TypeReference + terminator: optional + + ResponseErrors: list + ResponseError: + extends: commons.WithDocs + properties: + error: errors.DeclaredErrorName + + Pagination: + docs: | + If set, the endpoint will be generated with auto-pagination features. + union: + cursor: CursorPagination + offset: OffsetPagination + + CursorPagination: + docs: | + If set, the endpoint will be generated with auto-pagination features. + + The page must be defined as a property defined on the request, whereas + the next page and results are resolved from properties defined on the + response. + properties: + page: RequestProperty + next: ResponseProperty + results: ResponseProperty + + OffsetPagination: + docs: | + The page must be defined as a query parameter included in the request, + whereas the results are resolved from properties defined on the response. + + The page index is auto-incremented between every additional page request. + properties: + page: RequestProperty + results: ResponseProperty + hasNextPage: + docs: A response property that indicates whether there is a next page or not. + type: optional + step: + docs: | + The step size used to increment the page offset between every new page. + type: optional + + # shared properties + RequestPropertyValue: + union: + query: QueryParameter + body: types.ObjectProperty + + RequestProperty: + docs: | + A property associated with an endpoint's request. + properties: + propertyPath: + docs: | + If empty, the property is defined at the top-level. + Otherwise, the property is defined on the nested object identified + by the path. + type: optional> + property: RequestPropertyValue + + ResponseProperty: + docs: | + A property associated with a paginated endpoint's request or response. + properties: + propertyPath: + docs: | + If empty, the property is defined at the top-level. + Otherwise, the property is defined on the nested object identified + by the path. + type: optional> + property: types.ObjectProperty + + # examples + AutogeneratedEndpointExample: + properties: + example: ExampleEndpointCall + + UserSpecifiedEndpointExample: + properties: + codeSamples: + type: optional> + docs: Manually written code samples specified by the user + example: + type: optional + docs: Manually written example specified by the user + + ExampleEndpointCall: + extends: commons.WithDocs + properties: + id: optional + name: optional + url: string + rootPathParameters: list + servicePathParameters: list + endpointPathParameters: list + serviceHeaders: list + endpointHeaders: list + queryParameters: list + request: optional + response: ExampleResponse + + ExampleCodeSample: + availability: in-development + union: + language: ExampleCodeSampleLanguage + sdk: ExampleCodeSampleSdk + + ExampleCodeSampleLanguage: + docs: | + This is intended to co-exist with the auto-generated code samples. + extends: commons.WithDocs + properties: + name: + type: optional + docs: Override the example name. + language: string + code: string + install: + type: optional + docs: | + The command to install the dependencies for the code sample. + For example, `npm install` or `pip install -r requirements.txt`. + + ExampleCodeSampleSdk: + docs: | + This will be used to replace the auto-generated code samples. + extends: commons.WithDocs + properties: + name: + type: optional + docs: Override the example name. + sdk: SupportedSdkLanguage + code: string + + # be sure to keep this in sync with the list of supported Fern SDK languages + SupportedSdkLanguage: + enum: + - curl + - python + - javascript + - typescript + - go + - ruby + - csharp + - java + + ExamplePathParameter: + properties: + name: commons.Name + value: types.ExampleTypeReference + + ExampleQueryParameter: + properties: + name: commons.NameAndWireValue + value: types.ExampleTypeReference + shape: optional + + ExampleQueryParameterShape: + union: + single: {} + exploded: {} + commaSeparated: {} + + ExampleHeader: + properties: + name: commons.NameAndWireValue + value: types.ExampleTypeReference + + ExampleRequestBody: + union: + inlinedRequestBody: ExampleInlinedRequestBody + reference: types.ExampleTypeReference + + ExampleInlinedRequestBody: + extends: commons.WithJsonExample + properties: + properties: list + + ExampleInlinedRequestBodyProperty: + properties: + name: commons.NameAndWireValue + value: types.ExampleTypeReference + originalTypeDeclaration: + docs: | + This property may have been brought in via extension. originalTypeDeclaration + is the name of the type that contains this property + type: optional + + ExampleResponse: + union: + ok: ExampleEndpointSuccessResponse + error: ExampleEndpointErrorResponse + + ExampleEndpointSuccessResponse: + union: + body: optional + stream: list + sse: list + + ExampleServerSideEvent: + properties: + event: string + data: types.ExampleTypeReference + + ExampleEndpointErrorResponse: + properties: + error: errors.DeclaredErrorName + body: optional diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/ir.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/ir.yml new file mode 100644 index 00000000000..ef42039791a --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/ir.yml @@ -0,0 +1,179 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + auth: auth.yml + commons: commons.yml + constants: constants.yml + dynamic: dynamic/ir.yml + environment: environment.yml + errors: errors.yml + http: http.yml + proto: proto.yml + types: types.yml + variables: variables.yml + webhooks: webhooks.yml + websocket: websocket.yml + publish: publish.yml + +types: + IntermediateRepresentation: + docs: "Complete representation of the API schema" + properties: + fdrApiDefinitionId: + type: optional + docs: The unique identifier for the API definition used within FDR. This is retrieved once a definition has been registered. + apiVersion: optional + apiName: + type: commons.Name + docs: This is the human readable unique id for the API. + apiDisplayName: optional + apiDocs: optional + auth: auth.ApiAuth + headers: + docs: API Wide headers that are sent on every request + type: list + idempotencyHeaders: + docs: Headers that are sent for idempotent endpoints + type: list + types: + docs: "The types described by this API" + type: map + services: + docs: "The services exposed by this API" + type: map + webhookGroups: + docs: "The webhooks sent by this API" + type: map + websocketChannels: + docs: "The websocket channels served by this API" + type: optional> + errors: map + subpackages: map + rootPackage: Package + constants: constants.Constants + environments: optional + basePath: optional + pathParameters: list + errorDiscriminationStrategy: ErrorDiscriminationStrategy + sdkConfig: SdkConfig + variables: list + serviceTypeReferenceInfo: ServiceTypeReferenceInfo + readmeConfig: optional + sourceConfig: optional + publishConfig: optional + dynamic: optional + + ReadmeConfig: + docs: | + The configuration used to generate a README.md file. If present, the generator + should call the generator-cli to produce a README.md. + properties: + defaultEndpoint: + docs: | + If specified, this enpdoint should be used in every snippet (if possible). + Note that some endpoints aren't suitable for every feature (e.g. a non-list + endpoint for pagination), so the default is a no-op in those cases. + type: optional + bannerLink: optional + introduction: optional + apiReferenceLink: optional + features: + docs: | + If specified, configures the list of endpoints to associate + with each feature. + type: optional>> + SourceConfig: + properties: + sources: + docs: The raw API definitions that produced the IR. + type: list + ApiDefinitionSourceId: + docs: | + Uniquely identifies a specific API definition source. This allows us to clearly identify + what source a given type, endpoint, etc was derived from. + type: string + ApiDefinitionSource: + union: + proto: ProtoSource + openapi: {} + ProtoSource: + properties: + id: ApiDefinitionSourceId + protoRootUrl: + docs: | + The URL containing the `.proto` root directory source. This can be used + to pull down the original `.proto` source files during code generation. + type: string + SdkConfig: + properties: + isAuthMandatory: boolean + hasStreamingEndpoints: boolean + hasPaginatedEndpoints: boolean + hasFileDownloadEndpoints: boolean + platformHeaders: PlatformHeaders + PlatformHeaders: + properties: + language: string + sdkName: string + sdkVersion: string + userAgent: optional + UserAgent: + properties: + header: + type: literal<"User-Agent"> + docs: The user agent header for ease of access to generators. + value: + type: string + docs: Formatted as "/" + + ApiVersionScheme: + docs: | + The available set of versions for the API. This is used to generate a special + enum that can be used to specify the version of the API to use. + union: + header: HeaderApiVersionScheme + HeaderApiVersionScheme: + docs: | + The version information is sent as an HTTP header (e.g. X-API-Version) on every request. + + If the enum does _not_ define a default value, the version should be treated like + a required global header parameter. The version header should also support any + environment variable scanning specified by the header. + properties: + header: http.HttpHeader + value: types.EnumTypeDeclaration + ErrorDiscriminationStrategy: + union: + statusCode: {} + property: ErrorDiscriminationByPropertyStrategy + ErrorDiscriminationByPropertyStrategy: + properties: + discriminant: commons.NameAndWireValue + contentProperty: commons.NameAndWireValue + Package: + extends: commons.WithDocs + properties: + fernFilepath: commons.FernFilepath + service: optional + types: list + errors: list + webhooks: optional + websocket: optional + subpackages: list + hasEndpointsInTree: boolean + navigationConfig: optional + Subpackage: + extends: Package + properties: + name: commons.Name + PackageNavigationConfig: + properties: + pointsTo: commons.SubpackageId + ServiceTypeReferenceInfo: + properties: + typesReferencedOnlyByService: + docs: "Types referenced by exactly one service." + type: map> + sharedTypes: + docs: "Types referenced by either zero or multiple services." + type: list diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/proto.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/proto.yml new file mode 100644 index 00000000000..75f82571326 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/proto.yml @@ -0,0 +1,156 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: commons.yml + +types: + ProtobufService: + docs: | + Defines the information related to a Protobuf service declaration. This is + primarily meant to be used to instantiate the internal gRPC client used by + the SDK. + + For example, consider the following C# snippet which instantiates a + `UserService` gRPC client: + + ```csharp + using User.Grpc; + + public class RawGrpcClient + { + public UserService.UserServiceClient UserServiceClient; + + public RawGrpcClient(...) + { + GrpcChannel channel = GrpcChannel.ForAddress(...); + UserServiceClient = new UserService.UserServiceClient(channel); + } + } + ``` + properties: + file: + docs: | + The `.proto` source file that defines this service. + type: ProtobufFile + name: + docs: | + The name of the service defined in the `.proto` file (e.g. UserService). + type: commons.Name + + ProtobufType: + docs: | + A Protobuf type declaration. + union: + wellKnown: WellKnownProtobufType + userDefined: UserDefinedProtobufType + + UserDefinedProtobufType: + docs: | + Defines the information related to the original `.proto` source file + that defines this type. This is primarily meant to be used to generate + Protobuf mapper methods, which are used in gRPC-compatbile SDKs. + + For example, consider the following Go snippet which requires the + `go_package` setting: + + ```go + import "github.com/acme/acme-go/proto" + + type GetUserRequest struct { + Username string + Email string + } + + func (u *GetUserRequest) ToProto() *proto.GetUserRequest { + if u == nil { + return nil + } + return &proto.GetUserRequest{ + Username u.Username, + Email: u.Email, + } + } + ``` + properties: + file: + docs: | + The `.proto` source file that defines this type. + type: ProtobufFile + name: + docs: | + This name is _usually_ equivalent to the associated DeclaredTypeName's name. + However, its repeated here just in case the naming convention differs, which + is most relevant for APIs that specify `smart-casing`. + type: commons.Name + + WellKnownProtobufType: + docs: | + The set of well-known types supported by Protobuf. These types are often included + in the target runtime library, so they usually require special handling. + + The full list of well-known types can be found at https://protobuf.dev/reference/protobuf/google.protobuf + union: + any: {} + api: {} + boolValue: {} + bytesValue: {} + doubleValue: {} + duration: {} + empty: {} + enum: {} + enumValue: {} + field: {} + fieldCardinality: {} + fieldKind: {} + fieldMask: {} + floatValue: {} + int32Value: {} + int64Value: {} + listValue: {} + method: {} + mixin: {} + nullValue: {} + option: {} + sourceContext: {} + stringValue: {} + struct: {} + syntax: {} + timestamp: {} + type: {} + uint32Value: {} + uint64Value: {} + value: {} + + ProtobufFile: + properties: + filepath: + docs: | + The `.proto` source path, relative to the Protobuf root directory. + This is how the file is referenced in `import` statements. + type: string + packageName: + docs: | + The `.proto` package name. If not specified, a package name was not declared. + type: optional + options: + docs: | + Specifies a variety of language-specific options. + type: optional + + ProtobufFileOptions: + properties: + csharp: optional + + CsharpProtobufFileOptions: + properties: + namespace: + docs: | + Populated by the `csharp_namespace` file option, e.g. + + ```protobuf + option csharp_namespace = Grpc.Health.V1; + ``` + + This is used to determine what import path is required to reference the + associated type(s). + type: string diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/publish.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/publish.yml new file mode 100644 index 00000000000..54c523899bd --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/publish.yml @@ -0,0 +1,29 @@ +types: + PublishingConfig: + union: + github: + type: GithubPublish + docs: Publish via syncing to a GitHub repo and triggering GitHub workflows + direct: + type: DirectPublish + docs: Publish directly from the generator + + GithubPublish: + properties: + owner: string + repo: string + target: PublishTarget + + DirectPublish: + properties: + target: PublishTarget + + PublishTarget: + union: + postman: PostmanPublishTarget + + PostmanPublishTarget: + properties: + apiKey: string + workspaceId: string + collectionId: optional \ No newline at end of file diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/types.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/types.yml new file mode 100644 index 00000000000..48c0f173782 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/types.yml @@ -0,0 +1,493 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +imports: + commons: commons.yml + proto: proto.yml +types: + Source: + docs: | + The original source of the declared type (e.g. a `.proto` file). + union: + proto: proto.ProtobufType + + Encoding: + properties: + json: optional + proto: optional + + JsonEncoding: + properties: {} + + ProtoEncoding: + properties: {} + + TypeDeclaration: + docs: "A type, which is a name and a shape" + extends: commons.Declaration + properties: + name: DeclaredTypeName + shape: Type + autogeneratedExamples: list + userProvidedExamples: list + referencedTypes: + docs: All other named types that this type references (directly or indirectly) + type: set + encoding: optional + source: optional + inline: + type: optional + docs: Whether to try and inline the type declaration + + DeclaredTypeName: + properties: + typeId: commons.TypeId + fernFilepath: commons.FernFilepath + name: commons.Name + + Type: + discriminant: + value: _type + name: type + union: + alias: AliasTypeDeclaration + enum: EnumTypeDeclaration + object: ObjectTypeDeclaration + union: UnionTypeDeclaration + undiscriminatedUnion: UndiscriminatedUnionTypeDeclaration + + AliasTypeDeclaration: + properties: + aliasOf: TypeReference + resolvedType: ResolvedTypeReference + ResolvedTypeReference: + discriminant: + value: _type + name: type + union: + container: + type: ContainerType + key: container + named: ResolvedNamedType + primitive: + type: PrimitiveType + key: primitive + unknown: {} + ResolvedNamedType: + properties: + name: DeclaredTypeName + shape: ShapeType + + ShapeType: + enum: + - ENUM + - OBJECT + - UNION + - UNDISCRIMINATED_UNION + EnumTypeDeclaration: + properties: + default: optional + values: list + EnumValue: + extends: commons.Declaration + properties: + name: commons.NameAndWireValue + + ObjectTypeDeclaration: + properties: + extends: + docs: A list of other types to inherit from + type: list + properties: list + extendedProperties: + type: optional> + docs: A list of properties that all the parents of this object have. + extra-properties: + docs: Whether to allow extra properties on the object. + type: boolean + ObjectProperty: + extends: commons.Declaration + properties: + name: commons.NameAndWireValue + valueType: TypeReference + + UnionTypeDeclaration: + properties: + discriminant: commons.NameAndWireValue + extends: + docs: "A list of other types to inherit from" + type: list + types: list + baseProperties: list + SingleUnionType: + extends: commons.WithDocs + properties: + discriminantValue: commons.NameAndWireValue + shape: SingleUnionTypeProperties + displayName: optional + availability: optional + SingleUnionTypeProperties: + discriminant: + value: _type + name: propertiesType + union: + samePropertiesAsObject: DeclaredTypeName + singleProperty: SingleUnionTypeProperty + noProperties: {} + SingleUnionTypeProperty: + properties: + name: commons.NameAndWireValue + type: TypeReference + + UndiscriminatedUnionTypeDeclaration: + properties: + members: list + UndiscriminatedUnionMember: + extends: commons.WithDocs + properties: + type: TypeReference + + TypeReference: + discriminant: + value: _type + name: type + union: + container: + type: ContainerType + key: container + named: NamedType + primitive: + type: PrimitiveType + key: primitive + unknown: {} + + NamedType: + docs: | + A reference to a named type. For backwards compatbility, this type must be fully compatible + with the DeclaredTypeName. + properties: + typeId: commons.TypeId + fernFilepath: commons.FernFilepath + name: commons.Name + default: optional + inline: + type: optional + availability: deprecated + docs: Use the inline property on the TypeDeclaration instead. + + NamedTypeDefault: + union: + enum: EnumValue + + EnumTypeReference: + properties: + default: optional + name: DeclaredTypeName + + ContainerType: + discriminant: + value: _type + name: type + union: + list: + type: TypeReference + key: list + map: MapType + optional: + type: TypeReference + key: optional + set: + type: TypeReference + key: set + literal: + type: Literal + key: literal + MapType: + properties: + keyType: TypeReference + valueType: TypeReference + + PrimitiveType: + properties: + v1: PrimitiveTypeV1 + v2: optional + PrimitiveTypeV1: + enum: + - INTEGER + - value: LONG + docs: "Within the range -2^53 to 2^53" + - UINT + - UINT_64 + - FLOAT + - DOUBLE + - BOOLEAN + - STRING + - DATE + - DATE_TIME + - UUID + - BASE_64 + - BIG_INTEGER + PrimitiveTypeV2: + union: + integer: IntegerType + long: LongType + uint: UintType + uint64: Uint64Type + float: FloatType + double: DoubleType + boolean: BooleanType + string: StringType + date: DateType + dateTime: DateTimeType + uuid: UuidType + base64: Base64Type + bigInteger: BigIntegerType + + IntegerType: + properties: + default: optional + validation: optional + IntegerValidationRules: + properties: + min: optional + max: optional + exclusiveMin: optional + exclusiveMax: optional + multipleOf: optional + LongType: + properties: + default: optional + UintType: + properties: {} + Uint64Type: + properties: {} + FloatType: + properties: {} + DoubleType: + properties: + default: optional + validation: optional + DoubleValidationRules: + properties: + min: optional + max: optional + exclusiveMin: optional + exclusiveMax: optional + multipleOf: optional + BooleanType: + properties: + default: optional + StringType: + properties: + default: optional + validation: optional + StringValidationRules: + properties: + format: optional + pattern: optional + minLength: optional + maxLength: optional + DateType: + properties: {} + DateTimeType: + properties: {} + UuidType: + properties: {} + Base64Type: + properties: {} + BigIntegerType: + properties: + default: optional + + Literal: + union: + string: + type: string + key: string + boolean: + type: boolean + key: boolean + + # examples + + ExampleType: + extends: + - commons.WithJsonExample + - commons.WithDocs + properties: + name: optional + shape: ExampleTypeShape + + ExampleTypeShape: + union: + alias: ExampleAliasType + enum: ExampleEnumType + object: ExampleObjectType + union: ExampleUnionType + undiscriminatedUnion: ExampleUndiscriminatedUnionType + + ExampleAliasType: + properties: + value: ExampleTypeReference + + ExampleEnumType: + properties: + value: commons.NameAndWireValue + + ExampleObjectType: + properties: + properties: list + + ExampleObjectProperty: + properties: + name: commons.NameAndWireValue + value: ExampleTypeReference + originalTypeDeclaration: + docs: | + This property may have been brought in via extension. originalTypeDeclaration + is the name of the type that contains this property. + type: DeclaredTypeName + + ExampleUnionType: + properties: + discriminant: commons.NameAndWireValue + singleUnionType: ExampleSingleUnionType + + ExampleUndiscriminatedUnionType: + properties: + index: + type: integer + docs: | + The zero-based index of the undiscriminated union variant. + For the following undiscriminated union + ``` + MyUnion: + discriminated: false + union: + - string + - integer + ``` + a string example would have an index 0 and an integer example + would have an index 1. + singleUnionType: ExampleTypeReference + + ExampleSingleUnionType: + properties: + wireDiscriminantValue: commons.NameAndWireValue + shape: ExampleSingleUnionTypeProperties + + ExampleSingleUnionTypeProperties: + union: + samePropertiesAsObject: ExampleObjectTypeWithTypeId + singleProperty: ExampleTypeReference + noProperties: {} + + ExampleTypeReference: + extends: commons.WithJsonExample + properties: + shape: ExampleTypeReferenceShape + + ExampleTypeReferenceShape: + union: + primitive: + type: ExamplePrimitive + key: primitive + container: + type: ExampleContainer + key: container + unknown: + type: unknown + key: unknown + named: ExampleNamedType + + ExampleContainer: + union: + list: ExampleListContainer + set: ExampleSetContainer + optional: ExampleOptionalContainer + map: ExampleMapContainer + literal: ExampleLiteralContainer + + ExampleListContainer: + properties: + list: list + itemType: TypeReference + + ExampleSetContainer: + properties: + set: list + itemType: TypeReference + + ExampleOptionalContainer: + properties: + optional: optional + valueType: TypeReference + + ExampleMapContainer: + properties: + map: list + keyType: TypeReference + valueType: TypeReference + + ExampleLiteralContainer: + properties: + literal: ExamplePrimitive + + ExampleKeyValuePair: + properties: + key: ExampleTypeReference + value: ExampleTypeReference + + ExamplePrimitive: + union: + integer: + type: integer + key: integer + long: + type: long + key: long + uint: + type: uint + key: uint + uint64: + type: uint64 + key: uint64 + float: + type: double # TODO: Refactor the following to be a float once we have a float type. + key: float + double: + type: double + key: double + boolean: + type: boolean + key: boolean + string: + type: commons.EscapedString + key: string + date: + type: date + key: date + datetime: ExampleDatetime + uuid: + type: uuid + key: uuid + base64: + type: base64 + key: base64 + bigInteger: + type: bigint + key: bigInteger + + ExampleDatetime: + properties: + datetime: datetime + raw: optional + + ExampleNamedType: + properties: + typeName: DeclaredTypeName + shape: ExampleTypeShape + + ExampleObjectTypeWithTypeId: + properties: + typeId: commons.TypeId + object: ExampleObjectType diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/variables.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/variables.yml new file mode 100644 index 00000000000..2c196becb01 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/variables.yml @@ -0,0 +1,13 @@ +imports: + commons: commons.yml + types: types.yml + +types: + VariableId: string + + VariableDeclaration: + extends: commons.WithDocs + properties: + id: VariableId + name: commons.Name + type: types.TypeReference diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/webhooks.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/webhooks.yml new file mode 100644 index 00000000000..13d33bd6883 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/webhooks.yml @@ -0,0 +1,56 @@ +imports: + commons: commons.yml + types: types.yml + http: http.yml +types: + WebhookGroup: list + + Webhook: + extends: commons.Declaration + properties: + id: commons.WebhookId + name: WebhookName + displayName: optional + method: WebhookHttpMethod + headers: list + payload: WebhookPayload + examples: optional> + + WebhookName: commons.Name + + WebhookPayload: + union: + inlinedPayload: InlinedWebhookPayload + reference: WebhookPayloadReference + + WebhookPayloadReference: + extends: commons.WithDocs + properties: + payloadType: types.TypeReference + + InlinedWebhookPayload: + properties: + name: commons.Name + extends: list + properties: list + + InlinedWebhookPayloadProperty: + extends: commons.WithDocsAndAvailability + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + + WebhookHttpMethod: + enum: + - GET + - POST + + ExampleWebhookCall: + docs: | + An example webhook call. For now, this only includes the payload, + but it can be easily extended to support other endpoint properties + (e.g. headers). + extends: commons.WithDocs + properties: + name: optional + payload: types.ExampleTypeReference diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/definition/websocket.yml b/packages/ir-sdk/fern/apis/ir-types-v54/definition/websocket.yml new file mode 100644 index 00000000000..98b427e60f5 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/definition/websocket.yml @@ -0,0 +1,79 @@ +imports: + commons: commons.yml + types: types.yml + http: http.yml + +types: + WebSocketMessageId: string + + WebSocketChannel: + extends: commons.Declaration + properties: + name: WebSocketName + displayName: optional + path: http.HttpPath + auth: boolean + headers: list + queryParameters: list + pathParameters: list + messages: + docs: "The messages that can be sent and received on this channel" + type: list + examples: list + + WebSocketName: commons.Name + + WebSocketMessage: + extends: commons.Declaration + properties: + type: WebSocketMessageId + displayName: optional + origin: WebSocketMessageOrigin + body: WebSocketMessageBody + + WebSocketMessageOrigin: + enum: + - client + - server + + WebSocketMessageBody: + union: + inlinedBody: InlinedWebSocketMessageBody + reference: WebSocketMessageBodyReference + + InlinedWebSocketMessageBody: + properties: + name: commons.Name + extends: list + properties: list + + InlinedWebSocketMessageBodyProperty: + extends: commons.WithDocsAndAvailability + properties: + name: commons.NameAndWireValue + valueType: types.TypeReference + + WebSocketMessageBodyReference: + extends: commons.WithDocs + properties: + bodyType: types.TypeReference + + ExampleWebSocketSession: + extends: commons.WithDocs + properties: + name: optional + url: string + pathParameters: list + headers: list + queryParameters: list + messages: list + + ExampleWebSocketMessage: + properties: + type: WebSocketMessageId + body: ExampleWebSocketMessageBody + + ExampleWebSocketMessageBody: + union: + inlinedBody: http.ExampleInlinedRequestBody + reference: types.ExampleTypeReference diff --git a/packages/ir-sdk/fern/apis/ir-types-v54/generators.yml b/packages/ir-sdk/fern/apis/ir-types-v54/generators.yml new file mode 100644 index 00000000000..c6bfcab8564 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v54/generators.yml @@ -0,0 +1,57 @@ +default-group: local +groups: + dynamic-ir: + audiences: + - dynamic + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.38.6 + output: + location: npm + package-name: "@fern-api/dynamic-ir-sdk" + token: ${NPM_TOKEN} + config: + noOptionalProperties: true + noSerdeLayer: true + node: + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.38.6 + output: + location: npm + url: npm.buildwithfern.com + package-name: "@fern-fern/ir-v54-sdk" + config: + includeUtilsOnUnionMembers: true + noOptionalProperties: true + java: + generators: + - name: fernapi/java-model + version: 0.5.20 + output: + location: maven + url: maven.buildwithfern.com + coordinate: com.fern.fern:irV54 + config: + wrapped-aliases: true + enable-forward-compatible-enums: true + python: + generators: + - name: fernapi/fern-pydantic-model + version: 1.4.2 + output: + location: pypi + url: pypi.buildwithfern.com + package-name: fern_fern_ir_v54 + config: + # wrapped_aliases: true + include_union_utils: true + frozen: true + version: v2 + enum_type: python_enums + go: + generators: + - name: fernapi/fern-go-model + version: 0.9.3 + github: + repository: fern-api/ir-go diff --git a/packages/ir-sdk/src/sdk/api/resources/dynamic/resources/types/types/TypeReference.ts b/packages/ir-sdk/src/sdk/api/resources/dynamic/resources/types/types/TypeReference.ts index 7a8f3388d3f..0912e96a149 100644 --- a/packages/ir-sdk/src/sdk/api/resources/dynamic/resources/types/types/TypeReference.ts +++ b/packages/ir-sdk/src/sdk/api/resources/dynamic/resources/types/types/TypeReference.ts @@ -9,6 +9,7 @@ export type TypeReference = | FernIr.dynamic.TypeReference.Literal | FernIr.dynamic.TypeReference.Map | FernIr.dynamic.TypeReference.Named + | FernIr.dynamic.TypeReference.Nullable | FernIr.dynamic.TypeReference.Optional | FernIr.dynamic.TypeReference.Primitive | FernIr.dynamic.TypeReference.Set @@ -34,6 +35,11 @@ export namespace TypeReference { value: FernIr.TypeId; } + export interface Nullable extends _Utils { + type: "nullable"; + value: FernIr.dynamic.TypeReference; + } + export interface Optional extends _Utils { type: "optional"; value: FernIr.dynamic.TypeReference; @@ -62,6 +68,7 @@ export namespace TypeReference { literal: (value: FernIr.dynamic.LiteralType) => _Result; map: (value: FernIr.dynamic.MapType) => _Result; named: (value: FernIr.TypeId) => _Result; + nullable: (value: FernIr.dynamic.TypeReference) => _Result; optional: (value: FernIr.dynamic.TypeReference) => _Result; primitive: (value: FernIr.PrimitiveTypeV1) => _Result; set: (value: FernIr.dynamic.TypeReference) => _Result; @@ -123,6 +130,19 @@ export const TypeReference = { }; }, + nullable: (value: FernIr.dynamic.TypeReference): FernIr.dynamic.TypeReference.Nullable => { + return { + value: value, + type: "nullable", + _visit: function <_Result>( + this: FernIr.dynamic.TypeReference.Nullable, + visitor: FernIr.dynamic.TypeReference._Visitor<_Result>, + ) { + return FernIr.dynamic.TypeReference._visit(this, visitor); + }, + }; + }, + optional: (value: FernIr.dynamic.TypeReference): FernIr.dynamic.TypeReference.Optional => { return { value: value, @@ -187,6 +207,8 @@ export const TypeReference = { return visitor.map(value); case "named": return visitor.named(value.value); + case "nullable": + return visitor.nullable(value.value); case "optional": return visitor.optional(value.value); case "primitive": diff --git a/packages/ir-sdk/src/sdk/api/resources/types/types/ContainerType.ts b/packages/ir-sdk/src/sdk/api/resources/types/types/ContainerType.ts index 379cb459f13..0b63b2f55c2 100644 --- a/packages/ir-sdk/src/sdk/api/resources/types/types/ContainerType.ts +++ b/packages/ir-sdk/src/sdk/api/resources/types/types/ContainerType.ts @@ -7,6 +7,7 @@ import * as FernIr from "../../../index"; export type ContainerType = | FernIr.ContainerType.List | FernIr.ContainerType.Map + | FernIr.ContainerType.Nullable | FernIr.ContainerType.Optional | FernIr.ContainerType.Set | FernIr.ContainerType.Literal; @@ -21,6 +22,11 @@ export namespace ContainerType { type: "map"; } + export interface Nullable extends _Utils { + type: "nullable"; + nullable: FernIr.TypeReference; + } + export interface Optional extends _Utils { type: "optional"; optional: FernIr.TypeReference; @@ -43,6 +49,7 @@ export namespace ContainerType { export interface _Visitor<_Result> { list: (value: FernIr.TypeReference) => _Result; map: (value: FernIr.MapType) => _Result; + nullable: (value: FernIr.TypeReference) => _Result; optional: (value: FernIr.TypeReference) => _Result; set: (value: FernIr.TypeReference) => _Result; literal: (value: FernIr.Literal) => _Result; @@ -77,6 +84,19 @@ export const ContainerType = { }; }, + nullable: (value: FernIr.TypeReference): FernIr.ContainerType.Nullable => { + return { + nullable: value, + type: "nullable", + _visit: function <_Result>( + this: FernIr.ContainerType.Nullable, + visitor: FernIr.ContainerType._Visitor<_Result>, + ) { + return FernIr.ContainerType._visit(this, visitor); + }, + }; + }, + optional: (value: FernIr.TypeReference): FernIr.ContainerType.Optional => { return { optional: value, @@ -122,6 +142,8 @@ export const ContainerType = { return visitor.list(value.list); case "map": return visitor.map(value); + case "nullable": + return visitor.nullable(value.nullable); case "optional": return visitor.optional(value.optional); case "set": diff --git a/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleContainer.ts b/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleContainer.ts index 897086728d5..61129cf8fc0 100644 --- a/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleContainer.ts +++ b/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleContainer.ts @@ -8,6 +8,7 @@ export type ExampleContainer = | FernIr.ExampleContainer.List | FernIr.ExampleContainer.Set | FernIr.ExampleContainer.Optional + | FernIr.ExampleContainer.Nullable | FernIr.ExampleContainer.Map | FernIr.ExampleContainer.Literal; @@ -24,6 +25,10 @@ export namespace ExampleContainer { type: "optional"; } + export interface Nullable extends FernIr.ExampleNullableContainer, _Utils { + type: "nullable"; + } + export interface Map extends FernIr.ExampleMapContainer, _Utils { type: "map"; } @@ -40,6 +45,7 @@ export namespace ExampleContainer { list: (value: FernIr.ExampleListContainer) => _Result; set: (value: FernIr.ExampleSetContainer) => _Result; optional: (value: FernIr.ExampleOptionalContainer) => _Result; + nullable: (value: FernIr.ExampleNullableContainer) => _Result; map: (value: FernIr.ExampleMapContainer) => _Result; literal: (value: FernIr.ExampleLiteralContainer) => _Result; _other: (value: { type: string }) => _Result; @@ -86,6 +92,19 @@ export const ExampleContainer = { }; }, + nullable: (value: FernIr.ExampleNullableContainer): FernIr.ExampleContainer.Nullable => { + return { + ...value, + type: "nullable", + _visit: function <_Result>( + this: FernIr.ExampleContainer.Nullable, + visitor: FernIr.ExampleContainer._Visitor<_Result>, + ) { + return FernIr.ExampleContainer._visit(this, visitor); + }, + }; + }, + map: (value: FernIr.ExampleMapContainer): FernIr.ExampleContainer.Map => { return { ...value, @@ -120,6 +139,8 @@ export const ExampleContainer = { return visitor.set(value); case "optional": return visitor.optional(value); + case "nullable": + return visitor.nullable(value); case "map": return visitor.map(value); case "literal": diff --git a/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleNullableContainer.ts b/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleNullableContainer.ts new file mode 100644 index 00000000000..e3df356b5d9 --- /dev/null +++ b/packages/ir-sdk/src/sdk/api/resources/types/types/ExampleNullableContainer.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernIr from "../../../index"; + +export interface ExampleNullableContainer { + nullable: FernIr.ExampleTypeReference | undefined; + valueType: FernIr.TypeReference; +} diff --git a/packages/ir-sdk/src/sdk/api/resources/types/types/index.ts b/packages/ir-sdk/src/sdk/api/resources/types/types/index.ts index 60fceb88382..713720f316b 100644 --- a/packages/ir-sdk/src/sdk/api/resources/types/types/index.ts +++ b/packages/ir-sdk/src/sdk/api/resources/types/types/index.ts @@ -61,6 +61,7 @@ export * from "./ExampleContainer"; export * from "./ExampleListContainer"; export * from "./ExampleSetContainer"; export * from "./ExampleOptionalContainer"; +export * from "./ExampleNullableContainer"; export * from "./ExampleMapContainer"; export * from "./ExampleLiteralContainer"; export * from "./ExampleKeyValuePair"; diff --git a/packages/ir-sdk/src/sdk/serialization/resources/dynamic/resources/types/types/TypeReference.ts b/packages/ir-sdk/src/sdk/serialization/resources/dynamic/resources/types/types/TypeReference.ts index 0fbe4c40c2e..f0b3c5c3fc3 100644 --- a/packages/ir-sdk/src/sdk/serialization/resources/dynamic/resources/types/types/TypeReference.ts +++ b/packages/ir-sdk/src/sdk/serialization/resources/dynamic/resources/types/types/TypeReference.ts @@ -24,6 +24,9 @@ export const TypeReference: core.serialization.Schema< named: core.serialization.object({ value: TypeId, }), + nullable: core.serialization.object({ + value: core.serialization.lazy(() => serializers.dynamic.TypeReference), + }), optional: core.serialization.object({ value: core.serialization.lazy(() => serializers.dynamic.TypeReference), }), @@ -46,6 +49,8 @@ export const TypeReference: core.serialization.Schema< return FernIr.dynamic.TypeReference.map(value); case "named": return FernIr.dynamic.TypeReference.named(value.value); + case "nullable": + return FernIr.dynamic.TypeReference.nullable(value.value); case "optional": return FernIr.dynamic.TypeReference.optional(value.value); case "primitive": @@ -67,6 +72,7 @@ export declare namespace TypeReference { | TypeReference.Literal | TypeReference.Map | TypeReference.Named + | TypeReference.Nullable | TypeReference.Optional | TypeReference.Primitive | TypeReference.Set @@ -91,6 +97,11 @@ export declare namespace TypeReference { value: TypeId.Raw; } + export interface Nullable { + type: "nullable"; + value: serializers.dynamic.TypeReference.Raw; + } + export interface Optional { type: "optional"; value: serializers.dynamic.TypeReference.Raw; diff --git a/packages/ir-sdk/src/sdk/serialization/resources/types/types/ContainerType.ts b/packages/ir-sdk/src/sdk/serialization/resources/types/types/ContainerType.ts index 5c0cc84fe37..3eb815006f0 100644 --- a/packages/ir-sdk/src/sdk/serialization/resources/types/types/ContainerType.ts +++ b/packages/ir-sdk/src/sdk/serialization/resources/types/types/ContainerType.ts @@ -14,6 +14,9 @@ export const ContainerType: core.serialization.Schema serializers.TypeReference), }), map: core.serialization.lazyObject(() => serializers.MapType), + nullable: core.serialization.object({ + nullable: core.serialization.lazy(() => serializers.TypeReference), + }), optional: core.serialization.object({ optional: core.serialization.lazy(() => serializers.TypeReference), }), @@ -31,6 +34,8 @@ export const ContainerType: core.serialization.Schema serializers.ExampleListContainer), set: core.serialization.lazyObject(() => serializers.ExampleSetContainer), optional: core.serialization.lazyObject(() => serializers.ExampleOptionalContainer), + nullable: core.serialization.lazyObject(() => serializers.ExampleNullableContainer), map: core.serialization.lazyObject(() => serializers.ExampleMapContainer), literal: ExampleLiteralContainer, }) @@ -25,6 +26,8 @@ export const ExampleContainer: core.serialization.Schema = core.serialization.objectWithoutOptionalProperties({ + nullable: core.serialization.lazyObject(() => serializers.ExampleTypeReference).optional(), + valueType: core.serialization.lazy(() => serializers.TypeReference), +}); + +export declare namespace ExampleNullableContainer { + export interface Raw { + nullable?: serializers.ExampleTypeReference.Raw | null; + valueType: serializers.TypeReference.Raw; + } +} diff --git a/packages/ir-sdk/src/sdk/serialization/resources/types/types/index.ts b/packages/ir-sdk/src/sdk/serialization/resources/types/types/index.ts index 60fceb88382..713720f316b 100644 --- a/packages/ir-sdk/src/sdk/serialization/resources/types/types/index.ts +++ b/packages/ir-sdk/src/sdk/serialization/resources/types/types/index.ts @@ -61,6 +61,7 @@ export * from "./ExampleContainer"; export * from "./ExampleListContainer"; export * from "./ExampleSetContainer"; export * from "./ExampleOptionalContainer"; +export * from "./ExampleNullableContainer"; export * from "./ExampleMapContainer"; export * from "./ExampleLiteralContainer"; export * from "./ExampleKeyValuePair"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f22f930b952..031313bced9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5773,6 +5773,9 @@ importers: '@fern-fern/ir-v53-sdk': specifier: 0.0.1 version: 0.0.1 + '@fern-fern/ir-v54-sdk': + specifier: 0.0.1 + version: 0.0.1 '@fern-fern/ir-v6-model': specifier: 0.0.33 version: 0.0.33 @@ -8962,6 +8965,9 @@ packages: '@fern-fern/ir-v53-sdk@0.0.1': resolution: {integrity: sha512-7KNvdLlWyYkkhVsplvVmVKm6+LCGKTQJxE7jqjmjg+1AUBC75zcGAkiHylDLB8gkOCLN3Qcs2RHljC0yHVLlOw==} + '@fern-fern/ir-v54-sdk@0.0.1': + resolution: {integrity: sha512-RyVtsKaeLQNr6WAgVG/eMO9YFXVs68pthof1p+IJ4/1acKLB8pONR0Tg2qr7y+6yek1Ch3bbgs6JFyxvsCEjrQ==} + '@fern-fern/ir-v6-model@0.0.33': resolution: {integrity: sha512-I3KLvdrRzSrh5CcpU0v/Mjn4ywZhzVwhqJC8IDIQiP1yPvsCnjgbTBNwLRG8KdJqHfLOgdt/hfVzjeuFugSlGA==} @@ -15893,6 +15899,8 @@ snapshots: '@fern-fern/ir-v53-sdk@0.0.1': {} + '@fern-fern/ir-v54-sdk@0.0.1': {} + '@fern-fern/ir-v6-model@0.0.33': {} '@fern-fern/ir-v7-model@0.0.2': {}