diff --git a/fern/docs.yml b/fern/docs.yml
index 60f44f05e8b..a4f1d70a6c6 100644
--- a/fern/docs.yml
+++ b/fern/docs.yml
@@ -155,6 +155,10 @@ navigation:
icon: fa-regular fa-file
path: ./pages/api-definition/fern-definition/endpoints/multipart.mdx
slug: multipart
+ - page: Bytes
+ path: ./pages/api-definition/fern-definition/endpoints/bytes.mdx
+ icon: fa-regular fa-server
+ slug: bytes
- page: Server Sent Events
icon: fa-regular fa-signal-stream
path: ./pages/api-definition/fern-definition/endpoints/sse.mdx
diff --git a/fern/pages/api-definition/fern-definition/endpoints/bytes.mdx b/fern/pages/api-definition/fern-definition/endpoints/bytes.mdx
new file mode 100644
index 00000000000..20672d09424
--- /dev/null
+++ b/fern/pages/api-definition/fern-definition/endpoints/bytes.mdx
@@ -0,0 +1,55 @@
+---
+title: Binary Data and Files
+subtitle: Use the `bytes` type to handle binary data in your API
+---
+
+
+ The `bytes` type allows you to handle binary data in both requests and responses.
+
+
+## Sending bytes
+
+If your API needs to send a stream of bytes (i.e. typical for assets like audio, images and other files) then
+you can use the `bytes` type in the Fern Definition to model this.
+
+```yml audio.yml
+service:
+ base-path: /audio
+ endpoints:
+ upload:
+ display-name: Upload audio
+ method: POST
+ path: /upload
+ content-type: application/octet-stream
+ request:
+ type: bytes
+ docs: The bytes of the MP3 file that you would like to upload
+```
+
+## Receiving bytes
+
+On the other hand, if your API is returning a stream of bytes, then you can leverage the `bytes` type as a response.
+
+```yml textToSpeech.yml
+service:
+ base-path: /tts
+ endpoints:
+ upload:
+ display-name: Upload audio
+ method: POST
+ path: ""
+ request:
+ name: TTSRequest
+ body:
+ properties:
+ text:
+ type: string
+ docs: The text that you want converted to speach.
+ response:
+ type: bytes
+ docs: The bytes of the audio file.
+```
+
+
+
+
diff --git a/packages/cli/cli/versions.yml b/packages/cli/cli/versions.yml
index 9cb3833c404..c364ba3aa86 100644
--- a/packages/cli/cli/versions.yml
+++ b/packages/cli/cli/versions.yml
@@ -1,3 +1,16 @@
+- changelogEntry:
+ - summary: |
+ The Fern Definition now supports `bytes` as a response type.
+
+ ```yml service.yml
+ endpoints:
+ download:
+ response: bytes
+ ```
+ type: feat
+ irVersion: 53
+ version: 0.46.0-rc0
+
- changelogEntry:
- summary: |
Defaults are no longer set on datetimes when converting to docs shapes.
diff --git a/packages/cli/generation/ir-generator/src/converters/services/convertHttpResponse.ts b/packages/cli/generation/ir-generator/src/converters/services/convertHttpResponse.ts
index dfa46f3ccd4..da228af6915 100644
--- a/packages/cli/generation/ir-generator/src/converters/services/convertHttpResponse.ts
+++ b/packages/cli/generation/ir-generator/src/converters/services/convertHttpResponse.ts
@@ -6,7 +6,13 @@ import {
NonStreamHttpResponseBody,
StreamingResponse
} from "@fern-api/ir-sdk";
-import { isRawTextType, parseRawFileType, parseRawTextType, RawSchemas } from "@fern-api/fern-definition-schema";
+import {
+ isRawTextType,
+ parseRawFileType,
+ parseRawTextType,
+ parseRawBytesType,
+ RawSchemas
+} from "@fern-api/fern-definition-schema";
import { FernFileContext } from "../../FernFileContext";
import { TypeResolver } from "../../resolvers/TypeResolver";
import { getObjectPropertyFromResolvedType } from "./getObjectPropertyFromResolvedType";
@@ -69,6 +75,10 @@ export function convertHttpResponseBody({
nonStreamResponse = NonStreamHttpResponseBody.text({ ...response });
break;
}
+ case "bytes": {
+ nonStreamResponse = NonStreamHttpResponseBody.bytes({ ...response });
+ break;
+ }
default:
assertNever(response);
}
@@ -93,7 +103,7 @@ export function convertNonStreamHttpResponseBody({
endpoint: RawSchemas.HttpEndpointSchema;
file: FernFileContext;
typeResolver: TypeResolver;
-}): HttpResponseBody.FileDownload | HttpResponseBody.Text | HttpResponseBody.Json | undefined {
+}): HttpResponseBody.FileDownload | HttpResponseBody.Text | HttpResponseBody.Json | HttpResponseBody.Bytes | undefined {
const { response } = endpoint;
if (response != null) {
@@ -108,6 +118,10 @@ export function convertNonStreamHttpResponseBody({
return HttpResponseBody.text({
docs
});
+ } else if (parseRawBytesType(responseType) != null) {
+ return HttpResponseBody.bytes({
+ docs
+ });
} else {
return convertJsonResponse(response, docs, file, typeResolver);
}
diff --git a/packages/cli/generation/ir-generator/src/examples/generator/generateSuccessEndpointExample.ts b/packages/cli/generation/ir-generator/src/examples/generator/generateSuccessEndpointExample.ts
index 404577d87a2..1ba3b1dbba1 100644
--- a/packages/cli/generation/ir-generator/src/examples/generator/generateSuccessEndpointExample.ts
+++ b/packages/cli/generation/ir-generator/src/examples/generator/generateSuccessEndpointExample.ts
@@ -262,6 +262,8 @@ export function generateEndpointExample({
return { type: "failure", message: "Streaming unsupported" };
case "text":
return { type: "failure", message: "Text unsupported" };
+ case "bytes":
+ return { type: "failure", message: "Bytes unsupported" };
default:
assertNever(endpoint.response.body);
}
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 62d354b627b..292fcd2a04b 100644
--- a/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts
+++ b/packages/cli/generation/ir-generator/src/filtered-ir/IrGraph.ts
@@ -257,6 +257,7 @@ export class IrGraph {
}
},
text: noop,
+ bytes: noop,
_other: () => {
throw new Error("Unknown HttpResponse: " + httpEndpoint.response?.body?.type);
}
diff --git a/packages/cli/generation/ir-migrations/package.json b/packages/cli/generation/ir-migrations/package.json
index 471f9dd1dae..367cf824191 100644
--- a/packages/cli/generation/ir-migrations/package.json
+++ b/packages/cli/generation/ir-migrations/package.json
@@ -86,6 +86,7 @@
"@fern-fern/ir-v50-sdk": "0.0.3",
"@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-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 a1f0f50fb13..b09f640b32e 100644
--- a/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts
+++ b/packages/cli/generation/ir-migrations/src/IntermediateRepresentationMigrator.ts
@@ -51,6 +51,7 @@ import { V50_TO_V49_MIGRATION } from "./migrations/v50-to-v49/migrateFromV50ToV4
import { V51_TO_V50_MIGRATION } from "./migrations/v51-to-v50/migrateFromV51ToV50";
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 { V6_TO_V5_MIGRATION } from "./migrations/v6-to-v5/migrateFromV6ToV5";
import { V7_TO_V6_MIGRATION } from "./migrations/v7-to-v6/migrateFromV7ToV6";
import { V8_TO_V7_MIGRATION } from "./migrations/v8-to-v7/migrateFromV8ToV7";
@@ -279,6 +280,7 @@ const IntermediateRepresentationMigrator = {
const INTERMEDIATE_REPRESENTATION_MIGRATOR = IntermediateRepresentationMigrator.Builder
// put new migrations here
+ .withMigration(V54_TO_V53_MIGRATION)
.withMigration(V53_TO_V52_MIGRATION)
.withMigration(V52_TO_V51_MIGRATION)
.withMigration(V51_TO_V50_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 db32068c4be..d56ae8a7bbd 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 V53 } from "@fern-api/ir-sdk";
+export { serialization as V54 } 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";
@@ -29,3 +29,4 @@ export * as V49 from "@fern-fern/ir-v49-sdk/serialization";
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";
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 ca71ce96416..4644622a225 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 V53 } from "@fern-api/ir-sdk";
+export { FernIr as V54 } 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";
@@ -47,6 +47,7 @@ export * as V5 from "@fern-fern/ir-v5-model";
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 * 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/v54-to-v53/__test__/__snapshots__/migrateFromV53ToV52.test.ts.snap b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/__snapshots__/migrateFromV53ToV52.test.ts.snap
new file mode 100644
index 00000000000..b044632e6b1
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/__snapshots__/migrateFromV53ToV52.test.ts.snap
@@ -0,0 +1,1001 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`migrateFromV54ToV53 > 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.getAudioFile": {
+ "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": "getAudioFile",
+ "unsafeName": "getAudioFile",
+ },
+ "originalName": "getAudioFile",
+ "pascalCase": {
+ "safeName": "GetAudioFile",
+ "unsafeName": "GetAudioFile",
+ },
+ "screamingSnakeCase": {
+ "safeName": "GET_AUDIO_FILE",
+ "unsafeName": "GET_AUDIO_FILE",
+ },
+ "snakeCase": {
+ "safeName": "get_audio_file",
+ "unsafeName": "get_audio_file",
+ },
+ },
+ },
+ "location": {
+ "method": "GET",
+ "path": "/audio",
+ },
+ "request": {
+ "body": null,
+ "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": "getAudioRequest",
+ "unsafeName": "getAudioRequest",
+ },
+ "originalName": "GetAudioRequest",
+ "pascalCase": {
+ "safeName": "GetAudioRequest",
+ "unsafeName": "GetAudioRequest",
+ },
+ "screamingSnakeCase": {
+ "safeName": "GET_AUDIO_REQUEST",
+ "unsafeName": "GET_AUDIO_REQUEST",
+ },
+ "snakeCase": {
+ "safeName": "get_audio_request",
+ "unsafeName": "get_audio_request",
+ },
+ },
+ },
+ "headers": [],
+ "metadata": {
+ "includePathParameters": false,
+ "onlyPathParameters": false,
+ },
+ "pathParameters": [],
+ "queryParameters": [
+ {
+ "name": {
+ "name": {
+ "camelCase": {
+ "safeName": "format",
+ "unsafeName": "format",
+ },
+ "originalName": "format",
+ "pascalCase": {
+ "safeName": "Format",
+ "unsafeName": "Format",
+ },
+ "screamingSnakeCase": {
+ "safeName": "FORMAT",
+ "unsafeName": "FORMAT",
+ },
+ "snakeCase": {
+ "safeName": "format",
+ "unsafeName": "format",
+ },
+ },
+ "wireValue": "format",
+ },
+ "typeReference": {
+ "type": "named",
+ "value": "type_service:AudioFormat",
+ },
+ },
+ ],
+ "type": "inlined",
+ },
+ "response": {
+ "type": "json",
+ },
+ },
+ },
+ "headers": [],
+ "types": {
+ "type_service:AudioFormat": {
+ "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": "audioFormat",
+ "unsafeName": "audioFormat",
+ },
+ "originalName": "AudioFormat",
+ "pascalCase": {
+ "safeName": "AudioFormat",
+ "unsafeName": "AudioFormat",
+ },
+ "screamingSnakeCase": {
+ "safeName": "AUDIO_FORMAT",
+ "unsafeName": "AUDIO_FORMAT",
+ },
+ "snakeCase": {
+ "safeName": "audio_format",
+ "unsafeName": "audio_format",
+ },
+ },
+ },
+ "type": "enum",
+ "values": [
+ {
+ "name": {
+ "camelCase": {
+ "safeName": "mp3",
+ "unsafeName": "mp3",
+ },
+ "originalName": "MP3",
+ "pascalCase": {
+ "safeName": "Mp3",
+ "unsafeName": "Mp3",
+ },
+ "screamingSnakeCase": {
+ "safeName": "MP3",
+ "unsafeName": "MP3",
+ },
+ "snakeCase": {
+ "safeName": "mp3",
+ "unsafeName": "mp3",
+ },
+ },
+ "wireValue": "MP3",
+ },
+ {
+ "name": {
+ "camelCase": {
+ "safeName": "wav",
+ "unsafeName": "wav",
+ },
+ "originalName": "WAV",
+ "pascalCase": {
+ "safeName": "Wav",
+ "unsafeName": "Wav",
+ },
+ "screamingSnakeCase": {
+ "safeName": "WAV",
+ "unsafeName": "WAV",
+ },
+ "snakeCase": {
+ "safeName": "wav",
+ "unsafeName": "wav",
+ },
+ },
+ "wireValue": "WAV",
+ },
+ {
+ "name": {
+ "camelCase": {
+ "safeName": "ogg",
+ "unsafeName": "ogg",
+ },
+ "originalName": "OGG",
+ "pascalCase": {
+ "safeName": "Ogg",
+ "unsafeName": "Ogg",
+ },
+ "screamingSnakeCase": {
+ "safeName": "OGG",
+ "unsafeName": "OGG",
+ },
+ "snakeCase": {
+ "safeName": "ogg",
+ "unsafeName": "ogg",
+ },
+ },
+ "wireValue": "OGG",
+ },
+ ],
+ },
+ },
+ "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:AudioFormat",
+ ],
+ },
+ },
+ "services": {
+ "service_service": {
+ "availability": null,
+ "basePath": {
+ "head": "/",
+ "parts": [],
+ },
+ "displayName": null,
+ "encoding": {
+ "json": {},
+ "proto": null,
+ },
+ "endpoints": [
+ {
+ "allPathParameters": [],
+ "auth": false,
+ "autogeneratedExamples": [],
+ "availability": null,
+ "basePath": null,
+ "baseUrl": null,
+ "displayName": null,
+ "docs": null,
+ "errors": [],
+ "fullPath": {
+ "head": "/audio",
+ "parts": [],
+ },
+ "headers": [],
+ "id": "endpoint_service.getAudioFile",
+ "idempotent": false,
+ "method": "GET",
+ "name": {
+ "camelCase": {
+ "safeName": "getAudioFile",
+ "unsafeName": "getAudioFile",
+ },
+ "originalName": "getAudioFile",
+ "pascalCase": {
+ "safeName": "GetAudioFile",
+ "unsafeName": "GetAudioFile",
+ },
+ "screamingSnakeCase": {
+ "safeName": "GET_AUDIO_FILE",
+ "unsafeName": "GET_AUDIO_FILE",
+ },
+ "snakeCase": {
+ "safeName": "get_audio_file",
+ "unsafeName": "get_audio_file",
+ },
+ },
+ "pagination": null,
+ "path": {
+ "head": "/audio",
+ "parts": [],
+ },
+ "pathParameters": [],
+ "queryParameters": [
+ {
+ "allowMultiple": false,
+ "availability": null,
+ "docs": null,
+ "name": {
+ "name": {
+ "camelCase": {
+ "safeName": "format",
+ "unsafeName": "format",
+ },
+ "originalName": "format",
+ "pascalCase": {
+ "safeName": "Format",
+ "unsafeName": "Format",
+ },
+ "screamingSnakeCase": {
+ "safeName": "FORMAT",
+ "unsafeName": "FORMAT",
+ },
+ "snakeCase": {
+ "safeName": "format",
+ "unsafeName": "format",
+ },
+ },
+ "wireValue": "format",
+ },
+ "valueType": {
+ "_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": "audioFormat",
+ "unsafeName": "audioFormat",
+ },
+ "originalName": "AudioFormat",
+ "pascalCase": {
+ "safeName": "AudioFormat",
+ "unsafeName": "AudioFormat",
+ },
+ "screamingSnakeCase": {
+ "safeName": "AUDIO_FORMAT",
+ "unsafeName": "AUDIO_FORMAT",
+ },
+ "snakeCase": {
+ "safeName": "audio_format",
+ "unsafeName": "audio_format",
+ },
+ },
+ "typeId": "type_service:AudioFormat",
+ },
+ },
+ ],
+ "requestBody": null,
+ "response": {
+ "body": {
+ "docs": null,
+ "type": "fileDownload",
+ },
+ "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": "getAudioRequest",
+ "unsafeName": "getAudioRequest",
+ },
+ "originalName": "GetAudioRequest",
+ "pascalCase": {
+ "safeName": "GetAudioRequest",
+ "unsafeName": "GetAudioRequest",
+ },
+ "screamingSnakeCase": {
+ "safeName": "GET_AUDIO_REQUEST",
+ "unsafeName": "GET_AUDIO_REQUEST",
+ },
+ "snakeCase": {
+ "safeName": "get_audio_request",
+ "unsafeName": "get_audio_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:AudioFormat",
+ ],
+ "webhooks": null,
+ "websocket": null,
+ },
+ },
+ "types": {
+ "type_service:AudioFormat": {
+ "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": "audioFormat",
+ "unsafeName": "audioFormat",
+ },
+ "originalName": "AudioFormat",
+ "pascalCase": {
+ "safeName": "AudioFormat",
+ "unsafeName": "AudioFormat",
+ },
+ "screamingSnakeCase": {
+ "safeName": "AUDIO_FORMAT",
+ "unsafeName": "AUDIO_FORMAT",
+ },
+ "snakeCase": {
+ "safeName": "audio_format",
+ "unsafeName": "audio_format",
+ },
+ },
+ "typeId": "type_service:AudioFormat",
+ },
+ "referencedTypes": [],
+ "shape": {
+ "_type": "enum",
+ "default": null,
+ "values": [
+ {
+ "availability": null,
+ "docs": null,
+ "name": {
+ "name": {
+ "camelCase": {
+ "safeName": "mp3",
+ "unsafeName": "mp3",
+ },
+ "originalName": "MP3",
+ "pascalCase": {
+ "safeName": "Mp3",
+ "unsafeName": "Mp3",
+ },
+ "screamingSnakeCase": {
+ "safeName": "MP3",
+ "unsafeName": "MP3",
+ },
+ "snakeCase": {
+ "safeName": "mp3",
+ "unsafeName": "mp3",
+ },
+ },
+ "wireValue": "MP3",
+ },
+ },
+ {
+ "availability": null,
+ "docs": null,
+ "name": {
+ "name": {
+ "camelCase": {
+ "safeName": "wav",
+ "unsafeName": "wav",
+ },
+ "originalName": "WAV",
+ "pascalCase": {
+ "safeName": "Wav",
+ "unsafeName": "Wav",
+ },
+ "screamingSnakeCase": {
+ "safeName": "WAV",
+ "unsafeName": "WAV",
+ },
+ "snakeCase": {
+ "safeName": "wav",
+ "unsafeName": "wav",
+ },
+ },
+ "wireValue": "WAV",
+ },
+ },
+ {
+ "availability": null,
+ "docs": null,
+ "name": {
+ "name": {
+ "camelCase": {
+ "safeName": "ogg",
+ "unsafeName": "ogg",
+ },
+ "originalName": "OGG",
+ "pascalCase": {
+ "safeName": "Ogg",
+ "unsafeName": "Ogg",
+ },
+ "screamingSnakeCase": {
+ "safeName": "OGG",
+ "unsafeName": "OGG",
+ },
+ "snakeCase": {
+ "safeName": "ogg",
+ "unsafeName": "ogg",
+ },
+ },
+ "wireValue": "OGG",
+ },
+ },
+ ],
+ },
+ "source": null,
+ "userProvidedExamples": [],
+ },
+ },
+ "variables": [],
+ "webhookGroups": {},
+ "websocketChannels": {},
+}
+`;
diff --git a/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/definition/api.yml b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/definition/api.yml
new file mode 100644
index 00000000000..cc1ca43b9bc
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__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/v54-to-v53/__test__/fixtures/simple/definition/service.yml b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/definition/service.yml
new file mode 100644
index 00000000000..8a4f7668597
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/definition/service.yml
@@ -0,0 +1,21 @@
+types:
+ AudioFormat:
+ enum:
+ - MP3
+ - WAV
+ - OGG
+
+service:
+ auth: false
+ base-path: /
+ endpoints:
+ getAudioFile:
+ method: GET
+ path: /audio
+ request:
+ name: GetAudioRequest
+ query-parameters:
+ format:
+ type: AudioFormat
+ default: MP3
+ response: bytes
\ No newline at end of file
diff --git a/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/generators.yml b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/generators.yml
new file mode 100644
index 00000000000..0967ef424bc
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/fixtures/simple/generators.yml
@@ -0,0 +1 @@
+{}
diff --git a/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/migrateFromV53ToV52.test.ts b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/migrateFromV53ToV52.test.ts
new file mode 100644
index 00000000000..0dcd1e0ce0d
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/__test__/migrateFromV53ToV52.test.ts
@@ -0,0 +1,15 @@
+import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils";
+import { createMigrationTester } from "../../../__test__/utils/createMigrationTester";
+import { V54_TO_V53_MIGRATION } from "../migrateFromV54ToV53";
+
+const runMigration = createMigrationTester(V54_TO_V53_MIGRATION);
+
+describe("migrateFromV54ToV53", () => {
+ 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/v54-to-v53/migrateFromV54ToV53.ts b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/migrateFromV54ToV53.ts
new file mode 100644
index 00000000000..75a644233f3
--- /dev/null
+++ b/packages/cli/generation/ir-migrations/src/migrations/v54-to-v53/migrateFromV54ToV53.ts
@@ -0,0 +1,82 @@
+import { GeneratorName } from "@fern-api/configuration-loader";
+import { mapValues } from "lodash-es";
+import { IrSerialization } from "../../ir-serialization";
+import { IrVersions } from "../../ir-versions";
+import {
+ GeneratorWasNeverUpdatedToConsumeNewIR,
+ GeneratorWasNotCreatedYet,
+ IrMigration
+} from "../../types/IrMigration";
+
+export const V54_TO_V53_MIGRATION: IrMigration<
+ IrVersions.V54.ir.IntermediateRepresentation,
+ IrVersions.V53.ir.IntermediateRepresentation
+> = {
+ laterVersion: "v54",
+ earlierVersion: "v53",
+ 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.V53.IntermediateRepresentation.jsonOrThrow(ir, {
+ unrecognizedObjectKeys: "strip",
+ skipValidation: true
+ }),
+ migrateBackwards: (v54): IrVersions.V53.ir.IntermediateRepresentation => {
+ return {
+ ...v54,
+ services: mapValues(v54.services, (service) => ({
+ ...service,
+ endpoints: service.endpoints.map((endpoint) => ({
+ ...endpoint,
+ response: convertHttpResponse(endpoint.response)
+ }))
+ }))
+ };
+ }
+};
+
+function convertHttpResponse(
+ response: IrVersions.V54.HttpResponse | undefined
+): IrVersions.V53.HttpResponse | undefined {
+ if (response == null) {
+ return undefined;
+ }
+
+ return {
+ statusCode: response.statusCode,
+ body:
+ response.body?.type === "bytes"
+ ? IrVersions.V53.HttpResponseBody.fileDownload({
+ docs: undefined
+ })
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (response.body as any)
+ };
+}
diff --git a/packages/cli/register/src/ir-to-fdr-converter/convertPackage.ts b/packages/cli/register/src/ir-to-fdr-converter/convertPackage.ts
index a6f1b96a28f..cbd95fb57a9 100644
--- a/packages/cli/register/src/ir-to-fdr-converter/convertPackage.ts
+++ b/packages/cli/register/src/ir-to-fdr-converter/convertPackage.ts
@@ -520,6 +520,7 @@ function convertResponse(irResponse: Ir.http.HttpResponse): FdrCjsSdk.api.v1.reg
};
},
text: () => undefined, // TODO: support text/plain in FDR
+ bytes: () => undefined, // TODO: support text/plain in FDR
streamParameter: () => undefined, // TODO: support stream parameter in FDR
streaming: (streamingResponse) => {
if (streamingResponse.type === "text") {
diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/VERSION b/packages/ir-sdk/fern/apis/ir-types-latest/VERSION
index 1eebf35d56f..89d18917ebe 100644
--- a/packages/ir-sdk/fern/apis/ir-types-latest/VERSION
+++ b/packages/ir-sdk/fern/apis/ir-types-latest/VERSION
@@ -1 +1 @@
-53.24.0
+54.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 2e23ee9028a..bdeacf8dd51 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,11 @@ 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).
+## [v54.0.0] - 2024-12-11
+
+- Break: The HttpResponse type in the IR now supports bytes responses. This is useful for different languages -
+ for example TypeScript can return an `ArrayBuffer` instead of `stream.Readable` in this case.
+
## [v53.24.0] - 2024-11-04
- Feature: The dynamic snippets IR supports a configurable baseURL and/or environment.
diff --git a/packages/ir-sdk/fern/apis/ir-types-latest/definition/http.yml b/packages/ir-sdk/fern/apis/ir-types-latest/definition/http.yml
index 01185fd04ab..820550e8f88 100644
--- a/packages/ir-sdk/fern/apis/ir-types-latest/definition/http.yml
+++ b/packages/ir-sdk/fern/apis/ir-types-latest/definition/http.yml
@@ -194,12 +194,14 @@ types:
json: JsonResponse
fileDownload: FileDownloadResponse
text: TextResponse
+ bytes: BytesResponse
HttpResponseBody:
union:
json: JsonResponse
fileDownload: FileDownloadResponse
text: TextResponse
+ bytes: BytesResponse
streaming: StreamingResponse
streamParameter:
type: StreamParameterResponse
@@ -235,6 +237,9 @@ types:
TextResponse:
extends: commons.WithDocs
+
+ BytesResponse:
+ extends: commons.WithDocs
StreamParameterResponse:
properties:
diff --git a/packages/ir-sdk/fern/apis/ir-types-v53/VERSION b/packages/ir-sdk/fern/apis/ir-types-v53/VERSION
new file mode 100644
index 00000000000..cee221857a4
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/VERSION
@@ -0,0 +1 @@
+53.23.0
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
new file mode 100644
index 00000000000..34631de1847
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/changelog/CHANGELOG.md
@@ -0,0 +1,221 @@
+# 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-v53/definition/api.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/api.yml
new file mode 100644
index 00000000000..df8a217c3d7
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/definition/api.yml
@@ -0,0 +1,9 @@
+name: ir-v53
+audiences:
+ - dynamic
+
+# Notes:
+# - Add dynamic IR and generator-exec config.
+# - Add `float` primitive type.
+# - Add a `PrimitiveTypeV2` variant for every `PrimitiveTypeV1`.
+# - Add gRPC/Protobuf types.
\ No newline at end of file
diff --git a/packages/ir-sdk/fern/apis/ir-types-v53/definition/auth.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/auth.yml
new file mode 100644
index 00000000000..be4c49e7ff4
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/commons.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/commons.yml
new file mode 100644
index 00000000000..781c25fa1ce
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/constants.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/constants.yml
new file mode 100644
index 00000000000..8ceb53bb12b
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/dynamic/auth.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/auth.yml
new file mode 100644
index 00000000000..9df1bc0585c
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/dynamic/declaration.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/declaration.yml
new file mode 100644
index 00000000000..903ca06a542
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/dynamic/endpoints.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/endpoints.yml
new file mode 100644
index 00000000000..82b479d5863
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/dynamic/ir.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/ir.yml
new file mode 100644
index 00000000000..ef78d99015d
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/ir.yml
@@ -0,0 +1,26 @@
+imports:
+ commons: ../commons.yml
+ endpoints: ./endpoints.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>
diff --git a/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/snippets.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/snippets.yml
new file mode 100644
index 00000000000..ddb48eb3905
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/snippets.yml
@@ -0,0 +1,54 @@
+imports:
+ auth: ./auth.yml
+ endpoints: ./endpoints.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
+ 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-v53/definition/dynamic/types.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/dynamic/types.yml
new file mode 100644
index 00000000000..635de0246ac
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/environment.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/environment.yml
new file mode 100644
index 00000000000..3f076c5a466
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/errors.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/errors.yml
new file mode 100644
index 00000000000..3888562cbc0
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/generator-exec/config.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/generator-exec/config.yml
new file mode 100644
index 00000000000..22846a5f8fa
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/http.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/http.yml
new file mode 100644
index 00000000000..01185fd04ab
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/definition/http.yml
@@ -0,0 +1,473 @@
+# 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
+
+ HttpResponseBody:
+ union:
+ json: JsonResponse
+ fileDownload: FileDownloadResponse
+ text: TextResponse
+ 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
+
+ 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-v53/definition/ir.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/ir.yml
new file mode 100644
index 00000000000..ef42039791a
--- /dev/null
+++ b/packages/ir-sdk/fern/apis/ir-types-v53/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