Changelog
3.85.1
(fix): Fixed the generated wire tests for endpoints that use offset pagination. The tests
asserted page.hasNextPage() was true for every example, but the generated client
reports no next page when the response returns fewer items than the requested page
size (the pagination step), or when the response’s has-next-page property is
false. The wire test now evaluates the same condition against the mocked response,
and only asserts hasNextPage()/getNextPage() when a next page is actually expected.
3.85.0
(feat): Add an opt-in optional-auth config flag. When enabled, client auth
parameters are made optional even when the API spec mandates auth on all
endpoints (isAuthMandatory=true), so the client can be constructed without
credentials. Requests are then sent unauthenticated when no credentials are
supplied, instead of throwing from the auth provider. Useful for
hand-maintained wrapper clients that authenticate via external means
(e.g. cloud provider credentials). Defaults to false, so existing
behavior is unchanged.
3.84.0
(feat): Generated error classes now redeclare the body property with the error’s
typed body (e.g. public declare readonly body: MyErrorBody;) instead of
inheriting body?: unknown from the base API error class. This makes
err.body.<field> type-check in catch blocks without casting when the
error has a declared body schema.
3.83.2
(fix): Global headers declared with an env now fall back to that environment
variable at runtime. The resolution order for a global header is the
explicit option, then the environment variable, then the client default.
3.83.1
(fix): Scope the passthrough client.fetch() auth headers to the configured base URL.
Auth headers are now only attached when the resolved request URL has the same
origin as the configured base URL (or environment), so passing an absolute
cross-origin URL into the passthrough fetch escape hatch no longer leaks the
SDK’s credentials to an unrelated host. Relative paths and same-origin absolute
URLs are unaffected. Passthrough debug logs now redact credentials in the
request URL, matching the main fetcher.
3.83.0
(feat): Add support for webhook body-hash binding in the generated verifySignature helper.
When a webhook’s signature declares a body-hash binding, the helper now hashes the raw
request body and compares it to the hash transmitted separately as a query parameter on
the notification URL (e.g. Twilio’s bodySHA256) before verifying the HMAC signature.
Both checks must pass. The body-hash algorithm and encoding are independent of the outer
HMAC’s.
3.82.3
(fix): Fix server URL variable interpolation to render the selected environment’s URL
template instead of always using the first environment’s template. When a client
is constructed with both an environment and server URL variable values (e.g.
region), the base URL is now built from the selected environment’s template(s);
for multi-host environments every host’s template is formatted. An explicitly
provided baseUrl or custom environment value is no longer overridden.
3.82.2
(fix): Generated endpoint JSDoc now documents all thrown error paths: in addition to
the errors declared in the API definition, each method’s @throws annotations
include the base API error class (thrown for any undeclared HTTP error status
code) and the timeout error class (thrown when the request times out).
3.82.1
(fix): Send grant_type: "client_credentials" in the OAuth token request when the token
endpoint models grant_type as a plain (non-literal) string. Previously the
generated OAuthAuthProvider omitted grant_type entirely, so token requests
against OpenAPI-imported specs (where grant_type is an optional string rather
than a literal) failed. A required non-literal grant_type is no longer surfaced
as a user-supplied client-credentials option; it is synthesized automatically.
3.82.0
(feat): Add automatic idempotency-key generation, driven by the centralized
idempotencyKeyGeneration config in the IR. When enabled, the generated SDK attaches a
UUIDv4 idempotency-key header (default Idempotency-Key) to requests whose HTTP method is
listed in the IR (default POST/PUT). A caller-supplied key in request options still takes
precedence.
3.81.0
(feat): Add support for server URL variables (e.g. region/edge routing). Server variables
defined on the API’s environments are now exposed as optional string options on the
client constructor and interpolated into the base URL(s) at request time. Reserved
option names are de-collided by prefixing with serverUrl (e.g. a variable named
environment is exposed as serverUrlEnvironment).
3.80.2
(fix): Fix compile errors in the generated OAuthAuthProvider when the serde layer is
disabled: the token endpoint method is now called with the same camelCase name
that the generated client exposes (previously the original casing, e.g.
CreateOauth2Token, was used). Also guard against optional access_token
response properties so the token refresh path satisfies its Promise<string>
return type instead of string | undefined.
3.80.1
(fix): Make the structured User-Agent (emitted when includePlatformHeaders is
enabled) comply with the RFC 7230 token grammar. The npm package name is now
percent-encoded in the product token so the @ and / of a scoped package
are escaped (e.g. @dummy/sdk/0.0.1 becomes %40dummy%2Fsdk/0.0.1); the
original name can be recovered by URL-decoding. The architecture label is also
normalized so the 64-bit x86 aliases (x64, amd64, x86_64) all report as
the canonical x86_64.
3.80.0
(feat): Add opt-in support for a structured User-Agent header of the form
{sdkName}/{version} ({os}; {arch}) {runtime}/{runtimeVersion}, matching the
Twilio helper-library shape. This is gated behind the includePlatformHeaders
config option and is disabled by default, so existing generated output is
unchanged. When enabled, the platform + runtime information is consolidated
into the User-Agent and the discrete X-Fern-Runtime / X-Fern-Runtime-Version
headers are omitted. The platform group and runtime segment are dropped
gracefully in environments where they cannot be determined (e.g. browsers),
and the header remains subject to omitFernHeaders.
3.79.2
(fix): Pin the npm toolchain used by the generated publish workflow. The
.github/workflows/ci.yml publish job now runs on a pinned Node LTS
(node-version: "lts/Krypton") and calls npm publish directly instead
of npx -y npm@latest publish. Relying on npm@latest pulled whatever
npm release was newest at publish time, so a broken npm release could
break publishing. The pinned Node LTS bundles an npm that supports OIDC
trusted publishing. The npx semver invocation used for backport
detection is also pinned to semver@7.8.1.
3.79.1
(fix): Generated snippets now use baseUrl instead of environment when
no environments are defined in the API spec, matching the actual
constructor parameter users should provide.
3.79.0
(feat): Add a defaultTimeout custom config option, expressed in milliseconds, which is idiomatic for
JavaScript/TypeScript (setTimeout, AbortSignal.timeout(ms)). Use "infinity" to disable the
timeout. The seconds-based defaultTimeoutInSeconds and timeoutInSeconds keys are now
deprecated but continue to work: their values are converted to milliseconds (× 1000). Precedence
is defaultTimeout > defaultTimeoutInSeconds > timeoutInSeconds. Generated SDK output is
unchanged for existing configs.
3.78.2
(fix): Fix a regression where | undefined was dropped from the value type of generated
Record types backed by optional map values (e.g. optional additionalProperties).
Optional map values now correctly generate Record<string, T | undefined> with
serialization record(string(), T.optional()), while unknown/any map values
keep the redundant | undefined stripped (Record<string, unknown>).
3.78.1
(fix): Fix TypeError: Cannot use 'in' operator to search for 'path' in undefined
crash when null or undefined is passed to a file upload parameter at
runtime. The error is now a clear TypeError describing the expected types
instead of a cryptic in operator failure.
3.78.0
(feat): Add an additionalBodyParameters request option that spreads additional parameters into an
endpoint’s JSON request body. Caller-supplied properties override matching keys in the endpoint
body, matching the behavior of the Python, Swift, and Ruby SDKs. Omitting the option leaves the
request body unchanged and never fabricates a body for bodyless requests.