@kognitivedev/cloud-calendar 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -0
- package/CHANGELOG.md +10 -0
- package/dist/client.d.ts +46 -0
- package/dist/client.js +119 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.js +2 -0
- package/package.json +38 -0
- package/src/client.test.ts +43 -0
- package/src/client.ts +155 -0
- package/src/index.ts +26 -0
- package/src/types.ts +172 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +13 -0
package/CHANGELOG.md
ADDED
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HttpTransport } from "@kognitivedev/client-core";
|
|
2
|
+
import type { CalendarAvailabilityQueryInput, CalendarAvailabilityResult, CalendarConfirmHoldResult, CalendarEvent, CalendarHold, CalendarResource, CalendarService, CloudCalendarClientConfig, ConfirmCalendarHoldInput, CreateCalendarHoldInput, CreateCalendarResourceInput, CreateCalendarServiceInput, ListCalendarEventsInput, UpdateCalendarResourceInput, UpdateCalendarServiceInput } from "./types";
|
|
3
|
+
export declare class KognitiveCloudCalendarClient {
|
|
4
|
+
private readonly transport;
|
|
5
|
+
readonly resources: {
|
|
6
|
+
list: (input?: {
|
|
7
|
+
includeAvailability?: boolean;
|
|
8
|
+
}) => Promise<CalendarResource[]>;
|
|
9
|
+
create: (input: CreateCalendarResourceInput) => Promise<CalendarResource>;
|
|
10
|
+
update: (id: string, input: UpdateCalendarResourceInput) => Promise<CalendarResource>;
|
|
11
|
+
};
|
|
12
|
+
readonly services: {
|
|
13
|
+
list: () => Promise<CalendarService[]>;
|
|
14
|
+
create: (input: CreateCalendarServiceInput) => Promise<CalendarService>;
|
|
15
|
+
update: (id: string, input: UpdateCalendarServiceInput) => Promise<CalendarService>;
|
|
16
|
+
};
|
|
17
|
+
readonly availability: {
|
|
18
|
+
query: (input: CalendarAvailabilityQueryInput) => Promise<CalendarAvailabilityResult>;
|
|
19
|
+
};
|
|
20
|
+
readonly holds: {
|
|
21
|
+
list: () => Promise<CalendarHold[]>;
|
|
22
|
+
create: (input: CreateCalendarHoldInput) => Promise<CalendarHold>;
|
|
23
|
+
confirm: (id: string, input: ConfirmCalendarHoldInput) => Promise<CalendarConfirmHoldResult>;
|
|
24
|
+
release: (id: string, reason?: string | null) => Promise<CalendarHold>;
|
|
25
|
+
};
|
|
26
|
+
readonly events: {
|
|
27
|
+
list: (input?: ListCalendarEventsInput) => Promise<CalendarEvent[]>;
|
|
28
|
+
cancel: (id: string, reason?: string | null) => Promise<CalendarEvent>;
|
|
29
|
+
};
|
|
30
|
+
constructor(config: CloudCalendarClientConfig | HttpTransport);
|
|
31
|
+
listResources(input?: {
|
|
32
|
+
includeAvailability?: boolean;
|
|
33
|
+
}): Promise<CalendarResource[]>;
|
|
34
|
+
createResource(input: CreateCalendarResourceInput): Promise<CalendarResource>;
|
|
35
|
+
updateResource(id: string, input: UpdateCalendarResourceInput): Promise<CalendarResource>;
|
|
36
|
+
listServices(): Promise<CalendarService[]>;
|
|
37
|
+
createService(input: CreateCalendarServiceInput): Promise<CalendarService>;
|
|
38
|
+
updateService(id: string, input: UpdateCalendarServiceInput): Promise<CalendarService>;
|
|
39
|
+
queryAvailability(input: CalendarAvailabilityQueryInput): Promise<CalendarAvailabilityResult>;
|
|
40
|
+
listHolds(): Promise<CalendarHold[]>;
|
|
41
|
+
createHold(input: CreateCalendarHoldInput): Promise<CalendarHold>;
|
|
42
|
+
confirmHold(id: string, input: ConfirmCalendarHoldInput): Promise<CalendarConfirmHoldResult>;
|
|
43
|
+
releaseHold(id: string, reason?: string | null): Promise<CalendarHold>;
|
|
44
|
+
listEvents(input?: ListCalendarEventsInput): Promise<CalendarEvent[]>;
|
|
45
|
+
cancelEvent(id: string, reason?: string | null): Promise<CalendarEvent>;
|
|
46
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KognitiveCloudCalendarClient = void 0;
|
|
4
|
+
const client_core_1 = require("@kognitivedev/client-core");
|
|
5
|
+
const BASE_PATH = "/api/cloud/calendar";
|
|
6
|
+
function isTransportLike(value) {
|
|
7
|
+
return Boolean(value && typeof value === "object" && "baseUrl" in value && "json" in value && "raw" in value);
|
|
8
|
+
}
|
|
9
|
+
function toQueryDate(value) {
|
|
10
|
+
if (!value)
|
|
11
|
+
return undefined;
|
|
12
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
13
|
+
}
|
|
14
|
+
class KognitiveCloudCalendarClient {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.resources = {
|
|
17
|
+
list: (input = {}) => this.listResources(input),
|
|
18
|
+
create: (input) => this.createResource(input),
|
|
19
|
+
update: (id, input) => this.updateResource(id, input),
|
|
20
|
+
};
|
|
21
|
+
this.services = {
|
|
22
|
+
list: () => this.listServices(),
|
|
23
|
+
create: (input) => this.createService(input),
|
|
24
|
+
update: (id, input) => this.updateService(id, input),
|
|
25
|
+
};
|
|
26
|
+
this.availability = {
|
|
27
|
+
query: (input) => this.queryAvailability(input),
|
|
28
|
+
};
|
|
29
|
+
this.holds = {
|
|
30
|
+
list: () => this.listHolds(),
|
|
31
|
+
create: (input) => this.createHold(input),
|
|
32
|
+
confirm: (id, input) => this.confirmHold(id, input),
|
|
33
|
+
release: (id, reason) => this.releaseHold(id, reason),
|
|
34
|
+
};
|
|
35
|
+
this.events = {
|
|
36
|
+
list: (input = {}) => this.listEvents(input),
|
|
37
|
+
cancel: (id, reason) => this.cancelEvent(id, reason),
|
|
38
|
+
};
|
|
39
|
+
this.transport = isTransportLike(config) ? config : new client_core_1.HttpTransport(config);
|
|
40
|
+
}
|
|
41
|
+
async listResources(input = {}) {
|
|
42
|
+
const path = input.includeAvailability
|
|
43
|
+
? (0, client_core_1.withQuery)(`${BASE_PATH}/resources`, { include: "availability" })
|
|
44
|
+
: `${BASE_PATH}/resources`;
|
|
45
|
+
const res = await this.transport.json(path);
|
|
46
|
+
return res.resources;
|
|
47
|
+
}
|
|
48
|
+
async createResource(input) {
|
|
49
|
+
return this.transport.json(`${BASE_PATH}/resources`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
body: JSON.stringify(input),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async updateResource(id, input) {
|
|
55
|
+
return this.transport.json(`${BASE_PATH}/resources/${encodeURIComponent(id)}`, {
|
|
56
|
+
method: "PATCH",
|
|
57
|
+
body: JSON.stringify(input),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async listServices() {
|
|
61
|
+
const res = await this.transport.json(`${BASE_PATH}/services`);
|
|
62
|
+
return res.services;
|
|
63
|
+
}
|
|
64
|
+
async createService(input) {
|
|
65
|
+
return this.transport.json(`${BASE_PATH}/services`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: JSON.stringify(input),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async updateService(id, input) {
|
|
71
|
+
return this.transport.json(`${BASE_PATH}/services/${encodeURIComponent(id)}`, {
|
|
72
|
+
method: "PATCH",
|
|
73
|
+
body: JSON.stringify(input),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async queryAvailability(input) {
|
|
77
|
+
return this.transport.json(`${BASE_PATH}/availability/query`, {
|
|
78
|
+
method: "POST",
|
|
79
|
+
body: JSON.stringify(input),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async listHolds() {
|
|
83
|
+
const res = await this.transport.json(`${BASE_PATH}/holds`);
|
|
84
|
+
return res.holds;
|
|
85
|
+
}
|
|
86
|
+
async createHold(input) {
|
|
87
|
+
return this.transport.json(`${BASE_PATH}/holds`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
body: JSON.stringify(input),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async confirmHold(id, input) {
|
|
93
|
+
return this.transport.json(`${BASE_PATH}/holds/${encodeURIComponent(id)}/confirm`, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
body: JSON.stringify(input),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async releaseHold(id, reason) {
|
|
99
|
+
return this.transport.json(`${BASE_PATH}/holds/${encodeURIComponent(id)}/release`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
body: JSON.stringify({ reason }),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async listEvents(input = {}) {
|
|
105
|
+
const res = await this.transport.json((0, client_core_1.withQuery)(`${BASE_PATH}/events`, {
|
|
106
|
+
resourceId: input.resourceId,
|
|
107
|
+
from: toQueryDate(input.from),
|
|
108
|
+
to: toQueryDate(input.to),
|
|
109
|
+
}));
|
|
110
|
+
return res.events;
|
|
111
|
+
}
|
|
112
|
+
async cancelEvent(id, reason) {
|
|
113
|
+
return this.transport.json(`${BASE_PATH}/events/${encodeURIComponent(id)}/cancel`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
body: JSON.stringify({ reason }),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.KognitiveCloudCalendarClient = KognitiveCloudCalendarClient;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { KognitiveCloudCalendarClient } from "./client";
|
|
2
|
+
export type { CalendarAvailabilityQueryInput, CalendarAvailabilityResult, CalendarAvailabilityRule, CalendarBlackout, CalendarBooker, CalendarConfirmHoldResult, CalendarEvent, CalendarEventStatus, CalendarHold, CalendarHoldStatus, CalendarResource, CalendarService, CalendarSlot, CalendarStatus, CloudCalendarClientConfig, ConfirmCalendarHoldInput, CreateCalendarHoldInput, CreateCalendarResourceInput, CreateCalendarServiceInput, ListCalendarEventsInput, LogLevel, UpdateCalendarResourceInput, UpdateCalendarServiceInput, } from "./types";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KognitiveCloudCalendarClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "KognitiveCloudCalendarClient", { enumerable: true, get: function () { return client_1.KognitiveCloudCalendarClient; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { HttpTransportConfig, LogLevel } from "@kognitivedev/client-core";
|
|
2
|
+
export type { LogLevel };
|
|
3
|
+
export interface CloudCalendarClientConfig extends HttpTransportConfig {
|
|
4
|
+
}
|
|
5
|
+
export type CalendarStatus = "active" | "disabled" | "archived" | string;
|
|
6
|
+
export type CalendarHoldStatus = "active" | "confirmed" | "released" | "expired" | string;
|
|
7
|
+
export type CalendarEventStatus = "confirmed" | "cancelled" | string;
|
|
8
|
+
export interface CalendarBooker {
|
|
9
|
+
name: string;
|
|
10
|
+
email?: string | null;
|
|
11
|
+
phone?: string | null;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface CalendarAvailabilityRule {
|
|
15
|
+
id?: string;
|
|
16
|
+
projectId?: string;
|
|
17
|
+
resourceId?: string;
|
|
18
|
+
weekday: number;
|
|
19
|
+
startTime: string;
|
|
20
|
+
endTime: string;
|
|
21
|
+
status?: CalendarStatus;
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface CalendarBlackout {
|
|
25
|
+
id?: string;
|
|
26
|
+
projectId?: string;
|
|
27
|
+
resourceId?: string;
|
|
28
|
+
startAt: string | Date;
|
|
29
|
+
endAt: string | Date;
|
|
30
|
+
reason?: string | null;
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
export interface CalendarResource {
|
|
34
|
+
id: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
name: string;
|
|
37
|
+
slug: string;
|
|
38
|
+
timezone: string;
|
|
39
|
+
status: CalendarStatus;
|
|
40
|
+
metadata: Record<string, unknown>;
|
|
41
|
+
availabilityRules?: CalendarAvailabilityRule[];
|
|
42
|
+
blackouts?: CalendarBlackout[];
|
|
43
|
+
createdAt: string | Date;
|
|
44
|
+
updatedAt: string | Date;
|
|
45
|
+
}
|
|
46
|
+
export interface CalendarService {
|
|
47
|
+
id: string;
|
|
48
|
+
projectId: string;
|
|
49
|
+
name: string;
|
|
50
|
+
slug: string;
|
|
51
|
+
description: string | null;
|
|
52
|
+
durationMinutes: number;
|
|
53
|
+
bufferBeforeMinutes: number;
|
|
54
|
+
bufferAfterMinutes: number;
|
|
55
|
+
status: CalendarStatus;
|
|
56
|
+
metadata: Record<string, unknown>;
|
|
57
|
+
createdAt: string | Date;
|
|
58
|
+
updatedAt: string | Date;
|
|
59
|
+
}
|
|
60
|
+
export interface CalendarHold {
|
|
61
|
+
id: string;
|
|
62
|
+
projectId: string;
|
|
63
|
+
resourceId: string;
|
|
64
|
+
serviceId: string;
|
|
65
|
+
status: CalendarHoldStatus;
|
|
66
|
+
startAt: string | Date;
|
|
67
|
+
endAt: string | Date;
|
|
68
|
+
expiresAt: string | Date;
|
|
69
|
+
booker: Record<string, unknown>;
|
|
70
|
+
metadata: Record<string, unknown>;
|
|
71
|
+
confirmedEventId?: string | null;
|
|
72
|
+
createdAt: string | Date;
|
|
73
|
+
updatedAt: string | Date;
|
|
74
|
+
}
|
|
75
|
+
export interface CalendarEvent {
|
|
76
|
+
id: string;
|
|
77
|
+
projectId: string;
|
|
78
|
+
resourceId: string;
|
|
79
|
+
serviceId: string;
|
|
80
|
+
holdId?: string | null;
|
|
81
|
+
status: CalendarEventStatus;
|
|
82
|
+
startAt: string | Date;
|
|
83
|
+
endAt: string | Date;
|
|
84
|
+
booker: Record<string, unknown>;
|
|
85
|
+
metadata: Record<string, unknown>;
|
|
86
|
+
cancelledAt?: string | Date | null;
|
|
87
|
+
cancelReason?: string | null;
|
|
88
|
+
createdAt: string | Date;
|
|
89
|
+
updatedAt: string | Date;
|
|
90
|
+
}
|
|
91
|
+
export interface CreateCalendarResourceInput {
|
|
92
|
+
name: string;
|
|
93
|
+
slug?: string;
|
|
94
|
+
timezone?: string;
|
|
95
|
+
status?: CalendarStatus;
|
|
96
|
+
metadata?: Record<string, unknown>;
|
|
97
|
+
availabilityRules?: CalendarAvailabilityRule[];
|
|
98
|
+
blackouts?: CalendarBlackout[];
|
|
99
|
+
}
|
|
100
|
+
export type UpdateCalendarResourceInput = Partial<CreateCalendarResourceInput>;
|
|
101
|
+
export interface CreateCalendarServiceInput {
|
|
102
|
+
name: string;
|
|
103
|
+
slug?: string;
|
|
104
|
+
description?: string | null;
|
|
105
|
+
durationMinutes?: number;
|
|
106
|
+
bufferBeforeMinutes?: number;
|
|
107
|
+
bufferAfterMinutes?: number;
|
|
108
|
+
status?: CalendarStatus;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
export type UpdateCalendarServiceInput = Partial<CreateCalendarServiceInput>;
|
|
112
|
+
export interface CalendarAvailabilityQueryInput {
|
|
113
|
+
resourceId: string;
|
|
114
|
+
serviceId: string;
|
|
115
|
+
rangeStart: string | Date;
|
|
116
|
+
rangeEnd: string | Date;
|
|
117
|
+
requestedStart?: string | Date | null;
|
|
118
|
+
metadata?: Record<string, unknown>;
|
|
119
|
+
}
|
|
120
|
+
export interface CalendarSlot {
|
|
121
|
+
start: string;
|
|
122
|
+
end: string;
|
|
123
|
+
resourceId: string;
|
|
124
|
+
serviceId: string;
|
|
125
|
+
timezone: string;
|
|
126
|
+
status: "available";
|
|
127
|
+
}
|
|
128
|
+
export interface CalendarAvailabilityResult {
|
|
129
|
+
slots: CalendarSlot[];
|
|
130
|
+
count: number;
|
|
131
|
+
}
|
|
132
|
+
export interface CreateCalendarHoldInput {
|
|
133
|
+
resourceId: string;
|
|
134
|
+
serviceId: string;
|
|
135
|
+
startAt: string | Date;
|
|
136
|
+
booker?: Partial<CalendarBooker> | Record<string, unknown>;
|
|
137
|
+
metadata?: Record<string, unknown>;
|
|
138
|
+
ttlMinutes?: number;
|
|
139
|
+
}
|
|
140
|
+
export interface ConfirmCalendarHoldInput {
|
|
141
|
+
booker: Partial<CalendarBooker> | Record<string, unknown>;
|
|
142
|
+
metadata?: Record<string, unknown>;
|
|
143
|
+
}
|
|
144
|
+
export interface CalendarConfirmHoldResult {
|
|
145
|
+
hold: CalendarHold;
|
|
146
|
+
event: CalendarEvent;
|
|
147
|
+
}
|
|
148
|
+
export interface ListCalendarEventsInput {
|
|
149
|
+
resourceId?: string;
|
|
150
|
+
from?: string | Date;
|
|
151
|
+
to?: string | Date;
|
|
152
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kognitivedev/cloud-calendar",
|
|
3
|
+
"version": "0.2.29",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc -w --noCheck",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@kognitivedev/client-core": "^0.2.29"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^20.0.0",
|
|
20
|
+
"typescript": "^5.0.0",
|
|
21
|
+
"vitest": "^3.0.0"
|
|
22
|
+
},
|
|
23
|
+
"description": "Cloud calendar SDK for Kognitive scheduling APIs",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"kognitive",
|
|
26
|
+
"calendar",
|
|
27
|
+
"scheduling",
|
|
28
|
+
"cloud",
|
|
29
|
+
"sdk"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/kognitivedev/kognitive",
|
|
35
|
+
"directory": "packages/cloud-calendar"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://kognitive.dev"
|
|
38
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { KognitiveCloudCalendarClient } from "./client";
|
|
3
|
+
|
|
4
|
+
function createClient(calls: Array<{ input: string; init?: RequestInit }>) {
|
|
5
|
+
return new KognitiveCloudCalendarClient({
|
|
6
|
+
baseUrl: "https://api.example.test",
|
|
7
|
+
apiKey: "kog_test",
|
|
8
|
+
fetch: async (input, init) => {
|
|
9
|
+
calls.push({ input: String(input), init });
|
|
10
|
+
return new Response(JSON.stringify({ resources: [], services: [], holds: [], events: [], slots: [], count: 0 }), {
|
|
11
|
+
status: 200,
|
|
12
|
+
headers: { "content-type": "application/json" },
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("KognitiveCloudCalendarClient", () => {
|
|
19
|
+
it("passes API key auth and builds availability URL", async () => {
|
|
20
|
+
const calls: Array<{ input: string; init?: RequestInit }> = [];
|
|
21
|
+
const client = createClient(calls);
|
|
22
|
+
|
|
23
|
+
await client.availability.query({
|
|
24
|
+
resourceId: "resource-1",
|
|
25
|
+
serviceId: "service-1",
|
|
26
|
+
rangeStart: "2026-05-20T00:00:00.000Z",
|
|
27
|
+
rangeEnd: "2026-05-21T00:00:00.000Z",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
expect(calls[0].input).toBe("https://api.example.test/api/cloud/calendar/availability/query");
|
|
31
|
+
expect(new Headers(calls[0].init?.headers).get("Authorization")).toBe("Bearer kog_test");
|
|
32
|
+
expect(calls[0].init?.method).toBe("POST");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("builds resource include query", async () => {
|
|
36
|
+
const calls: Array<{ input: string; init?: RequestInit }> = [];
|
|
37
|
+
const client = createClient(calls);
|
|
38
|
+
|
|
39
|
+
await client.resources.list({ includeAvailability: true });
|
|
40
|
+
|
|
41
|
+
expect(calls[0].input).toBe("https://api.example.test/api/cloud/calendar/resources?include=availability");
|
|
42
|
+
});
|
|
43
|
+
});
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { HttpTransport, type HttpTransportConfig, withQuery } from "@kognitivedev/client-core";
|
|
2
|
+
import type {
|
|
3
|
+
CalendarAvailabilityQueryInput,
|
|
4
|
+
CalendarAvailabilityResult,
|
|
5
|
+
CalendarConfirmHoldResult,
|
|
6
|
+
CalendarEvent,
|
|
7
|
+
CalendarHold,
|
|
8
|
+
CalendarResource,
|
|
9
|
+
CalendarService,
|
|
10
|
+
CloudCalendarClientConfig,
|
|
11
|
+
ConfirmCalendarHoldInput,
|
|
12
|
+
CreateCalendarHoldInput,
|
|
13
|
+
CreateCalendarResourceInput,
|
|
14
|
+
CreateCalendarServiceInput,
|
|
15
|
+
ListCalendarEventsInput,
|
|
16
|
+
UpdateCalendarResourceInput,
|
|
17
|
+
UpdateCalendarServiceInput,
|
|
18
|
+
} from "./types";
|
|
19
|
+
|
|
20
|
+
const BASE_PATH = "/api/cloud/calendar";
|
|
21
|
+
|
|
22
|
+
function isTransportLike(value: unknown): value is HttpTransport {
|
|
23
|
+
return Boolean(value && typeof value === "object" && "baseUrl" in value && "json" in value && "raw" in value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function toQueryDate(value: string | Date | undefined): string | undefined {
|
|
27
|
+
if (!value) return undefined;
|
|
28
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class KognitiveCloudCalendarClient {
|
|
32
|
+
private readonly transport: HttpTransport;
|
|
33
|
+
|
|
34
|
+
readonly resources = {
|
|
35
|
+
list: (input: { includeAvailability?: boolean } = {}) => this.listResources(input),
|
|
36
|
+
create: (input: CreateCalendarResourceInput) => this.createResource(input),
|
|
37
|
+
update: (id: string, input: UpdateCalendarResourceInput) => this.updateResource(id, input),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
readonly services = {
|
|
41
|
+
list: () => this.listServices(),
|
|
42
|
+
create: (input: CreateCalendarServiceInput) => this.createService(input),
|
|
43
|
+
update: (id: string, input: UpdateCalendarServiceInput) => this.updateService(id, input),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
readonly availability = {
|
|
47
|
+
query: (input: CalendarAvailabilityQueryInput) => this.queryAvailability(input),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
readonly holds = {
|
|
51
|
+
list: () => this.listHolds(),
|
|
52
|
+
create: (input: CreateCalendarHoldInput) => this.createHold(input),
|
|
53
|
+
confirm: (id: string, input: ConfirmCalendarHoldInput) => this.confirmHold(id, input),
|
|
54
|
+
release: (id: string, reason?: string | null) => this.releaseHold(id, reason),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
readonly events = {
|
|
58
|
+
list: (input: ListCalendarEventsInput = {}) => this.listEvents(input),
|
|
59
|
+
cancel: (id: string, reason?: string | null) => this.cancelEvent(id, reason),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
constructor(config: CloudCalendarClientConfig | HttpTransport) {
|
|
63
|
+
this.transport = isTransportLike(config) ? config : new HttpTransport(config as HttpTransportConfig);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async listResources(input: { includeAvailability?: boolean } = {}): Promise<CalendarResource[]> {
|
|
67
|
+
const path = input.includeAvailability
|
|
68
|
+
? withQuery(`${BASE_PATH}/resources`, { include: "availability" })
|
|
69
|
+
: `${BASE_PATH}/resources`;
|
|
70
|
+
const res = await this.transport.json<{ resources: CalendarResource[] }>(path);
|
|
71
|
+
return res.resources;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async createResource(input: CreateCalendarResourceInput): Promise<CalendarResource> {
|
|
75
|
+
return this.transport.json<CalendarResource>(`${BASE_PATH}/resources`, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body: JSON.stringify(input),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async updateResource(id: string, input: UpdateCalendarResourceInput): Promise<CalendarResource> {
|
|
82
|
+
return this.transport.json<CalendarResource>(`${BASE_PATH}/resources/${encodeURIComponent(id)}`, {
|
|
83
|
+
method: "PATCH",
|
|
84
|
+
body: JSON.stringify(input),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async listServices(): Promise<CalendarService[]> {
|
|
89
|
+
const res = await this.transport.json<{ services: CalendarService[] }>(`${BASE_PATH}/services`);
|
|
90
|
+
return res.services;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async createService(input: CreateCalendarServiceInput): Promise<CalendarService> {
|
|
94
|
+
return this.transport.json<CalendarService>(`${BASE_PATH}/services`, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
body: JSON.stringify(input),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async updateService(id: string, input: UpdateCalendarServiceInput): Promise<CalendarService> {
|
|
101
|
+
return this.transport.json<CalendarService>(`${BASE_PATH}/services/${encodeURIComponent(id)}`, {
|
|
102
|
+
method: "PATCH",
|
|
103
|
+
body: JSON.stringify(input),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async queryAvailability(input: CalendarAvailabilityQueryInput): Promise<CalendarAvailabilityResult> {
|
|
108
|
+
return this.transport.json<CalendarAvailabilityResult>(`${BASE_PATH}/availability/query`, {
|
|
109
|
+
method: "POST",
|
|
110
|
+
body: JSON.stringify(input),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async listHolds(): Promise<CalendarHold[]> {
|
|
115
|
+
const res = await this.transport.json<{ holds: CalendarHold[] }>(`${BASE_PATH}/holds`);
|
|
116
|
+
return res.holds;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async createHold(input: CreateCalendarHoldInput): Promise<CalendarHold> {
|
|
120
|
+
return this.transport.json<CalendarHold>(`${BASE_PATH}/holds`, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
body: JSON.stringify(input),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async confirmHold(id: string, input: ConfirmCalendarHoldInput): Promise<CalendarConfirmHoldResult> {
|
|
127
|
+
return this.transport.json<CalendarConfirmHoldResult>(`${BASE_PATH}/holds/${encodeURIComponent(id)}/confirm`, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
body: JSON.stringify(input),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async releaseHold(id: string, reason?: string | null): Promise<CalendarHold> {
|
|
134
|
+
return this.transport.json<CalendarHold>(`${BASE_PATH}/holds/${encodeURIComponent(id)}/release`, {
|
|
135
|
+
method: "POST",
|
|
136
|
+
body: JSON.stringify({ reason }),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async listEvents(input: ListCalendarEventsInput = {}): Promise<CalendarEvent[]> {
|
|
141
|
+
const res = await this.transport.json<{ events: CalendarEvent[] }>(withQuery(`${BASE_PATH}/events`, {
|
|
142
|
+
resourceId: input.resourceId,
|
|
143
|
+
from: toQueryDate(input.from),
|
|
144
|
+
to: toQueryDate(input.to),
|
|
145
|
+
}));
|
|
146
|
+
return res.events;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async cancelEvent(id: string, reason?: string | null): Promise<CalendarEvent> {
|
|
150
|
+
return this.transport.json<CalendarEvent>(`${BASE_PATH}/events/${encodeURIComponent(id)}/cancel`, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
body: JSON.stringify({ reason }),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export { KognitiveCloudCalendarClient } from "./client";
|
|
2
|
+
export type {
|
|
3
|
+
CalendarAvailabilityQueryInput,
|
|
4
|
+
CalendarAvailabilityResult,
|
|
5
|
+
CalendarAvailabilityRule,
|
|
6
|
+
CalendarBlackout,
|
|
7
|
+
CalendarBooker,
|
|
8
|
+
CalendarConfirmHoldResult,
|
|
9
|
+
CalendarEvent,
|
|
10
|
+
CalendarEventStatus,
|
|
11
|
+
CalendarHold,
|
|
12
|
+
CalendarHoldStatus,
|
|
13
|
+
CalendarResource,
|
|
14
|
+
CalendarService,
|
|
15
|
+
CalendarSlot,
|
|
16
|
+
CalendarStatus,
|
|
17
|
+
CloudCalendarClientConfig,
|
|
18
|
+
ConfirmCalendarHoldInput,
|
|
19
|
+
CreateCalendarHoldInput,
|
|
20
|
+
CreateCalendarResourceInput,
|
|
21
|
+
CreateCalendarServiceInput,
|
|
22
|
+
ListCalendarEventsInput,
|
|
23
|
+
LogLevel,
|
|
24
|
+
UpdateCalendarResourceInput,
|
|
25
|
+
UpdateCalendarServiceInput,
|
|
26
|
+
} from "./types";
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { HttpTransportConfig, LogLevel } from "@kognitivedev/client-core";
|
|
2
|
+
|
|
3
|
+
export type { LogLevel };
|
|
4
|
+
|
|
5
|
+
export interface CloudCalendarClientConfig extends HttpTransportConfig {}
|
|
6
|
+
|
|
7
|
+
export type CalendarStatus = "active" | "disabled" | "archived" | string;
|
|
8
|
+
export type CalendarHoldStatus = "active" | "confirmed" | "released" | "expired" | string;
|
|
9
|
+
export type CalendarEventStatus = "confirmed" | "cancelled" | string;
|
|
10
|
+
|
|
11
|
+
export interface CalendarBooker {
|
|
12
|
+
name: string;
|
|
13
|
+
email?: string | null;
|
|
14
|
+
phone?: string | null;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CalendarAvailabilityRule {
|
|
19
|
+
id?: string;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
resourceId?: string;
|
|
22
|
+
weekday: number;
|
|
23
|
+
startTime: string;
|
|
24
|
+
endTime: string;
|
|
25
|
+
status?: CalendarStatus;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CalendarBlackout {
|
|
30
|
+
id?: string;
|
|
31
|
+
projectId?: string;
|
|
32
|
+
resourceId?: string;
|
|
33
|
+
startAt: string | Date;
|
|
34
|
+
endAt: string | Date;
|
|
35
|
+
reason?: string | null;
|
|
36
|
+
metadata?: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface CalendarResource {
|
|
40
|
+
id: string;
|
|
41
|
+
projectId: string;
|
|
42
|
+
name: string;
|
|
43
|
+
slug: string;
|
|
44
|
+
timezone: string;
|
|
45
|
+
status: CalendarStatus;
|
|
46
|
+
metadata: Record<string, unknown>;
|
|
47
|
+
availabilityRules?: CalendarAvailabilityRule[];
|
|
48
|
+
blackouts?: CalendarBlackout[];
|
|
49
|
+
createdAt: string | Date;
|
|
50
|
+
updatedAt: string | Date;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CalendarService {
|
|
54
|
+
id: string;
|
|
55
|
+
projectId: string;
|
|
56
|
+
name: string;
|
|
57
|
+
slug: string;
|
|
58
|
+
description: string | null;
|
|
59
|
+
durationMinutes: number;
|
|
60
|
+
bufferBeforeMinutes: number;
|
|
61
|
+
bufferAfterMinutes: number;
|
|
62
|
+
status: CalendarStatus;
|
|
63
|
+
metadata: Record<string, unknown>;
|
|
64
|
+
createdAt: string | Date;
|
|
65
|
+
updatedAt: string | Date;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CalendarHold {
|
|
69
|
+
id: string;
|
|
70
|
+
projectId: string;
|
|
71
|
+
resourceId: string;
|
|
72
|
+
serviceId: string;
|
|
73
|
+
status: CalendarHoldStatus;
|
|
74
|
+
startAt: string | Date;
|
|
75
|
+
endAt: string | Date;
|
|
76
|
+
expiresAt: string | Date;
|
|
77
|
+
booker: Record<string, unknown>;
|
|
78
|
+
metadata: Record<string, unknown>;
|
|
79
|
+
confirmedEventId?: string | null;
|
|
80
|
+
createdAt: string | Date;
|
|
81
|
+
updatedAt: string | Date;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface CalendarEvent {
|
|
85
|
+
id: string;
|
|
86
|
+
projectId: string;
|
|
87
|
+
resourceId: string;
|
|
88
|
+
serviceId: string;
|
|
89
|
+
holdId?: string | null;
|
|
90
|
+
status: CalendarEventStatus;
|
|
91
|
+
startAt: string | Date;
|
|
92
|
+
endAt: string | Date;
|
|
93
|
+
booker: Record<string, unknown>;
|
|
94
|
+
metadata: Record<string, unknown>;
|
|
95
|
+
cancelledAt?: string | Date | null;
|
|
96
|
+
cancelReason?: string | null;
|
|
97
|
+
createdAt: string | Date;
|
|
98
|
+
updatedAt: string | Date;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface CreateCalendarResourceInput {
|
|
102
|
+
name: string;
|
|
103
|
+
slug?: string;
|
|
104
|
+
timezone?: string;
|
|
105
|
+
status?: CalendarStatus;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
availabilityRules?: CalendarAvailabilityRule[];
|
|
108
|
+
blackouts?: CalendarBlackout[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type UpdateCalendarResourceInput = Partial<CreateCalendarResourceInput>;
|
|
112
|
+
|
|
113
|
+
export interface CreateCalendarServiceInput {
|
|
114
|
+
name: string;
|
|
115
|
+
slug?: string;
|
|
116
|
+
description?: string | null;
|
|
117
|
+
durationMinutes?: number;
|
|
118
|
+
bufferBeforeMinutes?: number;
|
|
119
|
+
bufferAfterMinutes?: number;
|
|
120
|
+
status?: CalendarStatus;
|
|
121
|
+
metadata?: Record<string, unknown>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type UpdateCalendarServiceInput = Partial<CreateCalendarServiceInput>;
|
|
125
|
+
|
|
126
|
+
export interface CalendarAvailabilityQueryInput {
|
|
127
|
+
resourceId: string;
|
|
128
|
+
serviceId: string;
|
|
129
|
+
rangeStart: string | Date;
|
|
130
|
+
rangeEnd: string | Date;
|
|
131
|
+
requestedStart?: string | Date | null;
|
|
132
|
+
metadata?: Record<string, unknown>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface CalendarSlot {
|
|
136
|
+
start: string;
|
|
137
|
+
end: string;
|
|
138
|
+
resourceId: string;
|
|
139
|
+
serviceId: string;
|
|
140
|
+
timezone: string;
|
|
141
|
+
status: "available";
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface CalendarAvailabilityResult {
|
|
145
|
+
slots: CalendarSlot[];
|
|
146
|
+
count: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface CreateCalendarHoldInput {
|
|
150
|
+
resourceId: string;
|
|
151
|
+
serviceId: string;
|
|
152
|
+
startAt: string | Date;
|
|
153
|
+
booker?: Partial<CalendarBooker> | Record<string, unknown>;
|
|
154
|
+
metadata?: Record<string, unknown>;
|
|
155
|
+
ttlMinutes?: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface ConfirmCalendarHoldInput {
|
|
159
|
+
booker: Partial<CalendarBooker> | Record<string, unknown>;
|
|
160
|
+
metadata?: Record<string, unknown>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface CalendarConfirmHoldResult {
|
|
164
|
+
hold: CalendarHold;
|
|
165
|
+
event: CalendarEvent;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface ListCalendarEventsInput {
|
|
169
|
+
resourceId?: string;
|
|
170
|
+
from?: string | Date;
|
|
171
|
+
to?: string | Date;
|
|
172
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"noEmit": false,
|
|
9
|
+
"incremental": false,
|
|
10
|
+
"baseUrl": ".",
|
|
11
|
+
"paths": {
|
|
12
|
+
"@kognitivedev/client-core": [
|
|
13
|
+
"../client-core/dist/index.d.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"include": ["src"],
|
|
18
|
+
"exclude": ["src/*.test.ts", "src/**/*.test.ts"]
|
|
19
|
+
}
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
resolve: {
|
|
5
|
+
alias: {
|
|
6
|
+
"@kognitivedev/client-core": new URL("../client-core/src/index.ts", import.meta.url).pathname,
|
|
7
|
+
},
|
|
8
|
+
},
|
|
9
|
+
test: {
|
|
10
|
+
globals: true,
|
|
11
|
+
environment: "node",
|
|
12
|
+
},
|
|
13
|
+
});
|