Skip to content

feat(connect): Add Connect module#1597

Open
gjtorikian wants to merge 4 commits into
mainfrom
add-connect
Open

feat(connect): Add Connect module#1597
gjtorikian wants to merge 4 commits into
mainfrom
add-connect

Conversation

@gjtorikian
Copy link
Copy Markdown
Contributor

@gjtorikian gjtorikian commented May 20, 2026

Summary

  • Introduce a new Connect resource client on WorkOS for managing OAuth and M2M applications, application secrets, redirect URIs, user consent options, and the external auth login/consent flow.
  • Add generated interfaces, serializers, fixtures, and specs under src/connect/ from the latest oagen spec.
  • Export src/connect/interfaces from the package barrel so consumers can import the new types.

Test plan

  • npm test passes (unit + serializer specs)
  • npm run build succeeds with the new exports
  • workos.connect is reachable on the client and methods type-check from a consumer

Summary by CodeRabbit

  • New Features

    • Added Connect API client for application management (create/read/update/delete), OAuth & M2M support, listing with pagination and org filtering, client secret management, and completing external OAuth2 flows.
    • Added type definitions, fixtures, and serializers for Connect request/response shapes; re-exported Connect interfaces.
  • Tests

    • Added comprehensive test suite covering Connect operations and serializers.

Review Change Stack

Expose a Connect client for managing OAuth and M2M
applications, application secrets, and the external auth
login/consent flow. Generated from the latest oagen spec
and wired into the WorkOS client alongside the existing
resource clients.
@gjtorikian gjtorikian requested review from a team as code owners May 20, 2026 19:48
@gjtorikian gjtorikian requested a review from ericroberts May 20, 2026 19:48
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c817f3f3-c427-4738-9e18-a7999a2f9e9b

📥 Commits

Reviewing files that changed from the base of the PR and between cda0161 and 7bf0e10.

📒 Files selected for processing (2)
  • src/connect/connect.ts
  • src/connect/interfaces/index.ts
✅ Files skipped from review due to trivial changes (2)
  • src/connect/interfaces/index.ts
  • src/connect/connect.ts

📝 Walkthrough

Walkthrough

This PR adds a generated Connect product client: TypeScript interfaces and serializers, a Connect class with methods for OAuth completion, application CRUD (OAuth/M2M), pagination, and client-secret management; fixtures and Jest tests for serializers and client methods; and exposes Connect in the SDK public API and WorkOS class.

Changes

Connect API Client Implementation

Layer / File(s) Summary
Connect Data Types & Serialization
src/connect/interfaces/*.ts, src/connect/serializers/*.ts
Adds TypeScript interfaces for Connect domain and wire shapes and serializer modules that map fields and timestamps between wire and domain formats.
Connect API Client Methods
src/connect/connect.ts
Adds Connect class with methods: completeOAuth2, listApplications (auto-pagination), createApplication (oauth/m2m), createOAuthApplication, createM2MApplication, getApplication, updateApplication, deleteApplication, listApplicationClientSecrets, createApplicationClientSecret, deleteClientSecret.
Fixtures & Test Suite
src/connect/fixtures/*.json, src/connect/serializers.spec.ts, src/connect/connect.spec.ts
Adds JSON fixtures for requests/responses and Jest tests validating serializer outputs and Connect client HTTP behavior, request shapes, pagination metadata, and 204 deletions.
Public Module Exports & WorkOS Integration
src/index.ts, src/workos.ts, .oagen-manifest.json
Re-exports Connect interfaces at the SDK root, initializes WorkOS.connect = new Connect(this), and updates the generation manifest to include the Connect artifacts.
  • Suggested reviewers:
    • imkesin
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The pull request description provides a summary of changes and a test plan but does not address the 'Documentation' section from the template regarding WorkOS Docs updates. Clarify whether WorkOS Docs updates are required by completing the documentation section of the template with a yes/no answer and any related docs PR links if applicable.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(connect): Add Connect module' clearly summarizes the main change—introducing a new Connect module to the SDK. It follows conventional commit format and accurately reflects the primary objective.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-connect

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 20, 2026

Greptile Summary

This PR introduces a new Connect module to the WorkOS Node SDK, generated from the oagen spec, covering OAuth and M2M application management, client secret lifecycle, and the external auth (Standalone Connect) login/consent flow.

  • New Connect class (src/connect/connect.ts) exposes nine API methods — list, create, get, update, delete for applications; list, create, delete for client secrets; and completeOAuth2 for the external auth bridge.
  • Auto-generated interfaces and serializers cover all request/response shapes including ConnectApplication, NewConnectApplicationSecret, UserManagementLoginRequest, and related types; the barrel export in src/connect/interfaces/index.ts re-exports all types including ListApplicationsOptions.
  • Integration into WorkOS via a new readonly connect property and a package-level barrel export of src/connect/interfaces.

Confidence Score: 4/5

Merging is low-risk for most callers, but the auto-pagination path and the two convenience-method helpers in connect.ts have known functional defects that have been flagged in prior review rounds and remain unaddressed.

The listApplications auto-pagination callback passes raw camelCase options (including organizationId) instead of serialized snake_case, so any paginated traversal with an organization filter silently drops the filter after the first page. The createOAuthApplication and createM2MApplication convenience methods build the wire body by hand, bypassing the typed serializers, which creates a null-vs-absent inconsistency for optional fields. Both issues are present in the code today and affect observable behavior for callers who use those paths.

src/connect/connect.ts — the listApplications pagination callback and the two convenience-method helpers warrant a closer look before this lands.

Important Files Changed

Filename Overview
src/connect/connect.ts Core Connect client with nine API methods; contains known unaddressed bugs with auto-pagination filter serialization and two convenience methods that manually build wire bodies, bypassing typed serializers.
src/connect/interfaces/index.ts Barrel re-exports all Connect interfaces including ListApplicationsOptions; correctly wired into the package-level src/index.ts export.
src/connect/serializers/update-oauth-application.serializer.ts Always serializes unspecified optional fields (description, scopes, redirect_uris) as null; consumers calling updateApplication with only name will send null for those fields.
src/connect/connect.spec.ts Comprehensive HTTP-level tests for all nine Connect methods; uses jest-fetch-mock correctly and covers method, path, body, and response shape.
src/workos.ts Trivial addition of readonly connect = new Connect(this) alongside the existing module properties.
src/index.ts Adds barrel export for src/connect/interfaces; all interface types are now publicly accessible.

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant Connect
    participant WorkOSAPI as WorkOS API

    Consumer->>Connect: completeOAuth2(payload)
    Connect->>WorkOSAPI: POST /authkit/oauth2/complete
    WorkOSAPI-->>Connect: redirect_uri
    Connect-->>Consumer: ExternalAuthCompleteResponse

    Consumer->>Connect: listApplications(options)
    Connect->>WorkOSAPI: GET /connect/applications
    WorkOSAPI-->>Connect: data + listMetadata
    Connect-->>Consumer: AutoPaginatable of ConnectApplication

    Consumer->>Connect: createApplication(payload)
    Connect->>WorkOSAPI: POST /connect/applications
    WorkOSAPI-->>Connect: ConnectApplicationResponse
    Connect-->>Consumer: ConnectApplication

    Consumer->>Connect: createApplicationClientSecret(appId, payload)
    Connect->>WorkOSAPI: POST /connect/applications/:id/client_secrets
    WorkOSAPI-->>Connect: secret + metadata
    Connect-->>Consumer: NewConnectApplicationSecret

    Consumer->>Connect: deleteClientSecret(secretId)
    Connect->>WorkOSAPI: DELETE /connect/client_secrets/:id
    WorkOSAPI-->>Connect: 204
    Connect-->>Consumer: void
Loading

Reviews (2): Last reviewed commit: "Update src/connect/connect.ts" | Re-trigger Greptile

Comment thread src/connect/interfaces/index.ts
Comment thread src/connect/connect.ts
Comment thread src/connect/connect.ts
Comment thread src/connect/connect.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/connect/connect.ts (1)

210-228: ⚡ Quick win

Manual body construction bypasses serialization logic.

Similar to createOAuthApplication, this method manually builds the request body instead of using serializeCreateM2MApplication (imported at line 51). While M2M applications don't have nested objects requiring serialization like OAuth applications do, this is still inconsistent with:

  • The createApplication method (lines 139-163) which uses serializers
  • The updateApplication method (lines 257-269) which uses serializers
♻️ Recommended refactor to use the serializer
 async createM2MApplication(
   name: string,
   organizationId: string,
   description?: string | null,
   scopes?: string[] | null,
 ): Promise<ConnectApplication> {
-  const body: Record<string, unknown> = {
-    application_type: 'm2m',
-    name: name,
-    organization_id: organizationId,
-  };
-  if (description !== undefined) body.description = description;
-  if (scopes !== undefined) body.scopes = scopes;
-  const { data } = await this.workos.post<ConnectApplicationResponse>(
+  const payload: CreateM2MApplication = {
+    applicationType: 'm2m',
+    name,
+    organizationId,
+    ...(description !== undefined && { description }),
+    ...(scopes !== undefined && { scopes }),
+  };
+  const { data } = await this.workos.post<ConnectApplicationResponse, CreateM2MApplicationResponse>(
     '/connect/applications',
-    body,
+    serializeCreateM2MApplication(payload),
   );
   return deserializeConnectApplication(data);
 }
src/connect/serializers.spec.ts (1)

43-43: ⚡ Quick win

Type safety bypassed with as any cast.

The as any cast defeats TypeScript's type checking. While this may be intentional in generated code to handle minor fixture/interface mismatches, it means type errors in serializers won't be caught by these tests.

If oagen controls the generation, consider ensuring fixtures exactly match their corresponding interfaces to avoid needing as any.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a6438bd4-4c7e-48e1-b5b9-0e0b42b27e73

📥 Commits

Reviewing files that changed from the base of the PR and between 9ebc818 and cda0161.

📒 Files selected for processing (49)
  • .oagen-manifest.json
  • src/connect/connect.spec.ts
  • src/connect/connect.ts
  • src/connect/fixtures/application-credentials-list-item.json
  • src/connect/fixtures/connect-application.json
  • src/connect/fixtures/create-application-secret.json
  • src/connect/fixtures/create-m2m-application.json
  • src/connect/fixtures/create-oauth-application.json
  • src/connect/fixtures/external-auth-complete-response.json
  • src/connect/fixtures/list-connect-application.json
  • src/connect/fixtures/new-connect-application-secret.json
  • src/connect/fixtures/redirect-uri-input.json
  • src/connect/fixtures/update-oauth-application.json
  • src/connect/fixtures/user-consent-option-choice.json
  • src/connect/fixtures/user-consent-option.json
  • src/connect/fixtures/user-management-login-request.json
  • src/connect/fixtures/user-object.json
  • src/connect/interfaces/application-credentials-list-item.interface.ts
  • src/connect/interfaces/connect-application.interface.ts
  • src/connect/interfaces/create-application-secret.interface.ts
  • src/connect/interfaces/create-m2m-application.interface.ts
  • src/connect/interfaces/create-oauth-application.interface.ts
  • src/connect/interfaces/external-auth-complete-response.interface.ts
  • src/connect/interfaces/index.ts
  • src/connect/interfaces/list-applications-options.interface.ts
  • src/connect/interfaces/new-connect-application-secret.interface.ts
  • src/connect/interfaces/redirect-uri-input.interface.ts
  • src/connect/interfaces/update-oauth-application.interface.ts
  • src/connect/interfaces/user-consent-option-choice.interface.ts
  • src/connect/interfaces/user-consent-option.interface.ts
  • src/connect/interfaces/user-management-login-request.interface.ts
  • src/connect/interfaces/user-object.interface.ts
  • src/connect/serializers.spec.ts
  • src/connect/serializers/application-credentials-list-item.serializer.ts
  • src/connect/serializers/connect-application.serializer.ts
  • src/connect/serializers/create-application-secret.serializer.ts
  • src/connect/serializers/create-m2m-application.serializer.ts
  • src/connect/serializers/create-oauth-application.serializer.ts
  • src/connect/serializers/external-auth-complete-response.serializer.ts
  • src/connect/serializers/index.ts
  • src/connect/serializers/new-connect-application-secret.serializer.ts
  • src/connect/serializers/redirect-uri-input.serializer.ts
  • src/connect/serializers/update-oauth-application.serializer.ts
  • src/connect/serializers/user-consent-option-choice.serializer.ts
  • src/connect/serializers/user-consent-option.serializer.ts
  • src/connect/serializers/user-management-login-request.serializer.ts
  • src/connect/serializers/user-object.serializer.ts
  • src/index.ts
  • src/workos.ts

Comment thread src/connect/connect.ts
/** A hint showing the last few characters of the secret value. */
secretHint: string;
/** The timestamp when the client secret was last used, or null if never used. */
lastUsedAt: string | null;
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 20, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Timestamp type inconsistency in internal interface.

lastUsedAt is typed as string | null while createdAt and updatedAt are typed as Date. The internal interface should use Date | null for all timestamp fields after deserialization from the wire format. This inconsistency will cause type errors and break code that expects uniform Date handling across timestamp properties.

🐛 Proposed fix
-  lastUsedAt: string | null;
+  lastUsedAt: Date | null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
lastUsedAt: string | null;
lastUsedAt: Date | null;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will work on getting this fixed upstream in the spec

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@gjtorikian Thanks for the update! Since the fix will happen upstream in the spec, would you like me to open a GitHub issue to track the lastUsedAt: string | nullDate | null correction in ApplicationCredentialsListItem? That way it won't get lost before the next oagen regeneration.

Comment thread src/connect/interfaces/index.ts
/** A hint showing the last few characters of the secret value. */
secretHint: string;
/** The timestamp when the client secret was last used, or null if never used. */
lastUsedAt: string | null;
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 20, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Timestamp type inconsistency in internal interface.

lastUsedAt is typed as string | null while createdAt and updatedAt are typed as Date. The internal interface should use Date | null for all timestamp fields after deserialization. This matches the same issue in application-credentials-list-item.interface.ts and will cause type errors when serializers convert timestamps.

🐛 Proposed fix
-  lastUsedAt: string | null;
+  lastUsedAt: Date | null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
lastUsedAt: string | null;
lastUsedAt: Date | null;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will work on getting this fixed upstream in the spec

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@gjtorikian, understood! Since this is an auto-generated file, fixing it at the spec level makes sense. Would you like me to open a GitHub issue to track this fix? It would cover the lastUsedAt: string | nullDate | null correction in both new-connect-application-secret.interface.ts and the same inconsistency in application-credentials-list-item.interface.ts.

Comment thread src/connect/serializers.spec.ts
gjtorikian and others added 3 commits May 20, 2026 16:15
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
/** An ISO 8601 timestamp. */
updatedAt: Date;
/** The type of the application. */
applicationType?: 'm2m';
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.

The CreateM2MApplication and CreateOAuthApplication types look good, but this ConnectApplication type is a bit weird. I'd expect applicationType to be a discriminator between the two as the form a kind of union, but here it only lists m2m.

Seems like this modeling isn't quite right. Is there a way to get the generator to give us something better?

Comment thread src/connect/connect.ts
* @throws {UnprocessableEntityException} 422
*/
async createApplication(
payload: CreateOAuthApplication | CreateM2MApplication,
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.

Nice, this type of union of the different applications is more what I was imagining. 💯

Copy link
Copy Markdown
Contributor

@mthadley mthadley left a comment

Choose a reason for hiding this comment

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

@gjtorikian Overall, looks solid.

The only thing that looks off and that could be usability problem is this, so requesting changes until it can be addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants