Skip to content

Commit 9531fa8

Browse files
authored
Add GET /user_management/users/:id/feature-flags support (#1364)
## Description - Add GET /user_management/users/:id/feature-flags support with a `listFeatureFlags` method on the users module ## Documentation Does this require changes to the WorkOS Docs? E.g. the [API Reference](https://workos.com/docs/reference) or code snippets need updates. ``` [x] Yes ``` If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.
1 parent 0154166 commit 9531fa8

File tree

9 files changed

+183
-3
lines changed

9 files changed

+183
-3
lines changed

src/organizations/interfaces/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export * from './create-organization-options.interface';
22
export * from './domain-data.interface';
3-
export * from './feature-flag.interface';
43
export * from './list-organization-feature-flags-options.interface';
54
export * from './list-organizations-options.interface';
65
export * from './organization.interface';

src/organizations/organizations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import {
1212
FeatureFlag,
1313
FeatureFlagResponse,
14-
} from './interfaces/feature-flag.interface';
14+
} from '../feature-flags/interfaces/feature-flag.interface';
1515
import {
1616
deserializeOrganization,
1717
serializeCreateOrganizationOptions,
@@ -23,7 +23,7 @@ import { ListOrganizationRolesResponse, RoleList } from '../roles/interfaces';
2323
import { deserializeRole } from '../roles/serializers/role.serializer';
2424
import { ListOrganizationRolesOptions } from './interfaces/list-organization-roles-options.interface';
2525
import { ListOrganizationFeatureFlagsOptions } from './interfaces/list-organization-feature-flags-options.interface';
26-
import { deserializeFeatureFlag } from './serializers/feature-flag.serializer';
26+
import { deserializeFeatureFlag } from '../feature-flags/serializers/feature-flag.serializer';
2727

2828
export class Organizations {
2929
constructor(private readonly workos: WorkOS) {}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"object": "list",
3+
"data": [
4+
{
5+
"object": "feature_flag",
6+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C5",
7+
"name": "Advanced Dashboard",
8+
"slug": "advanced-dashboard",
9+
"description": "Enable advanced dashboard features",
10+
"created_at": "2024-01-01T00:00:00.000Z",
11+
"updated_at": "2024-01-01T00:00:00.000Z"
12+
},
13+
{
14+
"object": "feature_flag",
15+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C6",
16+
"name": "Beta Features",
17+
"slug": "beta-features",
18+
"description": null,
19+
"created_at": "2024-01-01T00:00:00.000Z",
20+
"updated_at": "2024-01-01T00:00:00.000Z"
21+
},
22+
{
23+
"object": "feature_flag",
24+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C7",
25+
"name": "Premium Support",
26+
"slug": "premium-support",
27+
"description": "Access to premium support features",
28+
"created_at": "2024-01-01T00:00:00.000Z",
29+
"updated_at": "2024-01-01T00:00:00.000Z"
30+
}
31+
],
32+
"list_metadata": {}
33+
}

src/user-management/interfaces/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export * from './list-auth-factors-options.interface';
2626
export * from './list-invitations-options.interface';
2727
export * from './list-organization-memberships-options.interface';
2828
export * from './list-sessions-options.interface';
29+
export * from './list-user-feature-flags-options.interface';
2930
export * from './list-users-options.interface';
3031
export * from './magic-auth.interface';
3132
export * from './oauth-tokens.interface';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { PaginationOptions } from '../../common/interfaces';
2+
3+
export interface ListUserFeatureFlagsOptions extends PaginationOptions {
4+
userId: string;
5+
}

src/user-management/user-management.spec.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import listFactorFixture from './fixtures/list-factors.json';
1313
import listInvitationsFixture from './fixtures/list-invitations.json';
1414
import listOrganizationMembershipsFixture from './fixtures/list-organization-memberships.json';
1515
import listSessionsFixture from './fixtures/list-sessions.json';
16+
import listUserFeatureFlagsFixture from './fixtures/list-user-feature-flags.json';
1617
import listUsersFixture from './fixtures/list-users.json';
1718
import magicAuthFixture from './fixtures/magic_auth.json';
1819
import organizationMembershipFixture from './fixtures/organization-membership.json';
@@ -1602,6 +1603,118 @@ describe('UserManagement', () => {
16021603
});
16031604
});
16041605

1606+
describe('listUserFeatureFlags', () => {
1607+
it('returns feature flags for the user', async () => {
1608+
fetchOnce(listUserFeatureFlagsFixture);
1609+
1610+
const { data, object, listMetadata } =
1611+
await workos.userManagement.listUserFeatureFlags({ userId });
1612+
1613+
expect(fetchURL()).toContain(
1614+
`/user_management/users/${userId}/feature-flags`,
1615+
);
1616+
1617+
expect(object).toEqual('list');
1618+
expect(listMetadata).toEqual({});
1619+
expect(data).toHaveLength(3);
1620+
expect(data).toEqual([
1621+
{
1622+
object: 'feature_flag',
1623+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C5',
1624+
name: 'Advanced Dashboard',
1625+
slug: 'advanced-dashboard',
1626+
description: 'Enable advanced dashboard features',
1627+
createdAt: '2024-01-01T00:00:00.000Z',
1628+
updatedAt: '2024-01-01T00:00:00.000Z',
1629+
},
1630+
{
1631+
object: 'feature_flag',
1632+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C6',
1633+
name: 'Beta Features',
1634+
slug: 'beta-features',
1635+
description: null,
1636+
createdAt: '2024-01-01T00:00:00.000Z',
1637+
updatedAt: '2024-01-01T00:00:00.000Z',
1638+
},
1639+
{
1640+
object: 'feature_flag',
1641+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C7',
1642+
name: 'Premium Support',
1643+
slug: 'premium-support',
1644+
description: 'Access to premium support features',
1645+
createdAt: '2024-01-01T00:00:00.000Z',
1646+
updatedAt: '2024-01-01T00:00:00.000Z',
1647+
},
1648+
]);
1649+
});
1650+
1651+
describe('with the before option', () => {
1652+
it('forms the proper request to the API', async () => {
1653+
fetchOnce(listUserFeatureFlagsFixture);
1654+
1655+
const { data } = await workos.userManagement.listUserFeatureFlags({
1656+
userId,
1657+
before: 'flag_before_id',
1658+
});
1659+
1660+
expect(fetchSearchParams()).toEqual({
1661+
before: 'flag_before_id',
1662+
order: 'desc',
1663+
});
1664+
1665+
expect(fetchURL()).toContain(
1666+
`/user_management/users/${userId}/feature-flags`,
1667+
);
1668+
1669+
expect(data).toHaveLength(3);
1670+
});
1671+
});
1672+
1673+
describe('with the after option', () => {
1674+
it('forms the proper request to the API', async () => {
1675+
fetchOnce(listUserFeatureFlagsFixture);
1676+
1677+
const { data } = await workos.userManagement.listUserFeatureFlags({
1678+
userId,
1679+
after: 'flag_after_id',
1680+
});
1681+
1682+
expect(fetchSearchParams()).toEqual({
1683+
after: 'flag_after_id',
1684+
order: 'desc',
1685+
});
1686+
1687+
expect(fetchURL()).toContain(
1688+
`/user_management/users/${userId}/feature-flags`,
1689+
);
1690+
1691+
expect(data).toHaveLength(3);
1692+
});
1693+
});
1694+
1695+
describe('with the limit option', () => {
1696+
it('forms the proper request to the API', async () => {
1697+
fetchOnce(listUserFeatureFlagsFixture);
1698+
1699+
const { data } = await workos.userManagement.listUserFeatureFlags({
1700+
userId,
1701+
limit: 3,
1702+
});
1703+
1704+
expect(fetchSearchParams()).toEqual({
1705+
limit: '3',
1706+
order: 'desc',
1707+
});
1708+
1709+
expect(fetchURL()).toContain(
1710+
`/user_management/users/${userId}/feature-flags`,
1711+
);
1712+
1713+
expect(data).toHaveLength(3);
1714+
});
1715+
});
1716+
});
1717+
16051718
describe('listSessions', () => {
16061719
it('sends a listSessions request', async () => {
16071720
fetchOnce(listSessionsFixture);

src/user-management/user-management.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { fetchAndDeserialize } from '../common/utils/fetch-and-deserialize';
66
import { AutoPaginatable } from '../common/utils/pagination';
77
import { Challenge, ChallengeResponse } from '../mfa/interfaces';
88
import { deserializeChallenge } from '../mfa/serializers';
9+
import {
10+
FeatureFlag,
11+
FeatureFlagResponse,
12+
} from '../feature-flags/interfaces/feature-flag.interface';
13+
import { deserializeFeatureFlag } from '../feature-flags/serializers/feature-flag.serializer';
914
import { WorkOS } from '../workos';
1015
import {
1116
AuthenticateWithCodeOptions,
@@ -26,6 +31,7 @@ import {
2631
ListAuthFactorsOptions,
2732
ListSessionsOptions,
2833
ListUsersOptions,
34+
ListUserFeatureFlagsOptions,
2935
MagicAuth,
3036
MagicAuthResponse,
3137
PasswordReset,
@@ -821,6 +827,29 @@ export class UserManagement {
821827
);
822828
}
823829

830+
async listUserFeatureFlags(
831+
options: ListUserFeatureFlagsOptions,
832+
): Promise<AutoPaginatable<FeatureFlag>> {
833+
const { userId, ...paginationOptions } = options;
834+
835+
return new AutoPaginatable(
836+
await fetchAndDeserialize<FeatureFlagResponse, FeatureFlag>(
837+
this.workos,
838+
`/user_management/users/${userId}/feature-flags`,
839+
deserializeFeatureFlag,
840+
paginationOptions,
841+
),
842+
(params) =>
843+
fetchAndDeserialize<FeatureFlagResponse, FeatureFlag>(
844+
this.workos,
845+
`/user_management/users/${userId}/feature-flags`,
846+
deserializeFeatureFlag,
847+
params,
848+
),
849+
paginationOptions,
850+
);
851+
}
852+
824853
async listSessions(
825854
userId: string,
826855
options?: ListSessionsOptions,

0 commit comments

Comments
 (0)