Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/thick-showers-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@clerk/backend': patch
---

Adds the ability to list and create waitlist entries to the Backend API client.


```ts
import { createClerkClient } from '@clerk/backend';

const clerkClient = createClerkClient(...);

await clerkClient.waitlistEntries.list({...});
await clerkClient.waitlistEntries.create({
emailAddress: 'you@yourdomain.com',
notify: true
});
```
41 changes: 41 additions & 0 deletions packages/backend/src/api/endpoints/WaitlistEntryApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ClerkPaginationRequest } from '@clerk/types';

import type { PaginatedResourceResponse } from '../resources/Deserializer';
import type { WaitlistEntryStatus } from '../resources/Enums';
import type { WaitlistEntry } from '../resources/WaitlistEntry';
import { AbstractAPI } from './AbstractApi';
import type { WithSign } from './util-types';

const basePath = '/waitlist_entries';

type WaitlistEntryListParams = ClerkPaginationRequest<{
/**
* Filter waitlist entries by `email_address` or `id`
*/
query?: string;
status?: WaitlistEntryStatus;
orderBy?: WithSign<'created_at' | 'invited_at' | 'email_address'>;
Comment thread
tmilewski marked this conversation as resolved.
}>;

type WaitlistEntryCreateParams = {
emailAddress: string;
notify?: boolean;
};

export class WaitlistEntryAPI extends AbstractAPI {
public async list(params: WaitlistEntryListParams = {}) {
return this.request<PaginatedResourceResponse<WaitlistEntry>>({
method: 'GET',
path: basePath,
queryParams: params,
});
}

public async create(params: WaitlistEntryCreateParams) {
return this.request<WaitlistEntry>({
method: 'POST',
path: basePath,
bodyParams: params,
});
}
}
1 change: 1 addition & 0 deletions packages/backend/src/api/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ export * from './SessionApi';
export * from './SignInTokenApi';
export * from './TestingTokenApi';
export * from './UserApi';
export * from './WaitlistEntryApi';
export * from './WebhookApi';
2 changes: 2 additions & 0 deletions packages/backend/src/api/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
SignInTokenAPI,
TestingTokenAPI,
UserAPI,
WaitlistEntryAPI,
WebhookAPI,
} from './endpoints';
import { buildRequest } from './request';
Expand Down Expand Up @@ -55,6 +56,7 @@ export function createBackendApiClient(options: CreateBackendApiOptions) {
signInTokens: new SignInTokenAPI(request),
testingTokens: new TestingTokenAPI(request),
users: new UserAPI(request),
waitlistEntries: new WaitlistEntryAPI(request),
webhooks: new WebhookAPI(request),
};
}
3 changes: 3 additions & 0 deletions packages/backend/src/api/resources/Deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
import { AccountlessApplication } from './AccountlessApplication';
import type { PaginatedResponseJSON } from './JSON';
import { ObjectType } from './JSON';
import { WaitlistEntry } from './WaitlistEntry';

type ResourceResponse<T> = {
data: T;
Expand Down Expand Up @@ -135,6 +136,8 @@ function jsonToObject(item: any): any {
return getCount(item);
case ObjectType.User:
return User.fromJSON(item);
case ObjectType.WaitlistEntry:
return WaitlistEntry.fromJSON(item);
default:
return item;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/api/resources/Enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ export type ActorTokenStatus = (typeof ActorTokenStatus)[keyof typeof ActorToken
export type AllowlistIdentifierType = 'email_address' | 'phone_number' | 'web3_wallet';

export type BlocklistIdentifierType = AllowlistIdentifierType;

export type WaitlistEntryStatus = 'pending' | 'invited' | 'completed' | 'rejected';
9 changes: 5 additions & 4 deletions packages/backend/src/api/resources/JSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
OrganizationMembershipRole,
SignInStatus,
SignUpStatus,
WaitlistEntryStatus,
} from './Enums';

export const ObjectType = {
Expand Down Expand Up @@ -543,13 +544,13 @@ export interface VerificationJSON extends ClerkResourceJSON {
}

export interface WaitlistEntryJSON extends ClerkResourceJSON {
created_at: number;
email_address: string;
object: typeof ObjectType.WaitlistEntry;
id: string;
status: WaitlistEntryStatus;
email_address: string;
invitation: InvitationJSON | null;
is_locked: boolean;
object: typeof ObjectType.WaitlistEntry;
status: string;
created_at: number;
updated_at: number;
}

Expand Down
27 changes: 27 additions & 0 deletions packages/backend/src/api/resources/WaitlistEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { WaitlistEntryStatus } from './Enums';
import { Invitation } from './Invitation';
import type { WaitlistEntryJSON } from './JSON';

export class WaitlistEntry {
constructor(
readonly id: string,
readonly emailAddress: string,
readonly status: WaitlistEntryStatus,
readonly invitation: Invitation | null,
readonly createdAt: number,
readonly updatedAt: number,
readonly isLocked?: boolean,
) {}

static fromJSON(data: WaitlistEntryJSON): WaitlistEntry {
return new WaitlistEntry(
data.id,
data.email_address,
data.status,
data.invitation && Invitation.fromJSON(data.invitation),
data.created_at,
data.updated_at,
data.is_locked,
);
}
}
1 change: 1 addition & 0 deletions packages/backend/src/api/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export * from './User';
export * from './Verification';
export * from './SamlConnection';
export * from './TestingToken';
export * from './WaitlistEntry';

export type {
EmailWebhookEvent,
Expand Down