You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ac1789b
Browse filesBrowse the repository at this point in the historyBrowse files
feat: implement the URL search params serialization standard (#463)
* feat: implement the URL search params serialization standard
Port @seamapi/url-search-params-serializer to PHP as
Seam\UrlSearchParamsSerializer over a Seam\UrlSearchParams pair
collection, byte-for-byte identical to the TypeScript reference
implementation. The unit test suite mirrors the reference and Python
SDK suites, covering every branch of the standard.
PHP's own primitives each diverge from the standard, so the port
implements them directly: urlencode() is RFC 3986 flavored (escapes *,
keeps ~) where the WHATWG form encoding does the opposite; float
casts render 1.0, switch to exponents at the wrong thresholds, and
spell them E+21, so floats follow the ECMAScript Number::toString
algorithm; sorting compares UTF-16 code units, not UTF-8 bytes; and
dates always carry exactly three fractional digits and a literal Z.
PHP has a single absence value, so the Seam\NullValue enum adds the
explicit null sentinel: null means the safe option of omitting a
param, and sending null is always spelled NullValue::NULL.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
* feat: apply the URL search params standard and type nullable params
Wrap the Guzzle client in Seam\Http\SerializingClient so every request
follows the serialization standard. Query params given as a map are
serialized with UrlSearchParamsSerializer and handed to Guzzle as a raw
query string, since Guzzle's own encoder escapes *, keeps ~, and drops
an empty array entirely instead of sending name= (which the API reads
as the empty array rather than an unfiltered request). NullValue::NULL
sentinels in JSON bodies become JSON null, so the sentinel works on
both transports. A query already given as a string passes through
untouched, and nothing serialized means no query at all rather than a
bare trailing ?.
Consume the blueprint's isNullable flag in the codegen: a nullable
param is typed string|NullValue|null and accepts the sentinel, while a
merely optional one keeps ?string and rejects it, so the type system
catches sending an accidental null where it would unset a value.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
* feat: add _strict=true to the URL search params serializer
Mirror seamapi/python#617: the new StrictUrlSearchParamsSerializer
wraps the base serializer and appends _strict=true to any non-empty
query, telling the Seam API to use strict, schema-aware parsing. The
flag is appended after the sort so it always sits last, a
caller-supplied _strict param is replaced rather than repeated, and a
query with no serializable params stays empty.
The flag is Seam API behavior, not part of the serialization standard,
so it is isolated in the wrapper and the base UrlSearchParamsSerializer
stays a pure implementation of the standard. The SDK client serializes
every request with the strict wrapper.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
* refactor: drop comments that narrate instead of constrain
Keep a comment only when it says something the code cannot: a
non-obvious why, an external constraint, or an invariant a future edit
would break. Comments that narrate a test, restate an assertion, or
argue the code is correct are deleted; the tests are the explanation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
* docs: align the README sections with the other SDKs
Setting a param to null becomes a top-level usage section and
Serializing URL search params follows the structure of the Python and
Ruby READMEs, including the note explaining why PHP spells the
sentinel NullValue::NULL where the other SDKs spell it NULL with type
Null: both names are reserved in PHP, so the type and the value live
on one enum.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
* refactor: sort search params by stable byte order
Drop the UTF-16 sort key: a stable sort is what the standard needs to
keep array element order, and byte order matches URLSearchParams.sort()
for every ASCII name, which all Seam param names are. Only a name
beyond the Basic Multilingual Plane could order differently than the
reference implementation, and then only against a name in U+E000 to
U+FFFF.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HMKbYgbsoFdKiiaxXB6jh2
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments