diff --git a/.eslintrc.js b/.eslintrc.js
index 3aba8b6ca73..1b18e45c8d1 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -67,12 +67,7 @@ module.exports = {
ignoreRestSiblings: true
}
],
- "@typescript-eslint/no-namespace": [
- "error",
- {
- allowDeclarations: true
- }
- ],
+ "@typescript-eslint/no-namespace": "off",
"@typescript-eslint/explicit-module-boundary-types": [
"error",
{
@@ -129,7 +124,7 @@ module.exports = {
{
files: ['**/*.test.ts', '**/*.spec.ts'],
rules: {
- 'no-console': 'off'
+ 'no-console': 'off'
}
}
]
diff --git a/README.md b/README.md
index a61a4d0d182..224a93bf1bf 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,7 @@ Postman Collections, Server boilerplate, etc.). To add a generator run `fern add
| `fernapi/fern-ruby-sdk` | ![Ruby Generator Version](https://img.shields.io/docker/v/fernapi/fern-ruby-sdk) | [cli.ts](./generators/ruby/sdk/src/cli.ts) |
| `fernapi/fern-go-sdk` | ![Go Generator Version](https://img.shields.io/docker/v/fernapi/fern-go-sdk) | [main.go](./generators/go/cmd/fern-go-sdk/main.go) |
| `fernapi/fern-csharp-sdk` | ![C# Generator Version](https://img.shields.io/docker/v/fernapi/fern-csharp-sdk) | [cli.ts](./generators/csharp/sdk/src/cli.ts) |
+| `fernapi/fern-php-sdk` | ![PHP Generator Version](https://img.shields.io/docker/v/fernapi/fern-php-sdk) | [cli.ts](./generators/php/sdk/src/cli.ts) |
### Server-side Generators
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/fern/pages/changelogs/cli/2024-12-05.mdx b/fern/pages/changelogs/cli/2024-12-05.mdx
index 8dbf596d6c6..4aa53ac1300 100644
--- a/fern/pages/changelogs/cli/2024-12-05.mdx
+++ b/fern/pages/changelogs/cli/2024-12-05.mdx
@@ -1,4 +1,4 @@
## 0.45.3
-**`(fix):`** Unknown schemas are no longer incorrectly marked as `additionalProperties: true`.
+**`(fix):`** Unknown schemas are no longer incorrectly marked as `additionalProperties: true`.
diff --git a/fern/pages/changelogs/cli/2024-12-10.mdx b/fern/pages/changelogs/cli/2024-12-10.mdx
new file mode 100644
index 00000000000..dfceddb4453
--- /dev/null
+++ b/fern/pages/changelogs/cli/2024-12-10.mdx
@@ -0,0 +1,4 @@
+## 0.45.4-rc1
+**`(chore):`** Unknown schemas are no longer incorrectly marked as `additionalProperties: true`.
+
+
diff --git a/fern/pages/changelogs/cli/2024-12-11.mdx b/fern/pages/changelogs/cli/2024-12-11.mdx
new file mode 100644
index 00000000000..4f787adf6d9
--- /dev/null
+++ b/fern/pages/changelogs/cli/2024-12-11.mdx
@@ -0,0 +1,4 @@
+## 0.45.4
+**`(fix):`** Defaults are no longer set on datetimes when converting to docs shapes.
+
+
diff --git a/fern/pages/changelogs/cli/2024-12-12.mdx b/fern/pages/changelogs/cli/2024-12-12.mdx
new file mode 100644
index 00000000000..e84d5b08da9
--- /dev/null
+++ b/fern/pages/changelogs/cli/2024-12-12.mdx
@@ -0,0 +1,4 @@
+## 0.46.0
+**`(internal):`** No changes; promote `0.46.0-rc1` release candidate to minor version.
+
+
diff --git a/fern/pages/changelogs/go-sdk/2024-12-12.mdx b/fern/pages/changelogs/go-sdk/2024-12-12.mdx
new file mode 100644
index 00000000000..6476bfd794c
--- /dev/null
+++ b/fern/pages/changelogs/go-sdk/2024-12-12.mdx
@@ -0,0 +1,4 @@
+## 0.34.0
+**`(feat):`** Add support for sending the `User-Agent` header on every request. Go packages are uniquely identified by their full module path, so the `User-Agent` header is generated in the `/` format, e.g.
+``` User-Agent: github.com/acme/acme-go/1.0.0 ```
+
diff --git a/fern/pages/changelogs/java-model/2024-12-10.mdx b/fern/pages/changelogs/java-model/2024-12-10.mdx
new file mode 100644
index 00000000000..aec352b8f41
--- /dev/null
+++ b/fern/pages/changelogs/java-model/2024-12-10.mdx
@@ -0,0 +1,4 @@
+## 1.3.0
+**`(chore):`** Bump IR version to latest (v53)
+
+
diff --git a/fern/pages/changelogs/java-sdk/2024-12-10.mdx b/fern/pages/changelogs/java-sdk/2024-12-10.mdx
new file mode 100644
index 00000000000..7a36665e135
--- /dev/null
+++ b/fern/pages/changelogs/java-sdk/2024-12-10.mdx
@@ -0,0 +1,5 @@
+## 2.4.0
+**`(feat):`** We now support overriding sdk package prefixes by adding a "package-prefix" key under the java-sdk generator
+configuration.
+
+
diff --git a/fern/pages/changelogs/java-sdk/2024-12-11.mdx b/fern/pages/changelogs/java-sdk/2024-12-11.mdx
new file mode 100644
index 00000000000..ef7a801845a
--- /dev/null
+++ b/fern/pages/changelogs/java-sdk/2024-12-11.mdx
@@ -0,0 +1,4 @@
+## 2.7.0
+**`(feat):`** Apply Content-Type header from endpoint definition in SDK generator.
+
+
diff --git a/fern/pages/changelogs/java-spring/2024-12-10.mdx b/fern/pages/changelogs/java-spring/2024-12-10.mdx
new file mode 100644
index 00000000000..aec352b8f41
--- /dev/null
+++ b/fern/pages/changelogs/java-spring/2024-12-10.mdx
@@ -0,0 +1,4 @@
+## 1.3.0
+**`(chore):`** Bump IR version to latest (v53)
+
+
diff --git a/fern/pages/docs/building-your-docs/custom-css-js.mdx b/fern/pages/docs/building-your-docs/custom-css-js.mdx
index 926f8a33fb7..1a9e22a8b63 100644
--- a/fern/pages/docs/building-your-docs/custom-css-js.mdx
+++ b/fern/pages/docs/building-your-docs/custom-css-js.mdx
@@ -122,7 +122,7 @@ check out the [Global Configuration](/learn/docs/getting-started/global-configur
Customize the behavior of your Docs site by injecting custom JavaScript globally. Add a `custom.js` file and include it in your `fern/` project:
-
+
```bash {5}
fern/
├─ openapi/
diff --git a/fern/pages/sdks/comparison/speakeasy.mdx b/fern/pages/sdks/comparison/speakeasy.mdx
index 8b3d55b2e79..36e22954903 100644
--- a/fern/pages/sdks/comparison/speakeasy.mdx
+++ b/fern/pages/sdks/comparison/speakeasy.mdx
@@ -8,7 +8,7 @@ walk through the different capabilities of Fern and Speakeasy.
### 1. Fern is an all-in-one: SDKs + Docs
-If you choose Speakeasy, you'll have to find a separate docs vendor such as ReadMe. With Fern, you'll be able to generate SDKs and
+If you choose Speakeasy, you can integrate with third-party documentation providers or use its native Scalar integration. With Fern, you'll be able to generate SDKs and
Docs with embedded code snippets.
@@ -21,8 +21,8 @@ Fern's SDKs are battle-tested and have been downloaded millions of times.
| Language | Fern | Speakeasy |
| ---------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
-| TypeScript | **93k** weekly downloads ([Cohere](https://www.npmjs.com/package/cohere-ai)) | **5k** weekly downloads ([Unstructured](https://www.npmjs.com/package/unstructured-client)) |
-| Python | **5 million** lifetime downloads ([ElevenLabs](https://github.com/elevenlabs/elevenlabs-python)) | **194k** lifetime downloads ([Airbyte](https://github.com/airbytehq/airbyte-api-python-sdk)) |
+| TypeScript | **120k** weekly downloads ([Cohere](https://www.npmjs.com/package/cohere-ai)) | **85k** weekly downloads ([Mistral AI](https://www.npmjs.com/package/@mistralai/mistralai)) |
+| Python | **6 million** lifetime downloads ([ElevenLabs](https://pepy.tech/projects/ElevenLabs)) | **17 million** lifetime downloads ([Unstructured](https://pepy.tech/projects/unstructured-client)) |
### 3. Fern offers more Generally Available SDK languages.
@@ -33,7 +33,11 @@ Fern's SDKs are battle-tested and have been downloaded millions of times.
| Java | ✅ | ✅ |
| Go | ✅ | ✅ |
| C# | ✅ | ✅ |
+| PHP | ✅ | ✅ |
+| Terraform | ❌ | ✅ |
| Ruby | ✅ | ❌ (Alpha) |
+| Unity | ❌ | ❌ (Beta) |
+
### 4. Speakeasy generates Terraform providers.
@@ -49,7 +53,7 @@ is blocked if any failures are encountered.
-On the other hand, Speakeasy produces no tests in their SDKs ([example](https://github.com/airbytehq/airbyte-api-python-sdk)).
+On the other hand, Speakeasy supports contract testing, server mocking, and API sequence testing to streamline development workflows. ([example](https://www.speakeasy.com/docs/testing)).
### 6. Fern supports OAuth + DPoP.
@@ -58,8 +62,8 @@ On the other hand, Speakeasy produces no tests in their SDKs ([example](https://
| `Bearer` | ✅ | ✅ |
| `Basic` | ✅ | ✅ |
| Custom Headers | ✅ | ✅ |
-| `OAuth` Client Credentials | ✅ | 🏗️ Partial |
-| `OAuth` Refresh | ✅ | 🏗️ Partial |
+| `OAuth` Client Credentials | ✅ | ✅ |
+| `OAuth` Refresh | ✅ | ✅ |
| DPop (Proof of possession) | ✅ | ❌ |
### 7. Fern's file structure is resource based.
@@ -91,6 +95,6 @@ behavior.
| Feature | Fern | Speakeasy |
| ---------------- | ---- | --------- |
-| Auth Override | ✅ | ❌ |
-| Timeout Override | ✅ | ❌ |
-| Retry Override | ✅ | ❌ |
+| Auth Override | ✅ | ✅ |
+| Timeout Override | ✅ | ✅ |
+| Retry Override | ✅ | ✅ |
diff --git a/fern/pages/sdks/publish-sdk/publish-your-sdk.mdx b/fern/pages/sdks/publish-sdk/publish-your-sdk.mdx
index 831a6878b18..73b78bf7b40 100644
--- a/fern/pages/sdks/publish-sdk/publish-your-sdk.mdx
+++ b/fern/pages/sdks/publish-sdk/publish-your-sdk.mdx
@@ -77,6 +77,8 @@ This guide will walk you through how to publish public-facing SDKs through Fern.
```
+ Here are the [latest versions of each generator](https://github.com/fern-api/fern?tab=readme-ov-file#-generators).
+
### Configure `output` location
In order to setup publishing your SDK, you'll need to configure
diff --git a/generators/browser-compatible-base/src/utils/getSdkVersion.ts b/generators/browser-compatible-base/src/utils/getSdkVersion.ts
index 2bf95c59e84..fd2aff5f68f 100644
--- a/generators/browser-compatible-base/src/utils/getSdkVersion.ts
+++ b/generators/browser-compatible-base/src/utils/getSdkVersion.ts
@@ -10,32 +10,3 @@ export function getSdkVersion(config: FernGeneratorExec.GeneratorConfig): string
}
});
}
-
-export function getPackageName(config: FernGeneratorExec.GeneratorConfig): string | undefined {
- return config.output.mode._visit({
- publish: (gpc: FernGeneratorExec.GeneratorPublishConfig) =>
- gpc.publishTarget?._visit({
- maven: (mrc: FernGeneratorExec.MavenRegistryConfigV2) => mrc.coordinate,
- npm: (nrc: FernGeneratorExec.NpmRegistryConfigV2) => nrc.packageName,
- pypi: (prc: FernGeneratorExec.PypiRegistryConfig) => prc.packageName,
- rubygems: (rgrc: FernGeneratorExec.RubyGemsRegistryConfig) => rgrc.packageName,
- nuget: (nrc: FernGeneratorExec.NugetRegistryConfig) => nrc.packageName,
- postman: () => undefined,
- _other: () => undefined
- }),
- downloadFiles: () => undefined,
- github: (gom: FernGeneratorExec.GithubOutputMode) =>
- gom.publishInfo?._visit({
- maven: (mrc: FernGeneratorExec.MavenGithubPublishInfo) => mrc.coordinate,
- npm: (nrc: FernGeneratorExec.NpmGithubPublishInfo) => nrc.packageName,
- pypi: (prc: FernGeneratorExec.PypiGithubPublishInfo) => prc.packageName,
- rubygems: (rgrc: FernGeneratorExec.RubyGemsGithubPublishInfo) => rgrc.packageName,
- nuget: (nrc: FernGeneratorExec.NugetGithubPublishInfo) => nrc.packageName,
- postman: () => undefined,
- _other: () => undefined
- }),
- _other: () => {
- throw new Error("Unrecognized output mode.");
- }
- });
-}
diff --git a/generators/go-v2/ast/package.json b/generators/go-v2/ast/package.json
index 7fe9468c01a..c3a0a660718 100644
--- a/generators/go-v2/ast/package.json
+++ b/generators/go-v2/ast/package.json
@@ -30,14 +30,14 @@
"@fern-api/browser-compatible-base-generator": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/path-utils": "workspace:*",
- "@fern-fern/ir-sdk": "^53.23.0",
+ "@fern-fern/ir-sdk": "^53.24.0",
"zod": "^3.22.3"
},
"devDependencies": {
"@fern-api/browser-compatible-base-generator": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/path-utils": "workspace:*",
- "@fern-fern/ir-sdk": "^53.23.0",
+ "@fern-fern/ir-sdk": "^53.24.0",
"@types/jest": "^29.5.12",
"depcheck": "^1.4.6",
"eslint": "^8.56.0",
diff --git a/generators/go-v2/dynamic-snippets/build.cjs b/generators/go-v2/dynamic-snippets/build.cjs
index 493a872afe9..3ecb9feb92c 100644
--- a/generators/go-v2/dynamic-snippets/build.cjs
+++ b/generators/go-v2/dynamic-snippets/build.cjs
@@ -1,30 +1,48 @@
+const { NodeModulesPolyfillPlugin } = require('@esbuild-plugins/node-modules-polyfill');
+const { NodeGlobalsPolyfillPlugin } = require('@esbuild-plugins/node-globals-polyfill');
const packageJson = require("./package.json");
const tsup = require('tsup');
-const { writeFile, rename } = require("fs/promises");
+const { writeFile, mkdir } = require("fs/promises");
const path = require("path");
main();
async function main() {
- await tsup.build({
+ const config = {
entry: ['src/**/*.ts', '!src/__test__'],
- format: ['cjs'],
- clean: true,
+ target: "es2017",
minify: true,
dts: true,
- outDir: 'dist',
- target: "es2017",
external: [
- // Test dependencies should not be included in the published package.
'@fern-api/go-formatter',
],
+ esbuildPlugins: [
+ NodeModulesPolyfillPlugin(),
+ NodeGlobalsPolyfillPlugin({
+ process: true,
+ buffer: true,
+ util: true
+ })
+ ],
tsconfig: "./build.tsconfig.json"
+ };
+
+ await tsup.build({
+ ...config,
+ format: ['cjs'],
+ outDir: 'dist/cjs',
+ clean: true,
});
- process.chdir(path.join(__dirname, "dist"));
+ await tsup.build({
+ ...config,
+ format: ['esm'],
+ outDir: 'dist/esm',
+ clean: false,
+ });
- // The module expects the imports defined in the index.d.ts file.
- await rename("index.d.cts", "index.d.ts");
+ await mkdir(path.join(__dirname, "dist"), { recursive: true });
+ process.chdir(path.join(__dirname, "dist"));
await writeFile(
"package.json",
@@ -33,9 +51,26 @@ async function main() {
name: packageJson.name,
version: process.argv[2] || packageJson.version,
repository: packageJson.repository,
- main: "index.cjs",
- types: "index.d.ts",
- files: ["index.cjs", "index.d.ts"]
+ type: "module",
+ exports: {
+ // Conditional exports for ESM and CJS.
+ "import": {
+ "types": "./esm/index.d.ts",
+ "default": "./esm/index.js"
+ },
+ "require": {
+ "types": "./cjs/index.d.cts",
+ "default": "./cjs/index.cjs"
+ }
+ },
+ // Fallback for older tooling or direct imports.
+ main: "./cjs/index.cjs",
+ module: "./esm/index.js",
+ types: "./cjs/index.d.cts",
+ files: [
+ "cjs",
+ "esm"
+ ]
},
undefined,
2
diff --git a/generators/go-v2/dynamic-snippets/package.json b/generators/go-v2/dynamic-snippets/package.json
index b891c442153..7f51e512227 100644
--- a/generators/go-v2/dynamic-snippets/package.json
+++ b/generators/go-v2/dynamic-snippets/package.json
@@ -28,13 +28,15 @@
"dist": "pnpm compile && node build.cjs"
},
"devDependencies": {
+ "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
+ "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@fern-api/browser-compatible-base-generator": "workspace:*",
"@fern-api/core-utils": "workspace:*",
"@fern-api/fern-definition-schema": "workspace:*",
"@fern-api/go-ast": "workspace:*",
"@fern-api/go-formatter": "workspace:*",
"@fern-api/path-utils": "workspace:*",
- "@fern-fern/ir-sdk": "^53.23.0",
+ "@fern-fern/ir-sdk": "^53.24.0",
"@types/jest": "^29.5.12",
"depcheck": "^1.4.6",
"eslint": "^8.56.0",
diff --git a/generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts b/generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts
index 896200bed0b..b34ecf85e79 100644
--- a/generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts
+++ b/generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts
@@ -3,17 +3,10 @@ import {
AbstractFormatter,
FernGeneratorExec
} from "@fern-api/browser-compatible-base-generator";
-import { go } from "@fern-api/go-ast";
import { DynamicSnippetsGeneratorContext } from "./context/DynamicSnippetsGeneratorContext";
import { dynamic as DynamicSnippets } from "@fern-fern/ir-sdk/api";
-import { ErrorReporter, Severity } from "./context/ErrorReporter";
-import { Scope } from "./Scope";
-import { FilePropertyInfo } from "./context/FilePropertyMapper";
-
-const SNIPPET_PACKAGE_NAME = "example";
-const SNIPPET_IMPORT_PATH = "fern";
-const SNIPPET_FUNC_NAME = "do";
-const CLIENT_VAR_NAME = "client";
+import { EndpointSnippetGenerator } from "./EndpointSnippetGenerator";
+import { Result } from "./Result";
export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
DynamicSnippets.DynamicIntermediateRepresentation,
@@ -43,47 +36,29 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
-
- let bestReporter: ErrorReporter | undefined;
- let bestSnippet: string | undefined;
- let err: Error | undefined;
+ const result = new Result();
for (const endpoint of endpoints) {
- this.context.errors.reset();
+ const context = this.context.clone();
+ const snippetGenerator = new EndpointSnippetGenerator({
+ context,
+ formatter: this.formatter
+ });
try {
- const code = this.buildCodeBlock({ endpoint, snippet: request });
- const snippet = await code.toString({
- packageName: SNIPPET_PACKAGE_NAME,
- importPath: SNIPPET_IMPORT_PATH,
- rootImportPath: this.context.rootImportPath,
- customConfig: this.context.customConfig ?? {},
- formatter: this.formatter
- });
- if (this.context.errors.empty()) {
+ const snippet = await snippetGenerator.generateSnippet({ endpoint, request });
+ if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
- if (bestReporter == null || bestReporter.size() > this.context.errors.size()) {
- bestReporter = this.context.errors.clone();
- bestSnippet = snippet;
- }
+ result.update({ context, snippet });
} catch (error) {
- if (err == null) {
- err = error as Error;
+ if (result.err == null) {
+ result.err = error as Error;
}
}
}
- if (bestSnippet != null && bestReporter != null) {
- return {
- snippet: bestSnippet,
- errors: bestReporter.toDynamicSnippetErrors()
- };
- }
- throw (
- err ??
- new Error(`Failed to generate snippet for endpoint "${request.endpoint.method} ${request.endpoint.path}"`)
- );
+ return result.getResponseOrThrow({ endpoint: request.endpoint });
}
public generateSync(request: DynamicSnippets.EndpointSnippetRequest): DynamicSnippets.EndpointSnippetResponse {
@@ -91,585 +66,28 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
if (endpoints.length === 0) {
throw new Error(`No endpoints found that match "${request.endpoint.method} ${request.endpoint.path}"`);
}
-
- let bestReporter: ErrorReporter | undefined;
- let bestSnippet: string | undefined;
- let err: Error | undefined;
+ const result = new Result();
for (const endpoint of endpoints) {
- this.context.errors.reset();
+ const context = this.context.clone();
+ const snippetGenerator = new EndpointSnippetGenerator({
+ context,
+ formatter: this.formatter
+ });
try {
- const code = this.buildCodeBlock({ endpoint, snippet: request });
- const snippet = code.toStringSync({
- packageName: SNIPPET_PACKAGE_NAME,
- importPath: SNIPPET_IMPORT_PATH,
- rootImportPath: this.context.rootImportPath,
- customConfig: this.context.customConfig ?? {},
- formatter: this.formatter
- });
- if (this.context.errors.empty()) {
+ const snippet = snippetGenerator.generateSnippetSync({ endpoint, request });
+ if (context.errors.empty()) {
return {
snippet,
errors: undefined
};
}
- if (bestReporter == null || bestReporter.size() > this.context.errors.size()) {
- bestReporter = this.context.errors.clone();
- bestSnippet = snippet;
- }
+ result.update({ context, snippet });
} catch (error) {
- if (err == null) {
- err = error as Error;
+ if (result.err == null) {
+ result.err = error as Error;
}
}
}
- if (bestSnippet != null && bestReporter != null) {
- return {
- snippet: bestSnippet,
- errors: bestReporter.toDynamicSnippetErrors()
- };
- }
- throw (
- err ??
- new Error(`Failed to generate snippet for endpoint "${request.endpoint.method} ${request.endpoint.path}"`)
- );
- }
-
- private buildCodeBlock({
- endpoint,
- snippet
- }: {
- endpoint: DynamicSnippets.Endpoint;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.AstNode {
- return go.func({
- name: SNIPPET_FUNC_NAME,
- parameters: [],
- return_: [],
- body: go.codeblock((writer) => {
- writer.writeNode(this.constructClient({ endpoint, snippet }));
- writer.writeLine();
- writer.writeNode(this.callMethod({ endpoint, snippet }));
- })
- });
- }
-
- private constructClient({
- endpoint,
- snippet
- }: {
- endpoint: DynamicSnippets.Endpoint;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.CodeBlock {
- return go.codeblock((writer) => {
- writer.write(`${CLIENT_VAR_NAME} := `);
- writer.writeNode(this.getRootClientFuncInvocation(this.getConstructorArgs({ endpoint, snippet })));
- });
- }
-
- private callMethod({
- endpoint,
- snippet
- }: {
- endpoint: DynamicSnippets.Endpoint;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.MethodInvocation {
- return go.invokeMethod({
- on: go.codeblock(CLIENT_VAR_NAME),
- method: this.getMethod({ endpoint }),
- arguments_: [this.context.getContextTodoFunctionInvocation(), ...this.getMethodArgs({ endpoint, snippet })]
- });
- }
-
- private getConstructorArgs({
- endpoint,
- snippet
- }: {
- endpoint: DynamicSnippets.Endpoint;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.AstNode[] {
- const args: go.AstNode[] = [];
- if (endpoint.auth != null) {
- if (snippet.auth != null) {
- args.push(this.getConstructorAuthArg({ auth: endpoint.auth, values: snippet.auth }));
- } else {
- this.context.errors.add({
- severity: Severity.Warning,
- message: `Auth with ${endpoint.auth.type} configuration is required for this endpoint`
- });
- }
- }
- this.context.errors.scope(Scope.Headers);
- if (this.context.ir.headers != null && snippet.headers != null) {
- args.push(...this.getConstructorHeaderArgs({ headers: this.context.ir.headers, values: snippet.headers }));
- }
- this.context.errors.unscope();
- return args;
- }
-
- private getConstructorAuthArg({
- auth,
- values
- }: {
- auth: DynamicSnippets.Auth;
- values: DynamicSnippets.AuthValues;
- }): go.AstNode {
- switch (auth.type) {
- case "basic":
- if (values.type !== "basic") {
- this.context.errors.add({
- severity: Severity.Critical,
- message: this.newAuthMismatchError({ auth, values }).message
- });
- return go.TypeInstantiation.nop();
- }
- return this.getConstructorBasicAuthArg({ auth, values });
- case "bearer":
- if (values.type !== "bearer") {
- this.context.errors.add({
- severity: Severity.Critical,
- message: this.newAuthMismatchError({ auth, values }).message
- });
- return go.TypeInstantiation.nop();
- }
- return this.getConstructorBearerAuthArg({ auth, values });
- case "header":
- if (values.type !== "header") {
- this.context.errors.add({
- severity: Severity.Critical,
- message: this.newAuthMismatchError({ auth, values }).message
- });
- return go.TypeInstantiation.nop();
- }
- return this.getConstructorHeaderAuthArg({ auth, values });
- }
- }
-
- private getConstructorBasicAuthArg({
- auth,
- values
- }: {
- auth: DynamicSnippets.BasicAuth;
- values: DynamicSnippets.BasicAuthValues;
- }): go.AstNode {
- return go.codeblock((writer) => {
- writer.writeNode(
- go.invokeFunc({
- func: go.typeReference({
- name: "WithBasicAuth",
- importPath: this.context.getOptionImportPath()
- }),
- arguments_: [
- go.TypeInstantiation.string(values.username),
- go.TypeInstantiation.string(values.password)
- ]
- })
- );
- });
- }
-
- private getConstructorBearerAuthArg({
- auth,
- values
- }: {
- auth: DynamicSnippets.BearerAuth;
- values: DynamicSnippets.BearerAuthValues;
- }): go.AstNode {
- return go.codeblock((writer) => {
- writer.writeNode(
- go.invokeFunc({
- func: go.typeReference({
- name: `With${auth.token.pascalCase.unsafeName}`,
- importPath: this.context.getOptionImportPath()
- }),
- arguments_: [go.TypeInstantiation.string(values.token)]
- })
- );
- });
- }
-
- private getConstructorHeaderAuthArg({
- auth,
- values
- }: {
- auth: DynamicSnippets.HeaderAuth;
- values: DynamicSnippets.HeaderAuthValues;
- }): go.AstNode {
- return go.codeblock((writer) => {
- writer.writeNode(
- go.invokeFunc({
- func: go.typeReference({
- name: `With${auth.header.name.name.pascalCase.unsafeName}`,
- importPath: this.context.getOptionImportPath()
- }),
- arguments_: [
- this.context.dynamicTypeInstantiationMapper.convert({
- typeReference: auth.header.typeReference,
- value: values.value
- })
- ]
- })
- );
- });
- }
-
- private getConstructorHeaderArgs({
- headers,
- values
- }: {
- headers: DynamicSnippets.NamedParameter[];
- values: DynamicSnippets.Values;
- }): go.AstNode[] {
- const args: go.AstNode[] = [];
- for (const header of headers) {
- const arg = this.getConstructorHeaderArg({ header, value: values.value });
- if (arg != null) {
- args.push(arg);
- }
- }
- return args;
- }
-
- private getConstructorHeaderArg({
- header,
- value
- }: {
- header: DynamicSnippets.NamedParameter;
- value: unknown;
- }): go.AstNode | undefined {
- const typeInstantiation = this.context.dynamicTypeInstantiationMapper.convert({
- typeReference: header.typeReference,
- value
- });
- if (go.TypeInstantiation.isNop(typeInstantiation)) {
- // Literal header values (e.g. "X-API-Version") should not be included in the
- // client constructor.
- return undefined;
- }
- return go.codeblock((writer) => {
- writer.writeNode(
- go.invokeFunc({
- func: go.typeReference({
- name: `With${header.name.name.pascalCase.unsafeName}`,
- importPath: this.context.getOptionImportPath()
- }),
- arguments_: [typeInstantiation]
- })
- );
- });
- }
-
- private getMethodArgs({
- endpoint,
- snippet
- }: {
- endpoint: DynamicSnippets.Endpoint;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.AstNode[] {
- switch (endpoint.request.type) {
- case "inlined":
- return this.getMethodArgsForInlinedRequest({ request: endpoint.request, snippet });
- case "body":
- return this.getMethodArgsForBodyRequest({ request: endpoint.request, snippet });
- }
- }
-
- private getMethodArgsForBodyRequest({
- request,
- snippet
- }: {
- request: DynamicSnippets.BodyRequest;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.TypeInstantiation[] {
- const args: go.TypeInstantiation[] = [];
-
- this.context.errors.scope(Scope.PathParameters);
- if (request.pathParameters != null) {
- const pathParameterFields = this.getPathParameters({ namedParameters: request.pathParameters, snippet });
- args.push(...pathParameterFields.map((field) => field.value));
- }
- this.context.errors.unscope();
-
- this.context.errors.scope(Scope.RequestBody);
- if (request.body != null) {
- args.push(this.getBodyRequestArg({ body: request.body, value: snippet.requestBody }));
- }
- this.context.errors.unscope();
-
- return args;
- }
-
- private getBodyRequestArg({
- body,
- value
- }: {
- body: DynamicSnippets.ReferencedRequestBodyType;
- value: unknown;
- }): go.TypeInstantiation {
- switch (body.type) {
- case "bytes": {
- return this.getBytesBodyRequestArg({ value });
- }
- case "typeReference":
- return this.context.dynamicTypeInstantiationMapper.convert({ typeReference: body.value, value });
- }
- }
-
- private getBytesBodyRequestArg({ value }: { value: unknown }): go.TypeInstantiation {
- if (typeof value !== "string") {
- this.context.errors.add({
- severity: Severity.Critical,
- message: `Expected bytes value to be a string, got ${typeof value}`
- });
- return go.TypeInstantiation.nop();
- }
- return go.TypeInstantiation.bytes(value as string);
- }
-
- private getMethodArgsForInlinedRequest({
- request,
- snippet
- }: {
- request: DynamicSnippets.InlinedRequest;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.TypeInstantiation[] {
- const args: go.TypeInstantiation[] = [];
-
- this.context.errors.scope(Scope.PathParameters);
- const pathParameterFields: go.StructField[] = [];
- if (request.pathParameters != null) {
- pathParameterFields.push(...this.getPathParameters({ namedParameters: request.pathParameters, snippet }));
- }
- this.context.errors.unscope();
-
- this.context.errors.scope(Scope.RequestBody);
- const filePropertyInfo = this.getFilePropertyInfo({ request, snippet });
- this.context.errors.unscope();
-
- if (!this.context.includePathParametersInWrappedRequest({ request })) {
- args.push(...pathParameterFields.map((field) => field.value));
- }
-
- if (!this.context.customConfig?.inlineFileProperties) {
- args.push(...filePropertyInfo.fileFields.map((field) => field.value));
- }
-
- if (this.context.needsRequestParameter({ request })) {
- args.push(
- this.getInlinedRequestArg({
- request,
- snippet,
- pathParameterFields: this.context.includePathParametersInWrappedRequest({ request })
- ? pathParameterFields
- : [],
- filePropertyInfo
- })
- );
- }
- return args;
- }
-
- private getFilePropertyInfo({
- request,
- snippet
- }: {
- request: DynamicSnippets.InlinedRequest;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): FilePropertyInfo {
- if (request.body == null || !this.context.isFileUploadRequestBody(request.body)) {
- return {
- fileFields: [],
- bodyPropertyFields: []
- };
- }
- return this.context.filePropertyMapper.getFilePropertyInfo({
- body: request.body,
- value: snippet.requestBody
- });
- }
-
- private getInlinedRequestArg({
- request,
- snippet,
- pathParameterFields,
- filePropertyInfo
- }: {
- request: DynamicSnippets.InlinedRequest;
- snippet: DynamicSnippets.EndpointSnippetRequest;
- pathParameterFields: go.StructField[];
- filePropertyInfo: FilePropertyInfo;
- }): go.TypeInstantiation {
- this.context.errors.scope(Scope.QueryParameters);
- const queryParameters = this.context.associateQueryParametersByWireValue({
- parameters: request.queryParameters ?? [],
- values: snippet.queryParameters ?? {}
- });
- const queryParameterFields = queryParameters.map((queryParameter) => ({
- name: queryParameter.name.name.pascalCase.unsafeName,
- value: this.context.dynamicTypeInstantiationMapper.convert(queryParameter)
- }));
- this.context.errors.unscope();
-
- this.context.errors.scope(Scope.Headers);
- const headers = this.context.associateByWireValue({
- parameters: request.headers ?? [],
- values: snippet.headers ?? {}
- });
- const headerFields = headers.map((header) => ({
- name: header.name.name.pascalCase.unsafeName,
- value: this.context.dynamicTypeInstantiationMapper.convert(header)
- }));
- this.context.errors.unscope();
-
- this.context.errors.scope(Scope.RequestBody);
- const requestBodyFields =
- request.body != null
- ? this.getInlinedRequestBodyStructFields({
- body: request.body,
- value: snippet.requestBody,
- filePropertyInfo
- })
- : [];
- this.context.errors.unscope();
-
- return go.TypeInstantiation.structPointer({
- typeReference: go.typeReference({
- name: this.context.getMethodName(request.declaration.name),
- importPath: this.context.getImportPath(request.declaration.fernFilepath)
- }),
- fields: [...pathParameterFields, ...queryParameterFields, ...headerFields, ...requestBodyFields]
- });
- }
-
- private getInlinedRequestBodyStructFields({
- body,
- value,
- filePropertyInfo
- }: {
- body: DynamicSnippets.InlinedRequestBody;
- value: unknown;
- filePropertyInfo: FilePropertyInfo;
- }): go.StructField[] {
- switch (body.type) {
- case "properties":
- return this.getInlinedRequestBodyPropertyStructFields({ parameters: body.value, value });
- case "referenced":
- return [this.getReferencedRequestBodyPropertyStructField({ body, value })];
- case "fileUpload":
- return this.getFileUploadRequestBodyStructFields({ filePropertyInfo });
- }
- }
-
- private getFileUploadRequestBodyStructFields({
- filePropertyInfo
- }: {
- filePropertyInfo: FilePropertyInfo;
- }): go.StructField[] {
- if (this.context.customConfig?.inlineFileProperties) {
- return [...filePropertyInfo.fileFields, ...filePropertyInfo.bodyPropertyFields];
- }
- return filePropertyInfo.bodyPropertyFields;
- }
-
- private getReferencedRequestBodyPropertyStructField({
- body,
- value
- }: {
- body: DynamicSnippets.ReferencedRequestBody;
- value: unknown;
- }): go.StructField {
- return {
- name: this.context.getTypeName(body.bodyKey),
- value: this.getReferencedRequestBodyPropertyTypeInstantiation({ body: body.bodyType, value })
- };
- }
-
- private getReferencedRequestBodyPropertyTypeInstantiation({
- body,
- value
- }: {
- body: DynamicSnippets.ReferencedRequestBodyType;
- value: unknown;
- }): go.TypeInstantiation {
- switch (body.type) {
- case "bytes":
- return this.getBytesBodyRequestArg({ value });
- case "typeReference":
- return this.context.dynamicTypeInstantiationMapper.convert({ typeReference: body.value, value });
- }
- }
-
- private getInlinedRequestBodyPropertyStructFields({
- parameters,
- value
- }: {
- parameters: DynamicSnippets.NamedParameter[];
- value: unknown;
- }): go.StructField[] {
- const fields: go.StructField[] = [];
-
- const bodyProperties = this.context.associateByWireValue({
- parameters,
- values: this.context.getRecord(value) ?? {}
- });
- for (const parameter of bodyProperties) {
- fields.push({
- name: this.context.getTypeName(parameter.name.name),
- value: this.context.dynamicTypeInstantiationMapper.convert(parameter)
- });
- }
-
- return fields;
- }
-
- private getPathParameters({
- namedParameters,
- snippet
- }: {
- namedParameters: DynamicSnippets.NamedParameter[];
- snippet: DynamicSnippets.EndpointSnippetRequest;
- }): go.StructField[] {
- const args: go.StructField[] = [];
-
- const pathParameters = this.context.associateByWireValue({
- parameters: namedParameters,
- values: snippet.pathParameters ?? {}
- });
- for (const parameter of pathParameters) {
- args.push({
- name: this.context.getTypeName(parameter.name.name),
- value: this.context.dynamicTypeInstantiationMapper.convert(parameter)
- });
- }
-
- return args;
- }
-
- private getMethod({ endpoint }: { endpoint: DynamicSnippets.Endpoint }): string {
- if (endpoint.declaration.fernFilepath.allParts.length > 0) {
- return `${endpoint.declaration.fernFilepath.allParts
- .map((val) => this.context.getMethodName(val))
- .join(".")}.${this.context.getMethodName(endpoint.declaration.name)}`;
- }
- return this.context.getMethodName(endpoint.declaration.name);
- }
-
- private getRootClientFuncInvocation(arguments_: go.AstNode[]): go.FuncInvocation {
- return go.invokeFunc({
- func: go.typeReference({
- name: "NewClient",
- importPath: this.context.getClientImportPath()
- }),
- arguments_
- });
- }
-
- private newAuthMismatchError({
- auth,
- values
- }: {
- auth: DynamicSnippets.Auth;
- values: DynamicSnippets.AuthValues;
- }): Error {
- return new Error(`Expected auth type ${auth.type}, got ${values.type}`);
+ return result.getResponseOrThrow({ endpoint: request.endpoint });
}
}
diff --git a/generators/go-v2/dynamic-snippets/src/EndpointSnippetGenerator.ts b/generators/go-v2/dynamic-snippets/src/EndpointSnippetGenerator.ts
new file mode 100644
index 00000000000..f14e918b465
--- /dev/null
+++ b/generators/go-v2/dynamic-snippets/src/EndpointSnippetGenerator.ts
@@ -0,0 +1,666 @@
+import { AbstractFormatter } from "@fern-api/browser-compatible-base-generator";
+import { go } from "@fern-api/go-ast";
+import { DynamicSnippetsGeneratorContext } from "./context/DynamicSnippetsGeneratorContext";
+import { dynamic as DynamicSnippets } from "@fern-fern/ir-sdk/api";
+import { Severity } from "./context/ErrorReporter";
+import { Scope } from "./Scope";
+import { FilePropertyInfo } from "./context/FilePropertyMapper";
+
+const SNIPPET_PACKAGE_NAME = "example";
+const SNIPPET_IMPORT_PATH = "fern";
+const SNIPPET_FUNC_NAME = "do";
+const CLIENT_VAR_NAME = "client";
+
+export class EndpointSnippetGenerator {
+ private context: DynamicSnippetsGeneratorContext;
+ private formatter: AbstractFormatter | undefined;
+
+ constructor({ context, formatter }: { context: DynamicSnippetsGeneratorContext; formatter?: AbstractFormatter }) {
+ this.context = context;
+ this.formatter = formatter;
+ }
+
+ public async generateSnippet({
+ endpoint,
+ request
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ request: DynamicSnippets.EndpointSnippetRequest;
+ }): Promise {
+ const code = this.buildCodeBlock({ endpoint, snippet: request });
+ return await code.toString({
+ packageName: SNIPPET_PACKAGE_NAME,
+ importPath: SNIPPET_IMPORT_PATH,
+ rootImportPath: this.context.rootImportPath,
+ customConfig: this.context.customConfig ?? {},
+ formatter: this.formatter
+ });
+ }
+
+ public generateSnippetSync({
+ endpoint,
+ request
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ request: DynamicSnippets.EndpointSnippetRequest;
+ }): string {
+ const code = this.buildCodeBlock({ endpoint, snippet: request });
+ return code.toStringSync({
+ packageName: SNIPPET_PACKAGE_NAME,
+ importPath: SNIPPET_IMPORT_PATH,
+ rootImportPath: this.context.rootImportPath,
+ customConfig: this.context.customConfig ?? {},
+ formatter: this.formatter
+ });
+ }
+
+ private buildCodeBlock({
+ endpoint,
+ snippet
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.AstNode {
+ return go.func({
+ name: SNIPPET_FUNC_NAME,
+ parameters: [],
+ return_: [],
+ body: go.codeblock((writer) => {
+ writer.writeNode(this.constructClient({ endpoint, snippet }));
+ writer.writeLine();
+ writer.writeNode(this.callMethod({ endpoint, snippet }));
+ })
+ });
+ }
+
+ private constructClient({
+ endpoint,
+ snippet
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.CodeBlock {
+ return go.codeblock((writer) => {
+ writer.write(`${CLIENT_VAR_NAME} := `);
+ writer.writeNode(this.getRootClientFuncInvocation(this.getConstructorArgs({ endpoint, snippet })));
+ });
+ }
+
+ private callMethod({
+ endpoint,
+ snippet
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.MethodInvocation {
+ return go.invokeMethod({
+ on: go.codeblock(CLIENT_VAR_NAME),
+ method: this.getMethod({ endpoint }),
+ arguments_: [this.context.getContextTodoFunctionInvocation(), ...this.getMethodArgs({ endpoint, snippet })]
+ });
+ }
+
+ private getConstructorArgs({
+ endpoint,
+ snippet
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.AstNode[] {
+ const args: go.AstNode[] = [];
+ const baseUrlArg = this.getConstructorBaseUrlArg({
+ baseUrl: snippet.baseUrl,
+ environment: snippet.environment
+ });
+ if (baseUrlArg != null) {
+ args.push(baseUrlArg);
+ }
+ if (endpoint.auth != null) {
+ if (snippet.auth != null) {
+ args.push(this.getConstructorAuthArg({ auth: endpoint.auth, values: snippet.auth }));
+ } else {
+ this.context.errors.add({
+ severity: Severity.Warning,
+ message: `Auth with ${endpoint.auth.type} configuration is required for this endpoint`
+ });
+ }
+ }
+ this.context.errors.scope(Scope.Headers);
+ if (this.context.ir.headers != null && snippet.headers != null) {
+ args.push(...this.getConstructorHeaderArgs({ headers: this.context.ir.headers, values: snippet.headers }));
+ }
+ this.context.errors.unscope();
+ return args;
+ }
+
+ private getConstructorAuthArg({
+ auth,
+ values
+ }: {
+ auth: DynamicSnippets.Auth;
+ values: DynamicSnippets.AuthValues;
+ }): go.AstNode {
+ switch (auth.type) {
+ case "basic":
+ if (values.type !== "basic") {
+ this.context.errors.add({
+ severity: Severity.Critical,
+ message: this.newAuthMismatchError({ auth, values }).message
+ });
+ return go.TypeInstantiation.nop();
+ }
+ return this.getConstructorBasicAuthArg({ auth, values });
+ case "bearer":
+ if (values.type !== "bearer") {
+ this.context.errors.add({
+ severity: Severity.Critical,
+ message: this.newAuthMismatchError({ auth, values }).message
+ });
+ return go.TypeInstantiation.nop();
+ }
+ return this.getConstructorBearerAuthArg({ auth, values });
+ case "header":
+ if (values.type !== "header") {
+ this.context.errors.add({
+ severity: Severity.Critical,
+ message: this.newAuthMismatchError({ auth, values }).message
+ });
+ return go.TypeInstantiation.nop();
+ }
+ return this.getConstructorHeaderAuthArg({ auth, values });
+ }
+ }
+
+ private getConstructorBasicAuthArg({
+ auth,
+ values
+ }: {
+ auth: DynamicSnippets.BasicAuth;
+ values: DynamicSnippets.BasicAuthValues;
+ }): go.AstNode {
+ return go.codeblock((writer) => {
+ writer.writeNode(
+ go.invokeFunc({
+ func: go.typeReference({
+ name: "WithBasicAuth",
+ importPath: this.context.getOptionImportPath()
+ }),
+ arguments_: [
+ go.TypeInstantiation.string(values.username),
+ go.TypeInstantiation.string(values.password)
+ ]
+ })
+ );
+ });
+ }
+
+ private getConstructorBaseUrlArg({
+ baseUrl,
+ environment
+ }: {
+ baseUrl: string | undefined;
+ environment: DynamicSnippets.EnvironmentValues | undefined;
+ }): go.AstNode | undefined {
+ const baseUrlArg = this.getBaseUrlArg({ baseUrl, environment });
+ if (baseUrlArg == null) {
+ return undefined;
+ }
+ return go.codeblock((writer) => {
+ writer.writeNode(
+ go.invokeFunc({
+ func: go.typeReference({
+ name: "WithBaseURL",
+ importPath: this.context.getOptionImportPath()
+ }),
+ arguments_: [baseUrlArg]
+ })
+ );
+ });
+ }
+
+ private getBaseUrlArg({
+ baseUrl,
+ environment
+ }: {
+ baseUrl: string | undefined;
+ environment: DynamicSnippets.EnvironmentValues | undefined;
+ }): go.AstNode | undefined {
+ if (baseUrl != null && environment != null) {
+ this.context.errors.add({
+ severity: Severity.Critical,
+ message: "Cannot specify both baseUrl and environment options"
+ });
+ return undefined;
+ }
+ if (baseUrl != null) {
+ return go.TypeInstantiation.string(baseUrl);
+ }
+ if (environment != null) {
+ if (this.context.isSingleEnvironmentID(environment)) {
+ const typeReference = this.context.getEnvironmentTypeReferenceFromID(environment);
+ if (typeReference == null) {
+ this.context.errors.add({
+ severity: Severity.Warning,
+ message: `Environment "${environment}" was not found`
+ });
+ return undefined;
+ }
+ return go.TypeInstantiation.reference(typeReference);
+ }
+ if (this.context.isMultiEnvironmentValues(environment)) {
+ this.context.errors.add({
+ severity: Severity.Warning,
+ message:
+ "The Go SDK doesn't support a multi-environment client option yet; use the baseUrl option instead"
+ });
+ }
+ }
+ return undefined;
+ }
+
+ private getConstructorBearerAuthArg({
+ auth,
+ values
+ }: {
+ auth: DynamicSnippets.BearerAuth;
+ values: DynamicSnippets.BearerAuthValues;
+ }): go.AstNode {
+ return go.codeblock((writer) => {
+ writer.writeNode(
+ go.invokeFunc({
+ func: go.typeReference({
+ name: `With${auth.token.pascalCase.unsafeName}`,
+ importPath: this.context.getOptionImportPath()
+ }),
+ arguments_: [go.TypeInstantiation.string(values.token)]
+ })
+ );
+ });
+ }
+
+ private getConstructorHeaderAuthArg({
+ auth,
+ values
+ }: {
+ auth: DynamicSnippets.HeaderAuth;
+ values: DynamicSnippets.HeaderAuthValues;
+ }): go.AstNode {
+ return go.codeblock((writer) => {
+ writer.writeNode(
+ go.invokeFunc({
+ func: go.typeReference({
+ name: `With${auth.header.name.name.pascalCase.unsafeName}`,
+ importPath: this.context.getOptionImportPath()
+ }),
+ arguments_: [
+ this.context.dynamicTypeInstantiationMapper.convert({
+ typeReference: auth.header.typeReference,
+ value: values.value
+ })
+ ]
+ })
+ );
+ });
+ }
+
+ private getConstructorHeaderArgs({
+ headers,
+ values
+ }: {
+ headers: DynamicSnippets.NamedParameter[];
+ values: DynamicSnippets.Values;
+ }): go.AstNode[] {
+ const args: go.AstNode[] = [];
+ for (const header of headers) {
+ const arg = this.getConstructorHeaderArg({ header, value: values.value });
+ if (arg != null) {
+ args.push(arg);
+ }
+ }
+ return args;
+ }
+
+ private getConstructorHeaderArg({
+ header,
+ value
+ }: {
+ header: DynamicSnippets.NamedParameter;
+ value: unknown;
+ }): go.AstNode | undefined {
+ const typeInstantiation = this.context.dynamicTypeInstantiationMapper.convert({
+ typeReference: header.typeReference,
+ value
+ });
+ if (go.TypeInstantiation.isNop(typeInstantiation)) {
+ // Literal header values (e.g. "X-API-Version") should not be included in the
+ // client constructor.
+ return undefined;
+ }
+ return go.codeblock((writer) => {
+ writer.writeNode(
+ go.invokeFunc({
+ func: go.typeReference({
+ name: `With${header.name.name.pascalCase.unsafeName}`,
+ importPath: this.context.getOptionImportPath()
+ }),
+ arguments_: [typeInstantiation]
+ })
+ );
+ });
+ }
+
+ private getMethodArgs({
+ endpoint,
+ snippet
+ }: {
+ endpoint: DynamicSnippets.Endpoint;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.AstNode[] {
+ switch (endpoint.request.type) {
+ case "inlined":
+ return this.getMethodArgsForInlinedRequest({ request: endpoint.request, snippet });
+ case "body":
+ return this.getMethodArgsForBodyRequest({ request: endpoint.request, snippet });
+ }
+ }
+
+ private getMethodArgsForBodyRequest({
+ request,
+ snippet
+ }: {
+ request: DynamicSnippets.BodyRequest;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.TypeInstantiation[] {
+ const args: go.TypeInstantiation[] = [];
+
+ this.context.errors.scope(Scope.PathParameters);
+ if (request.pathParameters != null) {
+ const pathParameterFields = this.getPathParameters({ namedParameters: request.pathParameters, snippet });
+ args.push(...pathParameterFields.map((field) => field.value));
+ }
+ this.context.errors.unscope();
+
+ this.context.errors.scope(Scope.RequestBody);
+ if (request.body != null) {
+ args.push(this.getBodyRequestArg({ body: request.body, value: snippet.requestBody }));
+ }
+ this.context.errors.unscope();
+
+ return args;
+ }
+
+ private getBodyRequestArg({
+ body,
+ value
+ }: {
+ body: DynamicSnippets.ReferencedRequestBodyType;
+ value: unknown;
+ }): go.TypeInstantiation {
+ switch (body.type) {
+ case "bytes": {
+ return this.getBytesBodyRequestArg({ value });
+ }
+ case "typeReference":
+ return this.context.dynamicTypeInstantiationMapper.convert({ typeReference: body.value, value });
+ }
+ }
+
+ private getBytesBodyRequestArg({ value }: { value: unknown }): go.TypeInstantiation {
+ if (typeof value !== "string") {
+ this.context.errors.add({
+ severity: Severity.Critical,
+ message: `Expected bytes value to be a string, got ${typeof value}`
+ });
+ return go.TypeInstantiation.nop();
+ }
+ return go.TypeInstantiation.bytes(value as string);
+ }
+
+ private getMethodArgsForInlinedRequest({
+ request,
+ snippet
+ }: {
+ request: DynamicSnippets.InlinedRequest;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.TypeInstantiation[] {
+ const args: go.TypeInstantiation[] = [];
+
+ this.context.errors.scope(Scope.PathParameters);
+ const pathParameterFields: go.StructField[] = [];
+ if (request.pathParameters != null) {
+ pathParameterFields.push(...this.getPathParameters({ namedParameters: request.pathParameters, snippet }));
+ }
+ this.context.errors.unscope();
+
+ this.context.errors.scope(Scope.RequestBody);
+ const filePropertyInfo = this.getFilePropertyInfo({ request, snippet });
+ this.context.errors.unscope();
+
+ if (!this.context.includePathParametersInWrappedRequest({ request })) {
+ args.push(...pathParameterFields.map((field) => field.value));
+ }
+
+ if (!this.context.customConfig?.inlineFileProperties) {
+ args.push(...filePropertyInfo.fileFields.map((field) => field.value));
+ }
+
+ if (this.context.needsRequestParameter({ request })) {
+ args.push(
+ this.getInlinedRequestArg({
+ request,
+ snippet,
+ pathParameterFields: this.context.includePathParametersInWrappedRequest({ request })
+ ? pathParameterFields
+ : [],
+ filePropertyInfo
+ })
+ );
+ }
+ return args;
+ }
+
+ private getFilePropertyInfo({
+ request,
+ snippet
+ }: {
+ request: DynamicSnippets.InlinedRequest;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): FilePropertyInfo {
+ if (request.body == null || !this.context.isFileUploadRequestBody(request.body)) {
+ return {
+ fileFields: [],
+ bodyPropertyFields: []
+ };
+ }
+ return this.context.filePropertyMapper.getFilePropertyInfo({
+ body: request.body,
+ value: snippet.requestBody
+ });
+ }
+
+ private getInlinedRequestArg({
+ request,
+ snippet,
+ pathParameterFields,
+ filePropertyInfo
+ }: {
+ request: DynamicSnippets.InlinedRequest;
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ pathParameterFields: go.StructField[];
+ filePropertyInfo: FilePropertyInfo;
+ }): go.TypeInstantiation {
+ this.context.errors.scope(Scope.QueryParameters);
+ const queryParameters = this.context.associateQueryParametersByWireValue({
+ parameters: request.queryParameters ?? [],
+ values: snippet.queryParameters ?? {}
+ });
+ const queryParameterFields = queryParameters.map((queryParameter) => ({
+ name: queryParameter.name.name.pascalCase.unsafeName,
+ value: this.context.dynamicTypeInstantiationMapper.convert(queryParameter)
+ }));
+ this.context.errors.unscope();
+
+ this.context.errors.scope(Scope.Headers);
+ const headers = this.context.associateByWireValue({
+ parameters: request.headers ?? [],
+ values: snippet.headers ?? {}
+ });
+ const headerFields = headers.map((header) => ({
+ name: header.name.name.pascalCase.unsafeName,
+ value: this.context.dynamicTypeInstantiationMapper.convert(header)
+ }));
+ this.context.errors.unscope();
+
+ this.context.errors.scope(Scope.RequestBody);
+ const requestBodyFields =
+ request.body != null
+ ? this.getInlinedRequestBodyStructFields({
+ body: request.body,
+ value: snippet.requestBody,
+ filePropertyInfo
+ })
+ : [];
+ this.context.errors.unscope();
+
+ return go.TypeInstantiation.structPointer({
+ typeReference: go.typeReference({
+ name: this.context.getMethodName(request.declaration.name),
+ importPath: this.context.getImportPath(request.declaration.fernFilepath)
+ }),
+ fields: [...pathParameterFields, ...queryParameterFields, ...headerFields, ...requestBodyFields]
+ });
+ }
+
+ private getInlinedRequestBodyStructFields({
+ body,
+ value,
+ filePropertyInfo
+ }: {
+ body: DynamicSnippets.InlinedRequestBody;
+ value: unknown;
+ filePropertyInfo: FilePropertyInfo;
+ }): go.StructField[] {
+ switch (body.type) {
+ case "properties":
+ return this.getInlinedRequestBodyPropertyStructFields({ parameters: body.value, value });
+ case "referenced":
+ return [this.getReferencedRequestBodyPropertyStructField({ body, value })];
+ case "fileUpload":
+ return this.getFileUploadRequestBodyStructFields({ filePropertyInfo });
+ }
+ }
+
+ private getFileUploadRequestBodyStructFields({
+ filePropertyInfo
+ }: {
+ filePropertyInfo: FilePropertyInfo;
+ }): go.StructField[] {
+ if (this.context.customConfig?.inlineFileProperties) {
+ return [...filePropertyInfo.fileFields, ...filePropertyInfo.bodyPropertyFields];
+ }
+ return filePropertyInfo.bodyPropertyFields;
+ }
+
+ private getReferencedRequestBodyPropertyStructField({
+ body,
+ value
+ }: {
+ body: DynamicSnippets.ReferencedRequestBody;
+ value: unknown;
+ }): go.StructField {
+ return {
+ name: this.context.getTypeName(body.bodyKey),
+ value: this.getReferencedRequestBodyPropertyTypeInstantiation({ body: body.bodyType, value })
+ };
+ }
+
+ private getReferencedRequestBodyPropertyTypeInstantiation({
+ body,
+ value
+ }: {
+ body: DynamicSnippets.ReferencedRequestBodyType;
+ value: unknown;
+ }): go.TypeInstantiation {
+ switch (body.type) {
+ case "bytes":
+ return this.getBytesBodyRequestArg({ value });
+ case "typeReference":
+ return this.context.dynamicTypeInstantiationMapper.convert({ typeReference: body.value, value });
+ }
+ }
+
+ private getInlinedRequestBodyPropertyStructFields({
+ parameters,
+ value
+ }: {
+ parameters: DynamicSnippets.NamedParameter[];
+ value: unknown;
+ }): go.StructField[] {
+ const fields: go.StructField[] = [];
+
+ const bodyProperties = this.context.associateByWireValue({
+ parameters,
+ values: this.context.getRecord(value) ?? {}
+ });
+ for (const parameter of bodyProperties) {
+ fields.push({
+ name: this.context.getTypeName(parameter.name.name),
+ value: this.context.dynamicTypeInstantiationMapper.convert(parameter)
+ });
+ }
+
+ return fields;
+ }
+
+ private getPathParameters({
+ namedParameters,
+ snippet
+ }: {
+ namedParameters: DynamicSnippets.NamedParameter[];
+ snippet: DynamicSnippets.EndpointSnippetRequest;
+ }): go.StructField[] {
+ const args: go.StructField[] = [];
+
+ const pathParameters = this.context.associateByWireValue({
+ parameters: namedParameters,
+ values: snippet.pathParameters ?? {}
+ });
+ for (const parameter of pathParameters) {
+ args.push({
+ name: this.context.getTypeName(parameter.name.name),
+ value: this.context.dynamicTypeInstantiationMapper.convert(parameter)
+ });
+ }
+
+ return args;
+ }
+
+ private getMethod({ endpoint }: { endpoint: DynamicSnippets.Endpoint }): string {
+ if (endpoint.declaration.fernFilepath.allParts.length > 0) {
+ return `${endpoint.declaration.fernFilepath.allParts
+ .map((val) => this.context.getMethodName(val))
+ .join(".")}.${this.context.getMethodName(endpoint.declaration.name)}`;
+ }
+ return this.context.getMethodName(endpoint.declaration.name);
+ }
+
+ private getRootClientFuncInvocation(arguments_: go.AstNode[]): go.FuncInvocation {
+ return go.invokeFunc({
+ func: go.typeReference({
+ name: this.context.getClientConstructorName(),
+ importPath: this.context.getClientImportPath()
+ }),
+ arguments_
+ });
+ }
+
+ private newAuthMismatchError({
+ auth,
+ values
+ }: {
+ auth: DynamicSnippets.Auth;
+ values: DynamicSnippets.AuthValues;
+ }): Error {
+ return new Error(`Expected auth type ${auth.type}, got ${values.type}`);
+ }
+}
diff --git a/generators/go-v2/dynamic-snippets/src/Result.ts b/generators/go-v2/dynamic-snippets/src/Result.ts
new file mode 100644
index 00000000000..4389132b31a
--- /dev/null
+++ b/generators/go-v2/dynamic-snippets/src/Result.ts
@@ -0,0 +1,32 @@
+import { DynamicSnippetsGeneratorContext } from "./context/DynamicSnippetsGeneratorContext";
+import { ErrorReporter } from "./context/ErrorReporter";
+import { dynamic } from "@fern-fern/ir-sdk/api";
+
+export class Result {
+ public reporter: ErrorReporter | undefined;
+ public snippet: string | undefined;
+ public err: Error | undefined;
+
+ constructor() {
+ this.snippet = undefined;
+ this.reporter = undefined;
+ this.err = undefined;
+ }
+
+ public update({ context, snippet }: { context: DynamicSnippetsGeneratorContext; snippet: string }): void {
+ if (this.reporter == null || this.reporter.size() > context.errors.size()) {
+ this.reporter = context.errors.clone();
+ this.snippet = snippet;
+ }
+ }
+
+ public getResponseOrThrow({ endpoint }: { endpoint: dynamic.EndpointLocation }): dynamic.EndpointSnippetResponse {
+ if (this.snippet != null && this.reporter != null) {
+ return {
+ snippet: this.snippet,
+ errors: this.reporter.toDynamicSnippetErrors()
+ };
+ }
+ throw this.err ?? new Error(`Failed to generate snippet for endpoint "${endpoint.method} ${endpoint.path}"`);
+ }
+}
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/imdb.test.ts.snap b/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/imdb.test.ts.snap
index 75f048bade0..eadbd3fb122 100644
--- a/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/imdb.test.ts.snap
+++ b/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/imdb.test.ts.snap
@@ -119,3 +119,52 @@ func do() () {
}
"
`;
+
+exports[`imdb (sync) > GET /movies/{movieId} w/ baseURL 1`] = `
+"package example
+
+import (
+ client "github.com/acme/acme-go/client"
+ option "github.com/acme/acme-go/option"
+ context "context"
+)
+
+func do() () {
+ client := client.NewClient(
+ option.WithBaseURL(
+ "http://localhost:8080",
+ ),
+ option.WithToken(
+ "",
+ ),
+ )
+ client.Imdb.GetMovie(
+ context.TODO(),
+ "movie_xyz",
+ )
+}
+"
+`;
+
+exports[`imdb (sync) > GET /movies/{movieId} w/ exportedClientName 1`] = `
+"package example
+
+import (
+ client "github.com/acme/acme-go/client"
+ option "github.com/acme/acme-go/option"
+ context "context"
+)
+
+func do() () {
+ client := client.NewFernClient(
+ option.WithToken(
+ "",
+ ),
+ )
+ client.Imdb.GetMovie(
+ context.TODO(),
+ "movie_xyz",
+ )
+}
+"
+`;
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/single-url-environment-default.test.ts.snap b/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/single-url-environment-default.test.ts.snap
new file mode 100644
index 00000000000..76d4f3794ab
--- /dev/null
+++ b/generators/go-v2/dynamic-snippets/src/__test__/__snapshots__/single-url-environment-default.test.ts.snap
@@ -0,0 +1,98 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`single-url-environment-default > custom baseURL 1`] = `
+"package example
+
+import (
+ context "context"
+ client "github.com/acme/acme-go/client"
+ option "github.com/acme/acme-go/option"
+)
+
+func do() {
+ client := client.NewClient(
+ option.WithBaseURL(
+ "http://localhost:8080",
+ ),
+ option.WithToken(
+ "",
+ ),
+ )
+ client.Dummy.GetDummy(
+ context.TODO(),
+ )
+}
+"
+`;
+
+exports[`single-url-environment-default > invalid baseURL and environment 1`] = `
+[
+ {
+ "message": "Cannot specify both baseUrl and environment options",
+ "path": [],
+ "severity": "CRITICAL",
+ },
+]
+`;
+
+exports[`single-url-environment-default > invalid environment 1`] = `
+[
+ {
+ "message": "Environment "Unrecognized" was not found",
+ "path": [],
+ "severity": "WARNING",
+ },
+]
+`;
+
+exports[`single-url-environment-default > production environment 1`] = `
+"package example
+
+import (
+ context "context"
+ acme "github.com/acme/acme-go"
+ client "github.com/acme/acme-go/client"
+ option "github.com/acme/acme-go/option"
+)
+
+func do() {
+ client := client.NewClient(
+ option.WithBaseURL(
+ acme.Environments.Production,
+ ),
+ option.WithToken(
+ "",
+ ),
+ )
+ client.Dummy.GetDummy(
+ context.TODO(),
+ )
+}
+"
+`;
+
+exports[`single-url-environment-default > staging environment 1`] = `
+"package example
+
+import (
+ context "context"
+ acme "github.com/acme/acme-go"
+ client "github.com/acme/acme-go/client"
+ option "github.com/acme/acme-go/option"
+)
+
+func do() {
+ client := client.NewClient(
+ option.WithBaseURL(
+ acme.Environments.Staging,
+ ),
+ option.WithToken(
+ "",
+ ),
+ )
+ client.Dummy.GetDummy(
+ context.TODO(),
+ )
+}
+"
+`;
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/examples.test.ts b/generators/go-v2/dynamic-snippets/src/__test__/examples.test.ts
index 1d418078939..623116f0a6f 100644
--- a/generators/go-v2/dynamic-snippets/src/__test__/examples.test.ts
+++ b/generators/go-v2/dynamic-snippets/src/__test__/examples.test.ts
@@ -14,6 +14,8 @@ describe("examples", () => {
method: "GET",
path: "/metadata"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: AuthValues.bearer({
token: ""
}),
@@ -35,6 +37,8 @@ describe("examples", () => {
method: "GET",
path: "/metadata"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: AuthValues.bearer({
token: ""
}),
@@ -56,6 +60,8 @@ describe("examples", () => {
method: "POST",
path: "/movie"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: AuthValues.bearer({
token: ""
}),
@@ -89,6 +95,8 @@ describe("examples", () => {
method: "POST",
path: "/big-entity"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: AuthValues.bearer({
token: ""
}),
@@ -128,6 +136,8 @@ describe("examples (errors)", () => {
auth: AuthValues.bearer({
token: ""
}),
+ baseUrl: undefined,
+ environment: undefined,
pathParameters: undefined,
queryParameters: undefined,
headers: undefined,
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/exhaustive.test.ts b/generators/go-v2/dynamic-snippets/src/__test__/exhaustive.test.ts
index c1df36b203e..96e68f6d9e2 100644
--- a/generators/go-v2/dynamic-snippets/src/__test__/exhaustive.test.ts
+++ b/generators/go-v2/dynamic-snippets/src/__test__/exhaustive.test.ts
@@ -14,6 +14,8 @@ describe("exhaustive", () => {
method: "POST",
path: "/container/list-of-primitives"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -30,6 +32,8 @@ describe("exhaustive", () => {
method: "POST",
path: "/container/list-of-objects"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -71,6 +75,8 @@ describe("exhaustive (errors)", () => {
method: "POST",
path: "/container/list-of-objects"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/file-upload.test.ts b/generators/go-v2/dynamic-snippets/src/__test__/file-upload.test.ts
index 33881fc1c78..2f9a16ec52d 100644
--- a/generators/go-v2/dynamic-snippets/src/__test__/file-upload.test.ts
+++ b/generators/go-v2/dynamic-snippets/src/__test__/file-upload.test.ts
@@ -13,6 +13,8 @@ describe("file-upload (success)", () => {
method: "POST",
path: "/"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: undefined,
pathParameters: undefined,
queryParameters: undefined,
@@ -30,6 +32,8 @@ describe("file-upload (success)", () => {
method: "POST",
path: "/just-file"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: undefined,
pathParameters: undefined,
queryParameters: undefined,
@@ -46,6 +50,8 @@ describe("file-upload (success)", () => {
method: "POST",
path: "/just-file-with-query-params"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: undefined,
pathParameters: undefined,
queryParameters: {
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/imdb.test.ts b/generators/go-v2/dynamic-snippets/src/__test__/imdb.test.ts
index 9eb29c90934..cc9037d52e2 100644
--- a/generators/go-v2/dynamic-snippets/src/__test__/imdb.test.ts
+++ b/generators/go-v2/dynamic-snippets/src/__test__/imdb.test.ts
@@ -14,6 +14,8 @@ describe("imdb (success)", () => {
method: "GET",
path: "/movies/{movieId}"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -32,6 +34,8 @@ describe("imdb (success)", () => {
method: "POST",
path: "/movies/create-movie"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -66,6 +70,62 @@ describe("imdb (sync)", () => {
method: "GET",
path: "/movies/{movieId}"
},
+ baseUrl: undefined,
+ environment: undefined,
+ auth: dynamic.AuthValues.bearer({
+ token: ""
+ }),
+ pathParameters: {
+ movieId: "movie_xyz"
+ },
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.snippet).toMatchSnapshot();
+ });
+
+ it("GET /movies/{movieId} w/ baseURL", () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(`${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/imdb.json`),
+ config: buildGeneratorConfig()
+ });
+ const response = generator.generateSync({
+ endpoint: {
+ method: "GET",
+ path: "/movies/{movieId}"
+ },
+ baseUrl: "http://localhost:8080",
+ environment: undefined,
+ auth: dynamic.AuthValues.bearer({
+ token: ""
+ }),
+ pathParameters: {
+ movieId: "movie_xyz"
+ },
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.snippet).toMatchSnapshot();
+ });
+
+ it("GET /movies/{movieId} w/ exportedClientName", () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(`${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/imdb.json`),
+ config: buildGeneratorConfig({
+ customConfig: {
+ exportedClientName: "FernClient"
+ }
+ })
+ });
+ const response = generator.generateSync({
+ endpoint: {
+ method: "GET",
+ path: "/movies/{movieId}"
+ },
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -91,6 +151,8 @@ describe("imdb (errors)", () => {
method: "GET",
path: "/movies/{movieId}"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -114,6 +176,8 @@ describe("imdb (errors)", () => {
method: "POST",
path: "/movies/create-movie"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
@@ -138,6 +202,8 @@ describe("imdb (errors)", () => {
method: "POST",
path: "/movies/create-movie"
},
+ baseUrl: undefined,
+ environment: undefined,
auth: dynamic.AuthValues.bearer({
token: ""
}),
diff --git a/generators/go-v2/dynamic-snippets/src/__test__/single-url-environment-default.test.ts b/generators/go-v2/dynamic-snippets/src/__test__/single-url-environment-default.test.ts
new file mode 100644
index 00000000000..45c17d77fa4
--- /dev/null
+++ b/generators/go-v2/dynamic-snippets/src/__test__/single-url-environment-default.test.ts
@@ -0,0 +1,133 @@
+import { buildDynamicSnippetsGenerator } from "./utils/buildDynamicSnippetsGenerator";
+import { DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY } from "./utils/constant";
+import { buildGeneratorConfig } from "./utils/buildGeneratorConfig";
+import { AuthValues } from "@fern-fern/ir-sdk/api/resources/dynamic";
+import { AbsoluteFilePath } from "@fern-api/path-utils";
+import { TestCase } from "./utils/TestCase";
+
+describe("single-url-environment-default", () => {
+ it("production environment", async () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(
+ `${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/single-url-environment-default.json`
+ ),
+ config: buildGeneratorConfig()
+ });
+ const response = await generator.generate({
+ endpoint: {
+ method: "GET",
+ path: "/dummy"
+ },
+ auth: AuthValues.bearer({
+ token: ""
+ }),
+ baseUrl: undefined,
+ environment: "Production",
+ pathParameters: undefined,
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.snippet).toMatchSnapshot();
+ });
+
+ it("staging environment", async () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(
+ `${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/single-url-environment-default.json`
+ ),
+ config: buildGeneratorConfig()
+ });
+ const response = await generator.generate({
+ endpoint: {
+ method: "GET",
+ path: "/dummy"
+ },
+ auth: AuthValues.bearer({
+ token: ""
+ }),
+ baseUrl: undefined,
+ environment: "Staging",
+ pathParameters: undefined,
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.snippet).toMatchSnapshot();
+ });
+
+ it("custom baseURL", async () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(
+ `${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/single-url-environment-default.json`
+ ),
+ config: buildGeneratorConfig()
+ });
+ const response = await generator.generate({
+ endpoint: {
+ method: "GET",
+ path: "/dummy"
+ },
+ auth: AuthValues.bearer({
+ token: ""
+ }),
+ baseUrl: "http://localhost:8080",
+ environment: undefined,
+ pathParameters: undefined,
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.snippet).toMatchSnapshot();
+ });
+
+ it("invalid environment", async () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(
+ `${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/single-url-environment-default.json`
+ ),
+ config: buildGeneratorConfig()
+ });
+ const response = await generator.generate({
+ endpoint: {
+ method: "GET",
+ path: "/dummy"
+ },
+ auth: AuthValues.bearer({
+ token: ""
+ }),
+ baseUrl: undefined,
+ environment: "Unrecognized",
+ pathParameters: undefined,
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.errors).toMatchSnapshot();
+ });
+
+ it("invalid baseURL and environment", async () => {
+ const generator = buildDynamicSnippetsGenerator({
+ irFilepath: AbsoluteFilePath.of(
+ `${DYNAMIC_IR_TEST_DEFINITIONS_DIRECTORY}/single-url-environment-default.json`
+ ),
+ config: buildGeneratorConfig()
+ });
+ const response = await generator.generate({
+ endpoint: {
+ method: "GET",
+ path: "/dummy"
+ },
+ auth: AuthValues.bearer({
+ token: ""
+ }),
+ baseUrl: "http://localhost:8080",
+ environment: "Production",
+ pathParameters: undefined,
+ queryParameters: undefined,
+ headers: undefined,
+ requestBody: undefined
+ });
+ expect(response.errors).toMatchSnapshot();
+ });
+});
diff --git a/generators/go-v2/dynamic-snippets/src/context/DynamicSnippetsGeneratorContext.ts b/generators/go-v2/dynamic-snippets/src/context/DynamicSnippetsGeneratorContext.ts
index 2fdb3c9b2a7..813d80d9391 100644
--- a/generators/go-v2/dynamic-snippets/src/context/DynamicSnippetsGeneratorContext.ts
+++ b/generators/go-v2/dynamic-snippets/src/context/DynamicSnippetsGeneratorContext.ts
@@ -4,7 +4,7 @@ import {
FernGeneratorExec
} from "@fern-api/browser-compatible-base-generator";
import { BaseGoCustomConfigSchema, resolveRootImportPath } from "@fern-api/go-ast";
-import { FernFilepath, dynamic, TypeId, Name } from "@fern-fern/ir-sdk/api";
+import { FernFilepath, dynamic, TypeId, Name, EnvironmentId } from "@fern-fern/ir-sdk/api";
import { HttpEndpointReferenceParser } from "@fern-api/fern-definition-schema";
import { TypeInstance } from "../TypeInstance";
import { DiscriminatedUnionTypeInstance } from "../DiscriminatedUnionTypeInstance";
@@ -41,6 +41,13 @@ export class DynamicSnippetsGeneratorContext extends AbstractDynamicSnippetsGene
this.httpEndpointReferenceParser = new HttpEndpointReferenceParser();
}
+ public clone(): DynamicSnippetsGeneratorContext {
+ return new DynamicSnippetsGeneratorContext({
+ ir: this.ir,
+ config: this.config
+ });
+ }
+
public associateQueryParametersByWireValue({
parameters,
values
@@ -319,6 +326,13 @@ export class DynamicSnippetsGeneratorContext extends AbstractDynamicSnippetsGene
});
}
+ public getClientConstructorName(): string {
+ if (this.customConfig?.exportedClientName != null) {
+ return `New${this.customConfig.exportedClientName}`;
+ }
+ return "NewClient";
+ }
+
public getClientImportPath(): string {
return `${this.rootImportPath}/client`;
}
@@ -355,10 +369,52 @@ export class DynamicSnippetsGeneratorContext extends AbstractDynamicSnippetsGene
});
}
+ public getEnvironmentTypeReferenceFromID(environmentID: string): go.TypeReference | undefined {
+ if (this.ir.environments == null) {
+ return undefined;
+ }
+ const environments = this.ir.environments.environments;
+ switch (environments.type) {
+ case "singleBaseUrl": {
+ const environment = environments.environments.find((env) => env.id === environmentID);
+ if (environment == null) {
+ return undefined;
+ }
+ return this.getEnvironmentTypeReference(environment.name);
+ }
+ case "multipleBaseUrls": {
+ const environment = environments.environments.find((env) => env.id === environmentID);
+ if (environment == null) {
+ return undefined;
+ }
+ return this.getEnvironmentTypeReference(environment.name);
+ }
+ default:
+ assertNever(environments);
+ }
+ }
+
+ public isSingleEnvironmentID(environment: dynamic.EnvironmentValues): environment is EnvironmentId {
+ return typeof environment === "string";
+ }
+
+ public isMultiEnvironmentValues(
+ environment: dynamic.EnvironmentValues
+ ): environment is dynamic.MultipleEnvironmentUrlValues {
+ return typeof environment === "object";
+ }
+
public newParameterNotRecognizedError(parameterName: string): Error {
return new Error(`"${parameterName}" is not a recognized parameter for this endpoint`);
}
+ private getEnvironmentTypeReference(name: Name): go.TypeReference {
+ return go.typeReference({
+ name: `Environments.${this.getTypeName(name)}`,
+ importPath: this.rootImportPath
+ });
+ }
+
private isListTypeReference(typeReference: dynamic.TypeReference): boolean {
if (typeReference.type === "optional") {
return this.isListTypeReference(typeReference.value);
diff --git a/generators/go/internal/generator/sdk.go b/generators/go/internal/generator/sdk.go
index df87652c474..6922d35ebfa 100644
--- a/generators/go/internal/generator/sdk.go
+++ b/generators/go/internal/generator/sdk.go
@@ -496,6 +496,9 @@ func (f *fileWriter) writePlatformHeaders(
f.P(fmt.Sprintf("headers.Set(%q, %q)", sdkConfig.PlatformHeaders.Language, goLanguageHeader))
f.P(fmt.Sprintf("headers.Set(%q, %q)", sdkConfig.PlatformHeaders.SdkName, moduleConfig.Path))
f.P(fmt.Sprintf("headers.Set(%q, %q)", sdkConfig.PlatformHeaders.SdkVersion, sdkVersion))
+ if sdkConfig.PlatformHeaders.UserAgent != nil {
+ f.P(fmt.Sprintf("headers.Set(%q, %q)", sdkConfig.PlatformHeaders.UserAgent.Header(), sdkConfig.PlatformHeaders.UserAgent.Value))
+ }
f.P("return headers")
f.P("}")
}
diff --git a/generators/go/sdk/versions.yml b/generators/go/sdk/versions.yml
index 380e182455f..9ce98490dc0 100644
--- a/generators/go/sdk/versions.yml
+++ b/generators/go/sdk/versions.yml
@@ -1,3 +1,15 @@
+- version: 0.34.0
+ changelogEntry:
+ - type: feat
+ summary: >-
+ Add support for sending the `User-Agent` header on every request. Go packages
+ are uniquely identified by their full module path, so the `User-Agent` header
+ is generated in the `/` format, e.g.
+
+ ```
+ User-Agent: github.com/acme/acme-go/1.0.0
+ ```
+ irVersion: 53
- version: 0.33.0
changelogEntry:
- type: feat
diff --git a/generators/java/generator-utils/build.gradle b/generators/java/generator-utils/build.gradle
index 98da2c47168..938525d026d 100644
--- a/generators/java/generator-utils/build.gradle
+++ b/generators/java/generator-utils/build.gradle
@@ -1,6 +1,6 @@
dependencies {
api 'com.squareup:javapoet'
- api 'com.fern.fern:irV46'
+ api 'com.fern.fern:irV53'
api 'com.fern.fern:generator-exec-client'
api 'com.fasterxml.jackson.core:jackson-annotations'
api 'com.fasterxml.jackson.core:jackson-databind'
diff --git a/generators/java/generator-utils/src/main/java/com/fern/java/ICustomConfig.java b/generators/java/generator-utils/src/main/java/com/fern/java/ICustomConfig.java
index 724d305faaa..c1021bbecd9 100644
--- a/generators/java/generator-utils/src/main/java/com/fern/java/ICustomConfig.java
+++ b/generators/java/generator-utils/src/main/java/com/fern/java/ICustomConfig.java
@@ -18,6 +18,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
+import java.util.Optional;
import org.immutables.value.Value;
public interface ICustomConfig {
@@ -58,6 +59,9 @@ default Boolean disableRequiredPropertyBuilderChecks() {
return false;
}
+ @JsonProperty("package-prefix")
+ Optional packagePrefix();
+
enum JsonInclude {
NON_EMPTY("non-empty"),
NON_ABSENT("non-absent");
diff --git a/generators/java/generator-utils/src/main/java/com/fern/java/PoetTypeNameMapper.java b/generators/java/generator-utils/src/main/java/com/fern/java/PoetTypeNameMapper.java
index a32ee87e543..610a77f14e9 100644
--- a/generators/java/generator-utils/src/main/java/com/fern/java/PoetTypeNameMapper.java
+++ b/generators/java/generator-utils/src/main/java/com/fern/java/PoetTypeNameMapper.java
@@ -2,17 +2,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fern.ir.model.commons.TypeId;
-import com.fern.ir.model.types.AliasTypeDeclaration;
-import com.fern.ir.model.types.ContainerType;
-import com.fern.ir.model.types.DeclaredTypeName;
-import com.fern.ir.model.types.Literal;
-import com.fern.ir.model.types.MapType;
-import com.fern.ir.model.types.PrimitiveType;
-import com.fern.ir.model.types.PrimitiveTypeV1;
-import com.fern.ir.model.types.ResolvedNamedType;
-import com.fern.ir.model.types.ResolvedTypeReference;
-import com.fern.ir.model.types.TypeDeclaration;
-import com.fern.ir.model.types.TypeReference;
+import com.fern.ir.model.types.*;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterizedTypeName;
@@ -57,9 +47,9 @@ private TypeReferenceToTypeNameConverter(boolean primitiveAllowed) {
}
@Override
- public TypeName visitNamed(DeclaredTypeName declaredTypeName) {
+ public TypeName visitNamed(NamedType named) {
if (!customConfig.wrappedAliases()) {
- TypeDeclaration typeDeclaration = typeDefinitionsByName.get(declaredTypeName.getTypeId());
+ TypeDeclaration typeDeclaration = typeDefinitionsByName.get(named.getTypeId());
boolean isAlias = typeDeclaration.getShape().isAlias();
if (isAlias) {
AliasTypeDeclaration aliasTypeDeclaration =
@@ -67,7 +57,11 @@ public TypeName visitNamed(DeclaredTypeName declaredTypeName) {
return aliasTypeDeclaration.getResolvedType().visit(this);
}
}
- return poetClassNameFactory.getTypeClassName(declaredTypeName);
+ return poetClassNameFactory.getTypeClassName(DeclaredTypeName.builder()
+ .typeId(named.getTypeId())
+ .fernFilepath(named.getFernFilepath())
+ .name(named.getName())
+ .build());
}
@Override
@@ -139,6 +133,30 @@ public TypeName visitLong() {
return ClassName.get(Long.class);
}
+ @Override
+ public TypeName visitUint() {
+ if (primitiveAllowed) {
+ return TypeName.LONG;
+ }
+ return ClassName.get(Long.class);
+ }
+
+ @Override
+ public TypeName visitUint64() {
+ if (primitiveAllowed) {
+ return TypeName.LONG;
+ }
+ return ClassName.get(Long.class);
+ }
+
+ @Override
+ public TypeName visitFloat() {
+ if (primitiveAllowed) {
+ return TypeName.FLOAT;
+ }
+ return ClassName.get(Float.class);
+ }
+
@Override
public TypeName visitDateTime() {
return ClassName.get(OffsetDateTime.class);
diff --git a/generators/java/generator-utils/src/main/java/com/fern/java/generators/AliasGenerator.java b/generators/java/generator-utils/src/main/java/com/fern/java/generators/AliasGenerator.java
index 9d18b794957..404fe93ea42 100644
--- a/generators/java/generator-utils/src/main/java/com/fern/java/generators/AliasGenerator.java
+++ b/generators/java/generator-utils/src/main/java/com/fern/java/generators/AliasGenerator.java
@@ -213,6 +213,21 @@ public CodeBlock visitLong() {
return CodeBlock.of("return $T.$L($L)", Long.class, "toString", VALUE_FIELD_NAME);
}
+ @Override
+ public CodeBlock visitUint() {
+ return CodeBlock.of("return $T.$L($L)", Long.class, "toString", VALUE_FIELD_NAME);
+ }
+
+ @Override
+ public CodeBlock visitUint64() {
+ return CodeBlock.of("return $T.$L($L)", Long.class, "toString", VALUE_FIELD_NAME);
+ }
+
+ @Override
+ public CodeBlock visitFloat() {
+ return CodeBlock.of("return $T.$L($L)", Float.class, "toString", VALUE_FIELD_NAME);
+ }
+
@Override
public CodeBlock visitDateTime() {
return CodeBlock.of("return $L.$L()", VALUE_FIELD_NAME, "toString");
@@ -273,6 +288,21 @@ public CodeBlock visitLong() {
return CodeBlock.of("return $L.hashCode()", VALUE_FIELD_NAME);
}
+ @Override
+ public CodeBlock visitUint() {
+ return CodeBlock.of("return $L.hashCode()", VALUE_FIELD_NAME);
+ }
+
+ @Override
+ public CodeBlock visitUint64() {
+ return CodeBlock.of("return $L.hashCode()", VALUE_FIELD_NAME);
+ }
+
+ @Override
+ public CodeBlock visitFloat() {
+ return CodeBlock.of("return $T.hashCode($L)", Float.class, VALUE_FIELD_NAME);
+ }
+
@Override
public CodeBlock visitDateTime() {
return CodeBlock.of("return $L.hashCode()", VALUE_FIELD_NAME);
diff --git a/generators/java/generator-utils/src/main/java/com/fern/java/generators/UnionGenerator.java b/generators/java/generator-utils/src/main/java/com/fern/java/generators/UnionGenerator.java
index 871c661cfee..9d1b7a78c44 100644
--- a/generators/java/generator-utils/src/main/java/com/fern/java/generators/UnionGenerator.java
+++ b/generators/java/generator-utils/src/main/java/com/fern/java/generators/UnionGenerator.java
@@ -5,12 +5,7 @@
import com.fasterxml.jackson.annotation.JsonValue;
import com.fern.ir.model.commons.NameAndWireValue;
import com.fern.ir.model.constants.Constants;
-import com.fern.ir.model.types.DeclaredTypeName;
-import com.fern.ir.model.types.SingleUnionType;
-import com.fern.ir.model.types.SingleUnionTypeProperties;
-import com.fern.ir.model.types.SingleUnionTypeProperty;
-import com.fern.ir.model.types.TypeReference;
-import com.fern.ir.model.types.UnionTypeDeclaration;
+import com.fern.ir.model.types.*;
import com.fern.java.AbstractGeneratorContext;
import com.fern.java.FernJavaAnnotations;
import com.fern.java.generators.union.UnionSubType;
@@ -192,7 +187,13 @@ public Void visitSamePropertiesAsObject(DeclaredTypeName samePropertiesAsObject)
generatorContext
.getPoetTypeNameMapper()
.convertToTypeName(
- true, TypeReference.named(samePropertiesAsObject)),
+ true,
+ TypeReference.named(NamedType.builder()
+ .typeId(samePropertiesAsObject.getTypeId())
+ .fernFilepath(
+ samePropertiesAsObject.getFernFilepath())
+ .name(samePropertiesAsObject.getName())
+ .build())),
"value")
.build())
.addStatement("this.$L = $L", "value", "value")
@@ -275,7 +276,13 @@ public Optional visitSamePropertiesAsObject(DeclaredTypeName sameProp
return Optional.of(FieldSpec.builder(
generatorContext
.getPoetTypeNameMapper()
- .convertToTypeName(true, TypeReference.named(samePropertiesAsObject)),
+ .convertToTypeName(
+ true,
+ TypeReference.named(NamedType.builder()
+ .typeId(samePropertiesAsObject.getTypeId())
+ .fernFilepath(samePropertiesAsObject.getFernFilepath())
+ .name(samePropertiesAsObject.getName())
+ .build())),
"value",
Modifier.PRIVATE)
.addAnnotation(JsonUnwrapped.class)
diff --git a/generators/java/generator-utils/src/main/java/com/fern/java/utils/TypeReferenceUtils.java b/generators/java/generator-utils/src/main/java/com/fern/java/utils/TypeReferenceUtils.java
index f46380e20d4..cc41a1bd261 100644
--- a/generators/java/generator-utils/src/main/java/com/fern/java/utils/TypeReferenceUtils.java
+++ b/generators/java/generator-utils/src/main/java/com/fern/java/utils/TypeReferenceUtils.java
@@ -1,12 +1,6 @@
package com.fern.java.utils;
-import com.fern.ir.model.types.ContainerType;
-import com.fern.ir.model.types.DeclaredTypeName;
-import com.fern.ir.model.types.Literal;
-import com.fern.ir.model.types.MapType;
-import com.fern.ir.model.types.PrimitiveType;
-import com.fern.ir.model.types.PrimitiveTypeV1;
-import com.fern.ir.model.types.TypeReference;
+import com.fern.ir.model.types.*;
import java.util.Optional;
public class TypeReferenceUtils {
@@ -56,7 +50,7 @@ public String visitContainer(ContainerType container) {
}
@Override
- public String visitNamed(DeclaredTypeName named) {
+ public String visitNamed(NamedType named) {
return named.getName().getPascalCase().getUnsafeName();
}
@@ -171,6 +165,21 @@ public String visitLong() {
return "Long";
}
+ @Override
+ public String visitUint() {
+ return "Long";
+ }
+
+ @Override
+ public String visitUint64() {
+ return "Long";
+ }
+
+ @Override
+ public String visitFloat() {
+ return "Float";
+ }
+
@Override
public String visitDateTime() {
return "DateTime";
diff --git a/generators/java/model/versions.yml b/generators/java/model/versions.yml
index 13a83d04c69..2e1780d9e87 100644
--- a/generators/java/model/versions.yml
+++ b/generators/java/model/versions.yml
@@ -1,3 +1,10 @@
+- changelogEntry:
+ - summary: |
+ Bump IR version to latest (v53)
+ type: chore
+ createdAt: '2024-12-10'
+ irVersion: 53
+ version: 1.3.0
- changelogEntry:
- summary: |
Bump Jackson version to latest (2.17.2)
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/Cli.java b/generators/java/sdk/src/main/java/com/fern/java/client/Cli.java
index 0fb72f3aee2..a7c250fbdb3 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/Cli.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/Cli.java
@@ -119,8 +119,12 @@ public void runInGithubModeHook(
IntermediateRepresentation ir,
JavaSdkCustomConfig customConfig,
GithubOutputMode githubOutputMode) {
- ClientPoetClassNameFactory clientPoetClassNameFactory = new ClientPoetClassNameFactory(
- AbstractPoetClassNameFactory.getPackagePrefixWithOrgAndApiName(ir, generatorConfig.getOrganization()));
+ List packagePrefixTokens = customConfig
+ .packagePrefix()
+ .map(List::of)
+ .orElseGet(() -> AbstractPoetClassNameFactory.getPackagePrefixWithOrgAndApiName(
+ ir, generatorConfig.getOrganization()));
+ ClientPoetClassNameFactory clientPoetClassNameFactory = new ClientPoetClassNameFactory(packagePrefixTokens);
List resolvedAuthSchemes =
new FeatureResolver(ir, generatorConfig, generatorExecClient).getResolvedAuthSchemes();
ClientGeneratorContext context = new ClientGeneratorContext(
@@ -152,8 +156,12 @@ public void runInPublishModeHook(
IntermediateRepresentation ir,
JavaSdkCustomConfig customConfig,
GeneratorPublishConfig publishOutputMode) {
- ClientPoetClassNameFactory clientPoetClassNameFactory = new ClientPoetClassNameFactory(
- AbstractPoetClassNameFactory.getPackagePrefixWithOrgAndApiName(ir, generatorConfig.getOrganization()));
+ List packagePrefixTokens = customConfig
+ .packagePrefix()
+ .map(List::of)
+ .orElseGet(() -> AbstractPoetClassNameFactory.getPackagePrefixWithOrgAndApiName(
+ ir, generatorConfig.getOrganization()));
+ ClientPoetClassNameFactory clientPoetClassNameFactory = new ClientPoetClassNameFactory(packagePrefixTokens);
List resolvedAuthSchemes =
new FeatureResolver(ir, generatorConfig, generatorExecClient).getResolvedAuthSchemes();
ClientGeneratorContext context = new ClientGeneratorContext(
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/AbstractEndpointWriter.java b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/AbstractEndpointWriter.java
index 4448df9d75c..3ff1e9b5ce3 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/AbstractEndpointWriter.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/AbstractEndpointWriter.java
@@ -23,44 +23,9 @@
import com.fern.ir.model.commons.TypeId;
import com.fern.ir.model.environment.EnvironmentBaseUrlId;
import com.fern.ir.model.errors.ErrorDeclaration;
-import com.fern.ir.model.http.BytesRequest;
-import com.fern.ir.model.http.CursorPagination;
-import com.fern.ir.model.http.FileDownloadResponse;
-import com.fern.ir.model.http.FileProperty;
-import com.fern.ir.model.http.FileUploadRequest;
-import com.fern.ir.model.http.FileUploadRequestProperty;
-import com.fern.ir.model.http.HttpEndpoint;
-import com.fern.ir.model.http.HttpRequestBody;
-import com.fern.ir.model.http.HttpRequestBodyReference;
-import com.fern.ir.model.http.HttpResponseBody;
-import com.fern.ir.model.http.HttpService;
-import com.fern.ir.model.http.InlinedRequestBody;
-import com.fern.ir.model.http.InlinedRequestBodyProperty;
-import com.fern.ir.model.http.JsonResponse;
-import com.fern.ir.model.http.JsonResponseBody;
-import com.fern.ir.model.http.JsonResponseBodyWithProperty;
-import com.fern.ir.model.http.JsonStreamChunk;
-import com.fern.ir.model.http.OffsetPagination;
+import com.fern.ir.model.http.*;
import com.fern.ir.model.http.Pagination.Visitor;
-import com.fern.ir.model.http.PathParameter;
-import com.fern.ir.model.http.SdkRequest;
-import com.fern.ir.model.http.SdkRequestBodyType;
-import com.fern.ir.model.http.SdkRequestShape;
-import com.fern.ir.model.http.SdkRequestWrapper;
-import com.fern.ir.model.http.SseStreamChunk;
-import com.fern.ir.model.http.StreamingResponse;
-import com.fern.ir.model.http.TextResponse;
-import com.fern.ir.model.http.TextStreamChunk;
-import com.fern.ir.model.types.AliasTypeDeclaration;
-import com.fern.ir.model.types.DeclaredTypeName;
-import com.fern.ir.model.types.EnumTypeDeclaration;
-import com.fern.ir.model.types.ObjectProperty;
-import com.fern.ir.model.types.ObjectTypeDeclaration;
-import com.fern.ir.model.types.PrimitiveType;
-import com.fern.ir.model.types.Type;
-import com.fern.ir.model.types.TypeDeclaration;
-import com.fern.ir.model.types.UndiscriminatedUnionTypeDeclaration;
-import com.fern.ir.model.types.UnionTypeDeclaration;
+import com.fern.ir.model.types.*;
import com.fern.java.client.ClientGeneratorContext;
import com.fern.java.client.GeneratedClientOptions;
import com.fern.java.client.GeneratedEnvironmentsClass;
@@ -235,10 +200,41 @@ public final HttpEndpointMethodSpecs generate() {
boolean sendContentType = httpEndpoint.getRequestBody().isPresent()
|| (httpEndpoint.getResponse().isPresent()
&& httpEndpoint.getResponse().get().getBody().isPresent());
+ String contentType = httpEndpoint
+ .getRequestBody()
+ .flatMap(body -> body.visit(new HttpRequestBody.Visitor>() {
+ @Override
+ public Optional visitInlinedRequestBody(InlinedRequestBody inlinedRequestBody) {
+ return inlinedRequestBody.getContentType();
+ }
+
+ @Override
+ public Optional visitReference(HttpRequestBodyReference httpRequestBodyReference) {
+ return httpRequestBodyReference.getContentType();
+ }
+
+ @Override
+ public Optional visitFileUpload(FileUploadRequest fileUploadRequest) {
+ // N.B. File upload headers are obtained from request configuration.
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional visitBytes(BytesRequest bytesRequest) {
+ return bytesRequest.getContentType();
+ }
+
+ @Override
+ public Optional _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unknown request type.");
+ }
+ }))
+ .orElse(AbstractEndpointWriter.APPLICATION_JSON_HEADER);
CodeBlock requestInitializer = getInitializeRequestCodeBlock(
clientOptionsField,
generatedClientOptions,
httpEndpoint,
+ contentType,
generatedObjectMapper,
generatedHttpUrl.inlinableBuild(),
sendContentType);
@@ -369,6 +365,7 @@ public abstract CodeBlock getInitializeRequestCodeBlock(
FieldSpec clientOptionsMember,
GeneratedClientOptions clientOptions,
HttpEndpoint endpoint,
+ String contentType,
GeneratedObjectMapper objectMapper,
CodeBlock inlineableHttpUrl,
boolean sendContentType);
@@ -748,6 +745,10 @@ public JsonResponseBodyWithProperty _visitUnknown(Object unknownType) {
httpEndpoint.getPagination().get().visit(new Visitor() {
@Override
public Void visitCursor(CursorPagination cursor) {
+ if (cursor.getPage().getPropertyPath().isPresent()
+ && !cursor.getPage().getPropertyPath().get().isEmpty()) {
+ return null;
+ }
SnippetAndResultType nextSnippet = getNestedPropertySnippet(
cursor.getNext().getPropertyPath(),
cursor.getNext().getProperty(),
@@ -762,10 +763,31 @@ public Void visitCursor(CursorPagination cursor) {
.build();
httpResponseBuilder.addStatement(nextBlock);
String builderStartingAfterProperty = cursor.getPage()
- .getName()
- .getName()
- .getCamelCase()
- .getUnsafeName();
+ .getProperty()
+ .visit(new RequestPropertyValue.Visitor() {
+ @Override
+ public String visitQuery(QueryParameter queryParameter) {
+ return queryParameter
+ .getName()
+ .getName()
+ .getCamelCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String visitBody(ObjectProperty objectProperty) {
+ return objectProperty
+ .getName()
+ .getName()
+ .getCamelCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unkown request property value type.");
+ }
+ });
httpResponseBuilder.addStatement(
"$T $L = $T.builder().from($L).$L($L).build()",
requestParameterSpec.type,
@@ -811,8 +833,30 @@ public Void visitCursor(CursorPagination cursor) {
@Override
public Void visitOffset(OffsetPagination offset) {
- com.fern.ir.model.types.TypeReference pageType =
- offset.getPage().getValueType();
+ if (offset.getPage().getPropertyPath().isPresent()
+ && !offset.getPage().getPropertyPath().get().isEmpty()) {
+ return null;
+ }
+ com.fern.ir.model.types.TypeReference pageType = offset.getPage()
+ .getProperty()
+ .visit(new RequestPropertyValue.Visitor() {
+ @Override
+ public com.fern.ir.model.types.TypeReference visitQuery(
+ QueryParameter queryParameter) {
+ return queryParameter.getValueType();
+ }
+
+ @Override
+ public com.fern.ir.model.types.TypeReference visitBody(
+ ObjectProperty objectProperty) {
+ return objectProperty.getValueType();
+ }
+
+ @Override
+ public com.fern.ir.model.types.TypeReference _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unknown request property value type.");
+ }
+ });
Boolean pageIsOptional = pageType.visit(new TypeReferenceIsOptional(true));
if (pageIsOptional) {
com.fern.ir.model.types.TypeReference numberType =
@@ -824,11 +868,31 @@ public Void visitOffset(OffsetPagination offset) {
.convertToTypeName(true, numberType),
getNewPageNumberVariableName(),
requestParameterSpec.name,
- offset.getPage()
- .getName()
- .getName()
- .getPascalCase()
- .getUnsafeName()));
+ offset.getPage().getProperty().visit(new RequestPropertyValue.Visitor() {
+
+ @Override
+ public String visitQuery(QueryParameter queryParameter) {
+ return queryParameter
+ .getName()
+ .getName()
+ .getPascalCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String visitBody(ObjectProperty objectProperty) {
+ return objectProperty
+ .getName()
+ .getName()
+ .getPascalCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unknown request property value type.");
+ }
+ })));
} else {
httpResponseBuilder.addStatement(CodeBlock.of(
"$T $L = $L.get$L() + 1",
@@ -837,11 +901,31 @@ public Void visitOffset(OffsetPagination offset) {
.convertToTypeName(true, pageType),
getNewPageNumberVariableName(),
requestParameterSpec.name,
- offset.getPage()
- .getName()
- .getName()
- .getPascalCase()
- .getUnsafeName()));
+ offset.getPage().getProperty().visit(new RequestPropertyValue.Visitor() {
+
+ @Override
+ public String visitQuery(QueryParameter queryParameter) {
+ return queryParameter
+ .getName()
+ .getName()
+ .getPascalCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String visitBody(ObjectProperty objectProperty) {
+ return objectProperty
+ .getName()
+ .getName()
+ .getPascalCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unknown request property value type.");
+ }
+ })));
}
httpResponseBuilder.addStatement(
"$T $L = $T.builder().from($L).$L($L).build()",
@@ -849,11 +933,31 @@ public Void visitOffset(OffsetPagination offset) {
getNextRequestVariableName(),
requestParameterSpec.type,
requestParameterSpec.name,
- offset.getPage()
- .getName()
- .getName()
- .getCamelCase()
- .getUnsafeName(),
+ offset.getPage().getProperty().visit(new RequestPropertyValue.Visitor() {
+
+ @Override
+ public String visitQuery(QueryParameter queryParameter) {
+ return queryParameter
+ .getName()
+ .getName()
+ .getCamelCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String visitBody(ObjectProperty objectProperty) {
+ return objectProperty
+ .getName()
+ .getName()
+ .getCamelCase()
+ .getUnsafeName();
+ }
+
+ @Override
+ public String _visitUnknown(Object o) {
+ throw new IllegalArgumentException("Unknown request property value type.");
+ }
+ }),
getNewPageNumberVariableName());
SnippetAndResultType resultSnippet = getNestedPropertySnippet(
@@ -961,6 +1065,12 @@ public com.fern.ir.model.types.TypeReference _visitUnknown(Object unknownType) {
return null;
}
+ @Override
+ public Void visitStreamParameter(StreamParameterResponse streamParameterResponse) {
+ // TODO: Implement stream parameters.
+ throw new UnsupportedOperationException("Not implemented.");
+ }
+
@Override
public Void _visitUnknown(Object unknownType) {
return null;
@@ -1097,7 +1207,7 @@ public GetSnippetOutput visitContainer(com.fern.ir.model.types.ContainerType con
}
@Override
- public GetSnippetOutput visitNamed(DeclaredTypeName named) {
+ public GetSnippetOutput visitNamed(NamedType named) {
TypeDeclaration typeDeclaration =
clientGeneratorContext.getTypeDeclarations().get(named.getTypeId());
return typeDeclaration.getShape().visit(new Type.Visitor<>() {
@@ -1141,7 +1251,11 @@ public GetSnippetOutput visitObject(ObjectTypeDeclaration object) {
if (maybeMatchingProperty.isEmpty()) {
for (DeclaredTypeName declaredTypeName : object.getExtends()) {
try {
- return visitNamed(declaredTypeName);
+ return visitNamed(NamedType.builder()
+ .typeId(declaredTypeName.getTypeId())
+ .fernFilepath(declaredTypeName.getFernFilepath())
+ .name(declaredTypeName.getName())
+ .build());
} catch (Exception e) {
}
}
@@ -1299,7 +1413,7 @@ public Boolean visitContainer(com.fern.ir.model.types.ContainerType container) {
}
@Override
- public Boolean visitNamed(DeclaredTypeName named) {
+ public Boolean visitNamed(NamedType named) {
if (visitNamedType) {
TypeDeclaration typeDeclaration =
clientGeneratorContext.getTypeDeclarations().get(named.getTypeId());
@@ -1412,7 +1526,7 @@ public Boolean visitFile(FileProperty file) {
}
@Override
- public Boolean visitBodyProperty(InlinedRequestBodyProperty bodyProperty) {
+ public Boolean visitBodyProperty(FileUploadBodyProperty bodyProperty) {
return bodyProperty.getValueType().visit(new TypeReferenceIsOptional(false));
}
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/HttpRequestBodyIsWrappedInOptional.java b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/HttpRequestBodyIsWrappedInOptional.java
index 260ef382a25..f46a30b351a 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/HttpRequestBodyIsWrappedInOptional.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/HttpRequestBodyIsWrappedInOptional.java
@@ -22,7 +22,7 @@
import com.fern.ir.model.http.HttpRequestBodyReference;
import com.fern.ir.model.http.InlinedRequestBody;
import com.fern.ir.model.types.ContainerType;
-import com.fern.ir.model.types.DeclaredTypeName;
+import com.fern.ir.model.types.NamedType;
import com.fern.ir.model.types.PrimitiveType;
public class HttpRequestBodyIsWrappedInOptional {
@@ -72,7 +72,7 @@ public Boolean visitContainer(ContainerType container) {
}
@Override
- public Boolean visitNamed(DeclaredTypeName named) {
+ public Boolean visitNamed(NamedType named) {
return false;
}
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/NoRequestEndpointWriter.java b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/NoRequestEndpointWriter.java
index 204d6489dc5..2508645bffe 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/NoRequestEndpointWriter.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/NoRequestEndpointWriter.java
@@ -17,10 +17,7 @@
package com.fern.java.client.generators.endpoint;
import com.fern.ir.model.commons.ErrorId;
-import com.fern.ir.model.http.HttpEndpoint;
-import com.fern.ir.model.http.HttpMethod;
-import com.fern.ir.model.http.HttpService;
-import com.fern.ir.model.http.SdkRequest;
+import com.fern.ir.model.http.*;
import com.fern.java.client.ClientGeneratorContext;
import com.fern.java.client.GeneratedClientOptions;
import com.fern.java.client.GeneratedEnvironmentsClass;
@@ -86,6 +83,7 @@ public CodeBlock getInitializeRequestCodeBlock(
FieldSpec clientOptionsMember,
GeneratedClientOptions clientOptions,
HttpEndpoint httpEndpoint,
+ String contentType,
GeneratedObjectMapper generatedObjectMapper,
CodeBlock inlineableHttpUrl,
boolean sendContentType) {
@@ -111,10 +109,7 @@ public CodeBlock getInitializeRequestCodeBlock(
ClientOptionsGenerator.HEADERS_METHOD_NAME,
REQUEST_OPTIONS_PARAMETER_NAME);
if (sendContentType) {
- builder.add(
- ".addHeader($S, $S)\n",
- AbstractEndpointWriter.CONTENT_TYPE_HEADER,
- AbstractEndpointWriter.APPLICATION_JSON_HEADER);
+ builder.add(".addHeader($S, $S)\n", AbstractEndpointWriter.CONTENT_TYPE_HEADER, contentType);
}
return builder.add(".build();\n").unindent().build();
}
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/OnlyRequestEndpointWriter.java b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/OnlyRequestEndpointWriter.java
index 5434d9c69eb..bf4c57d8890 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/OnlyRequestEndpointWriter.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/OnlyRequestEndpointWriter.java
@@ -167,6 +167,7 @@ public CodeBlock getInitializeRequestCodeBlock(
FieldSpec clientOptionsMember,
GeneratedClientOptions clientOptions,
HttpEndpoint endpoint,
+ String contentType,
GeneratedObjectMapper generatedObjectMapper,
CodeBlock inlineableHttpUrl,
boolean sendContentType) {
@@ -192,10 +193,7 @@ public CodeBlock getInitializeRequestCodeBlock(
@Override
public Void visitTypeReference(HttpRequestBodyReference typeReference) {
- builder.add(
- ".addHeader($S, $S)\n",
- AbstractEndpointWriter.CONTENT_TYPE_HEADER,
- AbstractEndpointWriter.APPLICATION_JSON_HEADER);
+ builder.add(".addHeader($S, $S)\n", AbstractEndpointWriter.CONTENT_TYPE_HEADER, contentType);
return null;
}
@@ -228,10 +226,7 @@ public Void _visitUnknown(Object unknownType) {
clientOptionsMember.name,
ClientOptionsGenerator.HEADERS_METHOD_NAME,
REQUEST_OPTIONS_PARAMETER_NAME);
- builder.add(
- ".addHeader($S, $S)\n",
- AbstractEndpointWriter.CONTENT_TYPE_HEADER,
- AbstractEndpointWriter.APPLICATION_JSON_HEADER);
+ builder.add(".addHeader($S, $S)\n", AbstractEndpointWriter.CONTENT_TYPE_HEADER, contentType);
return builder.add(".build();\n").unindent().build();
}
}
diff --git a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/WrappedRequestEndpointWriter.java b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/WrappedRequestEndpointWriter.java
index dd44ef002f5..3e49a659f81 100644
--- a/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/WrappedRequestEndpointWriter.java
+++ b/generators/java/sdk/src/main/java/com/fern/java/client/generators/endpoint/WrappedRequestEndpointWriter.java
@@ -18,11 +18,7 @@
import com.fern.ir.model.commons.ErrorId;
import com.fern.ir.model.commons.NameAndWireValue;
-import com.fern.ir.model.http.FileProperty;
-import com.fern.ir.model.http.HttpEndpoint;
-import com.fern.ir.model.http.HttpMethod;
-import com.fern.ir.model.http.HttpService;
-import com.fern.ir.model.http.SdkRequest;
+import com.fern.ir.model.http.*;
import com.fern.java.client.ClientGeneratorContext;
import com.fern.java.client.GeneratedClientOptions;
import com.fern.java.client.GeneratedEnvironmentsClass;
@@ -139,6 +135,7 @@ public CodeBlock getInitializeRequestCodeBlock(
FieldSpec clientOptionsMember,
GeneratedClientOptions clientOptions,
HttpEndpoint _unused,
+ String contentType,
GeneratedObjectMapper generatedObjectMapper,
CodeBlock inlineableHttpUrl,
boolean sendContentType) {
@@ -201,10 +198,7 @@ public CodeBlock getInitializeRequestCodeBlock(
clientOptionsMember.name,
ClientOptionsGenerator.HEADERS_METHOD_NAME,
AbstractEndpointWriter.REQUEST_OPTIONS_PARAMETER_NAME)
- .add(
- ".addHeader($S, $S);\n",
- AbstractEndpointWriter.CONTENT_TYPE_HEADER,
- AbstractEndpointWriter.APPLICATION_JSON_HEADER);
+ .add(".addHeader($S, $S);\n", AbstractEndpointWriter.CONTENT_TYPE_HEADER, contentType);
} else {
requestBodyCodeBlock.add(
".headers($T.of($L.$L($L)));\n",
diff --git a/generators/java/sdk/versions.yml b/generators/java/sdk/versions.yml
index 0c266867c8f..ba31d555203 100644
--- a/generators/java/sdk/versions.yml
+++ b/generators/java/sdk/versions.yml
@@ -1,3 +1,33 @@
+- changelogEntry:
+ - summary: |
+ Apply Content-Type header from endpoint definition in SDK generator.
+ type: feat
+ createdAt: '2024-12-11'
+ irVersion: 53
+ version: 2.7.0
+- changelogEntry:
+ - summary: |
+ Don't generate pagination with nonempty path. Fixes pagination seed tests breaking.
+ type: fix
+ createdAt: '2024-12-10'
+ irVersion: 53
+ version: 2.6.0
+- changelogEntry:
+ - summary: |
+ Bump IR version to latest (v53)
+ type: chore
+ createdAt: '2024-12-10'
+ irVersion: 53
+ version: 2.5.0
+- changelogEntry:
+ - summary: |
+ We now support overriding sdk package prefixes by adding a "package-prefix" key under the java-sdk generator
+ configuration.
+ type: feat
+ createdAt: '2024-12-10'
+ irVersion: 46
+ version: 2.4.0
+
- changelogEntry:
- summary: |
The rootProject.name is now set in settings.gradle and ci.yml uses ./gradlew sonatypeCentralUpload for publishing.
diff --git a/generators/java/spring/src/main/java/com/fern/java/spring/generators/SpringServerInterfaceGenerator.java b/generators/java/spring/src/main/java/com/fern/java/spring/generators/SpringServerInterfaceGenerator.java
index 62dffde3fd6..9bc35e79339 100644
--- a/generators/java/spring/src/main/java/com/fern/java/spring/generators/SpringServerInterfaceGenerator.java
+++ b/generators/java/spring/src/main/java/com/fern/java/spring/generators/SpringServerInterfaceGenerator.java
@@ -17,22 +17,7 @@
import com.fern.ir.model.commons.ErrorId;
import com.fern.ir.model.commons.TypeId;
-import com.fern.ir.model.http.BytesRequest;
-import com.fern.ir.model.http.EndpointName;
-import com.fern.ir.model.http.FileDownloadResponse;
-import com.fern.ir.model.http.FileUploadRequest;
-import com.fern.ir.model.http.HttpEndpoint;
-import com.fern.ir.model.http.HttpRequestBody;
-import com.fern.ir.model.http.HttpRequestBodyReference;
-import com.fern.ir.model.http.HttpResponse;
-import com.fern.ir.model.http.HttpResponseBody;
-import com.fern.ir.model.http.HttpService;
-import com.fern.ir.model.http.InlinedRequestBody;
-import com.fern.ir.model.http.JsonResponse;
-import com.fern.ir.model.http.JsonResponseBody;
-import com.fern.ir.model.http.JsonResponseBodyWithProperty;
-import com.fern.ir.model.http.StreamingResponse;
-import com.fern.ir.model.http.TextResponse;
+import com.fern.ir.model.http.*;
import com.fern.java.generators.AbstractFileGenerator;
import com.fern.java.output.AbstractGeneratedJavaFile;
import com.fern.java.output.GeneratedAuthFiles;
@@ -163,6 +148,12 @@ public Void visitStreaming(StreamingResponse streaming) {
throw new RuntimeException("Streaming responses are not supported in spring server generator");
}
+ @Override
+ public Void visitStreamParameter(StreamParameterResponse streamParameterResponse) {
+ throw new RuntimeException(
+ "Stream parameter responses are not supported in spring server generator");
+ }
+
@Override
public Void _visitUnknown(Object unknownType) {
return null;
diff --git a/generators/java/spring/versions.yml b/generators/java/spring/versions.yml
index 5c58a14148b..30d47a4f0ba 100644
--- a/generators/java/spring/versions.yml
+++ b/generators/java/spring/versions.yml
@@ -1,3 +1,10 @@
+- changelogEntry:
+ - summary: |
+ Bump IR version to latest (v53)
+ type: chore
+ createdAt: '2024-12-10'
+ irVersion: 53
+ version: 1.3.0
- changelogEntry:
- summary: |
Bump Jackson version to latest (2.17.2)
diff --git a/generators/java/versions.lock b/generators/java/versions.lock
index 9d1893f55e2..9bea9e1ca2a 100644
--- a/generators/java/versions.lock
+++ b/generators/java/versions.lock
@@ -5,12 +5,12 @@ com.atlassian.commonmark:commonmark:0.12.1 (1 constraints: 36052a3b)
com.fasterxml.jackson:jackson-bom:2.17.2 (9 constraints: 349e3b26)
com.fasterxml.jackson.core:jackson-annotations:2.17.2 (8 constraints: 2c7787b5)
com.fasterxml.jackson.core:jackson-core:2.17.2 (8 constraints: f0870cf8)
-com.fasterxml.jackson.core:jackson-databind:2.17.2 (12 constraints: ddaf9215)
-com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2 (8 constraints: 0266e1bd)
-com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2 (3 constraints: 8e1c9f5a)
+com.fasterxml.jackson.core:jackson-databind:2.17.2 (12 constraints: dbafcf13)
+com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2 (8 constraints: 006674bc)
+com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2 (3 constraints: 8c1c8a5a)
com.fern.fern:generator-exec-client:0.0.806 (1 constraints: 70059d40)
com.fern.fern:generator-exec-model:0.0.806 (1 constraints: 760ff78e)
-com.fern.fern:irV46:0.0.3517 (1 constraints: a2053546)
+com.fern.fern:irV53:53.23.0 (1 constraints: 6f05cb40)
com.google.code.findbugs:annotations:3.0.1 (5 constraints: 0b486b6a)
com.google.code.findbugs:jsr305:3.0.2 (6 constraints: 3e53d684)
com.google.errorprone:error_prone_annotations:2.12.1 (5 constraints: 7b44cddd)
diff --git a/generators/java/versions.props b/generators/java/versions.props
index 40e15509c8c..07dc34c29b6 100644
--- a/generators/java/versions.props
+++ b/generators/java/versions.props
@@ -8,7 +8,7 @@ org.immutables:* = 2.8.8
org.apache.commons:commons-lang3 = 3.12.0
# fern
-com.fern.fern:irV46 = 0.0.3517
+com.fern.fern:irV53 = 53.23.0
com.fern.fern:generator-exec-client = 0.0.806
# testing
diff --git a/generators/python-v2/ast/src/PythonFile.ts b/generators/python-v2/ast/src/PythonFile.ts
index ddc5ec338cb..558bde6b910 100644
--- a/generators/python-v2/ast/src/PythonFile.ts
+++ b/generators/python-v2/ast/src/PythonFile.ts
@@ -2,8 +2,19 @@ import { AstNode } from "./core/AstNode";
import { Comment } from "./Comment";
import { Writer } from "./core/Writer";
import { Reference } from "./Reference";
-import { ModulePath } from "./core/types";
+import { ImportedName, ModulePath } from "./core/types";
import { StarImport } from "./StarImport";
+import { Class } from "./Class";
+import { Method } from "./Method";
+import { Field } from "./Field";
+import { Type } from "./Type";
+import { createPythonClassName } from "./core/utils";
+
+interface UniqueReferenceValue {
+ modulePath: ModulePath;
+ references: Reference[];
+ referenceNames: Set;
+}
export declare namespace PythonFile {
interface Args {
@@ -44,8 +55,12 @@ export class PythonFile extends AstNode {
}
public write(writer: Writer): void {
+ const uniqueReferences = this.deduplicateReferences();
+
+ this.updateWriterRefNameOverrides({ writer, uniqueReferences });
+
this.writeComments(writer);
- this.writeImports(writer);
+ this.writeImports({ writer, uniqueReferences });
this.statements.forEach((statement, idx) => {
statement.write(writer);
writer.newLine();
@@ -53,38 +68,87 @@ export class PythonFile extends AstNode {
writer.newLine();
}
});
+
+ writer.unsetRefNameOverrides();
}
/*******************************
* Helper Methods
*******************************/
- private writeComments(writer: Writer): void {
- this.comments.forEach((comment) => {
- comment.write(writer);
+ private updateWriterRefNameOverrides({
+ writer,
+ uniqueReferences
+ }: {
+ writer: Writer;
+ uniqueReferences: Map;
+ }): void {
+ const references: Reference[] = Array.from(uniqueReferences.values()).flatMap(({ references }) => references);
+
+ // Build up a map of refs to their name overrides, keeping track of names that have been used as we go.
+ const completeRefPathsToNameOverrides: Record = {};
+ const usedNames = this.getInitialUsedNames();
+
+ references.forEach((reference) => {
+ // Skip star imports since we should never override their import alias
+ if (reference instanceof StarImport) {
+ return;
+ }
+
+ const name = reference.alias ?? reference.name;
+ const fullyQualifiedModulePath = reference.getFullyQualifiedModulePath();
+
+ let nameOverride = name;
+ let modulePathIdx = reference.modulePath.length - 1;
+ let isAlias = !!reference.alias;
+
+ while (usedNames.has(nameOverride)) {
+ isAlias = true;
+
+ const module = reference.modulePath[modulePathIdx];
+ if (modulePathIdx < 0 || !module) {
+ nameOverride = `_${nameOverride}`;
+ } else {
+ nameOverride = `${createPythonClassName(module)}${nameOverride}`;
+ }
+
+ modulePathIdx--;
+ }
+ usedNames.add(nameOverride);
+
+ completeRefPathsToNameOverrides[fullyQualifiedModulePath] = {
+ name: nameOverride,
+ isAlias
+ };
});
- if (this.comments.length > 0) {
- writer.newLine();
- }
+ writer.setRefNameOverrides(completeRefPathsToNameOverrides);
}
- private getImportName(reference: Reference): string {
- const name = reference.name;
- const alias = reference.alias;
- return `${name}${alias ? ` as ${alias}` : ""}`;
+ private getInitialUsedNames(): Set {
+ const usedNames = new Set();
+
+ this.statements.forEach((statement) => {
+ if (statement instanceof Class) {
+ usedNames.add(statement.name);
+ } else if (statement instanceof Method) {
+ usedNames.add(statement.name);
+ } else if (statement instanceof Field) {
+ usedNames.add(statement.name);
+ }
+ });
+
+ return usedNames;
}
- private writeImports(writer: Writer): void {
+ private deduplicateReferences() {
// Deduplicate references by their fully qualified paths
- const uniqueReferences = new Map<
- string,
- { modulePath: ModulePath; references: Reference[]; referenceNames: Set }
- >();
+ const uniqueReferences = new Map();
for (const reference of this.references) {
- const fullyQualifiedPath = reference.getFullyQualifiedModulePath();
- const existingRefs = uniqueReferences.get(fullyQualifiedPath);
const referenceName = reference.name;
+ const fullyQualifiedPath = reference.getFullyQualifiedPath();
+ const existingRefs = uniqueReferences.get(fullyQualifiedPath);
+
if (existingRefs) {
if (!existingRefs.referenceNames.has(referenceName)) {
existingRefs.references.push(reference);
@@ -99,6 +163,35 @@ export class PythonFile extends AstNode {
}
}
+ return uniqueReferences;
+ }
+
+ private writeComments(writer: Writer): void {
+ this.comments.forEach((comment) => {
+ comment.write(writer);
+ });
+
+ if (this.comments.length > 0) {
+ writer.newLine();
+ }
+ }
+
+ private getImportName({ writer, reference }: { writer: Writer; reference: Reference }): string {
+ const nameOverride = writer.getRefNameOverride(reference);
+
+ const name = reference.name;
+ const alias = nameOverride.isAlias ? nameOverride.name : undefined;
+
+ return `${name}${alias ? ` as ${alias}` : ""}`;
+ }
+
+ private writeImports({
+ writer,
+ uniqueReferences
+ }: {
+ writer: Writer;
+ uniqueReferences: Map;
+ }): void {
for (const [fullyQualifiedPath, { modulePath, references }] of uniqueReferences) {
const refModulePath = modulePath;
if (refModulePath[0] === this.path[0]) {
@@ -127,12 +220,16 @@ export class PythonFile extends AstNode {
// Write the relative import statement
writer.write(
- `from ${relativePath} import ${references.map((ref) => this.getImportName(ref)).join(", ")}`
+ `from ${relativePath} import ${references
+ .map((reference) => this.getImportName({ writer, reference }))
+ .join(", ")}`
);
} else {
// Use fully qualified path
writer.write(
- `from ${fullyQualifiedPath} import ${references.map((ref) => this.getImportName(ref)).join(", ")}`
+ `from ${fullyQualifiedPath} import ${references
+ .map((reference) => this.getImportName({ writer, reference }))
+ .join(", ")}`
);
}
diff --git a/generators/python-v2/ast/src/Reference.ts b/generators/python-v2/ast/src/Reference.ts
index c3fed7fd680..26b5d9b4e48 100644
--- a/generators/python-v2/ast/src/Reference.ts
+++ b/generators/python-v2/ast/src/Reference.ts
@@ -43,7 +43,8 @@ export class Reference extends AstNode {
}
public write(writer: Writer): void {
- writer.write(this.alias ?? this.name);
+ const nameOverride = writer.getRefNameOverride(this);
+ writer.write(nameOverride.name);
if (this.genericTypes.length > 0) {
writer.write("[");
@@ -67,7 +68,11 @@ export class Reference extends AstNode {
}
}
- public getFullyQualifiedModulePath(): string {
+ public getFullyQualifiedPath(): string {
return this.modulePath.join(".");
}
+
+ public getFullyQualifiedModulePath(): string {
+ return `${this.getFullyQualifiedPath()}.${this.name}`;
+ }
}
diff --git a/generators/python-v2/ast/src/__test__/PythonFile.test.ts b/generators/python-v2/ast/src/__test__/PythonFile.test.ts
index 75968d22f65..4cfac924fc5 100644
--- a/generators/python-v2/ast/src/__test__/PythonFile.test.ts
+++ b/generators/python-v2/ast/src/__test__/PythonFile.test.ts
@@ -303,7 +303,10 @@ describe("PythonFile", () => {
const file = python.file({
path: ["root"],
comments: [python.comment({ docs: "flake8: noqa: F401, F403" })],
- imports: [python.starImport({ modulePath: ["root", "my_module"] })],
+ imports: [
+ python.starImport({ modulePath: ["root", "my_module_a"] }),
+ python.starImport({ modulePath: ["root", "my_module_b"] })
+ ],
statements: [
python.field({
name: "my_id",
@@ -314,6 +317,72 @@ describe("PythonFile", () => {
file.write(writer);
expect(await writer.toStringFormatted()).toMatchSnapshot();
- expect(file.getReferences()).toHaveLength(2);
+ expect(file.getReferences()).toHaveLength(3);
+ });
+
+ it("Write duplicative import names", async () => {
+ const file = python.file({ path: ["root"] });
+
+ const local_class = python.class_({
+ name: "Car"
+ });
+
+ local_class.add(
+ python.field({
+ name: "car",
+ initializer: python.instantiateClass({
+ classReference: python.reference({
+ modulePath: ["root", "cars"],
+ name: "Car"
+ }),
+ arguments_: []
+ })
+ })
+ );
+
+ local_class.add(
+ python.field({
+ name: "car",
+ initializer: python.instantiateClass({
+ classReference: python.reference({
+ modulePath: ["root", "transportation", "vehicles"],
+ name: "Car"
+ }),
+ arguments_: []
+ })
+ })
+ );
+
+ local_class.add(
+ python.field({
+ name: "automobile",
+ initializer: python.instantiateClass({
+ classReference: python.reference({
+ modulePath: ["root", "automobiles"],
+ name: "Car"
+ }),
+ arguments_: []
+ })
+ })
+ );
+
+ local_class.add(
+ python.field({
+ name: "vehicle",
+ initializer: python.instantiateClass({
+ classReference: python.reference({
+ modulePath: ["root", "vehicles", "automobiles"],
+ name: "Car"
+ }),
+ arguments_: []
+ })
+ })
+ );
+
+ file.addStatement(local_class);
+
+ file.write(writer);
+ expect(await writer.toStringFormatted()).toMatchSnapshot();
+ expect(file.getReferences()).toHaveLength(4);
});
});
diff --git a/generators/python-v2/ast/src/__test__/__snapshots__/PythonFile.test.ts.snap b/generators/python-v2/ast/src/__test__/__snapshots__/PythonFile.test.ts.snap
index 00a3170736e..68b01d373f2 100644
--- a/generators/python-v2/ast/src/__test__/__snapshots__/PythonFile.test.ts.snap
+++ b/generators/python-v2/ast/src/__test__/__snapshots__/PythonFile.test.ts.snap
@@ -112,11 +112,27 @@ my_variable: ImportedClass.nested.attribute
"
`;
+exports[`PythonFile > Write duplicative import names 1`] = `
+"from .cars import Car as CarsCar
+from .transportation.vehicles import Car as VehiclesCar
+from .automobiles import Car as AutomobilesCar
+from .vehicles.automobiles import Car as VehiclesAutomobilesCar
+
+
+class Car:
+ car = CarsCar()
+ car = VehiclesCar()
+ automobile = AutomobilesCar()
+ vehicle = VehiclesAutomobilesCar()
+"
+`;
+
exports[`PythonFile > Write star imports 1`] = `
"# flake8: noqa: F401, F403
from uuid import UUID
-from .my_module import *
+from .my_module_a import *
+from .my_module_b import *
my_id = UUID("1234")
"
diff --git a/generators/python-v2/ast/src/__test__/core/utils.test.ts b/generators/python-v2/ast/src/__test__/core/utils.test.ts
new file mode 100644
index 00000000000..de17c1fbd4c
--- /dev/null
+++ b/generators/python-v2/ast/src/__test__/core/utils.test.ts
@@ -0,0 +1,33 @@
+import { createPythonClassName } from "../../core/utils";
+
+describe("Casing", () => {
+ describe("createPythonClassName", () => {
+ const testCases: [string, string][] = [
+ // Basic cases
+ ["hello world", "HelloWorld"],
+ ["simpleTestCase", "SimpleTestCase"],
+ // Special characters
+ ["hello-world", "HelloWorld"],
+ ["$special#characters%", "SpecialCharacters"],
+ // Numbers
+ ["123 invalid class name", "Class123InvalidClassName"],
+ ["mixed 123 cases", "Mixed123Cases"],
+ // Underscores
+ ["_leading_underscores_", "LeadingUnderscores"],
+ ["trailing_underscores_", "TrailingUnderscores"],
+ ["_123numbers_starting", "Class123NumbersStarting"],
+ // Empty and invalid input
+ ["", "Class"],
+ ["123", "Class123"],
+ ["_123_", "Class123"],
+ // Complex cases
+ ["complex mix_of-DifferentCases", "ComplexMixOfDifferentCases"],
+ ["ALLCAPS input", "ALLCAPSInput"], // Preserve ALLCAPS as requested
+ ["PascalCaseAlready", "PascalCaseAlready"]
+ ];
+
+ it.each<[string, string]>(testCases)("should convert %s' to %s'", (input, expected) => {
+ expect(createPythonClassName(input)).toBe(expected);
+ });
+ });
+});
diff --git a/generators/python-v2/ast/src/core/Writer.ts b/generators/python-v2/ast/src/core/Writer.ts
index 3a937e958b5..1726f404910 100644
--- a/generators/python-v2/ast/src/core/Writer.ts
+++ b/generators/python-v2/ast/src/core/Writer.ts
@@ -1,9 +1,32 @@
import { AbstractWriter } from "@fern-api/base-generator";
import { Config } from "@wasm-fmt/ruff_fmt";
+import { Reference } from "../Reference";
+import { ImportedName } from "./types";
export declare namespace Writer {}
export class Writer extends AbstractWriter {
+ private fullyQualifiedModulePathsToImportedNames: Record = {};
+
+ public setRefNameOverrides(completeRefPathsToNameOverrides: Record): void {
+ this.fullyQualifiedModulePathsToImportedNames = completeRefPathsToNameOverrides;
+ }
+
+ public unsetRefNameOverrides(): void {
+ this.fullyQualifiedModulePathsToImportedNames = {};
+ }
+
+ public getRefNameOverride(reference: Reference): ImportedName {
+ const explicitNameOverride =
+ this.fullyQualifiedModulePathsToImportedNames[reference.getFullyQualifiedModulePath()];
+
+ if (explicitNameOverride) {
+ return explicitNameOverride;
+ }
+
+ return { name: reference.alias ?? reference.name, isAlias: !!reference.alias };
+ }
+
public toString(): string {
return this.buffer;
}
diff --git a/generators/python-v2/ast/src/core/types.ts b/generators/python-v2/ast/src/core/types.ts
index 491f0101733..756acb54ddd 100644
--- a/generators/python-v2/ast/src/core/types.ts
+++ b/generators/python-v2/ast/src/core/types.ts
@@ -1,2 +1,8 @@
export type ModulePath = string[] | Readonly;
+
export type AttrPath = string[] | Readonly;
+
+export interface ImportedName {
+ name: string;
+ isAlias?: boolean;
+}
diff --git a/generators/python-v2/ast/src/core/utils.ts b/generators/python-v2/ast/src/core/utils.ts
new file mode 100644
index 00000000000..6e00d4e593b
--- /dev/null
+++ b/generators/python-v2/ast/src/core/utils.ts
@@ -0,0 +1,48 @@
+export function createPythonClassName(input: string): string {
+ // Handle empty input
+ if (!input) {
+ return "Class";
+ }
+
+ // Clean up the input string
+ let cleanedInput = input
+ .replace(/[^a-zA-Z0-9\s_-]/g, " ") // Replace special characters with spaces
+ .replace(/[-_\s]+/g, " ") // Replace hyphens, underscores and multiple spaces with single space
+ .trim(); // Remove leading/trailing spaces
+
+ // Handle numeric-only or empty string after cleanup
+ if (!cleanedInput || /^\d+$/.test(cleanedInput)) {
+ return "Class" + (cleanedInput || "");
+ }
+
+ // Handle strings starting with numbers
+ if (/^\d/.test(cleanedInput)) {
+ cleanedInput = "Class" + cleanedInput;
+ }
+
+ // Split into words and handle special cases
+ const words = cleanedInput
+ .split(/(?=[A-Z])|[-_\s]+/)
+ .filter((word) => word.length > 0)
+ .map((word) => {
+ // Fix any garbled text by splitting on number boundaries
+ return word.split(/(?<=\d)(?=[a-zA-Z])|(?<=[a-zA-Z])(?=\d)/).filter((w) => w.length > 0);
+ })
+ .flat();
+
+ // Process each word
+ return words
+ .map((word, index) => {
+ // If it's the first word and starts with a number, prepend "Class"
+ if (index === 0 && /^\d/.test(word)) {
+ return "Class" + word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ }
+ // Preserve words that are all uppercase and longer than one character
+ if (word.length > 1 && word === word.toUpperCase() && !/^\d+$/.test(word)) {
+ return word;
+ }
+ // Capitalize first letter, lowercase rest
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ })
+ .join("");
+}
diff --git a/generators/typescript/codegen/package.json b/generators/typescript/codegen/package.json
index 15b70ad5af8..8dc1b2687d7 100644
--- a/generators/typescript/codegen/package.json
+++ b/generators/typescript/codegen/package.json
@@ -28,7 +28,7 @@
"devDependencies": {
"@fern-api/core-utils": "workspace:*",
"@fern-api/base-generator": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@types/jest": "^29.5.12",
"@types/node": "18.7.18",
"depcheck": "^1.4.6",
diff --git a/generators/typescript/express/cli/package.json b/generators/typescript/express/cli/package.json
index 83bd0cde9d4..5a0ebd5b3db 100644
--- a/generators/typescript/express/cli/package.json
+++ b/generators/typescript/express/cli/package.json
@@ -31,7 +31,7 @@
},
"devDependencies": {
"@fern-fern/generator-exec-sdk": "^0.0.898",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-generator-cli": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/express/cli/src/ExpressGeneratorCli.ts b/generators/typescript/express/cli/src/ExpressGeneratorCli.ts
index 35389879eec..315a099a3b1 100644
--- a/generators/typescript/express/cli/src/ExpressGeneratorCli.ts
+++ b/generators/typescript/express/cli/src/ExpressGeneratorCli.ts
@@ -5,7 +5,6 @@ import { NpmPackage, PersistedTypescriptProject } from "@fern-typescript/commons
import { GeneratorContext } from "@fern-typescript/contexts";
import { ExpressGenerator } from "@fern-typescript/express-generator";
import { camelCase, upperFirst } from "lodash-es";
-import { custom } from "zod";
import { ExpressCustomConfig } from "./custom-config/ExpressCustomConfig";
import { ExpressCustomConfigSchema } from "./custom-config/schema/ExpressCustomConfigSchema";
@@ -13,6 +12,7 @@ export class ExpressGeneratorCli extends AbstractGeneratorCli {
+ return this.intermediateRepresentation.types;
+ }
+
private generateTypeDeclarations() {
- for (const typeDeclaration of Object.values(this.intermediateRepresentation.types)) {
+ for (const typeDeclaration of Object.values(this.getTypesToGenerate())) {
this.withSourceFile({
filepath: this.typeDeclarationReferencer.getExportedFilepath(typeDeclaration.name),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.type.getGeneratedType(typeDeclaration.name).writeToFile(context);
}
});
@@ -289,11 +299,15 @@ export class ExpressGenerator {
}
private generateTypeSchemas() {
- for (const typeDeclaration of Object.values(this.intermediateRepresentation.types)) {
+ for (const typeDeclaration of Object.values(this.getTypesToGenerate())) {
this.withSourceFile({
filepath: this.typeSchemaDeclarationReferencer.getExportedFilepath(typeDeclaration.name),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.typeSchema.getGeneratedTypeSchema(typeDeclaration.name).writeToFile(context);
}
});
@@ -305,7 +319,11 @@ export class ExpressGenerator {
this.withSourceFile({
filepath: this.expressErrorDeclarationReferencer.getExportedFilepath(errorDeclaration.name),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressError.getGeneratedExpressError(errorDeclaration.name).writeToFile(context);
}
});
@@ -317,7 +335,11 @@ export class ExpressGenerator {
this.withSourceFile({
filepath: this.expressErrorSchemaDeclarationReferencer.getExportedFilepath(errorDeclaration.name),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressErrorSchema
.getGeneratedExpressErrorSchema(errorDeclaration.name)
?.writeToFile(context);
@@ -336,7 +358,11 @@ export class ExpressGenerator {
endpoint
}),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressInlinedRequestBody
.getGeneratedInlinedRequestBody(packageId, endpoint.name)
.writeToFile(context);
@@ -357,7 +383,11 @@ export class ExpressGenerator {
endpoint
}),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressInlinedRequestBodySchema
.getGeneratedInlinedRequestBodySchema(packageId, endpoint.name)
.writeToFile(context);
@@ -377,7 +407,11 @@ export class ExpressGenerator {
endpoint
}),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressEndpointTypeSchemas
.getGeneratedEndpointTypeSchemas(packageId, endpoint.name)
.writeToFile(context);
@@ -392,7 +426,11 @@ export class ExpressGenerator {
this.withSourceFile({
filepath: this.expressServiceDeclarationReferencer.getExportedFilepath(packageId),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressService.getGeneratedExpressService(packageId).writeToFile(context);
}
});
@@ -403,7 +441,11 @@ export class ExpressGenerator {
this.withSourceFile({
filepath: this.expressRegisterDeclarationReferencer.getExportedFilepath(),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.expressRegister.getGeneratedExpressRegister()?.writeToFile(context);
}
});
@@ -413,7 +455,11 @@ export class ExpressGenerator {
this.withSourceFile({
filepath: this.genericApiExpressErrorDeclarationReferencer.getExportedFilepath(),
run: ({ sourceFile, importsManager }) => {
- const context = this.generateExpressContext({ sourceFile, importsManager });
+ const context = this.generateExpressContext({
+ logger: this.context.logger,
+ sourceFile,
+ importsManager
+ });
context.genericAPIExpressError.getGeneratedGenericAPIExpressError().writeToFile(context);
}
});
@@ -470,13 +516,16 @@ export class ExpressGenerator {
}
private generateExpressContext({
+ logger,
sourceFile,
importsManager
}: {
+ logger: Logger;
sourceFile: SourceFile;
importsManager: ImportsManager;
}): ExpressContextImpl {
return new ExpressContextImpl({
+ logger,
sourceFile,
coreUtilitiesManager: this.coreUtilitiesManager,
dependencyManager: this.dependencyManager,
@@ -509,7 +558,8 @@ export class ExpressGenerator {
expressErrorSchemaGenerator: this.expressErrorSchemaGenerator,
includeSerdeLayer: this.config.includeSerdeLayer,
retainOriginalCasing: this.config.retainOriginalCasing,
- useBigInt: this.config.useBigInt
+ useBigInt: this.config.useBigInt,
+ enableInlineTypes: false
});
}
}
diff --git a/generators/typescript/express/generator/src/contexts/ExpressContextImpl.ts b/generators/typescript/express/generator/src/contexts/ExpressContextImpl.ts
index 8e1513d8dcb..e3a21c2957d 100644
--- a/generators/typescript/express/generator/src/contexts/ExpressContextImpl.ts
+++ b/generators/typescript/express/generator/src/contexts/ExpressContextImpl.ts
@@ -26,6 +26,7 @@ import { TypeGenerator } from "@fern-typescript/type-generator";
import { TypeReferenceExampleGenerator } from "@fern-typescript/type-reference-example-generator";
import { TypeSchemaGenerator } from "@fern-typescript/type-schema-generator";
import { SourceFile } from "ts-morph";
+import { Logger } from "@fern-api/logger";
import { EndpointDeclarationReferencer } from "../declaration-referencers/EndpointDeclarationReferencer";
import { ExpressErrorDeclarationReferencer } from "../declaration-referencers/ExpressErrorDeclarationReferencer";
import { ExpressInlinedRequestBodyDeclarationReferencer } from "../declaration-referencers/ExpressInlinedRequestBodyDeclarationReferencer";
@@ -45,6 +46,7 @@ import { TypeContextImpl } from "./type/TypeContextImpl";
export declare namespace ExpressContextImpl {
export interface Init {
+ logger: Logger;
sourceFile: SourceFile;
importsManager: ImportsManager;
dependencyManager: DependencyManager;
@@ -78,10 +80,12 @@ export declare namespace ExpressContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
useBigInt: boolean;
+ enableInlineTypes: boolean;
}
}
export class ExpressContextImpl implements ExpressContext {
+ public readonly logger: Logger;
public readonly sourceFile: SourceFile;
public readonly externalDependencies: ExternalDependencies;
public readonly coreUtilities: CoreUtilities;
@@ -101,6 +105,7 @@ export class ExpressContextImpl implements ExpressContext {
public readonly expressErrorSchema: ExpressErrorSchemaContext;
constructor({
+ logger,
typeResolver,
typeGenerator,
typeDeclarationReferencer,
@@ -132,8 +137,10 @@ export class ExpressContextImpl implements ExpressContext {
expressErrorSchemaGenerator,
includeSerdeLayer,
retainOriginalCasing,
+ enableInlineTypes,
useBigInt
}: ExpressContextImpl.Init) {
+ this.logger = logger;
this.includeSerdeLayer = includeSerdeLayer;
this.sourceFile = sourceFile;
this.externalDependencies = createExternalDependencies({
@@ -156,7 +163,9 @@ export class ExpressContextImpl implements ExpressContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes,
+ context: this
});
this.typeSchema = new TypeSchemaContextImpl({
sourceFile,
@@ -170,7 +179,8 @@ export class ExpressContextImpl implements ExpressContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.expressInlinedRequestBody = new ExpressInlinedRequestBodyContextImpl({
diff --git a/generators/typescript/express/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts b/generators/typescript/express/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
index e79c44acd7e..817c3595b76 100644
--- a/generators/typescript/express/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
+++ b/generators/typescript/express/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
@@ -9,7 +9,7 @@ import {
TypeReferenceToSchemaConverter
} from "@fern-typescript/type-reference-converters";
import { TypeSchemaGenerator } from "@fern-typescript/type-schema-generator";
-import { SourceFile } from "ts-morph";
+import { SourceFile, ts } from "ts-morph";
import { TypeDeclarationReferencer } from "../../declaration-referencers/TypeDeclarationReferencer";
import { getSchemaImportStrategy } from "../getSchemaImportStrategy";
@@ -27,6 +27,7 @@ export declare namespace TypeSchemaContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
useBigInt: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -56,17 +57,20 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes
}: TypeSchemaContextImpl.Init) {
this.sourceFile = sourceFile;
this.coreUtilities = coreUtilities;
this.importsManager = importsManager;
this.typeReferenceToRawTypeNodeConverter = new TypeReferenceToRawTypeNodeConverter({
getReferenceToNamedType: (typeName) => this.getReferenceToRawNamedType(typeName).getEntityName(),
+ generateForInlineUnion: (typeName) => this.generateForInlineUnion(typeName),
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeReferenceToSchemaConverter = new TypeReferenceToSchemaConverter({
getSchemaOfNamedType: (typeName) => this.getSchemaOfNamedType(typeName, { isGeneratingSchema: true }),
@@ -74,7 +78,8 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeDeclarationReferencer = typeDeclarationReferencer;
this.typeSchemaDeclarationReferencer = typeSchemaDeclarationReferencer;
@@ -104,7 +109,8 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
typeName: this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
getReferenceToSelf: (context) => context.type.getReferenceToNamedType(typeName),
includeSerdeLayer: this.includeSerdeLayer,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ inline: typeDeclaration.inline ?? false
}),
getReferenceToGeneratedType: () =>
this.typeDeclarationReferencer
@@ -129,7 +135,7 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
}
public getReferenceToRawType(typeReference: TypeReference): TypeReferenceNode {
- return this.typeReferenceToRawTypeNodeConverter.convert(typeReference);
+ return this.typeReferenceToRawTypeNodeConverter.convert({ typeReference });
}
public getReferenceToRawNamedType(typeName: DeclaredTypeName): Reference {
@@ -146,8 +152,12 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
});
}
+ private generateForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode {
+ throw new Error("Inline unions are not supported in Express Schemas");
+ }
+
public getSchemaOfTypeReference(typeReference: TypeReference): Zurg.Schema {
- return this.typeReferenceToSchemaConverter.convert(typeReference);
+ return this.typeReferenceToSchemaConverter.convert({ typeReference });
}
public getSchemaOfNamedType(
diff --git a/generators/typescript/express/generator/src/contexts/type/TypeContextImpl.ts b/generators/typescript/express/generator/src/contexts/type/TypeContextImpl.ts
index 00f71925f04..e2b627d0ec1 100644
--- a/generators/typescript/express/generator/src/contexts/type/TypeContextImpl.ts
+++ b/generators/typescript/express/generator/src/contexts/type/TypeContextImpl.ts
@@ -1,12 +1,13 @@
import {
DeclaredTypeName,
ExampleTypeReference,
+ ObjectProperty,
ResolvedTypeReference,
TypeDeclaration,
TypeReference
} from "@fern-fern/ir-sdk/api";
import { ImportsManager, Reference, TypeReferenceNode } from "@fern-typescript/commons";
-import { GeneratedType, GeneratedTypeReferenceExample, TypeContext } from "@fern-typescript/contexts";
+import { BaseContext, GeneratedType, GeneratedTypeReferenceExample, TypeContext } from "@fern-typescript/contexts";
import { TypeResolver } from "@fern-typescript/resolvers";
import { TypeGenerator } from "@fern-typescript/type-generator";
import {
@@ -29,6 +30,8 @@ export declare namespace TypeContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
useBigInt: boolean;
+ context: BaseContext;
+ enableInlineTypes: boolean;
}
}
@@ -43,6 +46,7 @@ export class TypeContextImpl implements TypeContext {
private typeReferenceExampleGenerator: TypeReferenceExampleGenerator;
private includeSerdeLayer: boolean;
private retainOriginalCasing: boolean;
+ private context: BaseContext;
constructor({
sourceFile,
@@ -54,7 +58,9 @@ export class TypeContextImpl implements TypeContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes,
+ context
}: TypeContextImpl.Init) {
this.sourceFile = sourceFile;
this.importsManager = importsManager;
@@ -64,24 +70,61 @@ export class TypeContextImpl implements TypeContext {
this.typeReferenceExampleGenerator = typeReferenceExampleGenerator;
this.includeSerdeLayer = includeSerdeLayer;
this.retainOriginalCasing = retainOriginalCasing;
+ this.context = context;
this.typeReferenceToParsedTypeNodeConverter = new TypeReferenceToParsedTypeNodeConverter({
getReferenceToNamedType: (typeName) => this.getReferenceToNamedType(typeName).getEntityName(),
+ generateForInlineUnion: (typeName) => this.generateForInlineUnion(typeName),
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeReferenceToStringExpressionConverter = new TypeReferenceToStringExpressionConverter({
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
}
public getReferenceToType(typeReference: TypeReference): TypeReferenceNode {
- return this.typeReferenceToParsedTypeNodeConverter.convert(typeReference);
+ return this.typeReferenceToParsedTypeNodeConverter.convert({ typeReference });
+ }
+
+ public getReferenceToInlinePropertyType(
+ typeReference: TypeReference,
+ parentTypeName: string,
+ propertyName: string
+ ): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "inlinePropertyParams",
+ parentTypeName,
+ propertyName
+ });
+ }
+
+ public getReferenceToInlineAliasType(typeReference: TypeReference, aliasTypeName: string): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "inlineAliasParams",
+ aliasTypeName
+ });
+ }
+
+ public generateForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode {
+ const generatedType = this.getGeneratedType(typeName);
+ return generatedType.generateForInlineUnion(this.context);
+ }
+
+ public getReferenceToTypeForInlineUnion(typeReference: TypeReference): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "forInlineUnionParams"
+ });
}
public getTypeDeclaration(typeName: DeclaredTypeName): TypeDeclaration {
@@ -110,7 +153,7 @@ export class TypeContextImpl implements TypeContext {
return this.getGeneratedType(typeDeclaration.name);
}
- public getGeneratedType(typeName: DeclaredTypeName): GeneratedType {
+ public getGeneratedType(typeName: DeclaredTypeName, typeNameOverride?: string): GeneratedType {
const typeDeclaration = this.typeResolver.getTypeDeclarationFromName(typeName);
const examples = typeDeclaration.userProvidedExamples;
if (examples.length === 0) {
@@ -120,12 +163,13 @@ export class TypeContextImpl implements TypeContext {
return this.typeGenerator.generateType({
shape: typeDeclaration.shape,
docs: typeDeclaration.docs ?? undefined,
- typeName: this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
+ typeName: typeNameOverride ?? this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
examples,
fernFilepath: typeDeclaration.name.fernFilepath,
getReferenceToSelf: (context) => context.type.getReferenceToNamedType(typeName),
includeSerdeLayer: this.includeSerdeLayer,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ inline: typeDeclaration.inline ?? false
});
}
@@ -135,11 +179,13 @@ export class TypeContextImpl implements TypeContext {
{ includeNullCheckIfOptional }: { includeNullCheckIfOptional: boolean }
): ts.Expression {
if (includeNullCheckIfOptional) {
- return this.typeReferenceToStringExpressionConverter.convertWithNullCheckIfOptional(valueType)(
- valueToStringify
- );
+ return this.typeReferenceToStringExpressionConverter.convertWithNullCheckIfOptional({
+ typeReference: valueType
+ })(valueToStringify);
} else {
- return this.typeReferenceToStringExpressionConverter.convert(valueType)(valueToStringify);
+ return this.typeReferenceToStringExpressionConverter.convert({
+ typeReference: valueType
+ })(valueToStringify);
}
}
diff --git a/generators/typescript/model/type-generator/package.json b/generators/typescript/model/type-generator/package.json
index afa139c4c1a..c7b904b8884 100644
--- a/generators/typescript/model/type-generator/package.json
+++ b/generators/typescript/model/type-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"@fern-typescript/union-generator": "workspace:*",
diff --git a/generators/typescript/model/type-generator/src/AbstractGeneratedType.ts b/generators/typescript/model/type-generator/src/AbstractGeneratedType.ts
index a3050ec5a2c..8529b489ae5 100644
--- a/generators/typescript/model/type-generator/src/AbstractGeneratedType.ts
+++ b/generators/typescript/model/type-generator/src/AbstractGeneratedType.ts
@@ -1,7 +1,7 @@
import { ExampleType, ExampleTypeShape, FernFilepath } from "@fern-fern/ir-sdk/api";
import { GetReferenceOpts, getTextOfTsNode, Reference } from "@fern-typescript/commons";
-import { BaseGeneratedType } from "@fern-typescript/contexts";
-import { ts } from "ts-morph";
+import { BaseContext, BaseGeneratedType } from "@fern-typescript/contexts";
+import { ModuleDeclarationStructure, StatementStructures, ts, WriterFunction } from "ts-morph";
export declare namespace AbstractGeneratedType {
export interface Init {
@@ -14,12 +14,14 @@ export declare namespace AbstractGeneratedType {
includeSerdeLayer: boolean;
noOptionalProperties: boolean;
retainOriginalCasing: boolean;
+ /** Whether inline types should be inlined */
+ enableInlineTypes: boolean;
}
}
const EXAMPLE_PREFIX = " ";
-export abstract class AbstractGeneratedType implements BaseGeneratedType {
+export abstract class AbstractGeneratedType implements BaseGeneratedType {
protected typeName: string;
protected shape: Shape;
protected examples: ExampleType[];
@@ -28,6 +30,7 @@ export abstract class AbstractGeneratedType implements BaseGener
protected includeSerdeLayer: boolean;
protected noOptionalProperties: boolean;
protected retainOriginalCasing: boolean;
+ protected enableInlineTypes: boolean;
private docs: string | undefined;
@@ -40,7 +43,8 @@ export abstract class AbstractGeneratedType implements BaseGener
fernFilepath,
includeSerdeLayer,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}: AbstractGeneratedType.Init) {
this.typeName = typeName;
this.shape = shape;
@@ -51,6 +55,7 @@ export abstract class AbstractGeneratedType implements BaseGener
this.includeSerdeLayer = includeSerdeLayer;
this.noOptionalProperties = noOptionalProperties;
this.retainOriginalCasing = retainOriginalCasing;
+ this.enableInlineTypes = enableInlineTypes;
}
protected getDocs(context: Context): string | undefined {
@@ -72,6 +77,14 @@ export abstract class AbstractGeneratedType implements BaseGener
return groups.join("\n\n");
}
- public abstract writeToFile(context: Context): void;
+ public writeToFile(context: Context): void {
+ context.sourceFile.addStatements(this.generateStatements(context));
+ }
+
+ public abstract generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[];
+ public abstract generateForInlineUnion(context: Context): ts.TypeNode;
+ public abstract generateModule(context: Context): ModuleDeclarationStructure | undefined;
public abstract buildExample(example: ExampleTypeShape, context: Context, opts: GetReferenceOpts): ts.Expression;
}
diff --git a/generators/typescript/model/type-generator/src/TypeGenerator.ts b/generators/typescript/model/type-generator/src/TypeGenerator.ts
index 2c18dac5794..82791705f42 100644
--- a/generators/typescript/model/type-generator/src/TypeGenerator.ts
+++ b/generators/typescript/model/type-generator/src/TypeGenerator.ts
@@ -17,7 +17,7 @@ import {
GeneratedType,
GeneratedUndiscriminatedUnionType,
GeneratedUnionType,
- ModelContext
+ BaseContext
} from "@fern-typescript/contexts";
import { GeneratedAliasTypeImpl } from "./alias/GeneratedAliasTypeImpl";
import { GeneratedBrandedStringAliasImpl } from "./alias/GeneratedBrandedStringAliasImpl";
@@ -34,6 +34,7 @@ export declare namespace TypeGenerator {
includeSerdeLayer: boolean;
noOptionalProperties: boolean;
retainOriginalCasing: boolean;
+ enableInlineTypes: boolean;
}
export namespace generateType {
@@ -46,17 +47,19 @@ export declare namespace TypeGenerator {
getReferenceToSelf: (context: Context) => Reference;
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
+ inline: boolean;
}
}
}
-export class TypeGenerator {
+export class TypeGenerator {
private useBrandedStringAliases: boolean;
private includeUtilsOnUnionMembers: boolean;
private includeOtherInUnionTypes: boolean;
private includeSerdeLayer: boolean;
private noOptionalProperties: boolean;
private retainOriginalCasing: boolean;
+ private enableInlineTypes: boolean;
constructor({
useBrandedStringAliases,
@@ -64,7 +67,8 @@ export class TypeGenerator {
includeOtherInUnionTypes,
includeSerdeLayer,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}: TypeGenerator.Init) {
this.useBrandedStringAliases = useBrandedStringAliases;
this.includeUtilsOnUnionMembers = includeUtilsOnUnionMembers;
@@ -72,6 +76,7 @@ export class TypeGenerator {
this.includeSerdeLayer = includeSerdeLayer;
this.noOptionalProperties = noOptionalProperties;
this.retainOriginalCasing = retainOriginalCasing;
+ this.enableInlineTypes = enableInlineTypes;
}
public generateType({
@@ -80,10 +85,12 @@ export class TypeGenerator {
typeName,
docs,
fernFilepath,
- getReferenceToSelf
+ getReferenceToSelf,
+ inline
}: TypeGenerator.generateType.Args): GeneratedType {
return Type._visit>(shape, {
- union: (shape) => this.generateUnion({ typeName, shape, examples, docs, fernFilepath, getReferenceToSelf }),
+ union: (shape) =>
+ this.generateUnion({ typeName, shape, examples, docs, fernFilepath, getReferenceToSelf, inline }),
undiscriminatedUnion: (shape) =>
this.generateUndiscriminatedUnion({
typeName,
@@ -135,7 +142,8 @@ export class TypeGenerator {
getReferenceToSelf,
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes
});
}
@@ -145,7 +153,8 @@ export class TypeGenerator {
examples,
docs,
fernFilepath,
- getReferenceToSelf
+ getReferenceToSelf,
+ inline
}: {
typeName: string;
shape: UnionTypeDeclaration;
@@ -153,6 +162,7 @@ export class TypeGenerator {
docs: string | undefined;
fernFilepath: FernFilepath;
getReferenceToSelf: (context: Context) => Reference;
+ inline: boolean;
}): GeneratedUnionType {
return new GeneratedUnionTypeImpl({
typeName,
@@ -165,7 +175,9 @@ export class TypeGenerator {
includeOtherInUnionTypes: this.includeOtherInUnionTypes,
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes,
+ inline
});
}
@@ -193,7 +205,8 @@ export class TypeGenerator {
getReferenceToSelf,
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes
});
}
@@ -222,7 +235,8 @@ export class TypeGenerator {
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
includeEnumUtils: this.includeUtilsOnUnionMembers,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes
});
}
@@ -251,7 +265,8 @@ export class TypeGenerator {
getReferenceToSelf,
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes
})
: new GeneratedAliasTypeImpl({
typeName,
@@ -262,7 +277,8 @@ export class TypeGenerator {
getReferenceToSelf,
includeSerdeLayer: this.includeSerdeLayer,
noOptionalProperties: this.noOptionalProperties,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ enableInlineTypes: this.enableInlineTypes
});
}
}
diff --git a/generators/typescript/model/type-generator/src/alias/GeneratedAliasTypeImpl.ts b/generators/typescript/model/type-generator/src/alias/GeneratedAliasTypeImpl.ts
index 487ed372ddd..873abd928e3 100644
--- a/generators/typescript/model/type-generator/src/alias/GeneratedAliasTypeImpl.ts
+++ b/generators/typescript/model/type-generator/src/alias/GeneratedAliasTypeImpl.ts
@@ -1,33 +1,72 @@
import { ExampleTypeShape, TypeReference } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts, getTextOfTsNode, maybeAddDocs } from "@fern-typescript/commons";
-import { ModelContext, NotBrandedGeneratedAliasType } from "@fern-typescript/contexts";
-import { ts } from "ts-morph";
+import {
+ generateInlineAliasModule,
+ GetReferenceOpts,
+ getTextOfTsNode,
+ maybeAddDocsStructure
+} from "@fern-typescript/commons";
+import { BaseContext, NotBrandedGeneratedAliasType } from "@fern-typescript/contexts";
+import {
+ ModuleDeclarationStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ TypeAliasDeclarationStructure,
+ WriterFunction
+} from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
-export class GeneratedAliasTypeImpl
+export class GeneratedAliasTypeImpl
extends AbstractGeneratedType
implements NotBrandedGeneratedAliasType
{
public readonly type = "alias";
public readonly isBranded = false;
- public writeToFile(context: Context): void {
- this.writeTypeAlias(context);
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const statements: StatementStructures[] = [this.generateTypeAlias(context)];
+ const module = this.generateModule(context);
+ if (module) {
+ statements.push(module);
+ }
+ return statements;
}
- public buildExample(example: ExampleTypeShape, context: Context, opts: GetReferenceOpts): ts.Expression {
- if (example.type !== "alias") {
- throw new Error("Example is not for an alias");
- }
- return context.type.getGeneratedExample(example.value).build(context, opts);
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return context.type.getReferenceToType(this.shape).typeNode;
}
- private writeTypeAlias(context: Context) {
- const typeAlias = context.sourceFile.addTypeAlias({
+ private generateTypeAlias(context: Context): TypeAliasDeclarationStructure {
+ const typeAlias: TypeAliasDeclarationStructure = {
+ kind: StructureKind.TypeAlias,
name: this.typeName,
- type: getTextOfTsNode(context.type.getReferenceToType(this.shape).typeNode),
+ type: getTextOfTsNode(context.type.getReferenceToInlineAliasType(this.shape, this.typeName).typeNode),
isExported: true
+ };
+ maybeAddDocsStructure(typeAlias, this.getDocs(context));
+ return typeAlias;
+ }
+
+ public generateModule(context: Context): ModuleDeclarationStructure | undefined {
+ if (!this.enableInlineTypes) {
+ return undefined;
+ }
+
+ return generateInlineAliasModule({
+ aliasTypeName: this.typeName,
+ typeReference: this.shape,
+ generateStatements: (typeName, typeNameOverride) =>
+ context.type.getGeneratedType(typeName, typeNameOverride).generateStatements(context),
+ getTypeDeclaration: (namedType) => context.type.getTypeDeclaration(namedType)
});
- maybeAddDocs(typeAlias, this.getDocs(context));
+ }
+
+ public buildExample(example: ExampleTypeShape, context: Context, opts: GetReferenceOpts): ts.Expression {
+ if (example.type !== "alias") {
+ throw new Error("Example is not for an alias");
+ }
+ return context.type.getGeneratedExample(example.value).build(context, opts);
}
}
diff --git a/generators/typescript/model/type-generator/src/alias/GeneratedBrandedStringAliasImpl.ts b/generators/typescript/model/type-generator/src/alias/GeneratedBrandedStringAliasImpl.ts
index 895b95f3991..e700272c7aa 100644
--- a/generators/typescript/model/type-generator/src/alias/GeneratedBrandedStringAliasImpl.ts
+++ b/generators/typescript/model/type-generator/src/alias/GeneratedBrandedStringAliasImpl.ts
@@ -1,19 +1,44 @@
import { ExampleTypeShape, TypeReference } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts, getTextOfTsKeyword, getTextOfTsNode, maybeAddDocs } from "@fern-typescript/commons";
-import { BrandedGeneratedAliasType, ModelContext } from "@fern-typescript/contexts";
-import { ts } from "ts-morph";
+import {
+ GetReferenceOpts,
+ getTextOfTsKeyword,
+ getTextOfTsNode,
+ maybeAddDocsNode,
+ maybeAddDocsStructure,
+ writerToString
+} from "@fern-typescript/commons";
+import { BrandedGeneratedAliasType, BaseContext } from "@fern-typescript/contexts";
+import {
+ FunctionDeclarationStructure,
+ ModuleDeclarationStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ TypeAliasDeclarationStructure,
+ WriterFunction
+} from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
-export class GeneratedBrandedStringAliasImpl
+export class GeneratedBrandedStringAliasImpl
extends AbstractGeneratedType
implements BrandedGeneratedAliasType
{
public readonly type = "alias";
public readonly isBranded = true;
- public writeToFile(context: Context): void {
- this.writeTypeAlias(context);
- this.writeBuilder(context);
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ return [this.generateTypeAliasStructure(context), this.generateBuilderFunction(context)];
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ const type = writerToString(this.generateTypeAliasStructure(context).type);
+ return ts.factory.createTypeReferenceNode(type);
+ }
+
+ public generateModule(): ModuleDeclarationStructure | undefined {
+ return undefined;
}
public getReferenceToCreator(context: Context, opts?: GetReferenceOpts): ts.Expression {
@@ -29,10 +54,11 @@ export class GeneratedBrandedStringAliasImpl
]);
}
- private writeTypeAlias(context: Context) {
+ private generateTypeAliasStructure(context: Context): TypeAliasDeclarationStructure {
const referenceToAliasedType = context.type.getReferenceToType(this.shape).typeNode;
- const typeAlias = context.sourceFile.addTypeAlias({
+ const typeAlias: TypeAliasDeclarationStructure = {
name: this.typeName,
+ kind: StructureKind.TypeAlias,
type: getTextOfTsNode(
ts.factory.createIntersectionTypeNode([
referenceToAliasedType,
@@ -47,13 +73,15 @@ export class GeneratedBrandedStringAliasImpl
])
),
isExported: true
- });
- maybeAddDocs(typeAlias, this.getDocs(context));
+ };
+ maybeAddDocsStructure(typeAlias, this.getDocs(context));
+ return typeAlias;
}
- private writeBuilder(context: Context) {
+ private generateBuilderFunction(context: Context): FunctionDeclarationStructure {
const VALUE_PARAMETER_NAME = "value";
- context.sourceFile.addFunction({
+ const builderFunction: FunctionDeclarationStructure = {
+ kind: StructureKind.Function,
name: this.typeName,
parameters: [
{
@@ -76,7 +104,8 @@ export class GeneratedBrandedStringAliasImpl
)
],
isExported: true
- });
+ };
+ return builderFunction;
}
private getStringBrand(): string {
diff --git a/generators/typescript/model/type-generator/src/enum/GeneratedEnumTypeImpl.ts b/generators/typescript/model/type-generator/src/enum/GeneratedEnumTypeImpl.ts
index 4405053cb5b..e5dda9347b3 100644
--- a/generators/typescript/model/type-generator/src/enum/GeneratedEnumTypeImpl.ts
+++ b/generators/typescript/model/type-generator/src/enum/GeneratedEnumTypeImpl.ts
@@ -3,10 +3,23 @@ import {
GetReferenceOpts,
getTextOfTsNode,
getWriterForMultiLineUnionType,
- maybeAddDocs
+ maybeAddDocsNode,
+ maybeAddDocsStructure
} from "@fern-typescript/commons";
import { BaseContext, GeneratedEnumType } from "@fern-typescript/contexts";
-import { OptionalKind, PropertySignatureStructure, ts, VariableDeclarationKind } from "ts-morph";
+import {
+ ModuleDeclarationStructure,
+ OptionalKind,
+ PropertySignatureStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ TypeAliasDeclarationStructure,
+ VariableDeclarationKind,
+ VariableStatementStructure,
+ WriterFunction,
+ WriterFunctionOrValue
+} from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
export declare namespace GeneratedEnumTypeImpl {
@@ -34,28 +47,48 @@ export class GeneratedEnumTypeImpl
this.includeEnumUtils = includeEnumUtils;
}
- public writeToFile(context: Context): void {
- const type = context.sourceFile.addTypeAlias({
+ private generateEnumType(context: Context): TypeAliasDeclarationStructure {
+ const type: TypeAliasDeclarationStructure = {
+ kind: StructureKind.TypeAlias,
name: this.typeName,
isExported: true,
type: getWriterForMultiLineUnionType(
this.shape.values.map((value) => ({
docs: value.docs,
- node: ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value.name.wireValue))
+ node: ts.factory.createStringLiteral(value.name.wireValue)
}))
)
- });
+ };
+
+ maybeAddDocsStructure(type, this.getDocs(context));
+ return type;
+ }
- maybeAddDocs(type, this.getDocs(context));
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return ts.factory.createParenthesizedType(
+ ts.factory.createUnionTypeNode(
+ this.shape.values.map((value) =>
+ ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value.name.wireValue))
+ )
+ )
+ );
+ }
- this.addConst(context);
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const statements: (string | WriterFunction | StatementStructures)[] = [
+ this.generateEnumType(context),
+ this.generateConst(context)
+ ];
if (this.includeEnumUtils) {
- this.addModule(context);
+ statements.push(this.generateModule());
}
+ return statements;
}
- private addConst(context: Context) {
+ private generateConst(context: Context): VariableStatementStructure {
const constProperties = this.shape.values.map((value) =>
ts.factory.createPropertyAssignment(
ts.factory.createIdentifier(this.getEnumValueName(value)),
@@ -160,7 +193,8 @@ export class GeneratedEnumTypeImpl
);
}
- context.sourceFile.addVariableStatement({
+ return {
+ kind: StructureKind.VariableStatement,
declarationKind: VariableDeclarationKind.Const,
isExported: true,
declarations: [
@@ -174,50 +208,55 @@ export class GeneratedEnumTypeImpl
)
}
]
- });
+ };
}
- private addModule(context: Context) {
- const enumModule = context.sourceFile.addModule({
+ public generateModule(): ModuleDeclarationStructure {
+ const enumModule: ModuleDeclarationStructure = {
+ kind: StructureKind.Module,
name: this.typeName,
isExported: true,
- hasDeclareKeyword: true
- });
-
- enumModule.addInterface({
- name: GeneratedEnumTypeImpl.VISITOR_INTERFACE_NAME,
- typeParameters: [GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER],
- properties: [
- ...this.shape.values.map(
- (enumValue): OptionalKind => ({
- name: this.getEnumValueVisitPropertyName(enumValue),
- type: getTextOfTsNode(
- ts.factory.createFunctionTypeNode(
- undefined,
- [],
- ts.factory.createTypeReferenceNode(
- GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER,
- undefined
- )
- )
- )
- })
- ),
+ hasDeclareKeyword: false,
+ statements: [
{
- name: GeneratedEnumTypeImpl.OTHER_VISITOR_METHOD_NAME,
- type: getTextOfTsNode(
- ts.factory.createFunctionTypeNode(
- undefined,
- [],
- ts.factory.createTypeReferenceNode(
- GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER,
- undefined
+ kind: StructureKind.Interface,
+ name: GeneratedEnumTypeImpl.VISITOR_INTERFACE_NAME,
+ typeParameters: [GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER],
+ properties: [
+ ...this.shape.values.map(
+ (enumValue): OptionalKind => ({
+ name: this.getEnumValueVisitPropertyName(enumValue),
+ type: getTextOfTsNode(
+ ts.factory.createFunctionTypeNode(
+ undefined,
+ [],
+ ts.factory.createTypeReferenceNode(
+ GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER,
+ undefined
+ )
+ )
+ )
+ })
+ ),
+ {
+ name: GeneratedEnumTypeImpl.OTHER_VISITOR_METHOD_NAME,
+ type: getTextOfTsNode(
+ ts.factory.createFunctionTypeNode(
+ undefined,
+ [],
+ ts.factory.createTypeReferenceNode(
+ GeneratedEnumTypeImpl.VISITOR_RETURN_TYPE_PARAMETER,
+ undefined
+ )
+ )
)
- )
- )
+ }
+ ]
}
]
- });
+ };
+
+ return enumModule;
}
public buildExample(example: ExampleTypeShape, context: Context, opts: GetReferenceOpts): ts.Expression {
diff --git a/generators/typescript/model/type-generator/src/object/GeneratedObjectTypeImpl.ts b/generators/typescript/model/type-generator/src/object/GeneratedObjectTypeImpl.ts
index 3d1fcefb8c1..7582ae5bac9 100644
--- a/generators/typescript/model/type-generator/src/object/GeneratedObjectTypeImpl.ts
+++ b/generators/typescript/model/type-generator/src/object/GeneratedObjectTypeImpl.ts
@@ -1,50 +1,129 @@
import { ExampleTypeShape, ObjectProperty, ObjectTypeDeclaration, TypeReference } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts, getTextOfTsNode, maybeAddDocs } from "@fern-typescript/commons";
-import { GeneratedObjectType, ModelContext } from "@fern-typescript/contexts";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import {
+ generateInlinePropertiesModule,
+ GetReferenceOpts,
+ getTextOfTsNode,
+ maybeAddDocsStructure,
+ TypeReferenceNode
+} from "@fern-typescript/commons";
+import { GeneratedObjectType, BaseContext } from "@fern-typescript/contexts";
+import {
+ InterfaceDeclarationStructure,
+ ModuleDeclarationStructure,
+ PropertySignatureStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ WriterFunction
+} from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
-export class GeneratedObjectTypeImpl
+interface Property {
+ name: string;
+ type: ts.TypeNode;
+ hasQuestionToken: boolean;
+ docs: string | undefined;
+ irProperty: ObjectProperty | undefined;
+}
+
+export class GeneratedObjectTypeImpl
extends AbstractGeneratedType
implements GeneratedObjectType
{
public readonly type = "object";
- public writeToFile(context: Context): void {
- const interfaceNode = context.sourceFile.addInterface({
- name: this.typeName,
- properties: [
- ...this.shape.properties.map((property) => {
- const value = context.type.getReferenceToType(property.valueType);
- const propertyNode: OptionalKind = {
- name: `"${this.getPropertyKeyFromProperty(property)}"`,
- type: getTextOfTsNode(
- this.noOptionalProperties ? value.typeNode : value.typeNodeWithoutUndefined
- ),
- hasQuestionToken: !this.noOptionalProperties && value.isOptional,
- docs: property.docs != null ? [{ description: property.docs }] : undefined
- };
-
- return propertyNode;
- }),
- ...(this.shape.extraProperties
- ? [
- {
- name: "[key: string]", // This is the simpler way to add an index signature
- type: "any",
- docs: [{ description: "Accepts any additional properties" }]
- }
- ]
- : [])
- ],
- isExported: true
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const statements: (string | WriterFunction | StatementStructures)[] = [this.generateInterface(context)];
+ const iModule = this.generateModule(context);
+ if (iModule) {
+ statements.push(iModule);
+ }
+ return statements;
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return ts.factory.createTypeLiteralNode(
+ this.generatePropertiesInternal(context).map(({ name, type, hasQuestionToken, docs, irProperty }) => {
+ let propertyValue: ts.TypeNode = type;
+ if (irProperty) {
+ const inlineUnionRef = context.type.getReferenceToTypeForInlineUnion(irProperty.valueType);
+ propertyValue = hasQuestionToken
+ ? inlineUnionRef.typeNode
+ : inlineUnionRef.typeNodeWithoutUndefined;
+ }
+ return ts.factory.createPropertySignature(
+ undefined,
+ ts.factory.createIdentifier(name),
+ hasQuestionToken ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined,
+ propertyValue
+ );
+ })
+ );
+ }
+
+ public generateProperties(context: Context): PropertySignatureStructure[] {
+ return this.generatePropertiesInternal(context).map(({ name, type, hasQuestionToken, docs }) => {
+ const propertyNode: PropertySignatureStructure = {
+ kind: StructureKind.PropertySignature,
+ name,
+ type: getTextOfTsNode(type),
+ hasQuestionToken,
+ docs: docs != null ? [{ description: docs }] : undefined
+ };
+
+ return propertyNode;
});
+ }
- maybeAddDocs(interfaceNode, this.getDocs(context));
+ private generatePropertiesInternal(context: Context): Property[] {
+ const props = this.shape.properties.map((property) => {
+ const value = this.getTypeForObjectProperty(context, property);
+ const propertyNode: Property = {
+ name: `"${this.getPropertyKeyFromProperty(property)}"`,
+ type: this.noOptionalProperties ? value.typeNode : value.typeNodeWithoutUndefined,
+ hasQuestionToken: !this.noOptionalProperties && value.isOptional,
+ docs: property.docs,
+ irProperty: property
+ };
+ return propertyNode;
+ });
+ if (this.shape.extraProperties) {
+ props.push({
+ name: "[key: string]", // This is the simpler way to add an index signature
+ type: ts.factory.createTypeReferenceNode("any"),
+ hasQuestionToken: false,
+ docs: "Accepts any additional properties",
+ irProperty: undefined
+ });
+ }
+ return props;
+ }
+
+ public generateInterface(context: Context): InterfaceDeclarationStructure {
+ const interfaceNode: InterfaceDeclarationStructure = {
+ kind: StructureKind.Interface,
+ name: this.typeName,
+ properties: [...this.generateProperties(context)],
+ isExported: true
+ };
+ maybeAddDocsStructure(interfaceNode, this.getDocs(context));
+ const iExtends = [];
for (const extension of this.shape.extends) {
- interfaceNode.addExtends(getTextOfTsNode(context.type.getReferenceToNamedType(extension).getTypeNode()));
+ iExtends.push(getTextOfTsNode(context.type.getReferenceToNamedType(extension).getTypeNode()));
}
+ interfaceNode.extends = iExtends;
+ return interfaceNode;
+ }
+
+ private getTypeForObjectProperty(context: Context, property: ObjectProperty): TypeReferenceNode {
+ return context.type.getReferenceToInlinePropertyType(
+ property.valueType,
+ this.typeName,
+ property.name.name.pascalCase.safeName
+ );
}
public getPropertyKey({ propertyWireKey }: { propertyWireKey: string }): string {
@@ -125,4 +204,20 @@ export class GeneratedObjectTypeImpl
})
];
}
+
+ public generateModule(context: Context): ModuleDeclarationStructure | undefined {
+ if (!this.enableInlineTypes) {
+ return undefined;
+ }
+ return generateInlinePropertiesModule({
+ parentTypeName: this.typeName,
+ properties: this.shape.properties.map((prop) => ({
+ propertyName: prop.name.name.pascalCase.safeName,
+ typeReference: prop.valueType
+ })),
+ generateStatements: (typeName, typeNameOverride) =>
+ context.type.getGeneratedType(typeName, typeNameOverride).generateStatements(context),
+ getTypeDeclaration: (namedType) => context.type.getTypeDeclaration(namedType)
+ });
+ }
}
diff --git a/generators/typescript/model/type-generator/src/undiscriminated-union/GeneratedUndiscriminatedUnionTypeImpl.ts b/generators/typescript/model/type-generator/src/undiscriminated-union/GeneratedUndiscriminatedUnionTypeImpl.ts
index 94a347ab875..655d8e0dd3a 100644
--- a/generators/typescript/model/type-generator/src/undiscriminated-union/GeneratedUndiscriminatedUnionTypeImpl.ts
+++ b/generators/typescript/model/type-generator/src/undiscriminated-union/GeneratedUndiscriminatedUnionTypeImpl.ts
@@ -1,28 +1,66 @@
-import { ExampleTypeShape, UndiscriminatedUnionTypeDeclaration } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts, getWriterForMultiLineUnionType, maybeAddDocs } from "@fern-typescript/commons";
-import { GeneratedUndiscriminatedUnionType, ModelContext } from "@fern-typescript/contexts";
-import { ts } from "ts-morph";
+import {
+ ExampleTypeShape,
+ UndiscriminatedUnionMember,
+ UndiscriminatedUnionTypeDeclaration
+} from "@fern-fern/ir-sdk/api";
+import {
+ GetReferenceOpts,
+ getWriterForMultiLineUnionType,
+ maybeAddDocsNode,
+ maybeAddDocsStructure
+} from "@fern-typescript/commons";
+import { GeneratedUndiscriminatedUnionType, BaseContext } from "@fern-typescript/contexts";
+import {
+ ModuleDeclarationStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ TypeAliasDeclarationStructure,
+ WriterFunction
+} from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
-export class GeneratedUndiscriminatedUnionTypeImpl
+export class GeneratedUndiscriminatedUnionTypeImpl
extends AbstractGeneratedType
implements GeneratedUndiscriminatedUnionType
{
public readonly type = "undiscriminatedUnion";
- public writeToFile(context: Context): void {
- const type = context.sourceFile.addTypeAlias({
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const statements: StatementStructures[] = [this.generateTypeAlias(context)];
+ return statements;
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return ts.factory.createUnionTypeNode(this.shape.members.map((value) => this.getTypeNode(context, value)));
+ }
+
+ public generateModule(): ModuleDeclarationStructure | undefined {
+ return undefined;
+ }
+
+ private generateTypeAlias(context: Context): TypeAliasDeclarationStructure {
+ const alias: TypeAliasDeclarationStructure = {
name: this.typeName,
+ kind: StructureKind.TypeAlias,
isExported: true,
type: getWriterForMultiLineUnionType(
- this.shape.members.map((value) => ({
- docs: value.docs,
- node: context.type.getReferenceToType(value.type).typeNode
- }))
+ this.shape.members.map((value) => {
+ return {
+ docs: value.docs,
+ node: this.getTypeNode(context, value)
+ };
+ })
)
- });
+ };
+ maybeAddDocsStructure(alias, this.getDocs(context));
+ return alias;
+ }
- maybeAddDocs(type, this.getDocs(context));
+ private getTypeNode(context: Context, member: UndiscriminatedUnionMember): ts.TypeNode {
+ return context.type.getReferenceToTypeForInlineUnion(member.type).typeNode;
}
public buildExample(example: ExampleTypeShape, context: Context, opts: GetReferenceOpts): ts.Expression {
diff --git a/generators/typescript/model/type-generator/src/union/GeneratedUnionTypeImpl.ts b/generators/typescript/model/type-generator/src/union/GeneratedUnionTypeImpl.ts
index 5757e2c358a..90c632d2360 100644
--- a/generators/typescript/model/type-generator/src/union/GeneratedUnionTypeImpl.ts
+++ b/generators/typescript/model/type-generator/src/union/GeneratedUnionTypeImpl.ts
@@ -5,36 +5,40 @@ import {
UnionTypeDeclaration
} from "@fern-fern/ir-sdk/api";
import { GetReferenceOpts } from "@fern-typescript/commons";
-import { GeneratedUnion, GeneratedUnionType, ModelContext } from "@fern-typescript/contexts";
+import { GeneratedUnion, GeneratedUnionType, BaseContext } from "@fern-typescript/contexts";
import { GeneratedUnionImpl } from "@fern-typescript/union-generator";
-import { ts } from "ts-morph";
+import { ModuleDeclarationStructure, StatementStructures, ts, WriterFunction } from "ts-morph";
import { AbstractGeneratedType } from "../AbstractGeneratedType";
import { ParsedSingleUnionTypeForUnion } from "./ParsedSingleUnionTypeForUnion";
import { UnknownSingleUnionType } from "./UnknownSingleUnionType";
import { UnknownSingleUnionTypeGenerator } from "./UnknownSingleUnionTypeGenerator";
export declare namespace GeneratedUnionTypeImpl {
- export interface Init
+ export interface Init
extends AbstractGeneratedType.Init {
includeUtilsOnUnionMembers: boolean;
includeOtherInUnionTypes: boolean;
+ inline: boolean;
}
}
-export class GeneratedUnionTypeImpl
+export class GeneratedUnionTypeImpl
extends AbstractGeneratedType
implements GeneratedUnionType
{
public readonly type = "union";
private generatedUnion: GeneratedUnionImpl;
+ private readonly inline: boolean;
constructor({
includeUtilsOnUnionMembers,
includeOtherInUnionTypes,
+ inline,
...superInit
}: GeneratedUnionTypeImpl.Init) {
super(superInit);
+ this.inline = inline;
const parsedSingleUnionTypes = this.shape.types.map(
(singleUnionType) =>
@@ -44,7 +48,8 @@ export class GeneratedUnionTypeImpl
includeUtilsOnUnionMembers,
includeSerdeLayer: this.includeSerdeLayer,
retainOriginalCasing: this.retainOriginalCasing,
- noOptionalProperties: this.noOptionalProperties
+ noOptionalProperties: this.noOptionalProperties,
+ enableInlineTypes: this.enableInlineTypes
})
);
@@ -67,12 +72,24 @@ export class GeneratedUnionTypeImpl
baseProperties: this.shape.baseProperties,
includeSerdeLayer: this.includeSerdeLayer,
retainOriginalCasing: this.retainOriginalCasing,
- noOptionalProperties: this.noOptionalProperties
+ noOptionalProperties: this.noOptionalProperties,
+ inline: this.inline,
+ enableInlineTypes: this.enableInlineTypes
});
}
- public writeToFile(context: Context): void {
- this.generatedUnion.writeToFile(context);
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ return this.generatedUnion.generateStatements(context);
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return this.generatedUnion.generateForInlineUnion(context);
+ }
+
+ public generateModule(): ModuleDeclarationStructure | undefined {
+ return undefined;
}
public getGeneratedUnion(): GeneratedUnion {
diff --git a/generators/typescript/model/type-generator/src/union/ParsedSingleUnionTypeForUnion.ts b/generators/typescript/model/type-generator/src/union/ParsedSingleUnionTypeForUnion.ts
index 36da8b43008..4c456fdbdba 100644
--- a/generators/typescript/model/type-generator/src/union/ParsedSingleUnionTypeForUnion.ts
+++ b/generators/typescript/model/type-generator/src/union/ParsedSingleUnionTypeForUnion.ts
@@ -5,7 +5,7 @@ import {
SingleUnionTypeProperty,
UnionTypeDeclaration
} from "@fern-fern/ir-sdk/api";
-import { ModelContext } from "@fern-typescript/contexts";
+import { BaseContext } from "@fern-typescript/contexts";
import {
AbstractKnownSingleUnionType,
NoPropertiesSingleUnionTypeGenerator,
@@ -22,10 +22,11 @@ export declare namespace ParsedSingleUnionTypeForUnion {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
noOptionalProperties: boolean;
+ enableInlineTypes: boolean;
}
}
-export class ParsedSingleUnionTypeForUnion extends AbstractKnownSingleUnionType {
+export class ParsedSingleUnionTypeForUnion extends AbstractKnownSingleUnionType {
private singleUnionTypeFromUnion: SingleUnionType;
private includeSerdeLayer: boolean;
private retainOriginalCasing: boolean;
@@ -37,7 +38,8 @@ export class ParsedSingleUnionTypeForUnion extends
includeUtilsOnUnionMembers,
includeSerdeLayer,
retainOriginalCasing,
- noOptionalProperties
+ noOptionalProperties,
+ enableInlineTypes
}: ParsedSingleUnionTypeForUnion.Init) {
super({
singleUnionType: SingleUnionTypeProperties._visit>(
@@ -45,7 +47,7 @@ export class ParsedSingleUnionTypeForUnion extends
{
noProperties: () => new NoPropertiesSingleUnionTypeGenerator(),
samePropertiesAsObject: (extended) =>
- new SamePropertiesAsObjectSingleUnionTypeGenerator({ extended }),
+ new SamePropertiesAsObjectSingleUnionTypeGenerator({ extended, enableInlineTypes }),
singleProperty: (singleProperty) =>
new SinglePropertySingleUnionTypeGenerator({
propertyName: ParsedSingleUnionTypeForUnion.getSinglePropertyKey(singleProperty, {
@@ -54,7 +56,10 @@ export class ParsedSingleUnionTypeForUnion extends
}),
getReferenceToPropertyType: (context) =>
context.type.getReferenceToType(singleProperty.type),
- noOptionalProperties
+ getReferenceToPropertyTypeForInlineUnion: (context) =>
+ context.type.getReferenceToTypeForInlineUnion(singleProperty.type),
+ noOptionalProperties,
+ enableInlineTypes
}),
_other: () => {
throw new Error("Unknown SingleUnionTypeProperties: " + singleUnionType.shape.propertiesType);
diff --git a/generators/typescript/model/type-generator/src/union/SamePropertiesAsObjectSingleUnionTypeGenerator.ts b/generators/typescript/model/type-generator/src/union/SamePropertiesAsObjectSingleUnionTypeGenerator.ts
index 7c62f2b5e14..3ffa593082e 100644
--- a/generators/typescript/model/type-generator/src/union/SamePropertiesAsObjectSingleUnionTypeGenerator.ts
+++ b/generators/typescript/model/type-generator/src/union/SamePropertiesAsObjectSingleUnionTypeGenerator.ts
@@ -1,29 +1,69 @@
import { DeclaredTypeName } from "@fern-fern/ir-sdk/api";
-import { ModelContext } from "@fern-typescript/contexts";
+import { BaseContext } from "@fern-typescript/contexts";
import { SingleUnionTypeGenerator } from "@fern-typescript/union-generator";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
export declare namespace SamePropertiesAsObjectSingleUnionTypeGenerator {
export interface Init {
extended: DeclaredTypeName;
+ enableInlineTypes: boolean;
}
}
-export class SamePropertiesAsObjectSingleUnionTypeGenerator
+export class SamePropertiesAsObjectSingleUnionTypeGenerator
implements SingleUnionTypeGenerator
{
private static BUILDER_PARAMETER_NAME = "value";
private extended: DeclaredTypeName;
+ private enableInlineTypes: boolean;
- constructor({ extended }: SamePropertiesAsObjectSingleUnionTypeGenerator.Init) {
+ constructor({ extended, enableInlineTypes }: SamePropertiesAsObjectSingleUnionTypeGenerator.Init) {
this.extended = extended;
+ this.enableInlineTypes = enableInlineTypes;
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ const typeDeclaration = context.type.getTypeDeclaration(this.extended);
+ if (typeDeclaration.inline) {
+ const type = context.type.getGeneratedType(typeDeclaration.name);
+ return type.generateForInlineUnion(context);
+ }
+ return context.type.getReferenceToNamedType(this.extended).getTypeNode();
}
public getExtendsForInterface(context: Context): ts.TypeNode[] {
+ const typeDeclaration = context.type.getTypeDeclaration(this.extended);
+ if (this.enableInlineTypes && typeDeclaration.inline) {
+ // inline types don't inherit the properties from the interface, but have the properties directly on the parent interface
+ return [];
+ }
return [context.type.getReferenceToNamedType(this.extended).getTypeNode()];
}
+ public getDiscriminantPropertiesForInterface(context: Context): OptionalKind[] {
+ const typeDeclaration = context.type.getTypeDeclaration(this.extended);
+ if (this.enableInlineTypes && typeDeclaration.inline) {
+ const type = context.type.getGeneratedType(typeDeclaration.name);
+ if (type.type === "object") {
+ return type.generateProperties(context);
+ }
+ }
+ return [];
+ }
+
+ public generateModule(context: Context): ModuleDeclarationStructure | undefined {
+ if (!this.enableInlineTypes) {
+ return undefined;
+ }
+ const typeDeclaration = context.type.getTypeDeclaration(this.extended);
+ if (!typeDeclaration.inline) {
+ return undefined;
+ }
+ const type = context.type.getGeneratedType(typeDeclaration.name);
+ return type.generateModule(context);
+ }
+
public getNonDiscriminantPropertiesForInterface(): OptionalKind[] {
return [];
}
diff --git a/generators/typescript/model/type-generator/src/union/UnknownSingleUnionType.ts b/generators/typescript/model/type-generator/src/union/UnknownSingleUnionType.ts
index 87fe64ae931..8f8cb0725bb 100644
--- a/generators/typescript/model/type-generator/src/union/UnknownSingleUnionType.ts
+++ b/generators/typescript/model/type-generator/src/union/UnknownSingleUnionType.ts
@@ -1,7 +1,7 @@
-import { ModelContext } from "@fern-typescript/contexts";
+import { BaseContext } from "@fern-typescript/contexts";
import { AbstractUnknownSingleUnionType } from "@fern-typescript/union-generator";
-export class UnknownSingleUnionType extends AbstractUnknownSingleUnionType {
+export class UnknownSingleUnionType extends AbstractUnknownSingleUnionType {
public getDocs(): string | null | undefined {
return undefined;
}
diff --git a/generators/typescript/model/type-generator/src/union/UnknownSingleUnionTypeGenerator.ts b/generators/typescript/model/type-generator/src/union/UnknownSingleUnionTypeGenerator.ts
index b003385945e..75697b73ae3 100644
--- a/generators/typescript/model/type-generator/src/union/UnknownSingleUnionTypeGenerator.ts
+++ b/generators/typescript/model/type-generator/src/union/UnknownSingleUnionTypeGenerator.ts
@@ -1,14 +1,26 @@
-import { ModelContext } from "@fern-typescript/contexts";
+import { BaseContext } from "@fern-typescript/contexts";
import { SingleUnionTypeGenerator } from "@fern-typescript/union-generator";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
-export class UnknownSingleUnionTypeGenerator implements SingleUnionTypeGenerator {
+export class UnknownSingleUnionTypeGenerator implements SingleUnionTypeGenerator {
private static BUILDER_PARAMETER_NAME = "value";
+ public generateForInlineUnion(context: BaseContext): ts.TypeNode {
+ return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
+ }
+
public getExtendsForInterface(): ts.TypeNode[] {
return [];
}
+ public getDiscriminantPropertiesForInterface(): OptionalKind[] {
+ return [];
+ }
+
+ public generateModule(context: BaseContext): ModuleDeclarationStructure | undefined {
+ return undefined;
+ }
+
public getNonDiscriminantPropertiesForInterface(): OptionalKind[] {
return [];
}
@@ -22,7 +34,7 @@ export class UnknownSingleUnionTypeGenerator implements SingleUnionTypeGenerator
}
public getVisitMethodParameterType(
- _context: ModelContext,
+ _context: BaseContext,
{ discriminant }: { discriminant: string }
): ts.TypeNode | undefined {
return ts.factory.createTypeLiteralNode([
@@ -36,7 +48,7 @@ export class UnknownSingleUnionTypeGenerator implements SingleUnionTypeGenerator
}
public getParametersForBuilder(
- _context: ModelContext,
+ _context: BaseContext,
{ discriminant }: { discriminant: string }
): ts.ParameterDeclaration[] {
return [
diff --git a/generators/typescript/model/type-reference-converters/package.json b/generators/typescript/model/type-reference-converters/package.json
index b19dd645d68..e5405ede708 100644
--- a/generators/typescript/model/type-reference-converters/package.json
+++ b/generators/typescript/model/type-reference-converters/package.json
@@ -27,7 +27,8 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
+ "@fern-api/core-utils": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/resolvers": "workspace:*",
"ts-morph": "^15.1.0"
diff --git a/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceConverter.ts b/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceConverter.ts
index d191e53c8d5..e698ff62e20 100644
--- a/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceConverter.ts
@@ -18,63 +18,129 @@ export declare namespace AbstractTypeReferenceConverter {
treatUnknownAsAny: boolean;
includeSerdeLayer: boolean;
useBigInt: boolean;
+ enableInlineTypes: boolean;
}
}
+export type ConvertTypeReferenceParams =
+ | ConvertTypeReferenceParams.DefaultParams
+ | ConvertTypeReferenceParams.InlinePropertyTypeParams
+ | ConvertTypeReferenceParams.InlineAliasTypeParams
+ | ConvertTypeReferenceParams.ForInlineUnionTypeParams;
+
+export namespace ConvertTypeReferenceParams {
+ export function isInlinePropertyParams(params: ConvertTypeReferenceParams): params is InlinePropertyTypeParams {
+ return params.type === "inlinePropertyParams";
+ }
+ export function isInlineAliasParams(params: ConvertTypeReferenceParams): params is InlineAliasTypeParams {
+ return params.type === "inlineAliasParams";
+ }
+ export function isForInlineUnionParams(params: ConvertTypeReferenceParams): params is ForInlineUnionTypeParams {
+ return params.type === "forInlineUnionParams";
+ }
+ export function hasGenericIn(
+ params: ConvertTypeReferenceParams
+ ): params is InlinePropertyTypeParams | InlineAliasTypeParams {
+ return isInlinePropertyParams(params) || isInlineAliasParams(params);
+ }
+
+ export interface DefaultParams extends WithTypeReference {
+ type?: undefined;
+ }
+
+ /**
+ * Metadata for converting inline types
+ */
+ export interface InlinePropertyTypeParams extends WithGenericIn, WithTypeReference {
+ type: "inlinePropertyParams";
+ parentTypeName: string;
+ propertyName: string;
+ }
+
+ export interface InlineAliasTypeParams extends WithGenericIn, WithTypeReference {
+ type: "inlineAliasParams";
+ aliasTypeName: string;
+ }
+
+ export interface ForInlineUnionTypeParams extends WithTypeReference {
+ type: "forInlineUnionParams";
+ }
+
+ export interface WithGenericIn {
+ genericIn?: GenericIn;
+ }
+
+ export interface WithTypeReference {
+ typeReference: TypeReference;
+ }
+
+ export const GenericIn = {
+ List: "list",
+ Map: "map",
+ Set: "set"
+ } as const;
+ export type GenericIn = typeof GenericIn[keyof typeof GenericIn];
+}
+
+const genericIn = ConvertTypeReferenceParams.GenericIn;
+
export abstract class AbstractTypeReferenceConverter {
protected typeResolver: TypeResolver;
protected treatUnknownAsAny: boolean;
protected includeSerdeLayer: boolean;
protected useBigInt: boolean;
+ protected enableInlineTypes: boolean;
constructor({
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
}: AbstractTypeReferenceConverter.Init) {
this.typeResolver = typeResolver;
this.treatUnknownAsAny = treatUnknownAsAny;
this.includeSerdeLayer = includeSerdeLayer;
this.useBigInt = useBigInt;
+ this.enableInlineTypes = enableInlineTypes;
}
- public convert(typeReference: TypeReference): T {
- return TypeReference._visit(typeReference, {
- named: this.named.bind(this),
- primitive: this.primitive.bind(this),
- container: this.container.bind(this),
- unknown: this.treatUnknownAsAny ? this.any.bind(this) : this.unknown.bind(this),
+ public convert(params: ConvertTypeReferenceParams): T {
+ return TypeReference._visit(params.typeReference, {
+ named: (type) => this.named(type, params),
+ primitive: (type) => this.primitive(type),
+ container: (type) => this.container(type, params),
+ unknown: () => (this.treatUnknownAsAny ? this.any() : this.unknown()),
_other: () => {
- throw new Error("Unexpected type reference: " + typeReference.type);
+ throw new Error("Unexpected type reference: " + params.typeReference.type);
}
});
}
- protected container(container: ContainerType): T {
+ protected container(container: ContainerType, params: ConvertTypeReferenceParams): T {
return ContainerType._visit(container, {
- map: this.map.bind(this),
- list: this.list.bind(this),
- set: this.set.bind(this),
- optional: this.optional.bind(this),
- literal: this.literal.bind(this),
+ map: (type) => this.map(type, setGenericIn(params, genericIn.Map)),
+ list: (type) => this.list(type, setGenericIn(params, genericIn.List)),
+ set: (type) => this.set(type, setGenericIn(params, genericIn.Set)),
+ optional: (type) => this.optional(type, params),
+ literal: (type) => this.literal(type, params),
_other: () => {
throw new Error("Unexpected container type: " + container.type);
}
});
}
- protected abstract named(typeName: DeclaredTypeName): T;
+ protected abstract named(typeName: DeclaredTypeName, params: ConvertTypeReferenceParams): T;
protected abstract string(): T;
protected abstract number(): T;
protected abstract long(): T;
protected abstract bigInteger(): T;
protected abstract boolean(): T;
protected abstract dateTime(): T;
- protected abstract list(itemType: TypeReference): T;
- protected abstract set(itemType: TypeReference): T;
- protected abstract optional(itemType: TypeReference): T;
- protected abstract literal(literal: Literal): T;
+ protected abstract list(itemType: TypeReference, params: ConvertTypeReferenceParams): T;
+ protected abstract set(itemType: TypeReference, params: ConvertTypeReferenceParams): T;
+ protected abstract optional(itemType: TypeReference, params: ConvertTypeReferenceParams): T;
+ protected abstract literal(literal: Literal, params: ConvertTypeReferenceParams): T;
protected abstract unknown(): T;
protected abstract any(): T;
@@ -99,17 +165,17 @@ export abstract class AbstractTypeReferenceConverter {
});
}
- protected map(mapType: MapType): T {
+ protected map(mapType: MapType, params: ConvertTypeReferenceParams): T {
const resolvdKeyType = this.typeResolver.resolveTypeReference(mapType.keyType);
if (resolvdKeyType.type === "named" && resolvdKeyType.shape === ShapeType.Enum) {
- return this.mapWithEnumKeys(mapType);
+ return this.mapWithEnumKeys(mapType, params);
} else {
- return this.mapWithNonEnumKeys(mapType);
+ return this.mapWithNonEnumKeys(mapType, params);
}
}
- protected abstract mapWithEnumKeys(mapType: MapType): T;
- protected abstract mapWithNonEnumKeys(mapType: MapType): T;
+ protected abstract mapWithEnumKeys(mapType: MapType, params: ConvertTypeReferenceParams): T;
+ protected abstract mapWithNonEnumKeys(mapType: MapType, params: ConvertTypeReferenceParams): T;
protected isTypeReferencePrimitive(typeReference: TypeReference): boolean {
const resolvedType = this.typeResolver.resolveTypeReference(typeReference);
@@ -130,3 +196,16 @@ export abstract class AbstractTypeReferenceConverter {
};
}
}
+
+function setGenericIn(
+ params: ConvertTypeReferenceParams,
+ genericIn: ConvertTypeReferenceParams.GenericIn
+): ConvertTypeReferenceParams {
+ if (ConvertTypeReferenceParams.hasGenericIn(params)) {
+ params = {
+ ...params,
+ genericIn
+ };
+ }
+ return params;
+}
diff --git a/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceToTypeNodeConverter.ts b/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceToTypeNodeConverter.ts
index 5651e791176..b49c7aeed11 100644
--- a/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceToTypeNodeConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/AbstractTypeReferenceToTypeNodeConverter.ts
@@ -1,26 +1,38 @@
import { DeclaredTypeName, Literal, MapType, ResolvedTypeReference, TypeReference } from "@fern-fern/ir-sdk/api";
import { TypeReferenceNode } from "@fern-typescript/commons";
import { ts } from "ts-morph";
-import { AbstractTypeReferenceConverter } from "./AbstractTypeReferenceConverter";
+import { assertNever } from "@fern-api/core-utils";
+import { AbstractTypeReferenceConverter, ConvertTypeReferenceParams } from "./AbstractTypeReferenceConverter";
+import { InlineConsts } from "@fern-typescript/commons/src/codegen-utils/inlineConsts";
export declare namespace AbstractTypeReferenceToTypeNodeConverter {
export interface Init extends AbstractTypeReferenceConverter.Init {
- getReferenceToNamedType: (typeName: DeclaredTypeName) => ts.EntityName;
+ getReferenceToNamedType: (typeName: DeclaredTypeName, params: ConvertTypeReferenceParams) => ts.EntityName;
+ generateForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode;
}
}
export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractTypeReferenceConverter {
- protected getReferenceToNamedType: (typeName: DeclaredTypeName) => ts.EntityName;
-
- constructor({ getReferenceToNamedType, ...superInit }: AbstractTypeReferenceToTypeNodeConverter.Init) {
+ protected getReferenceToNamedType: (
+ typeName: DeclaredTypeName,
+ params: ConvertTypeReferenceParams
+ ) => ts.EntityName;
+ protected generateForInlineUnion: (typeName: DeclaredTypeName) => ts.TypeNode;
+
+ constructor({
+ getReferenceToNamedType,
+ generateForInlineUnion,
+ ...superInit
+ }: AbstractTypeReferenceToTypeNodeConverter.Init) {
super(superInit);
this.getReferenceToNamedType = getReferenceToNamedType;
+ this.generateForInlineUnion = generateForInlineUnion;
}
- protected override named(typeName: DeclaredTypeName): TypeReferenceNode {
+ protected override named(typeName: DeclaredTypeName, params: ConvertTypeReferenceParams): TypeReferenceNode {
const resolvedType = this.typeResolver.resolveTypeName(typeName);
const isOptional = ResolvedTypeReference._visit(resolvedType, {
- container: (container) => this.container(container).isOptional,
+ container: (container) => this.container(container, params).isOptional,
primitive: (primitive) => this.primitive(primitive).isOptional,
named: () => false,
unknown: () => this.unknown().isOptional,
@@ -29,7 +41,26 @@ export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractT
}
});
- const typeNodeWithoutUndefined = ts.factory.createTypeReferenceNode(this.getReferenceToNamedType(typeName));
+ let typeNodeWithoutUndefined: ts.TypeNode;
+ const typeDeclaration = this.typeResolver.getTypeDeclarationFromName(typeName);
+ if (this.enableInlineTypes && typeDeclaration.inline) {
+ if (ConvertTypeReferenceParams.isInlinePropertyParams(params)) {
+ typeNodeWithoutUndefined = this.createTypeRefenceForInlinePropertyNamedType(params);
+ } else if (ConvertTypeReferenceParams.isInlineAliasParams(params)) {
+ typeNodeWithoutUndefined = this.createTypeRefenceForInlineAliasNamedType(typeName, params);
+ } else if (ConvertTypeReferenceParams.isForInlineUnionParams(params)) {
+ typeNodeWithoutUndefined = this.createTypeRefenceForInlineNamedTypeForInlineUnion(typeName);
+ } else {
+ typeNodeWithoutUndefined = ts.factory.createTypeReferenceNode(
+ this.getReferenceToNamedType(typeName, params)
+ );
+ }
+ } else {
+ typeNodeWithoutUndefined = ts.factory.createTypeReferenceNode(
+ this.getReferenceToNamedType(typeName, params)
+ );
+ }
+
if (!isOptional) {
return this.generateNonOptionalTypeReferenceNode(typeNodeWithoutUndefined);
} else {
@@ -41,6 +72,60 @@ export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractT
}
}
+ private createTypeRefenceForInlineNamedTypeForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode {
+ return this.generateForInlineUnion(typeName);
+ }
+
+ private createTypeRefenceForInlineAliasNamedType(
+ typeName: DeclaredTypeName,
+ params: ConvertTypeReferenceParams.InlineAliasTypeParams
+ ): ts.TypeNode {
+ let name: ts.EntityName = ts.factory.createIdentifier(params.aliasTypeName);
+ switch (params.genericIn) {
+ case "list":
+ name = ts.factory.createQualifiedName(name, InlineConsts.LIST_ITEM_TYPE_NAME);
+ break;
+ case "map":
+ name = ts.factory.createQualifiedName(name, InlineConsts.MAP_VALUE_TYPE_NAME);
+ break;
+ case "set":
+ name = ts.factory.createQualifiedName(name, InlineConsts.LIST_ITEM_TYPE_NAME);
+ break;
+ default:
+ return ts.factory.createTypeReferenceNode(this.getReferenceToNamedType(typeName, params));
+ }
+
+ return ts.factory.createTypeReferenceNode(name);
+ }
+
+ private createTypeRefenceForInlinePropertyNamedType({
+ parentTypeName,
+ propertyName,
+ genericIn
+ }: ConvertTypeReferenceParams.InlinePropertyTypeParams): ts.TypeNode {
+ let name = ts.factory.createQualifiedName(
+ ts.factory.createIdentifier(parentTypeName),
+ ts.factory.createIdentifier(propertyName)
+ );
+ switch (genericIn) {
+ case "list":
+ name = ts.factory.createQualifiedName(name, InlineConsts.LIST_ITEM_TYPE_NAME);
+ break;
+ case "map":
+ name = ts.factory.createQualifiedName(name, InlineConsts.MAP_VALUE_TYPE_NAME);
+ break;
+ case "set":
+ name = ts.factory.createQualifiedName(name, InlineConsts.LIST_ITEM_TYPE_NAME);
+ break;
+ case undefined:
+ break;
+ default:
+ assertNever(genericIn);
+ }
+
+ return ts.factory.createTypeReferenceNode(name);
+ }
+
protected override string(): TypeReferenceNode {
return this.generateNonOptionalTypeReferenceNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword));
}
@@ -73,8 +158,8 @@ export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractT
return this.generateNonOptionalTypeReferenceNode(ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword));
}
- protected override optional(itemType: TypeReference): TypeReferenceNode {
- const referencedToValueType = this.convert(itemType).typeNode;
+ protected override optional(itemType: TypeReference, params: ConvertTypeReferenceParams): TypeReferenceNode {
+ const referencedToValueType = this.convert({ ...params, typeReference: itemType }).typeNode;
return {
isOptional: true,
typeNode: this.addUndefinedToTypeNode(referencedToValueType),
@@ -107,9 +192,9 @@ export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractT
};
}
- protected override list(itemType: TypeReference): TypeReferenceNode {
+ protected override list(itemType: TypeReference, params: ConvertTypeReferenceParams): TypeReferenceNode {
return this.generateNonOptionalTypeReferenceNode(
- ts.factory.createArrayTypeNode(this.convert(itemType).typeNode)
+ ts.factory.createArrayTypeNode(this.convert({ ...params, typeReference: itemType }).typeNode)
);
}
@@ -139,25 +224,25 @@ export abstract class AbstractTypeReferenceToTypeNodeConverter extends AbstractT
});
}
- protected override mapWithEnumKeys(map: MapType): TypeReferenceNode {
- return this.mapWithOptionalValues(map);
+ protected override mapWithEnumKeys(map: MapType, params: ConvertTypeReferenceParams): TypeReferenceNode {
+ return this.mapWithOptionalValues(map, params);
}
- protected override mapWithNonEnumKeys(map: MapType): TypeReferenceNode {
+ protected override mapWithNonEnumKeys(map: MapType, params: ConvertTypeReferenceParams): TypeReferenceNode {
return this.generateNonOptionalTypeReferenceNode(
ts.factory.createTypeReferenceNode("Record", [
- this.convert(map.keyType).typeNode,
- this.convert(map.valueType).typeNode
+ this.convert({ ...params, typeReference: map.keyType }).typeNode,
+ this.convert({ ...params, typeReference: map.valueType }).typeNode
])
);
}
- protected mapWithOptionalValues(map: MapType): TypeReferenceNode {
- const valueType = this.convert(map.valueType);
+ protected mapWithOptionalValues(map: MapType, params: ConvertTypeReferenceParams): TypeReferenceNode {
+ const valueType = this.convert({ ...params, typeReference: map.valueType });
return this.generateNonOptionalTypeReferenceNode(
ts.factory.createTypeReferenceNode("Record", [
- this.convert(map.keyType).typeNode,
- (valueType.isOptional ? valueType : this.optional(map.valueType)).typeNode
+ this.convert({ ...params, typeReference: map.keyType }).typeNode,
+ (valueType.isOptional ? valueType : this.optional(map.valueType, params)).typeNode
])
);
}
diff --git a/generators/typescript/model/type-reference-converters/src/TypeReferenceToParsedTypeNodeConverter.ts b/generators/typescript/model/type-reference-converters/src/TypeReferenceToParsedTypeNodeConverter.ts
index 7de607125bc..343fabec135 100644
--- a/generators/typescript/model/type-reference-converters/src/TypeReferenceToParsedTypeNodeConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/TypeReferenceToParsedTypeNodeConverter.ts
@@ -1,6 +1,7 @@
import { TypeReference } from "@fern-fern/ir-sdk/api";
import { TypeReferenceNode } from "@fern-typescript/commons";
import { ts } from "ts-morph";
+import { ConvertTypeReferenceParams } from "./AbstractTypeReferenceConverter";
import { AbstractTypeReferenceToTypeNodeConverter } from "./AbstractTypeReferenceToTypeNodeConverter";
export declare namespace TypeReferenceToParsedTypeNodeConverter {
@@ -8,12 +9,12 @@ export declare namespace TypeReferenceToParsedTypeNodeConverter {
}
export class TypeReferenceToParsedTypeNodeConverter extends AbstractTypeReferenceToTypeNodeConverter {
- protected override set(itemType: TypeReference): TypeReferenceNode {
+ protected override set(itemType: TypeReference, params: ConvertTypeReferenceParams): TypeReferenceNode {
if (this.includeSerdeLayer && this.isTypeReferencePrimitive(itemType)) {
- const itemTypeNode = this.convert(itemType).typeNode;
+ const itemTypeNode = this.convert({ ...params, typeReference: itemType }).typeNode;
return this.generateNonOptionalTypeReferenceNode(ts.factory.createTypeReferenceNode("Set", [itemTypeNode]));
} else {
- return this.list(itemType);
+ return this.list(itemType, params);
}
}
diff --git a/generators/typescript/model/type-reference-converters/src/TypeReferenceToRawTypeNodeConverter.ts b/generators/typescript/model/type-reference-converters/src/TypeReferenceToRawTypeNodeConverter.ts
index 4bb04a41297..aeb0d6ae57a 100644
--- a/generators/typescript/model/type-reference-converters/src/TypeReferenceToRawTypeNodeConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/TypeReferenceToRawTypeNodeConverter.ts
@@ -1,17 +1,18 @@
import { TypeReference } from "@fern-fern/ir-sdk/api";
import { TypeReferenceNode } from "@fern-typescript/commons";
import { ts } from "ts-morph";
+import { ConvertTypeReferenceParams } from "./AbstractTypeReferenceConverter";
import { AbstractTypeReferenceToTypeNodeConverter } from "./AbstractTypeReferenceToTypeNodeConverter";
export class TypeReferenceToRawTypeNodeConverter extends AbstractTypeReferenceToTypeNodeConverter {
- protected override set(itemType: TypeReference): TypeReferenceNode {
+ protected override set(itemType: TypeReference, params: ConvertTypeReferenceParams): TypeReferenceNode {
return this.generateNonOptionalTypeReferenceNode(
- ts.factory.createArrayTypeNode(this.convert(itemType).typeNode)
+ ts.factory.createArrayTypeNode(this.convert({ ...params, typeReference: itemType }).typeNode)
);
}
- protected override optional(itemType: TypeReference): TypeReferenceNode {
- const referencedToValueType = this.convert(itemType).typeNode;
+ protected override optional(itemType: TypeReference, params: ConvertTypeReferenceParams): TypeReferenceNode {
+ const referencedToValueType = this.convert({ ...params, typeReference: itemType }).typeNode;
return {
isOptional: true,
typeNode: ts.factory.createUnionTypeNode([
diff --git a/generators/typescript/model/type-reference-converters/src/TypeReferenceToSchemaConverter.ts b/generators/typescript/model/type-reference-converters/src/TypeReferenceToSchemaConverter.ts
index 2c826715b6d..e3f96b82cea 100644
--- a/generators/typescript/model/type-reference-converters/src/TypeReferenceToSchemaConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/TypeReferenceToSchemaConverter.ts
@@ -1,6 +1,6 @@
import { DeclaredTypeName, Literal, MapType, TypeReference } from "@fern-fern/ir-sdk/api";
import { Zurg } from "@fern-typescript/commons";
-import { AbstractTypeReferenceConverter } from "./AbstractTypeReferenceConverter";
+import { AbstractTypeReferenceConverter, ConvertTypeReferenceParams } from "./AbstractTypeReferenceConverter";
export declare namespace TypeReferenceToSchemaConverter {
export interface Init extends AbstractTypeReferenceConverter.Init {
@@ -19,7 +19,7 @@ export class TypeReferenceToSchemaConverter extends AbstractTypeReferenceConvert
this.zurg = zurg;
}
- protected override named(typeName: DeclaredTypeName): Zurg.Schema {
+ protected override named(typeName: DeclaredTypeName, params: ConvertTypeReferenceParams): Zurg.Schema {
return this.getSchemaOfNamedType(typeName);
}
@@ -53,8 +53,8 @@ export class TypeReferenceToSchemaConverter extends AbstractTypeReferenceConvert
return this.zurg.date();
}
- protected override optional(itemType: TypeReference): Zurg.Schema {
- return this.convert(itemType).optional();
+ protected override optional(itemType: TypeReference, params: ConvertTypeReferenceParams): Zurg.Schema {
+ return this.convert({ ...params, typeReference: itemType }).optional();
}
protected override unknown(): Zurg.Schema {
@@ -65,8 +65,8 @@ export class TypeReferenceToSchemaConverter extends AbstractTypeReferenceConvert
return this.zurg.any();
}
- protected override list(itemType: TypeReference): Zurg.Schema {
- return this.zurg.list(this.convert(itemType));
+ protected override list(itemType: TypeReference, params: ConvertTypeReferenceParams): Zurg.Schema {
+ return this.zurg.list(this.convert({ ...params, typeReference: itemType }));
}
protected override literal(literal: Literal): Zurg.Schema {
@@ -79,30 +79,33 @@ export class TypeReferenceToSchemaConverter extends AbstractTypeReferenceConvert
});
}
- protected override mapWithEnumKeys(map: MapType): Zurg.Schema {
- return this.mapWithOptionalValues(map);
+ protected override mapWithEnumKeys(map: MapType, params: ConvertTypeReferenceParams): Zurg.Schema {
+ return this.mapWithOptionalValues(map, params);
}
- protected override mapWithNonEnumKeys({ keyType, valueType }: MapType): Zurg.Schema {
+ protected override mapWithNonEnumKeys(
+ { keyType, valueType }: MapType,
+ params: ConvertTypeReferenceParams
+ ): Zurg.Schema {
return this.zurg.record({
- keySchema: this.convert(keyType),
- valueSchema: this.convert(valueType)
+ keySchema: this.convert({ ...params, typeReference: keyType }),
+ valueSchema: this.convert({ ...params, typeReference: valueType })
});
}
- protected mapWithOptionalValues({ keyType, valueType }: MapType): Zurg.Schema {
- const valueSchema = this.convert(valueType);
+ protected mapWithOptionalValues({ keyType, valueType }: MapType, params: ConvertTypeReferenceParams): Zurg.Schema {
+ const valueSchema = this.convert({ ...params, typeReference: valueType });
return this.zurg.record({
- keySchema: this.convert(keyType),
+ keySchema: this.convert({ ...params, typeReference: keyType }),
valueSchema: valueSchema.isOptional ? valueSchema : valueSchema.optional()
});
}
- protected override set(itemType: TypeReference): Zurg.Schema {
+ protected override set(itemType: TypeReference, params: ConvertTypeReferenceParams): Zurg.Schema {
if (this.isTypeReferencePrimitive(itemType)) {
- return this.zurg.set(this.convert(itemType));
+ return this.zurg.set(this.convert({ ...params, typeReference: itemType }));
} else {
- return this.list(itemType);
+ return this.list(itemType, params);
}
}
}
diff --git a/generators/typescript/model/type-reference-converters/src/TypeReferenceToStringExpressionConverter.ts b/generators/typescript/model/type-reference-converters/src/TypeReferenceToStringExpressionConverter.ts
index 6fbdaec0fbd..9effd39cfcf 100644
--- a/generators/typescript/model/type-reference-converters/src/TypeReferenceToStringExpressionConverter.ts
+++ b/generators/typescript/model/type-reference-converters/src/TypeReferenceToStringExpressionConverter.ts
@@ -7,7 +7,7 @@ import {
TypeReference
} from "@fern-fern/ir-sdk/api";
import { ts } from "ts-morph";
-import { AbstractTypeReferenceConverter } from "./AbstractTypeReferenceConverter";
+import { AbstractTypeReferenceConverter, ConvertTypeReferenceParams } from "./AbstractTypeReferenceConverter";
export declare namespace TypeReferenceToStringExpressionConverter {
export interface Init extends AbstractTypeReferenceConverter.Init {}
@@ -16,7 +16,10 @@ export declare namespace TypeReferenceToStringExpressionConverter {
export class TypeReferenceToStringExpressionConverter extends AbstractTypeReferenceConverter<
(reference: ts.Expression) => ts.Expression
> {
- public convertWithNullCheckIfOptional(type: TypeReference): (reference: ts.Expression) => ts.Expression {
+ public convertWithNullCheckIfOptional(
+ params: ConvertTypeReferenceParams
+ ): (reference: ts.Expression) => ts.Expression {
+ const type = params.typeReference;
const isNullable = TypeReference._visit(type, {
named: (typeName) => {
const resolvedType = this.typeResolver.resolveTypeName(typeName);
@@ -31,7 +34,7 @@ export class TypeReferenceToStringExpressionConverter extends AbstractTypeRefere
});
if (!isNullable) {
- return this.convert(type);
+ return this.convert(params);
}
return (reference) =>
@@ -42,21 +45,24 @@ export class TypeReferenceToStringExpressionConverter extends AbstractTypeRefere
ts.factory.createNull()
),
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
- this.convert(type)(reference),
+ this.convert(params)(reference),
ts.factory.createToken(ts.SyntaxKind.ColonToken),
ts.factory.createIdentifier("undefined")
);
}
- protected override named(typeName: DeclaredTypeName): (reference: ts.Expression) => ts.Expression {
+ protected override named(
+ typeName: DeclaredTypeName,
+ params: ConvertTypeReferenceParams
+ ): (reference: ts.Expression) => ts.Expression {
const resolvedType = this.typeResolver.resolveTypeName(typeName);
return ResolvedTypeReference._visit<(reference: ts.Expression) => ts.Expression>(resolvedType, {
container: (containerType) =>
ContainerType._visit(containerType, {
list: this.list.bind(this),
- optional: this.optional.bind(this),
+ optional: (optionalType) => this.optional(optionalType, params),
set: this.set.bind(this),
- map: this.map.bind(this),
+ map: (mapType) => this.map(mapType, params),
literal: this.literal.bind(this),
_other: () => {
throw new Error("Unknown ContainerType: " + containerType.type);
@@ -137,8 +143,11 @@ export class TypeReferenceToStringExpressionConverter extends AbstractTypeRefere
return (reference) => reference;
}
- protected override optional(itemType: TypeReference): (reference: ts.Expression) => ts.Expression {
- return (reference) => this.convert(itemType)(reference);
+ protected override optional(
+ itemType: TypeReference,
+ params: ConvertTypeReferenceParams
+ ): (reference: ts.Expression) => ts.Expression {
+ return (reference) => this.convert({ ...params, typeReference: itemType })(reference);
}
protected override unknown(): (reference: ts.Expression) => ts.Expression {
diff --git a/generators/typescript/model/type-reference-example-generator/package.json b/generators/typescript/model/type-reference-example-generator/package.json
index 9249695b5d0..bb2b78f0016 100644
--- a/generators/typescript/model/type-reference-example-generator/package.json
+++ b/generators/typescript/model/type-reference-example-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"ts-morph": "^15.1.0"
diff --git a/generators/typescript/model/type-reference-example-generator/src/GeneratedTypeReferenceExampleImpl.ts b/generators/typescript/model/type-reference-example-generator/src/GeneratedTypeReferenceExampleImpl.ts
index 3319b62b028..ae783aafa9b 100644
--- a/generators/typescript/model/type-reference-example-generator/src/GeneratedTypeReferenceExampleImpl.ts
+++ b/generators/typescript/model/type-reference-example-generator/src/GeneratedTypeReferenceExampleImpl.ts
@@ -6,7 +6,7 @@ import {
ExampleTypeReferenceShape
} from "@fern-fern/ir-sdk/api";
import { GetReferenceOpts } from "@fern-typescript/commons";
-import { GeneratedTypeReferenceExample, ModelContext } from "@fern-typescript/contexts";
+import { GeneratedTypeReferenceExample, BaseContext } from "@fern-typescript/contexts";
import { ts } from "ts-morph";
export declare namespace GeneratedTypeReferenceExampleImpl {
@@ -22,7 +22,7 @@ export class GeneratedTypeReferenceExampleImpl implements GeneratedTypeReference
this.example = example;
}
- public build(context: ModelContext, opts: GetReferenceOpts): ts.Expression {
+ public build(context: BaseContext, opts: GetReferenceOpts): ts.Expression {
return this.buildExample({ example: this.example, context, opts });
}
@@ -32,7 +32,7 @@ export class GeneratedTypeReferenceExampleImpl implements GeneratedTypeReference
opts
}: {
example: ExampleTypeReference;
- context: ModelContext;
+ context: BaseContext;
opts: GetReferenceOpts;
}): ts.Expression {
return ExampleTypeReferenceShape._visit(example.shape, {
@@ -164,7 +164,7 @@ export class GeneratedTypeReferenceExampleImpl implements GeneratedTypeReference
opts
}: {
example: ExampleTypeReference;
- context: ModelContext;
+ context: BaseContext;
opts: GetReferenceOpts;
}): ts.PropertyName {
return ExampleTypeReferenceShape._visit(example.shape, {
diff --git a/generators/typescript/model/type-schema-generator/package.json b/generators/typescript/model/type-schema-generator/package.json
index 5042bb162e0..b44d9777503 100644
--- a/generators/typescript/model/type-schema-generator/package.json
+++ b/generators/typescript/model/type-schema-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-schema-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/model/union-generator/package.json b/generators/typescript/model/union-generator/package.json
index 5d836bdadc8..74042f0e321 100644
--- a/generators/typescript/model/union-generator/package.json
+++ b/generators/typescript/model/union-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"ts-morph": "^15.1.0"
diff --git a/generators/typescript/model/union-generator/src/GeneratedUnionImpl.ts b/generators/typescript/model/union-generator/src/GeneratedUnionImpl.ts
index 2e3de6daa38..8f02e7436c2 100644
--- a/generators/typescript/model/union-generator/src/GeneratedUnionImpl.ts
+++ b/generators/typescript/model/union-generator/src/GeneratedUnionImpl.ts
@@ -3,17 +3,23 @@ import {
FernWriters,
getTextOfTsNode,
getWriterForMultiLineUnionType,
- maybeAddDocs,
+ maybeAddDocsStructure,
ObjectWriter,
Reference
} from "@fern-typescript/commons";
import { GeneratedUnion, ModelContext } from "@fern-typescript/contexts";
import {
InterfaceDeclarationStructure,
+ ModuleDeclarationStructure,
OptionalKind,
PropertySignatureStructure,
+ StatementStructures,
+ StructureKind,
ts,
- VariableDeclarationKind
+ TypeAliasDeclarationStructure,
+ VariableDeclarationKind,
+ VariableStatementStructure,
+ WriterFunction
} from "ts-morph";
import { KnownSingleUnionType } from "./known-single-union-type/KnownSingleUnionType";
import { ParsedSingleUnionType } from "./parsed-single-union-type/ParsedSingleUnionType";
@@ -36,6 +42,8 @@ export declare namespace GeneratedUnionImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
noOptionalProperties: boolean;
+ inline: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -64,6 +72,8 @@ export class GeneratedUnionImpl implements Generat
private retainOriginalCasing: boolean;
private includeConstBuilders: boolean;
private noOptionalProperties: boolean;
+ private inline: boolean;
+ private enableInlineTypes: boolean;
constructor({
typeName,
@@ -78,7 +88,9 @@ export class GeneratedUnionImpl implements Generat
baseProperties = [],
includeSerdeLayer,
retainOriginalCasing,
- noOptionalProperties
+ noOptionalProperties,
+ inline,
+ enableInlineTypes
}: GeneratedUnionImpl.Init) {
this.getReferenceToUnion = getReferenceToUnion;
this.discriminant = discriminant;
@@ -93,14 +105,35 @@ export class GeneratedUnionImpl implements Generat
this.retainOriginalCasing = retainOriginalCasing;
this.includeConstBuilders = includeConstBuilders;
this.noOptionalProperties = noOptionalProperties;
+ this.inline = inline;
+ this.enableInlineTypes = enableInlineTypes;
}
- public writeToFile(context: Context): void {
- this.writeTypeAlias(context);
- this.writeModule(context);
+ public generateStatements(
+ context: Context
+ ): string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const statements: (string | WriterFunction | StatementStructures)[] = [
+ this.generateTypeAlias(context),
+ this.generateModule(context)
+ ];
+
if (this.includeConstBuilders) {
- this.writeConst(context);
+ const consts = this.generateConst(context);
+ if (consts) {
+ statements.push(consts);
+ }
}
+ return statements;
+ }
+
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return ts.factory.createParenthesizedType(
+ ts.factory.createUnionTypeNode(
+ this.getAllSingleUnionTypesForAlias().map((singleUnionType) =>
+ singleUnionType.generateForInlineUnion(context, this)
+ )
+ )
+ );
}
public getReferenceTo(context: Context): ts.TypeNode {
@@ -234,8 +267,9 @@ export class GeneratedUnionImpl implements Generat
* TYPE ALIAS *
**************/
- private writeTypeAlias(context: Context): void {
- const typeAlias = context.sourceFile.addTypeAlias({
+ private generateTypeAlias(context: Context): TypeAliasDeclarationStructure {
+ const typeAlias: TypeAliasDeclarationStructure = {
+ kind: StructureKind.TypeAlias,
name: this.typeName,
type: getWriterForMultiLineUnionType(
this.getAllSingleUnionTypesForAlias().map((singleUnionType) => ({
@@ -244,16 +278,23 @@ export class GeneratedUnionImpl implements Generat
}))
),
isExported: true
- });
- if (this.getDocs != null) {
- maybeAddDocs(typeAlias, this.getDocs(context));
- }
+ };
+ maybeAddDocsStructure(typeAlias, this.getDocs?.(context));
+ return typeAlias;
}
public getReferenceToSingleUnionType(
singleUnionType: ParsedSingleUnionType,
context: Context
): ts.TypeNode {
+ if (this.enableInlineTypes && this.inline) {
+ return ts.factory.createTypeReferenceNode(
+ ts.factory.createQualifiedName(
+ ts.factory.createIdentifier(this.typeName),
+ singleUnionType.getInterfaceName()
+ )
+ );
+ }
return ts.factory.createTypeReferenceNode(
ts.factory.createQualifiedName(
this.getReferenceToUnion(context).getEntityName(),
@@ -266,25 +307,29 @@ export class GeneratedUnionImpl implements Generat
* MODULE *
**********/
- private writeModule(context: Context): void {
- const module = context.sourceFile.addModule({
+ private generateModule(context: Context): ModuleDeclarationStructure {
+ const module: ModuleDeclarationStructure = {
+ kind: StructureKind.Module,
name: this.typeName,
isExported: true,
- hasDeclareKeyword: true
- });
- module.addInterfaces(this.getSingleUnionTypeInterfaces(context));
+ hasDeclareKeyword: false
+ };
+ const statements = [...this.getSingleUnionTypeInterfaces(context)];
if (this.includeUtilsOnUnionMembers) {
- module.addInterface(this.getUtilsInterface(context));
+ statements.push(this.getUtilsInterface(context));
}
if (this.includeUtilsOnUnionMembers || this.includeConstBuilders) {
- module.addInterface(this.getVisitorInterface(context));
+ statements.push(this.getVisitorInterface(context));
}
if (this.hasBaseInterface()) {
- module.addInterface(this.getBaseInterface(context));
+ statements.push(this.getBaseInterface(context));
}
+ module.statements = statements;
+ return module;
}
- private getSingleUnionTypeInterfaces(context: Context): OptionalKind[] {
+ private getSingleUnionTypeInterfaces(context: Context): StatementStructures[] {
+ const statements: StatementStructures[] = [];
const interfaces = this.getAllSingleUnionTypesForAlias().map((singleUnionType) =>
singleUnionType.getInterfaceDeclaration(context, this)
);
@@ -298,15 +343,24 @@ export class GeneratedUnionImpl implements Generat
}
}
- return interfaces.map((interface_) => ({
- name: interface_.name,
- extends: interface_.extends.map(getTextOfTsNode),
- properties: interface_.jsonProperties
- }));
+ for (const interface_ of interfaces) {
+ statements.push({
+ kind: StructureKind.Interface,
+ name: interface_.name,
+ isExported: true,
+ extends: interface_.extends.map(getTextOfTsNode),
+ properties: interface_.properties
+ });
+ if (interface_.module) {
+ statements.push(interface_.module);
+ }
+ }
+ return statements;
}
- private getUtilsInterface(context: Context): OptionalKind {
+ private getUtilsInterface(context: Context): InterfaceDeclarationStructure {
return {
+ kind: StructureKind.Interface,
name: GeneratedUnionImpl.UTILS_INTERFACE_NAME,
properties: [
{
@@ -317,8 +371,9 @@ export class GeneratedUnionImpl implements Generat
};
}
- private getBaseInterface(context: Context): OptionalKind {
+ private getBaseInterface(context: Context): InterfaceDeclarationStructure {
return {
+ kind: StructureKind.Interface,
name: GeneratedUnionImpl.BASE_INTERFACE_NAME,
properties: this.baseProperties.map((property) => {
const type = context.type.getReferenceToType(property.valueType);
@@ -359,8 +414,9 @@ export class GeneratedUnionImpl implements Generat
);
}
- private getVisitorInterface(context: Context): OptionalKind {
+ private getVisitorInterface(context: Context): InterfaceDeclarationStructure {
return {
+ kind: StructureKind.Interface,
name: GeneratedUnionImpl.VISITOR_INTERFACE_NAME,
typeParameters: [
{
@@ -390,7 +446,7 @@ export class GeneratedUnionImpl implements Generat
* CONST *
*********/
- private writeConst(context: Context): void {
+ private generateConst(context: Context): VariableStatementStructure | undefined {
const writer = FernWriters.object.writer({ asConst: true });
this.addBuilderProperties(context, writer);
@@ -400,7 +456,8 @@ export class GeneratedUnionImpl implements Generat
return;
}
- context.sourceFile.addVariableStatement({
+ return {
+ kind: StructureKind.VariableStatement,
declarationKind: VariableDeclarationKind.Const,
declarations: [
{
@@ -409,7 +466,7 @@ export class GeneratedUnionImpl implements Generat
}
],
isExported: true
- });
+ };
}
private addBuilderProperties(context: Context, writer: ObjectWriter) {
diff --git a/generators/typescript/model/union-generator/src/parsed-single-union-type/AbstractParsedSingleUnionType.ts b/generators/typescript/model/union-generator/src/parsed-single-union-type/AbstractParsedSingleUnionType.ts
index a376e7ec874..45a77a93ef3 100644
--- a/generators/typescript/model/union-generator/src/parsed-single-union-type/AbstractParsedSingleUnionType.ts
+++ b/generators/typescript/model/union-generator/src/parsed-single-union-type/AbstractParsedSingleUnionType.ts
@@ -32,16 +32,22 @@ export abstract class AbstractParsedSingleUnionType): ts.TypeNode {
+ return this.singleUnionType.generateForInlineUnion(context);
+ }
+
public getBuilder(context: Context, generatedUnion: GeneratedUnionImpl): ts.ArrowFunction {
const referenceToBuiltType = generatedUnion.getReferenceToSingleUnionType(this, context);
diff --git a/generators/typescript/model/union-generator/src/parsed-single-union-type/ParsedSingleUnionType.ts b/generators/typescript/model/union-generator/src/parsed-single-union-type/ParsedSingleUnionType.ts
index 2445a287572..bc6c380516d 100644
--- a/generators/typescript/model/union-generator/src/parsed-single-union-type/ParsedSingleUnionType.ts
+++ b/generators/typescript/model/union-generator/src/parsed-single-union-type/ParsedSingleUnionType.ts
@@ -1,5 +1,5 @@
import { ModelContext } from "@fern-typescript/contexts";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
import { GeneratedUnionImpl } from "../GeneratedUnionImpl";
export interface ParsedSingleUnionType {
@@ -13,6 +13,7 @@ export interface ParsedSingleUnionType {
context: Context,
generatedUnion: GeneratedUnionImpl
): ParsedSingleUnionType.InterfaceDeclaration;
+ generateForInlineUnion(context: Context, generatedUnion: GeneratedUnionImpl): ts.TypeNode;
getBuilder(context: Context, generatedUnion: GeneratedUnionImpl): ts.ArrowFunction;
getBuilderName(): string;
getBuilderArgsFromExistingValue(existingValue: ts.Expression): ts.Expression[];
@@ -29,6 +30,7 @@ export declare namespace ParsedSingleUnionType {
export interface InterfaceDeclaration {
name: string;
extends: ts.TypeNode[];
- jsonProperties: OptionalKind[];
+ properties: OptionalKind[];
+ module: ModuleDeclarationStructure | undefined;
}
}
diff --git a/generators/typescript/model/union-generator/src/single-union-type-generator/SingleUnionTypeGenerator.ts b/generators/typescript/model/union-generator/src/single-union-type-generator/SingleUnionTypeGenerator.ts
index feacc726caf..94c17b8ebbb 100644
--- a/generators/typescript/model/union-generator/src/single-union-type-generator/SingleUnionTypeGenerator.ts
+++ b/generators/typescript/model/union-generator/src/single-union-type-generator/SingleUnionTypeGenerator.ts
@@ -1,6 +1,9 @@
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
export interface SingleUnionTypeGenerator {
+ generateForInlineUnion(context: Context): ts.TypeNode;
+ getDiscriminantPropertiesForInterface(context: Context): OptionalKind[];
+ generateModule(context: Context): ModuleDeclarationStructure | undefined;
getExtendsForInterface(context: Context): ts.TypeNode[];
getNonDiscriminantPropertiesForInterface(context: Context): OptionalKind[];
getVisitorArguments(args: { localReferenceToUnionValue: ts.Expression }): ts.Expression[];
diff --git a/generators/typescript/model/union-generator/src/single-union-type-generator/common/NoPropertiesSingleUnionTypeGenerator.ts b/generators/typescript/model/union-generator/src/single-union-type-generator/common/NoPropertiesSingleUnionTypeGenerator.ts
index 57289922414..4c54e02ad50 100644
--- a/generators/typescript/model/union-generator/src/single-union-type-generator/common/NoPropertiesSingleUnionTypeGenerator.ts
+++ b/generators/typescript/model/union-generator/src/single-union-type-generator/common/NoPropertiesSingleUnionTypeGenerator.ts
@@ -1,11 +1,23 @@
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
import { SingleUnionTypeGenerator } from "../SingleUnionTypeGenerator";
export class NoPropertiesSingleUnionTypeGenerator implements SingleUnionTypeGenerator {
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ return ts.factory.createTypeLiteralNode([]);
+ }
+
public getExtendsForInterface(): ts.TypeNode[] {
return [];
}
+ public getDiscriminantPropertiesForInterface(context: Context): OptionalKind[] {
+ return [];
+ }
+
+ public generateModule(context: Context): ModuleDeclarationStructure | undefined {
+ return undefined;
+ }
+
public getNonDiscriminantPropertiesForInterface(): OptionalKind[] {
return [];
}
diff --git a/generators/typescript/model/union-generator/src/single-union-type-generator/common/SinglePropertySingleUnionTypeGenerator.ts b/generators/typescript/model/union-generator/src/single-union-type-generator/common/SinglePropertySingleUnionTypeGenerator.ts
index ebe4c29e57a..2ed14dec8e2 100644
--- a/generators/typescript/model/union-generator/src/single-union-type-generator/common/SinglePropertySingleUnionTypeGenerator.ts
+++ b/generators/typescript/model/union-generator/src/single-union-type-generator/common/SinglePropertySingleUnionTypeGenerator.ts
@@ -1,36 +1,67 @@
+import { assertNever } from "@fern-api/core-utils";
+import { NamedType, ObjectProperty, SingleUnionTypeProperty, TypeReference } from "@fern-fern/ir-sdk/api";
import { getTextOfTsNode, TypeReferenceNode } from "@fern-typescript/commons";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModelContext } from "@fern-typescript/contexts";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
import { SingleUnionTypeGenerator } from "../SingleUnionTypeGenerator";
export declare namespace SinglePropertySingleUnionTypeGenerator {
export interface Init {
propertyName: string;
getReferenceToPropertyType: (context: Context) => TypeReferenceNode;
+ getReferenceToPropertyTypeForInlineUnion: (context: Context) => TypeReferenceNode;
noOptionalProperties: boolean;
+ enableInlineTypes: boolean;
}
}
-export class SinglePropertySingleUnionTypeGenerator implements SingleUnionTypeGenerator {
+export class SinglePropertySingleUnionTypeGenerator
+ implements SingleUnionTypeGenerator
+{
private static BUILDER_PARAMETER_NAME = "value";
private propertyName: string;
private getReferenceToPropertyType: (context: Context) => TypeReferenceNode;
+ private getReferenceToPropertyTypeForInlineUnion: (context: Context) => TypeReferenceNode;
private noOptionalProperties: boolean;
constructor({
propertyName,
getReferenceToPropertyType,
+ getReferenceToPropertyTypeForInlineUnion,
noOptionalProperties
}: SinglePropertySingleUnionTypeGenerator.Init) {
this.propertyName = propertyName;
this.getReferenceToPropertyType = getReferenceToPropertyType;
+ this.getReferenceToPropertyTypeForInlineUnion = getReferenceToPropertyTypeForInlineUnion;
this.noOptionalProperties = noOptionalProperties;
}
+ public generateForInlineUnion(context: Context): ts.TypeNode {
+ const typeReference = this.getReferenceToPropertyTypeForInlineUnion(context);
+ const hasOptionalToken = !this.noOptionalProperties && typeReference.isOptional;
+ return ts.factory.createTypeLiteralNode([
+ ts.factory.createPropertySignature(
+ undefined,
+ this.propertyName,
+ hasOptionalToken ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : undefined,
+ this.noOptionalProperties ? typeReference.typeNode : typeReference.typeNodeWithoutUndefined
+ )
+ ]);
+ }
+
public getExtendsForInterface(): ts.TypeNode[] {
return [];
}
+ public getDiscriminantPropertiesForInterface(context: Context): OptionalKind[] {
+ return [];
+ }
+
+ public generateModule(context: Context): ModuleDeclarationStructure | undefined {
+ return undefined;
+ }
+
public getNonDiscriminantPropertiesForInterface(context: Context): OptionalKind[] {
const type = this.getReferenceToPropertyType(context);
return [
diff --git a/generators/typescript/model/union-schema-generator/package.json b/generators/typescript/model/union-schema-generator/package.json
index 74dfc158309..ee09125bf07 100644
--- a/generators/typescript/model/union-schema-generator/package.json
+++ b/generators/typescript/model/union-schema-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-schema-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/CHANGELOG.md b/generators/typescript/sdk/CHANGELOG.md
index 7f363a08e37..5b7cc0f5cd1 100644
--- a/generators/typescript/sdk/CHANGELOG.md
+++ b/generators/typescript/sdk/CHANGELOG.md
@@ -5,15 +5,73 @@ 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).
+## [0.43.0] - 2024-12-11
+
+- Feature: Generate inline types for inline schemas by setting `enableInlineTypes` to `true` in the generator config.
+ When enabled, the inline schemas will be generated as nested types in TypeScript.
+ This results in cleaner type names and a more intuitive developer experience.
+
+ Before:
+
+ ```ts
+ // MyRootType.ts
+ import * as MySdk from "...";
+
+ export interface MyRootType {
+ foo: MySdk.MyRootTypeFoo;
+ }
+
+ // MyRootTypeFoo.ts
+ import * as MySdk from "...";
+
+ export interface MyRootTypeFoo {
+ bar: MySdk.MyRootTypeFooBar;
+ }
+
+ // MyRootTypeFooBar.ts
+ import * as MySdk from "...";
+
+ export interface MyRootTypeFooBar {}
+ ```
+
+ After:
+
+ ```ts
+ // MyRootType.ts
+ import * as MySdk from "...";
+
+ export interface MyRootType {
+ foo: MyRootType.Foo;
+ }
+
+ export namespace MyRootType {
+ export interface Foo {
+ bar: Foo.Bar;
+ }
+
+ export namespace Foo {
+ export interface Bar {}
+ }
+ }
+ ```
+
+ Now users can get the deep nested `Bar` type as follows:
+
+ ```ts
+ import { MyRootType } from MySdk;
+
+ const bar: MyRootType.Foo.Bar = {};
+ ```
+
## [0.42.7] - 2024-12-03
-- Feature: Support `additionalProperties` in OpenAPI or `extra-properties` in the Fern Defnition. Now
- an object that has additionalProperties marked as true will generate the following interface:
+- Feature: Support `additionalProperties` in OpenAPI or `extra-properties` in the Fern Defnition. Now
+ an object that has additionalProperties marked as true will generate the following interface:
```ts
interface User {
- propertyOne: string
- [key: string]: any
+ propertyOne: string;
+ [key: string]: any;
}
```
diff --git a/generators/typescript/sdk/VERSION b/generators/typescript/sdk/VERSION
index 6028e3fe54d..8298bb08b2d 100644
--- a/generators/typescript/sdk/VERSION
+++ b/generators/typescript/sdk/VERSION
@@ -1 +1 @@
-0.42.7
+0.43.0
diff --git a/generators/typescript/sdk/cli/package.json b/generators/typescript/sdk/cli/package.json
index 22ae8a4290b..f730baa59db 100644
--- a/generators/typescript/sdk/cli/package.json
+++ b/generators/typescript/sdk/cli/package.json
@@ -35,7 +35,7 @@
"devDependencies": {
"@fern-api/fs-utils": "workspace:*",
"@fern-api/base-generator": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-generator-cli": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/cli/src/SdkGeneratorCli.ts b/generators/typescript/sdk/cli/src/SdkGeneratorCli.ts
index 6d9c4510e45..1356425e8df 100644
--- a/generators/typescript/sdk/cli/src/SdkGeneratorCli.ts
+++ b/generators/typescript/sdk/cli/src/SdkGeneratorCli.ts
@@ -54,6 +54,7 @@ export class SdkGeneratorCli extends AbstractGeneratorCli {
retainOriginalCasing: parsed?.retainOriginalCasing ?? false,
allowExtraFields: parsed?.allowExtraFields ?? false,
inlineFileProperties: parsed?.inlineFileProperties ?? false,
+ enableInlineTypes: parsed?.enableInlineTypes ?? false,
packageJson: parsed?.packageJson,
publishToJsr: parsed?.publishToJsr ?? false,
omitUndefined: parsed?.omitUndefined ?? false,
@@ -135,7 +136,8 @@ export class SdkGeneratorCli extends AbstractGeneratorCli {
packageJson: customConfig.packageJson,
outputJsr: customConfig.publishToJsr ?? false,
omitUndefined: customConfig.omitUndefined ?? false,
- useBigInt: customConfig.useBigInt ?? false
+ useBigInt: customConfig.useBigInt ?? false,
+ enableInlineTypes: customConfig.enableInlineTypes ?? false
}
});
const typescriptProject = await sdkGenerator.generate();
diff --git a/generators/typescript/sdk/cli/src/custom-config/SdkCustomConfig.ts b/generators/typescript/sdk/cli/src/custom-config/SdkCustomConfig.ts
index 0752a2cc3a8..81d6e6faed5 100644
--- a/generators/typescript/sdk/cli/src/custom-config/SdkCustomConfig.ts
+++ b/generators/typescript/sdk/cli/src/custom-config/SdkCustomConfig.ts
@@ -28,6 +28,7 @@ export interface SdkCustomConfig {
retainOriginalCasing: boolean | undefined;
allowExtraFields: boolean | undefined;
inlineFileProperties: boolean | undefined;
+ enableInlineTypes: boolean | undefined;
packageJson: Record | undefined;
publishToJsr: boolean | undefined;
omitUndefined: boolean | undefined;
diff --git a/generators/typescript/sdk/cli/src/custom-config/schema/SdkCustomConfigSchema.ts b/generators/typescript/sdk/cli/src/custom-config/schema/SdkCustomConfigSchema.ts
index 0f02543b4cf..21915edec84 100644
--- a/generators/typescript/sdk/cli/src/custom-config/schema/SdkCustomConfigSchema.ts
+++ b/generators/typescript/sdk/cli/src/custom-config/schema/SdkCustomConfigSchema.ts
@@ -33,6 +33,7 @@ export const SdkCustomConfigSchema = z.strictObject({
retainOriginalCasing: z.optional(z.boolean()),
allowExtraFields: z.optional(z.boolean()),
inlineFileProperties: z.optional(z.boolean()),
+ enableInlineTypes: z.optional(z.boolean()),
generateWireTests: z.optional(z.boolean()),
noScripts: z.optional(z.boolean()),
diff --git a/generators/typescript/sdk/client-class-generator/package.json b/generators/typescript/sdk/client-class-generator/package.json
index b3c5d25577d..52afab49d26 100644
--- a/generators/typescript/sdk/client-class-generator/package.json
+++ b/generators/typescript/sdk/client-class-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"@fern-typescript/resolvers": "workspace:*",
diff --git a/generators/typescript/sdk/client-class-generator/src/GeneratedSdkClientClassImpl.ts b/generators/typescript/sdk/client-class-generator/src/GeneratedSdkClientClassImpl.ts
index 06e33d31718..22923cff469 100644
--- a/generators/typescript/sdk/client-class-generator/src/GeneratedSdkClientClassImpl.ts
+++ b/generators/typescript/sdk/client-class-generator/src/GeneratedSdkClientClassImpl.ts
@@ -1,4 +1,4 @@
-import { assertNever } from "@fern-api/core-utils";
+import { assertNever, SetRequired } from "@fern-api/core-utils";
import {
AuthScheme,
BasicAuthScheme,
@@ -19,13 +19,24 @@ import {
getTextOfTsNode,
ImportsManager,
JavaScriptRuntime,
- maybeAddDocs,
+ maybeAddDocsStructure,
NpmPackage,
PackageId
} from "@fern-typescript/commons";
import { GeneratedEndpointImplementation, GeneratedSdkClientClass, SdkContext } from "@fern-typescript/contexts";
import { ErrorResolver, PackageResolver } from "@fern-typescript/resolvers";
-import { InterfaceDeclarationStructure, OptionalKind, PropertySignatureStructure, Scope, ts } from "ts-morph";
+import {
+ ClassDeclarationStructure,
+ InterfaceDeclarationStructure,
+ MethodDeclarationStructure,
+ ModuleDeclarationStructure,
+ OptionalKind,
+ PropertyDeclarationStructure,
+ PropertySignatureStructure,
+ Scope,
+ StructureKind,
+ ts
+} from "ts-morph";
import { code } from "ts-poet";
import { GeneratedBytesEndpointRequest } from "./endpoint-request/GeneratedBytesEndpointRequest";
import { GeneratedDefaultEndpointRequest } from "./endpoint-request/GeneratedDefaultEndpointRequest";
@@ -425,23 +436,34 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
}
public writeToFile(context: SdkContext): void {
- const serviceModule = context.sourceFile.addModule({
+ const serviceModule: ModuleDeclarationStructure = {
+ kind: StructureKind.Module,
name: this.serviceClassName,
isExported: true,
hasDeclareKeyword: true
- });
+ };
- const optionsInterface = serviceModule.addInterface(this.generateOptionsInterface(context));
- serviceModule.addInterface(this.generateRequestOptionsInterface(context));
+ const optionsInterface = this.generateOptionsInterface(context);
+ serviceModule.statements = [optionsInterface, this.generateRequestOptionsInterface(context)];
+ context.sourceFile.addModule(serviceModule);
- const serviceClass = context.sourceFile.addClass({
+ const serviceClass: SetRequired<
+ ClassDeclarationStructure,
+ "properties" | "ctors" | "methods" | "getAccessors"
+ > = {
+ kind: StructureKind.Class,
name: this.serviceClassName,
- isExported: true
- });
- maybeAddDocs(serviceClass, this.package_.docs);
+ isExported: true,
+ properties: [],
+ getAccessors: [],
+ ctors: [],
+ methods: []
+ };
+ maybeAddDocsStructure(serviceClass, this.package_.docs);
if (this.isRoot && context.generateOAuthClients) {
- serviceClass.addProperty({
+ serviceClass.properties.push({
+ kind: StructureKind.Property,
name: OAuthTokenProviderGenerator.OAUTH_TOKEN_PROVIDER_PROPERTY_NAME,
type: getTextOfTsNode(context.coreUtilities.auth.OAuthTokenProvider._getReferenceToType()),
scope: Scope.Private,
@@ -509,8 +531,8 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
type: getTextOfTsNode(
ts.factory.createTypeReferenceNode(
ts.factory.createQualifiedName(
- ts.factory.createIdentifier(serviceModule.getName()),
- ts.factory.createIdentifier(optionsInterface.getName())
+ ts.factory.createIdentifier(serviceModule.name),
+ ts.factory.createIdentifier(optionsInterface.name)
)
)
)
@@ -567,12 +589,12 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
}),
});
`;
- serviceClass.addConstructor({
+ serviceClass.ctors.push({
parameters,
statements: statements.toString({ dprintOptions: { indentWidth: 4 } })
});
} else {
- serviceClass.addConstructor({
+ serviceClass.ctors.push({
parameters: [
{
name: GeneratedSdkClientClassImpl.OPTIONS_PRIVATE_MEMBER,
@@ -581,12 +603,12 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
type: getTextOfTsNode(
ts.factory.createTypeReferenceNode(
ts.factory.createQualifiedName(
- ts.factory.createIdentifier(serviceModule.getName()),
- ts.factory.createIdentifier(optionsInterface.getName())
+ ts.factory.createIdentifier(serviceModule.name),
+ ts.factory.createIdentifier(optionsInterface.name)
)
)
),
- initializer: optionsInterface.getProperties().every((property) => property.hasQuestionToken())
+ initializer: optionsInterface.properties?.every((property) => property.hasQuestionToken)
? "{}"
: undefined
}
@@ -608,7 +630,8 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
const statements = endpoint.getStatements(context);
// const returnsAPIPromise = !context.neverThrowErrors && !endpoint.isPaginated(context);
- const method = serviceClass.addMethod({
+ const method: MethodDeclarationStructure = {
+ kind: StructureKind.Method,
name: endpoint.endpoint.name.camelCase.unsafeName,
parameters: signature.parameters,
returnType: getTextOfTsNode(
@@ -624,15 +647,16 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
ts.factory.createTypeReferenceNode("Promise", [overload.returnTypeWithoutPromise])
)
}))
- });
+ };
+ serviceClass.methods.push(method);
if (overloads.length === 0) {
- maybeAddDocs(method, docs);
+ maybeAddDocsStructure(method, docs);
}
}
if (isIdempotent) {
- serviceModule.addInterface(this.generateIdempotentRequestOptionsInterface(context));
+ serviceModule.statements.push(this.generateIdempotentRequestOptionsInterface(context));
}
for (const wrappedService of this.generatedWrappedServices) {
@@ -657,7 +681,7 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
]);
- serviceClass.addMethod({
+ serviceClass.methods.push({
scope: Scope.Protected,
isAsync: true,
name: GeneratedSdkClientClassImpl.AUTHORIZATION_HEADER_HELPER_METHOD_NAME,
@@ -667,13 +691,15 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
}
if (this.shouldGenerateCustomAuthorizationHeaderHelperMethod()) {
- serviceClass.addMethod({
+ serviceClass.methods.push({
scope: Scope.Protected,
isAsync: true,
name: GeneratedSdkClientClassImpl.CUSTOM_AUTHORIZATION_HEADER_HELPER_METHOD_NAME,
statements: this.getCustomAuthorizationHeaderStatements(context).map(getTextOfTsNode)
});
}
+
+ context.sourceFile.addClass(serviceClass);
}
private shouldGenerateAuthorizationHeaderHelperMethod(): boolean {
@@ -932,8 +958,9 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
: `${this.serviceClassName}.${GeneratedSdkClientClassImpl.REQUEST_OPTIONS_INTERFACE_NAME}`;
}
- private generateRequestOptionsInterface(context: SdkContext): OptionalKind {
- const requestOptions = {
+ private generateRequestOptionsInterface(context: SdkContext): InterfaceDeclarationStructure {
+ const requestOptions: SetRequired = {
+ kind: StructureKind.Interface,
name: GeneratedSdkClientClassImpl.REQUEST_OPTIONS_INTERFACE_NAME,
properties: [
{
@@ -988,9 +1015,7 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
* IDEMPOTENT REQUEST OPTIONS *
******************************/
- private generateIdempotentRequestOptionsInterface(
- context: SdkContext
- ): OptionalKind {
+ private generateIdempotentRequestOptionsInterface(context: SdkContext): InterfaceDeclarationStructure {
const properties: OptionalKind[] = [];
for (const header of this.intermediateRepresentation.idempotencyHeaders) {
if (!isLiteralHeader(header, context)) {
@@ -1003,6 +1028,7 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
}
}
return {
+ kind: StructureKind.Interface,
name: GeneratedSdkClientClassImpl.IDEMPOTENT_REQUEST_OPTIONS_INTERFACE_NAME,
extends: [GeneratedSdkClientClassImpl.REQUEST_OPTIONS_INTERFACE_NAME],
properties
@@ -1107,7 +1133,7 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
return properties;
}
- private generateOptionsInterface(context: SdkContext): OptionalKind {
+ private generateOptionsInterface(context: SdkContext): InterfaceDeclarationStructure {
const properties: OptionalKind[] = [];
if (!this.requireDefaultEnvironment) {
@@ -1304,6 +1330,7 @@ export class GeneratedSdkClientClassImpl implements GeneratedSdkClientClass {
}
return {
+ kind: StructureKind.Interface,
name: GeneratedSdkClientClassImpl.OPTIONS_INTERFACE_NAME,
properties
};
diff --git a/generators/typescript/sdk/client-class-generator/src/GeneratedWrappedService.ts b/generators/typescript/sdk/client-class-generator/src/GeneratedWrappedService.ts
index a8d49851de1..3b75ce4aa79 100644
--- a/generators/typescript/sdk/client-class-generator/src/GeneratedWrappedService.ts
+++ b/generators/typescript/sdk/client-class-generator/src/GeneratedWrappedService.ts
@@ -1,7 +1,8 @@
import { Subpackage, SubpackageId } from "@fern-fern/ir-sdk/api";
import { getTextOfTsNode, Reference } from "@fern-typescript/commons";
+import { SetRequired } from "@fern-api/core-utils";
import { SdkContext } from "@fern-typescript/contexts";
-import { ClassDeclaration, Scope, ts } from "ts-morph";
+import { ClassDeclarationStructure, Scope, ts } from "ts-morph";
import { GeneratedSdkClientClassImpl } from "./GeneratedSdkClientClassImpl";
import { OAuthTokenProviderGenerator } from "./oauth-generator/OAuthTokenProviderGenerator";
@@ -30,7 +31,7 @@ export class GeneratedWrappedService {
context
}: {
isRoot: boolean;
- class_: ClassDeclaration;
+ class_: SetRequired;
context: SdkContext;
}): void {
const referenceToWrapped = this.getReferenceToWrappedService(class_, context);
@@ -39,7 +40,7 @@ export class GeneratedWrappedService {
subpackageId: this.wrappedSubpackageId
});
- class_.addProperty({
+ class_.properties.push({
name: this.getCachedMemberName(),
scope: Scope.Protected,
type: getTextOfTsNode(
@@ -51,7 +52,7 @@ export class GeneratedWrappedService {
});
if (isRoot && context.generateOAuthClients) {
- class_.addGetAccessor({
+ class_.getAccessors.push({
name: this.getGetterName(),
returnType: getTextOfTsNode(referenceToWrapped.getTypeNode()),
scope: Scope.Public,
@@ -112,7 +113,7 @@ export class GeneratedWrappedService {
});
return;
}
- class_.addGetAccessor({
+ class_.getAccessors.push({
name: this.getGetterName(),
returnType: getTextOfTsNode(referenceToWrapped.getTypeNode()),
scope: Scope.Public,
@@ -151,7 +152,10 @@ export class GeneratedWrappedService {
return lastFernFilepathPart.camelCase.unsafeName;
}
- private getReferenceToWrappedService(serviceClass: ClassDeclaration, context: SdkContext): Reference {
+ private getReferenceToWrappedService(
+ serviceClass: SetRequired,
+ context: SdkContext
+ ): Reference {
const reference = context.sdkClientClass.getReferenceToClientClass({
isRoot: false,
subpackageId: this.wrappedSubpackageId
@@ -163,7 +167,7 @@ export class GeneratedWrappedService {
})
);
- if (wrappedServiceClassName !== serviceClass.getName()) {
+ if (wrappedServiceClassName !== serviceClass.name) {
return reference;
} else {
return context.sdkClientClass.getReferenceToClientClass(
diff --git a/generators/typescript/sdk/endpoint-error-union-generator/package.json b/generators/typescript/sdk/endpoint-error-union-generator/package.json
index 78c69f89171..75a75dccf9e 100644
--- a/generators/typescript/sdk/endpoint-error-union-generator/package.json
+++ b/generators/typescript/sdk/endpoint-error-union-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"@fern-typescript/resolvers": "workspace:*",
diff --git a/generators/typescript/sdk/endpoint-error-union-generator/src/EndpointErrorUnionGenerator.ts b/generators/typescript/sdk/endpoint-error-union-generator/src/EndpointErrorUnionGenerator.ts
index 33ffffc072a..7f20e8286d9 100644
--- a/generators/typescript/sdk/endpoint-error-union-generator/src/EndpointErrorUnionGenerator.ts
+++ b/generators/typescript/sdk/endpoint-error-union-generator/src/EndpointErrorUnionGenerator.ts
@@ -11,6 +11,7 @@ export declare namespace EndpointErrorUnionGenerator {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
noOptionalProperties: boolean;
+ enableInlineTypes: boolean;
}
export namespace generateEndpointErrorUnion {
@@ -27,19 +28,22 @@ export class EndpointErrorUnionGenerator {
private includeSerdeLayer: boolean;
private retainOriginalCasing: boolean;
private noOptionalProperties: boolean;
+ private enableInlineTypes: boolean;
constructor({
intermediateRepresentation,
errorResolver,
includeSerdeLayer,
retainOriginalCasing,
- noOptionalProperties
+ noOptionalProperties,
+ enableInlineTypes
}: EndpointErrorUnionGenerator.Init) {
this.intermediateRepresentation = intermediateRepresentation;
this.errorResolver = errorResolver;
this.includeSerdeLayer = includeSerdeLayer;
this.retainOriginalCasing = retainOriginalCasing;
this.noOptionalProperties = noOptionalProperties;
+ this.enableInlineTypes = enableInlineTypes;
}
public generateEndpointErrorUnion({
@@ -53,7 +57,8 @@ export class EndpointErrorUnionGenerator {
errorDiscriminationStrategy: this.intermediateRepresentation.errorDiscriminationStrategy,
includeSerdeLayer: this.includeSerdeLayer,
retainOriginalCasing: this.retainOriginalCasing,
- noOptionalProperties: this.noOptionalProperties
+ noOptionalProperties: this.noOptionalProperties,
+ enableInlineTypes: this.enableInlineTypes
});
}
}
diff --git a/generators/typescript/sdk/endpoint-error-union-generator/src/GeneratedEndpointErrorUnionImpl.ts b/generators/typescript/sdk/endpoint-error-union-generator/src/GeneratedEndpointErrorUnionImpl.ts
index aebb8f7d7b7..b8b173c9415 100644
--- a/generators/typescript/sdk/endpoint-error-union-generator/src/GeneratedEndpointErrorUnionImpl.ts
+++ b/generators/typescript/sdk/endpoint-error-union-generator/src/GeneratedEndpointErrorUnionImpl.ts
@@ -16,6 +16,7 @@ export declare namespace GeneratedEndpointErrorUnionImpl {
includeSerdeLayer: boolean;
noOptionalProperties: boolean;
retainOriginalCasing: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -33,7 +34,8 @@ export class GeneratedEndpointErrorUnionImpl implements GeneratedEndpointErrorUn
errorDiscriminationStrategy,
includeSerdeLayer,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}: GeneratedEndpointErrorUnionImpl.Init) {
this.endpoint = endpoint;
@@ -57,7 +59,8 @@ export class GeneratedEndpointErrorUnionImpl implements GeneratedEndpointErrorUn
errorDiscriminationStrategy,
includeUtilsOnUnionMembers,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
})
),
getReferenceToUnion: (context) =>
@@ -73,7 +76,10 @@ export class GeneratedEndpointErrorUnionImpl implements GeneratedEndpointErrorUn
includeOtherInUnionTypes: true,
includeSerdeLayer,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes,
+ // generate separate root types for errors in union
+ inline: false
});
}
@@ -95,7 +101,7 @@ export class GeneratedEndpointErrorUnionImpl implements GeneratedEndpointErrorUn
}
public writeToFile(context: SdkContext): void {
- this.errorUnion.writeToFile(context);
+ context.sourceFile.addStatements(this.errorUnion.generateStatements(context));
}
public getErrorUnion(): GeneratedUnion {
diff --git a/generators/typescript/sdk/endpoint-error-union-generator/src/error/ParsedSingleUnionTypeForError.ts b/generators/typescript/sdk/endpoint-error-union-generator/src/error/ParsedSingleUnionTypeForError.ts
index eebf8449cad..c1a23e6cc40 100644
--- a/generators/typescript/sdk/endpoint-error-union-generator/src/error/ParsedSingleUnionTypeForError.ts
+++ b/generators/typescript/sdk/endpoint-error-union-generator/src/error/ParsedSingleUnionTypeForError.ts
@@ -16,6 +16,7 @@ export declare namespace ParsedSingleUnionTypeForError {
includeUtilsOnUnionMembers: boolean;
noOptionalProperties: boolean;
retainOriginalCasing: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -31,7 +32,8 @@ export class ParsedSingleUnionTypeForError extends AbstractKnownSingleUnionType<
errorResolver,
includeUtilsOnUnionMembers,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}: ParsedSingleUnionTypeForError.Init) {
const errorDeclaration = errorResolver.getErrorDeclarationFromName(error.error);
super({
@@ -39,7 +41,8 @@ export class ParsedSingleUnionTypeForError extends AbstractKnownSingleUnionType<
errorDiscriminationStrategy,
errorDeclaration,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}),
includeUtilsOnUnionMembers
});
@@ -87,12 +90,14 @@ function getSingleUnionTypeGenerator({
errorDiscriminationStrategy,
errorDeclaration,
noOptionalProperties,
- retainOriginalCasing
+ retainOriginalCasing,
+ enableInlineTypes
}: {
errorDiscriminationStrategy: ErrorDiscriminationStrategy;
errorDeclaration: ErrorDeclaration;
noOptionalProperties: boolean;
retainOriginalCasing: boolean;
+ enableInlineTypes: boolean;
}): SingleUnionTypeGenerator {
if (errorDeclaration.type == null) {
return new NoPropertiesSingleUnionTypeGenerator();
@@ -111,6 +116,8 @@ function getSingleUnionTypeGenerator({
return new SinglePropertySingleUnionTypeGenerator({
propertyName,
getReferenceToPropertyType: (context) => context.type.getReferenceToType(type),
- noOptionalProperties
+ getReferenceToPropertyTypeForInlineUnion: (context) => context.type.getReferenceToTypeForInlineUnion(type),
+ noOptionalProperties,
+ enableInlineTypes
});
}
diff --git a/generators/typescript/sdk/endpoint-error-union-generator/src/error/UnknownErrorSingleUnionTypeGenerator.ts b/generators/typescript/sdk/endpoint-error-union-generator/src/error/UnknownErrorSingleUnionTypeGenerator.ts
index c71c1cba103..9e5ccc5538d 100644
--- a/generators/typescript/sdk/endpoint-error-union-generator/src/error/UnknownErrorSingleUnionTypeGenerator.ts
+++ b/generators/typescript/sdk/endpoint-error-union-generator/src/error/UnknownErrorSingleUnionTypeGenerator.ts
@@ -1,7 +1,7 @@
import { getTextOfTsNode } from "@fern-typescript/commons";
import { SdkContext } from "@fern-typescript/contexts";
import { SingleUnionTypeGenerator } from "@fern-typescript/union-generator";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import { ModuleDeclarationStructure, OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
export declare namespace UnknownErrorSingleUnionTypeGenerator {
export interface Init {
@@ -19,10 +19,29 @@ export class UnknownErrorSingleUnionTypeGenerator implements SingleUnionTypeGene
this.discriminant = discriminant;
}
+ public generateForInlineUnion(context: SdkContext): ts.TypeNode {
+ return ts.factory.createTypeLiteralNode([
+ ts.factory.createPropertySignature(
+ undefined,
+ UnknownErrorSingleUnionTypeGenerator.CONTENT_PROPERTY_NAME,
+ undefined,
+ context.coreUtilities.fetcher.Fetcher.Error._getReferenceToType()
+ )
+ ]);
+ }
+
public getExtendsForInterface(): ts.TypeNode[] {
return [];
}
+ public getDiscriminantPropertiesForInterface(): OptionalKind[] {
+ return [];
+ }
+
+ public generateModule(): ModuleDeclarationStructure | undefined {
+ return undefined;
+ }
+
public getNonDiscriminantPropertiesForInterface(context: SdkContext): OptionalKind[] {
return [
{
diff --git a/generators/typescript/sdk/environments-generator/package.json b/generators/typescript/sdk/environments-generator/package.json
index eab64d97613..658ecfc5e0a 100644
--- a/generators/typescript/sdk/environments-generator/package.json
+++ b/generators/typescript/sdk/environments-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"ts-morph": "^15.1.0"
diff --git a/generators/typescript/sdk/generator/package.json b/generators/typescript/sdk/generator/package.json
index 9fa358cc545..99c86f0016d 100644
--- a/generators/typescript/sdk/generator/package.json
+++ b/generators/typescript/sdk/generator/package.json
@@ -34,7 +34,7 @@
"@fern-api/logger": "workspace:*",
"@fern-fern/generator-cli-sdk": "0.0.17",
"@fern-fern/generator-exec-sdk": "^0.0.898",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-fern/snippet-sdk": "^0.0.5526",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/generator/src/SdkGenerator.ts b/generators/typescript/sdk/generator/src/SdkGenerator.ts
index bed1ab1ff30..2a2efd7df7a 100644
--- a/generators/typescript/sdk/generator/src/SdkGenerator.ts
+++ b/generators/typescript/sdk/generator/src/SdkGenerator.ts
@@ -7,7 +7,9 @@ import {
HttpEndpoint,
HttpService,
IntermediateRepresentation,
- OAuthScheme
+ OAuthScheme,
+ TypeDeclaration,
+ TypeId
} from "@fern-fern/ir-sdk/api";
import { FdrSnippetTemplate, FdrSnippetTemplateClient, FdrSnippetTemplateEnvironment } from "@fern-fern/snippet-sdk";
import {
@@ -119,6 +121,7 @@ export declare namespace SdkGenerator {
allowExtraFields: boolean;
writeUnitTests: boolean;
inlineFileProperties: boolean;
+ enableInlineTypes: boolean;
omitUndefined: boolean;
executionEnvironment: "local" | "dev" | "prod";
organization: string;
@@ -298,7 +301,8 @@ export class SdkGenerator {
includeOtherInUnionTypes: config.includeOtherInUnionTypes,
includeSerdeLayer: config.includeSerdeLayer,
noOptionalProperties: config.noOptionalProperties,
- retainOriginalCasing: config.retainOriginalCasing
+ retainOriginalCasing: config.retainOriginalCasing,
+ enableInlineTypes: config.enableInlineTypes
});
this.typeSchemaGenerator = new TypeSchemaGenerator({
includeUtilsOnUnionMembers: config.includeUtilsOnUnionMembers,
@@ -317,7 +321,8 @@ export class SdkGenerator {
intermediateRepresentation,
includeSerdeLayer: config.includeSerdeLayer,
retainOriginalCasing: config.retainOriginalCasing,
- noOptionalProperties: config.noOptionalProperties
+ noOptionalProperties: config.noOptionalProperties,
+ enableInlineTypes: config.enableInlineTypes
});
this.sdkEndpointTypeSchemasGenerator = new SdkEndpointTypeSchemasGenerator({
errorResolver: this.errorResolver,
@@ -540,6 +545,17 @@ export class SdkGenerator {
});
}
+ private getTypesToGenerate(): Record {
+ if (this.config.enableInlineTypes) {
+ return Object.fromEntries(
+ Object.entries(this.intermediateRepresentation.types).filter(
+ ([_, typeDeclaration]) => !typeDeclaration.inline
+ )
+ );
+ }
+ return this.intermediateRepresentation.types;
+ }
+
public async copyCoreUtilities({
pathToSrc,
pathToRoot
@@ -551,7 +567,7 @@ export class SdkGenerator {
}
private generateTypeDeclarations() {
- for (const typeDeclaration of Object.values(this.intermediateRepresentation.types)) {
+ for (const typeDeclaration of Object.values(this.getTypesToGenerate())) {
this.withSourceFile({
filepath: this.typeDeclarationReferencer.getExportedFilepath(typeDeclaration.name),
run: ({ sourceFile, importsManager }) => {
@@ -564,7 +580,7 @@ export class SdkGenerator {
private generateTypeSchemas(): { generated: boolean } {
let generated = false;
- for (const typeDeclaration of Object.values(this.intermediateRepresentation.types)) {
+ for (const typeDeclaration of Object.values(this.getTypesToGenerate())) {
this.withSourceFile({
filepath: this.typeSchemaDeclarationReferencer.getExportedFilepath(typeDeclaration.name),
run: ({ sourceFile, importsManager }) => {
@@ -1281,6 +1297,7 @@ export class SdkGenerator {
retainOriginalCasing: this.config.retainOriginalCasing,
targetRuntime: this.config.targetRuntime,
inlineFileProperties: this.config.inlineFileProperties,
+ enableInlineTypes: this.config.enableInlineTypes,
generateOAuthClients: this.generateOAuthClients,
omitUndefined: this.config.omitUndefined,
useBigInt: this.config.useBigInt,
diff --git a/generators/typescript/sdk/generator/src/contexts/SdkContextImpl.ts b/generators/typescript/sdk/generator/src/contexts/SdkContextImpl.ts
index 023d2072cc1..7fb00b977a5 100644
--- a/generators/typescript/sdk/generator/src/contexts/SdkContextImpl.ts
+++ b/generators/typescript/sdk/generator/src/contexts/SdkContextImpl.ts
@@ -111,6 +111,7 @@ export declare namespace SdkContextImpl {
retainOriginalCasing: boolean;
generateOAuthClients: boolean;
inlineFileProperties: boolean;
+ enableInlineTypes: boolean;
omitUndefined: boolean;
neverThrowErrors: boolean;
useBigInt: boolean;
@@ -203,7 +204,8 @@ export class SdkContextImpl implements SdkContext {
generateOAuthClients,
omitUndefined,
useBigInt,
- neverThrowErrors
+ neverThrowErrors,
+ enableInlineTypes
}: SdkContextImpl.Init) {
this.logger = logger;
this.ir = ir;
@@ -250,7 +252,9 @@ export class SdkContextImpl implements SdkContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes,
+ context: this
});
this.typeSchema = new TypeSchemaContextImpl({
sourceFile,
@@ -264,7 +268,8 @@ export class SdkContextImpl implements SdkContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.sdkError = new SdkErrorContextImpl({
sourceFile,
@@ -296,7 +301,8 @@ export class SdkContextImpl implements SdkContext {
importsManager,
includeSerdeLayer,
retainOriginalCasing,
- inlineFileProperties
+ inlineFileProperties,
+ enableInlineTypes
});
this.sdkInlinedRequestBodySchema = new SdkInlinedRequestBodySchemaContextImpl({
importsManager,
diff --git a/generators/typescript/sdk/generator/src/contexts/base/BaseContextImpl.ts b/generators/typescript/sdk/generator/src/contexts/base/BaseContextImpl.ts
index 09e3075fe3a..49cb2e6ec32 100644
--- a/generators/typescript/sdk/generator/src/contexts/base/BaseContextImpl.ts
+++ b/generators/typescript/sdk/generator/src/contexts/base/BaseContextImpl.ts
@@ -1,3 +1,4 @@
+import { Logger } from "@fern-api/logger";
import { Constants } from "@fern-fern/ir-sdk/api";
import {
CoreUtilitiesManager,
@@ -7,33 +8,50 @@ import {
ImportsManager
} from "@fern-typescript/commons";
import { CoreUtilities } from "@fern-typescript/commons/src/core-utilities/CoreUtilities";
-import { BaseContext } from "@fern-typescript/contexts";
+import { BaseContext, TypeContext, TypeSchemaContext } from "@fern-typescript/contexts";
import { SourceFile } from "ts-morph";
export declare namespace BaseContextImpl {
export interface Init {
+ logger: Logger;
sourceFile: SourceFile;
importsManager: ImportsManager;
dependencyManager: DependencyManager;
coreUtilitiesManager: CoreUtilitiesManager;
fernConstants: Constants;
+ type: TypeContext;
+ typeSchema: TypeSchemaContext;
+ includeSerdeLayer: boolean;
}
}
export class BaseContextImpl implements BaseContext {
+ public readonly logger: Logger;
public readonly sourceFile: SourceFile;
public readonly externalDependencies: ExternalDependencies;
public readonly coreUtilities: CoreUtilities;
public readonly fernConstants: Constants;
+ public readonly type: TypeContext;
+ public readonly typeSchema: TypeSchemaContext;
+ public readonly includeSerdeLayer: boolean;
constructor({
+ logger,
sourceFile,
importsManager,
dependencyManager,
coreUtilitiesManager,
- fernConstants
+ fernConstants,
+ type,
+ typeSchema,
+ includeSerdeLayer
}: BaseContextImpl.Init) {
+ this.logger = logger;
this.sourceFile = sourceFile;
+ this.fernConstants = fernConstants;
+ this.type = type;
+ this.typeSchema = typeSchema;
+ this.includeSerdeLayer = includeSerdeLayer;
this.externalDependencies = createExternalDependencies({
dependencyManager,
importsManager
@@ -42,6 +60,5 @@ export class BaseContextImpl implements BaseContext {
sourceFile,
importsManager
});
- this.fernConstants = fernConstants;
}
}
diff --git a/generators/typescript/sdk/generator/src/contexts/request-wrapper/RequestWrapperContextImpl.ts b/generators/typescript/sdk/generator/src/contexts/request-wrapper/RequestWrapperContextImpl.ts
index d8c9d9ea705..0146c4886a5 100644
--- a/generators/typescript/sdk/generator/src/contexts/request-wrapper/RequestWrapperContextImpl.ts
+++ b/generators/typescript/sdk/generator/src/contexts/request-wrapper/RequestWrapperContextImpl.ts
@@ -16,6 +16,7 @@ export declare namespace RequestWrapperContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
inlineFileProperties: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -28,6 +29,7 @@ export class RequestWrapperContextImpl implements RequestWrapperContext {
private includeSerdeLayer: boolean;
private retainOriginalCasing: boolean;
private inlineFileProperties: boolean;
+ private enableInlineTypes: boolean;
constructor({
requestWrapperGenerator,
@@ -37,7 +39,8 @@ export class RequestWrapperContextImpl implements RequestWrapperContext {
sourceFile,
includeSerdeLayer,
retainOriginalCasing,
- inlineFileProperties
+ inlineFileProperties,
+ enableInlineTypes
}: RequestWrapperContextImpl.Init) {
this.requestWrapperGenerator = requestWrapperGenerator;
this.requestWrapperDeclarationReferencer = requestWrapperDeclarationReferencer;
@@ -47,6 +50,7 @@ export class RequestWrapperContextImpl implements RequestWrapperContext {
this.includeSerdeLayer = includeSerdeLayer;
this.retainOriginalCasing = retainOriginalCasing;
this.inlineFileProperties = inlineFileProperties;
+ this.enableInlineTypes = enableInlineTypes;
}
public getGeneratedRequestWrapper(packageId: PackageId, endpointName: Name): GeneratedRequestWrapper {
@@ -67,7 +71,8 @@ export class RequestWrapperContextImpl implements RequestWrapperContext {
}),
includeSerdeLayer: this.includeSerdeLayer,
retainOriginalCasing: this.retainOriginalCasing,
- inlineFileProperties: this.inlineFileProperties
+ inlineFileProperties: this.inlineFileProperties,
+ enableInlineTypes: this.enableInlineTypes
});
}
diff --git a/generators/typescript/sdk/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts b/generators/typescript/sdk/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
index 8222e014e66..9cd2f1b1449 100644
--- a/generators/typescript/sdk/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
+++ b/generators/typescript/sdk/generator/src/contexts/type-schema/TypeSchemaContextImpl.ts
@@ -1,4 +1,4 @@
-import { DeclaredTypeName, ShapeType, TypeReference } from "@fern-fern/ir-sdk/api";
+import { DeclaredTypeName, ShapeType, TypeDeclaration, TypeReference } from "@fern-fern/ir-sdk/api";
import { ImportsManager, Reference, TypeReferenceNode, Zurg } from "@fern-typescript/commons";
import { CoreUtilities } from "@fern-typescript/commons/src/core-utilities/CoreUtilities";
import { GeneratedTypeSchema, TypeSchemaContext } from "@fern-typescript/contexts";
@@ -9,7 +9,7 @@ import {
TypeReferenceToSchemaConverter
} from "@fern-typescript/type-reference-converters";
import { TypeSchemaGenerator } from "@fern-typescript/type-schema-generator";
-import { SourceFile } from "ts-morph";
+import { ts, SourceFile } from "ts-morph";
import { TypeDeclarationReferencer } from "../../declaration-referencers/TypeDeclarationReferencer";
import { getSchemaImportStrategy } from "../getSchemaImportStrategy";
@@ -27,6 +27,7 @@ export declare namespace TypeSchemaContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
useBigInt: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -56,17 +57,20 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes
}: TypeSchemaContextImpl.Init) {
this.sourceFile = sourceFile;
this.coreUtilities = coreUtilities;
this.importsManager = importsManager;
this.typeReferenceToRawTypeNodeConverter = new TypeReferenceToRawTypeNodeConverter({
getReferenceToNamedType: (typeName) => this.getReferenceToRawNamedType(typeName).getEntityName(),
+ generateForInlineUnion: (typeName) => this.generateForInlineUnion(typeName),
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeReferenceToSchemaConverter = new TypeReferenceToSchemaConverter({
getSchemaOfNamedType: (typeName) => this.getSchemaOfNamedType(typeName, { isGeneratingSchema: true }),
@@ -74,7 +78,8 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeDeclarationReferencer = typeDeclarationReferencer;
this.typeSchemaDeclarationReferencer = typeSchemaDeclarationReferencer;
@@ -101,10 +106,11 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
docs: typeDeclaration.docs ?? undefined,
examples,
fernFilepath: typeDeclaration.name.fernFilepath,
- typeName: this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
+ typeName: this.getTypeNameForDeclaration(typeDeclaration),
getReferenceToSelf: (context) => context.type.getReferenceToNamedType(typeName),
includeSerdeLayer: this.includeSerdeLayer,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ inline: typeDeclaration.inline ?? false
}),
getReferenceToGeneratedType: () =>
this.typeDeclarationReferencer
@@ -130,8 +136,12 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
});
}
+ private getTypeNameForDeclaration(typeDeclaration: TypeDeclaration): string {
+ return this.typeDeclarationReferencer.getExportedName(typeDeclaration.name);
+ }
+
public getReferenceToRawType(typeReference: TypeReference): TypeReferenceNode {
- return this.typeReferenceToRawTypeNodeConverter.convert(typeReference);
+ return this.typeReferenceToRawTypeNodeConverter.convert({ typeReference });
}
public getReferenceToRawNamedType(typeName: DeclaredTypeName): Reference {
@@ -154,8 +164,12 @@ export class TypeSchemaContextImpl implements TypeSchemaContext {
});
}
+ private generateForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode {
+ throw new Error("Internal error; inline unions are not supported in schemas.");
+ }
+
public getSchemaOfTypeReference(typeReference: TypeReference): Zurg.Schema {
- return this.typeReferenceToSchemaConverter.convert(typeReference);
+ return this.typeReferenceToSchemaConverter.convert({ typeReference });
}
public getSchemaOfNamedType(
diff --git a/generators/typescript/sdk/generator/src/contexts/type/TypeContextImpl.ts b/generators/typescript/sdk/generator/src/contexts/type/TypeContextImpl.ts
index 74e3a28863d..8430bd866a1 100644
--- a/generators/typescript/sdk/generator/src/contexts/type/TypeContextImpl.ts
+++ b/generators/typescript/sdk/generator/src/contexts/type/TypeContextImpl.ts
@@ -1,18 +1,20 @@
import {
DeclaredTypeName,
ExampleTypeReference,
+ ObjectProperty,
ResolvedTypeReference,
TypeDeclaration,
TypeReference
} from "@fern-fern/ir-sdk/api";
import { ImportsManager, NpmPackage, Reference, TypeReferenceNode } from "@fern-typescript/commons";
-import { GeneratedType, GeneratedTypeReferenceExample, TypeContext } from "@fern-typescript/contexts";
+import { BaseContext, GeneratedType, GeneratedTypeReferenceExample, TypeContext } from "@fern-typescript/contexts";
import { TypeResolver } from "@fern-typescript/resolvers";
import { TypeGenerator } from "@fern-typescript/type-generator";
import {
TypeReferenceToParsedTypeNodeConverter,
TypeReferenceToStringExpressionConverter
} from "@fern-typescript/type-reference-converters";
+import { ConvertTypeReferenceParams } from "@fern-typescript/type-reference-converters/src/AbstractTypeReferenceConverter";
import { TypeReferenceExampleGenerator } from "@fern-typescript/type-reference-example-generator";
import { SourceFile, ts } from "ts-morph";
import { TypeDeclarationReferencer } from "../../declaration-referencers/TypeDeclarationReferencer";
@@ -31,6 +33,8 @@ export declare namespace TypeContextImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
useBigInt: boolean;
+ enableInlineTypes: boolean;
+ context: BaseContext;
}
}
@@ -47,6 +51,7 @@ export class TypeContextImpl implements TypeContext {
private retainOriginalCasing: boolean;
private isForSnippet: boolean;
private npmPackage: NpmPackage | undefined;
+ private context: BaseContext;
constructor({
npmPackage,
@@ -60,7 +65,9 @@ export class TypeContextImpl implements TypeContext {
treatUnknownAsAny,
includeSerdeLayer,
retainOriginalCasing,
- useBigInt
+ useBigInt,
+ enableInlineTypes,
+ context
}: TypeContextImpl.Init) {
this.npmPackage = npmPackage;
this.isForSnippet = isForSnippet;
@@ -72,24 +79,56 @@ export class TypeContextImpl implements TypeContext {
this.typeReferenceExampleGenerator = typeReferenceExampleGenerator;
this.includeSerdeLayer = includeSerdeLayer;
this.retainOriginalCasing = retainOriginalCasing;
+ this.context = context;
this.typeReferenceToParsedTypeNodeConverter = new TypeReferenceToParsedTypeNodeConverter({
getReferenceToNamedType: (typeName) => this.getReferenceToNamedType(typeName).getEntityName(),
+ generateForInlineUnion: (typeName) => this.generateForInlineUnion(typeName),
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
this.typeReferenceToStringExpressionConverter = new TypeReferenceToStringExpressionConverter({
typeResolver,
treatUnknownAsAny,
includeSerdeLayer,
- useBigInt
+ useBigInt,
+ enableInlineTypes
});
}
public getReferenceToType(typeReference: TypeReference): TypeReferenceNode {
- return this.typeReferenceToParsedTypeNodeConverter.convert(typeReference);
+ return this.typeReferenceToParsedTypeNodeConverter.convert({ typeReference });
+ }
+
+ public getReferenceToInlinePropertyType(
+ typeReference: TypeReference,
+ parentTypeName: string,
+ propertyName: string
+ ): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "inlinePropertyParams",
+ parentTypeName,
+ propertyName
+ });
+ }
+
+ public getReferenceToInlineAliasType(typeReference: TypeReference, aliasTypeName: string): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "inlineAliasParams",
+ aliasTypeName
+ });
+ }
+
+ public getReferenceToTypeForInlineUnion(typeReference: TypeReference): TypeReferenceNode {
+ return this.typeReferenceToParsedTypeNodeConverter.convert({
+ typeReference,
+ type: "forInlineUnionParams"
+ });
}
public getTypeDeclaration(typeName: DeclaredTypeName): TypeDeclaration {
@@ -118,6 +157,11 @@ export class TypeContextImpl implements TypeContext {
}
}
+ public generateForInlineUnion(typeName: DeclaredTypeName): ts.TypeNode {
+ const generatedType = this.getGeneratedType(typeName);
+ return generatedType.generateForInlineUnion(this.context);
+ }
+
public resolveTypeReference(typeReference: TypeReference): ResolvedTypeReference {
return this.typeResolver.resolveTypeReference(typeReference);
}
@@ -131,7 +175,7 @@ export class TypeContextImpl implements TypeContext {
return this.getGeneratedType(typeDeclaration.name);
}
- public getGeneratedType(typeName: DeclaredTypeName): GeneratedType {
+ public getGeneratedType(typeName: DeclaredTypeName, typeNameOverride?: string): GeneratedType {
const typeDeclaration = this.typeResolver.getTypeDeclarationFromName(typeName);
const examples = typeDeclaration.userProvidedExamples;
if (examples.length === 0) {
@@ -140,12 +184,13 @@ export class TypeContextImpl implements TypeContext {
return this.typeGenerator.generateType({
shape: typeDeclaration.shape,
docs: typeDeclaration.docs ?? undefined,
- typeName: this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
+ typeName: typeNameOverride ?? this.typeDeclarationReferencer.getExportedName(typeDeclaration.name),
examples,
fernFilepath: typeDeclaration.name.fernFilepath,
getReferenceToSelf: (context) => context.type.getReferenceToNamedType(typeName),
includeSerdeLayer: this.includeSerdeLayer,
- retainOriginalCasing: this.retainOriginalCasing
+ retainOriginalCasing: this.retainOriginalCasing,
+ inline: typeDeclaration.inline ?? false
});
}
@@ -155,11 +200,13 @@ export class TypeContextImpl implements TypeContext {
{ includeNullCheckIfOptional }: { includeNullCheckIfOptional: boolean }
): ts.Expression {
if (includeNullCheckIfOptional) {
- return this.typeReferenceToStringExpressionConverter.convertWithNullCheckIfOptional(valueType)(
- valueToStringify
- );
+ return this.typeReferenceToStringExpressionConverter.convertWithNullCheckIfOptional({
+ typeReference: valueType
+ })(valueToStringify);
} else {
- return this.typeReferenceToStringExpressionConverter.convert(valueType)(valueToStringify);
+ return this.typeReferenceToStringExpressionConverter.convert({
+ typeReference: valueType
+ })(valueToStringify);
}
}
diff --git a/generators/typescript/sdk/generator/src/declaration-referencers/TypeDeclarationReferencer.ts b/generators/typescript/sdk/generator/src/declaration-referencers/TypeDeclarationReferencer.ts
index 1f468479fb9..235f4d99453 100644
--- a/generators/typescript/sdk/generator/src/declaration-referencers/TypeDeclarationReferencer.ts
+++ b/generators/typescript/sdk/generator/src/declaration-referencers/TypeDeclarationReferencer.ts
@@ -1,5 +1,5 @@
import { RelativeFilePath } from "@fern-api/fs-utils";
-import { DeclaredTypeName } from "@fern-fern/ir-sdk/api";
+import { DeclaredTypeName, ObjectProperty, TypeDeclaration } from "@fern-fern/ir-sdk/api";
import { ExportedFilePath, getExportedDirectoriesForFernFilepath, Reference } from "@fern-typescript/commons";
import { AbstractDeclarationReferencer } from "./AbstractDeclarationReferencer";
import { DeclarationReferencer } from "./DeclarationReferencer";
diff --git a/generators/typescript/sdk/request-wrapper-generator/package.json b/generators/typescript/sdk/request-wrapper-generator/package.json
index 4add7383b61..e4c0bd15f9b 100644
--- a/generators/typescript/sdk/request-wrapper-generator/package.json
+++ b/generators/typescript/sdk/request-wrapper-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
"ts-morph": "^15.1.0"
diff --git a/generators/typescript/sdk/request-wrapper-generator/src/GeneratedRequestWrapperImpl.ts b/generators/typescript/sdk/request-wrapper-generator/src/GeneratedRequestWrapperImpl.ts
index 6c49dfa6363..c55c3c94767 100644
--- a/generators/typescript/sdk/request-wrapper-generator/src/GeneratedRequestWrapperImpl.ts
+++ b/generators/typescript/sdk/request-wrapper-generator/src/GeneratedRequestWrapperImpl.ts
@@ -1,7 +1,8 @@
-import { noop } from "@fern-api/core-utils";
+import { assertNever, noop } from "@fern-api/core-utils";
import {
ExampleEndpointCall,
FileProperty,
+ FileUploadRequest,
FileUploadRequestProperty,
HttpEndpoint,
HttpHeader,
@@ -10,14 +11,20 @@ import {
InlinedRequestBody,
InlinedRequestBodyProperty,
NameAndWireValue,
+ NamedType,
+ ObjectProperty,
QueryParameter,
+ TypeDeclaration,
TypeReference
} from "@fern-fern/ir-sdk/api";
import {
+ generateInlinePropertiesModule,
getExampleEndpointCalls,
getTextOfTsNode,
- maybeAddDocs,
+ maybeAddDocsNode,
+ maybeAddDocsStructure,
PackageId,
+ TypeReferenceNode,
visitJavaScriptRuntime
} from "@fern-typescript/commons";
import {
@@ -26,7 +33,17 @@ import {
RequestWrapperNonBodyProperty,
SdkContext
} from "@fern-typescript/contexts";
-import { OptionalKind, PropertySignatureStructure, ts } from "ts-morph";
+import {
+ ModuleDeclarationKind,
+ ModuleDeclarationStructure,
+ OptionalKind,
+ PropertySignatureStructure,
+ StatementStructures,
+ StructureKind,
+ ts,
+ TypeAliasDeclarationStructure,
+ WriterFunction
+} from "ts-morph";
import { RequestWrapperExampleGenerator } from "./RequestWrapperExampleGenerator";
export declare namespace GeneratedRequestWrapperImpl {
@@ -38,6 +55,7 @@ export declare namespace GeneratedRequestWrapperImpl {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
inlineFileProperties: boolean;
+ enableInlineTypes: boolean;
}
}
@@ -51,6 +69,7 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
protected includeSerdeLayer: boolean;
protected retainOriginalCasing: boolean;
protected inlineFileProperties: boolean;
+ private enableInlineTypes: boolean;
constructor({
service,
@@ -59,7 +78,8 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
packageId,
includeSerdeLayer,
retainOriginalCasing,
- inlineFileProperties
+ inlineFileProperties,
+ enableInlineTypes
}: GeneratedRequestWrapperImpl.Init) {
this.service = service;
this.endpoint = endpoint;
@@ -68,6 +88,7 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
this.includeSerdeLayer = includeSerdeLayer;
this.retainOriginalCasing = retainOriginalCasing;
this.inlineFileProperties = inlineFileProperties;
+ this.enableInlineTypes = enableInlineTypes;
}
public writeToFile(context: SdkContext): void {
@@ -92,7 +113,7 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
),
hasQuestionToken: type.isOptional
});
- maybeAddDocs(property, queryParameter.docs);
+ maybeAddDocsNode(property, queryParameter.docs);
}
for (const header of this.getAllNonLiteralHeaders(context)) {
const type = context.type.getReferenceToType(header.valueType);
@@ -101,7 +122,7 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
type: getTextOfTsNode(type.typeNodeWithoutUndefined),
hasQuestionToken: type.isOptional
});
- maybeAddDocs(property, header.docs);
+ maybeAddDocsNode(property, header.docs);
}
if (this.endpoint.requestBody != null) {
HttpRequestBody._visit(this.endpoint.requestBody, {
@@ -110,7 +131,11 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
inlinedRequestBody,
context
})) {
- requestInterface.addProperty(this.getInlineProperty(property, context));
+ requestInterface.addProperty(this.getInlineProperty(inlinedRequestBody, property, context));
+ }
+ const iModule = this.generateModule(inlinedRequestBody, context);
+ if (iModule) {
+ context.sourceFile.addModule(iModule);
}
for (const extension of inlinedRequestBody.extends) {
requestInterface.addExtends(
@@ -125,7 +150,7 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
type: getTextOfTsNode(type.typeNodeWithoutUndefined),
hasQuestionToken: type.isOptional
});
- maybeAddDocs(property, referenceToRequestBody.docs);
+ maybeAddDocsNode(property, referenceToRequestBody.docs);
},
fileUpload: (fileUploadRequest) => {
for (const property of fileUploadRequest.properties) {
@@ -141,7 +166,9 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
});
},
bodyProperty: (inlinedProperty) => {
- requestInterface.addProperty(this.getInlineProperty(inlinedProperty, context));
+ requestInterface.addProperty(
+ this.getInlineProperty(fileUploadRequest, inlinedProperty, context)
+ );
},
_other: () => {
throw new Error("Unknown FileUploadRequestProperty: " + property.type);
@@ -186,10 +213,11 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
}
private getInlineProperty(
+ requestBody: InlinedRequestBody | FileUploadRequest,
property: InlinedRequestBodyProperty,
context: SdkContext
): OptionalKind {
- const type = context.type.getReferenceToType(property.valueType);
+ const type = this.getTypeForBodyProperty(requestBody, property, context);
return {
name: `"${this.getInlinedRequestBodyPropertyKey(property)}"`,
type: getTextOfTsNode(type.typeNodeWithoutUndefined),
@@ -198,6 +226,36 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
};
}
+ private getTypeForBodyProperty(
+ requestBody: InlinedRequestBody | FileUploadRequest,
+ property: InlinedRequestBodyProperty,
+ context: SdkContext
+ ): TypeReferenceNode {
+ const propParentTypeName = requestBody.name.pascalCase.safeName;
+ const propName = property.name.name.pascalCase.safeName;
+ return context.type.getReferenceToInlinePropertyType(property.valueType, propParentTypeName, propName);
+ }
+
+ private generateModule(
+ inlinedRequestBody: InlinedRequestBody,
+ context: SdkContext
+ ): ModuleDeclarationStructure | undefined {
+ if (!this.enableInlineTypes) {
+ return undefined;
+ }
+
+ return generateInlinePropertiesModule({
+ parentTypeName: this.wrapperName,
+ properties: inlinedRequestBody.properties.map((prop) => ({
+ propertyName: prop.name.name.pascalCase.safeName,
+ typeReference: prop.valueType
+ })),
+ generateStatements: (typeName, typeNameOverride) =>
+ context.type.getGeneratedType(typeName, typeNameOverride).generateStatements(context),
+ getTypeDeclaration: (namedType) => context.type.getTypeDeclaration(namedType)
+ });
+ }
+
public areBodyPropertiesInlined(): boolean {
return this.endpoint.requestBody != null && this.endpoint.requestBody.type === "inlinedRequestBody";
}
@@ -498,3 +556,58 @@ export class GeneratedRequestWrapperImpl implements GeneratedRequestWrapper {
return property.type === "fileArray" ? ts.factory.createArrayTypeNode(value) : value;
}
}
+function generateTypeVisitor(
+ typeReference: TypeReference,
+ visitor: {
+ named: () => TOut;
+ list: () => TOut;
+ map: () => TOut;
+ set: () => TOut;
+ other: () => TOut;
+ }
+): TOut {
+ return typeReference._visit({
+ named: visitor.named,
+ primitive: visitor.other,
+ unknown: visitor.other,
+ container: (containerType) =>
+ containerType._visit({
+ list: visitor.list,
+ literal: visitor.other,
+ map: visitor.map,
+ set: visitor.set,
+ optional: (typeReference) => generateTypeVisitor(typeReference, visitor),
+ _other: visitor.other
+ }),
+ _other: visitor.other
+ });
+}
+
+function getNamedType(typeReference: TypeReference): NamedType | undefined {
+ switch (typeReference.type) {
+ case "named":
+ return typeReference;
+ case "container":
+ switch (typeReference.container.type) {
+ case "optional":
+ return getNamedType(typeReference.container.optional);
+ case "list":
+ return getNamedType(typeReference.container.list);
+ case "map":
+ return getNamedType(typeReference.container.valueType);
+ case "set":
+ return getNamedType(typeReference.container.set);
+ case "literal":
+ return undefined;
+ default:
+ assertNever(typeReference.container);
+ }
+ // fallthrough
+ case "primitive":
+ return undefined;
+ case "unknown":
+ return undefined;
+ default:
+ assertNever(typeReference);
+ }
+}
diff --git a/generators/typescript/sdk/request-wrapper-generator/src/RequestWrapperGenerator.ts b/generators/typescript/sdk/request-wrapper-generator/src/RequestWrapperGenerator.ts
index e8e0da0f816..ec52071dcee 100644
--- a/generators/typescript/sdk/request-wrapper-generator/src/RequestWrapperGenerator.ts
+++ b/generators/typescript/sdk/request-wrapper-generator/src/RequestWrapperGenerator.ts
@@ -13,6 +13,7 @@ export declare namespace RequestWrapperGenerator {
includeSerdeLayer: boolean;
retainOriginalCasing: boolean;
inlineFileProperties: boolean;
+ enableInlineTypes: boolean;
}
}
}
@@ -25,7 +26,8 @@ export class RequestWrapperGenerator {
wrapperName,
includeSerdeLayer,
retainOriginalCasing,
- inlineFileProperties
+ inlineFileProperties,
+ enableInlineTypes
}: RequestWrapperGenerator.generateRequestWrapper.Args): GeneratedRequestWrapper {
return new GeneratedRequestWrapperImpl({
packageId,
@@ -34,7 +36,8 @@ export class RequestWrapperGenerator {
wrapperName,
includeSerdeLayer,
retainOriginalCasing,
- inlineFileProperties
+ inlineFileProperties,
+ enableInlineTypes
});
}
}
diff --git a/generators/typescript/sdk/sdk-endpoint-type-schemas-generator/package.json b/generators/typescript/sdk/sdk-endpoint-type-schemas-generator/package.json
index 835346fd208..5a1a40aecd3 100644
--- a/generators/typescript/sdk/sdk-endpoint-type-schemas-generator/package.json
+++ b/generators/typescript/sdk/sdk-endpoint-type-schemas-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-schema-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/sdk-error-generator/package.json b/generators/typescript/sdk/sdk-error-generator/package.json
index ad385ac1098..bb35359c067 100644
--- a/generators/typescript/sdk/sdk-error-generator/package.json
+++ b/generators/typescript/sdk/sdk-error-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-error-class-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/sdk-error-schema-generator/package.json b/generators/typescript/sdk/sdk-error-schema-generator/package.json
index 51605ff06aa..bffc0aedcb9 100644
--- a/generators/typescript/sdk/sdk-error-schema-generator/package.json
+++ b/generators/typescript/sdk/sdk-error-schema-generator/package.json
@@ -28,7 +28,7 @@
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-schema-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/sdk/sdk-inlined-request-body-schema-generator/package.json b/generators/typescript/sdk/sdk-inlined-request-body-schema-generator/package.json
index 480994c7341..f82ee155563 100644
--- a/generators/typescript/sdk/sdk-inlined-request-body-schema-generator/package.json
+++ b/generators/typescript/sdk/sdk-inlined-request-body-schema-generator/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/abstract-schema-generator": "workspace:*",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*",
diff --git a/generators/typescript/utils/abstract-generator-cli/package.json b/generators/typescript/utils/abstract-generator-cli/package.json
index 7fbec6d57f6..1c5701d62ba 100644
--- a/generators/typescript/utils/abstract-generator-cli/package.json
+++ b/generators/typescript/utils/abstract-generator-cli/package.json
@@ -31,7 +31,7 @@
"@fern-api/base-generator": "workspace:*",
"@fern-api/logger": "workspace:*",
"@fern-fern/generator-exec-sdk": "^0.0.898",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"@fern-typescript/contexts": "workspace:*"
},
diff --git a/generators/typescript/utils/commons/package.json b/generators/typescript/utils/commons/package.json
index 612f7796015..0532c75b5ba 100644
--- a/generators/typescript/utils/commons/package.json
+++ b/generators/typescript/utils/commons/package.json
@@ -31,7 +31,7 @@
"@fern-api/fs-utils": "workspace:*",
"@fern-api/logger": "workspace:*",
"@fern-api/logging-execa": "workspace:*",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/fetcher": "workspace:*",
"@fern-typescript/zurg": "workspace:*",
"decompress": "^4.2.1",
diff --git a/generators/typescript/utils/commons/src/codegen-utils/generateInlineModule.ts b/generators/typescript/utils/commons/src/codegen-utils/generateInlineModule.ts
new file mode 100644
index 00000000000..af4728f0561
--- /dev/null
+++ b/generators/typescript/utils/commons/src/codegen-utils/generateInlineModule.ts
@@ -0,0 +1,251 @@
+import { assertNever } from "@fern-api/core-utils";
+import { TypeReference, TypeDeclaration, MapType, NamedType, DeclaredTypeName } from "@fern-fern/ir-sdk/api";
+import {
+ ModuleDeclarationKind,
+ ModuleDeclarationStructure,
+ StatementStructures,
+ StructureKind,
+ TypeAliasDeclarationStructure,
+ WriterFunction
+} from "ts-morph";
+import { InlineConsts } from "./inlineConsts";
+
+export function generateInlinePropertiesModule({
+ generateStatements,
+ getTypeDeclaration,
+ parentTypeName,
+ properties
+}: InlinePropertiesParams): ModuleDeclarationStructure | undefined {
+ const inlineProperties = getInlineProperties(properties, getTypeDeclaration);
+ if (inlineProperties.length === 0) {
+ return;
+ }
+ return {
+ kind: StructureKind.Module,
+ name: parentTypeName,
+ isExported: true,
+ hasDeclareKeyword: false,
+ declarationKind: ModuleDeclarationKind.Namespace,
+ statements: inlineProperties.flatMap(
+ ([propertyName, typeReference, typeDeclaration]: [string, TypeReference, TypeDeclaration]) => {
+ return generateTypeVisitor(typeReference, {
+ named: () => generateStatements(typeDeclaration.name, propertyName),
+ list: () => propertyListOrSetStatementGenerator(propertyName, typeDeclaration, generateStatements),
+ set: () => propertyListOrSetStatementGenerator(propertyName, typeDeclaration, generateStatements),
+ map: () => {
+ const statements: StatementStructures[] = [];
+ const mapModule: ModuleDeclarationStructure = {
+ kind: StructureKind.Module,
+ declarationKind: ModuleDeclarationKind.Namespace,
+ isExported: true,
+ hasDeclareKeyword: false,
+ name: propertyName,
+ statements: generateStatements(typeDeclaration.name, InlineConsts.MAP_VALUE_TYPE_NAME)
+ };
+
+ statements.push(mapModule);
+ return statements;
+ },
+ other: () => {
+ throw new Error(`Only named, list, map, and set properties can be inlined.
+ Property: ${JSON.stringify(propertyName)}`);
+ }
+ });
+ }
+ )
+ };
+}
+
+function propertyListOrSetStatementGenerator(
+ propertyName: string,
+ typeDeclaration: TypeDeclaration,
+ generateStatements: GenerateStatements
+) {
+ const statements: StatementStructures[] = [];
+ const listType: TypeAliasDeclarationStructure = {
+ kind: StructureKind.TypeAlias,
+ name: propertyName,
+ type: `${propertyName}.${InlineConsts.LIST_ITEM_TYPE_NAME}[]`,
+ isExported: true
+ };
+ statements.push(listType);
+
+ const listModule: ModuleDeclarationStructure = {
+ kind: StructureKind.Module,
+ declarationKind: ModuleDeclarationKind.Namespace,
+ isExported: true,
+ hasDeclareKeyword: false,
+ name: propertyName,
+ statements: generateStatements(typeDeclaration.name, InlineConsts.LIST_ITEM_TYPE_NAME)
+ };
+
+ statements.push(listModule);
+ return statements;
+}
+
+export function generateInlineAliasModule({
+ generateStatements,
+ getTypeDeclaration,
+ aliasTypeName,
+ typeReference
+}: InlineAliasParams): ModuleDeclarationStructure | undefined {
+ const inlineModuleStatements = generateTypeVisitor(typeReference, {
+ list: (itemType) => aliasListOrSetStatementGenerator(itemType, generateStatements, getTypeDeclaration),
+ set: (itemType) => aliasListOrSetStatementGenerator(itemType, generateStatements, getTypeDeclaration),
+ map: (mapType: MapType) => {
+ const namedType = getNamedType(mapType.valueType);
+ if (!namedType) {
+ return undefined;
+ }
+ const typeDeclaration = getTypeDeclaration(namedType);
+ if (!typeDeclaration.inline) {
+ return undefined;
+ }
+
+ return generateStatements(typeDeclaration.name, InlineConsts.MAP_VALUE_TYPE_NAME);
+ },
+ named: () => undefined,
+ other: () => undefined
+ });
+ if (!inlineModuleStatements) {
+ return undefined;
+ }
+ return {
+ kind: StructureKind.Module,
+ name: aliasTypeName,
+ isExported: true,
+ hasDeclareKeyword: false,
+ declarationKind: ModuleDeclarationKind.Namespace,
+ statements: inlineModuleStatements
+ };
+}
+
+function aliasListOrSetStatementGenerator(
+ listItemType: TypeReference,
+ generateStatements: GenerateStatements,
+ getTypeDeclaration: GetTypeDeclaration
+): undefined | string | WriterFunction | (string | WriterFunction | StatementStructures)[] {
+ const namedType = getNamedType(listItemType);
+ if (!namedType) {
+ return undefined;
+ }
+ const typeDeclaration = getTypeDeclaration(namedType);
+ if (!typeDeclaration.inline) {
+ return undefined;
+ }
+
+ return generateStatements(typeDeclaration.name, InlineConsts.LIST_ITEM_TYPE_NAME);
+}
+
+function getInlineProperties(
+ properties: Property[],
+ getTypeDeclaration: GetTypeDeclaration
+): [string, TypeReference, TypeDeclaration][] {
+ return properties
+ .map(({ propertyName, typeReference }): [string, TypeReference, TypeDeclaration] | undefined => {
+ const declaration = getInlineTypeDeclaration(typeReference, getTypeDeclaration);
+ if (!declaration) {
+ return undefined;
+ }
+ return [propertyName, typeReference, declaration];
+ })
+ .filter((x): x is [string, TypeReference, TypeDeclaration] => x !== undefined);
+}
+
+function getInlineTypeDeclaration(
+ typeReference: TypeReference,
+ getTypeDeclaration: GetTypeDeclaration
+): TypeDeclaration | undefined {
+ const namedType = getNamedType(typeReference);
+ if (!namedType) {
+ return undefined;
+ }
+ const typeDeclaration = getTypeDeclaration(namedType);
+ if (!typeDeclaration.inline) {
+ return undefined;
+ }
+
+ return typeDeclaration;
+}
+
+export interface InlinePropertiesParams {
+ generateStatements: GenerateStatements;
+ getTypeDeclaration: GetTypeDeclaration;
+ parentTypeName: string;
+ properties: Property[];
+}
+
+interface Property {
+ typeReference: TypeReference;
+ propertyName: string;
+}
+
+export interface InlineAliasParams {
+ generateStatements: GenerateStatements;
+ getTypeDeclaration: GetTypeDeclaration;
+ typeReference: TypeReference;
+ aliasTypeName: string;
+}
+
+type GenerateStatements = (
+ typeName: DeclaredTypeName,
+ typeNameOverride?: string
+) => string | WriterFunction | (string | WriterFunction | StatementStructures)[];
+
+type GetTypeDeclaration = (namedType: NamedType) => TypeDeclaration;
+
+function generateTypeVisitor(
+ typeReference: TypeReference,
+ visitor: {
+ named: (namedType: NamedType) => TOut;
+ list: (itemType: TypeReference) => TOut;
+ map: (mapType: MapType) => TOut;
+ set: (itemType: TypeReference) => TOut;
+ other: () => TOut;
+ }
+): TOut {
+ return typeReference._visit({
+ named: visitor.named,
+ primitive: visitor.other,
+ unknown: visitor.other,
+ container: (containerType) =>
+ containerType._visit({
+ list: visitor.list,
+ literal: visitor.other,
+ map: visitor.map,
+ set: visitor.set,
+ optional: (typeReference) => generateTypeVisitor(typeReference, visitor),
+ _other: visitor.other
+ }),
+ _other: visitor.other
+ });
+}
+
+function getNamedType(typeReference: TypeReference): NamedType | undefined {
+ switch (typeReference.type) {
+ case "named":
+ return typeReference;
+ case "container":
+ switch (typeReference.container.type) {
+ case "optional":
+ return getNamedType(typeReference.container.optional);
+ case "list":
+ return getNamedType(typeReference.container.list);
+ case "map":
+ return getNamedType(typeReference.container.valueType);
+ case "set":
+ return getNamedType(typeReference.container.set);
+ case "literal":
+ return undefined;
+ default:
+ assertNever(typeReference.container);
+ }
+ // fallthrough
+ case "primitive":
+ return undefined;
+ case "unknown":
+ return undefined;
+ default:
+ assertNever(typeReference);
+ }
+}
diff --git a/generators/typescript/utils/commons/src/codegen-utils/inlineConsts.ts b/generators/typescript/utils/commons/src/codegen-utils/inlineConsts.ts
new file mode 100644
index 00000000000..7a3a221e981
--- /dev/null
+++ b/generators/typescript/utils/commons/src/codegen-utils/inlineConsts.ts
@@ -0,0 +1,4 @@
+export const InlineConsts = {
+ MAP_VALUE_TYPE_NAME: "Value",
+ LIST_ITEM_TYPE_NAME: "Item"
+} as const;
diff --git a/generators/typescript/utils/commons/src/codegen-utils/maybeAddDocs.ts b/generators/typescript/utils/commons/src/codegen-utils/maybeAddDocs.ts
index bbf8ccd6fcb..593d4f74296 100644
--- a/generators/typescript/utils/commons/src/codegen-utils/maybeAddDocs.ts
+++ b/generators/typescript/utils/commons/src/codegen-utils/maybeAddDocs.ts
@@ -1,8 +1,17 @@
-import { JSDocableNode } from "ts-morph";
+import { JSDocableNode, JSDocableNodeStructure } from "ts-morph";
-export function maybeAddDocs(node: JSDocableNode, docs: string | null | undefined): void {
+export function maybeAddDocsNode(node: JSDocableNode, docs: string | null | undefined): void {
if (docs != null) {
+ docs = "\n" + docs;
+ node.addJsDoc(docs);
+ }
+}
+
+export function maybeAddDocsStructure(node: JSDocableNodeStructure, docs: string | null | undefined): void {
+ if (docs != null) {
+ docs = "\n" + docs;
// add newline so ts-morph makes it a multiline comment
- node.addJsDoc("\n" + docs);
+ node.docs = [docs];
+ return;
}
}
diff --git a/generators/typescript/utils/commons/src/codegen-utils/writerToString.ts b/generators/typescript/utils/commons/src/codegen-utils/writerToString.ts
new file mode 100644
index 00000000000..e471579f852
--- /dev/null
+++ b/generators/typescript/utils/commons/src/codegen-utils/writerToString.ts
@@ -0,0 +1,12 @@
+import { CodeBlockWriter, WriterFunction } from "ts-morph";
+
+export function writerToString(writer: WriterFunction | string): string {
+ if (typeof writer === "string") {
+ return writer;
+ }
+ // Create a minimal writer context that captures the output
+ const writerContext = new CodeBlockWriter();
+ // Execute the writer with our context
+ writer(writerContext);
+ return writerContext.toString();
+}
diff --git a/generators/typescript/utils/commons/src/index.ts b/generators/typescript/utils/commons/src/index.ts
index a00948bf805..0ea330a99f7 100644
--- a/generators/typescript/utils/commons/src/index.ts
+++ b/generators/typescript/utils/commons/src/index.ts
@@ -3,7 +3,9 @@ export { getPropertyKey } from "./codegen-utils/getPropertyKey";
export { getSchemaOptions } from "./codegen-utils/getSchemaOptions";
export { getTextOfTsKeyword } from "./codegen-utils/getTextOfTsKeyword";
export { getTextOfTsNode } from "./codegen-utils/getTextOfTsNode";
-export { maybeAddDocs } from "./codegen-utils/maybeAddDocs";
+export { maybeAddDocsNode, maybeAddDocsStructure } from "./codegen-utils/maybeAddDocs";
+export { writerToString } from "./codegen-utils/writerToString";
+export { generateInlineAliasModule, generateInlinePropertiesModule } from "./codegen-utils/generateInlineModule";
export * from "./core-utilities";
export { type Zurg } from "./core-utilities/zurg/Zurg";
export { DependencyManager, DependencyType, type PackageDependencies } from "./dependency-manager/DependencyManager";
diff --git a/generators/typescript/utils/contexts/package.json b/generators/typescript/utils/contexts/package.json
index 34f95fc84f8..2fc47911eeb 100644
--- a/generators/typescript/utils/contexts/package.json
+++ b/generators/typescript/utils/contexts/package.json
@@ -30,7 +30,7 @@
"@fern-api/logger": "workspace:*",
"@fern-api/base-generator": "workspace:*",
"@fern-fern/generator-exec-sdk": "^0.0.898",
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*",
"ts-morph": "^15.1.0"
},
diff --git a/generators/typescript/utils/contexts/src/base-context/BaseContext.ts b/generators/typescript/utils/contexts/src/base-context/BaseContext.ts
index 484a3ff08d8..619cbc43c02 100644
--- a/generators/typescript/utils/contexts/src/base-context/BaseContext.ts
+++ b/generators/typescript/utils/contexts/src/base-context/BaseContext.ts
@@ -1,11 +1,17 @@
+import { Logger } from "@fern-api/logger";
import { Constants } from "@fern-fern/ir-sdk/api";
import { ExternalDependencies } from "@fern-typescript/commons";
import { CoreUtilities } from "@fern-typescript/commons/src/core-utilities/CoreUtilities";
import { SourceFile } from "ts-morph";
+import { TypeContext, TypeSchemaContext } from "../model-context";
export interface BaseContext {
+ logger: Logger;
sourceFile: SourceFile;
externalDependencies: ExternalDependencies;
coreUtilities: CoreUtilities;
fernConstants: Constants;
+ type: TypeContext;
+ typeSchema: TypeSchemaContext;
+ includeSerdeLayer: boolean;
}
diff --git a/generators/typescript/utils/contexts/src/base-context/index.ts b/generators/typescript/utils/contexts/src/base-context/index.ts
index fe9a97ab7b5..7e00204fc7d 100644
--- a/generators/typescript/utils/contexts/src/base-context/index.ts
+++ b/generators/typescript/utils/contexts/src/base-context/index.ts
@@ -1 +1,4 @@
export { type BaseContext } from "./BaseContext";
+
+export * from "./type";
+export * from "./type-schema";
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/BaseGeneratedTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/BaseGeneratedTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/BaseGeneratedTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/BaseGeneratedTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedAliasTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedAliasTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedAliasTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedAliasTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedEnumTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedEnumTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedEnumTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedEnumTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedObjectTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedObjectTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedObjectTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedObjectTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedTypeSchema.ts
similarity index 84%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedTypeSchema.ts
index f1b00c475e6..55974a35891 100644
--- a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedTypeSchema.ts
+++ b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedTypeSchema.ts
@@ -1,11 +1,11 @@
-import { ModelContext } from "../ModelContext";
+import { BaseContext } from "../../base-context";
import { GeneratedAliasTypeSchema } from "./GeneratedAliasTypeSchema";
import { GeneratedEnumTypeSchema } from "./GeneratedEnumTypeSchema";
import { GeneratedObjectTypeSchema } from "./GeneratedObjectTypeSchema";
import { GeneratedUndiscriminatedUnionTypeSchema } from "./GeneratedUndiscriminatedUnionTypeSchema";
import { GeneratedUnionTypeSchema } from "./GeneratedUnionTypeSchema";
-export type GeneratedTypeSchema =
+export type GeneratedTypeSchema =
| GeneratedAliasTypeSchema
| GeneratedEnumTypeSchema
| GeneratedUnionTypeSchema
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedUndiscriminatedUnionTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedUndiscriminatedUnionTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedUndiscriminatedUnionTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedUndiscriminatedUnionTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedUnionTypeSchema.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedUnionTypeSchema.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/GeneratedUnionTypeSchema.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/GeneratedUnionTypeSchema.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/TypeSchemaContext.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/TypeSchemaContext.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/TypeSchemaContext.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/TypeSchemaContext.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type-schema/index.ts b/generators/typescript/utils/contexts/src/base-context/type-schema/index.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type-schema/index.ts
rename to generators/typescript/utils/contexts/src/base-context/type-schema/index.ts
diff --git a/generators/typescript/utils/contexts/src/base-context/type/BaseGeneratedType.ts b/generators/typescript/utils/contexts/src/base-context/type/BaseGeneratedType.ts
new file mode 100644
index 00000000000..f2a69f75d11
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/base-context/type/BaseGeneratedType.ts
@@ -0,0 +1,15 @@
+import { ExampleTypeShape } from "@fern-fern/ir-sdk/api";
+import { GetReferenceOpts } from "@fern-typescript/commons";
+import { ts } from "ts-morph";
+import { GeneratedFile } from "../../commons";
+import { GeneratedModule } from "../../commons/GeneratedModule";
+import { GeneratedStatements } from "../../commons/GeneratedStatements";
+import { GeneratedUnionInlineMemberNode } from "../../commons/GeneratedUnionInlineMemberNode";
+
+export interface BaseGeneratedType
+ extends GeneratedFile,
+ GeneratedStatements,
+ GeneratedModule,
+ GeneratedUnionInlineMemberNode {
+ buildExample: (example: ExampleTypeShape, context: Context, opts: GetReferenceOpts) => ts.Expression;
+}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedAliasType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedAliasType.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type/GeneratedAliasType.ts
rename to generators/typescript/utils/contexts/src/base-context/type/GeneratedAliasType.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedEnumType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedEnumType.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type/GeneratedEnumType.ts
rename to generators/typescript/utils/contexts/src/base-context/type/GeneratedEnumType.ts
diff --git a/generators/typescript/utils/contexts/src/base-context/type/GeneratedObjectType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedObjectType.ts
new file mode 100644
index 00000000000..c9bc70c056a
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/base-context/type/GeneratedObjectType.ts
@@ -0,0 +1,19 @@
+import { ExampleTypeShape, TypeReference } from "@fern-fern/ir-sdk/api";
+import { GetReferenceOpts } from "@fern-typescript/commons";
+import { InterfaceDeclarationStructure, PropertySignatureStructure, ts } from "ts-morph";
+import { BaseGeneratedType } from "./BaseGeneratedType";
+
+export interface GeneratedObjectType extends BaseGeneratedType {
+ type: "object";
+ getAllPropertiesIncludingExtensions: (
+ context: Context
+ ) => { wireKey: string; propertyKey: string; type: TypeReference }[];
+ generateInterface(context: Context): InterfaceDeclarationStructure;
+ generateProperties(context: Context): PropertySignatureStructure[];
+ getPropertyKey: (args: { propertyWireKey: string }) => string;
+ buildExampleProperties: (
+ example: ExampleTypeShape,
+ context: Context,
+ opts: GetReferenceOpts
+ ) => ts.ObjectLiteralElementLike[];
+}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedType.ts
similarity index 83%
rename from generators/typescript/utils/contexts/src/model-context/type/GeneratedType.ts
rename to generators/typescript/utils/contexts/src/base-context/type/GeneratedType.ts
index 180f96670ad..c56d430872b 100644
--- a/generators/typescript/utils/contexts/src/model-context/type/GeneratedType.ts
+++ b/generators/typescript/utils/contexts/src/base-context/type/GeneratedType.ts
@@ -1,11 +1,11 @@
-import { ModelContext } from "../ModelContext";
+import { BaseContext } from "../../base-context";
import { GeneratedAliasType } from "./GeneratedAliasType";
import { GeneratedEnumType } from "./GeneratedEnumType";
import { GeneratedObjectType } from "./GeneratedObjectType";
import { GeneratedUndiscriminatedUnionType } from "./GeneratedUndiscriminatedUnionType";
import { GeneratedUnionType } from "./GeneratedUnionType";
-export type GeneratedType =
+export type GeneratedType =
| GeneratedAliasType
| GeneratedEnumType
| GeneratedObjectType
diff --git a/generators/typescript/utils/contexts/src/base-context/type/GeneratedTypeReferenceExample.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedTypeReferenceExample.ts
new file mode 100644
index 00000000000..9df1addf9e8
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/base-context/type/GeneratedTypeReferenceExample.ts
@@ -0,0 +1,7 @@
+import { GetReferenceOpts } from "@fern-typescript/commons";
+import { ts } from "ts-morph";
+import { BaseContext } from "../../base-context";
+
+export interface GeneratedTypeReferenceExample {
+ build: (context: BaseContext, opts: GetReferenceOpts) => ts.Expression;
+}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedUndiscriminatedUnionType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedUndiscriminatedUnionType.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type/GeneratedUndiscriminatedUnionType.ts
rename to generators/typescript/utils/contexts/src/base-context/type/GeneratedUndiscriminatedUnionType.ts
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedUnionType.ts b/generators/typescript/utils/contexts/src/base-context/type/GeneratedUnionType.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type/GeneratedUnionType.ts
rename to generators/typescript/utils/contexts/src/base-context/type/GeneratedUnionType.ts
diff --git a/generators/typescript/utils/contexts/src/base-context/type/TypeContext.ts b/generators/typescript/utils/contexts/src/base-context/type/TypeContext.ts
new file mode 100644
index 00000000000..0c7af1da023
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/base-context/type/TypeContext.ts
@@ -0,0 +1,36 @@
+import {
+ DeclaredTypeName,
+ ExampleTypeReference,
+ ObjectProperty,
+ ResolvedTypeReference,
+ TypeDeclaration,
+ TypeId,
+ TypeReference
+} from "@fern-fern/ir-sdk/api";
+import { Reference, TypeReferenceNode } from "@fern-typescript/commons";
+import { ts } from "ts-morph";
+import { GeneratedType } from "./GeneratedType";
+import { GeneratedTypeReferenceExample } from "./GeneratedTypeReferenceExample";
+
+export interface TypeContext {
+ getReferenceToType: (typeReference: TypeReference) => TypeReferenceNode;
+ getReferenceToInlinePropertyType: (
+ typeReference: TypeReference,
+ parentTypeName: string,
+ propertyName: string
+ ) => TypeReferenceNode;
+ getReferenceToInlineAliasType: (typeReference: TypeReference, aliasTypeName: string) => TypeReferenceNode;
+ getReferenceToTypeForInlineUnion: (typeReference: TypeReference) => TypeReferenceNode;
+ stringify: (
+ valueToStringify: ts.Expression,
+ valueType: TypeReference,
+ opts: { includeNullCheckIfOptional: boolean }
+ ) => ts.Expression;
+ getReferenceToNamedType: (typeName: DeclaredTypeName) => Reference;
+ resolveTypeReference: (typeReference: TypeReference) => ResolvedTypeReference;
+ resolveTypeName: (typeName: DeclaredTypeName) => ResolvedTypeReference;
+ getTypeDeclaration: (typeName: DeclaredTypeName) => TypeDeclaration;
+ getGeneratedType: (typeName: DeclaredTypeName, typeNameOverride?: string) => GeneratedType;
+ getGeneratedTypeById: (typeId: TypeId) => GeneratedType;
+ getGeneratedExample: (example: ExampleTypeReference) => GeneratedTypeReferenceExample;
+}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/index.ts b/generators/typescript/utils/contexts/src/base-context/type/index.ts
similarity index 100%
rename from generators/typescript/utils/contexts/src/model-context/type/index.ts
rename to generators/typescript/utils/contexts/src/base-context/type/index.ts
diff --git a/generators/typescript/utils/contexts/src/commons/GeneratedModule.ts b/generators/typescript/utils/contexts/src/commons/GeneratedModule.ts
new file mode 100644
index 00000000000..1dc5153afc9
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/commons/GeneratedModule.ts
@@ -0,0 +1,5 @@
+import { ModuleDeclarationStructure } from "ts-morph";
+
+export interface GeneratedModule {
+ generateModule(context: Context): ModuleDeclarationStructure | undefined;
+}
diff --git a/generators/typescript/utils/contexts/src/commons/GeneratedStatements.ts b/generators/typescript/utils/contexts/src/commons/GeneratedStatements.ts
new file mode 100644
index 00000000000..13fa8fd2834
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/commons/GeneratedStatements.ts
@@ -0,0 +1,7 @@
+import { StatementStructures, WriterFunction } from "ts-morph";
+
+export interface GeneratedStatements {
+ generateStatements: (
+ context: Context
+ ) => string | WriterFunction | string | WriterFunction | (string | WriterFunction | StatementStructures)[];
+}
diff --git a/generators/typescript/utils/contexts/src/commons/GeneratedUnion.ts b/generators/typescript/utils/contexts/src/commons/GeneratedUnion.ts
index b5e8a09c5e8..6250bd6355f 100644
--- a/generators/typescript/utils/contexts/src/commons/GeneratedUnion.ts
+++ b/generators/typescript/utils/contexts/src/commons/GeneratedUnion.ts
@@ -1,7 +1,6 @@
import { ts } from "ts-morph";
-import { GeneratedFile } from "./GeneratedFile";
-export interface GeneratedUnion extends GeneratedFile {
+export interface GeneratedUnion {
discriminant: string;
visitPropertyName: string;
getReferenceTo: (context: Context) => ts.TypeNode;
diff --git a/generators/typescript/utils/contexts/src/commons/GeneratedUnionInlineMemberNode.ts b/generators/typescript/utils/contexts/src/commons/GeneratedUnionInlineMemberNode.ts
new file mode 100644
index 00000000000..19c5d2c7445
--- /dev/null
+++ b/generators/typescript/utils/contexts/src/commons/GeneratedUnionInlineMemberNode.ts
@@ -0,0 +1,5 @@
+import { ts } from "ts-morph";
+
+export interface GeneratedUnionInlineMemberNode {
+ generateForInlineUnion(context: Context): ts.TypeNode;
+}
diff --git a/generators/typescript/utils/contexts/src/express-context/ExpressContext.ts b/generators/typescript/utils/contexts/src/express-context/ExpressContext.ts
index c6a6e1abcfa..7b4d3785955 100644
--- a/generators/typescript/utils/contexts/src/express-context/ExpressContext.ts
+++ b/generators/typescript/utils/contexts/src/express-context/ExpressContext.ts
@@ -1,4 +1,4 @@
-import { ModelContext } from "../model-context/ModelContext";
+import { BaseContext } from "../base-context";
import { ExpressEndpointTypeSchemasContext } from "./express-endpoint-type-schemas";
import { ExpressErrorContext } from "./express-error";
import { ExpressErrorSchemaContext } from "./express-error-schema";
@@ -8,7 +8,7 @@ import { ExpressRegisterContext } from "./express-register";
import { ExpressServiceContext } from "./express-service";
import { GenericAPIExpressErrorContext } from "./generic-api-express-error";
-export interface ExpressContext extends ModelContext {
+export interface ExpressContext extends BaseContext {
expressEndpointTypeSchemas: ExpressEndpointTypeSchemasContext;
expressError: ExpressErrorContext;
expressErrorSchema: ExpressErrorSchemaContext;
diff --git a/generators/typescript/utils/contexts/src/model-context/ModelContext.ts b/generators/typescript/utils/contexts/src/model-context/ModelContext.ts
index f4dddef8658..ff3676aed4c 100644
--- a/generators/typescript/utils/contexts/src/model-context/ModelContext.ts
+++ b/generators/typescript/utils/contexts/src/model-context/ModelContext.ts
@@ -1,9 +1,3 @@
import { BaseContext } from "../base-context";
-import { TypeContext } from "./type";
-import { TypeSchemaContext } from "./type-schema";
-export interface ModelContext extends BaseContext {
- type: TypeContext;
- typeSchema: TypeSchemaContext;
- includeSerdeLayer: boolean;
-}
+export interface ModelContext extends BaseContext {}
diff --git a/generators/typescript/utils/contexts/src/model-context/index.ts b/generators/typescript/utils/contexts/src/model-context/index.ts
index e82e43cc427..e1eba561e55 100644
--- a/generators/typescript/utils/contexts/src/model-context/index.ts
+++ b/generators/typescript/utils/contexts/src/model-context/index.ts
@@ -1,3 +1,4 @@
export { type ModelContext } from "./ModelContext";
-export * from "./type";
-export * from "./type-schema";
+
+export * from "../base-context/type";
+export * from "../base-context/type-schema";
diff --git a/generators/typescript/utils/contexts/src/model-context/type/BaseGeneratedType.ts b/generators/typescript/utils/contexts/src/model-context/type/BaseGeneratedType.ts
deleted file mode 100644
index 8dd48ce23e3..00000000000
--- a/generators/typescript/utils/contexts/src/model-context/type/BaseGeneratedType.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { ExampleTypeShape } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts } from "@fern-typescript/commons";
-import { ts } from "ts-morph";
-import { GeneratedFile } from "../../commons/GeneratedFile";
-
-export interface BaseGeneratedType extends GeneratedFile {
- buildExample: (example: ExampleTypeShape, context: Context, opts: GetReferenceOpts) => ts.Expression;
-}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedObjectType.ts b/generators/typescript/utils/contexts/src/model-context/type/GeneratedObjectType.ts
deleted file mode 100644
index 3213cb7955c..00000000000
--- a/generators/typescript/utils/contexts/src/model-context/type/GeneratedObjectType.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { ExampleTypeShape, TypeReference } from "@fern-fern/ir-sdk/api";
-import { GetReferenceOpts } from "@fern-typescript/commons";
-import { ts } from "ts-morph";
-import { BaseGeneratedType } from "./BaseGeneratedType";
-
-export interface GeneratedObjectType extends BaseGeneratedType {
- type: "object";
- getAllPropertiesIncludingExtensions: (
- context: Context
- ) => { wireKey: string; propertyKey: string; type: TypeReference }[];
- getPropertyKey: (args: { propertyWireKey: string }) => string;
- buildExampleProperties: (
- example: ExampleTypeShape,
- context: Context,
- opts: GetReferenceOpts
- ) => ts.ObjectLiteralElementLike[];
-}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/GeneratedTypeReferenceExample.ts b/generators/typescript/utils/contexts/src/model-context/type/GeneratedTypeReferenceExample.ts
deleted file mode 100644
index 9a2fe5bf073..00000000000
--- a/generators/typescript/utils/contexts/src/model-context/type/GeneratedTypeReferenceExample.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { GetReferenceOpts } from "@fern-typescript/commons";
-import { ts } from "ts-morph";
-import { ModelContext } from "../ModelContext";
-
-export interface GeneratedTypeReferenceExample {
- build: (context: ModelContext, opts: GetReferenceOpts) => ts.Expression;
-}
diff --git a/generators/typescript/utils/contexts/src/model-context/type/TypeContext.ts b/generators/typescript/utils/contexts/src/model-context/type/TypeContext.ts
deleted file mode 100644
index 9b5721b019a..00000000000
--- a/generators/typescript/utils/contexts/src/model-context/type/TypeContext.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {
- DeclaredTypeName,
- ExampleTypeReference,
- ResolvedTypeReference,
- TypeDeclaration,
- TypeId,
- TypeReference
-} from "@fern-fern/ir-sdk/api";
-import { Reference, TypeReferenceNode } from "@fern-typescript/commons";
-import { ts } from "ts-morph";
-import { GeneratedType } from "./GeneratedType";
-import { GeneratedTypeReferenceExample } from "./GeneratedTypeReferenceExample";
-
-export interface TypeContext {
- getReferenceToType: (typeReference: TypeReference) => TypeReferenceNode;
- stringify: (
- valueToStringify: ts.Expression,
- valueType: TypeReference,
- opts: { includeNullCheckIfOptional: boolean }
- ) => ts.Expression;
- getReferenceToNamedType: (typeName: DeclaredTypeName) => Reference;
- resolveTypeReference: (typeReference: TypeReference) => ResolvedTypeReference;
- resolveTypeName: (typeName: DeclaredTypeName) => ResolvedTypeReference;
- getTypeDeclaration: (typeName: DeclaredTypeName) => TypeDeclaration;
- getGeneratedType: (typeName: DeclaredTypeName) => GeneratedType;
- getGeneratedTypeById: (typeId: TypeId) => GeneratedType;
- getGeneratedExample: (example: ExampleTypeReference) => GeneratedTypeReferenceExample;
-}
diff --git a/generators/typescript/utils/contexts/src/sdk-context/SdkContext.ts b/generators/typescript/utils/contexts/src/sdk-context/SdkContext.ts
index c05084ab1ef..30b31c48c44 100644
--- a/generators/typescript/utils/contexts/src/sdk-context/SdkContext.ts
+++ b/generators/typescript/utils/contexts/src/sdk-context/SdkContext.ts
@@ -2,7 +2,6 @@ import { FernGeneratorExec } from "@fern-fern/generator-exec-sdk";
import { IntermediateRepresentation } from "@fern-fern/ir-sdk/api";
import { JavaScriptRuntime, NpmPackage } from "@fern-typescript/commons";
import { ts } from "ts-morph";
-import { ModelContext } from "../model-context/ModelContext";
import { EndpointErrorUnionContext } from "./endpoint-error-union";
import { EnvironmentsContext } from "./environments";
import { GenericAPISdkErrorContext } from "./generic-api-sdk-error";
@@ -16,8 +15,9 @@ import { TimeoutSdkErrorContext } from "./timeout-sdk-error";
import { VersionContext } from "./version";
import { GeneratorNotificationService } from "@fern-api/base-generator";
import { Logger } from "@fern-api/logger";
+import { BaseContext } from "../base-context";
-export interface SdkContext extends ModelContext {
+export interface SdkContext extends BaseContext {
logger: Logger;
version: string | undefined;
ir: IntermediateRepresentation;
diff --git a/generators/typescript/utils/resolvers/package.json b/generators/typescript/utils/resolvers/package.json
index 1dfcf57c5ba..a048167788f 100644
--- a/generators/typescript/utils/resolvers/package.json
+++ b/generators/typescript/utils/resolvers/package.json
@@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
- "@fern-fern/ir-sdk": "53.8.0",
+ "@fern-fern/ir-sdk": "53.23.0",
"@fern-typescript/commons": "workspace:*"
},
"devDependencies": {
diff --git a/package.json b/package.json
index dce7ca97635..d4bfe10df9d 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"lint:eslint:fix": "pnpm lint:eslint --fix",
"lint:style": "stylelint 'packages/**/src/**/*.scss' --allow-empty-input --max-warnings 0",
"lint:style:fix": "pnpm lint:style --fix",
+ "lint:staged": "lint-staged",
"format": "prettier --write --ignore-unknown --ignore-path ./shared/.prettierignore \"**\"",
"format:fix": "pnpm format --ignore-path ./shared/.prettierignore \"**\"",
"format:check": "prettier --check --ignore-unknown --ignore-path ./shared/.prettierignore \"**\"",
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/ExampleEndpointFactory.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/ExampleEndpointFactory.ts
index f8734c32635..de214f06683 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/ExampleEndpointFactory.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/ExampleEndpointFactory.ts
@@ -586,6 +586,7 @@ function convertMultipartRequestToSchema(request: RequestWithExample.Multipart):
groupName: undefined,
additionalProperties: false,
availability: undefined,
- source: request.source
+ source: request.source,
+ inline: undefined
});
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/convertSecurityScheme.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/convertSecurityScheme.ts
index 5bac4362815..9fe924b0dfe 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/convertSecurityScheme.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/convertSecurityScheme.ts
@@ -101,7 +101,8 @@ function getScopes(oauthSecurityScheme: OpenAPIV3.OAuth2SecurityScheme, source:
wrapAsNullable: false,
groupName: undefined,
context: undefined,
- source
+ source,
+ inline: undefined
});
const schema = convertSchemaWithExampleToSchema(schemaWithExample);
if (schema.type === "enum") {
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/endpoint/convertParameters.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/endpoint/convertParameters.ts
index b0803ca4e08..eba3fb4b241 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/endpoint/convertParameters.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/converters/endpoint/convertParameters.ts
@@ -126,7 +126,8 @@ export function convertParameters({
}),
description: undefined,
availability,
- groupName: undefined
+ groupName: undefined,
+ inline: undefined
});
if (
resolvedParameter.in === "header" &&
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts
index 7555b1183b7..97f9f942c70 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/openapi/v3/extensions/getFernTypeExtension.ts
@@ -247,7 +247,8 @@ export function getSchemaFromFernType({
availability,
groupName,
encoding: undefined,
- example: undefined
+ example: undefined,
+ inline: undefined
})
: undefined,
list: (itemType) =>
@@ -260,7 +261,8 @@ export function getSchemaFromFernType({
description,
availability,
groupName,
- example: undefined
+ example: undefined,
+ inline: undefined
})
: undefined,
optional: (itemType) =>
@@ -272,7 +274,8 @@ export function getSchemaFromFernType({
value: itemType,
description,
availability,
- groupName
+ groupName,
+ inline: undefined
})
: undefined,
set: (itemType) =>
@@ -285,7 +288,8 @@ export function getSchemaFromFernType({
description,
availability,
groupName,
- example: undefined
+ example: undefined,
+ inline: undefined
})
: undefined,
literal: (literal) =>
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertAdditionalProperties.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertAdditionalProperties.ts
index 790388ebea1..c2da91f6167 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertAdditionalProperties.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertAdditionalProperties.ts
@@ -1,3 +1,4 @@
+import { assertNever } from "@fern-api/core-utils";
import {
Availability,
Encoding,
@@ -104,13 +105,21 @@ export function convertAdditionalProperties({
}),
groupName: undefined
},
- valueSchema: convertSchema(
- additionalProperties,
- context.options.optionalAdditionalProperties ? wrapAsNullable : false,
- context,
- [...breadcrumbs, "Value"],
- source,
- namespace
+ // Whether a type is inline is usually determined later by checking if a declaration is nested within another declaration,
+ // however this map is generated from the additionalProperties and thus is inline of the object (depending on the value type),
+ // so we allways add inline (depending on the value type).
+ valueSchema: addInline(
+ convertSchema(
+ additionalProperties,
+ context.options.optionalAdditionalProperties ? wrapAsNullable : false,
+ context,
+ [...breadcrumbs, "Value"],
+ source,
+ namespace,
+ undefined,
+ undefined,
+ undefined
+ )
),
groupName,
example,
@@ -118,6 +127,34 @@ export function convertAdditionalProperties({
});
}
+function addInline(schema: SchemaWithExample): SchemaWithExample {
+ switch (schema.type) {
+ case "array":
+ case "enum":
+ case "map":
+ case "object":
+ schema.inline = true;
+ break;
+ case "literal":
+ case "primitive":
+ case "reference":
+ case "unknown":
+ break;
+ case "nullable":
+ case "optional":
+ schema.inline = true;
+ schema.value = addInline(schema.value);
+ break;
+ case "oneOf":
+ schema.value.inline = true;
+ break;
+ default:
+ assertNever(schema);
+ }
+
+ return schema;
+}
+
export function wrapMap({
nameOverride,
generatedName,
@@ -158,11 +195,13 @@ export function wrapMap({
value: valueSchema,
groupName,
encoding,
- example
+ example,
+ inline: undefined
}),
description,
availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return SchemaWithExample.map({
@@ -175,7 +214,8 @@ export function wrapMap({
value: valueSchema,
groupName,
encoding,
- example
+ example,
+ inline: undefined
});
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertArray.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertArray.ts
index 8dfb49a657d..3e5acaf1f82 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertArray.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertArray.ts
@@ -91,11 +91,13 @@ export function wrapArray({
description,
availability,
groupName,
- example
+ example,
+ inline: undefined
}),
description,
availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return SchemaWithExample.array({
@@ -106,6 +108,7 @@ export function wrapArray({
description,
availability,
groupName,
- example
+ example,
+ inline: undefined
});
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertDiscriminatedOneOf.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertDiscriminatedOneOf.ts
index f36afe84672..c1606ce6d33 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertDiscriminatedOneOf.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertDiscriminatedOneOf.ts
@@ -243,12 +243,14 @@ export function wrapDiscriminantedOneOf({
commonProperties: properties,
groupName,
encoding: undefined,
- source
+ source,
+ inline: undefined
})
),
groupName,
description,
- availability
+ availability,
+ inline: undefined
});
}
return SchemaWithExample.oneOf(
@@ -263,7 +265,8 @@ export function wrapDiscriminantedOneOf({
commonProperties: properties,
groupName,
encoding: undefined,
- source
+ source,
+ inline: undefined
})
);
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertEnum.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertEnum.ts
index a46952d5591..2127a32d556 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertEnum.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertEnum.ts
@@ -23,7 +23,8 @@ export function convertEnum({
wrapAsNullable,
groupName,
context,
- source
+ source,
+ inline
}: {
nameOverride: string | undefined;
generatedName: string;
@@ -38,6 +39,7 @@ export function convertEnum({
groupName: SdkGroupName | undefined;
context: SchemaParserContext | undefined;
source: Source;
+ inline: boolean | undefined;
}): SchemaWithExample {
const strippedEnumVarNames = stripCommonPrefix(enumVarNames ?? []);
const uniqueValues = new Set(enumValues);
@@ -80,7 +82,8 @@ export function convertEnum({
description,
availability,
groupName,
- source
+ source,
+ inline
});
}
@@ -94,7 +97,8 @@ export function wrapEnum({
description,
availability,
groupName,
- source
+ source,
+ inline
}: {
wrapAsNullable: boolean;
nameOverride: string | undefined;
@@ -106,6 +110,7 @@ export function wrapEnum({
availability: Availability | undefined;
groupName: SdkGroupName | undefined;
source: Source;
+ inline: boolean | undefined;
}): SchemaWithExample {
if (wrapAsNullable) {
return SchemaWithExample.nullable({
@@ -122,11 +127,13 @@ export function wrapEnum({
availability,
example: undefined,
groupName,
- source
+ source,
+ inline
}),
description,
availability,
- groupName
+ groupName,
+ inline
});
}
return SchemaWithExample.enum({
@@ -139,7 +146,8 @@ export function wrapEnum({
default: _default,
example: undefined,
groupName,
- source
+ source,
+ inline
});
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertLiteral.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertLiteral.ts
index 341281bf377..3d9c34e4a74 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertLiteral.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertLiteral.ts
@@ -46,7 +46,8 @@ export function convertLiteral({
}),
description,
availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return SchemaWithExample.literal({
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertObject.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertObject.ts
index 562df7f040f..aaabbcb1280 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertObject.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertObject.ts
@@ -108,7 +108,8 @@ export function convertObject({
value: property.schema,
description: undefined,
availability: property.availability,
- groupName: undefined
+ groupName: undefined,
+ inline: undefined
})
};
}
@@ -195,7 +196,8 @@ export function convertObject({
description: undefined,
availability,
value: convertSchema(propertySchema, false, context, propertyBreadcrumbs, source, namespace),
- groupName
+ groupName,
+ inline: undefined
});
const conflicts: Record = {};
@@ -304,11 +306,13 @@ export function wrapObject({
fullExamples,
additionalProperties: isAdditionalPropertiesAny(additionalProperties),
availability: undefined,
- source
+ source,
+ inline: undefined
}),
description,
availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return SchemaWithExample.object({
@@ -323,7 +327,8 @@ export function wrapObject({
fullExamples,
additionalProperties: isAdditionalPropertiesAny(additionalProperties),
availability,
- source
+ source,
+ inline: undefined
});
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertSchemas.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertSchemas.ts
index 07de8a6f125..afdf1b27279 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertSchemas.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertSchemas.ts
@@ -126,7 +126,8 @@ export function convertReferenceObject(
value: referenceSchema,
description: undefined,
availability: undefined,
- groupName: undefined
+ groupName: undefined,
+ inline: undefined
});
} else {
return referenceSchema;
@@ -269,7 +270,8 @@ export function convertSchemaObject(
wrapAsNullable,
groupName,
context,
- source
+ source,
+ inline: undefined
});
}
@@ -299,7 +301,8 @@ export function convertSchemaObject(
),
groupName,
description: schema.description,
- availability
+ availability,
+ inline: undefined
});
} else if (secondElement === "null") {
return SchemaWithExample.nullable({
@@ -323,7 +326,8 @@ export function convertSchemaObject(
),
groupName,
description: schema.description,
- availability
+ availability,
+ inline: undefined
});
}
}
@@ -666,7 +670,8 @@ export function convertSchemaObject(
wrapAsNullable,
groupName,
context,
- source
+ source,
+ inline: undefined
});
}
@@ -1000,7 +1005,8 @@ function maybeInjectDescriptionOrGroupName(
value: schema.value,
description,
availability: schema.availability,
- groupName
+ groupName,
+ inline: undefined
});
} else if (schema.type === "nullable") {
return SchemaWithExample.nullable({
@@ -1010,7 +1016,8 @@ function maybeInjectDescriptionOrGroupName(
value: schema.value,
description,
availability: schema.availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return schema;
@@ -1072,7 +1079,8 @@ export function wrapLiteral({
}),
groupName,
description,
- availability
+ availability,
+ inline: undefined
});
}
return SchemaWithExample.literal({
@@ -1122,7 +1130,8 @@ export function wrapPrimitive({
}),
groupName,
description,
- availability
+ availability,
+ inline: undefined
});
}
return SchemaWithExample.primitive({
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertUndiscriminatedOneOf.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertUndiscriminatedOneOf.ts
index 112ffd85f71..2a7392f9cb2 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertUndiscriminatedOneOf.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/convertUndiscriminatedOneOf.ts
@@ -132,7 +132,8 @@ export function convertUndiscriminatedOneOf({
_default: undefined,
groupName,
context,
- source
+ source,
+ inline: undefined
});
}
@@ -265,7 +266,8 @@ export function convertUndiscriminatedOneOfWithDiscriminant({
_default: undefined,
groupName,
context,
- source
+ source,
+ inline: undefined
});
}
@@ -384,12 +386,14 @@ export function wrapUndiscriminantedOneOf({
schemas: subtypes,
groupName,
encoding,
- source
+ source,
+ inline: undefined
})
),
description,
availability,
- groupName
+ groupName,
+ inline: undefined
});
}
return SchemaWithExample.oneOf(
@@ -402,7 +406,8 @@ export function wrapUndiscriminantedOneOf({
schemas: subtypes,
groupName,
encoding,
- source
+ source,
+ inline: undefined
})
);
}
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaToSchemaWithExample.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaToSchemaWithExample.ts
index 5c15ae4f6d0..09d374a2688 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaToSchemaWithExample.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaToSchemaWithExample.ts
@@ -25,7 +25,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
fullExamples: undefined,
additionalProperties: schema.additionalProperties,
availability: schema.availability,
- source: schema.source
+ source: schema.source,
+ inline: undefined
});
case "array":
return SchemaWithExample.array({
@@ -36,7 +37,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
title: schema.title,
nameOverride: schema.nameOverride,
groupName: schema.groupName,
- example: undefined
+ example: undefined,
+ inline: undefined
});
case "enum":
return SchemaWithExample.enum({
@@ -49,7 +51,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
default: schema.default,
groupName: schema.groupName,
example: undefined,
- source: schema.source
+ source: schema.source,
+ inline: undefined
});
case "literal":
return SchemaWithExample.literal({
@@ -69,7 +72,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
description: schema.description,
availability: schema.availability,
value: convertSchemaToSchemaWithExample(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: undefined
});
case "optional":
return SchemaWithExample.optional({
@@ -79,7 +83,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
description: schema.description,
availability: schema.availability,
value: convertSchemaToSchemaWithExample(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: undefined
});
case "primitive":
return SchemaWithExample.primitive({
@@ -110,7 +115,8 @@ export function convertSchemaToSchemaWithExample(schema: Schema): SchemaWithExam
title: schema.title,
groupName: schema.groupName,
encoding: schema.encoding,
- example: undefined
+ example: undefined,
+ inline: undefined
});
case "reference":
return SchemaWithExample.reference({
@@ -150,7 +156,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: Schema): Schema
description: undefined,
availability: undefined,
value: convertSchemaToSchemaWithExample(schema),
- groupName: undefined
+ groupName: undefined,
+ inline: undefined
});
case "object":
case "array":
@@ -167,7 +174,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: Schema): Schema
description: undefined,
availability: schema.availability,
value: convertSchemaToSchemaWithExample(schema),
- groupName: undefined
+ groupName: undefined,
+ inline: undefined
});
case "optional":
return SchemaWithExample.optional({
@@ -177,7 +185,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: Schema): Schema
description: schema.description,
availability: schema.availability,
value: convertSchemaToSchemaWithExample(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: undefined
});
case "oneOf": {
const oneOfSchema = convertToOneOf(schema.value);
@@ -188,7 +197,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: Schema): Schema
description: oneOfSchema.description,
availability: oneOfSchema.availability,
value: SchemaWithExample.oneOf(convertToOneOf(schema.value)),
- groupName: oneOfSchema.groupName
+ groupName: oneOfSchema.groupName,
+ inline: undefined
});
}
default:
@@ -219,7 +229,8 @@ function convertToOneOf(oneOfSchema: OneOfSchema): OneOfSchemaWithExample {
),
groupName: oneOfSchema.groupName,
encoding: oneOfSchema.encoding,
- source: oneOfSchema.source
+ source: oneOfSchema.source,
+ inline: undefined
});
case "undisciminated":
return OneOfSchemaWithExample.undisciminated({
@@ -231,7 +242,8 @@ function convertToOneOf(oneOfSchema: OneOfSchema): OneOfSchemaWithExample {
schemas: oneOfSchema.schemas.map((oneOfSchema) => convertSchemaToSchemaWithExample(oneOfSchema)),
groupName: oneOfSchema.groupName,
encoding: oneOfSchema.encoding,
- source: oneOfSchema.source
+ source: oneOfSchema.source,
+ inline: undefined
});
default:
assertNever(oneOfSchema);
diff --git a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaWithExampleToSchema.ts b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaWithExampleToSchema.ts
index 108ff6b3063..5fbee12bbd0 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaWithExampleToSchema.ts
+++ b/packages/cli/api-importers/openapi/openapi-ir-parser/src/schema/utils/convertSchemaWithExampleToSchema.ts
@@ -24,7 +24,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
groupName: schema.groupName,
additionalProperties: schema.additionalProperties,
availability: schema.availability,
- source: schema.source
+ source: schema.source,
+ inline: schema.inline
});
case "array":
return Schema.array({
@@ -34,7 +35,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
generatedName: schema.generatedName,
nameOverride: schema.nameOverride,
title: schema.title,
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: schema.inline
});
case "enum":
return Schema.enum({
@@ -46,7 +48,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
values: schema.values,
default: schema.default,
groupName: schema.groupName,
- source: schema.source
+ source: schema.source,
+ inline: schema.inline
});
case "literal":
return Schema.literal({
@@ -66,7 +69,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
description: schema.description,
availability: schema.availability,
value: convertSchemaWithExampleToSchema(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: schema.inline
});
case "optional":
return Schema.optional({
@@ -76,7 +80,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
description: schema.description,
availability: schema.availability,
value: convertSchemaWithExampleToSchema(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: schema.inline
});
case "primitive":
return Schema.primitive({
@@ -106,7 +111,8 @@ export function convertSchemaWithExampleToSchema(schema: SchemaWithExample): Sch
title: schema.title,
nameOverride: schema.nameOverride,
groupName: schema.groupName,
- encoding: schema.encoding
+ encoding: schema.encoding,
+ inline: schema.inline
});
case "reference":
return Schema.reference({
@@ -146,7 +152,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: SchemaWithExamp
description: schema.description,
availability: schema.availability,
value: convertSchemaWithExampleToSchema(schema),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: undefined
});
case "optional":
return Schema.optional({
@@ -156,7 +163,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: SchemaWithExamp
description: schema.description,
availability: schema.availability,
value: convertSchemaWithExampleToSchema(schema.value),
- groupName: schema.groupName
+ groupName: schema.groupName,
+ inline: schema.inline
});
case "oneOf": {
const oneOfSchema = convertToOneOf(schema.value);
@@ -167,7 +175,8 @@ export function convertSchemaWithExampleToOptionalSchema(schema: SchemaWithExamp
description: oneOfSchema.description,
availability: oneOfSchema.availability,
value: Schema.oneOf(convertToOneOf(schema.value)),
- groupName: oneOfSchema.groupName
+ groupName: oneOfSchema.groupName,
+ inline: oneOfSchema.inline
});
}
default:
@@ -198,7 +207,8 @@ function convertToOneOf(oneOfSchema: OneOfSchemaWithExample): OneOfSchema {
),
groupName: oneOfSchema.groupName,
encoding: oneOfSchema.encoding,
- source: oneOfSchema.source
+ source: oneOfSchema.source,
+ inline: oneOfSchema.inline
});
case "undisciminated":
return OneOfSchema.undisciminated({
@@ -210,7 +220,8 @@ function convertToOneOf(oneOfSchema: OneOfSchemaWithExample): OneOfSchema {
schemas: oneOfSchema.schemas.map((oneOfSchema) => convertSchemaWithExampleToSchema(oneOfSchema)),
groupName: oneOfSchema.groupName,
encoding: oneOfSchema.encoding,
- source: oneOfSchema.source
+ source: oneOfSchema.source,
+ inline: oneOfSchema.inline
});
default:
assertNever(oneOfSchema);
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/apiture.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/apiture.json
index e53655a955b..833115b805e 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/apiture.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/apiture.json
@@ -4274,6 +4274,7 @@ This error response may have one of the following `type` values:
"viewCards",
"manageCards",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4447,6 +4448,7 @@ Account transfers are only allowed between `internal` and `external` accounts. A
"external",
"outside",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4607,6 +4609,7 @@ Account transfers are only allowed between `internal` and `external` accounts. A
"float",
"sameDay",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4667,6 +4670,7 @@ Account transfers are only allowed between `internal` and `external` accounts. A
"tel",
"web",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4889,6 +4893,7 @@ Account transfers are only allowed between `internal` and `external` accounts. A
"securityQuestions",
"authenticatorToken",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5031,6 +5036,7 @@ Account transfers are only allowed between `internal` and `external` accounts. A
"externalTransfer",
"billPay",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5157,6 +5163,7 @@ The client can use this value to localize the `items[].time` values to the local
"microDeposits",
"manual",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5286,6 +5293,7 @@ The client can use this value to localize the `items[].time` values to the local
"swiftBicCode",
"ibanAccountNumber",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5592,6 +5600,7 @@ The client can use this value to localize the `items[].time` values to the local
"loan",
"creditCard",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5786,6 +5795,7 @@ The client can use this value to localize the `items[].time` values to the local
"credit",
"debit",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6008,6 +6018,7 @@ The client can use this value to localize the `items[].time` values to the local
"check",
"other",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6043,6 +6054,7 @@ The client can use this value to localize the `items[].time` values to the local
"debit",
"credit",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6206,6 +6218,7 @@ The client can use this value to localize the `items[].time` values to the local
"closure",
"other",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6349,6 +6362,7 @@ The response may include dates prior to requested the start date, as that is use
"semiyearly",
"yearly",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6450,6 +6464,7 @@ The response may include dates prior to requested the start date, as that is use
"fixed",
"variable",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6538,6 +6553,7 @@ For recurring transfer schedules, `endsOn`, `count`, and `amountLimit` are mutua
"credit",
"both",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6638,6 +6654,7 @@ For recurring transfer schedules, `endsOn`, `count`, and `amountLimit` are mutua
"failed",
"other",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6687,6 +6704,7 @@ For recurring transfer schedules, `endsOn`, `count`, and `amountLimit` are mutua
"domesticWireTransfer",
"internationalWireTransfer",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13632,6 +13650,7 @@ Optionally, an agent can access a business customer's ACH accounts when acting o
"internal",
"external",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/aries.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/aries.json
index 7c52fb1a7d7..ad8c91902c0 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/aries.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/aries.json
@@ -427,6 +427,7 @@
"value": "present-proof",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -628,6 +629,7 @@
"manual",
"auto",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -644,6 +646,7 @@
"value": "didexchange/1.0",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -655,6 +658,7 @@
"multi",
"static",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -667,6 +671,7 @@
"active",
"error",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -679,6 +684,7 @@
"inviter",
"responder",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -865,6 +871,7 @@
"allowed",
"disallowed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -875,6 +882,7 @@
"allowed",
"disallowed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -885,6 +893,7 @@
"allowed",
"disallowed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -895,6 +904,7 @@
"required",
"preferred",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -954,6 +964,7 @@
"managed",
"unmanaged",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1700,6 +1711,7 @@
"ed25519",
"bls12381g2",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1710,6 +1722,7 @@
"ed25519",
"bls12381g2",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1721,6 +1734,7 @@
"posted",
"wallet_only",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2012,6 +2026,7 @@
"USER",
"ROLE_REMOVE",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2428,6 +2443,7 @@
"GE",
"GT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2596,6 +2612,7 @@
"value": ">",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2919,6 +2936,7 @@
"value": ">",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3765,6 +3783,7 @@
"add",
"remove",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4259,6 +4278,7 @@
"sender",
"receiver",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4286,6 +4306,7 @@
"done",
"deleted",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4481,6 +4502,7 @@
"value": "goal-code",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5051,6 +5073,7 @@
"TRANSACTION_ENDORSER",
"reset",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5062,6 +5085,7 @@
"TRANSACTION_ENDORSER",
"reset",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5463,6 +5487,7 @@
"self",
"external",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5490,6 +5515,7 @@
"holder",
"issuer",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5668,6 +5694,7 @@
"self",
"external",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5707,6 +5734,7 @@
"prover",
"verifier",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5717,6 +5745,7 @@
"true",
"false",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6062,6 +6091,7 @@
"self",
"external",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6130,6 +6160,7 @@
"issuer",
"holder",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6177,6 +6208,7 @@
"abandoned",
"deleted",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6680,6 +6712,7 @@
"self",
"external",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6715,6 +6748,7 @@
"prover",
"verifier",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6750,6 +6784,7 @@
"abandoned",
"deleted",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6760,6 +6795,7 @@
"true",
"false",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7042,6 +7078,7 @@
"managed",
"unmanaged",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7072,6 +7109,7 @@
"required",
"preferred",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7082,6 +7120,7 @@
"ISSUANCE_ON_DEMAND",
"ISSUANCE_BY_DEFAULT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7116,6 +7155,7 @@
"required",
"preferred",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7134,6 +7174,7 @@
"all",
"pick",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7394,6 +7435,7 @@ types:
- value: present-proof
name: PresentProof
docs: Attachment type
+ inline: true
source:
openapi: ../openapi.yml
AttachmentDef:
@@ -7464,6 +7506,7 @@ types:
- manual
- auto
docs: 'Connection acceptance: manual or auto'
+ inline: true
source:
openapi: ../openapi.yml
ConnRecordConnectionProtocol:
@@ -7473,6 +7516,7 @@ types:
- value: didexchange/1.0
name: Didexchange10
docs: Connection protocol used
+ inline: true
source:
openapi: ../openapi.yml
ConnRecordInvitationMode:
@@ -7481,6 +7525,7 @@ types:
- multi
- static
docs: Invitation mode
+ inline: true
source:
openapi: ../openapi.yml
ConnRecordRoutingState:
@@ -7490,6 +7535,7 @@ types:
- active
- error
docs: Routing state of connection
+ inline: true
source:
openapi: ../openapi.yml
ConnRecordTheirRole:
@@ -7499,6 +7545,7 @@ types:
- inviter
- responder
docs: Their role in the connection protocol
+ inline: true
source:
openapi: ../openapi.yml
ConnRecord:
@@ -7675,6 +7722,7 @@ types:
- required
- allowed
- disallowed
+ inline: true
source:
openapi: ../openapi.yml
ConstraintsStatusRevoked:
@@ -7682,6 +7730,7 @@ types:
- required
- allowed
- disallowed
+ inline: true
source:
openapi: ../openapi.yml
ConstraintsStatusSuspended:
@@ -7689,6 +7738,7 @@ types:
- required
- allowed
- disallowed
+ inline: true
source:
openapi: ../openapi.yml
ConstraintsSubjectIsIssuer:
@@ -7696,6 +7746,7 @@ types:
- required
- preferred
docs: SubjectIsIssuer
+ inline: true
source:
openapi: ../openapi.yml
Constraints:
@@ -7723,6 +7774,7 @@ types:
- managed
- unmanaged
docs: Mode regarding management of wallet key
+ inline: true
source:
openapi: ../openapi.yml
CreateWalletResponseSettings:
@@ -8044,6 +8096,7 @@ types:
- ed25519
- bls12381g2
docs: Key type associated with the DID
+ inline: true
source:
openapi: ../openapi.yml
DidPosture:
@@ -8054,6 +8107,7 @@ types:
docs: >-
Whether DID is current public DID, posted to ledger but not current public
DID, or local to the wallet
+ inline: true
source:
openapi: ../openapi.yml
DID:
@@ -8090,6 +8144,7 @@ types:
docs: >-
Key type to use for the DID keypair. Validated with the chosen DID
method's supported key types.
+ inline: true
source:
openapi: ../openapi.yml
DIDCreateOptions:
@@ -8143,6 +8198,7 @@ types:
- required
- preferred
docs: Preference
+ inline: true
source:
openapi: ../openapi.yml
DIFField:
@@ -8167,6 +8223,7 @@ types:
- required
- preferred
docs: Preference
+ inline: true
source:
openapi: ../openapi.yml
DIFHolder:
@@ -8392,6 +8449,7 @@ types:
- USER
- ROLE_REMOVE
docs: Ledger role
+ inline: true
source:
openapi: ../openapi.yml
GetNymRoleResponse:
@@ -8630,6 +8688,7 @@ types:
- GE
- GT
docs: Predicate type
+ inline: true
source:
openapi: ../openapi.yml
IndyGEProofPred:
@@ -8716,6 +8775,7 @@ types:
- value: '>'
name: GreaterThan
docs: Predicate type ('<', '<=', '>=', or '>')
+ inline: true
source:
openapi: ../openapi.yml
IndyPresPredSpec:
@@ -8884,6 +8944,7 @@ types:
- value: '>'
name: GreaterThan
docs: Predicate type ('<', '<=', '>=', or '>')
+ inline: true
source:
openapi: ../openapi.yml
IndyProofReqPredSpec:
@@ -9082,6 +9143,7 @@ types:
- ISSUANCE_ON_DEMAND
- ISSUANCE_BY_DEFAULT
docs: Issuance type
+ inline: true
source:
openapi: ../openapi.yml
IndyRevRegDefValue:
@@ -9428,6 +9490,7 @@ types:
- add
- remove
docs: Action for specific key
+ inline: true
source:
openapi: ../openapi.yml
KeylistUpdateRule:
@@ -9721,6 +9784,7 @@ types:
- sender
- receiver
docs: OOB Role
+ inline: true
source:
openapi: ../openapi.yml
OobRecordState:
@@ -9737,6 +9801,7 @@ types:
- done
- deleted
docs: Out of band message exchange state
+ inline: true
source:
openapi: ../openapi.yml
OobRecord:
@@ -9893,6 +9958,7 @@ types:
- value: goal-code
name: GoalCode
docs: feature type
+ inline: true
source:
openapi: ../openapi.yml
QueryItem:
@@ -10147,6 +10213,7 @@ types:
- all
- pick
docs: Selection
+ inline: true
source:
openapi: ../openapi.yml
SubmissionRequirements:
@@ -10226,6 +10293,7 @@ types:
- TRANSACTION_ENDORSER
- reset
docs: My transaction related job
+ inline: true
source:
openapi: ../openapi.yml
TransactionJobsTransactionTheirJob:
@@ -10234,6 +10302,7 @@ types:
- TRANSACTION_ENDORSER
- reset
docs: Their transaction related job
+ inline: true
source:
openapi: ../openapi.yml
TransactionJobs:
@@ -10381,6 +10450,7 @@ types:
- self
- external
docs: 'Issue-credential exchange initiator: self or external'
+ inline: true
source:
openapi: ../openapi.yml
V10CredentialExchangeRole:
@@ -10388,6 +10458,7 @@ types:
- holder
- issuer
docs: 'Issue-credential exchange role: holder or issuer'
+ inline: true
source:
openapi: ../openapi.yml
V10CredentialExchange:
@@ -10536,6 +10607,7 @@ types:
- self
- external
docs: 'Present-proof exchange initiator: self or external'
+ inline: true
source:
openapi: ../openapi.yml
V10PresentationExchangeRole:
@@ -10543,6 +10615,7 @@ types:
- prover
- verifier
docs: 'Present-proof exchange role: prover or verifier'
+ inline: true
source:
openapi: ../openapi.yml
V10PresentationExchangeVerified:
@@ -10550,6 +10623,7 @@ types:
- 'true'
- 'false'
docs: 'Whether presentation is verified: true or false'
+ inline: true
source:
openapi: ../openapi.yml
V10PresentationExchange:
@@ -10664,6 +10738,7 @@ types:
- self
- external
docs: 'Issue-credential exchange initiator: self or external'
+ inline: true
source:
openapi: ../openapi.yml
V20CredExRecordRole:
@@ -10671,6 +10746,7 @@ types:
- issuer
- holder
docs: 'Issue-credential exchange role: holder or issuer'
+ inline: true
source:
openapi: ../openapi.yml
V20CredExRecordState:
@@ -10697,6 +10773,7 @@ types:
- abandoned
- deleted
docs: Issue-credential exchange state
+ inline: true
source:
openapi: ../openapi.yml
V20CredExRecord:
@@ -11118,6 +11195,7 @@ types:
- self
- external
docs: 'Present-proof exchange initiator: self or external'
+ inline: true
source:
openapi: ../openapi.yml
V20PresExRecordRole:
@@ -11125,6 +11203,7 @@ types:
- prover
- verifier
docs: 'Present-proof exchange role: prover or verifier'
+ inline: true
source:
openapi: ../openapi.yml
V20PresExRecordState:
@@ -11145,6 +11224,7 @@ types:
- abandoned
- deleted
docs: Present-proof exchange state
+ inline: true
source:
openapi: ../openapi.yml
V20PresExRecordVerified:
@@ -11152,6 +11232,7 @@ types:
- 'true'
- 'false'
docs: 'Whether presentation is verified: ''true'' or ''false'''
+ inline: true
source:
openapi: ../openapi.yml
V20PresExRecord:
@@ -11374,6 +11455,7 @@ types:
- managed
- unmanaged
docs: Mode regarding management of wallet key
+ inline: true
source:
openapi: ../openapi.yml
WalletRecordSettings:
@@ -13036,6 +13118,7 @@ docs: Simple messaging
"value": "didexchange/1.0",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13052,6 +13135,7 @@ docs: Simple messaging
"active",
"completed",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13063,6 +13147,7 @@ docs: Simple messaging
"inviter",
"responder",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16700,6 +16785,7 @@ docs: Feature discovery v2
"TRANSACTION_ENDORSER",
"reset",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -18414,6 +18500,7 @@ docs: Introduction of known parties
"issuer",
"holder",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -18432,6 +18519,7 @@ docs: Introduction of known parties
"credential_revoked",
"abandoned",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20316,6 +20404,7 @@ types:
"issuer",
"holder",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20361,6 +20450,7 @@ types:
},
"abandoned",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -21702,6 +21792,7 @@ docs: Sign and verify json-ld data
"Profile",
"LinkedDomains",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -21714,6 +21805,7 @@ docs: Sign and verify json-ld data
"NETWORK_MONITOR",
"reset",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -22787,6 +22879,7 @@ docs: Interaction with ledger
"client",
"server",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -22797,6 +22890,7 @@ docs: Interaction with ledger
"granted",
"denied",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -23724,6 +23818,7 @@ types:
"both",
"base",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -23735,6 +23830,7 @@ types:
"ARGON2I_INT",
"RAW",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -23746,6 +23842,7 @@ types:
"in_memory",
"indy",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -23757,6 +23854,7 @@ types:
"both",
"base",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -23774,6 +23872,7 @@ types:
Dispatch only to webhooks associated with this wallet. base -
Dispatch only to webhooks associated with the base wallet.
both - Dispatch to both webhook targets.
+ inline: true
source:
openapi: ../openapi.yml
CreateWalletRequestWalletKeyDerivation:
@@ -23782,6 +23881,7 @@ types:
- ARGON2I_INT
- RAW
docs: Key derivation
+ inline: true
source:
openapi: ../openapi.yml
CreateWalletRequestWalletType:
@@ -23790,6 +23890,7 @@ types:
- in_memory
- indy
docs: Type of the wallet to create
+ inline: true
source:
openapi: ../openapi.yml
UpdateWalletRequestWalletDispatchType:
@@ -23802,6 +23903,7 @@ types:
Dispatch only to webhooks associated with this wallet. base -
Dispatch only to webhooks associated with the base wallet.
both - Dispatch to both webhook targets.
+ inline: true
source:
openapi: ../openapi.yml
imports:
@@ -25546,6 +25648,7 @@ docs: Out-of-band connections
"prover",
"verifier",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -25562,6 +25665,7 @@ docs: Out-of-band connections
"presentation_acked",
"abandoned",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -26906,6 +27010,7 @@ types:
"prover",
"verifier",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -26939,6 +27044,7 @@ types:
"done",
"abandoned",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -28633,6 +28739,7 @@ docs: did resolver interface.
"active",
"full",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -28643,6 +28750,7 @@ docs: did resolver interface.
"v1_0",
"v2_0",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -28655,6 +28763,7 @@ docs: did resolver interface.
"active",
"full",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -29406,6 +29515,7 @@ types:
- v1_0
- v2_0
docs: Specify which version of the revocation notification should be sent
+ inline: true
source:
openapi: ../openapi.yml
",
@@ -30609,6 +30719,7 @@ docs: Trust-ping over connection
"Profile",
"LinkedDomains",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -30618,6 +30729,7 @@ docs: Trust-ping over connection
"ed25519",
"bls12381g2",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -30627,6 +30739,7 @@ docs: Trust-ping over connection
"key",
"sov",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -30637,6 +30750,7 @@ docs: Trust-ping over connection
"posted",
"wallet_only",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -30671,6 +30785,7 @@ docs: Trust-ping over connection
docs: >-
Endpoint type to set (default 'Endpoint'); affects only public or posted
DIDs
+ inline: true
source:
openapi: ../openapi.yml
imports:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/assembly.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/assembly.json
index 28cf25bd848..d0ad7a97f3b 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/assembly.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/assembly.json
@@ -1294,6 +1294,7 @@
"success",
"unavailable",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1737,6 +1738,7 @@ Valid values are in the range [0, 1] inclusive.
"value": "us_social_security_number",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1834,6 +1836,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"default",
"basic",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2009,6 +2012,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"drivers_license",
"banking_information",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2096,6 +2100,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"NEUTRAL",
"NEGATIVE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2185,6 +2190,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"entity_type",
"hash",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2195,6 +2201,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"srt",
"vtt",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2207,6 +2214,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"conversational",
"catchy",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2221,6 +2229,7 @@ Can be any value between 0.0 and 1.0 inclusive.
"headline",
"paragraph",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2554,6 +2563,7 @@ See [Speech recognition](https://www.assemblyai.com/docs/Models/speech_recogniti
"default",
"high",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2641,6 +2651,7 @@ The default value is 'en_us'.
"uk",
"vi",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2777,6 +2788,7 @@ The default value is 'en_us'.
"value": "error",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6650,6 +6662,7 @@ docs: Real-time transcription
"value": "error",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/axle.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/axle.json
index c894a317c7d..a70148cc961 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/axle.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/axle.json
@@ -87,6 +87,7 @@
"COLL",
"COMP",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -184,6 +185,7 @@
"lessor",
"interest",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -275,6 +277,7 @@
- UIMPD
- COLL
- COMP
+ inline: true
source:
openapi: ../openapi.yml
Coverage:
@@ -335,6 +338,7 @@
- lessor
- interest
default: interest
+ inline: true
source:
openapi: ../openapi.yml
ThirdParty:
@@ -536,6 +540,7 @@
"auto",
"motorcycle",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -575,6 +580,7 @@ types:
enum:
- auto
- motorcycle
+ inline: true
source:
openapi: ../openapi.yml
Policy:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/belvo.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/belvo.json
index f53e5699ea0..fa029dd0715 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/belvo.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/belvo.json
@@ -6687,6 +6687,7 @@ In our documentation example, we use `{endpoint}` as a placeholder value. In pro
"SUCCEEDED",
"FAILED",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7781,6 +7782,7 @@ We return one of the following enum values:
"INDIVIDUAL",
"BUSINESS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7800,6 +7802,7 @@ We return one of the following enum values:
"SAVINGS",
"SALARY",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7817,6 +7820,7 @@ Can be either:
"LOAN_ACCOUNT",
"SAVINGS_ACCOUNT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7831,6 +7835,7 @@ Can be either:
"INDIVIDUAL",
"BUSINESS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7955,6 +7960,7 @@ Can be either:
"INFLOW",
"OUTFLOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7968,6 +7974,7 @@ Can be either:
"CPF",
"CNPJ",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7984,6 +7991,7 @@ Can be either:
"TI",
"NIT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8001,6 +8009,7 @@ Can be either:
"INDIVIDUAL",
"BUSINESS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8015,6 +8024,7 @@ Can be either:
"NSS",
"CURP",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8026,6 +8036,7 @@ Can be either:
"EMPLOYED",
"UNEMPLOYED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8048,6 +8059,7 @@ Can be either:
"ABSENCE",
"SICK_LEAVE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8066,6 +8078,7 @@ You can send through one of the following values:
"MEDIUM",
"LOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8092,6 +8105,7 @@ We return one of the following enum values:
"MEDIUM",
"LOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8114,6 +8128,7 @@ We return one of the following enum values:
"IRREGULAR",
"SINGLE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8146,6 +8161,7 @@ We return one of the following enum values:
"DEPOSIT",
"UNKNOWN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8159,6 +8175,7 @@ Can be either:
"CHECKING_ACCOUNT",
"SAVINGS_ACCOUNT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8186,6 +8203,7 @@ Can be either:
"credentials",
"openbanking",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8197,6 +8215,7 @@ Can be either:
"healthy",
"down",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8213,6 +8232,7 @@ Can be either:
"fiscal",
"employment",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8239,6 +8259,7 @@ We return one of the following values:
"PENSION",
"STOCK",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8259,6 +8280,7 @@ We return one of the following values:
"PENSION",
"VARIABLE_INCOME",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8288,6 +8310,7 @@ You can send through one or more of the following values:
"DEPOSIT",
"UNKNOWN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8333,6 +8356,7 @@ For Mexico's SAT, we return one of the following values:
"Pago",
"Traslado",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8363,6 +8387,7 @@ For more information, see our [Links](https://developers.belvo.com/docs/links-an
"single",
"recurrent",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8404,6 +8429,7 @@ We return one of the following values:
"unconfirmed",
"token_required",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8420,6 +8446,7 @@ We return one of the following values:
"INSURANCE_FEE",
"OTHERS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8434,6 +8461,7 @@ We return one of the following values:
"MONTHLY",
"YEARLY",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8444,6 +8472,7 @@ We return one of the following values:
"INDIVIDUAL",
"BUSINESS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8458,6 +8487,7 @@ We return one of the following values:
"PROCESSING",
"FAILED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8471,6 +8501,7 @@ We return one of the following values:
"open_finance",
"pse",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8486,6 +8517,7 @@ We return one of the following values:
"belvo",
"payments_way",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8501,6 +8533,7 @@ We return one of the following values:
"ACTIVE",
"INACTIVE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8514,6 +8547,7 @@ We return one of the following values:
"INFLOW",
"OUTFLOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8529,6 +8563,7 @@ We return one of the following values:
"BRA",
"COL",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8543,6 +8578,7 @@ We return one of the following values:
"BRL",
"COP",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8566,6 +8602,7 @@ We return one of the following values:
"REVERTED",
"UNCATEGORIZED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8615,6 +8652,7 @@ We return one of the following values:
},
"Taxes",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8637,6 +8675,7 @@ We return one of the following values:
"SUBSCRIPTION",
"REGULAR",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8648,6 +8687,7 @@ We return one of the following values:
"NEGATIVE",
"NO_OBLIGATIONS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8661,6 +8701,7 @@ We return one of the following values:
"PAID",
"PROVISIONED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8674,6 +8715,7 @@ We return one of the following values:
"NATIONAL",
"FOREIGN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8688,6 +8730,7 @@ We return one of the following values:
"OUTFLOW",
"INFLOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -28189,6 +28232,7 @@ types:
- FAILED
docs: |
The current status of the charge.
+ inline: true
source:
openapi: ../openapi.yml
ChargePaymentMethodDetails:
@@ -58602,6 +58646,7 @@ types:
"value": "-created_at",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -58611,6 +58656,7 @@ types:
"ACTIVE",
"INACTIVE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/deel.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/deel.json
index e9696a2567f..cb2f0dfb222 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/deel.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/deel.json
@@ -7396,6 +7396,7 @@
"client",
"contractor",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7614,6 +7615,7 @@
"rejected",
"waiting_for_client_payment",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8042,6 +8044,7 @@
"shield_msa",
"hris_direct_employee",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8057,6 +8060,7 @@
"payg_tasks",
"payg_milestones",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8068,6 +8072,7 @@
"client",
"contractor",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8093,6 +8098,7 @@
"total",
"status",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -8220,6 +8226,7 @@
"SICK_LEAVE",
"OTHER",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -8930,6 +8937,7 @@
"STANDARD",
"SPECIFIC",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -8946,6 +8954,7 @@
"value": "Part-time",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -8977,6 +8986,7 @@
"Skilled",
"Unskilled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -9080,6 +9090,7 @@
"ALLOWED_WITH_MAXIMUM_LIMITATION",
"NOT_ALLOWED",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -9128,6 +9139,7 @@
"STANDARD",
"SPECIFIC",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -9330,6 +9342,7 @@
"LIMITED_ROLLOVER",
"UNSET",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -9565,6 +9578,7 @@
"CALENDAR_DAYS",
"FULL_AMOUNT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -9640,6 +9654,7 @@
"value": "image/png",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -9691,6 +9706,7 @@
"CALENDAR_DAYS",
"FULL_AMOUNT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -9909,6 +9925,7 @@
"ENABLED",
"DISABLED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10397,6 +10414,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10418,6 +10436,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10623,6 +10642,7 @@
"withholding_tax",
"work",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10640,6 +10660,7 @@
"time_off",
"vat",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10676,6 +10697,7 @@
"failed",
"refunded",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10744,6 +10766,7 @@
"failed",
"refunded",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10768,6 +10791,7 @@
"SHIELD_DEPOSIT",
"EOR_MANAGEMENT_FEE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10832,6 +10856,7 @@
"individual",
"company",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10967,6 +10992,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -11005,6 +11031,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -11124,6 +11151,7 @@
"value": "tasks:write",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11474,6 +11502,7 @@
"mercury_wire",
"bt_pay_pal",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11510,6 +11539,7 @@
"paid",
"processing",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11843,6 +11873,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -11871,6 +11902,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -12084,6 +12116,7 @@
"CALENDAR_DAYS",
"FULL_AMOUNT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -12097,6 +12130,7 @@
"hris_direct_employee",
"service_account",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12231,6 +12265,7 @@
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12413,6 +12448,7 @@
"APPROVED",
"REJECTED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12423,6 +12459,7 @@
"SICK_LEAVE",
"OTHER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12537,6 +12574,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -12558,6 +12596,7 @@
"approved",
"declined",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -12814,6 +12853,7 @@
"enabled",
"disabled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -12839,6 +12879,7 @@
"Friday",
"Saturday",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12850,6 +12891,7 @@
"DAY_OF_LAST_WEEK",
"DAY_OF_MONTH",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12866,6 +12908,7 @@
"value": "calendar-month",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12877,6 +12920,7 @@
"REGULAR",
"WITHIN_MONTH",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12892,6 +12936,7 @@
"semimonthly",
"custom",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12907,6 +12952,7 @@
"semimonthly",
"custom",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -14119,6 +14165,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
TimesheetReviewsToCreate:
@@ -14146,6 +14193,7 @@
- approved
- declined
docs: Review status.
+ inline: true
source:
openapi: ../openapi.yml
PgoTaskReviewsByIdToCreate:
@@ -14163,6 +14211,7 @@
- approved
- declined
docs: Review status.
+ inline: true
source:
openapi: ../openapi.yml
PgoTaskReviewsToCreate:
@@ -14180,6 +14229,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
TimesheetReviewToCreate:
@@ -14487,6 +14537,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
InvoiceAdjustmentReviewsToCreate:
@@ -14509,6 +14560,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
InvoiceAdjustmentReviewToCreate:
@@ -15090,6 +15142,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
MilestoneReviewsToCreate:
@@ -15103,6 +15156,7 @@
enum:
- approved
- declined
+ inline: true
source:
openapi: ../openapi.yml
MilestoneReviewToCreate:
@@ -15137,6 +15191,7 @@
- CALENDAR_DAYS
- FULL_AMOUNT
docs: Either works days or calendar days
+ inline: true
source:
openapi: ../openapi.yml
EstimateFirstPaymentCompensationDetails:
@@ -15185,6 +15240,7 @@
- CALENDAR_DAYS
- FULL_AMOUNT
docs: Either works days or calendar days
+ inline: true
source:
openapi: ../openapi.yml
ProRata:
@@ -15520,6 +15576,7 @@
- CALENDAR_DAYS
- FULL_AMOUNT
docs: Either works days or calendar days
+ inline: true
source:
openapi: ../openapi.yml
FinalPaymentCalculated:
@@ -15775,6 +15832,7 @@
- value: Part-time
name: PartTime
docs: Is it a full-time contract or a part-time contract?
+ inline: true
source:
openapi: ../openapi.yml
EorContractToCreateEmploymentTimeOffType:
@@ -15785,6 +15843,7 @@
If you want to use standard number of holidays for this employee, choose
"STANDARD". If you want to enter a specific number of holidays, choose
"SPECIFIC" and enter the number of days in the holidays field.
+ inline: true
source:
openapi: ../openapi.yml
EorContractToCreateEmployment:
@@ -15888,6 +15947,7 @@
- Skilled
- Unskilled
docs: Type of worker.
+ inline: true
source:
openapi: ../openapi.yml
EorContractToCreateQuoteAdditionalFields:
@@ -16054,6 +16114,7 @@
- PRORATED
- STANDARD
- SPECIFIC
+ inline: true
source:
openapi: ../openapi.yml
EorCountryValidationsPartTimeHoliday:
@@ -16138,6 +16199,7 @@
- ALLOWED_WITHOUT_LIMITATION
- ALLOWED_WITH_MAXIMUM_LIMITATION
- NOT_ALLOWED
+ inline: true
source:
openapi: ../openapi.yml
EorCountryValidationsDefiniteContract:
@@ -16497,6 +16559,7 @@
- SICK_LEAVE
- OTHER
docs: Time off type.
+ inline: true
source:
openapi: ../openapi.yml
CreateTimeoff:
@@ -16588,6 +16651,7 @@
- enabled
- disabled
docs: Status of webhook.
+ inline: true
source:
openapi: ../openapi.yml
WebhookItem:
@@ -24517,6 +24581,7 @@ docs: The Contracts resource lets you create, amend and, retrieve Deel contracts
"CALENDAR_DAYS",
"FULL_AMOUNT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -31888,6 +31953,7 @@ docs: >-
"enabled",
"disabled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -31898,6 +31964,7 @@ docs: >-
"enabled",
"disabled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -32157,6 +32224,7 @@ types:
- enabled
- disabled
docs: Status of webhook.
+ inline: true
source:
openapi: ../openapi.yml
PatchWebhookRequestStatus:
@@ -32164,6 +32232,7 @@ types:
- enabled
- disabled
docs: Status of webhook.
+ inline: true
source:
openapi: ../openapi.yml
",
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/devrev.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/devrev.json
index 76ca63cecdd..aa52b714290 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/devrev.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/devrev.json
@@ -3910,6 +3910,7 @@ authentication connection.
"disable",
"enable",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3925,6 +3926,7 @@ for each authentication connection will depend on the type value.
"social",
"waad",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3981,6 +3983,7 @@ token. Only applicable for application access tokens.
"value": "urn:ietf:params:oauth:grant-type:token-exchange",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4025,6 +4028,7 @@ token. Only applicable for application access tokens.
"value": "urn:ietf:params:oauth:token-type:jwt",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4036,6 +4040,7 @@ token. Only applicable for application access tokens.
"expired",
"revoked",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4072,6 +4077,7 @@ token. Only applicable for application access tokens.
"value": "urn:ietf:params:oauth:token-type:jwt",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4276,6 +4282,7 @@ authentication connections have different configuration parameters.
"samlp",
"waad",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4380,6 +4387,7 @@ that can be updated.
"samlp",
"waad",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4517,6 +4525,7 @@ sort order. If not set, then no prior elements exist.
"parse_error",
"value_not_permitted",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4884,6 +4893,7 @@ sort order. If not set, then no prior elements exist.
"p2",
"p3",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4899,6 +4909,7 @@ always be returned in the specified sort-by order.
"after",
"before",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4943,6 +4954,7 @@ always be returned in the specified sort-by order.
"staging",
"test",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5032,6 +5044,7 @@ always be returned in the specified sort-by order.
"feature",
"product",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5559,6 +5572,7 @@ sort order. If not set, then no prior elements exist.
"low",
"medium",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5596,6 +5610,7 @@ will appear in the response.
"snap_kit",
"text",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5870,6 +5885,7 @@ default visibility.
"shadow",
"unassigned",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5897,6 +5913,7 @@ default visibility.
"rev_user",
"sys_user",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6030,6 +6047,7 @@ be set for other request types.
"work_deleted",
"work_updated",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6060,6 +6078,7 @@ be set for other request types.
"inactive",
"unverified",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6111,6 +6130,7 @@ be set for other request types.
"activate",
"deactivate",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6204,6 +6224,7 @@ event types. Note this is mutually exclusive with 'add' and
"issue",
"ticket",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/enum-casing.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/enum-casing.json
index f672a171260..5cbdda8189b 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/enum-casing.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/enum-casing.json
@@ -60,6 +60,7 @@
"success",
"failure",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -75,6 +76,7 @@
"value": "urn:ietf:params:oauth:grant-type:token-exchange",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -109,6 +111,7 @@ types:
enum:
- success
- failure
+ inline: true
source:
openapi: ../openapi.yml
ExampleResponse:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flagright.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flagright.json
index a680b8cbeb5..673bc9d5613 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flagright.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flagright.json
@@ -2157,6 +2157,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"GATHERING",
"UNKNOWN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2541,6 +2542,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"RUPAY",
"JCB",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2552,6 +2554,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"DEBIT",
"PREPAID",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2561,6 +2564,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"VIRTUAL",
"PHYSICAL",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2707,6 +2711,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"CLOSED",
"HIT",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2719,6 +2724,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"DOCUMENTS_COLLECTED",
"OTHER",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2766,6 +2772,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"REFUND",
"DECLINED",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2841,6 +2848,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"LARGE",
"UNKNOWN",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3231,6 +3239,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"value": "N/A",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3511,6 +3520,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"ZMW",
"ZWL",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3910,6 +3920,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"IN_PROGRESS",
"MANUAL_REVIEW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4105,6 +4116,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"IP_ADDRESS",
"STRING",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4115,6 +4127,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"BLACKLIST",
"FLAGRIGHT_LIBRARY",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4172,6 +4185,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"BusinessPayment",
"PromotionPayment",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4211,6 +4225,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"WALLET",
"CHECK",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4308,6 +4323,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"LOW",
"VERY_LOW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4341,6 +4357,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"BLOCK",
"SUSPEND",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4379,6 +4396,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"ORIGIN",
"DESTINATION",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4410,6 +4428,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"SANCTIONS_PEP",
"SANCTIONS_PEP_ADVERSE_MEDIA",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4421,6 +4440,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"CTF",
"SCREENING",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4525,6 +4545,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"PAYMENT_BENEFICIARY_NAME",
"BANK_NAME",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4790,6 +4811,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"REFUNDED",
"SUCCESSFUL",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4803,6 +4825,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"REFUND",
"OTHER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5085,6 +5108,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"F",
"NB",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5154,6 +5178,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"RETAIL",
"PROFESSIONAL",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5163,6 +5188,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"REGISTERED",
"UNREGISTERED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5180,6 +5206,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"SUSPENDED",
"BLOCKED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5290,6 +5317,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
"USER_STATE_UPDATED",
"ALERT_CLOSED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5381,6 +5409,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
enum:
- RETAIL
- PROFESSIONAL
+ inline: true
source:
openapi: ../openapi.yml
UserOptional:
@@ -5937,6 +5966,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- F
- NB
docs: Gender of the individual - Male, Female or Non-Binary
+ inline: true
source:
openapi: ../openapi.yml
UserDetails:
@@ -5973,6 +6003,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- LARGE
- UNKNOWN
docs: Segmentation of the business user
+ inline: true
source:
openapi: ../openapi.yml
CompanyGeneralDetails:
@@ -6139,6 +6170,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- RUPAY
- JCB
docs: Brand of Card
+ inline: true
source:
openapi: ../openapi.yml
CardDetailsCardFunding:
@@ -6147,12 +6179,14 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- DEBIT
- PREPAID
docs: Funding of Card
+ inline: true
source:
openapi: ../openapi.yml
CardDetailsCardType:
enum:
- VIRTUAL
- PHYSICAL
+ inline: true
source:
openapi: ../openapi.yml
CardDetails:
@@ -6334,6 +6368,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- BusinessPayment
- PromotionPayment
docs: Type of transaction
+ inline: true
source:
openapi: ../openapi.yml
MpesaDetails:
@@ -6496,6 +6531,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- CLOSED
- HIT
docs: Status of a case. E.g. Open, Closed etc.
+ inline: true
source:
openapi: ../openapi.yml
CaseManagementEventCaseStatusReason:
@@ -6507,6 +6543,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
docs: >-
Case status reason. E.g. Closed & False Positive, Closed & Investigation
Completed etc.
+ inline: true
source:
openapi: ../openapi.yml
CaseManagementEvent:
@@ -6872,6 +6909,7 @@ In order to make individual events retrievable, you also need to pass in a uniqu
- CANCELED
- REFUND
- DECLINED
+ inline: true
source:
openapi: ../openapi.yml
CheckDetails:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flexport.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flexport.json
index 7e7d2119f2d..29bcb63a483 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flexport.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/flexport.json
@@ -1052,6 +1052,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1425,6 +1426,7 @@
"requoted_quote",
"archived_quote",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1464,6 +1466,7 @@
"booked",
"shipment",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1561,6 +1564,7 @@
"contained_in_equipment",
"contained_in_battery_powered_vehicles",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1634,6 +1638,7 @@
"reviewed",
"complete",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2034,6 +2039,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2131,6 +2137,7 @@
"contained_in_equipment",
"contained_in_battery_powered_vehicles",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2380,6 +2387,7 @@
"DAP",
"DDP",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2392,6 +2400,7 @@
"sub_line",
"component_line",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2429,6 +2438,7 @@
"gross_volume",
"volume_weight",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2441,6 +2451,7 @@
"truck",
"rail",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2584,6 +2595,7 @@
"YD",
"Z3",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2647,6 +2659,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2764,6 +2777,7 @@
"freight_collect",
"freight_prepaid",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2783,6 +2797,7 @@
"DAP",
"DDP",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2797,6 +2812,7 @@
"delivery_order",
"work_order",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2808,6 +2824,7 @@
"high",
"standard",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2820,6 +2837,7 @@
"cancelled",
"closed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2832,6 +2850,7 @@
"truck",
"rail",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2891,6 +2910,7 @@
"buyers_agent",
"sellers_agent",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2937,6 +2957,7 @@
"icao",
"us_cbp",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3026,6 +3047,7 @@
"prs",
"dpr",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3057,6 +3079,7 @@
"collect",
"prepaid",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3172,6 +3195,7 @@
"customs_hold",
"pending",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3222,6 +3246,7 @@
"km",
"mi",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3430,6 +3455,7 @@
"terminal",
"unknown",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3462,6 +3488,7 @@
"door_to_door",
"door_to_port",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3656,6 +3683,7 @@
"additional",
"capital",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3711,6 +3739,7 @@
"paid",
"payment_pending",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3721,6 +3750,7 @@
"Shipment",
"Client",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3817,6 +3847,7 @@
"cm",
"in",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3827,6 +3858,7 @@
"cm",
"in",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3864,6 +3896,7 @@
"gross_volume",
"volume_weight",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4219,6 +4252,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4356,6 +4390,7 @@
"buyers_agent",
"sellers_agent",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4423,6 +4458,7 @@
"value": "/ocean/port",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4707,6 +4743,7 @@
"freight_collect",
"freight_prepaid",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4726,6 +4763,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4858,6 +4896,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4883,6 +4922,7 @@
"sub_line",
"component_line",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4962,6 +5002,7 @@
"W",
"X",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4975,6 +5016,7 @@
"delivery_order",
"work_order",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4984,6 +5026,7 @@
"standard",
"high",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5080,6 +5123,7 @@
"closed",
"cancelled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5350,6 +5394,7 @@
"fifty_three_ft",
"fifty_three_ft_hc",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5367,6 +5412,7 @@
"bulk",
"special",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5398,6 +5444,7 @@
"not_applicable",
"misflagged",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5455,6 +5502,7 @@
"DDP",
"DPU",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5584,6 +5632,7 @@
"standard",
"high",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5643,6 +5692,7 @@
"gated_out",
"final_destination",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5772,6 +5822,7 @@
"truck_intl",
"warehouse_storage",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5797,6 +5848,7 @@
"collect",
"prepaid",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5823,6 +5875,7 @@
"drayage",
"cartage",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5884,6 +5937,7 @@
"cbm",
"cbft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5946,6 +6000,7 @@
"kg",
"lbs",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6585,6 +6640,7 @@
- cbm
- cbft
docs: unit of measurement. "cbm" for cubic meters. "cbft" for cubic feet.
+ inline: true
source:
openapi: ../openapi.yml
VolumeCreate:
@@ -6602,6 +6658,7 @@
- kg
- lbs
docs: Required. Unit of measurement. "kg" for kilograms, "lbs" for pounds
+ inline: true
source:
openapi: ../openapi.yml
WeightCreate:
@@ -6619,6 +6676,7 @@
- cm
- in
docs: Required. Unit of measurement. "cm" for centimeters. "in" for inches.
+ inline: true
source:
openapi: ../openapi.yml
LengthCreate:
@@ -6666,6 +6724,7 @@
- packed_with_equipment
- contained_in_equipment
- contained_in_battery_powered_vehicles
+ inline: true
source:
openapi: ../openapi.yml
CreateCargo:
@@ -6836,6 +6895,7 @@
- cm
- in
docs: Required. Unit of measurement. "cm" for centimeters. "in" for inches.
+ inline: true
source:
openapi: ../openapi.yml
Length:
@@ -6893,6 +6953,7 @@
- packed_with_equipment
- contained_in_equipment
- contained_in_battery_powered_vehicles
+ inline: true
source:
openapi: ../openapi.yml
Cargo:
@@ -7136,6 +7197,7 @@
- value: /ocean/port
name: OceanPort
docs: Type of the object
+ inline: true
source:
openapi: ../openapi.yml
Placeport:
@@ -7213,6 +7275,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
OceanBookingDetail:
@@ -7244,6 +7307,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
AirBookingDetail:
@@ -7263,6 +7327,7 @@
enum:
- collect
- prepaid
+ inline: true
source:
openapi: ../openapi.yml
TruckingBookingDetail:
@@ -7296,6 +7361,7 @@
- submitted
- booked
- shipment
+ inline: true
source:
openapi: ../openapi.yml
BookingQuoteStatus:
@@ -7310,6 +7376,7 @@
- rejected_quote
- requoted_quote
- archived_quote
+ inline: true
source:
openapi: ../openapi.yml
Booking:
@@ -7398,6 +7465,7 @@
- DDP
- DPU
docs: Always required. The Incoterm of your shipment
+ inline: true
source:
openapi: ../openapi.yml
CreateOceanBooking:
@@ -7462,6 +7530,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
CreateAirBooking:
@@ -7545,6 +7614,7 @@
docs: >-
Whether the shipper or consignee is responsible for payment of trucking
freight. This can be `collect` (consignee) or `prepaid` (shipper).
+ inline: true
source:
openapi: ../openapi.yml
CreateTruckingBooking:
@@ -7570,6 +7640,7 @@
- km
- mi
docs: Required. Unit of measurement. "km" for kilometers. "mi" for miles.
+ inline: true
source:
openapi: ../openapi.yml
DistanceCreate:
@@ -7706,6 +7777,7 @@
Status about if the digitization process for this commercial invoice is
complete. If it is not complete, then the commercial invoice should be
considered a draft that can change.
+ inline: true
source:
openapi: ../openapi.yml
CommercialInvoice:
@@ -7770,6 +7842,7 @@
- prs
- dpr
docs: Required. Unit of measurement.
+ inline: true
source:
openapi: ../openapi.yml
CreateQuantity:
@@ -7823,6 +7896,7 @@
- customs_hold
- pending
docs: The release status for this entry.
+ inline: true
source:
openapi: ../openapi.yml
CustomsEntry:
@@ -8008,6 +8082,7 @@
- denied
- not_applicable
- misflagged
+ inline: true
source:
openapi: ../openapi.yml
ShipmentDangerousGoods:
@@ -8160,6 +8235,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
ShipmentPriority:
@@ -8167,6 +8243,7 @@
- standard
- high
docs: The level of attention Flexport should give to this shipment
+ inline: true
source:
openapi: ../openapi.yml
Shipment:
@@ -8435,6 +8512,7 @@
- ftl
- drayage
- cartage
+ inline: true
source:
openapi: ../openapi.yml
TruckingShipmentLeg:
@@ -8523,6 +8601,7 @@
- ventilated
- bulk
- special
+ inline: true
source:
openapi: ../openapi.yml
ShipmentContainerContainerSize:
@@ -8533,6 +8612,7 @@
- fourty_five_ft_hc
- fifty_three_ft
- fifty_three_ft_hc
+ inline: true
source:
openapi: ../openapi.yml
ShipmentContainer:
@@ -8590,6 +8670,7 @@
- terminal
- unknown
docs: The main reason for the exception as an identifier.
+ inline: true
source:
openapi: ../openapi.yml
Exception:
@@ -8683,6 +8764,7 @@
- additional
- capital
docs: Category of the charge.
+ inline: true
source:
openapi: ../openapi.yml
InvoiceItem:
@@ -8736,6 +8818,7 @@
- paid
- payment_pending
docs: Status of the invoice
+ inline: true
source:
openapi: ../openapi.yml
InvoiceType:
@@ -8745,6 +8828,7 @@
docs: >-
What the invoice is being issued for. Shipment related charges are type
`Shipment` and non-shipment related charges are type `Client`
+ inline: true
source:
openapi: ../openapi.yml
Invoice:
@@ -8990,6 +9074,7 @@
- gross_volume
- volume_weight
docs: The type of measure
+ inline: true
source:
openapi: ../openapi.yml
LineItemMeasurement:
@@ -9011,6 +9096,7 @@
- sub_line
- component_line
default: main_line
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderLineItemIncoterm:
@@ -9027,6 +9113,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderLineItemUnitOfMeasure:
@@ -9076,6 +9163,7 @@
- TDWB
- W
- X
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderLineItem:
@@ -9140,6 +9228,7 @@
- buyers_agent
- sellers_agent
docs: The role that the party has
+ inline: true
source:
openapi: ../openapi.yml
PartiesContactsItem:
@@ -9201,6 +9290,7 @@
because they've finished shipping), while Cancelled POs denote POs that
were mistakenly uploaded or that should not be used.
default: open
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderIncoterm:
@@ -9217,6 +9307,7 @@
- DAP
- DDP
- DPU
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderOrderClass:
@@ -9227,18 +9318,21 @@
- delivery_order
- work_order
docs: Class of the purchase order.
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderFreightPaymnetTerms:
enum:
- freight_collect
- freight_prepaid
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrderPriority:
enum:
- standard
- high
+ inline: true
source:
openapi: ../openapi.yml
PurchaseOrder:
@@ -9317,6 +9411,7 @@
- buyers_agent
- sellers_agent
docs: The role that the party has
+ inline: true
source:
openapi: ../openapi.yml
CreatePartyContactsItem:
@@ -9364,6 +9459,7 @@
- icao
- us_cbp
docs: The code type of the port
+ inline: true
source:
openapi: ../openapi.yml
CreatePurchaseOrderPort:
@@ -9449,6 +9545,7 @@
- gross_volume
- volume_weight
docs: The type of measure
+ inline: true
source:
openapi: ../openapi.yml
CreateLineItemMeasurement:
@@ -9474,6 +9571,7 @@
- truck
- rail
docs: Required if there is no transportation_mode in purchase order
+ inline: true
source:
openapi: ../openapi.yml
CreateLineItemIncoterm:
@@ -9492,6 +9590,7 @@
docs: >-
Required if there is no incoterm in the line item's purchase order. The
Incoterm of your line item.
+ inline: true
source:
openapi: ../openapi.yml
CreateLineItemLineType:
@@ -9501,6 +9600,7 @@
- component_line
docs: type of the line item
default: main_line
+ inline: true
source:
openapi: ../openapi.yml
CreateLineItemUnitOfMeasure:
@@ -9633,6 +9733,7 @@
- Z3
docs: The measurement per unit for this line item.
default: EA
+ inline: true
source:
openapi: ../openapi.yml
CreateLineItem:
@@ -9731,6 +9832,7 @@
because they've finished shipping), while Cancelled POs denote POs that
were mistakenly uploaded or that should not be used
default: open
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrderFreightPaymentTerms:
@@ -9738,6 +9840,7 @@
- freight_collect
- freight_prepaid
docs: The freight payment term for the purchase order
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrderTransportationMode:
@@ -9747,6 +9850,7 @@
- truck
- rail
docs: Required if there is no transportation_mode in purchase order
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrderIncoterm:
@@ -9765,6 +9869,7 @@
docs: >-
Required if there is no incoterm in each line item. The incoterm of your
purchase order.
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrderPriority:
@@ -9773,6 +9878,7 @@
- standard
docs: priority of the purchase order.
default: standard
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrderOrderClass:
@@ -9784,6 +9890,7 @@
- work_order
docs: Class of the purchase order.
default: purchase_order
+ inline: true
source:
openapi: ../openapi.yml
CreateOrUpdatePurchaseOrder:
@@ -11518,6 +11625,7 @@ errors:
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11527,6 +11635,7 @@ errors:
"booked",
"submitted",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11536,6 +11645,7 @@ errors:
"cargo_ready_date",
"created_at",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11573,6 +11683,7 @@ errors:
"no",
"notsure",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -11626,6 +11737,7 @@ errors:
contain goods subject to export control regulations? Export Control
Regulations include dual use item control, Hong Kong strategic commodity
control, US and EU export control, etc.
+ inline: true
source:
openapi: ../openapi.yml
BookingCreateResponse:
@@ -13366,6 +13478,7 @@ docs: >-
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13799,6 +13912,7 @@ docs: >-
"belly_freighter",
"unknown",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -13811,6 +13925,7 @@ docs: >-
"truck",
"rail",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -13826,6 +13941,7 @@ docs: >-
"airport_transfer",
"air_cartage",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -13844,6 +13960,7 @@ docs: >-
`truck`, or `rail`. If `transportation_mode` is `truck`, `ocean`, or
`rail`, `country_code` in both `origin_address` and `destination_address`
is required.
+ inline: true
source:
openapi: ../openapi.yml
CreateCarbonCalculationFlightType:
@@ -13855,6 +13972,7 @@ docs: >-
For `transportation_mode: air`, the type of plane used. One of
`freighter`, `belly_freighter`, or `unknown`. Defaults to `unknown`.
default: unknown
+ inline: true
source:
openapi: ../openapi.yml
CreateCarbonCalculationTruckingServiceType:
@@ -13870,6 +13988,7 @@ docs: >-
For `transportation_mode: truck`, the type of service used. One of `ftl`,
`ltl`, `drayage`, `cartage`, `last_mile`, `airport_transfer`, or
`air_cartage`.
+ inline: true
source:
openapi: ../openapi.yml
CarbonCalculationCreateResponse:
@@ -19886,6 +20005,7 @@ docs: Endpoints relating to Document objects
"value": "/shipment_leg",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20781,6 +20901,7 @@ Other details about this invoice",
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20792,6 +20913,7 @@ Other details about this invoice",
"void",
"paid",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -22385,6 +22507,7 @@ docs: Endpoints relating to Location objects
"roadport",
"seaport",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -24398,6 +24521,7 @@ docs: Endpoints relating to Product objects
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -24417,6 +24541,7 @@ docs: Endpoints relating to Product objects
"buyers_agent",
"sellers_agent",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -24427,6 +24552,7 @@ docs: Endpoints relating to Product objects
"closed",
"cancelled",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -25649,6 +25775,7 @@ docs: >-
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -27176,6 +27303,7 @@ docs: >-
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -27189,6 +27317,7 @@ docs: >-
"updated_at",
"archived_at",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hathora.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hathora.json
index c4e0482b4e0..88fb55154ff 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hathora.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hathora.json
@@ -1126,6 +1126,7 @@
"succeeded",
"failed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.json",
},
@@ -1260,6 +1261,7 @@
"public",
"local",
],
+ "inline": true,
"source": {
"openapi": "../openapi.json",
},
@@ -1271,6 +1273,7 @@
"rate_egress",
"total_egress",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.json",
},
@@ -1312,6 +1315,7 @@
"medium",
"large",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.json",
},
@@ -1390,6 +1394,7 @@
"Sydney",
"Sao_Paulo",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.json",
},
@@ -1430,6 +1435,7 @@
"suspended",
"destroyed",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.json",
},
@@ -1461,6 +1467,7 @@
"udp",
"tls",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.json",
},
@@ -2109,6 +2116,7 @@ types:
- running
- succeeded
- failed
+ inline: true
source:
openapi: ../openapi.json
Build:
@@ -2139,6 +2147,7 @@ types:
- private
- public
- local
+ inline: true
source:
openapi: ../openapi.json
Lobby:
@@ -4482,6 +4491,7 @@ service:
"private",
"local",
],
+ "inline": true,
"source": {
"openapi": "../openapi.json",
},
@@ -4818,6 +4828,7 @@ types:
- public
- private
- local
+ inline: true
source:
openapi: ../openapi.json
",
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hookdeck.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hookdeck.json
index a5abcd54a1c..5ddbed65787 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hookdeck.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hookdeck.json
@@ -2488,6 +2488,7 @@
"each_attempt",
"last_attempt",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2566,6 +2567,7 @@
"SOCKET_CLOSED",
"UNKNOWN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2578,6 +2580,7 @@
"COMPLETED",
"HOLD",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2590,6 +2593,7 @@
"SUCCESSFUL",
"HOLD",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2603,6 +2607,7 @@
"UNPAUSE",
"AUTOMATIC",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2890,6 +2895,7 @@
"info",
"debug",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3142,6 +3148,7 @@
"minute",
"hour",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3417,6 +3424,7 @@
"SUCCESSFUL",
"FAILED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3441,6 +3449,7 @@
"path",
"query",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3462,6 +3471,7 @@
"sha256",
"sha512",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3484,6 +3494,7 @@
"base64",
"hex",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -3512,6 +3523,7 @@
"TRANSFORMATION_FAILED",
"CLI_DISCONNECTED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3605,6 +3617,7 @@
"HANDSHAKE",
"POLLING",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3651,6 +3664,7 @@
"pipedrive",
"sendgrid",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3690,6 +3704,7 @@
"ACKNOWLEDGED",
"RESOLVED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3872,6 +3887,7 @@
"first_attempt",
"final_attempt",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3910,6 +3926,7 @@
"transformation",
"backpressure",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3945,6 +3962,7 @@
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4101,6 +4119,7 @@
"NORMAL",
"LOW",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4129,6 +4148,7 @@
"INGESTION_FATAL",
"UNKNOWN",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4179,6 +4199,7 @@
"linear",
"exponential",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4313,6 +4334,7 @@
"minute",
"second",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4499,6 +4521,7 @@
"value": "event.successful",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4645,6 +4668,7 @@
"error",
"fatal",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -7060,6 +7084,7 @@ types:
enum:
- base64
- hex
+ inline: true
source:
openapi: ../openapi.yml
HmacIntegrationConfigs:
@@ -7091,6 +7116,7 @@ types:
enum:
- minute
- second
+ inline: true
source:
openapi: ../openapi.yml
ShopifyIntegrationConfigs:
@@ -7263,6 +7289,7 @@ types:
- warn
- info
- debug
+ inline: true
source:
openapi: ../openapi.yml
ConsoleLine:
@@ -7456,6 +7483,7 @@ types:
- NORMAL
- LOW
docs: The priority attributed to the request when received
+ inline: true
source:
openapi: ../openapi.yml
RequestDataParsedQueryOne:
@@ -8792,6 +8820,7 @@ docs: An attempt is any request that Hookdeck makes on behalf of an event.
"http",
"cli",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -8811,6 +8840,7 @@ docs: An attempt is any request that Hookdeck makes on behalf of an event.
- http
- cli
docs: Bookmark target
+ inline: true
source:
openapi: ../openapi.yml
imports:
@@ -11957,6 +11987,7 @@ docs: ''
"accepted",
"rejected",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -11998,6 +12029,7 @@ docs: ''
enum:
- accepted
- rejected
+ inline: true
source:
openapi: ../openapi.yml
CreateRequestBulkRetryRequestQueryRejectionCauseAny:
@@ -13585,6 +13617,7 @@ docs: ''
"minute",
"hour",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -13710,6 +13743,7 @@ docs: ''
"minute",
"hour",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -13773,6 +13807,7 @@ docs: ''
- minute
- hour
docs: Period to rate limit attempts
+ inline: true
source:
openapi: ../openapi.yml
CreateConnectionRequestDestination:
@@ -13834,6 +13869,7 @@ docs: ''
- minute
- hour
docs: Period to rate limit attempts
+ inline: true
source:
openapi: ../openapi.yml
UpsertConnectionRequestDestination:
@@ -15161,6 +15197,7 @@ docs: >-
"minute",
"hour",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -15183,6 +15220,7 @@ docs: >-
"minute",
"hour",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -15194,6 +15232,7 @@ docs: >-
"minute",
"hour",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -15214,6 +15253,7 @@ docs: >-
- minute
- hour
docs: Period to rate limit attempts
+ inline: true
source:
openapi: ../openapi.yml
UpsertDestinationRequestRateLimitPeriod:
@@ -15222,6 +15262,7 @@ docs: >-
- minute
- hour
docs: Period to rate limit attempts
+ inline: true
source:
openapi: ../openapi.yml
UpdateDestinationRequestRateLimitPeriod:
@@ -15230,6 +15271,7 @@ docs: >-
- minute
- hour
docs: Period to rate limit attempts
+ inline: true
source:
openapi: ../openapi.yml
imports:
@@ -18470,6 +18512,7 @@ docs: >-
"ACKNOWLEDGED",
"RESOLVED",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -18528,6 +18571,7 @@ docs: >-
- ACKNOWLEDGED
- RESOLVED
docs: New status
+ inline: true
source:
openapi: ../openapi.yml
imports:
@@ -19577,6 +19621,7 @@ docs: Notifications let your team receive alerts anytime an issue changes.
"accepted",
"rejected",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/humanloop.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/humanloop.json
index 3776a029cf4..02e49b11501 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/humanloop.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/humanloop.json
@@ -864,6 +864,7 @@ in the Evaluation Report.",
"system",
"tool",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1206,6 +1207,7 @@ in the inheriting classes with documentation and appropriate Field definitions."
"default",
"other",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1422,6 +1424,7 @@ function.",
"cancelled",
"failed",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1483,6 +1486,7 @@ function.",
"target_free",
"target_required",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1629,6 +1633,7 @@ function.",
"boolean",
"number",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1641,6 +1646,7 @@ function.",
"text",
"number",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1652,6 +1658,7 @@ function.",
"active",
"inactive",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1728,6 +1735,7 @@ function.",
"correction",
"comment",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1913,6 +1921,7 @@ function.",
"low",
"auto",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -1974,6 +1983,7 @@ Used by a File's PAPV (Positive Action Per View) metric.",
"neutral",
"unset",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2559,6 +2569,7 @@ Does not have things like the signature or setup schema.",
"chat",
"edit",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2577,6 +2588,7 @@ Does not have things like the signature or setup schema.",
"google",
"groq",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2631,6 +2643,7 @@ Does not have things like the signature or setup schema.",
"active",
"inactive",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2697,6 +2710,7 @@ Observability is implemented by running monitoring Evaluators on Logs.",
"completed",
"failed",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2804,6 +2818,7 @@ Observability is implemented by running monitoring Evaluators on Logs.",
"supportadmin",
"user",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2815,6 +2830,7 @@ Observability is implemented by running monitoring Evaluators on Logs.",
"updated_at",
"name",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3481,6 +3497,7 @@ Observability is implemented by running monitoring Evaluators on Logs.",
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3539,6 +3556,7 @@ Observability is implemented by running monitoring Evaluators on Logs.",
"week",
"month",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3823,6 +3841,7 @@ V4 uses organization and inline. Those are deprecated and will be removed in fav
"organization",
"inline",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3866,6 +3885,7 @@ V4 uses organization and inline. Those are deprecated and will be removed in fav
"json_schema",
"get_api_call",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3877,6 +3897,7 @@ V4 uses organization and inline. Those are deprecated and will be removed in fav
"add",
"remove",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4060,6 +4081,7 @@ V4 uses organization and inline. Those are deprecated and will be removed in fav
"committed",
"deleted",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -5267,6 +5289,7 @@ types:
Specify the detail level of the image provided to the model. For more
details see:
https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding
+ inline: true
source:
openapi: ../openapi.yml
ImageUrl:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hume.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hume.json
index 85e3504dc4d..525c50ba481 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hume.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/hume.json
@@ -255,6 +255,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"tr",
"uk",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
@@ -353,6 +354,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"asc",
"desc",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
@@ -555,6 +557,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"utterance",
"conversational_turn",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
@@ -1068,6 +1071,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"started",
"ended",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
@@ -1190,6 +1194,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"COMPLETED",
"FAILED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
@@ -1270,6 +1275,7 @@ If you wish to supply more than 100 URLs, consider providing them as an archive
"created_before",
"created_after",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yaml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/inline-path-parameters.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/inline-path-parameters.json
index 8a25286f6d0..80bde1edcc0 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/inline-path-parameters.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/inline-path-parameters.json
@@ -213,6 +213,7 @@ types:
"private",
"public",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -235,6 +236,7 @@ types:
- private
- public
docs: Access level
+ inline: true
source:
openapi: ../openapi.yml
SearchResponse:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/intercom.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/intercom.json
index 4593cee2110..dac6ff60561 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/intercom.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/intercom.json
@@ -4042,6 +4042,7 @@
"upfront_email_collection_change",
"welcome_message_change",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4279,6 +4280,7 @@
"comment",
"note",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4320,6 +4322,7 @@
"note",
"quick_reply",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4477,6 +4480,7 @@
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4730,6 +4734,7 @@
"admin",
"team",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5735,6 +5740,7 @@
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5880,6 +5886,7 @@
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5922,7 +5929,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6636,6 +6643,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
},
"Unstable",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -6692,6 +6700,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"ticket",
"conversation",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6718,6 +6727,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"AND",
"OR",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6788,6 +6798,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"draft",
"live",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6914,6 +6925,7 @@ Their responses are likely to contain a pages object that hosts pagination links
"value": "conversation.list",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7175,6 +7187,7 @@ Their responses are likely to contain a pages object that hosts pagination links
"value": "~",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7216,6 +7229,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"cancelled",
"active",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7418,7 +7432,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7495,6 +7509,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"team",
"user",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7571,6 +7586,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"comment",
"quick_reply",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7583,7 +7599,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7814,6 +7830,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7865,6 +7882,7 @@ You can copy the `icon` property for your ticket type from [Twemoji Cheatsheet](
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10497,6 +10515,7 @@ types:
- temporary_expectation_change
- upfront_email_collection_change
- welcome_message_change
+ inline: true
source:
openapi: ../openapi.yml
ActivityLog:
@@ -10617,6 +10636,7 @@ types:
enum:
- comment
- note
+ inline: true
source:
openapi: ../openapi.yml
AdminReplyConversationRequest:
@@ -10654,6 +10674,7 @@ types:
- comment
- note
- quick_reply
+ inline: true
source:
openapi: ../openapi.yml
AdminReplyTicketRequestReplyOptionsItem:
@@ -10796,6 +10817,7 @@ types:
- published
- draft
docs: Whether the article is `published` or is a `draft` .
+ inline: true
source:
openapi: ../openapi.yml
ArticleContent:
@@ -11003,6 +11025,7 @@ types:
enum:
- admin
- team
+ inline: true
source:
openapi: ../openapi.yml
AssignConversationRequest:
@@ -11784,6 +11807,7 @@ types:
Whether the article will be `published` or will be a `draft`. Defaults to
draft. For multilingual articles, this will be the state of the default
language's content.
+ inline: true
source:
openapi: ../openapi.yml
CreateArticleRequest:
@@ -11911,6 +11935,7 @@ types:
name: BackOffice
- Tracker
docs: Category of the Ticket Type.
+ inline: true
source:
openapi: ../openapi.yml
CreateTicketTypeRequest:
@@ -11972,6 +11997,7 @@ types:
- type: optional
source:
openapi: ../openapi.yml
+ inline: true
CustomAttributes:
type: map
docs: >-
@@ -12492,6 +12518,7 @@ types:
- ticket
- conversation
docs: ticket or conversation
+ inline: true
source:
openapi: ../openapi.yml
LinkedObject:
@@ -12532,6 +12559,7 @@ types:
- AND
- OR
docs: An operator to allow boolean inspection between multiple fields.
+ inline: true
source:
openapi: ../openapi.yml
MultipleFilterSearchRequestValue:
@@ -12561,6 +12589,7 @@ types:
docs: >-
News items will not be visible to your users in the assigned newsfeeds
until they are set live.
+ inline: true
source:
openapi: ../openapi.yml
NewsItemRequest:
@@ -12660,6 +12689,7 @@ types:
- value: conversation.list
name: ConversationList
docs: The type of object
+ inline: true
source:
openapi: ../openapi.yml
PaginatedResponseDataItem:
@@ -12832,6 +12862,7 @@ types:
docs: >-
The accepted operators you can use to define how you want to search for
the value.
+ inline: true
source:
openapi: ../openapi.yml
SingleFilterSearchRequest:
@@ -12861,6 +12892,7 @@ types:
- `hit`: If there’s at least one hit event in the underlying sla_events table, and no “missed” or “canceled” events for the conversation.
- `missed`: If there are any missed sla_events for the conversation and no canceled events. If there’s even a single missed sla event, the status will always be missed. A missed status is not applied when the SLA expires, only the next time a teammate replies.
- `active`: An SLA has been applied to a conversation, but has not yet been fulfilled. SLA status is active only if there are no “hit, “missed”, or “canceled” events.
+ inline: true
source:
openapi: ../openapi.yml
SlaApplied:
@@ -13019,6 +13051,7 @@ types:
- type: File
source:
openapi: ../openapi.yml
+ inline: true
TicketCustomAttributes:
type: map
docs: >-
@@ -13048,6 +13081,7 @@ types:
- team
- user
docs: The type of the author
+ inline: true
source:
openapi: ../openapi.yml
TicketPartAuthor:
@@ -13095,6 +13129,7 @@ types:
- comment
- quick_reply
docs: Type of the part
+ inline: true
source:
openapi: ../openapi.yml
TicketReply:
@@ -13137,6 +13172,7 @@ types:
- list
source:
openapi: ../openapi.yml
+ inline: true
TicketRequestCustomAttributes:
type: map
docs: >-
@@ -13292,6 +13328,7 @@ types:
Whether the article will be `published` or will be a `draft`. Defaults to
draft. For multilingual articles, this will be the state of the default
language's content.
+ inline: true
source:
openapi: ../openapi.yml
UpdateArticleRequest:
@@ -13343,6 +13380,7 @@ types:
name: BackOffice
- Tracker
docs: Category of the Ticket Type.
+ inline: true
source:
openapi: ../openapi.yml
UpdateTicketTypeRequest:
@@ -14467,6 +14505,7 @@ types:
"workflow_preview",
"fin_preview",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -14484,6 +14523,7 @@ types:
docs: >-
The type of the source that triggered AI Agent involvement in the
conversation.
+ inline: true
source:
openapi: ../openapi.yml
AiAgent:
@@ -14562,6 +14602,7 @@ imports:
"content_snippet",
"workflow_connector_action",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -14577,6 +14618,7 @@ imports:
- content_snippet
- workflow_connector_action
docs: The type of the content source.
+ inline: true
source:
openapi: ../openapi.yml
ContentSource:
@@ -17183,6 +17225,7 @@ imports:
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -17231,6 +17274,7 @@ imports:
"highlight",
"plain",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -17258,6 +17302,7 @@ imports:
"highlight",
"plain",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -19669,6 +19714,7 @@ types:
Whether the article is `published` or is a `draft`. For multilingual
articles, this will be the state of the default language's content.
default: draft
+ inline: true
source:
openapi: ../openapi.yml
Articles:
@@ -19754,6 +19800,7 @@ types:
- highlight
- plain
docs: The type of text - `highlight` or `plain`.
+ inline: true
source:
openapi: ../openapi.yml
ArticleSearchHighlightsHighlightedTitleItem:
@@ -19773,6 +19820,7 @@ types:
- highlight
- plain
docs: The type of text - `highlight` or `plain`.
+ inline: true
source:
openapi: ../openapi.yml
ArticleSearchHighlightsHighlightedSummaryItemItem:
@@ -28608,6 +28656,7 @@ If you want to reply to a coveration or take an action such as assign, unassign,
"priority",
"not_priority",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -28619,6 +28668,7 @@ If you want to reply to a coveration or take an action such as assign, unassign,
"closed",
"snoozed",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -28653,6 +28703,7 @@ If you want to reply to a coveration or take an action such as assign, unassign,
"user",
"contact",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -31892,6 +31943,7 @@ types:
- user
- contact
docs: The role associated to the contact - user or lead.
+ inline: true
source:
openapi: ../openapi.yml
CreateConversationRequestFrom:
@@ -31972,6 +32024,7 @@ types:
- closed
- snoozed
docs: Can be set to "open", "closed" or "snoozed".
+ inline: true
source:
openapi: ../openapi.yml
ConversationPriority:
@@ -31979,6 +32032,7 @@ types:
- priority
- not_priority
docs: If marked as priority, it will return priority or else not_priority.
+ inline: true
source:
openapi: ../openapi.yml
Conversation:
@@ -33032,6 +33086,7 @@ You can update a data attribute.
"datetime",
"date",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -33042,6 +33097,7 @@ You can update a data attribute.
"contact",
"company",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -33132,6 +33188,7 @@ You can update a data attribute.
"boolean",
"date",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -33142,6 +33199,7 @@ You can update a data attribute.
"contact",
"company",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -33152,6 +33210,7 @@ You can update a data attribute.
"company",
"conversation",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -33171,6 +33230,7 @@ You can update a data attribute.
- contact
- company
docs: The model that the data attribute belongs to.
+ inline: true
source:
openapi: ../openapi.yml
CreateDataAttributeRequestDataType:
@@ -33182,6 +33242,7 @@ You can update a data attribute.
- datetime
- date
docs: The type of data stored for this attribute.
+ inline: true
source:
openapi: ../openapi.yml
DataAttributeModel:
@@ -33191,6 +33252,7 @@ You can update a data attribute.
docs: >-
Value is `contact` for user/lead attributes and `company` for company
attributes.
+ inline: true
source:
openapi: ../openapi.yml
DataAttributeDataType:
@@ -33201,6 +33263,7 @@ You can update a data attribute.
- boolean
- date
docs: The data type of the attribute.
+ inline: true
source:
openapi: ../openapi.yml
DataAttribute:
@@ -34856,6 +34919,7 @@ Your exported message data will be streamed continuously back down to you in a g
"no_data",
"canceled",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -35047,6 +35111,7 @@ types:
- no_data
- canceled
docs: The current state of your job.
+ inline: true
source:
openapi: ../openapi.yml
DataExport:
@@ -38033,6 +38098,7 @@ This will return the Message model that has been created.
"facebook",
"twitter",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -38210,6 +38276,7 @@ types:
docs: >-
The type of message that was sent. Can be email, inapp, facebook or
twitter.
+ inline: true
source:
openapi: ../openapi.yml
Message:
@@ -38837,6 +38904,7 @@ types:
"draft",
"live",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -39258,6 +39326,7 @@ types:
docs: >-
News items will not be visible to your users in the assigned newsfeeds
until they are set live.
+ inline: true
source:
openapi: ../openapi.yml
NewsItem:
@@ -40262,6 +40331,7 @@ types:
"contact",
"user",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -40356,6 +40426,7 @@ types:
- contact
- user
docs: 'Type of the contact: contact (lead) or user.'
+ inline: true
source:
openapi: ../openapi.yml
Segment:
@@ -40712,6 +40783,7 @@ This will return a subscription type model for the subscription type that was ad
"opt_out",
"opt_in",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -40721,6 +40793,7 @@ This will return a subscription type model for the subscription type that was ad
"email",
"sms_message",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -40732,6 +40805,7 @@ This will return a subscription type model for the subscription type that was ad
"draft",
"archived",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -40945,6 +41019,7 @@ types:
- draft
- archived
docs: The state of the subscription type.
+ inline: true
source:
openapi: ../openapi.yml
SubscriptionTypeConsentType:
@@ -40952,12 +41027,14 @@ types:
- opt_out
- opt_in
docs: Describes the type of consent.
+ inline: true
source:
openapi: ../openapi.yml
SubscriptionTypeContentTypesItem:
enum:
- email
- sms_message
+ inline: true
source:
openapi: ../openapi.yml
SubscriptionType:
@@ -43142,6 +43219,7 @@ types:
"datetime",
"files",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -43159,6 +43237,7 @@ types:
- datetime
- files
docs: The data type of the attribute
+ inline: true
source:
openapi: ../openapi.yml
imports:
@@ -45604,6 +45683,7 @@ The table below shows the operators you can use to define how you want to search
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45676,6 +45756,7 @@ The table below shows the operators you can use to define how you want to search
"waiting_on_customer",
"resolved",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45688,6 +45769,7 @@ The table below shows the operators you can use to define how you want to search
"waiting_on_customer",
"resolved",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45700,6 +45782,7 @@ The table below shows the operators you can use to define how you want to search
"waiting_on_customer",
"resolved",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45766,6 +45849,7 @@ The table below shows the operators you can use to define how you want to search
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45794,6 +45878,7 @@ The table below shows the operators you can use to define how you want to search
"waiting_on_customer",
"resolved",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -45854,6 +45939,7 @@ types:
- waiting_on_customer
- resolved
docs: The state of the ticket.
+ inline: true
source:
openapi: ../openapi.yml
UpdateTicketRequestAssignment:
@@ -45876,6 +45962,7 @@ types:
name: BackOffice
- Tracker
docs: Category of the Ticket.
+ inline: true
source:
openapi: ../openapi.yml
TicketTicketState:
@@ -45885,6 +45972,7 @@ types:
- waiting_on_customer
- resolved
docs: The state the ticket is currently in
+ inline: true
source:
openapi: ../openapi.yml
Ticket:
@@ -45970,6 +46058,7 @@ types:
- waiting_on_customer
- resolved
docs: The previous state of the ticket.
+ inline: true
source:
openapi: ../openapi.yml
TicketPartTicketState:
@@ -45979,6 +46068,7 @@ types:
- waiting_on_customer
- resolved
docs: The state of the ticket.
+ inline: true
source:
openapi: ../openapi.yml
TicketPart:
@@ -46033,6 +46123,7 @@ types:
name: BackOffice
- Tracker
docs: Category of the Ticket Type.
+ inline: true
source:
openapi: ../openapi.yml
TicketType:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/merge.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/merge.json
index 5419f90792a..5fb5fc872e9 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/merge.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/merge.json
@@ -105,6 +105,7 @@ View a list of your organization's `LinkedAccount` objects.",
"INCOMPLETE",
"RELINK_NEEDED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -183,6 +184,7 @@ View a list of your organization's `LinkedAccount` objects.",
"SAVINGS",
"CHECKING",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -368,6 +370,7 @@ Fetch from the `LIST Benefits` endpoint and filter by `ID` to show all benefits.
"mktg",
"filestorage",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -389,6 +392,7 @@ Fetch from the `LIST Benefits` endpoint and filter by `ID` to show all benefits.
"mktg",
"filestorage",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -530,6 +534,7 @@ Fetch from the `LIST Companies` endpoint and filter by `ID` to show all companie
"STRING",
"LIST_OF_STRINGS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1035,6 +1040,7 @@ Fetch from the `LIST Companies` endpoint and filter by `ID` to show all companie
"ZM",
"ZW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1246,6 +1252,7 @@ Fetch from the `LIST Earnings` endpoint and filter by `ID` to show all earnings.
"OVERTIME",
"BONUS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2223,6 +2230,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"PENDING",
"INACTIVE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2240,6 +2248,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"CONTRACTOR",
"FREELANCE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2251,6 +2260,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"READ",
"WRITE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2264,6 +2274,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"BASE64",
"GZIP_BASE64",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2374,6 +2385,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"WHITE",
"PREFER_NOT_TO_DISCLOSE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2389,6 +2401,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"NONEXEMPT",
"OWNER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2409,6 +2422,7 @@ Fetch from the `LIST Employments` endpoint and filter by `ID` to show all employ
"OTHER",
"PREFER_NOT_TO_DISCLOSE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2510,6 +2524,7 @@ Fetch from the `LIST Employee` endpoint and expand groups to view an employee's
"BUSINESS_UNIT",
"GROUP",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2571,6 +2586,7 @@ Fetch from the `LIST Employee` endpoint and expand groups to view an employee's
"ONGOING",
"RESOLVED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3023,6 +3039,7 @@ Fetch from the `LIST Locations` endpoint and filter by `ID` to show all office l
"HOME",
"WORK",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3040,6 +3057,7 @@ Fetch from the `LIST Locations` endpoint and filter by `ID` to show all office l
"HEAD_OF_HOUSEHOLD",
"QUALIFYING_WIDOW_OR_WIDOWER_WITH_DEPENDENT_CHILD",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3075,6 +3093,7 @@ Fetch from the `LIST Locations` endpoint and filter by `ID` to show all office l
"PATCH",
"DELETE",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -3995,6 +4014,7 @@ Create a `MultipartFormField` to define a multipart form entry.",
"ZWR",
"ZWL",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4023,6 +4043,7 @@ Create a `MultipartFormField` to define a multipart form entry.",
"PRO_RATA",
"SEMIMONTHLY",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4089,6 +4110,7 @@ Fetch from the `LIST PayGroup` endpoint and filter by `ID` to show all pay group
"EVERY_SIX_MONTHS",
"YEAR",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4177,6 +4199,7 @@ Fetch from the `LIST PayrollRuns` endpoint and filter by `ID` to show all payrol
"VOLUNTEER",
"BEREAVEMENT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4190,6 +4213,7 @@ Fetch from the `LIST PayrollRuns` endpoint and filter by `ID` to show all payrol
"GDPR",
"OTHER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4274,6 +4298,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"XML",
"MULTIPART",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4293,6 +4318,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"VOLUNTEER",
"BEREAVEMENT",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4304,6 +4330,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"JSON",
"BASE64_GZIP",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4321,6 +4348,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"FAILED",
"CLOSED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4338,6 +4366,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"TERMINATION",
"SIGN_ON_BONUS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4349,6 +4378,7 @@ View the `RemoteResponse` returned from your `DataPassthrough`.",
"IN_NEXT_SYNC",
"IN_LAST_SYNC",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4389,6 +4419,7 @@ View the `SyncStatus` for an account to see how recently its models were synced.
"PAUSED",
"PARTIALLY_SYNCED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4782,6 +4813,7 @@ Fetch from the `LIST TimeOffs` endpoint and filter by `ID` to show all time off
"CANCELLED",
"DELETED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4793,6 +4825,7 @@ Fetch from the `LIST TimeOffs` endpoint and filter by `ID` to show all time off
"HOURS",
"DAYS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10270,6 +10303,7 @@ service:
"CHECKING",
"SAVINGS",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -10285,6 +10319,7 @@ service:
"value": "remote_created_at",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11524,6 +11559,7 @@ service:
},
"payroll_run",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -11537,6 +11573,7 @@ service:
},
"payroll_run",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -12362,6 +12399,7 @@ service:
"INACTIVE",
"PENDING",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13365,6 +13403,7 @@ service:
"value": "work_location,team,pay_group",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13420,6 +13459,7 @@ service:
},
"marital_status",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -13475,6 +13515,7 @@ service:
},
"marital_status",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -14478,6 +14519,7 @@ service:
"value": "work_location,team,pay_group",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -14533,6 +14575,7 @@ service:
},
"marital_status",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -14588,6 +14631,7 @@ service:
},
"marital_status",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16386,6 +16430,7 @@ service:
},
"pay_group",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16401,6 +16446,7 @@ service:
"value": "effective_date",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16456,6 +16502,7 @@ service:
},
"pay_period",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16511,6 +16558,7 @@ service:
},
"pay_period",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16524,6 +16572,7 @@ service:
},
"pay_group",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16579,6 +16628,7 @@ service:
},
"pay_period",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -16634,6 +16684,7 @@ service:
},
"pay_period",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -17599,6 +17650,7 @@ service:
"ONGOING",
"RESOLVED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -17969,6 +18021,7 @@ service:
"mktg",
"ticketing",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -19079,6 +19132,7 @@ service:
},
"run_type",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -19091,6 +19145,7 @@ service:
"SIGN_ON_BONUS",
"TERMINATION",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -19104,6 +19159,7 @@ service:
},
"run_type",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -19117,6 +19173,7 @@ service:
},
"run_type",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -19130,6 +19187,7 @@ service:
},
"run_type",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20515,6 +20573,7 @@ service:
"value": "employee,approver",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20541,6 +20600,7 @@ service:
},
"units",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20554,6 +20614,7 @@ service:
"VACATION",
"VOLUNTEER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20580,6 +20641,7 @@ service:
},
"units",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20592,6 +20654,7 @@ service:
"DELETED",
"REQUESTED",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20605,6 +20668,7 @@ service:
"value": "employee,approver",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20631,6 +20695,7 @@ service:
},
"units",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -20657,6 +20722,7 @@ service:
},
"units",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -21274,6 +21340,7 @@ service:
"VACATION",
"VOLUNTEER",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/non-alphanumeric-characters.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/non-alphanumeric-characters.json
index 0e93f21bc04..205a502067b 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/non-alphanumeric-characters.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/non-alphanumeric-characters.json
@@ -66,6 +66,7 @@
"value": "",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/ntropy.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/ntropy.json
index 58712f5011b..20a1c1a672a 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/ntropy.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/ntropy.json
@@ -685,6 +685,7 @@
"consumer",
"business",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -695,6 +696,7 @@
"consumer",
"business",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -714,6 +716,7 @@
"financing",
"taxes",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -853,6 +856,7 @@
"invalid_bank_statement",
"internal_error",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -894,6 +898,7 @@
"completed",
"error",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1025,6 +1030,7 @@ enriched transactions.",
"completed",
"error",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1054,6 +1060,7 @@ enriched transactions.",
"low",
"unknown",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1111,6 +1118,7 @@ enriched transactions.",
"person",
"organization",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1363,6 +1371,7 @@ enriched transactions.",
"ZM",
"ZW",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1521,6 +1530,7 @@ enriched transactions.",
"ZWL",
"HRK",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1548,6 +1558,7 @@ enriched transactions.",
"processed",
"failed",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1562,6 +1573,7 @@ enriched transactions.",
"person",
"transaction_type",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -1664,6 +1676,7 @@ enriched transactions.",
"incoming",
"outgoing",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2020,6 +2033,7 @@ enriched transactions.",
"delivery_service",
"payment_processor",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2377,6 +2391,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"yearly",
"other",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2391,6 +2406,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"value": "one off",
},
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2451,6 +2467,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"resolved",
"rejected",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2610,6 +2627,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"account_holder_not_found",
"internal_error",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -2782,6 +2800,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"value": "batches.error",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -2855,6 +2874,7 @@ whether a transaction is a one-time event or a part of a recurring series.",
"account_holder_id",
"account_holder_name",
],
+ "inline": undefined,
"source": {
"openapi": "../openapi.yml",
},
@@ -4488,6 +4508,7 @@ types:
name: BatchesCompleted
- value: batches.error
name: BatchesError
+ inline: true
source:
openapi: ../openapi.yml
Webhook:
@@ -10586,6 +10607,7 @@ sdk.webhooks.create(
"value": "batches.error",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10621,6 +10643,7 @@ sdk.webhooks.create(
"value": "batches.error",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10954,6 +10977,7 @@ types:
name: BatchesCompleted
- value: batches.error
name: BatchesError
+ inline: true
source:
openapi: ../openapi.yml
WebhookPatchEventsItem:
@@ -10972,6 +10996,7 @@ types:
name: BatchesCompleted
- value: batches.error
name: BatchesError
+ inline: true
source:
openapi: ../openapi.yml
",
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/oauth.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/oauth.json
index 6e76ddae20f..253a8865cc2 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/oauth.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/oauth.json
@@ -123,6 +123,7 @@
"refresh_token",
"client_credentials",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -152,6 +153,7 @@
- refresh_token
- client_credentials
docs: The type of grant to request
+ inline: true
source:
openapi: ../openapi.yml
AuthGetTokenResponse:
diff --git a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/only-include-referenced-schemas.json b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/only-include-referenced-schemas.json
index 06f4b3d0bf1..30726459099 100644
--- a/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/only-include-referenced-schemas.json
+++ b/packages/cli/api-importers/openapi/openapi-ir-to-fern-tests/src/__test__/__snapshots__/openapi-docs/only-include-referenced-schemas.json
@@ -4041,6 +4041,7 @@
"upfront_email_collection_change",
"welcome_message_change",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4278,6 +4279,7 @@
"comment",
"note",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4319,6 +4321,7 @@
"note",
"quick_reply",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4476,6 +4479,7 @@
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -4729,6 +4733,7 @@
"admin",
"team",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5703,6 +5708,7 @@
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5831,6 +5837,7 @@
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -5873,7 +5880,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6420,6 +6427,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"ticket",
"conversation",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6446,6 +6454,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"AND",
"OR",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6516,6 +6525,7 @@ A "cursor" or pointer is used to keep track of the current position in the resul
"draft",
"live",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6642,6 +6652,7 @@ Their responses are likely to contain a pages object that hosts pagination links
"value": "conversation.list",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6903,6 +6914,7 @@ Their responses are likely to contain a pages object that hosts pagination links
"value": "~",
},
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -6944,6 +6956,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"cancelled",
"active",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7146,7 +7159,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7223,6 +7236,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"team",
"user",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7299,6 +7313,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"comment",
"quick_reply",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7311,7 +7326,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"discriminated": false,
"docs": undefined,
"encoding": undefined,
- "inline": undefined,
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7542,6 +7557,7 @@ Important: if there are any canceled sla_events for the conversation - meaning a
"published",
"draft",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -7593,6 +7609,7 @@ You can copy the `icon` property for your ticket type from [Twemoji Cheatsheet](
},
"Tracker",
],
+ "inline": true,
"source": {
"openapi": "../openapi.yml",
},
@@ -10204,6 +10221,7 @@ types:
- temporary_expectation_change
- upfront_email_collection_change
- welcome_message_change
+ inline: true
source:
openapi: ../openapi.yml
ActivityLog:
@@ -10324,6 +10342,7 @@ types:
enum:
- comment
- note
+ inline: true
source:
openapi: ../openapi.yml
AdminReplyConversationRequest:
@@ -10361,6 +10380,7 @@ types:
- comment
- note
- quick_reply
+ inline: true
source:
openapi: ../openapi.yml
AdminReplyTicketRequestReplyOptionsItem:
@@ -10503,6 +10523,7 @@ types:
- published
- draft
docs: Whether the article is `published` or is a `draft` .
+ inline: true
source:
openapi: ../openapi.yml
ArticleContent:
@@ -10710,6 +10731,7 @@ types:
enum:
- admin
- team
+ inline: true
source:
openapi: ../openapi.yml
AssignConversationRequest:
@@ -11466,6 +11488,7 @@ types:
Whether the article will be `published` or will be a `draft`. Defaults to
draft. For multilingual articles, this will be the state of the default
language's content.
+ inline: true
source:
openapi: ../openapi.yml
CreateArticleRequest:
@@ -11586,6 +11609,7 @@ types:
name: BackOffice
- Tracker
docs: Category of the Ticket Type.
+ inline: true
source:
openapi: ../openapi.yml
CreateTicketTypeRequest:
@@ -11647,6 +11671,7 @@ types:
- type: optional
source:
openapi: ../openapi.yml
+ inline: true
CustomAttributes:
type: map