Skip to content

feat: Generate Pipes off the OpenAPI spec#1625

Open
gjtorikian wants to merge 4 commits into
mainfrom
oagen/own-pipes
Open

feat: Generate Pipes off the OpenAPI spec#1625
gjtorikian wants to merge 4 commits into
mainfrom
oagen/own-pipes

Conversation

@gjtorikian

Copy link
Copy Markdown
Contributor

Description

This PR generates the Pipes API fresh from the OpenAPI spec.

The existing shape of methods is preserved. As well, new functions are added:

  • authorizeDataIntegration
  • getUserConnectedAccount
  • deleteUserConnectedAccount
  • listUserDataProviders

Because of this, this is a non-breaking change.

@gjtorikian gjtorikian requested review from a team as code owners June 16, 2026 21:47
@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR regenerates the Pipes module from the OpenAPI spec via oagen, preserving the existing getAccessToken signature while adding four new methods: authorizeDataIntegration, getUserConnectedAccount, deleteUserConnectedAccount, and listUserDataProviders.

  • pipes.ts: All five methods use encodeURIComponent on path segments and follow the repo-wide leading-slash URL convention (fixing a minor inconsistency in the old implementation). The getAccessToken return type was updated from GetAccessTokenResponse to the generated DataIntegrationAccessTokenResponse; the two types are structurally identical so no consumer code breaks.
  • Serializers & interfaces: A new barrel (serializers/index.ts) is added; the discriminated-union deserializer for access-token responses correctly handles active: true/false branches with a fallback throw. Two minor concerns: DataIntegrationsListResponseDataConnectedAccountResponse.userland_user_id is typed as non-optional but the serializer guards with ?? null, suggesting the field can be absent; and CreateDataIntegrationTokenOptions is exported publicly but not wired to any method.
  • Tests: pipes-errors.spec.ts is a hand-written complement to the generated suite, explicitly covering the needs_reauthorization branch and the null-expiry success path that the generator cannot emit.

Confidence Score: 5/5

Safe to merge — new methods are additive and the getAccessToken change is backward compatible at both the TypeScript and runtime levels.

All five methods are well-tested, serialization logic is straightforward, and the discriminated-union deserializer handles the access-token response correctly with a defensive throw on unexpected values. The only open items are a type annotation inconsistency on a deprecated wire field and a dead exported interface, neither of which affects runtime behavior.

src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts — the userland_user_id field type may need to be marked optional to match actual API behavior.

Important Files Changed

Filename Overview
src/pipes/pipes.ts Core Pipes class regenerated from OpenAPI spec; adds 4 new methods with correct encodeURIComponent path safety and consistent leading-slash URL convention; getAccessToken signature preserved for backward compatibility
src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts Wire interface declares `userland_user_id: string
src/pipes/serializers/data-integration-access-token-response.serializer.ts Discriminated-union deserializer for access token response; correctly handles active=true/false branches with a default throw for unexpected values
src/pipes/pipes.spec.ts Updated auto-generated integration tests covering happy-path and error throw for all 5 methods; error-branch deserialization gaps are covered in the companion hand-written pipes-errors.spec.ts
src/pipes/pipes-errors.spec.ts Hand-written supplement covering needs_reauthorization and null-expiry paths that the generator cannot reach; clearly documented to prevent oagen from overwriting it
src/pipes/interfaces/index.ts Barrel exports all new interfaces; CreateDataIntegrationTokenOptions is exported but no method in pipes.ts accepts it, creating a confusing unused public API surface
src/pipes/serializers/index.ts New serializer barrel; exports all serializers including deserializeDataIntegrationAccessTokenResponse (previously flagged as missing)
src/pipes/serializers.spec.ts Auto-generated serializer unit tests; each serializer gets a round-trip test against its fixture with presence assertions

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant C as Caller
    participant P as Pipes
    participant W as WorkOS HTTP Client
    participant API as WorkOS API

    C->>P: "authorizeDataIntegration({ slug, userId, ... })"
    P->>W: "POST /data-integrations/{slug}/authorize"
    W->>API: HTTP POST
    API-->>W: DataIntegrationAuthorizeUrlResponseWire
    W-->>P: "{ url }"
    P-->>C: DataIntegrationAuthorizeUrlResponse

    C->>P: "getAccessToken({ provider, userId, ... })"
    P->>W: "POST /data-integrations/{provider}/token"
    W->>API: HTTP POST
    API-->>W: "DataIntegrationAccessTokenResponseWire (active=true|false)"
    W-->>P: discriminated union
    P-->>C: DataIntegrationAccessTokenResponse

    C->>P: "getUserConnectedAccount({ userId, slug, organizationId? })"
    P->>W: "GET /user_management/users/{userId}/connected_accounts/{slug}"
    W->>API: "HTTP GET ?organization_id=..."
    API-->>W: ConnectedAccountResponse
    W-->>P: ConnectedAccount
    P-->>C: ConnectedAccount

    C->>P: "deleteUserConnectedAccount({ userId, slug, organizationId? })"
    P->>W: "DELETE /user_management/users/{userId}/connected_accounts/{slug}"
    W->>API: "HTTP DELETE ?organization_id=..."
    API-->>W: 204
    P-->>C: void

    C->>P: "listUserDataProviders({ userId, organizationId? })"
    P->>W: "GET /user_management/users/{userId}/data_providers"
    W->>API: "HTTP GET ?organization_id=..."
    API-->>W: DataIntegrationsListResponseWire
    W-->>P: DataIntegrationsListResponse
    P-->>C: DataIntegrationsListResponse
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"}}}%%
sequenceDiagram
    participant C as Caller
    participant P as Pipes
    participant W as WorkOS HTTP Client
    participant API as WorkOS API

    C->>P: "authorizeDataIntegration({ slug, userId, ... })"
    P->>W: "POST /data-integrations/{slug}/authorize"
    W->>API: HTTP POST
    API-->>W: DataIntegrationAuthorizeUrlResponseWire
    W-->>P: "{ url }"
    P-->>C: DataIntegrationAuthorizeUrlResponse

    C->>P: "getAccessToken({ provider, userId, ... })"
    P->>W: "POST /data-integrations/{provider}/token"
    W->>API: HTTP POST
    API-->>W: "DataIntegrationAccessTokenResponseWire (active=true|false)"
    W-->>P: discriminated union
    P-->>C: DataIntegrationAccessTokenResponse

    C->>P: "getUserConnectedAccount({ userId, slug, organizationId? })"
    P->>W: "GET /user_management/users/{userId}/connected_accounts/{slug}"
    W->>API: "HTTP GET ?organization_id=..."
    API-->>W: ConnectedAccountResponse
    W-->>P: ConnectedAccount
    P-->>C: ConnectedAccount

    C->>P: "deleteUserConnectedAccount({ userId, slug, organizationId? })"
    P->>W: "DELETE /user_management/users/{userId}/connected_accounts/{slug}"
    W->>API: "HTTP DELETE ?organization_id=..."
    API-->>W: 204
    P-->>C: void

    C->>P: "listUserDataProviders({ userId, organizationId? })"
    P->>W: "GET /user_management/users/{userId}/data_providers"
    W->>API: "HTTP GET ?organization_id=..."
    API-->>W: DataIntegrationsListResponseWire
    W-->>P: DataIntegrationsListResponse
    P-->>C: DataIntegrationsListResponse
Loading

Reviews (5): Last reviewed commit: "test(pipes): regenerate spec with error-..." | Re-trigger Greptile

Comment thread src/pipes/serializers/index.ts
Comment thread src/pipes/fixtures/data-integration-access-token-response.json
Comment thread src/pipes/pipes.spec.ts
@gjtorikian gjtorikian marked this pull request as draft June 18, 2026 19:06
@gjtorikian gjtorikian added the autogenerated Autogenerated code or content label Jun 18, 2026
@gjtorikian gjtorikian marked this pull request as ready for review June 23, 2026 18:08
gjtorikian and others added 3 commits June 23, 2026 16:05
…coverage

Addresses the review of the Pipes regeneration:

- serializers/index.ts: re-export the discriminated-union serializer
  (deserializeDataIntegrationAccessTokenResponse) that was generated but
  missing from the barrel.
- fixtures/data-integration-access-token-response.json: emit a single valid
  union branch instead of merging mutually-exclusive fields (dropped the
  contradictory `error` alongside `active: true`).
- serializers/data-integrations-get-user-token-request.serializer.ts: pass
  organization_id straight through instead of coercing an omitted optional to
  `null`, matching the prior wire behavior.
- Remove hand-written files orphaned when Pipes became an owned service
  (get-access-token/access-token serializers + 4 unused fixtures).
- Add pipes-errors.spec.ts restoring coverage of getAccessToken's
  `active: false` branches and the null-expiry success path.

The three generated-output changes come from fixes in oagen-emitters
(node-bugfixes); regenerating with that build reproduces them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-add the 500-error-throw assertion that the generated pipes.spec.ts
dropped, completing the hand-owned coverage of getAccessToken alongside
the active:false branches and null-expiry path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate pipes.spec.ts with the new oagen test generation: an
error-path test per method (asserts the client throws on a non-2xx
response) and a union-branch test for getAccessToken's `active: false`
arm (asserts the discriminator on the deserialized result). Only the
pipes changes from the regen are committed; the unrelated cross-service
emitter drift is left out.

Trim the hand-owned pipes-errors.spec.ts now that the generator covers
the `active: false` discriminator routing and the error throw. Two cases
the generator can't reach are kept: the second failure enum value
(`needs_reauthorization`, deep-asserting the deserialized `error` field —
the generated branch test only emits the first value and asserts the
discriminator) and the null-expiry success path (a nullable field, not a
union branch).

21 pipes tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@dandorman dandorman left a comment

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.

looks good to me!

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.

2 participants