Skip to content

Port PHP SDK code generation from nextlove to Metalsmith#446

Merged
razor-x merged 4 commits into
mainfrom
claude/php-codegen-port-4399z1
Jul 21, 2026
Merged

Port PHP SDK code generation from nextlove to Metalsmith#446
razor-x merged 4 commits into
mainfrom
claude/php-codegen-port-4399z1

Conversation

@razor-x

@razor-x razor-x commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

Migrate the PHP SDK code generation from the @seamapi/nextlove-sdk-generator package to an in-repo Metalsmith-based plugin. This replaces the external dependency with a local implementation that maintains byte-identical output while enabling future improvements.

Key Changes

  • New Metalsmith plugin (codegen/lib/routes.ts): Core code generation logic that iterates over blueprint routes and endpoints to generate PHP resource classes and client methods
  • OpenAPI parsing utilities: Added frozen output-parity workarounds ported from nextlove:
    • deep-extract-resource-object-schemas.ts: Extracts nested object schemas into separate resource classes
    • get-parameter-and-response-schema.ts: Parses request/response schemas from OpenAPI
    • deep-flatten-one-of-and-all-of-schema.ts: Flattens complex schema compositions
    • flatten-obj-schema.ts: Normalizes object schemas
    • get-filtered-routes.ts: Filters routes based on OpenAPI extensions
    • map-parent-to-children-resource.ts: Maps parent resources to child namespaces
  • Layout builders: Context generators for Handlebars templates:
    • layouts/object.ts: Builds context for resource object classes
    • layouts/seam-client.ts: Builds context for SeamClient and resource client classes
  • Handlebars templates: PHP code generation templates:
    • layouts/object.hbs: Resource object class template
    • layouts/seam-client.hbs: SeamClient class template
    • layouts/partials/client-class.hbs: Resource client class template
    • layouts/partials/route-method.hbs: Client method template
    • layouts/partials/poll-until-ready.hbs: Action attempt polling template
  • Build configuration:
    • codegen/smith.ts: Metalsmith pipeline setup
    • tsconfig.json: TypeScript configuration
    • eslint.config.ts: ESLint configuration
  • Build script: Updated package.json to use tsx codegen/smith.ts instead of node generate-routes.js

Implementation Details

  • All OpenAPI parsing utilities are marked as TEMPORARY with TODO comments indicating they should migrate to @seamapi/blueprint once output changes are allowed
  • The implementation maintains exact output parity with the previous generator, including quirks like the ActionAttempt result widening and integer-to-mixed type mapping
  • PHP type mapping and parameter sorting logic are verbatim ports from nextlove to ensure identical output
  • The code uses the blueprint for route/endpoint iteration order while consulting raw OpenAPI specs where the blueprint normalizes data differently

https://claude.ai/code/session_01UrUX4ghim2PDnBjXayuLDj

claude and others added 4 commits July 21, 2026 21:07
Replace the @seamapi/nextlove-sdk-generator based generation with the
metalsmith + handlebars + @seamapi/blueprint architecture used by
seamapi/javascript-http and seamapi/python. The generated output under
src/ (SeamClient.php and Objects/*.php) is byte-identical.

The blueprint drives the route, endpoint, and namespace iteration order.
The raw OpenAPI spec is still consulted wherever the nextlove generator
derived output from data the blueprint normalizes differently (integer
vs number types, resource schema set and order, parameter and oneOf/allOf
flattening, deeply nested namespaces); each of those spots carries a TODO
to migrate to the blueprint once output is allowed to change, and the
supporting code lives in files marked TEMPORARY.

- Add codegen/ with the Metalsmith pipeline, plugin, context builders,
  and Handlebars layouts and partials
- Remove generate-routes.js
- Pin @seamapi/types at 1.827.0 for output parity and use
  @seamapi/blueprint 0.55.0 with @seamapi/smith
- Add tsconfig.json, a one-line eslint.config.ts, and typecheck, lint,
  postlint, and preformat scripts matching seamapi/docs
- Ignore *.hbs and CODEGEN.md in a new .prettierignore since the glimmer
  parser mangles PHP-flavored templates, and format .ts with the js rules
- Ignore the generated CODEGEN.md seed and *.tsbuildinfo in .gitignore

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrUX4ghim2PDnBjXayuLDj
The HttpError and Paginator tests ran against the hosted
fake.seam.vc test server, so they fail whenever that service is
unavailable (as it currently is, returning 500s) rather than testing
the SDK. Remove those server-dependent tests and the Fixture helper.

Keep testNonSeamError, which exercises the client's connection-error
handling against an unreachable host and needs no Seam server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrUX4ghim2PDnBjXayuLDj
The previous commit deleted tests/Fixture.php but did not stage the
HttpErrorTest edit that removes its Fixture usage, so CI still ran the
old server-dependent tests and errored with "Class Tests\Fixture not
found". Apply the intended HttpErrorTest, leaving only testNonSeamError.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrUX4ghim2PDnBjXayuLDj
@razor-x
razor-x marked this pull request as ready for review July 21, 2026 22:05
@razor-x
razor-x merged commit 2d5ee5c into main Jul 21, 2026
5 checks passed
@razor-x
razor-x deleted the claude/php-codegen-port-4399z1 branch July 21, 2026 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants