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> + 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-v53/definition/proto.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/proto.yml new file mode 100644 index 00000000000..75f82571326 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/publish.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/publish.yml new file mode 100644 index 00000000000..54c523899bd --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/types.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/types.yml new file mode 100644 index 00000000000..48c0f173782 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/variables.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/variables.yml new file mode 100644 index 00000000000..2c196becb01 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/webhooks.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/webhooks.yml new file mode 100644 index 00000000000..13d33bd6883 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/definition/websocket.yml b/packages/ir-sdk/fern/apis/ir-types-v53/definition/websocket.yml new file mode 100644 index 00000000000..98b427e60f5 --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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-v53/generators.yml b/packages/ir-sdk/fern/apis/ir-types-v53/generators.yml new file mode 100644 index 00000000000..d797db4b66e --- /dev/null +++ b/packages/ir-sdk/fern/apis/ir-types-v53/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.8.13 + output: + location: npm + url: npm.buildwithfern.com + package-name: "@fern-fern/ir-v53-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:irV53 + 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_v53 + 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/http/types/BytesResponse.ts b/packages/ir-sdk/src/sdk/api/resources/http/types/BytesResponse.ts new file mode 100644 index 00000000000..69a078881e9 --- /dev/null +++ b/packages/ir-sdk/src/sdk/api/resources/http/types/BytesResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernIr from "../../../index"; + +export interface BytesResponse extends FernIr.WithDocs {} diff --git a/packages/ir-sdk/src/sdk/api/resources/http/types/HttpResponseBody.ts b/packages/ir-sdk/src/sdk/api/resources/http/types/HttpResponseBody.ts index 55b819dc128..1544b316dc6 100644 --- a/packages/ir-sdk/src/sdk/api/resources/http/types/HttpResponseBody.ts +++ b/packages/ir-sdk/src/sdk/api/resources/http/types/HttpResponseBody.ts @@ -8,6 +8,7 @@ export type HttpResponseBody = | FernIr.HttpResponseBody.Json | FernIr.HttpResponseBody.FileDownload | FernIr.HttpResponseBody.Text + | FernIr.HttpResponseBody.Bytes | FernIr.HttpResponseBody.Streaming /** * If there is a parameter that controls whether the response is streaming or not. Note @@ -29,6 +30,10 @@ export declare namespace HttpResponseBody { type: "text"; } + interface Bytes extends FernIr.BytesResponse, _Utils { + type: "bytes"; + } + interface Streaming extends _Utils { type: "streaming"; value: FernIr.StreamingResponse; @@ -46,6 +51,7 @@ export declare namespace HttpResponseBody { json: (value: FernIr.JsonResponse) => _Result; fileDownload: (value: FernIr.FileDownloadResponse) => _Result; text: (value: FernIr.TextResponse) => _Result; + bytes: (value: FernIr.BytesResponse) => _Result; streaming: (value: FernIr.StreamingResponse) => _Result; streamParameter: (value: FernIr.StreamParameterResponse) => _Result; _other: (value: { type: string }) => _Result; @@ -92,6 +98,19 @@ export const HttpResponseBody = { }; }, + bytes: (value: FernIr.BytesResponse): FernIr.HttpResponseBody.Bytes => { + return { + ...value, + type: "bytes", + _visit: function <_Result>( + this: FernIr.HttpResponseBody.Bytes, + visitor: FernIr.HttpResponseBody._Visitor<_Result> + ) { + return FernIr.HttpResponseBody._visit(this, visitor); + }, + }; + }, + streaming: (value: FernIr.StreamingResponse): FernIr.HttpResponseBody.Streaming => { return { value: value, @@ -126,6 +145,8 @@ export const HttpResponseBody = { return visitor.fileDownload(value); case "text": return visitor.text(value); + case "bytes": + return visitor.bytes(value); case "streaming": return visitor.streaming(value.value); case "streamParameter": diff --git a/packages/ir-sdk/src/sdk/api/resources/http/types/NonStreamHttpResponseBody.ts b/packages/ir-sdk/src/sdk/api/resources/http/types/NonStreamHttpResponseBody.ts index e3cdb7bfb6f..4fef4b32994 100644 --- a/packages/ir-sdk/src/sdk/api/resources/http/types/NonStreamHttpResponseBody.ts +++ b/packages/ir-sdk/src/sdk/api/resources/http/types/NonStreamHttpResponseBody.ts @@ -7,7 +7,8 @@ import * as FernIr from "../../../index"; export type NonStreamHttpResponseBody = | FernIr.NonStreamHttpResponseBody.Json | FernIr.NonStreamHttpResponseBody.FileDownload - | FernIr.NonStreamHttpResponseBody.Text; + | FernIr.NonStreamHttpResponseBody.Text + | FernIr.NonStreamHttpResponseBody.Bytes; export declare namespace NonStreamHttpResponseBody { interface Json extends _Utils { @@ -23,6 +24,10 @@ export declare namespace NonStreamHttpResponseBody { type: "text"; } + interface Bytes extends FernIr.BytesResponse, _Utils { + type: "bytes"; + } + interface _Utils { _visit: <_Result>(visitor: FernIr.NonStreamHttpResponseBody._Visitor<_Result>) => _Result; } @@ -31,6 +36,7 @@ export declare namespace NonStreamHttpResponseBody { json: (value: FernIr.JsonResponse) => _Result; fileDownload: (value: FernIr.FileDownloadResponse) => _Result; text: (value: FernIr.TextResponse) => _Result; + bytes: (value: FernIr.BytesResponse) => _Result; _other: (value: { type: string }) => _Result; } } @@ -75,6 +81,19 @@ export const NonStreamHttpResponseBody = { }; }, + bytes: (value: FernIr.BytesResponse): FernIr.NonStreamHttpResponseBody.Bytes => { + return { + ...value, + type: "bytes", + _visit: function <_Result>( + this: FernIr.NonStreamHttpResponseBody.Bytes, + visitor: FernIr.NonStreamHttpResponseBody._Visitor<_Result> + ) { + return FernIr.NonStreamHttpResponseBody._visit(this, visitor); + }, + }; + }, + _visit: <_Result>( value: FernIr.NonStreamHttpResponseBody, visitor: FernIr.NonStreamHttpResponseBody._Visitor<_Result> @@ -86,6 +105,8 @@ export const NonStreamHttpResponseBody = { return visitor.fileDownload(value); case "text": return visitor.text(value); + case "bytes": + return visitor.bytes(value); default: return visitor._other(value as any); } diff --git a/packages/ir-sdk/src/sdk/api/resources/http/types/index.ts b/packages/ir-sdk/src/sdk/api/resources/http/types/index.ts index ecc9c093dc5..849ed56935f 100644 --- a/packages/ir-sdk/src/sdk/api/resources/http/types/index.ts +++ b/packages/ir-sdk/src/sdk/api/resources/http/types/index.ts @@ -34,6 +34,7 @@ export * from "./JsonResponseBody"; export * from "./JsonResponseBodyWithProperty"; export * from "./FileDownloadResponse"; export * from "./TextResponse"; +export * from "./BytesResponse"; export * from "./StreamParameterResponse"; export * from "./StreamingResponse"; export * from "./TextStreamChunk"; diff --git a/packages/ir-sdk/src/sdk/serialization/resources/http/types/BytesResponse.ts b/packages/ir-sdk/src/sdk/serialization/resources/http/types/BytesResponse.ts new file mode 100644 index 00000000000..5e1b094c8e8 --- /dev/null +++ b/packages/ir-sdk/src/sdk/serialization/resources/http/types/BytesResponse.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernIr from "../../../../api/index"; +import * as core from "../../../../core"; +import { WithDocs } from "../../commons/types/WithDocs"; + +export const BytesResponse: core.serialization.ObjectSchema = + core.serialization.objectWithoutOptionalProperties({}).extend(WithDocs); + +export declare namespace BytesResponse { + interface Raw extends WithDocs.Raw {} +} diff --git a/packages/ir-sdk/src/sdk/serialization/resources/http/types/HttpResponseBody.ts b/packages/ir-sdk/src/sdk/serialization/resources/http/types/HttpResponseBody.ts index 4895950f199..108eac746c6 100644 --- a/packages/ir-sdk/src/sdk/serialization/resources/http/types/HttpResponseBody.ts +++ b/packages/ir-sdk/src/sdk/serialization/resources/http/types/HttpResponseBody.ts @@ -8,6 +8,7 @@ import * as core from "../../../../core"; import { JsonResponse } from "./JsonResponse"; import { FileDownloadResponse } from "./FileDownloadResponse"; import { TextResponse } from "./TextResponse"; +import { BytesResponse } from "./BytesResponse"; import { StreamingResponse } from "./StreamingResponse"; import { StreamParameterResponse } from "./StreamParameterResponse"; @@ -19,6 +20,7 @@ export const HttpResponseBody: core.serialization.Schema({ transform: (value) => { @@ -29,6 +31,8 @@ export const NonStreamHttpResponseBody: core.serialization.Schema< return FernIr.NonStreamHttpResponseBody.fileDownload(value); case "text": return FernIr.NonStreamHttpResponseBody.text(value); + case "bytes": + return FernIr.NonStreamHttpResponseBody.bytes(value); default: return value as FernIr.NonStreamHttpResponseBody; } @@ -37,7 +41,11 @@ export const NonStreamHttpResponseBody: core.serialization.Schema< }); export declare namespace NonStreamHttpResponseBody { - type Raw = NonStreamHttpResponseBody.Json | NonStreamHttpResponseBody.FileDownload | NonStreamHttpResponseBody.Text; + type Raw = + | NonStreamHttpResponseBody.Json + | NonStreamHttpResponseBody.FileDownload + | NonStreamHttpResponseBody.Text + | NonStreamHttpResponseBody.Bytes; interface Json { type: "json"; @@ -51,4 +59,8 @@ export declare namespace NonStreamHttpResponseBody { interface Text extends TextResponse.Raw { type: "text"; } + + interface Bytes extends BytesResponse.Raw { + type: "bytes"; + } } diff --git a/packages/ir-sdk/src/sdk/serialization/resources/http/types/index.ts b/packages/ir-sdk/src/sdk/serialization/resources/http/types/index.ts index ecc9c093dc5..849ed56935f 100644 --- a/packages/ir-sdk/src/sdk/serialization/resources/http/types/index.ts +++ b/packages/ir-sdk/src/sdk/serialization/resources/http/types/index.ts @@ -34,6 +34,7 @@ export * from "./JsonResponseBody"; export * from "./JsonResponseBodyWithProperty"; export * from "./FileDownloadResponse"; export * from "./TextResponse"; +export * from "./BytesResponse"; export * from "./StreamParameterResponse"; export * from "./StreamingResponse"; export * from "./TextStreamChunk"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62d5a8971bf..d5c3f260a3b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5191,6 +5191,9 @@ importers: '@fern-fern/ir-v52-sdk': specifier: 0.0.1 version: 0.0.1 + '@fern-fern/ir-v53-sdk': + specifier: 0.0.1 + version: 0.0.1 '@fern-fern/ir-v6-model': specifier: 0.0.33 version: 0.0.33 @@ -8199,6 +8202,9 @@ packages: '@fern-fern/ir-v52-sdk@0.0.1': resolution: {integrity: sha512-UGmPWWaGAAAXUSq/A/uUuDl/iMO2+rJJ6ICBmXMlUFA/AAeSLhpxjbywGz3YU0NLgOBrVe0D00ZO9aW9TNx2/A==} + '@fern-fern/ir-v53-sdk@0.0.1': + resolution: {integrity: sha512-7KNvdLlWyYkkhVsplvVmVKm6+LCGKTQJxE7jqjmjg+1AUBC75zcGAkiHylDLB8gkOCLN3Qcs2RHljC0yHVLlOw==} + '@fern-fern/ir-v6-model@0.0.33': resolution: {integrity: sha512-I3KLvdrRzSrh5CcpU0v/Mjn4ywZhzVwhqJC8IDIQiP1yPvsCnjgbTBNwLRG8KdJqHfLOgdt/hfVzjeuFugSlGA==} @@ -15350,6 +15356,8 @@ snapshots: '@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': {}