Files
GibSend/packages/sdk/src/email.ts
T
2025-11-17 11:42:09 +11:00

154 lines
4.0 KiB
TypeScript

import { render } from "@react-email/render";
import * as React from "react";
import { UseSend } from "./usesend";
import { paths } from "../types/schema";
import { ErrorResponse } from "../types";
type SendEmailPayload =
paths["/v1/emails"]["post"]["requestBody"]["content"]["application/json"] & {
react?: React.ReactElement;
};
type CreateEmailResponse = {
data: CreateEmailResponseSuccess | null;
error: ErrorResponse | null;
};
type CreateEmailResponseSuccess =
paths["/v1/emails"]["post"]["responses"]["200"]["content"]["application/json"];
type GetEmailResponseSuccess =
paths["/v1/emails/{emailId}"]["get"]["responses"]["200"]["content"]["application/json"];
type GetEmailResponse = {
data: GetEmailResponseSuccess | null;
error: ErrorResponse | null;
};
type UpdateEmailPayload =
paths["/v1/emails/{emailId}"]["patch"]["requestBody"]["content"]["application/json"] & {
react?: React.ReactElement;
};
type UpdateEmailResponse = {
data: UpdateEmailResponseSuccess | null;
error: ErrorResponse | null;
};
type UpdateEmailResponseSuccess =
paths["/v1/emails/{emailId}"]["patch"]["responses"]["200"]["content"]["application/json"];
type CancelEmailResponse = {
data: CancelEmailResponseSuccess | null;
error: ErrorResponse | null;
};
type CancelEmailResponseSuccess =
paths["/v1/emails/{emailId}/cancel"]["post"]["responses"]["200"]["content"]["application/json"];
// Batch emails types
/**
* Payload for sending multiple emails in a single batch request.
*/
type BatchEmailPayload =
paths["/v1/emails/batch"]["post"]["requestBody"]["content"]["application/json"];
/**
* Successful response schema for batch email send.
*/
type BatchEmailResponseSuccess =
paths["/v1/emails/batch"]["post"]["responses"]["200"]["content"]["application/json"];
/**
* Response structure for the batch method.
*/
type BatchEmailResponse = {
data: BatchEmailResponseSuccess["data"] | null;
error: ErrorResponse | null;
};
type EmailRequestOptions = {
idempotencyKey?: string;
};
export class Emails {
constructor(private readonly usesend: UseSend) {
this.usesend = usesend;
}
async send(payload: SendEmailPayload, options?: EmailRequestOptions) {
return this.create(payload, options);
}
async create(
payload: SendEmailPayload,
options?: EmailRequestOptions,
): Promise<CreateEmailResponse> {
if (payload.react) {
payload.html = await render(payload.react as React.ReactElement);
delete payload.react;
}
const data = await this.usesend.post<CreateEmailResponseSuccess>(
"/emails",
payload,
options?.idempotencyKey
? { headers: { "Idempotency-Key": options.idempotencyKey } }
: undefined,
);
return data;
}
/**
* Send up to 100 emails in a single request.
*
* @param payload An array of email payloads. Max 100 emails.
* @returns A promise that resolves to the list of created email IDs or an error.
*/
async batch(
payload: BatchEmailPayload,
options?: EmailRequestOptions,
): Promise<BatchEmailResponse> {
// Note: React element rendering is not supported in batch mode.
const response = await this.usesend.post<BatchEmailResponseSuccess>(
"/emails/batch",
payload,
options?.idempotencyKey
? { headers: { "Idempotency-Key": options.idempotencyKey } }
: undefined,
);
return {
data: response.data ? response.data.data : null,
error: response.error,
};
}
async get(id: string): Promise<GetEmailResponse> {
const data = await this.usesend.get<GetEmailResponseSuccess>(
`/emails/${id}`
);
return data;
}
async update(
id: string,
payload: UpdateEmailPayload
): Promise<UpdateEmailResponse> {
const data = await this.usesend.patch<UpdateEmailResponseSuccess>(
`/emails/${id}`,
payload
);
return data;
}
async cancel(id: string): Promise<CancelEmailResponse> {
const data = await this.usesend.post<CancelEmailResponseSuccess>(
`/emails/${id}/cancel`,
{}
);
return data;
}
}