diff --git a/src/models/scheduler.ts b/src/models/scheduler.ts index a51d1588..b6268204 100644 --- a/src/models/scheduler.ts +++ b/src/models/scheduler.ts @@ -459,3 +459,26 @@ export interface FindBookingQueryParams { export type ConfirmBookingQueryParams = FindBookingQueryParams; export type RescheduleBookingQueryParams = FindBookingQueryParams; export type DestroyBookingQueryParams = FindBookingQueryParams; + +export interface SchedulerAvailabilityTimeSlot { + emails: string[]; + startTime: number; + endTime: number; + eventId?: string; + masterId?: string; + calendarId?: string; +} + +export interface SchedulerAvailabilityResponse { + order?: string[]; + timeSlots: SchedulerAvailabilityTimeSlot[]; +} + +export interface GetSchedulerAvailabilityQueryParams { + startTime: number; + endTime: number; + configurationId?: string; + slug?: string; + clientId?: string; + bookingId?: string; +} diff --git a/src/resources/availability.ts b/src/resources/availability.ts new file mode 100644 index 00000000..79492541 --- /dev/null +++ b/src/resources/availability.ts @@ -0,0 +1,35 @@ +import { Overrides } from '../config.js'; +import { NylasResponse } from '../models/response.js'; +import { + SchedulerAvailabilityResponse, + GetSchedulerAvailabilityQueryParams, +} from '../models/scheduler.js'; +import { Resource } from './resource.js'; +import { makePathParams } from '../utils.js'; + +/** + * The parameters for the {@link SchedulerAvailability.get} method + * @property queryParams The query parameters to include in the request + */ +export interface GetSchedulerAvailabilityParams { + queryParams: GetSchedulerAvailabilityQueryParams; +} + +export class SchedulerAvailability extends Resource { + /** + * Get availability for a scheduling configuration + * @return The availability response with time slots + */ + public get({ + queryParams, + overrides, + }: GetSchedulerAvailabilityParams & Overrides): Promise< + NylasResponse + > { + return super._find({ + path: makePathParams('/v3/scheduling/availability', {}), + queryParams, + overrides, + }); + } +} diff --git a/src/resources/scheduler.ts b/src/resources/scheduler.ts index 397f5175..7c46b67e 100644 --- a/src/resources/scheduler.ts +++ b/src/resources/scheduler.ts @@ -1,16 +1,19 @@ import { Configurations } from './configurations.js'; import { Sessions } from './sessions.js'; import { Bookings } from './bookings.js'; +import { SchedulerAvailability } from './availability.js'; import APIClient from '../apiClient.js'; export class Scheduler { public configurations: Configurations; public bookings: Bookings; public sessions: Sessions; + public availability: SchedulerAvailability; constructor(apiClient: APIClient) { this.configurations = new Configurations(apiClient); this.bookings = new Bookings(apiClient); this.sessions = new Sessions(apiClient); + this.availability = new SchedulerAvailability(apiClient); } } diff --git a/tests/resources/attachments.spec.ts b/tests/resources/attachments.spec.ts index 3c068b58..b14d1ac8 100644 --- a/tests/resources/attachments.spec.ts +++ b/tests/resources/attachments.spec.ts @@ -20,7 +20,7 @@ describe('Attachments', () => { // Mock Web ReadableStream (native in Node 18+) const mockStream = new ReadableStream({ - start(controller) { + start(controller: ReadableStreamDefaultController): void { controller.enqueue(new Uint8Array([1, 2, 3])); controller.close(); }, diff --git a/tests/resources/availability.spec.ts b/tests/resources/availability.spec.ts new file mode 100644 index 00000000..1a39fd51 --- /dev/null +++ b/tests/resources/availability.spec.ts @@ -0,0 +1,136 @@ +import APIClient from '../../src/apiClient'; +import { SchedulerAvailability } from '../../src/resources/availability'; +jest.mock('../../src/apiClient'); + +describe('SchedulerAvailability', () => { + let apiClient: jest.Mocked; + let availability: SchedulerAvailability; + + beforeAll(() => { + apiClient = new APIClient({ + apiKey: 'apiKey', + apiUri: 'https://test.api.nylas.com', + timeout: 30, + headers: {}, + }) as jest.Mocked; + + availability = new SchedulerAvailability(apiClient); + apiClient.request.mockResolvedValue({}); + }); + + describe('get', () => { + it('should call apiClient.request with configurationId', async () => { + await availability.get({ + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/availability', + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + configurationId: 'configuration123', + }, + overrides: { + apiUri: 'https://test.api.nylas.com', + headers: { override: 'foobar' }, + }, + }); + }); + + it('should call apiClient.request with slug', async () => { + await availability.get({ + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + slug: 'my-schedule', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/availability', + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + slug: 'my-schedule', + }, + overrides: undefined, + }); + }); + + it('should call apiClient.request with clientId', async () => { + await availability.get({ + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + clientId: 'client123', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/availability', + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + clientId: 'client123', + }, + overrides: undefined, + }); + }); + + it('should call apiClient.request with bookingId for reschedule availability', async () => { + await availability.get({ + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + configurationId: 'configuration123', + bookingId: 'booking456', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/availability', + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + configurationId: 'configuration123', + bookingId: 'booking456', + }, + overrides: undefined, + }); + }); + + it('should URL-encode special characters in query params', async () => { + await availability.get({ + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + slug: 'my schedule/special', + }, + }); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'GET', + path: '/v3/scheduling/availability', + queryParams: { + startTime: 1659367800, + endTime: 1659369600, + slug: 'my schedule/special', + }, + overrides: undefined, + }); + }); + }); +});