Skip to content

Commit 8ecd912

Browse files
radenkovicyun-jay
andauthored
Fix/scheduler availability endpoint (#720)
Co-authored-by: Yunus Szönyi <yunus@hellomateo.de>
1 parent 45a1414 commit 8ecd912

5 files changed

Lines changed: 198 additions & 1 deletion

File tree

src/models/scheduler.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,3 +459,26 @@ export interface FindBookingQueryParams {
459459
export type ConfirmBookingQueryParams = FindBookingQueryParams;
460460
export type RescheduleBookingQueryParams = FindBookingQueryParams;
461461
export type DestroyBookingQueryParams = FindBookingQueryParams;
462+
463+
export interface SchedulerAvailabilityTimeSlot {
464+
emails: string[];
465+
startTime: number;
466+
endTime: number;
467+
eventId?: string;
468+
masterId?: string;
469+
calendarId?: string;
470+
}
471+
472+
export interface SchedulerAvailabilityResponse {
473+
order?: string[];
474+
timeSlots: SchedulerAvailabilityTimeSlot[];
475+
}
476+
477+
export interface GetSchedulerAvailabilityQueryParams {
478+
startTime: number;
479+
endTime: number;
480+
configurationId?: string;
481+
slug?: string;
482+
clientId?: string;
483+
bookingId?: string;
484+
}

src/resources/availability.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Overrides } from '../config.js';
2+
import { NylasResponse } from '../models/response.js';
3+
import {
4+
SchedulerAvailabilityResponse,
5+
GetSchedulerAvailabilityQueryParams,
6+
} from '../models/scheduler.js';
7+
import { Resource } from './resource.js';
8+
import { makePathParams } from '../utils.js';
9+
10+
/**
11+
* The parameters for the {@link SchedulerAvailability.get} method
12+
* @property queryParams The query parameters to include in the request
13+
*/
14+
export interface GetSchedulerAvailabilityParams {
15+
queryParams: GetSchedulerAvailabilityQueryParams;
16+
}
17+
18+
export class SchedulerAvailability extends Resource {
19+
/**
20+
* Get availability for a scheduling configuration
21+
* @return The availability response with time slots
22+
*/
23+
public get({
24+
queryParams,
25+
overrides,
26+
}: GetSchedulerAvailabilityParams & Overrides): Promise<
27+
NylasResponse<SchedulerAvailabilityResponse>
28+
> {
29+
return super._find({
30+
path: makePathParams('/v3/scheduling/availability', {}),
31+
queryParams,
32+
overrides,
33+
});
34+
}
35+
}

src/resources/scheduler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import { Configurations } from './configurations.js';
22
import { Sessions } from './sessions.js';
33
import { Bookings } from './bookings.js';
4+
import { SchedulerAvailability } from './availability.js';
45
import APIClient from '../apiClient.js';
56

67
export class Scheduler {
78
public configurations: Configurations;
89
public bookings: Bookings;
910
public sessions: Sessions;
11+
public availability: SchedulerAvailability;
1012

1113
constructor(apiClient: APIClient) {
1214
this.configurations = new Configurations(apiClient);
1315
this.bookings = new Bookings(apiClient);
1416
this.sessions = new Sessions(apiClient);
17+
this.availability = new SchedulerAvailability(apiClient);
1518
}
1619
}

tests/resources/attachments.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('Attachments', () => {
2020

2121
// Mock Web ReadableStream (native in Node 18+)
2222
const mockStream = new ReadableStream({
23-
start(controller) {
23+
start(controller: ReadableStreamDefaultController<Uint8Array>): void {
2424
controller.enqueue(new Uint8Array([1, 2, 3]));
2525
controller.close();
2626
},
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import APIClient from '../../src/apiClient';
2+
import { SchedulerAvailability } from '../../src/resources/availability';
3+
jest.mock('../../src/apiClient');
4+
5+
describe('SchedulerAvailability', () => {
6+
let apiClient: jest.Mocked<APIClient>;
7+
let availability: SchedulerAvailability;
8+
9+
beforeAll(() => {
10+
apiClient = new APIClient({
11+
apiKey: 'apiKey',
12+
apiUri: 'https://test.api.nylas.com',
13+
timeout: 30,
14+
headers: {},
15+
}) as jest.Mocked<APIClient>;
16+
17+
availability = new SchedulerAvailability(apiClient);
18+
apiClient.request.mockResolvedValue({});
19+
});
20+
21+
describe('get', () => {
22+
it('should call apiClient.request with configurationId', async () => {
23+
await availability.get({
24+
queryParams: {
25+
startTime: 1659367800,
26+
endTime: 1659369600,
27+
configurationId: 'configuration123',
28+
},
29+
overrides: {
30+
apiUri: 'https://test.api.nylas.com',
31+
headers: { override: 'foobar' },
32+
},
33+
});
34+
35+
expect(apiClient.request).toHaveBeenCalledWith({
36+
method: 'GET',
37+
path: '/v3/scheduling/availability',
38+
queryParams: {
39+
startTime: 1659367800,
40+
endTime: 1659369600,
41+
configurationId: 'configuration123',
42+
},
43+
overrides: {
44+
apiUri: 'https://test.api.nylas.com',
45+
headers: { override: 'foobar' },
46+
},
47+
});
48+
});
49+
50+
it('should call apiClient.request with slug', async () => {
51+
await availability.get({
52+
queryParams: {
53+
startTime: 1659367800,
54+
endTime: 1659369600,
55+
slug: 'my-schedule',
56+
},
57+
});
58+
59+
expect(apiClient.request).toHaveBeenCalledWith({
60+
method: 'GET',
61+
path: '/v3/scheduling/availability',
62+
queryParams: {
63+
startTime: 1659367800,
64+
endTime: 1659369600,
65+
slug: 'my-schedule',
66+
},
67+
overrides: undefined,
68+
});
69+
});
70+
71+
it('should call apiClient.request with clientId', async () => {
72+
await availability.get({
73+
queryParams: {
74+
startTime: 1659367800,
75+
endTime: 1659369600,
76+
clientId: 'client123',
77+
},
78+
});
79+
80+
expect(apiClient.request).toHaveBeenCalledWith({
81+
method: 'GET',
82+
path: '/v3/scheduling/availability',
83+
queryParams: {
84+
startTime: 1659367800,
85+
endTime: 1659369600,
86+
clientId: 'client123',
87+
},
88+
overrides: undefined,
89+
});
90+
});
91+
92+
it('should call apiClient.request with bookingId for reschedule availability', async () => {
93+
await availability.get({
94+
queryParams: {
95+
startTime: 1659367800,
96+
endTime: 1659369600,
97+
configurationId: 'configuration123',
98+
bookingId: 'booking456',
99+
},
100+
});
101+
102+
expect(apiClient.request).toHaveBeenCalledWith({
103+
method: 'GET',
104+
path: '/v3/scheduling/availability',
105+
queryParams: {
106+
startTime: 1659367800,
107+
endTime: 1659369600,
108+
configurationId: 'configuration123',
109+
bookingId: 'booking456',
110+
},
111+
overrides: undefined,
112+
});
113+
});
114+
115+
it('should URL-encode special characters in query params', async () => {
116+
await availability.get({
117+
queryParams: {
118+
startTime: 1659367800,
119+
endTime: 1659369600,
120+
slug: 'my schedule/special',
121+
},
122+
});
123+
124+
expect(apiClient.request).toHaveBeenCalledWith({
125+
method: 'GET',
126+
path: '/v3/scheduling/availability',
127+
queryParams: {
128+
startTime: 1659367800,
129+
endTime: 1659369600,
130+
slug: 'my schedule/special',
131+
},
132+
overrides: undefined,
133+
});
134+
});
135+
});
136+
});

0 commit comments

Comments
 (0)