Skip to navigation

3.108.7

(fix): With esmOnly: true, the SDK no longer runs or ships scripts/rename-to-esm-files.cjs. The package is already "type": "module", so build:esm is now just tsc and the main, types and exports entries point at dist/esm/**/*.js and *.d.ts instead of .mjs and .d.mts.

3.108.6

(fix): README generation in self-hosted GitHub mode can clone a private repository with a personal access token again. Upgrades @fern-api/generator-cli to 0.12.1, which also sends the token as an Authorization header. Before this, git in the generator image (libcurl 8.23+) dropped the token from the clone URL and failed with could not read Username.

3.108.5

(fix): XML (TwiML) serialization writes empty elements as <Hangup/> instead of <Hangup />, matching the legacy twilio-node output byte for byte.

3.108.4

(fix): In Node, a rejected WebSocket handshake (a non-101 response) now includes the server’s response body in the error. Callers see Unexpected server response: 400 (<body>) instead of only Unexpected server response: 400, so a bad query parameter or an auth failure can be told apart from other errors. The ErrorEvent also exposes the rejection as optional statusCode, headers and body fields (the body is capped at 1000 characters); they stay undefined for other errors. The error reaches error listeners and waitForOpen(). Retry behavior does not change, and browser WebSockets are unaffected.

3.108.3

(fix): The generated serialization layer no longer throws “Maximum call stack size exceeded” when a value fails validation with a very large number of nested errors. list, object and record schemas now append child errors in a loop instead of spreading them into Array.prototype.push.

3.108.2

(fix): XML (TwiML) builders match the legacy call shapes: a child builder keeps the child’s name even when it collides with the element’s text field (dial().number("+1…") adds a <Number> child; the text is set with text(...) / setNumber(...)), every element builder has a uniform text(...) setter, and the child-builder verbs are also available on the value itself (new VoiceResponse().say("hi")). Children added through the value’s verbs live in its ordered content (which toXml() renders); the typed child property (children) is not updated by them.

3.108.1

(fix): Fix TS1484 compilation error in the generated XML (TwiML) runtime: src/core/xml/builder.ts imported the XmlSerializable interface as a value, which the ESM build (tsconfig.esm.json, verbatimModuleSyntax) rejects. The import is now type-only, so pnpm build succeeds for SDKs with xml-encoded types.

3.108.0

(fix): With noSerdeLayer: false, JSON-style parts of a multipart request are now serialized before they are encoded, as JSON request bodies are. A part whose type is or contains a named type was sent as toJson(value) with the SDK’s camelCase property names instead of the wire names.

(feat): Add the opt-in includeMultipartPartContentType config option. When enabled, non-file parts of a multipart request carry their declared content type (e.g. OpenAPI encoding.<part>.contentType: application/json) as the part’s Content-Type header. It is off by default because in browsers such parts are sent as a Blob, which also adds filename="".

3.107.8

(fix): With noSerdeLayer: false, the serialization Raw type of an undiscriminated union with a self-recursive map member (e.g. map<string, JsonLike>) now uses an index signature instead of Record<string, JsonLike.Raw>, which TypeScript rejected as a circular type alias (TS2456).

(fix): A named alias of a string-keyed map (e.g. Branch = map<string, Node>) is now emitted as { [key: string]: Node } instead of Record<string, Node>, in both the public type and the serialization Raw type. The two are the same type, but TypeScript rejects a cycle that runs through Record as a circular type alias (TS2456), so a map schema that is part of a recursive type now compiles.

3.107.7

(fix): Fix generated WebhooksHelper.verifyRequest failing to compile (TS2550: Property 'hasOwn' does not exist on type 'ObjectConstructor') under the SDK’s default target: ES6 tsconfig: the supported-algorithm check used Object.prototype.hasOwnProperty.call, which the generator’s Biome --fix --unsafe pass rewrote to the ES2022-only Object.hasOwn. The check is now an isSupportedAlgorithm type guard over Object.keys(HMAC_ALGORITHMS), which Biome leaves alone and which compiles on ES6.

3.107.6

(fix): TypeScript dynamic snippets now follow the SDK generator’s noSerdeLayer default (on unless noSerdeLayer: false or serdeLayer: true is set), so they use wire property names (e.g. per_page) that match the generated request types. Without a serde layer, query parameters, headers, file fields and object properties use the wire value, as the SDK does, even when a name override gives them a different original name. Property names that aren’t valid identifiers (e.g. org.iso.18013.5.1) are now quoted, file values are always sent as a Blob, and a required file field (or file list) missing from the example gets a fs.createReadStream("/path/to/your/file") placeholder instead of being dropped. Optional file fields missing from the example are still left out; dynamic IR from CLIs that predate the isOptional flag treats every file as required. A config that never sets noSerdeLayer but pins a TypeScript generator older than 1.0 (where the serde layer was on by default) now gets wire-name snippets; fern generator upgrade sets the flag explicitly, so upgraded configs are unaffected.

3.107.5

(fix): XML (TwiML) serialization drops characters outside the XML 1.0 Char production (e.g. \x01) from text and attribute values instead of emitting XML that no parser accepts.

3.107.4

(fix): XML (TwiML) child builder methods accept the element’s text content as a string, so legacy-style calls such as response.dial("+15551234567") and response.say("hi") produce <Dial>+15551234567</Dial> instead of an empty element. Element text no longer escapes double quotes as &quot; (attributes still do), matching the legacy TwiML output.

3.107.3

(fix): WebhooksHelper.verifyRequest now parses name=value settings headers when webhook-signature.algorithm-header sets key-id-parameter/algorithm-parameter (e.g. Twilio’s X-Twilio-Webhooks-Signature-Settings: key=<id>,algorithm=HMAC_SHA256), so the key resolver receives the bare key ID instead of key=<id>. Requires IR 67.33.0.

3.107.2

(fix): With flattenAnyAuthOptions enabled, dynamic snippets now keep nested auth options for APIs that use endpoint-level security, which matches the generated SDK. Only auth: any snippets are flattened.

3.107.1

(fix): Reject . and .. as path parameter values. encodeURIComponent leaves dots unencoded, so URL resolution removed these dot segments and sent the request, with its auth headers, to a different endpoint (for example, /users/{userId}/roles with userId: ".." was sent to /roles). The SDK now throws its generic API error (e.g. MyClientError) before the request is sent. SDKs generated with neverThrowErrors throw a plain Error.

3.107.0

(feat): Add the flattenAnyAuthOptions config option. When it is enabled and the API uses auth: any, each scheme’s client options are flat (e.g. { apiKey }, { clientId, clientSecret }, { token }) instead of nested under the scheme key (e.g. { apiKey: { apiKey } }). This matches the Python SDK. Options with the same name, such as the bearer token and the OAuth token override, are shared, and an OAuth token skips the client-credentials flow. The default is false, so existing SDKs keep the nested shape.

3.106.1

(fix): The generated API error’s requestId getter now works without configuration for APIs that return the request ID under a vendor-specific header: it reads X-Request-Id and otherwise falls back to the first response header whose name ends in request-id / requestid (e.g. Twilio-Request-Id, x-amzn-RequestId). Removed the requestIdHeader config option introduced in 3.106.0.

3.106.0

(feat): The generated API error class’s requestId getter now reads the canonical X-Request-Id header (previously the lowercase x-request-id), matching the casing of every other header the SDK emits. Added the requestIdHeader config option so SDKs can point requestId at a different response header, e.g. requestIdHeader: Twilio-Request-Id.

3.105.2

(fix): The generated WebhooksHelper now consumes algorithm-header from api.settings.webhook-signature: a request-level verifyRequest helper reads the configured signature header first (missing or empty fails early with “could not run: missing signature header”), then the algorithm-selection header (e.g. X-Twilio-Webhook-Signature-Settings: <key_id>;HMAC_SHA256) to pick the HMAC algorithm from the configured wire values and hand the key ID to an application-supplied secret resolver. When the header is absent the configured default algorithm and the plain secret are used, so legacy auth-token flows keep working. The lower-level verifySignature is unchanged and still returns false without throwing.