diff --git a/package.json b/package.json index 9a30e42e..4fa298df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "resend", - "version": "6.18.1", + "version": "6.19.0", "description": "Node.js library for the Resend API", "main": "./dist/index.cjs", "module": "./dist/index.mjs", diff --git a/src/broadcasts/broadcasts.spec.ts b/src/broadcasts/broadcasts.spec.ts index cf19bbed..567cf7e2 100644 --- a/src/broadcasts/broadcasts.spec.ts +++ b/src/broadcasts/broadcasts.spec.ts @@ -2,6 +2,7 @@ import createFetchMock from 'vitest-fetch-mock'; import type { ErrorResponse } from '../interfaces'; import { Resend } from '../resend'; import { mockSuccessResponse } from '../test-utils/mock-fetch'; +import type { CancelBroadcastResponseSuccess } from './interfaces/cancel-broadcast.interface'; import type { CreateBroadcastOptions, CreateBroadcastResponseSuccess, @@ -629,6 +630,76 @@ describe('Broadcasts', () => { }); }); + describe('cancel', () => { + it('cancels a broadcast', async () => { + const id = 'b01e0de9-7c27-4a53-bf38-2e3f98389a65'; + const response: CancelBroadcastResponseSuccess = { + object: 'broadcast', + id, + }; + fetchMock.mockOnce(JSON.stringify(response), { + status: 200, + headers: { + 'content-type': 'application/json', + }, + }); + + const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop'); + + await expect( + resend.broadcasts.cancel(id), + ).resolves.toMatchInlineSnapshot(` + { + "data": { + "id": "b01e0de9-7c27-4a53-bf38-2e3f98389a65", + "object": "broadcast", + }, + "error": null, + "headers": { + "content-type": "application/json", + }, + } + `); + }); + + describe('when broadcast is not cancelable', () => { + it('returns error', async () => { + const response: ErrorResponse = { + name: 'validation_error', + statusCode: 403, + message: 'Only queued or scheduled broadcasts can be canceled', + }; + + fetchMock.mockOnce(JSON.stringify(response), { + status: 403, + headers: { + 'content-type': 'application/json', + }, + }); + + const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop'); + + const result = resend.broadcasts.cancel( + '559ac32e-9ef5-46fb-82a1-b76b840c0f7b', + ); + + await expect(result).resolves.toMatchInlineSnapshot(` + { + "data": null, + "error": { + "message": "Only queued or scheduled broadcasts can be canceled", + "name": "validation_error", + "statusCode": 403, + }, + "headers": { + "content-type": "application/json", + }, + } + `); + }); + }); + }); + describe('update', () => { it('updates a broadcast', async () => { const id = 'b01e0de9-7c27-4a53-bf38-2e3f98389a65'; diff --git a/src/broadcasts/broadcasts.ts b/src/broadcasts/broadcasts.ts index 6487eabe..910dd718 100644 --- a/src/broadcasts/broadcasts.ts +++ b/src/broadcasts/broadcasts.ts @@ -1,6 +1,10 @@ import { buildPaginationUrl } from '../common/utils/build-pagination-query'; import { render } from '../render'; import type { Resend } from '../resend'; +import type { + CancelBroadcastResponse, + CancelBroadcastResponseSuccess, +} from './interfaces/cancel-broadcast.interface'; import type { CreateBroadcastOptions, CreateBroadcastRequestOptions, @@ -95,6 +99,13 @@ export class Broadcasts { return data; } + async cancel(id: string): Promise { + const data = await this.resend.post( + `/broadcasts/${id}/cancel`, + ); + return data; + } + async update( id: string, payload: UpdateBroadcastOptions, diff --git a/src/broadcasts/interfaces/cancel-broadcast.interface.ts b/src/broadcasts/interfaces/cancel-broadcast.interface.ts new file mode 100644 index 00000000..88e31636 --- /dev/null +++ b/src/broadcasts/interfaces/cancel-broadcast.interface.ts @@ -0,0 +1,8 @@ +import type { Response } from '../../interfaces'; +import type { Broadcast } from './broadcast'; + +export interface CancelBroadcastResponseSuccess extends Pick { + object: 'broadcast'; +} + +export type CancelBroadcastResponse = Response; diff --git a/src/broadcasts/interfaces/index.ts b/src/broadcasts/interfaces/index.ts index c83f1c02..8d5c0424 100644 --- a/src/broadcasts/interfaces/index.ts +++ b/src/broadcasts/interfaces/index.ts @@ -1,4 +1,5 @@ export * from './broadcast'; +export * from './cancel-broadcast.interface'; export * from './create-broadcast-options.interface'; export * from './get-broadcast.interface'; export * from './list-broadcasts.interface';