diff --git a/.oagen-manifest.json b/.oagen-manifest.json index ba29803e3..f4f865519 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -1,7 +1,7 @@ { "version": 2, "language": "node", - "generatedAt": "2026-06-01T17:59:24.986Z", + "generatedAt": "2026-06-16T18:02:10.415Z", "files": [ "src/api-keys/interfaces/create-validation-options.interface.ts", "src/api-keys/interfaces/delete-api-key-options.interface.ts", @@ -82,6 +82,47 @@ "src/groups/serializers/index.ts", "src/groups/serializers/update-group.serializer.ts", "src/groups/serializers/user-organization-membership-base-list-data.serializer.ts", + "src/pipes/fixtures/connected-account.json", + "src/pipes/fixtures/data-integration-access-token-response-access-token.json", + "src/pipes/fixtures/data-integration-access-token-response.json", + "src/pipes/fixtures/data-integration-authorize-url-response.json", + "src/pipes/fixtures/data-integrations-get-data-integration-authorize-url-request.json", + "src/pipes/fixtures/data-integrations-get-user-token-request.json", + "src/pipes/fixtures/data-integrations-list-response-data-connected-account.json", + "src/pipes/fixtures/data-integrations-list-response-data.json", + "src/pipes/fixtures/data-integrations-list-response.json", + "src/pipes/interfaces/authorize-data-integration-options.interface.ts", + "src/pipes/interfaces/connected-account-state.interface.ts", + "src/pipes/interfaces/connected-account.interface.ts", + "src/pipes/interfaces/create-data-integration-token-options.interface.ts", + "src/pipes/interfaces/data-integration-access-token-response-access-token.interface.ts", + "src/pipes/interfaces/data-integration-access-token-response-error.interface.ts", + "src/pipes/interfaces/data-integration-access-token-response.interface.ts", + "src/pipes/interfaces/data-integration-authorize-url-response.interface.ts", + "src/pipes/interfaces/data-integrations-get-data-integration-authorize-url-request.interface.ts", + "src/pipes/interfaces/data-integrations-get-user-token-request.interface.ts", + "src/pipes/interfaces/data-integrations-list-response-data-connected-account-state.interface.ts", + "src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts", + "src/pipes/interfaces/data-integrations-list-response-data-ownership.interface.ts", + "src/pipes/interfaces/data-integrations-list-response-data.interface.ts", + "src/pipes/interfaces/data-integrations-list-response.interface.ts", + "src/pipes/interfaces/delete-user-connected-account-options.interface.ts", + "src/pipes/interfaces/get-user-connected-account-options.interface.ts", + "src/pipes/interfaces/index.ts", + "src/pipes/interfaces/list-user-data-providers-options.interface.ts", + "src/pipes/pipes.spec.ts", + "src/pipes/pipes.ts", + "src/pipes/serializers.spec.ts", + "src/pipes/serializers/connected-account.serializer.ts", + "src/pipes/serializers/data-integration-access-token-response-access-token.serializer.ts", + "src/pipes/serializers/data-integration-access-token-response.serializer.ts", + "src/pipes/serializers/data-integration-authorize-url-response.serializer.ts", + "src/pipes/serializers/data-integrations-get-data-integration-authorize-url-request.serializer.ts", + "src/pipes/serializers/data-integrations-get-user-token-request.serializer.ts", + "src/pipes/serializers/data-integrations-list-response-data-connected-account.serializer.ts", + "src/pipes/serializers/data-integrations-list-response-data.serializer.ts", + "src/pipes/serializers/data-integrations-list-response.serializer.ts", + "src/pipes/serializers/index.ts", "src/radar/fixtures/radar-list-entry-already-present-response.json", "src/radar/fixtures/radar-standalone-assess-request.json", "src/radar/fixtures/radar-standalone-delete-radar-list-entry-request.json", diff --git a/src/pipes/fixtures/connected-account.json b/src/pipes/fixtures/connected-account.json new file mode 100644 index 000000000..47260b9ed --- /dev/null +++ b/src/pipes/fixtures/connected-account.json @@ -0,0 +1,10 @@ +{ + "object": "connected_account", + "id": "data_installation_01EHZNVPK3SFK441A1RGBFSHRT", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": null, + "scopes": ["repo", "user:email"], + "state": "connected", + "created_at": "2024-01-16T14:20:00.000Z", + "updated_at": "2024-01-16T14:20:00.000Z" +} diff --git a/src/pipes/fixtures/data-integration-access-token-response-access-token.json b/src/pipes/fixtures/data-integration-access-token-response-access-token.json new file mode 100644 index 000000000..d9f476c0b --- /dev/null +++ b/src/pipes/fixtures/data-integration-access-token-response-access-token.json @@ -0,0 +1,7 @@ +{ + "object": "access_token", + "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a", + "expires_at": "2025-12-31T23:59:59.000Z", + "scopes": ["repo", "user:email"], + "missing_scopes": [] +} diff --git a/src/pipes/fixtures/data-integration-access-token-response.json b/src/pipes/fixtures/data-integration-access-token-response.json new file mode 100644 index 000000000..2b0c3da0c --- /dev/null +++ b/src/pipes/fixtures/data-integration-access-token-response.json @@ -0,0 +1,10 @@ +{ + "active": true, + "access_token": { + "object": "access_token", + "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a", + "expires_at": "2025-12-31T23:59:59.000Z", + "scopes": ["repo", "user:email"], + "missing_scopes": [] + } +} diff --git a/src/pipes/fixtures/data-integration-authorize-url-response.json b/src/pipes/fixtures/data-integration-authorize-url-response.json new file mode 100644 index 000000000..0d6b120d0 --- /dev/null +++ b/src/pipes/fixtures/data-integration-authorize-url-response.json @@ -0,0 +1,3 @@ +{ + "url": "https://api.workos.com/data-integrations/q2czJKmVAraSBg8xFpT7M9uR/authorize-redirect" +} diff --git a/src/pipes/fixtures/data-integrations-get-data-integration-authorize-url-request.json b/src/pipes/fixtures/data-integrations-get-data-integration-authorize-url-request.json new file mode 100644 index 000000000..b38a7cd52 --- /dev/null +++ b/src/pipes/fixtures/data-integrations-get-data-integration-authorize-url-request.json @@ -0,0 +1,5 @@ +{ + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", + "return_to": "https://example.com/callback" +} diff --git a/src/pipes/fixtures/data-integrations-get-user-token-request.json b/src/pipes/fixtures/data-integrations-get-user-token-request.json new file mode 100644 index 000000000..ef8c44380 --- /dev/null +++ b/src/pipes/fixtures/data-integrations-get-user-token-request.json @@ -0,0 +1,4 @@ +{ + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT" +} diff --git a/src/pipes/fixtures/data-integrations-list-response-data-connected-account.json b/src/pipes/fixtures/data-integrations-list-response-data-connected-account.json new file mode 100644 index 000000000..17097fac7 --- /dev/null +++ b/src/pipes/fixtures/data-integrations-list-response-data-connected-account.json @@ -0,0 +1,11 @@ +{ + "object": "connected_account", + "id": "data_installation_01EHZNVPK3SFK441A1RGBFSHRT", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "test_organizationId", + "scopes": ["repo", "user:email"], + "state": "connected", + "created_at": "test_createdAt", + "updated_at": "test_updatedAt", + "userland_user_id": "test_userlandUserId" +} diff --git a/src/pipes/fixtures/data-integrations-list-response-data.json b/src/pipes/fixtures/data-integrations-list-response-data.json new file mode 100644 index 000000000..8a79e6da9 --- /dev/null +++ b/src/pipes/fixtures/data-integrations-list-response-data.json @@ -0,0 +1,24 @@ +{ + "object": "data_provider", + "id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "name": "GitHub", + "description": "Connect your GitHub account to access repositories.", + "slug": "github", + "integration_type": "test_integrationType", + "credentials_type": "test_credentialsType", + "scopes": ["repo", "user:email"], + "ownership": "userland_user", + "created_at": "test_createdAt", + "updated_at": "test_updatedAt", + "connected_account": { + "object": "connected_account", + "id": "data_installation_01EHZNVPK3SFK441A1RGBFSHRT", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "test_organizationId", + "scopes": ["repo", "user:email"], + "state": "connected", + "created_at": "test_createdAt", + "updated_at": "test_updatedAt", + "userland_user_id": "test_userlandUserId" + } +} diff --git a/src/pipes/fixtures/data-integrations-list-response.json b/src/pipes/fixtures/data-integrations-list-response.json new file mode 100644 index 000000000..b0ab94489 --- /dev/null +++ b/src/pipes/fixtures/data-integrations-list-response.json @@ -0,0 +1,29 @@ +{ + "object": "list", + "data": [ + { + "object": "data_provider", + "id": "data_integration_01EHZNVPK3SFK441A1RGBFSHRT", + "name": "GitHub", + "description": "Connect your GitHub account to access repositories.", + "slug": "github", + "integration_type": "test_integrationType", + "credentials_type": "test_credentialsType", + "scopes": ["repo", "user:email"], + "ownership": "userland_user", + "created_at": "test_createdAt", + "updated_at": "test_updatedAt", + "connected_account": { + "object": "connected_account", + "id": "data_installation_01EHZNVPK3SFK441A1RGBFSHRT", + "user_id": "user_01EHZNVPK3SFK441A1RGBFSHRT", + "organization_id": "test_organizationId", + "scopes": ["repo", "user:email"], + "state": "connected", + "created_at": "test_createdAt", + "updated_at": "test_updatedAt", + "userland_user_id": "test_userlandUserId" + } + } + ] +} diff --git a/src/pipes/fixtures/get-access-token-needs-reauth.json b/src/pipes/fixtures/get-access-token-needs-reauth.json deleted file mode 100644 index 2dc793597..000000000 --- a/src/pipes/fixtures/get-access-token-needs-reauth.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "active": false, - "error": "needs_reauthorization" -} diff --git a/src/pipes/fixtures/get-access-token-no-expiry.json b/src/pipes/fixtures/get-access-token-no-expiry.json deleted file mode 100644 index f34a2712b..000000000 --- a/src/pipes/fixtures/get-access-token-no-expiry.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "active": true, - "access_token": { - "object": "access_token", - "access_token": "test_access_token_456", - "expires_at": null, - "scopes": ["read:data"], - "missing_scopes": ["write:data"] - } -} diff --git a/src/pipes/fixtures/get-access-token-not-installed.json b/src/pipes/fixtures/get-access-token-not-installed.json deleted file mode 100644 index 2e1a5adb5..000000000 --- a/src/pipes/fixtures/get-access-token-not-installed.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "active": false, - "error": "not_installed" -} diff --git a/src/pipes/fixtures/get-access-token-success.json b/src/pipes/fixtures/get-access-token-success.json deleted file mode 100644 index e071bb703..000000000 --- a/src/pipes/fixtures/get-access-token-success.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "active": true, - "access_token": { - "object": "access_token", - "access_token": "test_access_token_123", - "expires_at": "2025-10-18T12:00:00.000Z", - "scopes": ["read:users", "write:users"], - "missing_scopes": [] - } -} diff --git a/src/pipes/interfaces/authorize-data-integration-options.interface.ts b/src/pipes/interfaces/authorize-data-integration-options.interface.ts new file mode 100644 index 000000000..53305f767 --- /dev/null +++ b/src/pipes/interfaces/authorize-data-integration-options.interface.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface AuthorizeDataIntegrationOptions { + /** The slug identifier of the provider (e.g., `github`, `slack`, `notion`). */ + slug: string; + /** The ID of the user to authorize. */ + userId: string; + /** An organization ID to scope the authorization to a specific organization. */ + organizationId?: string; + /** The URL to redirect the user to after authorization. */ + returnTo?: string; +} diff --git a/src/pipes/interfaces/connected-account-state.interface.ts b/src/pipes/interfaces/connected-account-state.interface.ts new file mode 100644 index 000000000..49beb89e4 --- /dev/null +++ b/src/pipes/interfaces/connected-account-state.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export const ConnectedAccountState = { + Connected: 'connected', + NeedsReauthorization: 'needs_reauthorization', + Disconnected: 'disconnected', +} as const; + +export type ConnectedAccountState = + (typeof ConnectedAccountState)[keyof typeof ConnectedAccountState]; diff --git a/src/pipes/interfaces/connected-account.interface.ts b/src/pipes/interfaces/connected-account.interface.ts new file mode 100644 index 000000000..b027f50ea --- /dev/null +++ b/src/pipes/interfaces/connected-account.interface.ts @@ -0,0 +1,38 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { ConnectedAccountState } from './connected-account-state.interface'; + +export interface ConnectedAccount { + /** Distinguishes the connected account object. */ + object: 'connected_account'; + /** The unique identifier of the connected account. */ + id: string; + /** The [User](https://workos.com/docs/reference/authkit/user) identifier associated with this connection. */ + userId: string | null; + /** The [Organization](https://workos.com/docs/reference/organization) identifier associated with this connection, or `null` if not scoped to an organization. */ + organizationId: string | null; + /** The OAuth scopes granted for this connection. */ + scopes: string[]; + /** + * The state of the connected account: + * - `connected`: The connection is active and tokens are valid. + * - `needs_reauthorization`: The user needs to reauthorize the connection, typically because required scopes have changed. + * - `disconnected`: The connection has been disconnected. + */ + state: ConnectedAccountState; + /** The timestamp when the connection was created. */ + createdAt: string; + /** The timestamp when the connection was last updated. */ + updatedAt: string; +} + +export interface ConnectedAccountResponse { + object: 'connected_account'; + id: string; + user_id: string | null; + organization_id: string | null; + scopes: string[]; + state: ConnectedAccountState; + created_at: string; + updated_at: string; +} diff --git a/src/pipes/interfaces/create-data-integration-token-options.interface.ts b/src/pipes/interfaces/create-data-integration-token-options.interface.ts new file mode 100644 index 000000000..f6c6ca2c7 --- /dev/null +++ b/src/pipes/interfaces/create-data-integration-token-options.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface CreateDataIntegrationTokenOptions { + /** The identifier of the integration. */ + slug: string; + /** A [User](https://workos.com/docs/reference/authkit/user) identifier. */ + userId: string; + /** An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization. */ + organizationId?: string; +} diff --git a/src/pipes/interfaces/data-integration-access-token-response-access-token.interface.ts b/src/pipes/interfaces/data-integration-access-token-response-access-token.interface.ts new file mode 100644 index 000000000..80c171760 --- /dev/null +++ b/src/pipes/interfaces/data-integration-access-token-response-access-token.interface.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by oagen. Do not edit. + +/** The [access token](https://workos.com/docs/reference/pipes/access-token) object, present when `active` is `true`. */ +export interface DataIntegrationAccessTokenResponseAccessToken { + /** Distinguishes the access token object. */ + object: 'access_token'; + /** The OAuth access token for the connected integration. */ + accessToken: string; + /** The ISO-8601 formatted timestamp indicating when the access token expires. */ + expiresAt: Date | null; + /** The scopes granted to the access token. */ + scopes: string[]; + /** If the integration has requested scopes that aren't present on the access token, they're listed here. */ + missingScopes: string[]; +} + +export interface DataIntegrationAccessTokenResponseAccessTokenResponse { + object: 'access_token'; + access_token: string; + expires_at: string | null; + scopes: string[]; + missing_scopes: string[]; +} diff --git a/src/pipes/interfaces/data-integration-access-token-response-error.interface.ts b/src/pipes/interfaces/data-integration-access-token-response-error.interface.ts new file mode 100644 index 000000000..64066e574 --- /dev/null +++ b/src/pipes/interfaces/data-integration-access-token-response-error.interface.ts @@ -0,0 +1,9 @@ +// This file is auto-generated by oagen. Do not edit. + +export const DataIntegrationAccessTokenResponseError = { + NotInstalled: 'not_installed', + NeedsReauthorization: 'needs_reauthorization', +} as const; + +export type DataIntegrationAccessTokenResponseError = + (typeof DataIntegrationAccessTokenResponseError)[keyof typeof DataIntegrationAccessTokenResponseError]; diff --git a/src/pipes/interfaces/data-integration-access-token-response.interface.ts b/src/pipes/interfaces/data-integration-access-token-response.interface.ts new file mode 100644 index 000000000..d703985ba --- /dev/null +++ b/src/pipes/interfaces/data-integration-access-token-response.interface.ts @@ -0,0 +1,17 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationAccessTokenResponseAccessToken, + DataIntegrationAccessTokenResponseAccessTokenResponse, +} from './data-integration-access-token-response-access-token.interface'; + +export type DataIntegrationAccessTokenResponse = + | { active: true; accessToken: DataIntegrationAccessTokenResponseAccessToken } + | { active: false; error: 'needs_reauthorization' | 'not_installed' }; + +export type DataIntegrationAccessTokenResponseWire = + | { + active: true; + access_token: DataIntegrationAccessTokenResponseAccessTokenResponse; + } + | { active: false; error: 'needs_reauthorization' | 'not_installed' }; diff --git a/src/pipes/interfaces/data-integration-authorize-url-response.interface.ts b/src/pipes/interfaces/data-integration-authorize-url-response.interface.ts new file mode 100644 index 000000000..eae80c60d --- /dev/null +++ b/src/pipes/interfaces/data-integration-authorize-url-response.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DataIntegrationAuthorizeUrlResponse { + /** The OAuth authorization URL to redirect the user to. */ + url: string; +} + +export interface DataIntegrationAuthorizeUrlResponseWire { + url: string; +} diff --git a/src/pipes/interfaces/data-integrations-get-data-integration-authorize-url-request.interface.ts b/src/pipes/interfaces/data-integrations-get-data-integration-authorize-url-request.interface.ts new file mode 100644 index 000000000..d59991717 --- /dev/null +++ b/src/pipes/interfaces/data-integrations-get-data-integration-authorize-url-request.interface.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DataIntegrationsGetDataIntegrationAuthorizeUrlRequest { + /** The ID of the user to authorize. */ + userId: string; + /** An organization ID to scope the authorization to a specific organization. */ + organizationId?: string; + /** The URL to redirect the user to after authorization. */ + returnTo?: string; +} + +export interface DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse { + user_id: string; + organization_id?: string; + return_to?: string; +} diff --git a/src/pipes/interfaces/data-integrations-get-user-token-request.interface.ts b/src/pipes/interfaces/data-integrations-get-user-token-request.interface.ts new file mode 100644 index 000000000..24c3875d3 --- /dev/null +++ b/src/pipes/interfaces/data-integrations-get-user-token-request.interface.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DataIntegrationsGetUserTokenRequest { + /** A [User](https://workos.com/docs/reference/authkit/user) identifier. */ + userId: string; + /** An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization. */ + organizationId?: string | null; +} + +export interface DataIntegrationsGetUserTokenRequestResponse { + user_id: string; + organization_id?: string | null; +} diff --git a/src/pipes/interfaces/data-integrations-list-response-data-connected-account-state.interface.ts b/src/pipes/interfaces/data-integrations-list-response-data-connected-account-state.interface.ts new file mode 100644 index 000000000..2acbeb924 --- /dev/null +++ b/src/pipes/interfaces/data-integrations-list-response-data-connected-account-state.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export const DataIntegrationsListResponseDataConnectedAccountState = { + Connected: 'connected', + NeedsReauthorization: 'needs_reauthorization', + Disconnected: 'disconnected', +} as const; + +export type DataIntegrationsListResponseDataConnectedAccountState = + (typeof DataIntegrationsListResponseDataConnectedAccountState)[keyof typeof DataIntegrationsListResponseDataConnectedAccountState]; diff --git a/src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts b/src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts new file mode 100644 index 000000000..3912b16bd --- /dev/null +++ b/src/pipes/interfaces/data-integrations-list-response-data-connected-account.interface.ts @@ -0,0 +1,44 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { DataIntegrationsListResponseDataConnectedAccountState } from './data-integrations-list-response-data-connected-account-state.interface'; + +export interface DataIntegrationsListResponseDataConnectedAccount { + /** Distinguishes the connected account object. */ + object: 'connected_account'; + /** The unique identifier of the connected account. */ + id: string; + /** The [User](https://workos.com/docs/reference/authkit/user) identifier associated with this connection. */ + userId: string | null; + /** The [Organization](https://workos.com/docs/reference/organization) identifier associated with this connection, or `null` if not scoped to an organization. */ + organizationId: string | null; + /** The OAuth scopes granted for this connection. */ + scopes: string[]; + /** + * The state of the connected account: + * - `connected`: The connection is active and tokens are valid. + * - `needs_reauthorization`: The user needs to reauthorize the connection, typically because required scopes have changed. + * - `disconnected`: The connection has been disconnected. + */ + state: DataIntegrationsListResponseDataConnectedAccountState; + /** The timestamp when the connection was created. */ + createdAt: string; + /** The timestamp when the connection was last updated. */ + updatedAt: string; + /** + * Use `user_id` instead. + * @deprecated + */ + userlandUserId: string | null; +} + +export interface DataIntegrationsListResponseDataConnectedAccountResponse { + object: 'connected_account'; + id: string; + user_id: string | null; + organization_id: string | null; + scopes: string[]; + state: DataIntegrationsListResponseDataConnectedAccountState; + created_at: string; + updated_at: string; + userland_user_id: string | null; +} diff --git a/src/pipes/interfaces/data-integrations-list-response-data-ownership.interface.ts b/src/pipes/interfaces/data-integrations-list-response-data-ownership.interface.ts new file mode 100644 index 000000000..481181a74 --- /dev/null +++ b/src/pipes/interfaces/data-integrations-list-response-data-ownership.interface.ts @@ -0,0 +1,9 @@ +// This file is auto-generated by oagen. Do not edit. + +export const DataIntegrationsListResponseDataOwnership = { + UserlandUser: 'userland_user', + Organization: 'organization', +} as const; + +export type DataIntegrationsListResponseDataOwnership = + (typeof DataIntegrationsListResponseDataOwnership)[keyof typeof DataIntegrationsListResponseDataOwnership]; diff --git a/src/pipes/interfaces/data-integrations-list-response-data.interface.ts b/src/pipes/interfaces/data-integrations-list-response-data.interface.ts new file mode 100644 index 000000000..ba78aeb69 --- /dev/null +++ b/src/pipes/interfaces/data-integrations-list-response-data.interface.ts @@ -0,0 +1,49 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsListResponseDataConnectedAccount, + DataIntegrationsListResponseDataConnectedAccountResponse, +} from './data-integrations-list-response-data-connected-account.interface'; +import type { DataIntegrationsListResponseDataOwnership } from './data-integrations-list-response-data-ownership.interface'; + +export interface DataIntegrationsListResponseData { + /** Distinguishes the data provider object. */ + object: 'data_provider'; + /** The unique identifier of the provider. */ + id: string; + /** The display name of the provider (e.g., "GitHub", "Slack"). */ + name: string; + /** A description of the provider explaining how it will be used, if configured. */ + description: string | null; + /** The slug identifier used in API calls (e.g., `github`, `slack`, `notion`). */ + slug: string; + /** The type of integration (e.g., `github`, `slack`). */ + integrationType: string; + /** The type of credentials used by the provider (e.g., `oauth2`). */ + credentialsType: string; + /** The OAuth scopes configured for this provider, or `null` if none are configured. */ + scopes: string[] | null; + /** Whether the provider is owned by a user or organization. */ + ownership: DataIntegrationsListResponseDataOwnership; + /** The timestamp when the provider was created. */ + createdAt: string; + /** The timestamp when the provider was last updated. */ + updatedAt: string; + /** The user's [connected account](https://workos.com/docs/reference/pipes/connected-account) for this provider, or `null` if the user has not connected. */ + connectedAccount: DataIntegrationsListResponseDataConnectedAccount | null; +} + +export interface DataIntegrationsListResponseDataResponse { + object: 'data_provider'; + id: string; + name: string; + description: string | null; + slug: string; + integration_type: string; + credentials_type: string; + scopes: string[] | null; + ownership: DataIntegrationsListResponseDataOwnership; + created_at: string; + updated_at: string; + connected_account: DataIntegrationsListResponseDataConnectedAccountResponse | null; +} diff --git a/src/pipes/interfaces/data-integrations-list-response.interface.ts b/src/pipes/interfaces/data-integrations-list-response.interface.ts new file mode 100644 index 000000000..5afef10dd --- /dev/null +++ b/src/pipes/interfaces/data-integrations-list-response.interface.ts @@ -0,0 +1,18 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsListResponseData, + DataIntegrationsListResponseDataResponse, +} from './data-integrations-list-response-data.interface'; + +export interface DataIntegrationsListResponse { + /** Indicates this is a list response. */ + object: 'list'; + /** A list of [providers](https://workos.com/docs/reference/pipes/provider), each including a [`connected_account`](https://workos.com/docs/reference/pipes/connected-account) field with the user's connection status. */ + data: DataIntegrationsListResponseData[]; +} + +export interface DataIntegrationsListResponseWire { + object: 'list'; + data: DataIntegrationsListResponseDataResponse[]; +} diff --git a/src/pipes/interfaces/delete-user-connected-account-options.interface.ts b/src/pipes/interfaces/delete-user-connected-account-options.interface.ts new file mode 100644 index 000000000..c044d1f4d --- /dev/null +++ b/src/pipes/interfaces/delete-user-connected-account-options.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DeleteUserConnectedAccountOptions { + /** A [User](https://workos.com/docs/reference/authkit/user) identifier. */ + userId: string; + /** The slug identifier of the provider (e.g., `github`, `slack`, `notion`). */ + slug: string; + /** An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization. */ + organizationId?: string; +} diff --git a/src/pipes/interfaces/get-user-connected-account-options.interface.ts b/src/pipes/interfaces/get-user-connected-account-options.interface.ts new file mode 100644 index 000000000..e35ebc59c --- /dev/null +++ b/src/pipes/interfaces/get-user-connected-account-options.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetUserConnectedAccountOptions { + /** A [User](https://workos.com/docs/reference/authkit/user) identifier. */ + userId: string; + /** The slug identifier of the provider (e.g., `github`, `slack`, `notion`). */ + slug: string; + /** An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization. */ + organizationId?: string; +} diff --git a/src/pipes/interfaces/index.ts b/src/pipes/interfaces/index.ts index 5e19e976b..46441c501 100644 --- a/src/pipes/interfaces/index.ts +++ b/src/pipes/interfaces/index.ts @@ -1,2 +1,22 @@ +// This file is auto-generated by oagen. Do not edit. + export * from './access-token.interface'; +export * from './authorize-data-integration-options.interface'; +export * from './connected-account-state.interface'; +export * from './connected-account.interface'; +export * from './create-data-integration-token-options.interface'; +export * from './data-integration-access-token-response-access-token.interface'; +export * from './data-integration-access-token-response-error.interface'; +export * from './data-integration-access-token-response.interface'; +export * from './data-integration-authorize-url-response.interface'; +export * from './data-integrations-get-data-integration-authorize-url-request.interface'; +export * from './data-integrations-get-user-token-request.interface'; +export * from './data-integrations-list-response-data-connected-account-state.interface'; +export * from './data-integrations-list-response-data-connected-account.interface'; +export * from './data-integrations-list-response-data-ownership.interface'; +export * from './data-integrations-list-response-data.interface'; +export * from './data-integrations-list-response.interface'; +export * from './delete-user-connected-account-options.interface'; export * from './get-access-token.interface'; +export * from './get-user-connected-account-options.interface'; +export * from './list-user-data-providers-options.interface'; diff --git a/src/pipes/interfaces/list-user-data-providers-options.interface.ts b/src/pipes/interfaces/list-user-data-providers-options.interface.ts new file mode 100644 index 000000000..b51dc0dde --- /dev/null +++ b/src/pipes/interfaces/list-user-data-providers-options.interface.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface ListUserDataProvidersOptions { + /** A [User](https://workos.com/docs/reference/authkit/user) identifier to list providers and connected accounts for. */ + userId: string; + /** An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to filter connections for a specific organization. */ + organizationId?: string; +} diff --git a/src/pipes/pipes-errors.spec.ts b/src/pipes/pipes-errors.spec.ts new file mode 100644 index 000000000..b0fbe209e --- /dev/null +++ b/src/pipes/pipes-errors.spec.ts @@ -0,0 +1,57 @@ +// Hand-written supplement to the generated pipes.spec.ts. The generated suite +// now covers getAccessToken's happy path, the `active: false` branch (asserting +// the discriminator), and the error-throw path. Two gaps the generator can't +// reach remain here: the second failure enum value — the generated branch test +// only emits the first (`not_installed`) and asserts the discriminator, not the +// deserialized `error` field — and the null-expiry success path, which is a +// nullable field rather than a union branch. Keep this file hand-owned (distinct +// name) so `regenerateOwnedTests` does not overwrite it. +import fetch from 'jest-fetch-mock'; +import { fetchOnce } from '../common/utils/test-utils'; +import { WorkOS } from '../workos'; + +const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); + +describe('Pipes getAccessToken inactive responses', () => { + beforeEach(() => fetch.resetMocks()); + + it('deserializes a needs_reauthorization error response', async () => { + fetchOnce({ active: false, error: 'needs_reauthorization' }); + + const result = await workos.pipes.getAccessToken({ + provider: 'test_provider', + userId: 'user_id_01234', + }); + + expect(result).toEqual({ active: false, error: 'needs_reauthorization' }); + }); + + it('deserializes a success response without an expiry date', async () => { + fetchOnce({ + active: true, + access_token: { + object: 'access_token', + access_token: 'test_access_token', + expires_at: null, + scopes: ['read:data'], + missing_scopes: [], + }, + }); + + const result = await workos.pipes.getAccessToken({ + provider: 'test_provider', + userId: 'user_id_01234', + }); + + expect(result).toEqual({ + active: true, + accessToken: { + object: 'access_token', + accessToken: 'test_access_token', + expiresAt: null, + scopes: ['read:data'], + missingScopes: [], + }, + }); + }); +}); diff --git a/src/pipes/pipes.spec.ts b/src/pipes/pipes.spec.ts index 03a002519..5f0ece960 100644 --- a/src/pipes/pipes.spec.ts +++ b/src/pipes/pipes.spec.ts @@ -1,108 +1,188 @@ +// This file is auto-generated by oagen. Do not edit. + import fetch from 'jest-fetch-mock'; -import { fetchOnce, fetchURL, fetchBody } from '../common/utils/test-utils'; +import { + fetchOnce, + fetchURL, + fetchMethod, + fetchBody, +} from '../common/utils/test-utils'; import { WorkOS } from '../workos'; -import getAccessTokenSuccessFixture from './fixtures/get-access-token-success.json'; -import getAccessTokenNoExpiryFixture from './fixtures/get-access-token-no-expiry.json'; -import getAccessTokenNotInstalledFixture from './fixtures/get-access-token-not-installed.json'; -import getAccessTokenNeedsReauthFixture from './fixtures/get-access-token-needs-reauth.json'; + +import dataIntegrationAuthorizeUrlResponseFixture from './fixtures/data-integration-authorize-url-response.json'; +import dataIntegrationAccessTokenResponseFixture from './fixtures/data-integration-access-token-response.json'; +import connectedAccountFixture from './fixtures/connected-account.json'; +import dataIntegrationsListResponseFixture from './fixtures/data-integrations-list-response.json'; + +const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); describe('Pipes', () => { - let workos: WorkOS; + beforeEach(() => fetch.resetMocks()); + + describe('authorizeDataIntegration', () => { + it('sends the correct request and returns result', async () => { + fetchOnce(dataIntegrationAuthorizeUrlResponseFixture); + + const result = await workos.pipes.authorizeDataIntegration({ + slug: 'test_slug', + userId: 'user_id_01234', + }); - beforeAll(() => { - workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', { - apiHostname: 'api.workos.test', - clientId: 'proj_123', + expect(fetchMethod()).toBe('POST'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/data-integrations/test_slug/authorize', + ); + expect(fetchBody()).toEqual( + expect.objectContaining({ user_id: 'user_id_01234' }), + ); + expect(result.url).toBe( + 'https://api.workos.com/data-integrations/q2czJKmVAraSBg8xFpT7M9uR/authorize-redirect', + ); }); - }); - beforeEach(() => fetch.resetMocks()); + it('throws when the API responds with an error', async () => { + fetchOnce({ message: 'Bad Request' }, { status: 400 }); + + await expect( + workos.pipes.authorizeDataIntegration({ + slug: 'test_slug', + userId: 'user_id_01234', + }), + ).rejects.toThrow(); + }); + }); describe('getAccessToken', () => { - it('returns access token with expiry date', async () => { - fetchOnce(getAccessTokenSuccessFixture); - const response = await workos.pipes.getAccessToken({ - provider: 'test-provider', - userId: 'user_123', - organizationId: 'org_456', - }); + it('sends the correct request and returns result', async () => { + fetchOnce(dataIntegrationAccessTokenResponseFixture); - expect(fetchURL()).toContain('/data-integrations/test-provider/token'); - expect(fetchBody()).toEqual({ - user_id: 'user_123', - organization_id: 'org_456', - }); - expect(response).toEqual({ - active: true, - accessToken: { - object: 'access_token', - accessToken: 'test_access_token_123', - expiresAt: new Date('2025-10-18T12:00:00.000Z'), - scopes: ['read:users', 'write:users'], - missingScopes: [], - }, + const result = await workos.pipes.getAccessToken({ + provider: 'test_provider', + userId: 'user_id_01234', }); + + expect(fetchMethod()).toBe('POST'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/data-integrations/test_provider/token', + ); + expect(fetchBody()).toEqual( + expect.objectContaining({ user_id: 'user_id_01234' }), + ); + expect(result).toBeDefined(); }); - it('returns access token without expiry date', async () => { - fetchOnce(getAccessTokenNoExpiryFixture); - const response = await workos.pipes.getAccessToken({ - provider: 'test-provider', - userId: 'user_789', - }); + it('returns the active=false response variant', async () => { + fetchOnce({ active: false, error: 'not_installed' }); - expect(fetchURL()).toContain('/data-integrations/test-provider/token'); - expect(fetchBody()).toEqual({ - user_id: 'user_789', - organization_id: undefined, - }); - expect(response).toEqual({ - active: true, - accessToken: { - object: 'access_token', - accessToken: 'test_access_token_456', - expiresAt: null, - scopes: ['read:data'], - missingScopes: ['write:data'], - }, + const result = await workos.pipes.getAccessToken({ + provider: 'test_provider', + userId: 'user_id_01234', }); + + expect(result.active).toBe(false); }); - it('returns not_installed failure when integration is not installed', async () => { - fetchOnce(getAccessTokenNotInstalledFixture); - const response = await workos.pipes.getAccessToken({ - provider: 'test-provider', - userId: 'user_123', - }); + it('throws when the API responds with an error', async () => { + fetchOnce({ message: 'Bad Request' }, { status: 400 }); - expect(fetchURL()).toContain('/data-integrations/test-provider/token'); - expect(response).toEqual({ - active: false, - error: 'not_installed', + await expect( + workos.pipes.getAccessToken({ + provider: 'test_provider', + userId: 'user_id_01234', + }), + ).rejects.toThrow(); + }); + }); + + describe('getUserConnectedAccount', () => { + it('returns the expected result', async () => { + fetchOnce(connectedAccountFixture); + + const result = await workos.pipes.getUserConnectedAccount({ + userId: 'test_userId', + slug: 'test_slug', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/user_management/users/test_userId/connected_accounts/test_slug', + ); + expect(result.object).toBe('connected_account'); + expect(result.id).toBe('data_installation_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.userId).toBe('user_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.organizationId).toBeNull(); + expect(result.scopes).toEqual(['repo', 'user:email']); + expect(result.state).toBe('connected'); + expect(result.createdAt).toBe('2024-01-16T14:20:00.000Z'); + expect(result.updatedAt).toBe('2024-01-16T14:20:00.000Z'); }); - it('returns needs_reauthorization failure when token needs refresh', async () => { - fetchOnce(getAccessTokenNeedsReauthFixture); - const response = await workos.pipes.getAccessToken({ - provider: 'test-provider', - userId: 'user_123', + it('throws when the API responds with an error', async () => { + fetchOnce({ message: 'Bad Request' }, { status: 400 }); + + await expect( + workos.pipes.getUserConnectedAccount({ + userId: 'test_userId', + slug: 'test_slug', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', + }), + ).rejects.toThrow(); + }); + }); + + describe('deleteUserConnectedAccount', () => { + it('sends a DELETE request', async () => { + fetchOnce({}, { status: 204 }); + + await workos.pipes.deleteUserConnectedAccount({ + userId: 'test_userId', + slug: 'test_slug', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', }); - expect(fetchURL()).toContain('/data-integrations/test-provider/token'); - expect(response).toEqual({ - active: false, - error: 'needs_reauthorization', + expect(fetchMethod()).toBe('DELETE'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/user_management/users/test_userId/connected_accounts/test_slug', + ); + }); + + it('throws when the API responds with an error', async () => { + fetchOnce({ message: 'Bad Request' }, { status: 400 }); + + await expect( + workos.pipes.deleteUserConnectedAccount({ + userId: 'test_userId', + slug: 'test_slug', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', + }), + ).rejects.toThrow(); + }); + }); + + describe('listUserDataProviders', () => { + it('returns the expected result', async () => { + fetchOnce(dataIntegrationsListResponseFixture); + + const result = await workos.pipes.listUserDataProviders({ + userId: 'test_userId', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/user_management/users/test_userId/data_providers', + ); + expect(result.object).toBe('list'); }); - it('throws error for server errors', async () => { - fetchOnce({ message: 'Internal Server Error' }, { status: 500 }); + it('throws when the API responds with an error', async () => { + fetchOnce({ message: 'Bad Request' }, { status: 400 }); await expect( - workos.pipes.getAccessToken({ - provider: 'test-provider', - userId: 'user_123', + workos.pipes.listUserDataProviders({ + userId: 'test_userId', + organizationId: 'org_01EHZNVPK3SFK441A1RGBFSHRT', }), ).rejects.toThrow(); }); diff --git a/src/pipes/pipes.ts b/src/pipes/pipes.ts index 0bb23b22e..5a2beec79 100644 --- a/src/pipes/pipes.ts +++ b/src/pipes/pipes.ts @@ -1,28 +1,186 @@ +// This file is auto-generated by oagen. Do not edit. + import type { WorkOS } from '../workos'; -import { - GetAccessTokenOptions, - GetAccessTokenResponse, - SerializedGetAccessTokenResponse, -} from './interfaces/get-access-token.interface'; -import { - serializeGetAccessTokenOptions, - deserializeGetAccessTokenResponse, -} from './serializers/get-access-token.serializer'; +import type { AuthorizeDataIntegrationOptions } from './interfaces/authorize-data-integration-options.interface'; +import type { GetAccessTokenOptions } from './interfaces/get-access-token.interface'; +import type { GetUserConnectedAccountOptions } from './interfaces/get-user-connected-account-options.interface'; +import type { DeleteUserConnectedAccountOptions } from './interfaces/delete-user-connected-account-options.interface'; +import type { ListUserDataProvidersOptions } from './interfaces/list-user-data-providers-options.interface'; +import type { + DataIntegrationAuthorizeUrlResponse, + DataIntegrationAuthorizeUrlResponseWire, +} from './interfaces/data-integration-authorize-url-response.interface'; +import type { + DataIntegrationAccessTokenResponse, + DataIntegrationAccessTokenResponseWire, +} from './interfaces/data-integration-access-token-response.interface'; +import type { + ConnectedAccount, + ConnectedAccountResponse, +} from './interfaces/connected-account.interface'; +import type { + DataIntegrationsListResponse, + DataIntegrationsListResponseWire, +} from './interfaces/data-integrations-list-response.interface'; +import type { DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse } from './interfaces/data-integrations-get-data-integration-authorize-url-request.interface'; +import type { DataIntegrationsGetUserTokenRequestResponse } from './interfaces/data-integrations-get-user-token-request.interface'; +import { deserializeDataIntegrationAuthorizeUrlResponse } from './serializers/data-integration-authorize-url-response.serializer'; +import { deserializeDataIntegrationAccessTokenResponse } from './serializers/data-integration-access-token-response.serializer'; +import { deserializeConnectedAccount } from './serializers/connected-account.serializer'; +import { deserializeDataIntegrationsListResponse } from './serializers/data-integrations-list-response.serializer'; +import { serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest } from './serializers/data-integrations-get-data-integration-authorize-url-request.serializer'; +import { serializeDataIntegrationsGetUserTokenRequest } from './serializers/data-integrations-get-user-token-request.serializer'; export class Pipes { constructor(private readonly workos: WorkOS) {} - async getAccessToken({ - provider, - ...options - }: GetAccessTokenOptions & { - provider: string; - }): Promise { - const { data } = await this.workos.post( - `data-integrations/${provider}/token`, - serializeGetAccessTokenOptions(options), + /** + * Get authorization URL + * + * Generates an OAuth authorization URL to initiate the connection flow for a user. Redirect the user to the returned URL to begin the OAuth flow with the third-party provider. + * @param options - The request options. + * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @example "github" + * @returns {Promise} + * @throws {BadRequestException} 400 + * @throws {UnauthorizedException} 401 + * @throws {AuthorizationException} 403 + * @throws {NotFoundException} 404 + */ + async authorizeDataIntegration( + options: AuthorizeDataIntegrationOptions, + ): Promise { + const { slug, ...payload } = options; + const { data } = await this.workos.post< + DataIntegrationAuthorizeUrlResponseWire, + DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse + >( + `/data-integrations/${encodeURIComponent(slug)}/authorize`, + serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest(payload), + ); + return deserializeDataIntegrationAuthorizeUrlResponse(data); + } + + /** + * Get an access token for a connected account + * + * Fetches a valid OAuth access token for a user's connected account. WorkOS automatically handles token refresh, ensuring you always receive a valid, non-expired token. + * @param options - Object containing userId. + * @param options.provider - The identifier of the integration. + * @example "github" + * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier. + * @example "user_01EHZNVPK3SFK441A1RGBFSHRT" + * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to scope the connection to a specific organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {BadRequestException} 400 + * @throws {UnauthorizedException} 401 + * @throws {NotFoundException} 404 + */ + async getAccessToken( + options: GetAccessTokenOptions & { provider: string }, + ): Promise { + const { provider, ...payload } = options; + const { data } = await this.workos.post< + DataIntegrationAccessTokenResponseWire, + DataIntegrationsGetUserTokenRequestResponse + >( + `/data-integrations/${encodeURIComponent(provider)}/token`, + serializeDataIntegrationsGetUserTokenRequest(payload), + ); + return deserializeDataIntegrationAccessTokenResponse(data); + } + + /** + * Get a connected account + * + * Retrieves a user's [connected account](https://workos.com/docs/reference/pipes/connected-account) for a specific provider. + * @param options - Additional query options. + * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier. + * @example "user_01EHZNVPK3SFK441A1RGBFSHRT" + * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @example "github" + * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {UnauthorizedException} 401 + * @throws {NotFoundException} 404 + */ + async getUserConnectedAccount( + options: GetUserConnectedAccountOptions, + ): Promise { + const { userId, slug } = options; + const { data } = await this.workos.get( + `/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, + { + query: { + ...(options.organizationId !== undefined && { + organization_id: options.organizationId, + }), + }, + }, + ); + return deserializeConnectedAccount(data); + } + + /** + * Delete a connected account + * + * Disconnects WorkOS's account for the user, including removing any stored access and refresh tokens. The user will need to reauthorize if they want to reconnect. This does not revoke access on the provider side. + * @param options - Additional query options. + * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier. + * @example "user_01EHZNVPK3SFK441A1RGBFSHRT" + * @param options.slug - The slug identifier of the provider (e.g., `github`, `slack`, `notion`). + * @example "github" + * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter if the connection is scoped to an organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {UnauthorizedException} 401 + * @throws {NotFoundException} 404 + */ + async deleteUserConnectedAccount( + options: DeleteUserConnectedAccountOptions, + ): Promise { + const { userId, slug } = options; + await this.workos.delete( + `/user_management/users/${encodeURIComponent(userId)}/connected_accounts/${encodeURIComponent(slug)}`, + { + query: { + ...(options.organizationId !== undefined && { + organization_id: options.organizationId, + }), + }, + }, ); + } - return deserializeGetAccessTokenResponse(data); + /** + * List providers + * + * Retrieves a list of available providers and the user's connection status for each. Returns all providers configured for your environment, along with the user's [connected account](https://workos.com/docs/reference/pipes/connected-account) information where applicable. + * @param options - Additional query options. + * @param options.userId - A [User](https://workos.com/docs/reference/authkit/user) identifier to list providers and connected accounts for. + * @example "user_01EHZNVPK3SFK441A1RGBFSHRT" + * @param options.organizationId - An [Organization](https://workos.com/docs/reference/organization) identifier. Optional parameter to filter connections for a specific organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {UnauthorizedException} 401 + * @throws {NotFoundException} 404 + */ + async listUserDataProviders( + options: ListUserDataProvidersOptions, + ): Promise { + const { userId } = options; + const { data } = await this.workos.get( + `/user_management/users/${encodeURIComponent(userId)}/data_providers`, + { + query: { + ...(options.organizationId !== undefined && { + organization_id: options.organizationId, + }), + }, + }, + ); + return deserializeDataIntegrationsListResponse(data); } } diff --git a/src/pipes/serializers.spec.ts b/src/pipes/serializers.spec.ts new file mode 100644 index 000000000..02474bce3 --- /dev/null +++ b/src/pipes/serializers.spec.ts @@ -0,0 +1,105 @@ +// This file is auto-generated by oagen. Do not edit. + +import { deserializeDataIntegrationAuthorizeUrlResponse } from './serializers/data-integration-authorize-url-response.serializer'; +import { deserializeConnectedAccount } from './serializers/connected-account.serializer'; +import { deserializeDataIntegrationsListResponse } from './serializers/data-integrations-list-response.serializer'; +import { deserializeDataIntegrationsListResponseData } from './serializers/data-integrations-list-response-data.serializer'; +import { deserializeDataIntegrationAccessTokenResponseAccessToken } from './serializers/data-integration-access-token-response-access-token.serializer'; +import { serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest } from './serializers/data-integrations-get-data-integration-authorize-url-request.serializer'; +import { serializeDataIntegrationsGetUserTokenRequest } from './serializers/data-integrations-get-user-token-request.serializer'; +import { deserializeDataIntegrationsListResponseDataConnectedAccount } from './serializers/data-integrations-list-response-data-connected-account.serializer'; +import type { DataIntegrationAuthorizeUrlResponseWire } from './interfaces/data-integration-authorize-url-response.interface'; +import type { ConnectedAccountResponse } from './interfaces/connected-account.interface'; +import type { DataIntegrationsListResponseWire } from './interfaces/data-integrations-list-response.interface'; +import type { DataIntegrationsListResponseDataResponse } from './interfaces/data-integrations-list-response-data.interface'; +import type { DataIntegrationAccessTokenResponseAccessTokenResponse } from './interfaces/data-integration-access-token-response-access-token.interface'; +import type { DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse } from './interfaces/data-integrations-get-data-integration-authorize-url-request.interface'; +import type { DataIntegrationsGetUserTokenRequestResponse } from './interfaces/data-integrations-get-user-token-request.interface'; +import type { DataIntegrationsListResponseDataConnectedAccountResponse } from './interfaces/data-integrations-list-response-data-connected-account.interface'; +import dataIntegrationAuthorizeUrlResponseFixture from './fixtures/data-integration-authorize-url-response.json'; +import connectedAccountFixture from './fixtures/connected-account.json'; +import dataIntegrationsListResponseFixture from './fixtures/data-integrations-list-response.json'; +import dataIntegrationsListResponseDataFixture from './fixtures/data-integrations-list-response-data.json'; +import dataIntegrationAccessTokenResponseAccessTokenFixture from './fixtures/data-integration-access-token-response-access-token.json'; +import dataIntegrationsGetDataIntegrationAuthorizeUrlRequestFixture from './fixtures/data-integrations-get-data-integration-authorize-url-request.json'; +import dataIntegrationsGetUserTokenRequestFixture from './fixtures/data-integrations-get-user-token-request.json'; +import dataIntegrationsListResponseDataConnectedAccountFixture from './fixtures/data-integrations-list-response-data-connected-account.json'; + +describe('DataIntegrationAuthorizeUrlResponseSerializer', () => { + it('deserializes correctly', () => { + const fixture = + dataIntegrationAuthorizeUrlResponseFixture as DataIntegrationAuthorizeUrlResponseWire; + const deserialized = + deserializeDataIntegrationAuthorizeUrlResponse(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('ConnectedAccountSerializer', () => { + it('deserializes correctly', () => { + const fixture = connectedAccountFixture as ConnectedAccountResponse; + const deserialized = deserializeConnectedAccount(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('DataIntegrationsListResponseSerializer', () => { + it('deserializes correctly', () => { + const fixture = + dataIntegrationsListResponseFixture as DataIntegrationsListResponseWire; + const deserialized = deserializeDataIntegrationsListResponse(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('DataIntegrationsListResponseDataSerializer', () => { + it('deserializes correctly', () => { + const fixture = + dataIntegrationsListResponseDataFixture as DataIntegrationsListResponseDataResponse; + const deserialized = deserializeDataIntegrationsListResponseData(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('DataIntegrationAccessTokenResponseAccessTokenSerializer', () => { + it('deserializes correctly', () => { + const fixture = + dataIntegrationAccessTokenResponseAccessTokenFixture as DataIntegrationAccessTokenResponseAccessTokenResponse; + const deserialized = + deserializeDataIntegrationAccessTokenResponseAccessToken(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('DataIntegrationsGetDataIntegrationAuthorizeUrlRequestSerializer', () => { + it('serializes correctly', () => { + const fixture = + dataIntegrationsGetDataIntegrationAuthorizeUrlRequestFixture as DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse; + const serialized = + serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest( + fixture as any, + ); + expect(serialized).toBeDefined(); + }); +}); + +describe('DataIntegrationsGetUserTokenRequestSerializer', () => { + it('serializes correctly', () => { + const fixture = + dataIntegrationsGetUserTokenRequestFixture as DataIntegrationsGetUserTokenRequestResponse; + const serialized = serializeDataIntegrationsGetUserTokenRequest( + fixture as any, + ); + expect(serialized).toBeDefined(); + }); +}); + +describe('DataIntegrationsListResponseDataConnectedAccountSerializer', () => { + it('deserializes correctly', () => { + const fixture = + dataIntegrationsListResponseDataConnectedAccountFixture as DataIntegrationsListResponseDataConnectedAccountResponse; + const deserialized = + deserializeDataIntegrationsListResponseDataConnectedAccount(fixture); + expect(deserialized).toBeDefined(); + }); +}); diff --git a/src/pipes/serializers/access-token.serializer.ts b/src/pipes/serializers/access-token.serializer.ts deleted file mode 100644 index b76fdc2ad..000000000 --- a/src/pipes/serializers/access-token.serializer.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { - AccessToken, - SerializedAccessToken, -} from '../interfaces/access-token.interface'; - -export function deserializeAccessToken( - serialized: SerializedAccessToken, -): AccessToken { - return { - object: 'access_token', - accessToken: serialized.access_token, - expiresAt: serialized.expires_at - ? new Date(Date.parse(serialized.expires_at)) - : null, - scopes: serialized.scopes, - missingScopes: serialized.missing_scopes, - }; -} diff --git a/src/pipes/serializers/connected-account.serializer.ts b/src/pipes/serializers/connected-account.serializer.ts new file mode 100644 index 000000000..0844158d5 --- /dev/null +++ b/src/pipes/serializers/connected-account.serializer.ts @@ -0,0 +1,19 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + ConnectedAccount, + ConnectedAccountResponse, +} from '../interfaces/connected-account.interface'; + +export const deserializeConnectedAccount = ( + response: ConnectedAccountResponse, +): ConnectedAccount => ({ + object: response.object, + id: response.id, + userId: response.user_id ?? null, + organizationId: response.organization_id ?? null, + scopes: response.scopes, + state: response.state, + createdAt: response.created_at, + updatedAt: response.updated_at, +}); diff --git a/src/pipes/serializers/data-integration-access-token-response-access-token.serializer.ts b/src/pipes/serializers/data-integration-access-token-response-access-token.serializer.ts new file mode 100644 index 000000000..379baed66 --- /dev/null +++ b/src/pipes/serializers/data-integration-access-token-response-access-token.serializer.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationAccessTokenResponseAccessToken, + DataIntegrationAccessTokenResponseAccessTokenResponse, +} from '../interfaces/data-integration-access-token-response-access-token.interface'; + +export const deserializeDataIntegrationAccessTokenResponseAccessToken = ( + response: DataIntegrationAccessTokenResponseAccessTokenResponse, +): DataIntegrationAccessTokenResponseAccessToken => ({ + object: response.object, + accessToken: response.access_token, + expiresAt: response.expires_at != null ? new Date(response.expires_at) : null, + scopes: response.scopes, + missingScopes: response.missing_scopes, +}); diff --git a/src/pipes/serializers/data-integration-access-token-response.serializer.ts b/src/pipes/serializers/data-integration-access-token-response.serializer.ts new file mode 100644 index 000000000..853ffb33c --- /dev/null +++ b/src/pipes/serializers/data-integration-access-token-response.serializer.ts @@ -0,0 +1,30 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationAccessTokenResponse, + DataIntegrationAccessTokenResponseWire, +} from '../interfaces/data-integration-access-token-response.interface'; +import { deserializeDataIntegrationAccessTokenResponseAccessToken } from './data-integration-access-token-response-access-token.serializer'; + +export const deserializeDataIntegrationAccessTokenResponse = ( + response: DataIntegrationAccessTokenResponseWire, +): DataIntegrationAccessTokenResponse => { + switch (response.active) { + case true: + return { + active: true, + accessToken: deserializeDataIntegrationAccessTokenResponseAccessToken( + response.access_token, + ), + }; + case false: + return { + active: false, + error: response.error, + }; + default: + throw new Error( + `Unknown active: ${String((response as Record).active)}`, + ); + } +}; diff --git a/src/pipes/serializers/data-integration-authorize-url-response.serializer.ts b/src/pipes/serializers/data-integration-authorize-url-response.serializer.ts new file mode 100644 index 000000000..be4bda1e9 --- /dev/null +++ b/src/pipes/serializers/data-integration-authorize-url-response.serializer.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationAuthorizeUrlResponse, + DataIntegrationAuthorizeUrlResponseWire, +} from '../interfaces/data-integration-authorize-url-response.interface'; + +export const deserializeDataIntegrationAuthorizeUrlResponse = ( + response: DataIntegrationAuthorizeUrlResponseWire, +): DataIntegrationAuthorizeUrlResponse => ({ + url: response.url, +}); diff --git a/src/pipes/serializers/data-integrations-get-data-integration-authorize-url-request.serializer.ts b/src/pipes/serializers/data-integrations-get-data-integration-authorize-url-request.serializer.ts new file mode 100644 index 000000000..a3bb3f876 --- /dev/null +++ b/src/pipes/serializers/data-integrations-get-data-integration-authorize-url-request.serializer.ts @@ -0,0 +1,14 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsGetDataIntegrationAuthorizeUrlRequest, + DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse, +} from '../interfaces/data-integrations-get-data-integration-authorize-url-request.interface'; + +export const serializeDataIntegrationsGetDataIntegrationAuthorizeUrlRequest = ( + model: DataIntegrationsGetDataIntegrationAuthorizeUrlRequest, +): DataIntegrationsGetDataIntegrationAuthorizeUrlRequestResponse => ({ + user_id: model.userId, + organization_id: model.organizationId, + return_to: model.returnTo, +}); diff --git a/src/pipes/serializers/data-integrations-get-user-token-request.serializer.ts b/src/pipes/serializers/data-integrations-get-user-token-request.serializer.ts new file mode 100644 index 000000000..0a4208ee4 --- /dev/null +++ b/src/pipes/serializers/data-integrations-get-user-token-request.serializer.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsGetUserTokenRequest, + DataIntegrationsGetUserTokenRequestResponse, +} from '../interfaces/data-integrations-get-user-token-request.interface'; + +export const serializeDataIntegrationsGetUserTokenRequest = ( + model: DataIntegrationsGetUserTokenRequest, +): DataIntegrationsGetUserTokenRequestResponse => ({ + user_id: model.userId, + organization_id: model.organizationId, +}); diff --git a/src/pipes/serializers/data-integrations-list-response-data-connected-account.serializer.ts b/src/pipes/serializers/data-integrations-list-response-data-connected-account.serializer.ts new file mode 100644 index 000000000..ba6a6316d --- /dev/null +++ b/src/pipes/serializers/data-integrations-list-response-data-connected-account.serializer.ts @@ -0,0 +1,20 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsListResponseDataConnectedAccount, + DataIntegrationsListResponseDataConnectedAccountResponse, +} from '../interfaces/data-integrations-list-response-data-connected-account.interface'; + +export const deserializeDataIntegrationsListResponseDataConnectedAccount = ( + response: DataIntegrationsListResponseDataConnectedAccountResponse, +): DataIntegrationsListResponseDataConnectedAccount => ({ + object: response.object, + id: response.id, + userId: response.user_id ?? null, + organizationId: response.organization_id ?? null, + scopes: response.scopes, + state: response.state, + createdAt: response.created_at, + updatedAt: response.updated_at, + userlandUserId: response.userland_user_id ?? null, +}); diff --git a/src/pipes/serializers/data-integrations-list-response-data.serializer.ts b/src/pipes/serializers/data-integrations-list-response-data.serializer.ts new file mode 100644 index 000000000..10e30dacf --- /dev/null +++ b/src/pipes/serializers/data-integrations-list-response-data.serializer.ts @@ -0,0 +1,29 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsListResponseData, + DataIntegrationsListResponseDataResponse, +} from '../interfaces/data-integrations-list-response-data.interface'; +import { deserializeDataIntegrationsListResponseDataConnectedAccount } from './data-integrations-list-response-data-connected-account.serializer'; + +export const deserializeDataIntegrationsListResponseData = ( + response: DataIntegrationsListResponseDataResponse, +): DataIntegrationsListResponseData => ({ + object: response.object, + id: response.id, + name: response.name, + description: response.description ?? null, + slug: response.slug, + integrationType: response.integration_type, + credentialsType: response.credentials_type, + scopes: response.scopes ?? null, + ownership: response.ownership, + createdAt: response.created_at, + updatedAt: response.updated_at, + connectedAccount: + response.connected_account != null + ? deserializeDataIntegrationsListResponseDataConnectedAccount( + response.connected_account, + ) + : null, +}); diff --git a/src/pipes/serializers/data-integrations-list-response.serializer.ts b/src/pipes/serializers/data-integrations-list-response.serializer.ts new file mode 100644 index 000000000..d331b2784 --- /dev/null +++ b/src/pipes/serializers/data-integrations-list-response.serializer.ts @@ -0,0 +1,14 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + DataIntegrationsListResponse, + DataIntegrationsListResponseWire, +} from '../interfaces/data-integrations-list-response.interface'; +import { deserializeDataIntegrationsListResponseData } from './data-integrations-list-response-data.serializer'; + +export const deserializeDataIntegrationsListResponse = ( + response: DataIntegrationsListResponseWire, +): DataIntegrationsListResponse => ({ + object: response.object, + data: response.data.map(deserializeDataIntegrationsListResponseData), +}); diff --git a/src/pipes/serializers/get-access-token.serializer.ts b/src/pipes/serializers/get-access-token.serializer.ts deleted file mode 100644 index 44aecec24..000000000 --- a/src/pipes/serializers/get-access-token.serializer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - GetAccessTokenOptions, - GetAccessTokenResponse, - SerializedGetAccessTokenOptions, - SerializedGetAccessTokenResponse, -} from '../interfaces/get-access-token.interface'; -import { deserializeAccessToken } from './access-token.serializer'; - -export function serializeGetAccessTokenOptions( - options: GetAccessTokenOptions, -): SerializedGetAccessTokenOptions { - return { - user_id: options.userId, - organization_id: options.organizationId, - }; -} - -export function deserializeGetAccessTokenResponse( - response: SerializedGetAccessTokenResponse, -): GetAccessTokenResponse { - if (response.active) { - return { - active: true, - accessToken: deserializeAccessToken(response.access_token), - }; - } - - return { - active: false, - error: response.error, - }; -} diff --git a/src/pipes/serializers/index.ts b/src/pipes/serializers/index.ts new file mode 100644 index 000000000..40baf6493 --- /dev/null +++ b/src/pipes/serializers/index.ts @@ -0,0 +1,11 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './connected-account.serializer'; +export * from './data-integration-access-token-response.serializer'; +export * from './data-integration-access-token-response-access-token.serializer'; +export * from './data-integration-authorize-url-response.serializer'; +export * from './data-integrations-get-data-integration-authorize-url-request.serializer'; +export * from './data-integrations-get-user-token-request.serializer'; +export * from './data-integrations-list-response.serializer'; +export * from './data-integrations-list-response-data.serializer'; +export * from './data-integrations-list-response-data-connected-account.serializer';