Skip to content

Commit b8a0e2e

Browse files
committed
feat(backend): Add waitlist entries to Backend API client
1 parent a7fc1d6 commit b8a0e2e

File tree

9 files changed

+126
-4
lines changed

9 files changed

+126
-4
lines changed

.changeset/thick-showers-drop.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@clerk/backend': patch
3+
---
4+
5+
Adds the ability to list and create waitlist entries to the Backend API client.
6+
7+
8+
```ts
9+
import { createClerkClient } from '@clerk/backend';
10+
11+
const clerkClient = createClerkClient(...);
12+
13+
await clerkClient.waitlistEntries.list({...});
14+
await clerkClient.waitlistEntries.create({
15+
emailAddress: '[email protected]',
16+
notify: true
17+
});
18+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { ClerkPaginationRequest } from '@clerk/types';
2+
3+
import type { PaginatedResourceResponse } from '../resources/Deserializer';
4+
import type { WaitlistEntryStatus } from '../resources/Enums';
5+
import type { WaitlistEntry } from '../resources/WaitlistEntry';
6+
import { AbstractAPI } from './AbstractApi';
7+
import type { WithSign } from './util-types';
8+
9+
const basePath = '/waitlist_entries';
10+
11+
type WaitlistEntryListParams = ClerkPaginationRequest<{
12+
/**
13+
* Filter waitlist entries by `email_address` or `id`
14+
*/
15+
query?: string;
16+
status?: WaitlistEntryStatus;
17+
orderBy?: WithSign<'created_at' | 'invited_at' | 'email_address'>;
18+
}>;
19+
20+
type WaitlistEntryCreateParams = {
21+
emailAddress: string;
22+
notify?: boolean;
23+
};
24+
25+
export class WaitlistEntryAPI extends AbstractAPI {
26+
public async list(params: WaitlistEntryListParams = {}) {
27+
return this.request<PaginatedResourceResponse<WaitlistEntry>>({
28+
method: 'GET',
29+
path: basePath,
30+
queryParams: params,
31+
});
32+
}
33+
34+
public async create(params: WaitlistEntryCreateParams) {
35+
return this.request<WaitlistEntry>({
36+
method: 'POST',
37+
path: basePath,
38+
bodyParams: params,
39+
});
40+
}
41+
}

packages/backend/src/api/endpoints/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ export * from './SignInTokenApi';
1313
export * from './UserApi';
1414
export * from './SamlConnectionApi';
1515
export * from './TestingTokenApi';
16+
export * from './WaitlistEntryApi';

packages/backend/src/api/factory.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SignInTokenAPI,
1414
TestingTokenAPI,
1515
UserAPI,
16+
WaitlistEntryAPI,
1617
} from './endpoints';
1718
import { buildRequest } from './request';
1819

@@ -40,5 +41,6 @@ export function createBackendApiClient(options: CreateBackendApiOptions) {
4041
domains: new DomainAPI(request),
4142
samlConnections: new SamlConnectionAPI(request),
4243
testingTokens: new TestingTokenAPI(request),
44+
waitlistEntries: new WaitlistEntryAPI(request),
4345
};
4446
}

packages/backend/src/api/resources/Deserializer.ts

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { AccountlessApplication } from './AccountlessApplication';
2222
import type { PaginatedResponseJSON } from './JSON';
2323
import { ObjectType } from './JSON';
24+
import { WaitlistEntry } from './WaitlistEntry';
2425

2526
type ResourceResponse<T> = {
2627
data: T;
@@ -105,6 +106,8 @@ function jsonToObject(item: any): any {
105106
return getCount(item);
106107
case ObjectType.User:
107108
return User.fromJSON(item);
109+
case ObjectType.WaitlistEntry:
110+
return WaitlistEntry.fromJSON(item);
108111
default:
109112
return item;
110113
}

packages/backend/src/api/resources/Enums.ts

+2
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ export type SignInStatus = 'needs_identifier' | 'needs_factor_one' | 'needs_fact
3636
export type SignUpStatus = 'missing_requirements' | 'complete' | 'abandoned';
3737

3838
export type InvitationStatus = 'pending' | 'accepted' | 'revoked' | 'expired';
39+
40+
export type WaitlistEntryStatus = 'pending' | 'invited' | 'completed' | 'rejected';

packages/backend/src/api/resources/JSON.ts

+31-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
OrganizationMembershipRole,
88
SignInStatus,
99
SignUpStatus,
10+
WaitlistEntryStatus,
1011
} from './Enums';
1112

1213
export const ObjectType = {
@@ -385,13 +386,13 @@ export interface VerificationJSON extends ClerkResourceJSON {
385386
}
386387

387388
export interface WaitlistEntryJSON extends ClerkResourceJSON {
388-
created_at: number;
389-
email_address: string;
389+
object: typeof ObjectType.WaitlistEntry;
390390
id: string;
391+
status: WaitlistEntryStatus;
392+
email_address: string;
391393
invitation: InvitationJSON | null;
392394
is_locked: boolean;
393-
object: typeof ObjectType.WaitlistEntry;
394-
status: string;
395+
created_at: number;
395396
updated_at: number;
396397
}
397398

@@ -482,3 +483,29 @@ export interface SamlAccountConnectionJSON extends ClerkResourceJSON {
482483
created_at: number;
483484
updated_at: number;
484485
}
486+
487+
// export type WaitlistEntry = {
488+
// object: WaitlistEntryObject;
489+
// id: string;
490+
// emailAddress: string;
491+
// status: WaitlistEntryStatus;
492+
// /**
493+
// * Indicates if the waitlist entry is locked. Locked entries are being processed in a batch action and are unavailable for other actions.
494+
// *
495+
// * @remarks
496+
// */
497+
// isLocked?: boolean | undefined;
498+
// /**
499+
// * Unix timestamp of creation.
500+
// *
501+
// * @remarks
502+
// */
503+
// createdAt: number;
504+
// /**
505+
// * Unix timestamp of last update.
506+
// *
507+
// * @remarks
508+
// */
509+
// updatedAt: number;
510+
// invitation?: WaitlistEntryInvitation | null | undefined;
511+
// };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { WaitlistEntryStatus } from './Enums';
2+
import { Invitation } from './Invitation';
3+
import type { WaitlistEntryJSON } from './JSON';
4+
5+
export class WaitlistEntry {
6+
constructor(
7+
readonly id: string,
8+
readonly emailAddress: string,
9+
readonly status: WaitlistEntryStatus,
10+
readonly invitation: Invitation | null,
11+
readonly createdAt: number,
12+
readonly updatedAt: number,
13+
readonly isLocked?: boolean,
14+
) {}
15+
16+
static fromJSON(data: WaitlistEntryJSON): WaitlistEntry {
17+
return new WaitlistEntry(
18+
data.id,
19+
data.email_address,
20+
data.status,
21+
data.invitation && Invitation.fromJSON(data.invitation),
22+
data.created_at,
23+
data.updated_at,
24+
data.is_locked,
25+
);
26+
}
27+
}

packages/backend/src/api/resources/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export * from './User';
3434
export * from './Verification';
3535
export * from './SamlConnection';
3636
export * from './TestingToken';
37+
export * from './WaitlistEntry';
3738

3839
export type {
3940
EmailWebhookEvent,

0 commit comments

Comments
 (0)