Repository navigation
feat(api-sync): auto-generate SDK methods for standard new operations - #40
Merged
Merged
Conversation
Adds an "operation-insert" change kind to the patcher: a spec operation with no matching SDK method is now classified STANDARD (JSON body/response, mapped to an existing resource by tag, flat scalar object shape) or NON-STANDARD (multipart/form-data, no matching resource, polymorphic schemas, etc), with a specific needs-human reason for the latter. STANDARD operations get a method, and any needed input/response classes, generated and spliced into the mapped resource file automatically, and bump the SDK's minor version the same way an enum addition does. Fixes a latent brace-counting bug (string interpolation's T_CURLY_OPEN token has no matching plain '}' token) uncovered while writing the class-boundary finder this needed. Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends
scripts/api-sync.phpwith a newoperation-insertchange kind so that a spec operation with no matching SDK method no longer always requires a human. Every operation newly present relative to.api-sync/spec-snapshot.jsonis classified:resourceForTag()), and the body shape is a flat object of scalar properties (this generator version's scope). A method, plus any needed input/response classes, is synthesized and spliced into the mapped resource file; the SDK's minor version is bumped the same way an enum addition is.oneOf/anyOf/allOf) or enum/nested-object-bearing schema this generator version doesn't yet synthesize.Key pieces (all in
scripts/api-sync.php):resourceForTag()-- best-effort tag -> resource-file/class table (also backs the fixture-based test, see below).classifyNewOperation()/nonStandardBodyReason()-- the classification boundary.reconcileOperations()-- old-vs-new diff (same event-based mechanism the rest ofcomputeStructuralDiff()uses), with a defensive per-run dedup guard mirroring the existing$scheduledInsertions/$scheduledCasespattern.synthesizeInputClassLines()/synthesizeResponseClassLines()/buildOperationMethodLines()-- code generation, reusingphpTypeFor()/snakeToCamel()and this SDK's documented conventions (ID-empty validation, required-before-optional ctor params, literal+conditionaltoArray()).findClassBoundaries()-- a dedicated, self-contained line counter for splicing new classes/methods into a resource file. Along the way this uncovered a real bug: PHP tokenizes the{of a"{$expr}"string interpolation asT_CURLY_OPEN(no matching plain'}'token on the close side), which silently unbalances a naive brace counter on every interpolated path string -- i.e. every resource method in this SDK. Fixed by treatingT_CURLY_OPENas an opening brace.computeStructuralDiff()no longer unconditionally reports "new operation" -- that's nowreconcileOperations()'s job.computeBump()treatsoperation-insertthe same asenum-member-added(minor bump), wired into the existing single--applypath.Golden self-test
Added to
tests/ApiSync/ApiSyncTest.php, using this repo's existing fixture-based testing convention (a small scratch repo shaped like the real one) rather than mutating the real cloned SDK: the real spec's simplest candidate resources (e.g.PartnerFees) turned out to have pre-existing field-level drift between the committed spec and the hand-written SDK (unrelated to this PR), which would make a real-repo byte-level round-trip assertion meaningless. The fixture keeps the test deterministic and focused on the mechanism itself:buildGoldenRepo()builds a scratch repo with a hand-writtenWidgetsresource (aget(string $id)and acreate(CreateWidgetInput $input)method, matching a spec that already has both operations) plus the full.api-sync/*.jsonset.--apply, and asserts: the regenerated code matches the deleted originals' route, HTTP verb, and parameter/return-type shape (checked structurally, not by exact class name -- the generator derives names from the method name); a second--applyis byte-identical (idempotent, no double-insert); and a synthetic multipart operation on the same tag correctly lands in needs-human with the precise reason.--checkis CI-red while the operation-insert is pending/unapplied, and clean once applied.Test plan
composer test(pest) -- 50 passed, including the new golden self-testvendor/bin/pint --teston both changed files -- passedphp scripts/api-sync.php --check --spec=<current public spec>against this repo's real, unmodified state -- exit 0 (no regression on the real spec/SDK)composer contract-check-- unaffected, still OKhttps://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs