All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
Improvement: Support setting
extraPeerDependencies
andextraPeerDependenciesMeta
as configuration arguments. For example:extraPeerDependencies: "openai": "^4.47.1" extraPeerDependenciesMeta: "openai": optional: true
- Fix: Functionality to generate integration tests against a mock server has been disabled.
-
Fix: The OAuth token provider supports SDKs that enable the
neverThrowErrors
setting. If the OAuth token provider fails to retrieve and/or refresh an access token, an error will not be thrown. Instead, the original access token will be used and the user will be able to act upon an error available on the response. For example,const response = await client.user.get(...) if (!response.ok) { // Handle the response.error ... }
- Fix: Remove instances of
node:stream
so that the generated SDK is Webpack + Next.js compatible.
- (Pre-emptive) Fix: URL encoded bodies are now appropriately encoded within the fetcher.
- Fix: Pass
abortSignal
toStream
for server-sent-events and JSON streams so that the user can opt out and break from a stream.
-
Feature: Add
abortSignal
toRequestOptions
. SDK consumers can now specify an an arbitrary abort signal that can interrupt the API call.const controller = new AbortController(); client.endpoint.call(..., { abortSignal: controller.signal, })
-
Feature: Add
inlineFileProperties
configuration to support generating file upload properties as in-lined request properties (instead of positional parameters). Simply configure the following:- name: fernapi/fern-typscript-node-sdk version: 0.19.0 ... config: inlineFileProperties: true
Before:
/** * @param {File | fs.ReadStream} file * @param {File[] | fs.ReadStream[]} fileList * @param {File | fs.ReadStream | undefined} maybeFile * @param {File[] | fs.ReadStream[] | undefined} maybeFileList * @param {Acme.MyRequest} request * @param {Service.RequestOptions} requestOptions - Request-specific configuration. * * @example * await client.service.post(fs.createReadStream("/path/to/your/file"), [fs.createReadStream("/path/to/your/file")], fs.createReadStream("/path/to/your/file"), [fs.createReadStream("/path/to/your/file")], {}) */ public async post( file: File | fs.ReadStream, fileList: File[] | fs.ReadStream[], maybeFile: File | fs.ReadStream | undefined, maybeFileList: File[] | fs.ReadStream[] | undefined, request: Acme.MyRequest, requestOptions?: Acme.RequestOptions ): Promise<void> { ... }
After:
/** * @param {Acme.MyRequest} request * @param {Service.RequestOptions} requestOptions - Request-specific configuration. * * @example * await client.service.post({ * file: fs.createReadStream("/path/to/your/file"), * fileList: [fs.createReadStream("/path/to/your/file")] * }) */ public async post( request: Acme.MyRequest, requestOptions?: Service.RequestOptions ): Promise<void> { ... }
- Internal: The generator now uses the latest FDR SDK.
- Fix: If OAuth is configured, the generated
getAuthorizationHeader
helper now treats the bearer token as optional. This prevents us from sending theAuthorization
header when retrieving the access token.
-
Fix: If OAuth environment variables are specified, the
clientId
andclientSecret
parameters are optional.export declare namespace Client { interface Options { ... clientId?: core.Supplier<string>; clientSecret?: core.Supplier<string>; } ... }
- Feature: Add support for the OAuth client credentials flow. The new
OAuthTokenProvider
automatically resolves the access token and refreshes it as needed. The resolved access token is then used as the bearer token in all client requests.
- Fix: Multipart form data requests are now compatible across browser and Node.js runtimes.
- Internal: Bump to v43 of IR which means that you will need
0.26.1
of the Fern CLI version. To bump your CLI version, please runfern upgrade
.
-
Improvement: The SDK generator now supports upload endpoints that specify an array of files like so:
/** * @param {File[] | fs.ReadStream[]} files * @param {Acme.UploadFileRequest} request * @param {Service.RequestOptions} requestOptions - Request-specific configuration. */ public async post( files: File[] | fs.ReadStream[], request: Acme.UploadFileRequest, requestOptions?: Service.RequestOptions ): Promise<void> { const _request = new FormData(); for (const _file of files) { _request.append("files", _file); } ... }
-
Improvement: The SDK generator now supports
@param
JSDoc comments for endpoint parameters. The generator now arranges JSDoc in a few separate groups, one for each of@param
,@throws
, and@examples
like so:/** * This endpoint checks the health of a resource. * * @param {string} id - A unique identifier. * @param {Service.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Acme.UnauthorizedRequest} * @throws {@link Acme.BadRequest} * * @example * await testSdk.health.service.check("id-2sdx82h") */ public async check(id: string, requestOptions?: Service.RequestOptions): Promise<void> { ... }
-
Improvement: The generator will only include user-provided examples if they exist, and otherwise only include a single generated example, like so:
/** * This endpoint checks the health of a resource. * * @example * await testSdk.health.service.check("id-2sdx82h") */ public async check(id: string, requestOptions?: Service.RequestOptions): Promise<void> { ... }
-
Fix: The SDK generator now escapes path parameters that would previously create invalid URLs (e.g. "\example"). Method implementations will now have references to
encodeURIComponent
like the following:const _response = await core.fetcher({ url: urlJoin( (await core.Supplier.get(this._options.environment)) ?? environments.AcmeEnvironment.Prod, `/users/${encodeURIComponent(userId)}` ), ... });
- Fix: snippet templates now move file upload parameters to unnamed args
- Fix: remove duplicate quotation marks in snippet templates
- Fix: fixes to styling of the SDK code snippet templates.
- Feature: The generator now registers snippet templates which can be used for dynamic SDK code snippet generation.
- Improvement: Earlier for inlined request exports, we were doing the following:
export { MyRequest } from "./MyRequest";
In an effort to make the generated code JSR compatible, the TS generator
will now append the type
explicitly for request exports.
export { type MyRequest } from "./MyRequest";
- Feature: plain text responses are now supported in the TypeScript generator.
- Fix: Minor fixes to SSE processing. In particular, stream terminal characters are now
respected like
[DONE]
and JSON parsed data is sent to the deserialize function.
- Feature: Bump to v38 of IR and support server-sent events where the events are sent
with a
data:
prefix and terminated with a new line.
-
Fix: Code snippets are generated for file upload endpoints using
fs.readStream
. Previously, generation for these endpoints was being skipped. -
Fix: If integration tests are not enabled, simple jest tests with a
yarn test
script will be created. -
Improvement: In an effort to make the generated code JSR compatible, the generator now directly imports from files instead of using directory imports.
-
Improvement: In an effort to make the generated code JSR compatible, we make sure all methods are strongly typed with return signatures (in this case
_getAuthorizationHeader()
). -
Fix: Generate code snippet for FileDownload endpoint
-
Fix: Import for
node-fetch
inFetcher.ts
uses a dynamic import instead ofrequire
which so that the SDK works in ESM environments (that are using local file output). When theoutputEsm
config flag is turned on, the dynamic import will be turned into an ESM specific import. -
Fix: The test job in
ci.yml
works even if you have not configured Fern to generate integration tests.Without integration tests the test job will run
yarn && yarn test
. With the integration tests, the test job will delegate to the fern clifern yarn test
. -
Feature: Add
allowExtraFields
option to permit extra fields in the serialized request.- name: fernapi/fern-typscript-node-sdk version: 0.14.0-rc0 ... config: allowExtraFields: true
- Support V37 of the IR.
- Feature: Add
retainOriginalCasing
option to preserve the naming convention expressed in the API. For example, the following Fern definition will generate a type like so:
types:
GetUsersRequest
properties:
group_id: string
Before
export interface GetUsersRequest {
groupId: string;
}
export interface GetUsersRequest = core.serialization.object({
groupId: core.serialization.string("group_id")
})
export namespace GetUsersRequest {
interface Raw {
group_id: string
}
}
After
export interface GetUsersRequest {
group_id: string;
}
export interface GetUsersRequest = core.serialization.object({
group_id: core.serialization.string()
})
export namespace GetUsersRequest {
interface Raw {
group_id: string
}
}
- Fix: The generator stopped working for remote code generation starting in
0.12.7
. This is now fixed.
- Improvement: Enhance serde performance by reducing reliance on async behavior and lazy async dynamic imports.
- Internal: Shared generator notification and config parsing logic.
- Improvement: Enhance serde performance by reducing reliance on async behavior and lazy async dynamic imports.
-
Improvement: the SDK will now leverage environment variable defaults, where specified, for authentication variables, such as bearer tokens, api keys, custom headers, etc.
Previously, the SDK would only leverage these defaults for bearer token auth IF auth was mandatory throughout the SDK.
-
In Node.js environments the SDK will default to using
node-fetch
. The SDK depends on v2 of node-fetch to stay CJS compatible.Previously the SDK was doing
require("node-fetch")
but it should berequire("node-fetch").default
based on node-fetch/node-fetch#450 (comment).
-
Introduce a custom configuration called
tolerateRepublish
which supports running npm publish with the flag--tolerateRepublish
. This flag allows you to publish on top of an existing npm package.To turn on this flag, update your generators.yml:
groups: generators: - name: fernapi/fern-typscript-node-sdk version: 0.12.5 ... config: tolerateRepublish: true
- Fix: Previously reference.md was just leveraging the function name for the reference, now it leverages the full package-scoped path, mirroring how the function would be used in reality.
seedExamples.getException(...)
// is now
seedExamples.file.notification.service.getException(...)
- Fix: Previously SDK code snippets would not support generation with undiscriminated unions. Now, it does.
-
Fix: Previously SDK code snippets would not take into account default parameter values and would always include a
{}
. This was odd and didn't represent how a developer would use the SDK. Now, the snippets check for default parameter values and omit if there are no fields specified.// Before client.users.list({}); // After client.users.list();
-
Fix: Optional objects in deep query parameters were previously being incorrectly serialized. Before this change, optional objects were just being JSON.stringified which would send the incorrect contents over the wire.
// Before if (foo != null) { _queryParams["foo"] = JSON.stringify(foo); } // After if (foo != null) { _queryParams["foo"] = foo; } // After (with serde layer) if (foo != null) { _queryParams["foo"] = serializers.Foo.jsonOrThrow(foo, { skipValidation: false, breadcrumbs: ["request", "foo"] }); }
-
Feature: support deep object query parameter serialization. If, query parameters are objects then Fern will support serializing them.
MyFoo: properties: bar: optional<string> query-parameters: foo: MyFoo
will now be serialized as
?foo[bar]="...
and appear in the SDK as a regular objectclient.doThing({ foo: { bar: "..." } });
-
Fix: Previously
core.Stream
would not work in the Browser. Now the generated Fern SDK includes a polyfill forReadableStream
and usesTextDecoder
instead ofBuffer
. -
Feature: add in a reference markdown file, this shows a quick outline of the available endpoints, it's documentation, code snippet, and parameters.
This feature is currently behind a feature flag called
includeApiReference
and can be usedconfig: includeApiReference: true
- Fix: The
Fetcher
now supports sending binary as a request body. This is important for APIs that intakeapplication/octet-stream
content types or for folks that have .fernignored their and added custom utilities that leverage the fetcher.
- Fix: ensure SDK generator always uses
node-fetch
in Node.js environments. There is an experimental fetch packaged with newer versions of Node.js, however it causes unexpected behavior with file uploads.
- Fix: ensure SDK generator does not drop additional parameters from requests that perform file upload. Previously, if an endpoint had
file
inputs without additionalbody
parameters, query parameters were eroniously ignored.
- Fix: The SDK generator no longer generates a
tsconfig.json
withnoUnusedParameters
enabled. This check was too strict.
- Feature: The SDK generator now forwards information about the runtime that it is being
used in. The header
X-Fern-Runtime
will report the runtime (e.g.browser
,node
,deno
) and the headerX-Fern-Runtime-Version
will report the version.
-
Feature: The SDK generator now supports whitelabelling. When this is turned on, there will be no mention of Fern in the generated code.
Note: You must be on the enterprise tier to enable this mode.
- Chore: Intialize this changelog