@mrcharles/sdk 0.0.0-stage → 0.1.0
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/README.md +113 -2
- package/dist/mrcharles.esm.js +509 -0
- package/dist/mrcharles.esm.js.map +19 -0
- package/dist/mrcharles.min.js +4 -0
- package/dist/mrcharles.min.js.map +20 -0
- package/dist/types/client.d.ts +63 -0
- package/dist/types/embed.d.ts +26 -0
- package/dist/types/env.d.ts +30 -0
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/http.d.ts +7 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/links.d.ts +33 -0
- package/dist/types/rooms.d.ts +64 -0
- package/dist/types/slots.d.ts +19 -0
- package/dist/types/types.d.ts +337 -0
- package/dist/types/uuid.d.ts +2 -0
- package/package.json +55 -4
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types of the Mr Charles booking API.
|
|
3
|
+
* Mirrors apps/backend-api/internal/sites/dto.go and the lesson DTOs; the
|
|
4
|
+
* API adds fields without notice but never removes or renames one within v1.
|
|
5
|
+
*/
|
|
6
|
+
export type Locale = 'es' | 'ca' | 'en';
|
|
7
|
+
export type Localized = Partial<Record<Locale, string>>;
|
|
8
|
+
export type PaymentMode = 'card' | 'on_site';
|
|
9
|
+
export type Channel = 'phone' | 'email';
|
|
10
|
+
export interface OperatingHours {
|
|
11
|
+
/** 0–6, Sunday–Saturday */
|
|
12
|
+
dayOfWeek: number;
|
|
13
|
+
openTime: string;
|
|
14
|
+
closeTime: string;
|
|
15
|
+
isClosed: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface PublicStudio {
|
|
18
|
+
name: string;
|
|
19
|
+
slug: string;
|
|
20
|
+
description: string;
|
|
21
|
+
shortDescription: string | null;
|
|
22
|
+
studioType: string | null;
|
|
23
|
+
logoUrl: string | null;
|
|
24
|
+
coverImageUrl: string | null;
|
|
25
|
+
addressLine1: string;
|
|
26
|
+
addressLine2: string | null;
|
|
27
|
+
city: string;
|
|
28
|
+
postalCode: string;
|
|
29
|
+
country: string;
|
|
30
|
+
latitude: number | null;
|
|
31
|
+
longitude: number | null;
|
|
32
|
+
phone: string | null;
|
|
33
|
+
email: string;
|
|
34
|
+
website: string | null;
|
|
35
|
+
/** IANA zone. Every date and time of this studio belongs to it. */
|
|
36
|
+
timezone: string;
|
|
37
|
+
isVerified: boolean;
|
|
38
|
+
averageRating: number | null;
|
|
39
|
+
totalReviews: number;
|
|
40
|
+
operatingHours: OperatingHours[];
|
|
41
|
+
socialLinks: {
|
|
42
|
+
platform: string;
|
|
43
|
+
url: string;
|
|
44
|
+
}[];
|
|
45
|
+
amenities: {
|
|
46
|
+
name: string;
|
|
47
|
+
category: string;
|
|
48
|
+
}[];
|
|
49
|
+
}
|
|
50
|
+
export interface Equipment {
|
|
51
|
+
name: string;
|
|
52
|
+
category: string;
|
|
53
|
+
brand: string | null;
|
|
54
|
+
model: string | null;
|
|
55
|
+
quantity: number;
|
|
56
|
+
}
|
|
57
|
+
export interface PublicRoom {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
description: string | null;
|
|
61
|
+
capacity: number;
|
|
62
|
+
roomType: string | null;
|
|
63
|
+
/** Minor units: 2500 = €25.00 per hour */
|
|
64
|
+
hourlyCents: number;
|
|
65
|
+
currency: string;
|
|
66
|
+
/** Only these rooms accept online bookings */
|
|
67
|
+
bookable: boolean;
|
|
68
|
+
minMinutes: number;
|
|
69
|
+
maxMinutes: number;
|
|
70
|
+
stepMinutes: number;
|
|
71
|
+
paymentModes: PaymentMode[];
|
|
72
|
+
depositPercent: number;
|
|
73
|
+
cancelNoticeHours: number;
|
|
74
|
+
instructions: Localized;
|
|
75
|
+
photos: string[];
|
|
76
|
+
equipment: Equipment[];
|
|
77
|
+
facilities: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface PublicSiteConfig {
|
|
80
|
+
template: string;
|
|
81
|
+
theme: {
|
|
82
|
+
primary: string;
|
|
83
|
+
accent: string;
|
|
84
|
+
font: string;
|
|
85
|
+
radius: string;
|
|
86
|
+
mode?: string;
|
|
87
|
+
logoUrl: string | null;
|
|
88
|
+
};
|
|
89
|
+
sections: Record<string, boolean>;
|
|
90
|
+
content: {
|
|
91
|
+
tagline: Localized;
|
|
92
|
+
about: Localized;
|
|
93
|
+
bookingNote: Localized;
|
|
94
|
+
whatsapp: string;
|
|
95
|
+
instagram: string;
|
|
96
|
+
gallery: string[];
|
|
97
|
+
};
|
|
98
|
+
legal: {
|
|
99
|
+
legalName: string;
|
|
100
|
+
taxId: string;
|
|
101
|
+
address: string;
|
|
102
|
+
email: string;
|
|
103
|
+
phone: string;
|
|
104
|
+
};
|
|
105
|
+
seo: {
|
|
106
|
+
title: string;
|
|
107
|
+
description: string;
|
|
108
|
+
};
|
|
109
|
+
defaultLocale: Locale;
|
|
110
|
+
locales: Locale[];
|
|
111
|
+
status: string;
|
|
112
|
+
customDomain: string | null;
|
|
113
|
+
canonicalHost: string;
|
|
114
|
+
/**
|
|
115
|
+
* Sandbox: this site exists for testing. Codes come back as `hold.devCode`,
|
|
116
|
+
* nothing is sent to anyone, card payments are off and bookings are purged
|
|
117
|
+
* after seven days. Tell the guest.
|
|
118
|
+
*/
|
|
119
|
+
sandbox: boolean;
|
|
120
|
+
}
|
|
121
|
+
export interface PublicSite {
|
|
122
|
+
studio: PublicStudio;
|
|
123
|
+
rooms: PublicRoom[];
|
|
124
|
+
site: PublicSiteConfig;
|
|
125
|
+
/** At least one room is bookable online */
|
|
126
|
+
bookingOnline: boolean;
|
|
127
|
+
cardPayments: boolean;
|
|
128
|
+
/** Present when holds require a Turnstile token */
|
|
129
|
+
captchaSiteKey?: string;
|
|
130
|
+
/** Present when card deposits are possible — use it to mount Stripe */
|
|
131
|
+
stripePublishableKey?: string;
|
|
132
|
+
}
|
|
133
|
+
/** A continuous free span, "HH:MM" in the studio's zone. "24:00" is a valid end. */
|
|
134
|
+
export interface FreeSpan {
|
|
135
|
+
start: string;
|
|
136
|
+
end: string;
|
|
137
|
+
}
|
|
138
|
+
export interface DayAvailability {
|
|
139
|
+
/** YYYY-MM-DD */
|
|
140
|
+
date: string;
|
|
141
|
+
free: FreeSpan[];
|
|
142
|
+
}
|
|
143
|
+
export interface RoomAvailability {
|
|
144
|
+
roomId: string;
|
|
145
|
+
timezone: string;
|
|
146
|
+
hourlyCents: number;
|
|
147
|
+
currency: string;
|
|
148
|
+
minMinutes: number;
|
|
149
|
+
maxMinutes: number;
|
|
150
|
+
stepMinutes: number;
|
|
151
|
+
minNoticeMin: number;
|
|
152
|
+
maxAdvanceDays: number;
|
|
153
|
+
days: DayAvailability[];
|
|
154
|
+
}
|
|
155
|
+
export interface HoldRequest {
|
|
156
|
+
roomId: string;
|
|
157
|
+
/** YYYY-MM-DD in the studio's zone */
|
|
158
|
+
date: string;
|
|
159
|
+
/** HH:MM in the studio's zone */
|
|
160
|
+
startTime: string;
|
|
161
|
+
durationMinutes: number;
|
|
162
|
+
guestName: string;
|
|
163
|
+
channel: Channel;
|
|
164
|
+
/** E.164 phone (+34…) when channel is phone; an address when email */
|
|
165
|
+
contact: string;
|
|
166
|
+
locale?: Locale;
|
|
167
|
+
/** One per attempt; reuse it when retrying the same request */
|
|
168
|
+
idempotencyKey: string;
|
|
169
|
+
/** Required when the site payload has captchaSiteKey */
|
|
170
|
+
captchaToken?: string;
|
|
171
|
+
}
|
|
172
|
+
export interface Price {
|
|
173
|
+
priceCents: number;
|
|
174
|
+
/** What a card payment charges now */
|
|
175
|
+
depositCents: number;
|
|
176
|
+
currency: string;
|
|
177
|
+
minutes: number;
|
|
178
|
+
}
|
|
179
|
+
export interface Hold {
|
|
180
|
+
holdId: string;
|
|
181
|
+
status: string;
|
|
182
|
+
roomId: string;
|
|
183
|
+
roomName: string;
|
|
184
|
+
date: string;
|
|
185
|
+
startTime: string;
|
|
186
|
+
endTime: string;
|
|
187
|
+
timezone: string;
|
|
188
|
+
price: Price;
|
|
189
|
+
channel: Channel;
|
|
190
|
+
contactMasked: string;
|
|
191
|
+
/** ISO instant; the slot is yours until then (12 minutes) */
|
|
192
|
+
expiresAt: string;
|
|
193
|
+
resendsLeft: number;
|
|
194
|
+
paymentModes: PaymentMode[];
|
|
195
|
+
/** Only on sandbox sites: the code that would have been sent. */
|
|
196
|
+
devCode?: string;
|
|
197
|
+
}
|
|
198
|
+
export interface ConfirmRequest {
|
|
199
|
+
/** Must be one of hold.paymentModes */
|
|
200
|
+
paymentMode: PaymentMode;
|
|
201
|
+
/** Shown to the studio */
|
|
202
|
+
notes?: string;
|
|
203
|
+
/** Optional second contact for the receipt */
|
|
204
|
+
email?: string;
|
|
205
|
+
}
|
|
206
|
+
export interface Booking {
|
|
207
|
+
id: string;
|
|
208
|
+
reference: string;
|
|
209
|
+
status: 'confirmed' | 'pending_payment' | 'cancelled' | 'completed' | 'no_show' | string;
|
|
210
|
+
paymentMode: PaymentMode;
|
|
211
|
+
paymentStatus: string;
|
|
212
|
+
studioName: string;
|
|
213
|
+
roomName: string;
|
|
214
|
+
guestName: string;
|
|
215
|
+
date: string;
|
|
216
|
+
startTime: string;
|
|
217
|
+
endTime: string;
|
|
218
|
+
timezone: string;
|
|
219
|
+
startsAt: string;
|
|
220
|
+
endsAt: string;
|
|
221
|
+
minutes: number;
|
|
222
|
+
priceCents: number;
|
|
223
|
+
depositCents: number;
|
|
224
|
+
currency: string;
|
|
225
|
+
cancelNoticeHours: number;
|
|
226
|
+
mayCancel: boolean;
|
|
227
|
+
notes: string | null;
|
|
228
|
+
paymentDueAt: string | null;
|
|
229
|
+
createdAt: string;
|
|
230
|
+
}
|
|
231
|
+
export interface Confirmation {
|
|
232
|
+
booking: Booking;
|
|
233
|
+
/** Keep it if you build your own manage screen */
|
|
234
|
+
manageToken: string;
|
|
235
|
+
/** Hand it to the guest — the only way back to the booking */
|
|
236
|
+
manageUrl: string;
|
|
237
|
+
/** Stripe PaymentIntent secret, when paymentMode is card */
|
|
238
|
+
clientSecret?: string;
|
|
239
|
+
}
|
|
240
|
+
export interface Money {
|
|
241
|
+
/** Minor units */
|
|
242
|
+
amount: number;
|
|
243
|
+
currency: string;
|
|
244
|
+
}
|
|
245
|
+
export interface TeacherProfile {
|
|
246
|
+
/** Instructor *profile* id — not what the booking endpoints want */
|
|
247
|
+
id: string;
|
|
248
|
+
/** user.id is the id for availability, slots and the booking link */
|
|
249
|
+
user: {
|
|
250
|
+
id: string;
|
|
251
|
+
displayName: string;
|
|
252
|
+
username: string;
|
|
253
|
+
avatarUrl: string | null;
|
|
254
|
+
};
|
|
255
|
+
headline: string | null;
|
|
256
|
+
bio: string;
|
|
257
|
+
teachingPhilosophy: string | null;
|
|
258
|
+
hourlyRate: Money;
|
|
259
|
+
experienceYears: number;
|
|
260
|
+
teachesOnline: boolean;
|
|
261
|
+
teachesInPerson: boolean;
|
|
262
|
+
instruments: {
|
|
263
|
+
instrument: string;
|
|
264
|
+
skillLevel?: string;
|
|
265
|
+
[k: string]: unknown;
|
|
266
|
+
}[];
|
|
267
|
+
genres: string[];
|
|
268
|
+
teachingSpecialties: string[];
|
|
269
|
+
audienceLevels: string[];
|
|
270
|
+
languages: string[];
|
|
271
|
+
locationDisplay: string | null;
|
|
272
|
+
teachingSinceYear: number | null;
|
|
273
|
+
averageRating: number | null;
|
|
274
|
+
totalReviews: number;
|
|
275
|
+
totalStudents: number;
|
|
276
|
+
totalLessons: number;
|
|
277
|
+
isVerified: boolean;
|
|
278
|
+
createdAt: string;
|
|
279
|
+
}
|
|
280
|
+
export interface LessonOffer {
|
|
281
|
+
id: string;
|
|
282
|
+
/** Instructor *profile* id (see TeacherProfile.id) */
|
|
283
|
+
instructorId: string;
|
|
284
|
+
title: string;
|
|
285
|
+
description: string;
|
|
286
|
+
instrument: string;
|
|
287
|
+
audienceLevels: string[];
|
|
288
|
+
price: Money;
|
|
289
|
+
durationMinutes: number;
|
|
290
|
+
format: 'online' | 'in_person' | 'both' | string;
|
|
291
|
+
maxParticipants: number;
|
|
292
|
+
publishedAt: string | null;
|
|
293
|
+
}
|
|
294
|
+
export interface LessonPolicy {
|
|
295
|
+
minNoticeMin: number;
|
|
296
|
+
maxAdvanceDays: number;
|
|
297
|
+
slotGranularityMin: number;
|
|
298
|
+
rescheduleMinNoticeMin: number;
|
|
299
|
+
rescheduleMaxPerBooking: number;
|
|
300
|
+
}
|
|
301
|
+
export interface LessonSlot {
|
|
302
|
+
date: string;
|
|
303
|
+
/** HH:MM in the teacher's zone */
|
|
304
|
+
startTime: string;
|
|
305
|
+
endTime: string;
|
|
306
|
+
}
|
|
307
|
+
export interface LessonSlots {
|
|
308
|
+
instructorId: string;
|
|
309
|
+
offerId: string;
|
|
310
|
+
timezone: string;
|
|
311
|
+
durationMinutes: number;
|
|
312
|
+
days: {
|
|
313
|
+
date: string;
|
|
314
|
+
slots: LessonSlot[];
|
|
315
|
+
}[];
|
|
316
|
+
policy?: LessonPolicy;
|
|
317
|
+
}
|
|
318
|
+
export interface TeacherWindows {
|
|
319
|
+
timezone: string;
|
|
320
|
+
windows: {
|
|
321
|
+
date: string;
|
|
322
|
+
startTime: string;
|
|
323
|
+
endTime: string;
|
|
324
|
+
}[];
|
|
325
|
+
}
|
|
326
|
+
export interface EmbedBookedEvent {
|
|
327
|
+
type: 'mrcharles:booked';
|
|
328
|
+
reference: string;
|
|
329
|
+
bookingId: string;
|
|
330
|
+
manageUrl: string;
|
|
331
|
+
status: string;
|
|
332
|
+
}
|
|
333
|
+
export interface EmbedResizeEvent {
|
|
334
|
+
type: 'mrcharles:resize';
|
|
335
|
+
height: number;
|
|
336
|
+
}
|
|
337
|
+
export type EmbedEvent = EmbedBookedEvent | EmbedResizeEvent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrcharles/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mr Charles booking SDK \u2014 put studio room bookings and teacher lessons on any website.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://developers.mrcharles.app/integrate/sdk/",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/oryontech-ou/mrcharles.git",
|
|
10
|
+
"directory": "packages/sdk"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mrcharles",
|
|
14
|
+
"booking",
|
|
15
|
+
"studio",
|
|
16
|
+
"music",
|
|
17
|
+
"lessons",
|
|
18
|
+
"sdk"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"main": "./dist/mrcharles.esm.js",
|
|
23
|
+
"module": "./dist/mrcharles.esm.js",
|
|
24
|
+
"types": "./dist/types/index.d.ts",
|
|
25
|
+
"unpkg": "./dist/mrcharles.min.js",
|
|
26
|
+
"jsdelivr": "./dist/mrcharles.min.js",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/types/index.d.ts",
|
|
30
|
+
"import": "./dist/mrcharles.esm.js",
|
|
31
|
+
"default": "./dist/mrcharles.esm.js"
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "rm -rf dist && bun build src/index.ts --target=browser --format=esm --outdir=dist --entry-naming='mrcharles.esm.[ext]' --sourcemap=linked && bun build src/global.ts --target=browser --format=iife --minify --outdir=dist --entry-naming='mrcharles.min.[ext]' --sourcemap=linked && tsc -p tsconfig.build.json",
|
|
41
|
+
"test": "bun test",
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"clean": "rm -rf dist"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/bun": "^1.0.0",
|
|
47
|
+
"typescript": "^5.9.3"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"nx": {
|
|
53
|
+
"tags": [
|
|
54
|
+
"scope:sdk"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|