Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## 3.91.0
**`(feat):`** Add the opt-in `deepObjectMapQueryParameters` configuration option. When enabled, query parameters typed
as a map (e.g. `map<string, string>`, which is what an OpenAPI `type: object` + `additionalProperties`
schema imports as) are handed to the query builder and serialized in deepObject form
(`?metadata[env]=prod`) instead of being JSON-stringified (`?metadata=%7B%22env%22...`). Maps whose
values are objects, nested maps, lists, sets, or date-times are supported too: with the serde layer
enabled they are run through the generated schema first, so nested keys use wire names, sets become
arrays, and dates are ISO strings (`?metadata[env][created_at]=2026-09-04T00:00:00.000Z`). Defaults to
`false`, so existing SDKs are unaffected.

```yaml
- name: fernapi/fern-typescript-sdk
config:
deepObjectMapQueryParameters: true
```

Maps with `unknown` values (an OpenAPI `additionalProperties: true` import) are rejected at
generation time. There is no schema to normalize such a value against, so a non-plain object like a
`Date` or a `Set` would contribute no enumerable keys and be dropped from the query string with no
error. Rather than emit an SDK that silently loses data, generation fails:

```
Query parameter 'metadata' on GET /search is a map with `unknown` values, which
`deepObjectMapQueryParameters` cannot safely encode: a non-plain object such as a Date or a Set
would be silently dropped from the query string.
Either give the map a concrete value type (so the serde layer can normalize it), or disable
`deepObjectMapQueryParameters`.
```

One other behaviour to be aware of, inherent to deepObject encoding: an empty map is omitted from the
query string entirely, where it previously serialized as `?key=%7B%7D`. There are no keys to explode,
so nothing is emitted.

Query parameters explicitly declared `explode: false` keep their existing encoding; deepObject form is
only applied where `explode` is true or unset.


Loading