Skip to content

Commit

Permalink
feat(clerk-js,types): Introduce UserOrganizationInvitation
Browse files Browse the repository at this point in the history
+ UserOrganizationInvitationResource
+ UserOrganizationInvitationJSON
+ ClerkPaginatedResponse that handles FAPI paginated responses
  • Loading branch information
panteliselef committed Aug 1, 2023
1 parent aad6351 commit 5e1a09d
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .changeset/shaggy-vans-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@clerk/clerk-js': patch
'@clerk/types': patch
---

Introduces a new internal class `UserOrganizationInvitation` that represents and invitation to join an organization with the organization data populated
Additions to support the above
- UserOrganizationInvitationResource
- UserOrganizationInvitationJSON
- ClerkPaginatedResponse

ClerkPaginatedResponse represents a paginated FAPI response
6 changes: 6 additions & 0 deletions packages/clerk-js/src/core/resources/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
EmailAddressResource,
ExternalAccountJSON,
ExternalAccountResource,
GetUserOrganizationInvitationsParams,
ImageResource,
OrganizationMembershipResource,
PhoneNumberResource,
Expand Down Expand Up @@ -42,6 +43,7 @@ import {
SamlAccount,
SessionWithActivities,
TOTP,
UserOrganizationInvitation,
Web3Wallet,
} from './internal';

Expand Down Expand Up @@ -250,6 +252,10 @@ export class User extends BaseResource implements UserResource {
});
};

getOrganizationInvitations = (params?: GetUserOrganizationInvitationsParams) => {
return UserOrganizationInvitation.retrieve(params);
};

getOrganizationMemberships = async (
retrieveMembership: RetrieveMembershipsParams,
): Promise<OrganizationMembership[]> => {
Expand Down
64 changes: 64 additions & 0 deletions packages/clerk-js/src/core/resources/UserOrganizationInvitation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type {
ClerkPaginatedResponse,
GetUserOrganizationInvitationsParams,
MembershipRole,
OrganizationInvitationStatus,
OrganizationResource,
UserOrganizationInvitationJSON,
UserOrganizationInvitationResource,
} from '@clerk/types';

import { unixEpochToDate } from '../../utils/date';
import { BaseResource, Organization } from './internal';

export class UserOrganizationInvitation extends BaseResource implements UserOrganizationInvitationResource {
id!: string;
emailAddress!: string;
organization!: OrganizationResource;
publicMetadata: OrganizationInvitationPublicMetadata = {};
status!: OrganizationInvitationStatus;
role!: MembershipRole;
createdAt!: Date;
updatedAt!: Date;

static async retrieve(
params?: GetUserOrganizationInvitationsParams,
): Promise<ClerkPaginatedResponse<UserOrganizationInvitation>> {
return await BaseResource._fetch({
path: '/me/organization_invitations',
method: 'GET',
search: params as any,
})
.then(res => {
const { data: invites, total_count } =
res?.response as unknown as ClerkPaginatedResponse<UserOrganizationInvitationJSON>;

return {
total_count,
data: invites.map(invitation => new UserOrganizationInvitation(invitation)),
};
})
.catch(() => ({
total_count: 0,
data: [],
}));
}

constructor(data: UserOrganizationInvitationJSON) {
super();
this.fromJSON(data);
}
protected fromJSON(data: UserOrganizationInvitationJSON | null): this {
if (data) {
this.id = data.id;
this.emailAddress = data.email_address;
this.organization = new Organization(data.organization);
this.publicMetadata = data.public_metadata;
this.role = data.role;
this.status = data.status;
this.createdAt = unixEpochToDate(data.created_at);
this.updatedAt = unixEpochToDate(data.updated_at);
}
return this;
}
}
1 change: 1 addition & 0 deletions packages/clerk-js/src/core/resources/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export * from './SignUp';
export * from './Token';
export * from './TOTP';
export * from './User';
export * from './UserOrganizationInvitation';
export * from './Verification';
export * from './Web3Wallet';
8 changes: 8 additions & 0 deletions packages/types/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ export interface ClerkPaginationParams {
limit?: number;
offset?: number;
}

/**
* Pagination params
*/
export interface ClerkPaginatedResponse<T> {
data: T[];
total_count: number;
}
1 change: 1 addition & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export * from './theme';
export * from './token';
export * from './totp';
export * from './user';
export * from './userOrganizationInvitation';
export * from './userSettings';
export * from './utils';
export * from './verification';
Expand Down
12 changes: 12 additions & 0 deletions packages/types/src/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,18 @@ export interface OrganizationInvitationJSON extends ClerkResourceJSON {
updated_at: number;
}

export interface UserOrganizationInvitationJSON extends ClerkResourceJSON {
object: 'organization_invitation';
id: string;
email_address: string;
organization: OrganizationJSON;
public_metadata: OrganizationInvitationPublicMetadata;
status: OrganizationInvitationStatus;
role: MembershipRole;
created_at: number;
updated_at: number;
}

export interface UserDataJSON {
first_name?: string;
last_name?: string;
Expand Down
7 changes: 7 additions & 0 deletions packages/types/src/user.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ClerkPaginatedResponse, ClerkPaginationParams } from './api';
import type { BackupCodeResource } from './backupCode';
import type { DeletedObjectResource } from './deletedObject';
import type { EmailAddressResource } from './emailAddress';
Expand All @@ -12,6 +13,7 @@ import type { SamlAccountResource } from './samlAccount';
import type { SessionWithActivitiesResource } from './session';
import type { OAuthStrategy } from './strategies';
import type { TOTPResource } from './totp';
import type { UserOrganizationInvitationResource } from './userOrganizationInvitation';
import type { SnakeToCamel } from './utils';
import type { Web3WalletResource } from './web3Wallet';

Expand Down Expand Up @@ -93,6 +95,9 @@ export interface UserResource extends ClerkResource {
getSessions: () => Promise<SessionWithActivitiesResource[]>;
setProfileImage: (params: SetProfileImageParams) => Promise<ImageResource>;
createExternalAccount: (params: CreateExternalAccountParams) => Promise<ExternalAccountResource>;
getOrganizationInvitations: (
params?: GetUserOrganizationInvitationsParams,
) => Promise<ClerkPaginatedResponse<UserOrganizationInvitationResource>>;
createTOTP: () => Promise<TOTPResource>;
verifyTOTP: (params: VerifyTOTPParams) => Promise<TOTPResource>;
disableTOTP: () => Promise<DeletedObjectResource>;
Expand Down Expand Up @@ -150,3 +155,5 @@ export type UpdateUserPasswordParams = {
};

export type RemoveUserPasswordParams = Pick<UpdateUserPasswordParams, 'currentPassword'>;

export type GetUserOrganizationInvitationsParams = ClerkPaginationParams;
30 changes: 30 additions & 0 deletions packages/types/src/userOrganizationInvitation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { OrganizationResource } from './organization';
import type { OrganizationInvitationStatus } from './organizationInvitation';
import type { MembershipRole } from './organizationMembership';
import type { ClerkResource } from './resource';

declare global {
/**
* If you want to provide custom types for the organizationInvitation.publicMetadata
* object, simply redeclare this rule in the global namespace.
* Every organizationInvitation object will use the provided type.
*/
interface UserOrganizationInvitationPublicMetadata {
[k: string]: unknown;
}

interface UserOrganizationInvitationPrivateMetadata {
[k: string]: unknown;
}
}

export interface UserOrganizationInvitationResource extends ClerkResource {
id: string;
emailAddress: string;
organization: OrganizationResource;
publicMetadata: UserOrganizationInvitationPublicMetadata;
role: MembershipRole;
status: OrganizationInvitationStatus;
createdAt: Date;
updatedAt: Date;
}

0 comments on commit 5e1a09d

Please sign in to comment.