3.42.3

(chore): Update bundled npm tar package from 7.5.8 to 7.5.10 to fix GHSA-qffp-2rhf-9h96 (Hardlink Path Traversal via Drive-Relative Linkpath).


3.42.2

(fix): Fix custom-plugins configuration not being applied when running in local/download-files mode (fern generate --local). The download-files config class was missing the customPlugins field, causing the values to be silently dropped during deserialization.


3.42.1

(fix): Fix compilation error for objects with many properties that exceed the JVM 255-parameter-slot limit. Types like CMS-1500 claim forms caused too many parameters javac errors. The generator now computes precise JVM slot counts (long/double consume two slots, all other types one) and, when the threshold is exceeded, generates a constructor that accepts the Builder as a single parameter, keeping the public API unchanged.


3.42.0

(feat): Add support for custom Gradle plugins via the custom-plugins configuration option. Users can now specify custom Gradle plugins (with optional versions) that will be added to the generated build.gradle file. Format: ["plugin-id:version", "plugin-id"]. Plugins are applied after built-in plugins (java-library, maven-publish, spotless).

3.41.0

(feat): Add custom-interceptors configuration option for the Java SDK generator. When enabled (custom-interceptors: true in generators.yml), the generated client builder exposes an addInterceptor(Interceptor) method that allows SDK users to add custom OkHttp interceptors. Interceptors are applied to the OkHttpClient when the client is built. This enables use cases like PKCV (Public Key Client Validation), custom request signing, and other HTTP-level customizations via custom code protected by .fernignore.

3.40.9

(fix): Fix wire test generation for form-urlencoded request bodies: objects now serialize as Java’s Map.toString() format ({key=value}) instead of JSON ({"key":"value"}), and ISO 8601 dates with zero seconds drop the :00 to match Java’s OffsetDateTime.toString() output (e.g. 2015-07-30T20:00Z instead of 2015-07-30T20:00:00Z).

3.40.8

(fix): Fix wire test generation to convert RFC 2822 dates to ISO 8601 in both the mock response body (served by MockWebServer) and the expected response assertion. Previously, only the expected response was converted, leaving RFC 2822 dates in the mock response which caused DateTimeParseException during Jackson deserialization for fields typed as dateTime (not dateTimeRfc2822). The conversion now happens upfront so a single normalized resource file is shared by both mock setup and validation.

3.40.7

(fix): Fix wire test generation for URI and path paginated endpoints returning wrong type. The published @fern-fern/ir-sdk doesn’t include uri/path as Pagination union members, so the raw IR JSON passes through undeserialized with _type discriminant fields instead of type. The generator now normalizes raw IR JSON (_typetype) before extracting the pagination item type, so wire tests correctly use SyncPagingIterable<T> instead of the raw response type.

3.40.6

(fix): Fix wire test generation for form-urlencoded request body encoding. The generator now uses + for spaces (matching Java’s URLEncoder.encode()) instead of %20 (from encodeURIComponent), serializes arrays as [val1, val2] (matching Java’s List.toString()), and serializes objects as JSON strings.

(fix): Fix wire test generation for RFC 2822 date fields. The expected response body in wire tests now converts RFC 2822 dates (e.g. Thu, 30 Jul 2015 20:00:00 +0000) to ISO 8601 with Z suffix (e.g. 2015-07-30T20:00:00Z) to match Jackson’s JavaTimeModule serialization of OffsetDateTime. The mock response body retains RFC 2822 dates since the SDK’s Rfc2822DateTimeDeserializer handles them correctly.

3.40.5

(fix): Fix wire test generation for URI and path paginated endpoints. The generated wire tests incorrectly used the raw response type (e.g. ListMessagesResponse) instead of the paginated return type (SyncPagingIterable<T>) for endpoints using URI or path-based pagination, causing compilation failures.


3.40.4

(fix): Bump Jackson from 2.18.2 to 2.18.6 to fix GHSA-72hv-8253-57qq (Number Length Constraint Bypass in Async Parser leading to potential DoS).


3.40.3

(fix): Make OAuth authentication section a stable feature block in generated READMEs. Previously, the authentication documentation was injected as an addendum to the Usage block with a ## Authentication heading, which the BlockMerger parsed as a separate top-level block on subsequent merges. The authentication content is now registered as a proper AUTHENTICATION feature with a stable block ID, making README merges deterministic.

3.40.2

(fix): Patch minimatch to 10.2.3 in container to fix GHSA-7r86-cg39-jmmj (ReDoS via combinatorial backtracking in matchOne()) and GHSA-23c5-xmqv-rm74 (ReDoS via nested *() extglobs).


3.40.1

(fix): Fix Rfc2822DateTimeDeserializer visibility. The class was generated with package-private access, causing compilation errors when types in other packages referenced it via @JsonDeserialize(using = ...). The class is now public.

(fix): Fix URI/path pagination generating String instead of Optional<String> for the next page token. UriPage.create and PathPage.create expect Optional<String>, but getNestedPropertySnippet was unwrapping the optional via .orElse(null). The generator now builds the getter chain directly to preserve the Optional<String> type.

3.40.0

(feat): Add DATE_TIME_RFC_2822 primitive type support. Fields with format: date-time-rfc-2822 (e.g. Twilio’s dateCreated, dateSent, dateUpdated) now generate as OffsetDateTime with a per-field @JsonDeserialize(using = Rfc2822DateTimeDeserializer.class) annotation that parses RFC 2822 dates via DateTimeFormatter.RFC_1123_DATE_TIME.

3.39.1

(chore): Use generator-cli JS API directly instead of subprocess spawning. Remove generator-cli from Docker image since it is now bundled via esbuild.


3.39.0

(feat): Add support for logging to the generated SDK. Users can configure logging by passing a LogConfig to the client builder’s .logging() method.

1import com.example.api.AcmeApiClient;
2import com.example.api.core.LogConfig;
3import com.example.api.core.LogLevel;
4import com.example.api.core.ConsoleLogger;
5
6AcmeApiClient client = AcmeApiClient.builder()
7 .token("YOUR_TOKEN")
8 .logging(LogConfig.builder()
9 .level(LogLevel.DEBUG) // INFO is the default
10 .logger(new ConsoleLogger()) // ConsoleLogger is the default
11 .silent(false) // true is the default, set to false to enable logging
12 .build())
13 .build();

The LogConfig builder accepts the following properties:

  • level(LogLevel): The log level to use. Defaults to LogLevel.INFO.
  • logger(ILogger): The logger implementation to use. Defaults to ConsoleLogger.
  • silent(boolean): Whether to silence the logger. Defaults to true.

The LogLevel enum supports the following values:

  • DEBUG
  • INFO
  • WARN
  • ERROR

To provide a custom logger, implement the ILogger interface with debug, info, warn, and error methods.

HTTP request and response details (method, URL, status code, headers, body) are logged via a LoggingInterceptor added to the OkHttp client. Sensitive headers (authorization, x-api-key, cookie, x-csrf-token, etc.) are automatically redacted in logs.


3.38.1

(fix): Preserve existing README.md when the generator does not produce one. Previously, overwriteLocalContents deleted all files before copying generator output, so if README generation failed silently the file was removed from the target repository. The method now skips deleting README.md when the source directory does not include it.


3.37.1

(fix): Update container packages to fix 8 security vulnerabilities: gnupg2-minimal (CVE-2026-24882), curl-minimal and libcurl-minimal (CVE-2025-13034, CVE-2025-14017, CVE-2025-14524, CVE-2025-14819, CVE-2025-15079, CVE-2025-15224), alsa-lib (CVE-2026-25068), expat (CVE-2026-25210), openssh and openssh-clients (CVE-2025-61984, CVE-2025-61985), and npm tar (GHSA-83g3-92jg-28cx).