diff --git a/.oagen-manifest.json b/.oagen-manifest.json index ba29803e3..f512e8f4c 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -82,6 +82,44 @@ "src/groups/serializers/index.ts", "src/groups/serializers/update-group.serializer.ts", "src/groups/serializers/user-organization-membership-base-list-data.serializer.ts", + "src/organizations/fixtures/audit-log-configuration-log-stream.json", + "src/organizations/fixtures/audit-log-configuration.json", + "src/organizations/fixtures/audit-logs-retention.json", + "src/organizations/fixtures/list-organization.json", + "src/organizations/fixtures/organization-domain-data.json", + "src/organizations/fixtures/organization-input.json", + "src/organizations/fixtures/organization.json", + "src/organizations/fixtures/update-audit-logs-retention.json", + "src/organizations/fixtures/update-organization.json", + "src/organizations/interfaces/audit-log-configuration-log-stream-state.interface.ts", + "src/organizations/interfaces/audit-log-configuration-log-stream-type.interface.ts", + "src/organizations/interfaces/audit-log-configuration-log-stream.interface.ts", + "src/organizations/interfaces/audit-log-configuration-state.interface.ts", + "src/organizations/interfaces/audit-log-configuration.interface.ts", + "src/organizations/interfaces/audit-logs-retention.interface.ts", + "src/organizations/interfaces/delete-organization-options.interface.ts", + "src/organizations/interfaces/get-audit-log-configuration-options.interface.ts", + "src/organizations/interfaces/get-organization-by-external-id-options.interface.ts", + "src/organizations/interfaces/get-organization-options.interface.ts", + "src/organizations/interfaces/index.ts", + "src/organizations/interfaces/organization-domain-data-state.interface.ts", + "src/organizations/interfaces/organization-domain-data.interface.ts", + "src/organizations/interfaces/organization-input.interface.ts", + "src/organizations/interfaces/organization.interface.ts", + "src/organizations/interfaces/update-audit-logs-retention.interface.ts", + "src/organizations/interfaces/update-organization.interface.ts", + "src/organizations/organizations.spec.ts", + "src/organizations/organizations.ts", + "src/organizations/serializers.spec.ts", + "src/organizations/serializers/audit-log-configuration-log-stream.serializer.ts", + "src/organizations/serializers/audit-log-configuration.serializer.ts", + "src/organizations/serializers/audit-logs-retention.serializer.ts", + "src/organizations/serializers/index.ts", + "src/organizations/serializers/organization-domain-data.serializer.ts", + "src/organizations/serializers/organization-input.serializer.ts", + "src/organizations/serializers/organization.serializer.ts", + "src/organizations/serializers/update-audit-logs-retention.serializer.ts", + "src/organizations/serializers/update-organization.serializer.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/actions/actions.spec.ts b/src/actions/actions.spec.ts index 25af43269..ff3658da7 100644 --- a/src/actions/actions.spec.ts +++ b/src/actions/actions.spec.ts @@ -142,8 +142,8 @@ describe('Actions', () => { name: 'Foo Corp', allowProfilesOutsideOrganization: false, domains: [], - createdAt: '2024-10-22T17:12:50.746Z', - updatedAt: '2024-10-22T17:12:50.746Z', + createdAt: new Date('2024-10-22T17:12:50.746Z'), + updatedAt: new Date('2024-10-22T17:12:50.746Z'), externalId: null, metadata: {}, }, diff --git a/src/organizations/fixtures/audit-log-configuration-log-stream.json b/src/organizations/fixtures/audit-log-configuration-log-stream.json new file mode 100644 index 000000000..c108bda98 --- /dev/null +++ b/src/organizations/fixtures/audit-log-configuration-log-stream.json @@ -0,0 +1,7 @@ +{ + "id": "als_01EHZNVPK3SFK441A1RGBFSHRT", + "type": "Datadog", + "state": "active", + "last_synced_at": "2026-01-15T12:00:00.000Z", + "created_at": "2026-01-15T12:00:00.000Z" +} diff --git a/src/organizations/fixtures/audit-log-configuration.json b/src/organizations/fixtures/audit-log-configuration.json new file mode 100644 index 000000000..fd33f4567 --- /dev/null +++ b/src/organizations/fixtures/audit-log-configuration.json @@ -0,0 +1,12 @@ +{ + "organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT", + "retention_period_in_days": 30, + "state": "active", + "log_stream": { + "id": "als_01EHZNVPK3SFK441A1RGBFSHRT", + "type": "Datadog", + "state": "active", + "last_synced_at": "2026-01-15T12:00:00.000Z", + "created_at": "2026-01-15T12:00:00.000Z" + } +} diff --git a/src/organizations/fixtures/audit-logs-retention.json b/src/organizations/fixtures/audit-logs-retention.json new file mode 100644 index 000000000..0720427e5 --- /dev/null +++ b/src/organizations/fixtures/audit-logs-retention.json @@ -0,0 +1,3 @@ +{ + "retention_period_in_days": 30 +} diff --git a/src/organizations/fixtures/list-organization.json b/src/organizations/fixtures/list-organization.json new file mode 100644 index 000000000..60eb366aa --- /dev/null +++ b/src/organizations/fixtures/list-organization.json @@ -0,0 +1,35 @@ +{ + "data": [ + { + "object": "organization", + "id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "name": "Acme Inc.", + "domains": [ + { + "object": "organization_domain", + "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", + "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", + "domain": "foo-corp.com", + "state": "pending", + "verification_prefix": "superapp-domain-verification-z3kjny", + "verification_token": "m5Oztg3jdK4NJLgs8uIlIprMw", + "verification_strategy": "dns", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "metadata": { + "tier": "diamond" + }, + "external_id": "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191", + "stripe_customer_id": "cus_R9qWAGMQ6nGE7V", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + "allow_profiles_outside_organization": false + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/src/organizations/fixtures/organization-domain-data.json b/src/organizations/fixtures/organization-domain-data.json new file mode 100644 index 000000000..f0032cb01 --- /dev/null +++ b/src/organizations/fixtures/organization-domain-data.json @@ -0,0 +1,4 @@ +{ + "domain": "foo-corp.com", + "state": "verified" +} diff --git a/src/organizations/fixtures/organization-input.json b/src/organizations/fixtures/organization-input.json new file mode 100644 index 000000000..47adf0b2b --- /dev/null +++ b/src/organizations/fixtures/organization-input.json @@ -0,0 +1,15 @@ +{ + "name": "Foo Corp", + "allow_profiles_outside_organization": false, + "domains": ["example.com"], + "domain_data": [ + { + "domain": "foo-corp.com", + "state": "verified" + } + ], + "metadata": { + "tier": "diamond" + }, + "external_id": "ext_12345" +} diff --git a/src/organizations/fixtures/organization.json b/src/organizations/fixtures/organization.json new file mode 100644 index 000000000..39eaa6fb0 --- /dev/null +++ b/src/organizations/fixtures/organization.json @@ -0,0 +1,27 @@ +{ + "object": "organization", + "id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "name": "Acme Inc.", + "domains": [ + { + "object": "organization_domain", + "id": "org_domain_01EHZNVPK2QXHMVWCEDQEKY69A", + "organization_id": "org_01HE8GSH8FQPASKSY27THRKRBP", + "domain": "foo-corp.com", + "state": "pending", + "verification_prefix": "superapp-domain-verification-z3kjny", + "verification_token": "m5Oztg3jdK4NJLgs8uIlIprMw", + "verification_strategy": "dns", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "metadata": { + "tier": "diamond" + }, + "external_id": "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191", + "stripe_customer_id": "cus_R9qWAGMQ6nGE7V", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z", + "allow_profiles_outside_organization": false +} diff --git a/src/organizations/fixtures/update-audit-logs-retention.json b/src/organizations/fixtures/update-audit-logs-retention.json new file mode 100644 index 000000000..0720427e5 --- /dev/null +++ b/src/organizations/fixtures/update-audit-logs-retention.json @@ -0,0 +1,3 @@ +{ + "retention_period_in_days": 30 +} diff --git a/src/organizations/fixtures/update-organization.json b/src/organizations/fixtures/update-organization.json index 505947b87..322ad7ca4 100644 --- a/src/organizations/fixtures/update-organization.json +++ b/src/organizations/fixtures/update-organization.json @@ -1,13 +1,16 @@ { - "name": "Test Organization 2", - "object": "organization", - "id": "org_01EHT88Z8J8795GZNQ4ZP1J81T", + "name": "Foo Corp", "allow_profiles_outside_organization": false, - "domains": [ + "domains": ["foo-corp.com"], + "domain_data": [ { - "domain": "example.com", - "object": "organization_domain", - "id": "org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8" + "domain": "foo-corp.com", + "state": "verified" } - ] + ], + "stripe_customer_id": "cus_R9qWAGMQ6nGE7V", + "metadata": { + "tier": "diamond" + }, + "external_id": "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191" } diff --git a/src/organizations/interfaces/audit-log-configuration-log-stream-state.interface.ts b/src/organizations/interfaces/audit-log-configuration-log-stream-state.interface.ts new file mode 100644 index 000000000..2a0c15d5a --- /dev/null +++ b/src/organizations/interfaces/audit-log-configuration-log-stream-state.interface.ts @@ -0,0 +1,11 @@ +// This file is auto-generated by oagen. Do not edit. + +export const AuditLogConfigurationLogStreamState = { + Active: 'active', + Inactive: 'inactive', + Error: 'error', + Invalid: 'invalid', +} as const; + +export type AuditLogConfigurationLogStreamState = + (typeof AuditLogConfigurationLogStreamState)[keyof typeof AuditLogConfigurationLogStreamState]; diff --git a/src/organizations/interfaces/audit-log-configuration-log-stream-type.interface.ts b/src/organizations/interfaces/audit-log-configuration-log-stream-type.interface.ts new file mode 100644 index 000000000..dea42debc --- /dev/null +++ b/src/organizations/interfaces/audit-log-configuration-log-stream-type.interface.ts @@ -0,0 +1,14 @@ +// This file is auto-generated by oagen. Do not edit. + +export const AuditLogConfigurationLogStreamType = { + AzureSentinel: 'AzureSentinel', + Datadog: 'Datadog', + GenericHttps: 'GenericHttps', + GoogleCloudStorage: 'GoogleCloudStorage', + S3: 'S3', + Snowflake: 'Snowflake', + Splunk: 'Splunk', +} as const; + +export type AuditLogConfigurationLogStreamType = + (typeof AuditLogConfigurationLogStreamType)[keyof typeof AuditLogConfigurationLogStreamType]; diff --git a/src/organizations/interfaces/audit-log-configuration-log-stream.interface.ts b/src/organizations/interfaces/audit-log-configuration-log-stream.interface.ts new file mode 100644 index 000000000..009ac226d --- /dev/null +++ b/src/organizations/interfaces/audit-log-configuration-log-stream.interface.ts @@ -0,0 +1,26 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { AuditLogConfigurationLogStreamType } from './audit-log-configuration-log-stream-type.interface'; +import type { AuditLogConfigurationLogStreamState } from './audit-log-configuration-log-stream-state.interface'; + +/** The Audit Log Stream currently configured for the organization, if any. */ +export interface AuditLogConfigurationLogStream { + /** Unique identifier of the Audit Log Stream. */ + id: string; + /** The type of the Audit Log Stream destination. */ + type: AuditLogConfigurationLogStreamType; + /** The current state of the Audit Log Stream. */ + state: AuditLogConfigurationLogStreamState; + /** ISO-8601 timestamp of when the last event was successfully synced, or null if no events have been synced. */ + lastSyncedAt: string | null; + /** An ISO 8601 timestamp. */ + createdAt: Date; +} + +export interface AuditLogConfigurationLogStreamResponse { + id: string; + type: AuditLogConfigurationLogStreamType; + state: AuditLogConfigurationLogStreamState; + last_synced_at: string | null; + created_at: string; +} diff --git a/src/organizations/interfaces/audit-log-configuration-state.interface.ts b/src/organizations/interfaces/audit-log-configuration-state.interface.ts new file mode 100644 index 000000000..ca0204e93 --- /dev/null +++ b/src/organizations/interfaces/audit-log-configuration-state.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export const AuditLogConfigurationState = { + Active: 'active', + Inactive: 'inactive', + Disabled: 'disabled', +} as const; + +export type AuditLogConfigurationState = + (typeof AuditLogConfigurationState)[keyof typeof AuditLogConfigurationState]; diff --git a/src/organizations/interfaces/audit-log-configuration.interface.ts b/src/organizations/interfaces/audit-log-configuration.interface.ts new file mode 100644 index 000000000..05d61da50 --- /dev/null +++ b/src/organizations/interfaces/audit-log-configuration.interface.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + AuditLogConfigurationLogStream, + AuditLogConfigurationLogStreamResponse, +} from './audit-log-configuration-log-stream.interface'; +import type { AuditLogConfigurationState } from './audit-log-configuration-state.interface'; + +export interface AuditLogConfiguration { + /** Unique identifier of the Organization. */ + organizationId: string; + /** The number of days Audit Log events will be retained before being permanently deleted. */ + retentionPeriodInDays: number; + /** The current state of the audit log configuration for the organization. */ + state: AuditLogConfigurationState; + /** The Audit Log Stream currently configured for the organization, if any. */ + logStream?: AuditLogConfigurationLogStream; +} + +export interface AuditLogConfigurationResponse { + organization_id: string; + retention_period_in_days: number; + state: AuditLogConfigurationState; + log_stream?: AuditLogConfigurationLogStreamResponse; +} diff --git a/src/organizations/interfaces/audit-logs-retention.interface.ts b/src/organizations/interfaces/audit-logs-retention.interface.ts new file mode 100644 index 000000000..26cba3ea5 --- /dev/null +++ b/src/organizations/interfaces/audit-logs-retention.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface AuditLogsRetention { + /** The number of days Audit Log events will be retained before being permanently deleted. Valid values are 30 and 365. */ + retentionPeriodInDays: number | null; +} + +export interface AuditLogsRetentionResponse { + retention_period_in_days: number | null; +} diff --git a/src/organizations/interfaces/create-organization-options.interface.ts b/src/organizations/interfaces/create-organization-options.interface.ts index 1f32b6821..16fd8c9b2 100644 --- a/src/organizations/interfaces/create-organization-options.interface.ts +++ b/src/organizations/interfaces/create-organization-options.interface.ts @@ -1,21 +1,19 @@ -import { PostOptions } from '../../common/interfaces'; -import { DomainData } from './domain-data.interface'; +import { OrganizationDomainData } from './organization-domain-data.interface'; +// CreateOrganizationOptions mirrors the generated OrganizationInput request body +// so it can be passed straight to serializeOrganizationInput. Kept hand-owned +// because oagen only generates path-param option interfaces. export interface CreateOrganizationOptions { + /** The name of the organization. */ name: string; - domainData?: DomainData[]; + /** Whether the organization allows profiles from outside the organization to sign in. */ + allowProfilesOutsideOrganization?: boolean; + /** The domains associated with the organization. Deprecated in favor of `domain_data`. */ + domains?: string[]; + /** The domains associated with the organization, including verification state. */ + domainData?: OrganizationDomainData[]; + /** Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. */ + metadata?: Record | null; + /** An external identifier for the Organization. */ externalId?: string | null; - metadata?: Record; } - -export interface SerializedCreateOrganizationOptions { - name: string; - domain_data?: DomainData[]; - external_id?: string | null; - metadata?: Record; -} - -export type CreateOrganizationRequestOptions = Pick< - PostOptions, - 'idempotencyKey' ->; diff --git a/src/organizations/interfaces/delete-organization-options.interface.ts b/src/organizations/interfaces/delete-organization-options.interface.ts new file mode 100644 index 000000000..fcbca7e42 --- /dev/null +++ b/src/organizations/interfaces/delete-organization-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DeleteOrganizationOptions { + /** Unique identifier of the Organization. */ + id: string; +} diff --git a/src/organizations/interfaces/get-audit-log-configuration-options.interface.ts b/src/organizations/interfaces/get-audit-log-configuration-options.interface.ts new file mode 100644 index 000000000..bde869c05 --- /dev/null +++ b/src/organizations/interfaces/get-audit-log-configuration-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetAuditLogConfigurationOptions { + /** Unique identifier of the Organization. */ + id: string; +} diff --git a/src/organizations/interfaces/get-organization-by-external-id-options.interface.ts b/src/organizations/interfaces/get-organization-by-external-id-options.interface.ts new file mode 100644 index 000000000..a7b2aa3e3 --- /dev/null +++ b/src/organizations/interfaces/get-organization-by-external-id-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetOrganizationByExternalIdOptions { + /** The external ID of the Organization. */ + externalId: string; +} diff --git a/src/organizations/interfaces/get-organization-options.interface.ts b/src/organizations/interfaces/get-organization-options.interface.ts new file mode 100644 index 000000000..98bd4a0aa --- /dev/null +++ b/src/organizations/interfaces/get-organization-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetOrganizationOptions { + /** Unique identifier of the Organization. */ + id: string; +} diff --git a/src/organizations/interfaces/index.ts b/src/organizations/interfaces/index.ts index d44e49367..365f70e7b 100644 --- a/src/organizations/interfaces/index.ts +++ b/src/organizations/interfaces/index.ts @@ -1,6 +1,23 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './audit-log-configuration-log-stream-state.interface'; +export * from './audit-log-configuration-log-stream-type.interface'; +export * from './audit-log-configuration-log-stream.interface'; +export * from './audit-log-configuration-state.interface'; +export * from './audit-log-configuration.interface'; +export * from './audit-logs-retention.interface'; export * from './create-organization-options.interface'; +export * from './delete-organization-options.interface'; export * from './domain-data.interface'; +export * from './get-audit-log-configuration-options.interface'; +export * from './get-organization-by-external-id-options.interface'; +export * from './get-organization-options.interface'; export * from './list-organization-feature-flags-options.interface'; export * from './list-organizations-options.interface'; +export * from './organization-domain-data-state.interface'; +export * from './organization-domain-data.interface'; +export * from './organization-input.interface'; export * from './organization.interface'; +export * from './update-audit-logs-retention.interface'; export * from './update-organization-options.interface'; +export * from './update-organization.interface'; diff --git a/src/organizations/interfaces/list-organizations-options.interface.ts b/src/organizations/interfaces/list-organizations-options.interface.ts index d5dfded3d..4c8fd56e0 100644 --- a/src/organizations/interfaces/list-organizations-options.interface.ts +++ b/src/organizations/interfaces/list-organizations-options.interface.ts @@ -3,4 +3,6 @@ import { PaginationOptions } from '../../common/interfaces/pagination-options.in export interface ListOrganizationsOptions extends PaginationOptions { /** The domains of an Organization. Any Organization with a matching domain will be returned. */ domains?: string[]; + /** Searchable text for an Organization. Matches against the Organization name and domains. */ + search?: string; } diff --git a/src/organizations/interfaces/organization-domain-data-state.interface.ts b/src/organizations/interfaces/organization-domain-data-state.interface.ts new file mode 100644 index 000000000..47f27b6e9 --- /dev/null +++ b/src/organizations/interfaces/organization-domain-data-state.interface.ts @@ -0,0 +1,9 @@ +// This file is auto-generated by oagen. Do not edit. + +export const OrganizationDomainDataState = { + Pending: 'pending', + Verified: 'verified', +} as const; + +export type OrganizationDomainDataState = + (typeof OrganizationDomainDataState)[keyof typeof OrganizationDomainDataState]; diff --git a/src/organizations/interfaces/organization-domain-data.interface.ts b/src/organizations/interfaces/organization-domain-data.interface.ts new file mode 100644 index 000000000..cbfd04c55 --- /dev/null +++ b/src/organizations/interfaces/organization-domain-data.interface.ts @@ -0,0 +1,15 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { OrganizationDomainDataState } from './organization-domain-data-state.interface'; + +export interface OrganizationDomainData { + /** The domain value. */ + domain: string; + /** The verification state of the domain. */ + state: OrganizationDomainDataState; +} + +export interface OrganizationDomainDataResponse { + domain: string; + state: OrganizationDomainDataState; +} diff --git a/src/organizations/interfaces/organization-input.interface.ts b/src/organizations/interfaces/organization-input.interface.ts new file mode 100644 index 000000000..0e8d290c9 --- /dev/null +++ b/src/organizations/interfaces/organization-input.interface.ts @@ -0,0 +1,30 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + OrganizationDomainData, + OrganizationDomainDataResponse, +} from './organization-domain-data.interface'; + +export interface OrganizationInput { + /** The name of the organization. */ + name: string; + /** Whether the organization allows profiles from outside the organization to sign in. */ + allowProfilesOutsideOrganization?: boolean; + /** The domains associated with the organization. Deprecated in favor of `domain_data`. */ + domains?: string[]; + /** The domains associated with the organization, including verification state. */ + domainData?: OrganizationDomainData[]; + /** Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. */ + metadata?: Record | null; + /** An external identifier for the Organization. */ + externalId?: string | null; +} + +export interface OrganizationInputResponse { + name: string; + allow_profiles_outside_organization?: boolean; + domains?: string[]; + domain_data?: OrganizationDomainDataResponse[]; + metadata?: Record | null; + external_id?: string | null; +} diff --git a/src/organizations/interfaces/organization.interface.ts b/src/organizations/interfaces/organization.interface.ts index 53b32b793..f5281b46f 100644 --- a/src/organizations/interfaces/organization.interface.ts +++ b/src/organizations/interfaces/organization.interface.ts @@ -1,4 +1,6 @@ -import { +// This file is auto-generated by oagen. Do not edit. + +import type { OrganizationDomain, OrganizationDomainResponse, } from '../../organization-domains/interfaces/organization-domain.interface'; @@ -10,34 +12,34 @@ export interface Organization { id: string; /** A descriptive name for the Organization. This field does not need to be unique. */ name: string; - /** - * Whether the Organization allows profiles outside of its managed domains. - * @deprecated - */ - allowProfilesOutsideOrganization: boolean; /** List of Organization Domains. */ domains: OrganizationDomain[]; + /** Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. */ + metadata?: Record; + /** The external ID of the Organization. */ + externalId?: string | null; /** The Stripe customer ID of the Organization. */ stripeCustomerId?: string; /** An ISO 8601 timestamp. */ - createdAt: string; + createdAt: Date; /** An ISO 8601 timestamp. */ - updatedAt: string; - /** The external ID of the Organization. */ - externalId: string | null; - /** Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. */ - metadata: Record; + updatedAt: Date; + /** + * Whether the Organization allows profiles outside of its managed domains. + * @deprecated + */ + allowProfilesOutsideOrganization?: boolean; } export interface OrganizationResponse { object: 'organization'; id: string; name: string; - allow_profiles_outside_organization: boolean; domains: OrganizationDomainResponse[]; + metadata?: Record; + external_id?: string | null; stripe_customer_id?: string; created_at: string; updated_at: string; - external_id?: string | null; - metadata?: Record; + allow_profiles_outside_organization?: boolean; } diff --git a/src/organizations/interfaces/update-audit-logs-retention.interface.ts b/src/organizations/interfaces/update-audit-logs-retention.interface.ts new file mode 100644 index 000000000..861ca0636 --- /dev/null +++ b/src/organizations/interfaces/update-audit-logs-retention.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface UpdateAuditLogsRetention { + /** The number of days Audit Log events will be retained. Valid values are `30` and `365`. */ + retentionPeriodInDays: number; +} + +export interface UpdateAuditLogsRetentionResponse { + retention_period_in_days: number; +} diff --git a/src/organizations/interfaces/update-organization-options.interface.ts b/src/organizations/interfaces/update-organization-options.interface.ts index 0f21a4749..e4ed7bc3e 100644 --- a/src/organizations/interfaces/update-organization-options.interface.ts +++ b/src/organizations/interfaces/update-organization-options.interface.ts @@ -1,18 +1,8 @@ -import { DomainData } from './domain-data.interface'; +import { UpdateOrganization } from './update-organization.interface'; -export interface UpdateOrganizationOptions { - organization: string; - name?: string; - domainData?: DomainData[]; - stripeCustomerId?: string | null; - externalId?: string | null; - metadata?: Record; -} - -export interface SerializedUpdateOrganizationOptions { - name?: string; - domain_data?: DomainData[]; - stripe_customer_id?: string | null; - external_id?: string | null; - metadata?: Record; +// UpdateOrganizationOptions is the update request body plus the path id. After +// the resource strips `id`, the remainder is passed to serializeUpdateOrganization. +export interface UpdateOrganizationOptions extends UpdateOrganization { + /** Unique identifier of the Organization. */ + id: string; } diff --git a/src/organizations/interfaces/update-organization.interface.ts b/src/organizations/interfaces/update-organization.interface.ts new file mode 100644 index 000000000..566a23293 --- /dev/null +++ b/src/organizations/interfaces/update-organization.interface.ts @@ -0,0 +1,36 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + OrganizationDomainData, + OrganizationDomainDataResponse, +} from './organization-domain-data.interface'; + +export interface UpdateOrganization { + /** The name of the organization. */ + name?: string; + /** Whether the organization allows profiles from outside the organization to sign in. */ + allowProfilesOutsideOrganization?: boolean; + /** + * The domains associated with the organization. Deprecated in favor of `domain_data`. + * @deprecated + */ + domains?: string[]; + /** The domains associated with the organization, including verification state. */ + domainData?: OrganizationDomainData[]; + /** The Stripe customer ID associated with the organization. */ + stripeCustomerId?: string; + /** Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. */ + metadata?: Record | null; + /** An external identifier for the Organization. */ + externalId?: string | null; +} + +export interface UpdateOrganizationResponse { + name?: string; + allow_profiles_outside_organization?: boolean; + domains?: string[]; + domain_data?: OrganizationDomainDataResponse[]; + stripe_customer_id?: string; + metadata?: Record | null; + external_id?: string | null; +} diff --git a/src/organizations/organizations.spec.ts b/src/organizations/organizations.spec.ts index 1014611ae..43682decb 100644 --- a/src/organizations/organizations.spec.ts +++ b/src/organizations/organizations.spec.ts @@ -1,366 +1,154 @@ +// This file is auto-generated by oagen. Do not edit. + import fetch from 'jest-fetch-mock'; import { fetchOnce, fetchURL, + fetchMethod, fetchSearchParams, - fetchHeaders, fetchBody, } from '../common/utils/test-utils'; import { WorkOS } from '../workos'; -import clearStripeCustomerId from './fixtures/clear-stripe-customer-id.json'; -import createOrganizationInvalid from './fixtures/create-organization-invalid.json'; -import createOrganization from './fixtures/create-organization.json'; -import getOrganization from './fixtures/get-organization.json'; -import listOrganizationsFixture from './fixtures/list-organizations.json'; -import updateOrganization from './fixtures/update-organization.json'; -import setStripeCustomerId from './fixtures/set-stripe-customer-id.json'; -import setStripeCustomerIdDisabled from './fixtures/set-stripe-customer-id-disabled.json'; -import { DomainDataState } from './interfaces'; + +import listOrganizationFixture from './fixtures/list-organization.json'; +import organizationFixture from './fixtures/organization.json'; +import auditLogConfigurationFixture from './fixtures/audit-log-configuration.json'; const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); +function expectOrganization(result: any) { + expect(result.object).toBe('organization'); + expect(result.id).toBe('org_01EHWNCE74X7JSDV0X3SZ3KJNY'); + expect(result.name).toBe('Acme Inc.'); + expect(result.metadata).toEqual({ tier: 'diamond' }); + expect(result.externalId).toBe('2fe01467-f7ea-4dd2-8b79-c2b4f56d0191'); + expect(result.createdAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); + expect(result.updatedAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); +} + describe('Organizations', () => { beforeEach(() => fetch.resetMocks()); describe('listOrganizations', () => { - describe('without any options', () => { - it('returns organizations and metadata', async () => { - fetchOnce(listOrganizationsFixture); - - const { data, listMetadata } = - await workos.organizations.listOrganizations(); + it('returns paginated results', async () => { + fetchOnce(listOrganizationFixture); - expect(fetchSearchParams()).toEqual({ + const { data, listMetadata } = + await workos.organizations.listOrganizations({ order: 'desc', + domains: ['foo-corp.com'], + search: 'Acme Corp', }); - expect(fetchURL()).toContain('/organizations'); - - expect(data).toHaveLength(7); - - expect(listMetadata).toEqual({ - after: null, - before: 'before-id', - }); - }); - }); - describe('with the domain option', () => { - it('forms the proper request to the API', async () => { - fetchOnce(listOrganizationsFixture); - - const { data } = await workos.organizations.listOrganizations({ - domains: ['example.com', 'example2.com'], - }); - - expect(fetchSearchParams()).toEqual({ - domains: 'example.com,example2.com', - order: 'desc', - }); - - expect(fetchURL()).toContain('/organizations'); - - expect(data).toHaveLength(7); - }); - }); - - describe('with the before option', () => { - it('forms the proper request to the API', async () => { - fetchOnce(listOrganizationsFixture); - - const { data } = await workos.organizations.listOrganizations({ - before: 'before-id', - }); - - expect(fetchSearchParams()).toEqual({ - before: 'before-id', - order: 'desc', - }); - - expect(fetchURL()).toContain('/organizations'); - - expect(data).toHaveLength(7); - }); - }); - - describe('with the after option', () => { - it('forms the proper request to the API', async () => { - fetchOnce(listOrganizationsFixture); - - const { data } = await workos.organizations.listOrganizations({ - after: 'after-id', - }); - - expect(fetchSearchParams()).toEqual({ - after: 'after-id', - order: 'desc', - }); - - expect(fetchURL()).toContain('/organizations'); - - expect(data).toHaveLength(7); - }); - }); - - describe('with the limit option', () => { - it('forms the proper request to the API', async () => { - fetchOnce(listOrganizationsFixture); - - const { data } = await workos.organizations.listOrganizations({ - limit: 10, - }); - - expect(fetchSearchParams()).toEqual({ - limit: '10', - order: 'desc', - }); - - expect(fetchURL()).toContain('/organizations'); - - expect(data).toHaveLength(7); - }); + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe('/organizations'); + expect(fetchSearchParams()).toHaveProperty('order'); + expect(Array.isArray(data)).toBe(true); + expect(listMetadata).toBeDefined(); + expect(data.length).toBeGreaterThan(0); + expectOrganization(data[0]); }); }); describe('createOrganization', () => { - describe('with an idempotency key', () => { - it('includes an idempotency key with request', async () => { - fetchOnce(createOrganization, { status: 201 }); + it('sends the correct request and returns result', async () => { + fetchOnce(organizationFixture); - await workos.organizations.createOrganization( - { - domainData: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - name: 'Test Organization', - }, - { - idempotencyKey: 'the-idempotency-key', - }, - ); - - expect(fetchHeaders()).toMatchObject({ - 'Idempotency-Key': 'the-idempotency-key', - }); - expect(fetchBody()).toEqual({ - domain_data: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - name: 'Test Organization', - }); + const result = await workos.organizations.createOrganization({ + name: 'Test', }); - }); - - describe('with a valid payload', () => { - describe('with `domain_data`', () => { - it('creates an organization', async () => { - fetchOnce(createOrganization, { status: 201 }); - - const subject = await workos.organizations.createOrganization({ - domainData: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - name: 'Test Organization', - }); - expect(fetchBody()).toEqual({ - domain_data: [{ domain: 'example.com', state: 'verified' }], - name: 'Test Organization', - }); - expect(subject.id).toEqual('org_01EHT88Z8J8795GZNQ4ZP1J81T'); - expect(subject.name).toEqual('Test Organization'); - expect(subject.domains).toHaveLength(1); - }); - }); - - it('adds metadata to the request', async () => { - fetchOnce(createOrganization, { status: 201 }); - - await workos.organizations.createOrganization({ - name: 'My organization', - metadata: { key: 'value' }, - }); - - expect(fetchBody()).toMatchObject({ - metadata: { key: 'value' }, - }); - }); + expect(fetchMethod()).toBe('POST'); + expect(new URL(String(fetchURL())).pathname).toBe('/organizations'); + expect(fetchBody()).toEqual(expect.objectContaining({ name: 'Test' })); + expectOrganization(result); }); + }); - describe('with an invalid payload', () => { - it('returns an error', async () => { - fetchOnce(createOrganizationInvalid, { - status: 409, - headers: { 'X-Request-ID': 'a-request-id' }, - }); + describe('getOrganizationByExternalId', () => { + it('returns the expected result', async () => { + fetchOnce(organizationFixture); - await expect( - workos.organizations.createOrganization({ - domainData: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - name: 'Test Organization', - }), - ).rejects.toThrow( - 'An Organization with the domain example.com already exists.', - ); - expect(fetchBody()).toEqual({ - domain_data: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - name: 'Test Organization', - }); + const result = await workos.organizations.getOrganizationByExternalId({ + externalId: 'test_externalId', }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/organizations/external_id/test_externalId', + ); + expectOrganization(result); }); }); describe('getOrganization', () => { - it(`requests an Organization`, async () => { - fetchOnce(getOrganization); - const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); + it('returns the expected result', async () => { + fetchOnce(organizationFixture); - const subject = await workos.organizations.getOrganization( - 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - ); + const result = await workos.organizations.getOrganization({ + id: 'test_id', + }); - expect(fetchURL()).toContain( - '/organizations/org_01EHT88Z8J8795GZNQ4ZP1J81T', + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/organizations/test_id', ); - expect(subject.id).toEqual('org_01EHT88Z8J8795GZNQ4ZP1J81T'); - expect(subject.name).toEqual('Test Organization 3'); - expect(subject.allowProfilesOutsideOrganization).toEqual(false); - expect(subject.domains).toEqual([ - { - object: 'organization_domain', - id: 'org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8', - domain: 'example.com', - state: 'verified', - verificationStrategy: 'dns', - verificationToken: 'xB8SeACdKJQP9DP4CahU4YuQZ', - }, - ]); + expectOrganization(result); }); }); - describe('getOrganizationByExternalId', () => { - it('sends request', async () => { - const externalId = 'user_external_id'; - const apiResponse = { - ...getOrganization, - external_id: externalId, - }; - fetchOnce(apiResponse); - - const organization = - await workos.organizations.getOrganizationByExternalId(externalId); + describe('updateOrganization', () => { + it('sends the correct request and returns result', async () => { + fetchOnce(organizationFixture); - expect(fetchURL()).toContain(`/organizations/external_id/${externalId}`); - expect(organization).toMatchObject({ - id: apiResponse.id, - externalId: apiResponse.external_id, + const result = await workos.organizations.updateOrganization({ + id: 'test_id', + name: 'Test', + allowProfilesOutsideOrganization: true, }); - }); - }); - - describe('deleteOrganization', () => { - it('sends request to delete an Organization', async () => { - fetchOnce(); - const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); - await workos.organizations.deleteOrganization( - 'org_01EHT88Z8J8795GZNQ4ZP1J81T', + expect(fetchMethod()).toBe('PUT'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/organizations/test_id', ); - - expect(fetchURL()).toContain( - '/organizations/org_01EHT88Z8J8795GZNQ4ZP1J81T', + expect(fetchBody()).toEqual( + expect.objectContaining({ + name: 'Test', + allow_profiles_outside_organization: true, + }), ); + expectOrganization(result); }); }); - describe('updateOrganization', () => { - describe('with a valid payload', () => { - describe('with `domain_data`', () => { - it('updates an organization', async () => { - fetchOnce(updateOrganization, { status: 201 }); - - const subject = await workos.organizations.updateOrganization({ - organization: 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - domainData: [ - { domain: 'example.com', state: DomainDataState.Verified }, - ], - }); - - expect(fetchBody()).toEqual({ - domain_data: [{ domain: 'example.com', state: 'verified' }], - }); - expect(subject.id).toEqual('org_01EHT88Z8J8795GZNQ4ZP1J81T'); - expect(subject.name).toEqual('Test Organization 2'); - expect(subject.domains).toHaveLength(1); - }); - }); - - it('adds metadata to the request', async () => { - fetchOnce(updateOrganization, { status: 201 }); + describe('deleteOrganization', () => { + it('sends a DELETE request', async () => { + fetchOnce({}, { status: 204 }); - await workos.organizations.updateOrganization({ - organization: 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - metadata: { key: 'value' }, - }); + await workos.organizations.deleteOrganization({ id: 'test_id' }); - expect(fetchBody()).toEqual({ - metadata: { key: 'value' }, - }); - }); + expect(fetchMethod()).toBe('DELETE'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/organizations/test_id', + ); }); + }); - describe('when given `stripeCustomerId`', () => { - it('updates the organization’s Stripe customer ID', async () => { - fetchOnce(setStripeCustomerId); - - const subject = await workos.organizations.updateOrganization({ - organization: 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - stripeCustomerId: 'cus_MX8J9nfK4lP2Yw', - }); - - expect(fetchBody()).toMatchObject({ - stripe_customer_id: 'cus_MX8J9nfK4lP2Yw', - }); - - expect(subject.stripeCustomerId).toBe('cus_MX8J9nfK4lP2Yw'); - }); - - it('clears the organization’s Stripe customer ID with a `null` value', async () => { - fetchOnce(clearStripeCustomerId); - - const subject = await workos.organizations.updateOrganization({ - organization: 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - stripeCustomerId: null, - }); + describe('getAuditLogConfiguration', () => { + it('returns the expected result', async () => { + fetchOnce(auditLogConfigurationFixture); - expect(fetchBody()).toEqual({ - stripe_customer_id: null, - }); - - expect(subject.stripeCustomerId).toBeUndefined(); + const result = await workos.organizations.getAuditLogConfiguration({ + id: 'test_id', }); - describe('when the feature is not enabled', () => { - it('returns an error', async () => { - fetchOnce(setStripeCustomerIdDisabled, { status: 422 }); - - await expect( - workos.organizations.updateOrganization({ - organization: 'org_01EHT88Z8J8795GZNQ4ZP1J81T', - stripeCustomerId: 'cus_MX8J9nfK4lP2Yw', - }), - ).rejects.toThrow( - 'stripe_customer_id is not enabled for this environment', - ); - - expect(fetchBody()).toEqual({ - stripe_customer_id: 'cus_MX8J9nfK4lP2Yw', - }); - }); - }); + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/organizations/test_id/audit_log_configuration', + ); + expect(result.organizationId).toBe('org_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.retentionPeriodInDays).toBe(30); + expect(result.state).toBe('active'); }); }); }); diff --git a/src/organizations/organizations.ts b/src/organizations/organizations.ts index 4f2053471..b9c58eba5 100644 --- a/src/organizations/organizations.ts +++ b/src/organizations/organizations.ts @@ -1,20 +1,29 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { WorkOS } from '../workos'; import { AutoPaginatable } from '../common/utils/pagination'; -import { WorkOS } from '../workos'; -import { - CreateOrganizationOptions, - CreateOrganizationRequestOptions, - ListOrganizationsOptions, +import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize'; +import type { ListOrganizationsOptions } from './interfaces/list-organizations-options.interface'; +import type { CreateOrganizationOptions } from './interfaces/create-organization-options.interface'; +import type { GetOrganizationByExternalIdOptions } from './interfaces/get-organization-by-external-id-options.interface'; +import type { GetOrganizationOptions } from './interfaces/get-organization-options.interface'; +import type { UpdateOrganizationOptions } from './interfaces/update-organization-options.interface'; +import type { DeleteOrganizationOptions } from './interfaces/delete-organization-options.interface'; +import type { GetAuditLogConfigurationOptions } from './interfaces/get-audit-log-configuration-options.interface'; +import type { Organization, OrganizationResponse, - UpdateOrganizationOptions, -} from './interfaces'; -import { - deserializeOrganization, - serializeCreateOrganizationOptions, - serializeUpdateOrganizationOptions, -} from './serializers'; - -import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize'; +} from './interfaces/organization.interface'; +import type { + AuditLogConfiguration, + AuditLogConfigurationResponse, +} from './interfaces/audit-log-configuration.interface'; +import type { OrganizationInputResponse } from './interfaces/organization-input.interface'; +import type { UpdateOrganizationResponse } from './interfaces/update-organization.interface'; +import { deserializeOrganization } from './serializers/organization.serializer'; +import { deserializeAuditLogConfiguration } from './serializers/audit-log-configuration.serializer'; +import { serializeOrganizationInput } from './serializers/organization-input.serializer'; +import { serializeUpdateOrganization } from './serializers/update-organization.serializer'; export class Organizations { constructor(private readonly workos: WorkOS) {} @@ -30,12 +39,13 @@ export class Organizations { async listOrganizations( options?: ListOrganizationsOptions, ): Promise> { + const paginationOptions = options; return new AutoPaginatable( await fetchAndDeserialize( this.workos, '/organizations', deserializeOrganization, - options, + paginationOptions, ), (params) => fetchAndDeserialize( @@ -44,7 +54,7 @@ export class Organizations { deserializeOrganization, params, ), - options, + paginationOptions, ); } @@ -52,78 +62,60 @@ export class Organizations { * Create an Organization * * Creates a new organization in the current environment. - * @param payload - Object containing name. + * @param options - The request options. * @returns {Promise} * @throws {BadRequestException} 400 * @throws {ConflictException} 409 * @throws {UnprocessableEntityException} 422 */ async createOrganization( - payload: CreateOrganizationOptions, - requestOptions: CreateOrganizationRequestOptions = {}, + options: CreateOrganizationOptions, ): Promise { - const { data } = await this.workos.post( - '/organizations', - serializeCreateOrganizationOptions(payload), - requestOptions, - ); - + const payload = options; + const { data } = await this.workos.post< + OrganizationResponse, + OrganizationInputResponse + >('/organizations', serializeOrganizationInput(payload)); return deserializeOrganization(data); } /** - * Delete an Organization - * - * Permanently deletes an organization in the current environment. It cannot be undone. - * @param id - Unique identifier of the Organization. - * - * @example - * "org_01EHZNVPK3SFK441A1RGBFSHRT" - * - * @returns {Promise} - * @throws 403 response from the API. - */ - async deleteOrganization(id: string) { - await this.workos.delete(`/organizations/${id}`); - } - - /** - * Get an Organization - * - * Get the details of an existing organization. - * @param id - Unique identifier of the Organization. - * - * @example - * "org_01EHZNVPK3SFK441A1RGBFSHRT" + * Get an Organization by External ID * + * Get the details of an existing organization by an [external identifier](https://workos.com/docs/authkit/metadata/external-identifiers). + * @param options - The request options. + * @param options.externalId - The external ID of the Organization. + * @example "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191" * @returns {Promise} * @throws {NotFoundException} 404 */ - async getOrganization(id: string): Promise { + async getOrganizationByExternalId( + options: GetOrganizationByExternalIdOptions, + ): Promise { + const { externalId } = options; const { data } = await this.workos.get( - `/organizations/${id}`, + `/organizations/external_id/${encodeURIComponent(externalId)}`, ); - return deserializeOrganization(data); } /** - * Get an Organization by External ID - * - * Get the details of an existing organization by an [external identifier](https://workos.com/docs/authkit/metadata/external-identifiers). - * @param externalId - The external ID of the Organization. - * - * @example - * "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191" + * Get an Organization * + * Get the details of an existing organization. + * @param options - The request options. + * @param options.id - Unique identifier of the Organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" * @returns {Promise} * @throws {NotFoundException} 404 */ - async getOrganizationByExternalId(externalId: string): Promise { + async getOrganization( + options: GetOrganizationOptions, + ): Promise { + const { id } = options; const { data } = await this.workos.get( - `/organizations/external_id/${externalId}`, + `/organizations/${encodeURIComponent(id)}`, ); - return deserializeOrganization(data); } @@ -131,10 +123,25 @@ export class Organizations { * Update an Organization * * Updates an organization in the current environment. - * @param payload - The request body. + * @param options - The request body. + * @param options.id - Unique identifier of the Organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @param options.name - The name of the organization. + * @example "Foo Corp" + * @param options.allowProfilesOutsideOrganization - Whether the organization allows profiles from outside the organization to sign in. + * @example false + * @param options.domains - (deprecated) The domains associated with the organization. Deprecated in favor of `domain_data`. + * @example ["foo-corp.com"] + * @param options.domainData - The domains associated with the organization, including verification state. + * @param options.stripeCustomerId - The Stripe customer ID associated with the organization. + * @example "cus_R9qWAGMQ6nGE7V" + * @param options.metadata - Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization. + * @example {"tier":"diamond"} + * @param options.externalId - An external identifier for the Organization. + * @example "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191" * @returns {Promise} * @throws {BadRequestException} 400 - * @throws 403 response from the API. + * @throws {AuthorizationException} 403 * @throws {NotFoundException} 404 * @throws {ConflictException} 409 * @throws {UnprocessableEntityException} 422 @@ -142,13 +149,49 @@ export class Organizations { async updateOrganization( options: UpdateOrganizationOptions, ): Promise { - const { organization: organizationId, ...payload } = options; - - const { data } = await this.workos.put( - `/organizations/${organizationId}`, - serializeUpdateOrganizationOptions(payload), + const { id, ...payload } = options; + const { data } = await this.workos.put< + OrganizationResponse, + UpdateOrganizationResponse + >( + `/organizations/${encodeURIComponent(id)}`, + serializeUpdateOrganization(payload), ); - return deserializeOrganization(data); } + + /** + * Delete an Organization + * + * Permanently deletes an organization in the current environment. It cannot be undone. + * @param options - The request options. + * @param options.id - Unique identifier of the Organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {AuthorizationException} 403 + */ + async deleteOrganization(options: DeleteOrganizationOptions): Promise { + const { id } = options; + await this.workos.delete(`/organizations/${encodeURIComponent(id)}`); + } + + /** + * Get Audit Log Configuration + * + * Get the unified view of audit log trail and stream configuration for an organization. + * @param options - The request options. + * @param options.id - Unique identifier of the Organization. + * @example "org_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {NotFoundException} 404 + */ + async getAuditLogConfiguration( + options: GetAuditLogConfigurationOptions, + ): Promise { + const { id } = options; + const { data } = await this.workos.get( + `/organizations/${encodeURIComponent(id)}/audit_log_configuration`, + ); + return deserializeAuditLogConfiguration(data); + } } diff --git a/src/organizations/serializers.spec.ts b/src/organizations/serializers.spec.ts new file mode 100644 index 000000000..a7104b8bc --- /dev/null +++ b/src/organizations/serializers.spec.ts @@ -0,0 +1,94 @@ +// This file is auto-generated by oagen. Do not edit. + +import { serializeUpdateAuditLogsRetention } from './serializers/update-audit-logs-retention.serializer'; +import { serializeOrganizationDomainData } from './serializers/organization-domain-data.serializer'; +import { serializeOrganizationInput } from './serializers/organization-input.serializer'; +import { serializeUpdateOrganization } from './serializers/update-organization.serializer'; +import { deserializeAuditLogsRetention } from './serializers/audit-logs-retention.serializer'; +import { deserializeOrganization } from './serializers/organization.serializer'; +import { deserializeAuditLogConfiguration } from './serializers/audit-log-configuration.serializer'; +import { deserializeAuditLogConfigurationLogStream } from './serializers/audit-log-configuration-log-stream.serializer'; +import type { UpdateAuditLogsRetentionResponse } from './interfaces/update-audit-logs-retention.interface'; +import type { OrganizationDomainDataResponse } from './interfaces/organization-domain-data.interface'; +import type { OrganizationInputResponse } from './interfaces/organization-input.interface'; +import type { UpdateOrganizationResponse } from './interfaces/update-organization.interface'; +import type { AuditLogsRetentionResponse } from './interfaces/audit-logs-retention.interface'; +import type { OrganizationResponse } from './interfaces/organization.interface'; +import type { AuditLogConfigurationResponse } from './interfaces/audit-log-configuration.interface'; +import type { AuditLogConfigurationLogStreamResponse } from './interfaces/audit-log-configuration-log-stream.interface'; +import updateAuditLogsRetentionFixture from './fixtures/update-audit-logs-retention.json'; +import organizationDomainDataFixture from './fixtures/organization-domain-data.json'; +import organizationInputFixture from './fixtures/organization-input.json'; +import updateOrganizationFixture from './fixtures/update-organization.json'; +import auditLogsRetentionFixture from './fixtures/audit-logs-retention.json'; +import organizationFixture from './fixtures/organization.json'; +import auditLogConfigurationFixture from './fixtures/audit-log-configuration.json'; +import auditLogConfigurationLogStreamFixture from './fixtures/audit-log-configuration-log-stream.json'; + +describe('UpdateAuditLogsRetentionSerializer', () => { + it('serializes correctly', () => { + const fixture = + updateAuditLogsRetentionFixture as UpdateAuditLogsRetentionResponse; + const serialized = serializeUpdateAuditLogsRetention(fixture as any); + expect(serialized).toBeDefined(); + }); +}); + +describe('OrganizationDomainDataSerializer', () => { + it('serializes correctly', () => { + const fixture = + organizationDomainDataFixture as OrganizationDomainDataResponse; + const serialized = serializeOrganizationDomainData(fixture as any); + expect(serialized).toBeDefined(); + }); +}); + +describe('OrganizationInputSerializer', () => { + it('serializes correctly', () => { + const fixture = organizationInputFixture as OrganizationInputResponse; + const serialized = serializeOrganizationInput(fixture as any); + expect(serialized).toBeDefined(); + }); +}); + +describe('UpdateOrganizationSerializer', () => { + it('serializes correctly', () => { + const fixture = updateOrganizationFixture as UpdateOrganizationResponse; + const serialized = serializeUpdateOrganization(fixture as any); + expect(serialized).toBeDefined(); + }); +}); + +describe('AuditLogsRetentionSerializer', () => { + it('deserializes correctly', () => { + const fixture = auditLogsRetentionFixture as AuditLogsRetentionResponse; + const deserialized = deserializeAuditLogsRetention(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('OrganizationSerializer', () => { + it('deserializes correctly', () => { + const fixture = organizationFixture as OrganizationResponse; + const deserialized = deserializeOrganization(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('AuditLogConfigurationSerializer', () => { + it('deserializes correctly', () => { + const fixture = + auditLogConfigurationFixture as AuditLogConfigurationResponse; + const deserialized = deserializeAuditLogConfiguration(fixture); + expect(deserialized).toBeDefined(); + }); +}); + +describe('AuditLogConfigurationLogStreamSerializer', () => { + it('deserializes correctly', () => { + const fixture = + auditLogConfigurationLogStreamFixture as AuditLogConfigurationLogStreamResponse; + const deserialized = deserializeAuditLogConfigurationLogStream(fixture); + expect(deserialized).toBeDefined(); + }); +}); diff --git a/src/organizations/serializers/audit-log-configuration-log-stream.serializer.ts b/src/organizations/serializers/audit-log-configuration-log-stream.serializer.ts new file mode 100644 index 000000000..262d25925 --- /dev/null +++ b/src/organizations/serializers/audit-log-configuration-log-stream.serializer.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + AuditLogConfigurationLogStream, + AuditLogConfigurationLogStreamResponse, +} from '../interfaces/audit-log-configuration-log-stream.interface'; + +export const deserializeAuditLogConfigurationLogStream = ( + response: AuditLogConfigurationLogStreamResponse, +): AuditLogConfigurationLogStream => ({ + id: response.id, + type: response.type, + state: response.state, + lastSyncedAt: response.last_synced_at ?? null, + createdAt: new Date(response.created_at), +}); diff --git a/src/organizations/serializers/audit-log-configuration.serializer.ts b/src/organizations/serializers/audit-log-configuration.serializer.ts new file mode 100644 index 000000000..4d783e313 --- /dev/null +++ b/src/organizations/serializers/audit-log-configuration.serializer.ts @@ -0,0 +1,19 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + AuditLogConfiguration, + AuditLogConfigurationResponse, +} from '../interfaces/audit-log-configuration.interface'; +import { deserializeAuditLogConfigurationLogStream } from './audit-log-configuration-log-stream.serializer'; + +export const deserializeAuditLogConfiguration = ( + response: AuditLogConfigurationResponse, +): AuditLogConfiguration => ({ + organizationId: response.organization_id, + retentionPeriodInDays: response.retention_period_in_days, + state: response.state, + logStream: + response.log_stream != null + ? deserializeAuditLogConfigurationLogStream(response.log_stream) + : undefined, +}); diff --git a/src/organizations/serializers/audit-logs-retention.serializer.ts b/src/organizations/serializers/audit-logs-retention.serializer.ts new file mode 100644 index 000000000..f459a443e --- /dev/null +++ b/src/organizations/serializers/audit-logs-retention.serializer.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + AuditLogsRetention, + AuditLogsRetentionResponse, +} from '../interfaces/audit-logs-retention.interface'; + +export const deserializeAuditLogsRetention = ( + response: AuditLogsRetentionResponse, +): AuditLogsRetention => ({ + retentionPeriodInDays: response.retention_period_in_days ?? null, +}); diff --git a/src/organizations/serializers/create-organization-options.serializer.ts b/src/organizations/serializers/create-organization-options.serializer.ts deleted file mode 100644 index f11aa6d46..000000000 --- a/src/organizations/serializers/create-organization-options.serializer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { - CreateOrganizationOptions, - SerializedCreateOrganizationOptions, -} from '../interfaces'; - -export const serializeCreateOrganizationOptions = ( - options: CreateOrganizationOptions, -): SerializedCreateOrganizationOptions => ({ - name: options.name, - domain_data: options.domainData, - external_id: options.externalId, - metadata: options.metadata, -}); diff --git a/src/organizations/serializers/index.ts b/src/organizations/serializers/index.ts index c53e493c4..7a25e36a8 100644 --- a/src/organizations/serializers/index.ts +++ b/src/organizations/serializers/index.ts @@ -1,3 +1,10 @@ -export * from './create-organization-options.serializer'; +// This file is auto-generated by oagen. Do not edit. + +export * from './audit-log-configuration.serializer'; +export * from './audit-log-configuration-log-stream.serializer'; +export * from './audit-logs-retention.serializer'; export * from './organization.serializer'; -export * from './update-organization-options.serializer'; +export * from './organization-domain-data.serializer'; +export * from './organization-input.serializer'; +export * from './update-audit-logs-retention.serializer'; +export * from './update-organization.serializer'; diff --git a/src/organizations/serializers/organization-domain-data.serializer.ts b/src/organizations/serializers/organization-domain-data.serializer.ts new file mode 100644 index 000000000..99f3891cb --- /dev/null +++ b/src/organizations/serializers/organization-domain-data.serializer.ts @@ -0,0 +1,13 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + OrganizationDomainData, + OrganizationDomainDataResponse, +} from '../interfaces/organization-domain-data.interface'; + +export const serializeOrganizationDomainData = ( + model: OrganizationDomainData, +): OrganizationDomainDataResponse => ({ + domain: model.domain, + state: model.state, +}); diff --git a/src/organizations/serializers/organization-input.serializer.ts b/src/organizations/serializers/organization-input.serializer.ts new file mode 100644 index 000000000..84d404ba5 --- /dev/null +++ b/src/organizations/serializers/organization-input.serializer.ts @@ -0,0 +1,21 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + OrganizationInput, + OrganizationInputResponse, +} from '../interfaces/organization-input.interface'; +import { serializeOrganizationDomainData } from './organization-domain-data.serializer'; + +export const serializeOrganizationInput = ( + model: OrganizationInput, +): OrganizationInputResponse => ({ + name: model.name, + allow_profiles_outside_organization: model.allowProfilesOutsideOrganization, + domains: model.domains, + domain_data: + model.domainData != null + ? model.domainData.map(serializeOrganizationDomainData) + : undefined, + metadata: model.metadata ?? null, + external_id: model.externalId ?? null, +}); diff --git a/src/organizations/serializers/organization.serializer.ts b/src/organizations/serializers/organization.serializer.ts index 1c1761d2d..4ae4c1065 100644 --- a/src/organizations/serializers/organization.serializer.ts +++ b/src/organizations/serializers/organization.serializer.ts @@ -1,20 +1,23 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + Organization, + OrganizationResponse, +} from '../interfaces/organization.interface'; import { deserializeOrganizationDomain } from '../../organization-domains/serializers/organization-domain.serializer'; -import { Organization, OrganizationResponse } from '../interfaces'; export const deserializeOrganization = ( - organization: OrganizationResponse, + response: OrganizationResponse, ): Organization => ({ - object: organization.object, - id: organization.id, - name: organization.name, + object: response.object, + id: response.id, + name: response.name, + domains: response.domains.map(deserializeOrganizationDomain), + metadata: response.metadata ?? {}, + externalId: response.external_id ?? null, + stripeCustomerId: response.stripe_customer_id, + createdAt: new Date(response.created_at), + updatedAt: new Date(response.updated_at), allowProfilesOutsideOrganization: - organization.allow_profiles_outside_organization, - domains: organization.domains.map(deserializeOrganizationDomain), - ...(typeof organization.stripe_customer_id === 'undefined' - ? undefined - : { stripeCustomerId: organization.stripe_customer_id }), - createdAt: organization.created_at, - updatedAt: organization.updated_at, - externalId: organization.external_id ?? null, - metadata: organization.metadata ?? {}, + response.allow_profiles_outside_organization, }); diff --git a/src/organizations/serializers/update-audit-logs-retention.serializer.ts b/src/organizations/serializers/update-audit-logs-retention.serializer.ts new file mode 100644 index 000000000..14faac71c --- /dev/null +++ b/src/organizations/serializers/update-audit-logs-retention.serializer.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + UpdateAuditLogsRetention, + UpdateAuditLogsRetentionResponse, +} from '../interfaces/update-audit-logs-retention.interface'; + +export const serializeUpdateAuditLogsRetention = ( + model: UpdateAuditLogsRetention, +): UpdateAuditLogsRetentionResponse => ({ + retention_period_in_days: model.retentionPeriodInDays, +}); diff --git a/src/organizations/serializers/update-organization-options.serializer.ts b/src/organizations/serializers/update-organization-options.serializer.ts deleted file mode 100644 index 08e8c1b06..000000000 --- a/src/organizations/serializers/update-organization-options.serializer.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { - SerializedUpdateOrganizationOptions, - UpdateOrganizationOptions, -} from '../interfaces'; - -export const serializeUpdateOrganizationOptions = ( - options: Omit, -): SerializedUpdateOrganizationOptions => ({ - name: options.name, - domain_data: options.domainData, - stripe_customer_id: options.stripeCustomerId, - external_id: options.externalId, - metadata: options.metadata, -}); diff --git a/src/organizations/serializers/update-organization.serializer.ts b/src/organizations/serializers/update-organization.serializer.ts new file mode 100644 index 000000000..6ce6618ef --- /dev/null +++ b/src/organizations/serializers/update-organization.serializer.ts @@ -0,0 +1,22 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + UpdateOrganization, + UpdateOrganizationResponse, +} from '../interfaces/update-organization.interface'; +import { serializeOrganizationDomainData } from './organization-domain-data.serializer'; + +export const serializeUpdateOrganization = ( + model: UpdateOrganization, +): UpdateOrganizationResponse => ({ + name: model.name, + allow_profiles_outside_organization: model.allowProfilesOutsideOrganization, + domains: model.domains, + domain_data: + model.domainData != null + ? model.domainData.map(serializeOrganizationDomainData) + : undefined, + stripe_customer_id: model.stripeCustomerId, + metadata: model.metadata ?? null, + external_id: model.externalId ?? null, +});