2.2.0
(feat): Add omitFernHeaders configuration option. When enabled, Fern platform headers
(X-Fern-Language, X-Fern-SDK-Name, X-Fern-SDK-Version, User-Agent) are omitted
from generated SDK requests.
2.1.12
(fix): Fix WireMock datetime mismatch in wire tests. The mock-utils package generates datetime
query parameter values with milliseconds (e.g., 2022-01-02T00:00:00.000Z) via
Date.toISOString(), but PHP’s DateTimeInterface::RFC3339 format omits fractional
seconds (e.g., 2022-01-02T00:00:00Z). Since WireMock’s equalTo is an exact-match,
the stubs never fired. Now strips zero milliseconds from WireMock datetime query
parameter values to match the PHP SDK’s serialization format.
2.1.11
(chore): Add concurrency configuration to generated CI workflow with cancel-in-progress: false
to prevent stacked runs from being cancelled when a newer run starts.
2.1.10
(fix): Fix serialization and deserialization of boolean values in union types.
(Matches existing fix for floats.)
2.1.9
(fix): Re-throw errors after logging for README.md and reference.md generation failures.
Documentation generation errors now break the generation flow so they are treated
as important to fix.
2.1.8
(fix): Fix dynamic snippets to include global headers in generated code examples.
Previously, required global headers (e.g., X-Organization-ID) configured via
x-fern-global-headers were missing from dynamic snippet output. Also fixes
header value lookup to use wire values instead of a non-existent property.
2.1.7
(chore): Improve error logging for README.md and reference.md generation failures.
The generator now logs the actual error message and stack trace instead
of a generic message, making it easier to diagnose generation issues.
2.1.6
(chore): Parallelize endpoint snippet generation in populateSnippetsCache(). All
endpoints are now processed concurrently via Promise.all instead of
sequentially, reducing snippet generation time for large APIs.
2.1.5
(chore): Standardize WireMock configuration to use WIREMOCK_URL environment variable
(e.g., http://localhost:8080) instead of a hardcoded URL. Docker Compose
now uses dynamic port mapping (0:8080) to avoid port conflicts when running
multiple SDK tests in parallel. The bootstrap script discovers the assigned
port and sets WIREMOCK_URL automatically. Falls back to http://localhost:8080
if the variable is not set.
2.1.4
(fix): Fix PHP 8.5 deprecation warning for ReflectionProperty::getDefaultValue() called on
properties without a default value. Now checks hasDefaultValue() before calling
getDefaultValue() in JsonSerializableType::jsonDeserialize().
2.1.3
(chore): Use generator-cli JS API directly instead of subprocess spawning.
Remove generator-cli from Docker image since it is now bundled via esbuild.
2.1.2
(fix): Fix generateClientInterfaces to generate interfaces for aggregator-only clients (clients
that hold sub-client properties but have no direct API endpoints). Previously, these clients
were skipped, leaving the top-level client and intermediate grouping clients without interfaces.
Interfaces now include typed getter method signatures for each sub-client (e.g.,
getUsers(): UsersClientInterface), and the corresponding client classes implement these
getters.
2.1.1
(fix): Fix PHPStan static analysis errors in core runtime classes. Tightens return types
(e.g., castKey now returns int|string instead of mixed), adds missing null checks,
and improves PHPDoc annotations across JsonSerializer, JsonDeserializer, and Utils.
Also fixes BaseApiException::__toString() to use getCode() instead of direct property
access and print_r() for non-scalar body values.
(fix): Add of object bound to pagination template generics (CursorPager, OffsetPager)
to satisfy PHPStan’s requirement for clone on object types.
2.1.0
(fix): Fix wire test generation for types with required constructor fields. Previously, the
test generator would pass empty arrays [] as constructor arguments when no example
values were provided for required fields (e.g., new SomeType([])). Now generates
appropriate placeholder values based on each field’s type (e.g., new SomeType(['ids' => [1]])).
(feat): Add support for fileDownload (application/octet-stream) and bytes response types.
Previously, endpoints returning binary data would throw an error at runtime because no
success handling was generated. Now these endpoints return the raw response body as a string.
2.0.0
(feat): Introduce PSR-7/17/18 HTTP interfaces for framework-agnostic HTTP client support.
This restores the PSR-7/17/18 agnostic approach that was temporarily reverted in v1.30.0. The SDK now supports any PSR-18 compliant HTTP client (Guzzle, Symfony HttpClient, etc.) and uses php-http/discovery to automatically find an installed client at runtime.
Breaking changes are minimal, but do exist:
- Guzzle is no longer a hard dependency (moved to suggest/require-dev)
- Per-request timeout behavior may differ between HTTP client implementations (currently supported for Guzzle and Symfony)
- Code that directly catches GuzzleHttp\Exception\RequestException will require a refactor
Migration: Existing Guzzle users should be largely unaffected as Guzzle implements PSR-18. For custom HTTP clients, ensure they implement PSR-18 interfaces.
1.30.0
(fix): Temporarily revert PSR-7/17/18 HTTP interfaces back to hard Guzzle dependency.
This restores the pre-1.27.0 behavior where the SDK requires Guzzle as a hard dependency.
Users should expect this to be re-introduced as a breaking change in v2.0.0.
This change reverts the framework-agnostic HTTP client support introduced in v1.27.0, restoring Guzzle middleware-based retry logic and direct Guzzle dependency.