feat!: Regenerate SDK from the OpenAPI spec via oagen - #111
Merged
Conversation
Replace the hand-written SDK with code generated by oagen from the openapi-spec repo. Hand-maintained resource modules covered only a slice of the WorkOS API and drifted as endpoints changed; generated code covers the full surface and stays in lockstep with the spec on regeneration. BREAKING CHANGE: Global application config is removed — build an instance-scoped client with `WorkOS.Client.new/1` and pass it to every resource function. Requires Elixir >= 1.18 (JSON is handled by the stdlib `JSON` module instead of Jason). Version bumps to 2.0.0.
…njection Regenerated with oagen-emitters wrapper/url-builder support: - 10 authenticate_with_* wrappers plus create_oauth_application / create_m2m_application on Connect, each pinning grant_type or application_type and reading client_id/client_secret from the client - SSO.get_authorization_url / get_logout_url and UserManagement.get_authorization_url / get_logout_url emitted as URL builders (no HTTP request) - SSO.get_profile_and_token injects grant_type and client credentials - WorkOS.Client gains :client_id (WORKOS_CLIENT_ID fallback), build_url/3, and param-injection helpers - Connect.complete_oauth_2 renamed to complete_oauth2 (reviewed name) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the @oagen-ignore-file helper surface to Elixir: Passwordless (Magic Link) endpoints, webhook signature verification, AuthKit Actions, sealed session cookies (AES-256-GCM), PKCE utilities, AuthKit and SSO PKCE/device/logout flow helpers, JWKS conveniences, client-side Vault encrypt/decrypt (LEB128-framed, SDK-interoperable), and a PKCE-only public-client preset. All files carry @oagen-ignore-file and live outside the oagen manifest, so regeneration never overwrites or prunes them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The entry module, client, Cast, Page, errors, test_helper, fixture loader, and client runtime-contract tests are spec-independent. They are now marked @oagen-ignore-file so oagen never overwrites or prunes them; the emitter no longer generates them. The manifest drops their entries accordingly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Passing an array query parameter raised ArgumentError before the request ever left the process: Req hands :params to URI.encode_query, which rejects list values outright. build_url/3 comma-joined them correctly but request/5 did not, so four live endpoints were unusable with their documented parameters — list_organizations with :domains, list_events with :events, list_applications with :registration_types, and list_organization_memberships with :statuses. Both paths now share one normalizer so they cannot drift apart again. The remaining changes close gaps against text/sdk-runtime-contract.md: Per-request :max_retries and :base_url overrides were missing from the five the contract requires; only headers, timeout, and idempotency key were honored. Retried POSTs now get a generated idempotency key. Retries are enabled by default and only one of 211 operations opted in via the spec's injectIdempotencyKey, so by default a POST could be replayed against the API with no key at all. :idempotency still works with retries disabled, for the spec-driven case. ApiError gains :param, which the contract asks implementations to preserve where possible; WorkOS reports the offending field either at the top level or per-entry under errors. Nil query values are dropped rather than sent as `key=`, matching build_url/3.
Emitter output only; no hand-authored changes here. Every generated success test now pins the request method, the request path, and real field values, and each service gains empty-page, query-encoding, and per-request-option coverage alongside new per-group round-trip tests. 321 tests to 545. Two model changes come from the spec rather than the emitter: Connection drops callback_endpoint, which the spec no longer declares, and several models gain deprecation notes for fields the spec marked deprecated. The union-split parents create_authenticate and create_application are gone, replaced by their wrapper methods; the spec-driven split makes the parent unreachable.
These six moduledocs named a symbol this SDK does not define — docs for `MfaTotpSessionAuthenticateRequest` sat under `defmodule WorkOS.MFATotpSessionAuthenticateRequest`, and one rendered a raw snake_case fragment as `ConnectApplication_redirect_uri`. Regenerated output of the emitter fix; no hand edits.
openapi-spec v0.50.0 and v0.51.0 add a free-form `config` string map to the DataIntegration request bodies and configuration response, and a `client_credentials` value to the connected-account auth method enums. Regenerated output; no hand edits.
|
Too many files changed for review. ( |
# Conflicts: # lib/workos/user_management/organization_membership.ex # test/support/user_management_client_mock.ex
Elixir 1.20 warns when a variable used inside size(...) of a bitstring pattern was bound outside the match, and the lint job compiles with --warnings-as-errors on the newest pair — so these four patterns failed CI even though the matches were correct. The warning does not exist on 1.19 or earlier, which is why `script/ci` passes locally while CI goes red.
The regenerated SDK requires Elixir ~> 1.18 because JSON now goes through the stdlib JSON module instead of Jason. Mix refuses to run on 1.16 and 1.17 outright, so both legs failed before reaching a single test — they are leftovers from the hand-written SDK's support window.
The lint job runs `mix credo --strict -a`, which enables the low-priority design checks. AliasUsage flagged 20 fully-qualified references to three-deep modules, failing CI with exit 2. Only hand-maintained files were affected — nothing here changes generated output or the emitter.
script/ci ran `mix credo --all` while lint.yml runs `mix credo --strict -a` — 57 checks locally versus 69 in CI. It also compiled in dev, where elixirc_paths omits test/support, while every CI job sets MIX_ENV=test. Both gaps let a clean local run precede a red PR, which is the one thing this script exists to prevent.
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
Replaces the hand-written SDK with oagen-generated code. The hand-maintained resource modules covered only a slice of the WorkOS API and drifted as endpoints changed; generated output covers the full surface and stays in lockstep with
openapi-specon every regenerationRemoves global application config — this is the main breaking change. Build an instance-scoped client with
WorkOS.Client.new/1and pass it as the first argument to every resource function.config/*.exsis gone. Elixir >= 1.18 is now required, since JSON goes through the stdlibJSONmodule instead of Jason. Version bumps to 2.0.0.Keeps the non-spec helper surface hand-maintained. Passwordless (Magic Link), webhook signature verification, AuthKit Actions, sealed session cookies (AES-256-GCM), PKCE utilities, JWKS conveniences, client-side Vault encrypt/decrypt (LEB128-framed, interoperable with the other SDKs), and a PKCE-only public-client preset all carry
@oagen-ignore-fileand sit outside the manifest, so regeneration never overwrites or prunes them. The entry module, client,Cast,Page, and error modules are marked the same way.Fixes four endpoints that were unusable with their documented parameters. Array query params raised
ArgumentErrorbefore the request left the process — Req passes:paramstoURI.encode_query, which rejects lists — breakinglist_organizationswith:domains,list_eventswith:events,list_applicationswith:registration_types, andlist_organization_membershipswith:statuses.build_url/3andrequest/5now share one normalizer so they can't drift apart again.Closes the remaining gaps against the SDK runtime contract. Per-request
:max_retriesand:base_urloverrides now work alongside headers/timeout/idempotency key; retried POSTs get a generated idempotency key (previously only 1 of 211 operations opted in via the spec, so a retried POST could be replayed with no key);ApiErrorgains:param; nil query values are dropped rather than sent askey=.