Skip to content

feat(generated): regenerate from spec (5 changes)#397

Merged
gjtorikian merged 8 commits into
mainfrom
oagen/spec-update-dee95fc33c4f813ac60adfa8c57d210db8183dd8
Jun 17, 2026
Merged

feat(generated): regenerate from spec (5 changes)#397
gjtorikian merged 8 commits into
mainfrom
oagen/spec-update-dee95fc33c4f813ac60adfa8c57d210db8183dd8

Conversation

@workos-sdk-automation

@workos-sdk-automation workos-sdk-automation Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

feat(api_keys): Add expire API key operation and update expires_at requirement

  • Add ApiKeys.createApiKeyExpire() method to expire, schedule, or clear expiration of API keys
  • Make expires_at field required in ApiKeyCreatedData and ApiKeyRevokedData
  • Add new event models: ApiKeyUpdated, ApiKeyUpdatedData, ApiKeyUpdatedDataOwner, UserApiKeyUpdatedDataOwner, ApiKeyUpdatedDataPreviousAttribute
  • Add api_key.updated webhook event type support

feat(user_management)!: Add name field to user models and remove returnTo from revokeSession

  • Add name field (user's full name) to User, CreateUser, UpdateUser, UserObject, EmailChangeConfirmationUser models
  • Add name parameter to createUser() and updateUser() methods
  • Remove returnTo parameter from revokeSession() method (breaking change)

feat(directory_sync): Replace dsync deactivated events with token lifecycle events

  • Remove DsyncDeactivated, DsyncDeactivatedData, DsyncDeactivatedDataDomain models (breaking changes)
  • Add new token lifecycle event models: DsyncTokenCreated, DsyncTokenCreatedData, DsyncTokenRevoked, DsyncTokenRevokedData

feat(radar): Remove DOMAIN_SIGN_UP_RATE_LIMIT control type

  • Remove DOMAIN_SIGN_UP_RATE_LIMIT enum value from RadarStandaloneResponseControl

feat(audit_logs): Add Snowflake log stream type

  • Add SNOWFLAKE enum value to AuditLogConfigurationLogStreamType

Triggered by workos/openapi-spec@dee95fc

BEGIN_COMMIT_OVERRIDE
feat(api_keys): Add expire API key operation and update expires_at requirement (#397)
feat(user_management): Add name field to user models and remove returnTo from revokeSession (#397)
feat(directory_sync): Replace dsync deactivated events with token lifecycle events (#397)
feat(radar): Remove DOMAIN_SIGN_UP_RATE_LIMIT control type (#397)
feat(audit_logs): Add Snowflake log stream type (#397)
END_COMMIT_OVERRIDE

@workos-sdk-automation workos-sdk-automation Bot requested review from a team as code owners June 3, 2026 19:20
@workos-sdk-automation workos-sdk-automation Bot added the autogenerated Autogenerated code or content label Jun 3, 2026
@workos-sdk-automation workos-sdk-automation Bot added the autogenerated Autogenerated code or content label Jun 3, 2026
@greptile-apps

greptile-apps Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This auto-generated PR regenerates the PHP SDK from an updated OpenAPI spec, adding API key expiration support, new webhook event models (api_key.updated, dsync.token.created/revoked), a name field on user models, and a SNOWFLAKE audit log stream type.

  • API key expiration: Adds ApiKeys::createApiKeyExpire() and the ExpireApiKey request resource; also promotes expires_at from optional to required in ApiKeyCreatedData and ApiKeyRevokedData (breaking change documented in the PR).
  • User management: Adds name (full name) to User, CreateUser, UpdateUser, UserObject, and EmailChangeConfirmationUser; removes the returnTo parameter from revokeSession() (breaking change).
  • Directory sync: Replaces the removed dsync.deactivated event models with new DsyncTokenCreated and DsyncTokenRevoked event models; three DsyncDeactivatedContext* helper classes are left behind as unreachable dead code.

Confidence Score: 5/5

Safe to merge; all changes are auto-generated from spec, breaking changes are documented, and the only notable gap is three orphaned context files left behind by the dsync.deactivated removal.

The auto-generated changes are internally consistent and follow established patterns. New event models, user field additions, and the revokeSession simplification are all straightforward. The three orphaned DsyncDeactivatedContext* files are dead code but cause no runtime failures.

lib/Resource/DsyncDeactivatedContext.php and its two companion files (DsyncDeactivatedContextActor.php, DsyncDeactivatedContextGoogleAnalyticsSession.php) should be deleted — they were left unreachable when DsyncDeactivatedData.php was removed.

Important Files Changed

Filename Overview
lib/Service/ApiKeys.php Adds createApiKeyExpire() method; the DateTimeImmutable-to-string serialization bug in the body was already flagged in a prior review thread
lib/Resource/ExpireApiKey.php New request-body resource with correct toArray() date formatting; not used by createApiKeyExpire(), which builds the body manually
lib/Resource/ApiKeyUpdatedData.php New event payload resource for api_key.updated; correctly uses a discriminated union for owner type with UnexpectedValueException on unknown types
lib/Resource/DsyncDeactivatedContext.php Orphaned file — DsyncDeactivatedData.php was deleted but this and its two companion context classes were left behind as unreachable dead code
lib/Service/UserManagement.php Adds name field to createUser/updateUser; removes returnTo from revokeSession; all changes look correct and consistent with resource model updates
lib/Resource/ApiKeyCreatedData.php Makes expiresAt required (no default), moves it before permissions in constructor order; fromArray still handles absent expires_at correctly
lib/Resource/DsyncTokenCreatedData.php New event payload for dsync.token.created; clean implementation following existing patterns
tests/Service/ApiKeysTest.php Adds testCreateApiKeyExpire; only tests the null expiresAt path, so the DateTimeImmutable body serialization bug is not caught by this test

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ApiKeys::createApiKeyExpire] -->|POST expire endpoint| B[HTTP Client]
    B --> C[ApiKey::fromArray response]
    D[ExpireApiKey resource] -.->|defined but unused| A

    E[api_key.updated webhook] --> F[ApiKeyUpdated]
    F --> G[ApiKeyUpdatedData]
    G --> H{owner type}
    H -->|organization| I[ApiKeyUpdatedDataOwner]
    H -->|user| J[UserApiKeyUpdatedDataOwner]
    G --> K[ApiKeyUpdatedDataPreviousAttribute]

    L[dsync.token.created] --> M[DsyncTokenCreated]
    M --> N[DsyncTokenCreatedData]
    O[dsync.token.revoked] --> P[DsyncTokenRevoked]
    P --> Q[DsyncTokenRevokedData]

    R[DsyncDeactivatedContext] -.->|orphaned dead code| S[no references]
    T[DsyncDeactivatedContextActor] -.->|orphaned dead code| S
    U[DsyncDeactivatedContextGoogleAnalyticsSession] -.->|orphaned dead code| S
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[ApiKeys::createApiKeyExpire] -->|POST expire endpoint| B[HTTP Client]
    B --> C[ApiKey::fromArray response]
    D[ExpireApiKey resource] -.->|defined but unused| A

    E[api_key.updated webhook] --> F[ApiKeyUpdated]
    F --> G[ApiKeyUpdatedData]
    G --> H{owner type}
    H -->|organization| I[ApiKeyUpdatedDataOwner]
    H -->|user| J[UserApiKeyUpdatedDataOwner]
    G --> K[ApiKeyUpdatedDataPreviousAttribute]

    L[dsync.token.created] --> M[DsyncTokenCreated]
    M --> N[DsyncTokenCreatedData]
    O[dsync.token.revoked] --> P[DsyncTokenRevoked]
    P --> Q[DsyncTokenRevokedData]

    R[DsyncDeactivatedContext] -.->|orphaned dead code| S[no references]
    T[DsyncDeactivatedContextActor] -.->|orphaned dead code| S
    U[DsyncDeactivatedContextGoogleAnalyticsSession] -.->|orphaned dead code| S
Loading

Reviews (2): Last reviewed commit: "update changelog" | Re-trigger Greptile

Comment thread lib/Service/ApiKeys.php
Comment on lines +145 to +147
$body = array_filter([
'expires_at' => $expiresAt,
], fn ($v) => $v !== null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 DateTimeImmutable serialized as {} in the request body

The HTTP client passes the body to Guzzle's json option (line 227 of HttpClient.php), which calls json_encode internally. DateTimeImmutable does not implement JsonSerializable, so json_encode(new \DateTimeImmutable(...)) returns {}. When a caller passes a future $expiresAt, the API receives {"expires_at":{}} — an invalid value — and will likely return a 400 or silently ignore the field.

Additionally, array_filter removes null entries, so it is impossible to send the explicit "expires_at": null payload that the docblock says clears a scheduled future expiration. Both issues are fixed by formatting the date before serialization and not filtering the field out.

Suggested change
$body = array_filter([
'expires_at' => $expiresAt,
], fn ($v) => $v !== null);
$body = [
'expires_at' => $expiresAt?->format(\DateTimeInterface::RFC3339_EXTENDED),
];

@gjtorikian gjtorikian changed the title feat(generated)!: regenerate from spec (5 changes) feat(generated): regenerate from spec (5 changes) Jun 17, 2026
@gjtorikian gjtorikian merged commit d8a3804 into main Jun 17, 2026
10 checks passed
@gjtorikian gjtorikian deleted the oagen/spec-update-dee95fc33c4f813ac60adfa8c57d210db8183dd8 branch June 17, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autogenerated Autogenerated code or content

Development

Successfully merging this pull request may close these issues.

1 participant