From e2985449aef3a90cae1b994254684b5c188b90f8 Mon Sep 17 00:00:00 2001 From: Kapil Gowru Date: Thu, 31 Jul 2025 15:10:50 -0600 Subject: [PATCH 1/3] Update parameter-names.mdx based on issue #266 --- .../pages/extensions/parameter-names.mdx | 133 ++++++++++++++++-- 1 file changed, 118 insertions(+), 15 deletions(-) diff --git a/fern/products/openapi-def/pages/extensions/parameter-names.mdx b/fern/products/openapi-def/pages/extensions/parameter-names.mdx index ff60bf613..325ef57a0 100644 --- a/fern/products/openapi-def/pages/extensions/parameter-names.mdx +++ b/fern/products/openapi-def/pages/extensions/parameter-names.mdx @@ -1,18 +1,23 @@ --- title: Customize parameter names -description: Use `x-fern-parameter-name` to customize query parameter, header and path parameter naming. +description: Use extension headers to customize query parameter, header and path parameter naming. --- - The `x-fern-parameter-name` extension allows you to customize the variable names of parameters in your generated SDKs. + These extensions allow you to customize parameter names and behavior in your generated SDKs. -## Headers +## Available Extensions -In the example below, the header `X-API-Version` is renamed to `version` in the -generated SDK. The rename makes the SDK more human readable. +### x-fern-parameter-name -```yaml {8} +Customize the variable names of parameters in your generated SDKs. + +#### Headers + +In the example below, the header `X-API-Version` is renamed to `version` in the generated SDK for better readability: + +```yaml paths: "/user": get: @@ -26,16 +31,15 @@ paths: required: true ``` -## Query parameters +#### Query parameters -In the example below, the query parameter `q` is renamed to `search_terms` in the -generated SDK. The rename makes the parameter more approachable for end users. +Rename query parameters to be more descriptive in the SDK: -```yaml {8} +```yaml paths: "/user/search": get: - operationId: search_user + operationId: search_user parameters: - in: query name: q @@ -45,12 +49,11 @@ paths: required: false ``` -## Path parameters +#### Path parameters -In the example below, the path parameter `userId` is renamed to `id` in the -generated SDK. The rename makes the SDK less verbose. +Make path parameter names more concise in the SDK: -```yaml {8} +```yaml paths: "/user/{userId}": get: @@ -63,3 +66,103 @@ paths: type: string required: false ``` + +### x-fern-sdk-variables + +Define variables that can be provided when instantiating the SDK client. This allows setting values that will be automatically injected into API paths. + +Example defining a project ID variable: + +```yaml +x-fern-sdk-variables: + project_id: + type: string + description: "The ID of the project" + pattern: "^proj_[a-zA-Z0-9]+$" +``` + +Then use the variable in paths: + +```yaml +paths: + "/v1/connect/{project_id}/accounts": + parameters: + - name: project_id + in: path + required: true + schema: + type: string + x-fern-sdk-variable: project_id +``` + +The SDK will automatically inject the project ID value provided during client instantiation into the path. + + + The variable pattern allows validating the format of values at runtime. + + +### x-fern-sdk-method-name + +Customize the generated method name in the SDK: + +```yaml +paths: + "/users": + get: + operationId: list_users + x-fern-sdk-method-name: getUsers +``` + +### x-fern-sdk-group-name + +Group related endpoints under a namespace in the SDK: + +```yaml +paths: + "/users": + get: + operationId: list_users + x-fern-sdk-group-name: users +``` + +### x-fern-ignore + +Exclude an endpoint from SDK generation: + +```yaml +paths: + "/internal/metrics": + get: + x-fern-ignore: true +``` + + + Use x-fern-ignore sparingly and only for endpoints that should not be exposed in SDKs. + + +### x-fern-sdk-return-value + +Specify what part of the response should be returned: + +```yaml +paths: + "/users/{id}": + get: + x-fern-sdk-return-value: data +``` + +### x-fern-pagination + +Configure pagination behavior for list endpoints: + +```yaml +paths: + "/users": + get: + x-fern-pagination: + cursor: "$request.after" + next_cursor: "$response.page_info.end_cursor" + results: "$response.data" +``` + +This configures how pagination fields map between requests and responses. \ No newline at end of file From f7db0c83983a4be7dd4b8dec7c9eed736083b155 Mon Sep 17 00:00:00 2001 From: Kapil Gowru Date: Thu, 31 Jul 2025 15:10:50 -0600 Subject: [PATCH 2/3] Update configuration.mdx based on issue #266 --- .../overview/typescript/configuration.mdx | 165 ++++-------------- 1 file changed, 38 insertions(+), 127 deletions(-) diff --git a/fern/products/sdks/overview/typescript/configuration.mdx b/fern/products/sdks/overview/typescript/configuration.mdx index 6fc216209..adcd78ee3 100644 --- a/fern/products/sdks/overview/typescript/configuration.mdx +++ b/fern/products/sdks/overview/typescript/configuration.mdx @@ -11,7 +11,7 @@ groups: local: generators: - name: fernapi/fern-typescript-sdk - version: + version: config: namespaceExport: Acme ``` @@ -130,9 +130,11 @@ Specify extra peer dependencies meta fields in the generated `package.json`: ```yaml # generators.yml config: - extraPeerDependencies: - react: ">=16.8.0 <19.0.0" - "react-dom": ">=16.8.0 <19.0.0" + extraPeerDependenciesMeta: + react: + optional: true + "react-dom": + optional: true ``` @@ -165,7 +167,6 @@ Choose whether you want to support Node.js 16 and above (`Node16`), or Node.js 1 - Includes the content type and content length from binary responses. The user will receive an object of the following type: ```typescript @@ -180,7 +181,14 @@ Includes the content type and content length from binary responses. The user wil - When enabled, [`withCredentials`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials) is set to `true` when making network requests. +When enabled, [`withCredentials`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials) is set to `true` when making network requests. + + + +When enabled, adds standard SDK client headers to requests including: +- x-fern-sdk-name +- x-fern-sdk-version +- x-fern-sdk-id @@ -411,134 +419,37 @@ generate a `jsr.json` as well as a GitHub workflow to publish to JSR. - - Generate WebSocket clients from your AsyncAPI specs. - - - - By default, the client will throw an error if the response from the server -doesn't match the expected type (based on how the response is modeled in the -Fern Definition). - -If `skipResponseValidation` is set to `true`, the client will never throw if the response is misshapen. Instead, the client will log the issue using `console.warn` and return the data (casted to the expected response type). - -Response validation only occurs when the Serde layer is enabled (`noSerdeLayer: false`). The Serde layer is disabled by default (`noSerdeLayer: true`). - - - - -Change the type of stream that is used in the generated SDK. - -* `wrapper`: The streams use a wrapper with multiple underlying implementations to support versions of Node.js before Node.js 18. -* `web`: The streams use the web standard `ReadableStream`. - -The default is `web`. - - - - When `treatUnknownAsAny` is enabled, [unknown types from Fern are generated into TypeScript using `any` instead of the `unknown` type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type). - - - -When `useBigInt` is set to `true`, a customized JSON serializer & deserializer is used that will preserve the precision of `bigint`'s, as opposed to the native `JSON.stringify` and `JSON.parse` function which converts `bigint`'s to number's losing precision. - -When combining `useBigInt` with our serialization layer (`no-serde: false`), both the request and response properties that are marked as `long` and `bigint` in OpenAPI/Fern spec, will consistently be `bigint`'s. -However, when disabling the serialization layer (`no-serde: true`), they will be typed as `number | bigint`. - -Here's an overview of what to expect from the generated types when combining `useBigInt` and `noSerde` with the following Fern definition: - -*Fern definition*: + +Define variables that will be passed to the client constructor and injected into paths and headers. This is useful for injecting values like project IDs, API versions, etc. +Example OpenAPI configuration: ```yaml -types: - ObjectWithOptionalField: - properties: - longProp: long - bigIntProp: bigint +x-fern-sdk-variables: + project_id: + type: string + description: The ID of the project + pattern: "^proj_[a-zA-Z0-9]+$" ``` -*TypeScript output*: +The variable will be automatically injected into paths that contain `{project_id}`: +```yaml +paths: + /v1/connect/{project_id}/accounts: + get: + ... +``` +In the generated TypeScript SDK: ```typescript -// useBigInt: true -// noSerde: false -interface ObjectWithLongAndBigInt { - longProp: bigint; - bigIntProp: bigint; -} - -// useBigInt: true -// noSerde: true -interface ObjectWithLongAndBigInt { - longProp: bigint | number; - bigIntProp: bigint | number; -} +const client = new Client({ + projectId: "proj_123" // Required constructor param +}) -// useBigInt: false -// noSerde: false -interface ObjectWithLongAndBigInt { - longProp: number; - bigIntProp: string; -} - -// useBigInt: false -// noSerde: true -interface ObjectWithLongAndBigInt { - longProp: number; - bigIntProp: string; -} +// projectId automatically injected into path +await client.listAccounts() ``` - - - When `useBrandedStringAliases` is disabled (the default), string aliases are generated as - normal TypeScript aliases: - - ```typescript - // generated code - - export type MyString = string; - - export type OtherString = string; - ``` - When `useBrandedStringAliases` is enabled, string aliases are generated as branded strings. This makes each alias feel like its own type and improves compile-time safety. - - ```yaml - # fern definition - - types: - MyString: string - OtherString: string - ``` - - ```typescript - // generated code - - export type MyString = string & { __MyString: void }; - export const MyString = (value: string): MyString => value as MyString; - - export type OtherString = string & { __OtherString: void }; - export const OtherString = (value: string): OtherString => value as OtherString; - ``` - - ```typescript - // consuming the generated type - - function printMyString(s: MyString): void { - console.log("MyString: " + s); - } - - // doesn't compile, "foo" is not assignable to MyString - printMyString("foo"); - - const otherString = OtherString("other-string"); - // doesn't compile, otherString is not assignable to MyString - printMyString(otherString); - - // compiles - const myString = MyString("my-string"); - printMyString(myString); - ``` - - \ No newline at end of file + + Generate WebSocket clients from your AsyncAPI specs. + Date: Thu, 31 Jul 2025 15:10:51 -0600 Subject: [PATCH 3/3] Update configuration.mdx based on issue #266 --- .../sdks/overview/python/configuration.mdx | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/fern/products/sdks/overview/python/configuration.mdx b/fern/products/sdks/overview/python/configuration.mdx index 1c0eb6af7..f75a141d6 100644 --- a/fern/products/sdks/overview/python/configuration.mdx +++ b/fern/products/sdks/overview/python/configuration.mdx @@ -18,6 +18,47 @@ groups: class_name: "YourClient" ``` +## Extension Headers + +The Python SDK generator supports injection of variables into request paths through the `x-fern-sdk-variables` extension in your OpenAPI spec. This allows you to define variables that will be set once in the client constructor and automatically injected into relevant request paths. + +For example, to inject a project ID into all relevant paths: + +```yaml +components: + x-fern-sdk-variables: + project_id: + type: string + description: "The ID of the project" + pattern: "^proj_[a-zA-Z0-9]+$" +``` + +Then in your paths: + +```yaml +/v1/connect/{project_id}/accounts: + parameters: + - name: project_id + in: path + required: true + schema: + type: string + x-fern-sdk-variable: project_id +``` + +The generated client will accept the variable in its constructor: + +```python +client = Client(project_id="proj_123") +``` + +And automatically inject it into requests: + +```python +# project_id is injected from the client constructor +accounts = client.accounts.list() +``` + ## SDK Configuration Options @@ -72,12 +113,9 @@ groups: - -Specifies the Python package name that users will import your generated client -from. +Specifies the Python package name that users will import your generated client from. -For example, setting `package_name: "my_custom_package"` enables users to use -`my_custom_package import Client` to import your client: +For example, setting `package_name: "my_custom_package"` enables users to use `my_custom_package import Client` to import your client: ```yaml {7-10} default-group: local