diff --git a/.oagen-manifest.json b/.oagen-manifest.json index f4f865519..e1304a4cc 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -1,7 +1,6 @@ { "version": 2, "language": "node", - "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", @@ -59,6 +58,35 @@ "src/connect/serializers/user-consent-option.serializer.ts", "src/connect/serializers/user-management-login-request.serializer.ts", "src/connect/serializers/user-object.serializer.ts", + "src/flag-target-types/fixtures/create-flag-target-type.json", + "src/flag-target-types/fixtures/flag-target-type.json", + "src/flag-target-types/fixtures/list-flag-target-type.json", + "src/flag-target-types/flag-target-types.spec.ts", + "src/flag-target-types/flag-target-types.ts", + "src/flag-target-types/interfaces/create-flag-target-type-options.interface.ts", + "src/flag-target-types/interfaces/create-flag-target-type.interface.ts", + "src/flag-target-types/interfaces/flag-target-type.interface.ts", + "src/flag-target-types/interfaces/get-flag-target-type-options.interface.ts", + "src/flag-target-types/interfaces/index.ts", + "src/flag-target-types/interfaces/list-flag-target-types-options.interface.ts", + "src/flag-target-types/serializers/create-flag-target-type.serializer.ts", + "src/flag-target-types/serializers/flag-target-type.serializer.ts", + "src/flag-target-types/serializers/index.ts", + "src/flag-targets/fixtures/create-flag-target.json", + "src/flag-targets/fixtures/flag-target.json", + "src/flag-targets/fixtures/list-flag-target.json", + "src/flag-targets/flag-targets.spec.ts", + "src/flag-targets/flag-targets.ts", + "src/flag-targets/interfaces/create-flag-target-options.interface.ts", + "src/flag-targets/interfaces/create-flag-target.interface.ts", + "src/flag-targets/interfaces/delete-flag-target-options.interface.ts", + "src/flag-targets/interfaces/flag-target.interface.ts", + "src/flag-targets/interfaces/get-flag-target-options.interface.ts", + "src/flag-targets/interfaces/index.ts", + "src/flag-targets/interfaces/list-flag-targets-options.interface.ts", + "src/flag-targets/serializers/create-flag-target.serializer.ts", + "src/flag-targets/serializers/flag-target.serializer.ts", + "src/flag-targets/serializers/index.ts", "src/groups/fixtures/create-group-membership.json", "src/groups/fixtures/create-group.json", "src/groups/fixtures/group.json", diff --git a/src/feature-flags/interfaces/flag-poll-response.interface.ts b/src/feature-flags/interfaces/flag-poll-response.interface.ts index 762f53ed4..35c55c025 100644 --- a/src/feature-flags/interfaces/flag-poll-response.interface.ts +++ b/src/feature-flags/interfaces/flag-poll-response.interface.ts @@ -1,4 +1,4 @@ -export interface FlagTarget { +export interface FlagPollTarget { id: string; enabled: boolean; } @@ -14,8 +14,8 @@ export interface FlagPollEntry { enabled: boolean; default_value: boolean; targets: { - users: FlagTarget[]; - organizations: FlagTarget[]; + users: FlagPollTarget[]; + organizations: FlagPollTarget[]; /** Absent until the API's custom-targets rollout flag is enabled. */ custom_targets?: FlagCustomTarget[]; }; diff --git a/src/feature-flags/runtime-client.ts b/src/feature-flags/runtime-client.ts index e13841597..318597cb0 100644 --- a/src/feature-flags/runtime-client.ts +++ b/src/feature-flags/runtime-client.ts @@ -9,7 +9,7 @@ import { FlagCustomTarget, FlagPollEntry, FlagPollResponse, - FlagTarget, + FlagPollTarget, RuntimeClientOptions, RuntimeClientLogger, RuntimeClientStats, @@ -300,7 +300,10 @@ export class FeatureFlagsRuntimeClient extends EventEmitter return true; } - const targetsChanged = (xs: FlagTarget[], ys: FlagTarget[]): boolean => { + const targetsChanged = ( + xs: FlagPollTarget[], + ys: FlagPollTarget[], + ): boolean => { if (xs.length !== ys.length) return true; const map = new Map(ys.map((t) => [t.id, t.enabled])); return xs.some((t) => map.get(t.id) !== t.enabled); diff --git a/src/flag-target-types/fixtures/create-flag-target-type.json b/src/flag-target-types/fixtures/create-flag-target-type.json new file mode 100644 index 000000000..2d0e12a1a --- /dev/null +++ b/src/flag-target-types/fixtures/create-flag-target-type.json @@ -0,0 +1,3 @@ +{ + "slug": "workspace" +} diff --git a/src/flag-target-types/fixtures/flag-target-type.json b/src/flag-target-types/fixtures/flag-target-type.json new file mode 100644 index 000000000..88777edd9 --- /dev/null +++ b/src/flag-target-types/fixtures/flag-target-type.json @@ -0,0 +1,7 @@ +{ + "object": "flag_target_type", + "id": "flag_target_type_01EHZNVPK3SFK441A1RGBFSHRT", + "slug": "workspace", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/src/flag-target-types/fixtures/list-flag-target-type.json b/src/flag-target-types/fixtures/list-flag-target-type.json new file mode 100644 index 000000000..da42ebb09 --- /dev/null +++ b/src/flag-target-types/fixtures/list-flag-target-type.json @@ -0,0 +1,15 @@ +{ + "data": [ + { + "object": "flag_target_type", + "id": "flag_target_type_01EHZNVPK3SFK441A1RGBFSHRT", + "slug": "workspace", + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/src/flag-target-types/flag-target-types.spec.ts b/src/flag-target-types/flag-target-types.spec.ts new file mode 100644 index 000000000..d0fdc7554 --- /dev/null +++ b/src/flag-target-types/flag-target-types.spec.ts @@ -0,0 +1,78 @@ +// This file is auto-generated by oagen. Do not edit. + +import fetch from 'jest-fetch-mock'; +import { + fetchOnce, + fetchURL, + fetchMethod, + fetchSearchParams, + fetchBody, +} from '../common/utils/test-utils'; +import { WorkOS } from '../workos'; + +import listFlagTargetTypeFixture from './fixtures/list-flag-target-type.json'; +import flagTargetTypeFixture from './fixtures/flag-target-type.json'; + +const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); + +function expectFlagTargetType(result: any) { + expect(result.object).toBe('flag_target_type'); + expect(result.id).toBe('flag_target_type_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.slug).toBe('workspace'); + expect(result.createdAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); + expect(result.updatedAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); +} + +describe('FlagTargetTypes', () => { + beforeEach(() => fetch.resetMocks()); + + describe('listFlagTargetTypes', () => { + it('returns paginated results', async () => { + fetchOnce(listFlagTargetTypeFixture); + + const { data, listMetadata } = + await workos.flagTargetTypes.listFlagTargetTypes({ order: 'desc' }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe('/flag_target_types'); + expect(fetchSearchParams()).toHaveProperty('order'); + expect(Array.isArray(data)).toBe(true); + expect(listMetadata).toBeDefined(); + expect(data.length).toBeGreaterThan(0); + expectFlagTargetType(data[0]); + }); + }); + + describe('createFlagTargetType', () => { + it('sends the correct request and returns result', async () => { + fetchOnce(flagTargetTypeFixture); + + const result = await workos.flagTargetTypes.createFlagTargetType({ + slug: 'test_slug', + }); + + expect(fetchMethod()).toBe('POST'); + expect(new URL(String(fetchURL())).pathname).toBe('/flag_target_types'); + expect(fetchBody()).toEqual( + expect.objectContaining({ slug: 'test_slug' }), + ); + expectFlagTargetType(result); + }); + }); + + describe('getFlagTargetType', () => { + it('returns the expected result', async () => { + fetchOnce(flagTargetTypeFixture); + + const result = await workos.flagTargetTypes.getFlagTargetType({ + id: 'test_id', + }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/flag_target_types/test_id', + ); + expectFlagTargetType(result); + }); + }); +}); diff --git a/src/flag-target-types/flag-target-types.ts b/src/flag-target-types/flag-target-types.ts new file mode 100644 index 000000000..e56c13c2f --- /dev/null +++ b/src/flag-target-types/flag-target-types.ts @@ -0,0 +1,87 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { WorkOS } from '../workos'; +import { AutoPaginatable } from '../common/utils/pagination'; +import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize'; +import type { ListFlagTargetTypesOptions } from './interfaces/list-flag-target-types-options.interface'; +import type { CreateFlagTargetTypeOptions } from './interfaces/create-flag-target-type-options.interface'; +import type { GetFlagTargetTypeOptions } from './interfaces/get-flag-target-type-options.interface'; +import type { + FlagTargetType, + FlagTargetTypeResponse, +} from './interfaces/flag-target-type.interface'; +import type { CreateFlagTargetTypeResponse } from './interfaces/create-flag-target-type.interface'; +import { deserializeFlagTargetType } from './serializers/flag-target-type.serializer'; +import { serializeCreateFlagTargetType } from './serializers/create-flag-target-type.serializer'; + +export class FlagTargetTypes { + constructor(private readonly workos: WorkOS) {} + + /** + * List flag target types + * + * Get a list of the custom Flag Target Types registered for the current environment's project. The built-in `user` and `organization` target types are not included. + * @param options - Pagination and filter options. + * @returns {Promise>} + * @throws {BadRequestException} 400 + */ + async listFlagTargetTypes( + options?: ListFlagTargetTypesOptions, + ): Promise> { + const paginationOptions = options; + return new AutoPaginatable( + await fetchAndDeserialize( + this.workos, + '/flag_target_types', + deserializeFlagTargetType, + paginationOptions, + ), + (params) => + fetchAndDeserialize( + this.workos, + '/flag_target_types', + deserializeFlagTargetType, + params, + ), + paginationOptions, + ); + } + + /** + * Create a flag target type + * + * Register a custom Flag Target Type, making its slug usable as the `target_type` of a Flag Target anywhere in the project. + * @returns {Promise} + * @throws {BadRequestException} 400 + */ + async createFlagTargetType( + options: CreateFlagTargetTypeOptions, + ): Promise { + const payload = options; + const { data } = await this.workos.post< + FlagTargetTypeResponse, + CreateFlagTargetTypeResponse + >('/flag_target_types', serializeCreateFlagTargetType(payload)); + return deserializeFlagTargetType(data); + } + + /** + * Get a flag target type + * + * Get the details of an existing Flag Target Type. + * @param options - The request options. + * @param options.id - Unique identifier of the Flag Target Type. + * @example "flag_target_type_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {NotFoundException} 404 + */ + async getFlagTargetType( + options: GetFlagTargetTypeOptions, + ): Promise { + const { id } = options; + const { data } = await this.workos.get( + `/flag_target_types/${encodeURIComponent(id)}`, + ); + return deserializeFlagTargetType(data); + } +} diff --git a/src/flag-target-types/interfaces/create-flag-target-type-options.interface.ts b/src/flag-target-types/interfaces/create-flag-target-type-options.interface.ts new file mode 100644 index 000000000..e18af42fc --- /dev/null +++ b/src/flag-target-types/interfaces/create-flag-target-type-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface CreateFlagTargetTypeOptions { + /** A unique key used as the `target_type` of a Flag Target, scoped to the project. May contain lowercase letters, numbers, underscores and hyphens. */ + slug: string; +} diff --git a/src/flag-target-types/interfaces/create-flag-target-type.interface.ts b/src/flag-target-types/interfaces/create-flag-target-type.interface.ts new file mode 100644 index 000000000..51563f881 --- /dev/null +++ b/src/flag-target-types/interfaces/create-flag-target-type.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface CreateFlagTargetType { + /** A unique key used as the `target_type` of a Flag Target, scoped to the project. May contain lowercase letters, numbers, underscores and hyphens. */ + slug: string; +} + +export interface CreateFlagTargetTypeResponse { + slug: string; +} diff --git a/src/flag-target-types/interfaces/flag-target-type.interface.ts b/src/flag-target-types/interfaces/flag-target-type.interface.ts new file mode 100644 index 000000000..a3eb06ad2 --- /dev/null +++ b/src/flag-target-types/interfaces/flag-target-type.interface.ts @@ -0,0 +1,22 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface FlagTargetType { + /** Distinguishes the Flag Target Type object. */ + object: 'flag_target_type'; + /** Unique identifier of the Flag Target Type. */ + id: string; + /** A unique key used as the `target_type` of a Flag Target, scoped to the project. */ + slug: string; + /** An ISO 8601 timestamp. */ + createdAt: Date; + /** An ISO 8601 timestamp. */ + updatedAt: Date; +} + +export interface FlagTargetTypeResponse { + object: 'flag_target_type'; + id: string; + slug: string; + created_at: string; + updated_at: string; +} diff --git a/src/flag-target-types/interfaces/get-flag-target-type-options.interface.ts b/src/flag-target-types/interfaces/get-flag-target-type-options.interface.ts new file mode 100644 index 000000000..2173f877e --- /dev/null +++ b/src/flag-target-types/interfaces/get-flag-target-type-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetFlagTargetTypeOptions { + /** Unique identifier of the Flag Target Type. */ + id: string; +} diff --git a/src/flag-target-types/interfaces/index.ts b/src/flag-target-types/interfaces/index.ts new file mode 100644 index 000000000..ba3519c5d --- /dev/null +++ b/src/flag-target-types/interfaces/index.ts @@ -0,0 +1,7 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './create-flag-target-type-options.interface'; +export * from './create-flag-target-type.interface'; +export * from './flag-target-type.interface'; +export * from './get-flag-target-type-options.interface'; +export * from './list-flag-target-types-options.interface'; diff --git a/src/flag-target-types/interfaces/list-flag-target-types-options.interface.ts b/src/flag-target-types/interfaces/list-flag-target-types-options.interface.ts new file mode 100644 index 000000000..f8dde0cea --- /dev/null +++ b/src/flag-target-types/interfaces/list-flag-target-types-options.interface.ts @@ -0,0 +1,5 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { PaginationOptions } from '../../common/interfaces/pagination-options.interface'; + +export type ListFlagTargetTypesOptions = PaginationOptions; diff --git a/src/flag-target-types/serializers/create-flag-target-type.serializer.ts b/src/flag-target-types/serializers/create-flag-target-type.serializer.ts new file mode 100644 index 000000000..75a91b71f --- /dev/null +++ b/src/flag-target-types/serializers/create-flag-target-type.serializer.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + CreateFlagTargetType, + CreateFlagTargetTypeResponse, +} from '../interfaces/create-flag-target-type.interface'; + +export const serializeCreateFlagTargetType = ( + model: CreateFlagTargetType, +): CreateFlagTargetTypeResponse => ({ + slug: model.slug, +}); diff --git a/src/flag-target-types/serializers/flag-target-type.serializer.ts b/src/flag-target-types/serializers/flag-target-type.serializer.ts new file mode 100644 index 000000000..50fe85e54 --- /dev/null +++ b/src/flag-target-types/serializers/flag-target-type.serializer.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + FlagTargetType, + FlagTargetTypeResponse, +} from '../interfaces/flag-target-type.interface'; + +export const deserializeFlagTargetType = ( + response: FlagTargetTypeResponse, +): FlagTargetType => ({ + object: response.object, + id: response.id, + slug: response.slug, + createdAt: new Date(response.created_at), + updatedAt: new Date(response.updated_at), +}); diff --git a/src/flag-target-types/serializers/index.ts b/src/flag-target-types/serializers/index.ts new file mode 100644 index 000000000..afd78c9de --- /dev/null +++ b/src/flag-target-types/serializers/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './create-flag-target-type.serializer'; +export * from './flag-target-type.serializer'; diff --git a/src/flag-targets/fixtures/create-flag-target.json b/src/flag-targets/fixtures/create-flag-target.json new file mode 100644 index 000000000..34d488635 --- /dev/null +++ b/src/flag-targets/fixtures/create-flag-target.json @@ -0,0 +1,5 @@ +{ + "flag_slug": "new-checkout", + "target_type": "organization", + "target_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY" +} diff --git a/src/flag-targets/fixtures/flag-target.json b/src/flag-targets/fixtures/flag-target.json new file mode 100644 index 000000000..103f11ffa --- /dev/null +++ b/src/flag-targets/fixtures/flag-target.json @@ -0,0 +1,13 @@ +{ + "object": "flag_target", + "id": "flag_target_01EHZNVPK3SFK441A1RGBFSHRT", + "flag_id": "flag_01EHZNVPK3SFK441A1RGBFSHRT", + "flag_slug": "new-checkout", + "environment_id": "environment_01EHWNCE74X7JSDV0X3SZ3KJNY", + "target_type": "organization", + "target_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "value_type": "boolean", + "value": true, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" +} diff --git a/src/flag-targets/fixtures/list-flag-target.json b/src/flag-targets/fixtures/list-flag-target.json new file mode 100644 index 000000000..1bab753b8 --- /dev/null +++ b/src/flag-targets/fixtures/list-flag-target.json @@ -0,0 +1,21 @@ +{ + "data": [ + { + "object": "flag_target", + "id": "flag_target_01EHZNVPK3SFK441A1RGBFSHRT", + "flag_id": "flag_01EHZNVPK3SFK441A1RGBFSHRT", + "flag_slug": "new-checkout", + "environment_id": "environment_01EHWNCE74X7JSDV0X3SZ3KJNY", + "target_type": "organization", + "target_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY", + "value_type": "boolean", + "value": true, + "created_at": "2026-01-15T12:00:00.000Z", + "updated_at": "2026-01-15T12:00:00.000Z" + } + ], + "list_metadata": { + "before": null, + "after": null + } +} diff --git a/src/flag-targets/flag-targets.spec.ts b/src/flag-targets/flag-targets.spec.ts new file mode 100644 index 000000000..d3f5ec3df --- /dev/null +++ b/src/flag-targets/flag-targets.spec.ts @@ -0,0 +1,105 @@ +// This file is auto-generated by oagen. Do not edit. + +import fetch from 'jest-fetch-mock'; +import { + fetchOnce, + fetchURL, + fetchMethod, + fetchSearchParams, + fetchBody, +} from '../common/utils/test-utils'; +import { WorkOS } from '../workos'; + +import listFlagTargetFixture from './fixtures/list-flag-target.json'; +import flagTargetFixture from './fixtures/flag-target.json'; + +const workos = new WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU'); + +function expectFlagTarget(result: any) { + expect(result.object).toBe('flag_target'); + expect(result.id).toBe('flag_target_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.flagId).toBe('flag_01EHZNVPK3SFK441A1RGBFSHRT'); + expect(result.flagSlug).toBe('new-checkout'); + expect(result.environmentId).toBe('environment_01EHWNCE74X7JSDV0X3SZ3KJNY'); + expect(result.targetType).toBe('organization'); + expect(result.targetId).toBe('org_01EHWNCE74X7JSDV0X3SZ3KJNY'); + expect(result.valueType).toBe('boolean'); + expect(result.value).toBe(true); + expect(result.createdAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); + expect(result.updatedAt.toISOString()).toBe('2026-01-15T12:00:00.000Z'); +} + +describe('FlagTargets', () => { + beforeEach(() => fetch.resetMocks()); + + describe('listFlagTargets', () => { + it('returns paginated results', async () => { + fetchOnce(listFlagTargetFixture); + + const { data, listMetadata } = await workos.flagTargets.listFlagTargets({ + order: 'desc', + flagSlug: 'new-checkout', + targetType: 'organization', + targetId: 'org_01EHWNCE74X7JSDV0X3SZ3KJNY', + }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe('/flag_targets'); + expect(fetchSearchParams()).toHaveProperty('order'); + expect(Array.isArray(data)).toBe(true); + expect(listMetadata).toBeDefined(); + expect(data.length).toBeGreaterThan(0); + expectFlagTarget(data[0]); + }); + }); + + describe('createFlagTarget', () => { + it('sends the correct request and returns result', async () => { + fetchOnce(flagTargetFixture); + + const result = await workos.flagTargets.createFlagTarget({ + flagSlug: 'test_flag_slug', + targetType: 'test_target_type', + targetId: 'target_id_01234', + }); + + expect(fetchMethod()).toBe('POST'); + expect(new URL(String(fetchURL())).pathname).toBe('/flag_targets'); + expect(fetchBody()).toEqual( + expect.objectContaining({ + flag_slug: 'test_flag_slug', + target_type: 'test_target_type', + target_id: 'target_id_01234', + }), + ); + expectFlagTarget(result); + }); + }); + + describe('getFlagTarget', () => { + it('returns the expected result', async () => { + fetchOnce(flagTargetFixture); + + const result = await workos.flagTargets.getFlagTarget({ id: 'test_id' }); + + expect(fetchMethod()).toBe('GET'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/flag_targets/test_id', + ); + expectFlagTarget(result); + }); + }); + + describe('deleteFlagTarget', () => { + it('sends a DELETE request', async () => { + fetchOnce({}, { status: 204 }); + + await workos.flagTargets.deleteFlagTarget({ id: 'test_id' }); + + expect(fetchMethod()).toBe('DELETE'); + expect(new URL(String(fetchURL())).pathname).toBe( + '/flag_targets/test_id', + ); + }); + }); +}); diff --git a/src/flag-targets/flag-targets.ts b/src/flag-targets/flag-targets.ts new file mode 100644 index 000000000..cb53acbca --- /dev/null +++ b/src/flag-targets/flag-targets.ts @@ -0,0 +1,118 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { WorkOS } from '../workos'; +import type { PaginationOptions } from '../common/interfaces/pagination-options.interface'; +import { AutoPaginatable } from '../common/utils/pagination'; +import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize'; +import type { ListFlagTargetsOptions } from './interfaces/list-flag-targets-options.interface'; +import type { CreateFlagTargetOptions } from './interfaces/create-flag-target-options.interface'; +import type { GetFlagTargetOptions } from './interfaces/get-flag-target-options.interface'; +import type { DeleteFlagTargetOptions } from './interfaces/delete-flag-target-options.interface'; +import type { + FlagTarget, + FlagTargetResponse, +} from './interfaces/flag-target.interface'; +import type { CreateFlagTargetResponse } from './interfaces/create-flag-target.interface'; +import { deserializeFlagTarget } from './serializers/flag-target.serializer'; +import { serializeCreateFlagTarget } from './serializers/create-flag-target.serializer'; + +const serializeListFlagTargetsOptions = ( + options: ListFlagTargetsOptions, +): PaginationOptions => { + const wire: Record = { + limit: options.limit, + before: options.before, + after: options.after, + order: options.order, + }; + if (options.flagSlug !== undefined) wire.flag_slug = options.flagSlug; + if (options.targetType !== undefined) wire.target_type = options.targetType; + if (options.targetId !== undefined) wire.target_id = options.targetId; + return wire as PaginationOptions; +}; + +export class FlagTargets { + constructor(private readonly workos: WorkOS) {} + + /** + * List flag targets + * + * Get a list of the Flag Targets in the current environment, optionally filtered by Feature Flag slug, target type, or targeted entity. + * @param options - Pagination and filter options. + * @returns {Promise>} + * @throws {BadRequestException} 400 + */ + async listFlagTargets( + options?: ListFlagTargetsOptions, + ): Promise> { + return new AutoPaginatable( + await fetchAndDeserialize( + this.workos, + '/flag_targets', + deserializeFlagTarget, + options ? serializeListFlagTargetsOptions(options) : undefined, + ), + (params) => + fetchAndDeserialize( + this.workos, + '/flag_targets', + deserializeFlagTarget, + params, + ), + options ? serializeListFlagTargetsOptions(options) : undefined, + ); + } + + /** + * Create a flag target + * + * Enable a Feature Flag for a target in the current environment. The `target_type` is given explicitly: a custom target type has to be registered with `POST /flag_target_types` first, and its `target_id` is an identifier from your own domain model, which carries no prefix to infer a type from. + * @returns {Promise} + * @throws {BadRequestException} 400 + * @throws {NotFoundException} 404 + * @throws {UnprocessableEntityException} 422 + */ + async createFlagTarget( + options: CreateFlagTargetOptions, + ): Promise { + const payload = options; + const { data } = await this.workos.post< + FlagTargetResponse, + CreateFlagTargetResponse + >('/flag_targets', serializeCreateFlagTarget(payload)); + return deserializeFlagTarget(data); + } + + /** + * Get a flag target + * + * Get the details of an existing Flag Target. + * @param options - The request options. + * @param options.id - Unique identifier of the Flag Target. + * @example "flag_target_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {NotFoundException} 404 + */ + async getFlagTarget(options: GetFlagTargetOptions): Promise { + const { id } = options; + const { data } = await this.workos.get( + `/flag_targets/${encodeURIComponent(id)}`, + ); + return deserializeFlagTarget(data); + } + + /** + * Delete a flag target + * + * Disable a Feature Flag for a target by deleting the Flag Target. + * @param options - The request options. + * @param options.id - Unique identifier of the Flag Target. + * @example "flag_target_01EHZNVPK3SFK441A1RGBFSHRT" + * @returns {Promise} + * @throws {NotFoundException} 404 + */ + async deleteFlagTarget(options: DeleteFlagTargetOptions): Promise { + const { id } = options; + await this.workos.delete(`/flag_targets/${encodeURIComponent(id)}`); + } +} diff --git a/src/flag-targets/interfaces/create-flag-target-options.interface.ts b/src/flag-targets/interfaces/create-flag-target-options.interface.ts new file mode 100644 index 000000000..f046f167b --- /dev/null +++ b/src/flag-targets/interfaces/create-flag-target-options.interface.ts @@ -0,0 +1,10 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface CreateFlagTargetOptions { + /** The slug of the Feature Flag to target. */ + flagSlug: string; + /** The type of the target: `organization`, `user`, or the slug of a Flag Target Type registered for the project. */ + targetType: string; + /** The ID of the entity to target. For the built-in target types this is a WorkOS Organization or User ID; for a custom target type it is an identifier from your own domain model. */ + targetId: string; +} diff --git a/src/flag-targets/interfaces/create-flag-target.interface.ts b/src/flag-targets/interfaces/create-flag-target.interface.ts new file mode 100644 index 000000000..fd1a93b08 --- /dev/null +++ b/src/flag-targets/interfaces/create-flag-target.interface.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface CreateFlagTarget { + /** The slug of the Feature Flag to target. */ + flagSlug: string; + /** The type of the target: `organization`, `user`, or the slug of a Flag Target Type registered for the project. */ + targetType: string; + /** The ID of the entity to target. For the built-in target types this is a WorkOS Organization or User ID; for a custom target type it is an identifier from your own domain model. */ + targetId: string; +} + +export interface CreateFlagTargetResponse { + flag_slug: string; + target_type: string; + target_id: string; +} diff --git a/src/flag-targets/interfaces/delete-flag-target-options.interface.ts b/src/flag-targets/interfaces/delete-flag-target-options.interface.ts new file mode 100644 index 000000000..b17e3d215 --- /dev/null +++ b/src/flag-targets/interfaces/delete-flag-target-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface DeleteFlagTargetOptions { + /** Unique identifier of the Flag Target. */ + id: string; +} diff --git a/src/flag-targets/interfaces/flag-target.interface.ts b/src/flag-targets/interfaces/flag-target.interface.ts new file mode 100644 index 000000000..800d74dbe --- /dev/null +++ b/src/flag-targets/interfaces/flag-target.interface.ts @@ -0,0 +1,40 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface FlagTarget { + /** Distinguishes the Flag Target object. */ + object: 'flag_target'; + /** Unique identifier of the Flag Target. */ + id: string; + /** The ID of the Feature Flag the target belongs to. */ + flagId: string; + /** The slug of the Feature Flag the target belongs to, which is how the Feature Flag endpoints address it. */ + flagSlug: string; + /** The ID of the environment the Flag Target belongs to. */ + environmentId: string; + /** The type of the target: `organization`, `user`, or a custom target type slug. */ + targetType: string; + /** The ID of the targeted entity. */ + targetId: string; + /** The type of `value`. Only `boolean` is supported today; additional types are reserved for future multivariate Feature Flags. */ + valueType: 'boolean'; + /** The value the Feature Flag evaluates to for this target. */ + value: boolean; + /** An ISO 8601 timestamp. */ + createdAt: Date; + /** An ISO 8601 timestamp. */ + updatedAt: Date; +} + +export interface FlagTargetResponse { + object: 'flag_target'; + id: string; + flag_id: string; + flag_slug: string; + environment_id: string; + target_type: string; + target_id: string; + value_type: 'boolean'; + value: boolean; + created_at: string; + updated_at: string; +} diff --git a/src/flag-targets/interfaces/get-flag-target-options.interface.ts b/src/flag-targets/interfaces/get-flag-target-options.interface.ts new file mode 100644 index 000000000..ceb8ebbca --- /dev/null +++ b/src/flag-targets/interfaces/get-flag-target-options.interface.ts @@ -0,0 +1,6 @@ +// This file is auto-generated by oagen. Do not edit. + +export interface GetFlagTargetOptions { + /** Unique identifier of the Flag Target. */ + id: string; +} diff --git a/src/flag-targets/interfaces/index.ts b/src/flag-targets/interfaces/index.ts new file mode 100644 index 000000000..f8f1440bd --- /dev/null +++ b/src/flag-targets/interfaces/index.ts @@ -0,0 +1,8 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './create-flag-target-options.interface'; +export * from './create-flag-target.interface'; +export * from './delete-flag-target-options.interface'; +export * from './flag-target.interface'; +export * from './get-flag-target-options.interface'; +export * from './list-flag-targets-options.interface'; diff --git a/src/flag-targets/interfaces/list-flag-targets-options.interface.ts b/src/flag-targets/interfaces/list-flag-targets-options.interface.ts new file mode 100644 index 000000000..9240f2cb6 --- /dev/null +++ b/src/flag-targets/interfaces/list-flag-targets-options.interface.ts @@ -0,0 +1,12 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { PaginationOptions } from '../../common/interfaces/pagination-options.interface'; + +export interface ListFlagTargetsOptions extends PaginationOptions { + /** Filter Flag Targets by the slug of the Feature Flag they belong to. */ + flagSlug?: string; + /** Filter Flag Targets by the type of the targeted entity, to find every Feature Flag targeting entities of that type. */ + targetType?: string; + /** Filter Flag Targets by the ID of the targeted entity, to find every Feature Flag targeting it. */ + targetId?: string; +} diff --git a/src/flag-targets/serializers/create-flag-target.serializer.ts b/src/flag-targets/serializers/create-flag-target.serializer.ts new file mode 100644 index 000000000..1c8b1a3b4 --- /dev/null +++ b/src/flag-targets/serializers/create-flag-target.serializer.ts @@ -0,0 +1,14 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + CreateFlagTarget, + CreateFlagTargetResponse, +} from '../interfaces/create-flag-target.interface'; + +export const serializeCreateFlagTarget = ( + model: CreateFlagTarget, +): CreateFlagTargetResponse => ({ + flag_slug: model.flagSlug, + target_type: model.targetType, + target_id: model.targetId, +}); diff --git a/src/flag-targets/serializers/flag-target.serializer.ts b/src/flag-targets/serializers/flag-target.serializer.ts new file mode 100644 index 000000000..584371fe9 --- /dev/null +++ b/src/flag-targets/serializers/flag-target.serializer.ts @@ -0,0 +1,22 @@ +// This file is auto-generated by oagen. Do not edit. + +import type { + FlagTarget, + FlagTargetResponse, +} from '../interfaces/flag-target.interface'; + +export const deserializeFlagTarget = ( + response: FlagTargetResponse, +): FlagTarget => ({ + object: response.object, + id: response.id, + flagId: response.flag_id, + flagSlug: response.flag_slug, + environmentId: response.environment_id, + targetType: response.target_type, + targetId: response.target_id, + valueType: response.value_type, + value: response.value, + createdAt: new Date(response.created_at), + updatedAt: new Date(response.updated_at), +}); diff --git a/src/flag-targets/serializers/index.ts b/src/flag-targets/serializers/index.ts new file mode 100644 index 000000000..0f3bd54d5 --- /dev/null +++ b/src/flag-targets/serializers/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by oagen. Do not edit. + +export * from './create-flag-target.serializer'; +export * from './flag-target.serializer'; diff --git a/src/index.ts b/src/index.ts index f00652919..8025ea29a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,8 @@ export * from './directory-sync/interfaces'; export * from './events/interfaces'; export * from './feature-flags/interfaces'; export { FeatureFlagsRuntimeClient } from './feature-flags/runtime-client'; +export * from './flag-target-types/interfaces'; +export * from './flag-targets/interfaces'; export * from './groups/interfaces'; export * from './multi-factor-auth/interfaces'; export * from './organizations/interfaces'; diff --git a/src/index.worker.ts b/src/index.worker.ts index f1b0b4bbb..461da24e1 100644 --- a/src/index.worker.ts +++ b/src/index.worker.ts @@ -16,6 +16,8 @@ export * from './common/interfaces'; export * from './common/utils/pagination'; export * from './directory-sync/interfaces'; export * from './events/interfaces'; +export * from './flag-target-types/interfaces'; +export * from './flag-targets/interfaces'; export * from './organizations/interfaces'; export * from './organization-domains/interfaces'; export * from './passwordless/interfaces'; diff --git a/src/workos.ts b/src/workos.ts index 6f5c12bb8..6177aec48 100644 --- a/src/workos.ts +++ b/src/workos.ts @@ -38,6 +38,8 @@ import { AuditLogs } from './audit-logs/audit-logs'; import { UserManagement } from './user-management/user-management'; import { BadRequestException } from './common/exceptions/bad-request.exception'; import { FeatureFlags } from './feature-flags/feature-flags'; +import { FlagTargets } from './flag-targets/flag-targets'; +import { FlagTargetTypes } from './flag-target-types/flag-target-types'; import { Groups } from './groups/groups'; import { HttpClient, HttpClientError } from './common/net/http-client'; @@ -78,6 +80,8 @@ export class WorkOS { readonly connect = new Connect(this); readonly events = new Events(this); readonly featureFlags = new FeatureFlags(this); + readonly flagTargets = new FlagTargets(this); + readonly flagTargetTypes = new FlagTargetTypes(this); readonly groups = new Groups(this); readonly multiFactorAuth = new MultiFactorAuth(this); readonly organizations = new Organizations(this);