@slotchain/sdk 1.1.4 → 1.2.1
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/dist/index.cjs.js +184 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.mts +262 -22
- package/dist/index.d.ts +262 -22
- package/dist/index.esm.js +184 -16
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -2
- package/src/clients/customer-client.ts +129 -29
- package/src/clients/customer-client.ts.bak +165 -0
- package/src/clients/document-client.ts +148 -0
- package/src/clients/tenant-client.ts +2 -3
- package/src/index.ts +16 -0
- package/src/types/api.ts +150 -1
- package/src/types/next-ambient.d.ts +29 -0
package/dist/index.d.mts
CHANGED
|
@@ -170,12 +170,93 @@ interface Slot {
|
|
|
170
170
|
created_at: string;
|
|
171
171
|
updated_at: string;
|
|
172
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Customer record — matches the `customers` table.
|
|
175
|
+
*/
|
|
173
176
|
interface Customer {
|
|
174
177
|
id: string;
|
|
178
|
+
tenant_id: string;
|
|
179
|
+
customer_type: 'individual' | 'organization';
|
|
180
|
+
name: string;
|
|
181
|
+
email: string;
|
|
182
|
+
phone?: string;
|
|
183
|
+
address?: string;
|
|
184
|
+
city?: string;
|
|
185
|
+
state?: string;
|
|
186
|
+
zip_code?: string;
|
|
187
|
+
is_guest?: boolean;
|
|
188
|
+
metadata?: Record<string, unknown>;
|
|
189
|
+
created_at: string;
|
|
190
|
+
updated_at: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A row in `customer_users` — links an IDP user (Clerk userId, Auth0 sub, etc.) to a Customer.
|
|
194
|
+
*/
|
|
195
|
+
interface CustomerIdentity {
|
|
196
|
+
id: string;
|
|
197
|
+
customer_id: string;
|
|
198
|
+
idp_id: string;
|
|
199
|
+
role: 'owner' | 'admin' | 'member';
|
|
200
|
+
is_primary: boolean;
|
|
201
|
+
created_at: string;
|
|
202
|
+
updated_at: string;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Customer with their associated IDP identities (from `customer_users` join).
|
|
206
|
+
*/
|
|
207
|
+
interface CustomerWithIdentities extends Customer {
|
|
208
|
+
identities?: CustomerIdentity[];
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Notification preferences stored in `customer.metadata.notification_preferences`.
|
|
212
|
+
*/
|
|
213
|
+
interface NotificationPreferences {
|
|
214
|
+
email?: boolean;
|
|
215
|
+
sms?: boolean;
|
|
216
|
+
push?: boolean;
|
|
217
|
+
booking_confirmation?: boolean;
|
|
218
|
+
booking_reminder?: boolean;
|
|
219
|
+
booking_cancellation?: boolean;
|
|
220
|
+
marketing?: boolean;
|
|
221
|
+
[key: string]: boolean | undefined;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Customer with their bookings, as returned by GET /api/v1/customers/bookings.
|
|
225
|
+
*/
|
|
226
|
+
interface CustomerWithBookings {
|
|
227
|
+
customer: Customer;
|
|
228
|
+
bookings: Booking[];
|
|
229
|
+
/** Bookings organised by slot ID → array of bookings */
|
|
230
|
+
groupedBySlot: Record<string, Booking[]>;
|
|
231
|
+
total: number;
|
|
232
|
+
total_slots: number;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Options for resolving a customer from an IDP identity or email.
|
|
236
|
+
* At least one of `idpId` or `email` must be provided.
|
|
237
|
+
*/
|
|
238
|
+
interface ResolveCustomerOptions {
|
|
175
239
|
tenantId: string;
|
|
240
|
+
/** IDP user ID (Clerk userId, Auth0 sub, etc.) — checked first */
|
|
241
|
+
idpId?: string;
|
|
242
|
+
/** Email address — used as fallback if idpId lookup returns nothing */
|
|
176
243
|
email?: string;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Options for atomic customer upsert (find or create by email within a tenant).
|
|
247
|
+
*/
|
|
248
|
+
interface FindOrCreateCustomerOptions {
|
|
249
|
+
tenant_id: string;
|
|
250
|
+
email: string;
|
|
177
251
|
name?: string;
|
|
178
252
|
phone?: string;
|
|
253
|
+
address?: string;
|
|
254
|
+
city?: string;
|
|
255
|
+
state?: string;
|
|
256
|
+
zip_code?: string;
|
|
257
|
+
customer_type?: 'individual' | 'organization';
|
|
258
|
+
is_guest?: boolean;
|
|
259
|
+
metadata?: Record<string, unknown>;
|
|
179
260
|
}
|
|
180
261
|
interface Flow {
|
|
181
262
|
id: string;
|
|
@@ -237,6 +318,63 @@ interface GetOrganizationOptions {
|
|
|
237
318
|
limit?: number;
|
|
238
319
|
is_public?: boolean;
|
|
239
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Artifact / document attached to a customer or booking
|
|
323
|
+
*/
|
|
324
|
+
type ArtifactEntityType = 'customer' | 'booking' | 'slot' | 'service' | 'tenant';
|
|
325
|
+
type ArtifactMimeCategory = 'pdf' | 'document' | 'image' | 'spreadsheet' | 'video' | 'audio' | 'other';
|
|
326
|
+
interface Artifact {
|
|
327
|
+
id: string;
|
|
328
|
+
tenant_id: string;
|
|
329
|
+
/** The Slotly entity this file is attached to */
|
|
330
|
+
related_entity_type: ArtifactEntityType;
|
|
331
|
+
related_entity_id: string;
|
|
332
|
+
/** Original filename supplied by the uploader */
|
|
333
|
+
original_filename: string;
|
|
334
|
+
/** Storage path within the tenant bucket (opaque — use url/signed_url to access) */
|
|
335
|
+
storage_path: string;
|
|
336
|
+
/** MIME category, derived server-side */
|
|
337
|
+
mime_category: ArtifactMimeCategory;
|
|
338
|
+
mime_type?: string;
|
|
339
|
+
size_bytes?: number;
|
|
340
|
+
/** Optional label, e.g. "CV", "Invoice", "Contract" */
|
|
341
|
+
label?: string;
|
|
342
|
+
metadata?: Record<string, unknown>;
|
|
343
|
+
uploaded_by_user_id?: string;
|
|
344
|
+
created_at: string;
|
|
345
|
+
updated_at: string;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Artifact with a short-lived signed download URL (returned from getUrl / list with signed=true)
|
|
349
|
+
*/
|
|
350
|
+
interface ArtifactWithUrl extends Artifact {
|
|
351
|
+
signed_url: string;
|
|
352
|
+
/** Unix timestamp (seconds) when the signed_url expires */
|
|
353
|
+
signed_url_expires_at: number;
|
|
354
|
+
}
|
|
355
|
+
interface ListArtifactsOptions {
|
|
356
|
+
related_entity_type?: ArtifactEntityType;
|
|
357
|
+
related_entity_id?: string;
|
|
358
|
+
/** Include signed download URLs in each result (adds latency) */
|
|
359
|
+
signed?: boolean;
|
|
360
|
+
mime_category?: ArtifactMimeCategory;
|
|
361
|
+
label?: string;
|
|
362
|
+
page?: number;
|
|
363
|
+
limit?: number;
|
|
364
|
+
}
|
|
365
|
+
interface UploadArtifactOptions {
|
|
366
|
+
/** The file binary */
|
|
367
|
+
file: Blob | Buffer | ArrayBuffer;
|
|
368
|
+
/** Original filename */
|
|
369
|
+
filename: string;
|
|
370
|
+
/** The entity this artifact belongs to */
|
|
371
|
+
related_entity_type: ArtifactEntityType;
|
|
372
|
+
related_entity_id: string;
|
|
373
|
+
/** Optional label for the UI, e.g. "CV", "Invoice" */
|
|
374
|
+
label?: string;
|
|
375
|
+
mime_type?: string;
|
|
376
|
+
metadata?: Record<string, unknown>;
|
|
377
|
+
}
|
|
240
378
|
/**
|
|
241
379
|
* Full tenant configuration including branding, services, and service items
|
|
242
380
|
* Service items are nested within each service object (not as a separate top-level array)
|
|
@@ -265,7 +403,7 @@ declare class TenantClient {
|
|
|
265
403
|
constructor(client: AxiosInstance);
|
|
266
404
|
/**
|
|
267
405
|
* Get tenant configuration by slug
|
|
268
|
-
* GET /api/v1/
|
|
406
|
+
* GET /api/v1/tenants/:slug
|
|
269
407
|
*/
|
|
270
408
|
getBySlug(slug: string): Promise<ApiResponse<Tenant>>;
|
|
271
409
|
/**
|
|
@@ -837,11 +975,12 @@ declare class CustomerClient {
|
|
|
837
975
|
/**
|
|
838
976
|
* Create a new customer
|
|
839
977
|
* POST /api/v1/customers
|
|
840
|
-
*
|
|
841
|
-
* @param data - Customer creation data (tenant_id, name, email required)
|
|
842
|
-
* @returns Created customer
|
|
843
978
|
*/
|
|
844
|
-
create(data: Partial<Customer>
|
|
979
|
+
create(data: Partial<Customer> & {
|
|
980
|
+
tenant_id: string;
|
|
981
|
+
name: string;
|
|
982
|
+
email: string;
|
|
983
|
+
}): Promise<ApiResponse<Customer>>;
|
|
845
984
|
/**
|
|
846
985
|
* Update customer by ID
|
|
847
986
|
* PUT /api/v1/customers/:id
|
|
@@ -871,30 +1010,67 @@ declare class CustomerClient {
|
|
|
871
1010
|
tenantId: string;
|
|
872
1011
|
}): Promise<ApiResponse<Customer | null>>;
|
|
873
1012
|
/**
|
|
874
|
-
* Get autocomplete data from existing customers and bookings
|
|
875
|
-
* GET /api/v1/customers/autocomplete
|
|
876
|
-
*
|
|
877
|
-
* @param tenantId - Tenant ID (required)
|
|
878
|
-
* @returns Autocomplete data
|
|
1013
|
+
* Get autocomplete data from existing customers and bookings.
|
|
1014
|
+
* GET /api/v1/customers/autocomplete?tenantId=:tenantId
|
|
879
1015
|
*/
|
|
880
|
-
autocomplete(tenantId: string): Promise<ApiResponse<
|
|
1016
|
+
autocomplete(tenantId: string): Promise<ApiResponse<{
|
|
1017
|
+
companies: string[];
|
|
1018
|
+
jobTitles: string[];
|
|
1019
|
+
experienceLevels: string[];
|
|
1020
|
+
cities: string[];
|
|
1021
|
+
states: string[];
|
|
1022
|
+
zipCodes: string[];
|
|
1023
|
+
}>>;
|
|
881
1024
|
/**
|
|
882
|
-
* Get all bookings for a customer
|
|
883
|
-
* GET /api/v1/customers/bookings
|
|
884
|
-
*
|
|
885
|
-
* @param params - Query parameters (email optional, userId optional, tenantId required)
|
|
886
|
-
* @returns Customer bookings data
|
|
1025
|
+
* Get all bookings for a customer, grouped by slot.
|
|
1026
|
+
* GET /api/v1/customers/bookings?tenantId=:id
|
|
887
1027
|
*/
|
|
888
1028
|
getBookings(params: {
|
|
889
1029
|
email?: string;
|
|
890
1030
|
userId?: string;
|
|
891
1031
|
tenantId: string;
|
|
892
|
-
}): Promise<ApiResponse<
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1032
|
+
}): Promise<ApiResponse<CustomerWithBookings>>;
|
|
1033
|
+
/**
|
|
1034
|
+
* Atomic upsert: find an existing customer by email within a tenant, or create one.
|
|
1035
|
+
* POST /api/v1/customers/find-or-create
|
|
1036
|
+
*/
|
|
1037
|
+
findOrCreate(options: FindOrCreateCustomerOptions): Promise<ApiResponse<Customer & {
|
|
1038
|
+
created: boolean;
|
|
897
1039
|
}>>;
|
|
1040
|
+
/**
|
|
1041
|
+
* Resolve a customer from an IDP identity or email.
|
|
1042
|
+
* Tries idpId lookup (customer_users) first, then falls back to email.
|
|
1043
|
+
* POST /api/v1/customers/resolve
|
|
1044
|
+
*/
|
|
1045
|
+
resolve(options: ResolveCustomerOptions): Promise<ApiResponse<Customer | null>>;
|
|
1046
|
+
/**
|
|
1047
|
+
* Get a customer with their linked IDP identities (customer_users rows).
|
|
1048
|
+
* GET /api/v1/customers/:id?include_identities=true
|
|
1049
|
+
*/
|
|
1050
|
+
getWithIdentities(id: string): Promise<ApiResponse<CustomerWithIdentities>>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Link an IDP user ID to a customer (creates a customer_users row).
|
|
1053
|
+
* POST /api/v1/customers/:id/users
|
|
1054
|
+
*/
|
|
1055
|
+
linkUser(customerId: string, idpId: string, options?: {
|
|
1056
|
+
role?: CustomerIdentity['role'];
|
|
1057
|
+
is_primary?: boolean;
|
|
1058
|
+
}): Promise<ApiResponse<CustomerIdentity>>;
|
|
1059
|
+
/**
|
|
1060
|
+
* Unlink an IDP user from a customer (deletes the customer_users row).
|
|
1061
|
+
* DELETE /api/v1/customers/:id/users/:idpId
|
|
1062
|
+
*/
|
|
1063
|
+
unlinkUser(customerId: string, idpId: string): Promise<ApiResponse<void>>;
|
|
1064
|
+
/**
|
|
1065
|
+
* Get notification preferences for a customer.
|
|
1066
|
+
* GET /api/v1/customers/:id/preferences/notifications
|
|
1067
|
+
*/
|
|
1068
|
+
getNotificationPreferences(customerId: string): Promise<ApiResponse<NotificationPreferences>>;
|
|
1069
|
+
/**
|
|
1070
|
+
* Update notification preferences for a customer (partial merge).
|
|
1071
|
+
* PATCH /api/v1/customers/:id/preferences/notifications
|
|
1072
|
+
*/
|
|
1073
|
+
updateNotificationPreferences(customerId: string, preferences: Partial<NotificationPreferences>): Promise<ApiResponse<NotificationPreferences>>;
|
|
898
1074
|
}
|
|
899
1075
|
|
|
900
1076
|
declare class FlowClient {
|
|
@@ -1185,6 +1361,68 @@ declare class OrganizationClient {
|
|
|
1185
1361
|
getBySlug(slug: string, options?: GetOrganizationOptions): Promise<ApiResponse<Organization | OrganizationFullConfig>>;
|
|
1186
1362
|
}
|
|
1187
1363
|
|
|
1364
|
+
/**
|
|
1365
|
+
* DocumentClient — manage file artifacts attached to Slotly entities.
|
|
1366
|
+
*
|
|
1367
|
+
* Artifacts are tenant-scoped files (CVs, invoices, images, etc.) linked
|
|
1368
|
+
* to a customer, booking, slot, service, or tenant record.
|
|
1369
|
+
*
|
|
1370
|
+
* @example Upload a CV for a customer
|
|
1371
|
+
* ```ts
|
|
1372
|
+
* const artifact = await slotly.document.upload({
|
|
1373
|
+
* file: buffer,
|
|
1374
|
+
* filename: 'cv-2024.pdf',
|
|
1375
|
+
* related_entity_type: 'customer',
|
|
1376
|
+
* related_entity_id: customerId,
|
|
1377
|
+
* label: 'CV',
|
|
1378
|
+
* });
|
|
1379
|
+
* ```
|
|
1380
|
+
*
|
|
1381
|
+
* @example List all CVs for a customer
|
|
1382
|
+
* ```ts
|
|
1383
|
+
* const { data } = await slotly.document.listByEntity('customer', customerId, { signed: true });
|
|
1384
|
+
* ```
|
|
1385
|
+
*/
|
|
1386
|
+
declare class DocumentClient {
|
|
1387
|
+
private readonly client;
|
|
1388
|
+
private readonly base;
|
|
1389
|
+
constructor(client: AxiosInstance);
|
|
1390
|
+
/**
|
|
1391
|
+
* Upload a file artifact.
|
|
1392
|
+
* Sends as multipart/form-data.
|
|
1393
|
+
*/
|
|
1394
|
+
upload(options: UploadArtifactOptions): Promise<Artifact>;
|
|
1395
|
+
/**
|
|
1396
|
+
* List artifacts for a specific entity.
|
|
1397
|
+
* Pass `signed: true` to get download URLs in each result.
|
|
1398
|
+
*/
|
|
1399
|
+
listByEntity(entityType: ArtifactEntityType, entityId: string, options?: Omit<ListArtifactsOptions, 'related_entity_type' | 'related_entity_id'>): Promise<ApiResponse<(Artifact | ArtifactWithUrl)[]>>;
|
|
1400
|
+
/**
|
|
1401
|
+
* List artifacts with full filter options.
|
|
1402
|
+
*/
|
|
1403
|
+
list(options: ListArtifactsOptions): Promise<ApiResponse<(Artifact | ArtifactWithUrl)[]>>;
|
|
1404
|
+
/**
|
|
1405
|
+
* Get a single artifact by ID.
|
|
1406
|
+
*/
|
|
1407
|
+
get(id: string, signed?: boolean): Promise<Artifact | ArtifactWithUrl>;
|
|
1408
|
+
/**
|
|
1409
|
+
* Get a signed download URL for an artifact.
|
|
1410
|
+
* Returns the full ArtifactWithUrl including `signed_url` and `signed_url_expires_at`.
|
|
1411
|
+
*/
|
|
1412
|
+
getUrl(id: string): Promise<ArtifactWithUrl>;
|
|
1413
|
+
/**
|
|
1414
|
+
* Delete an artifact and its stored file.
|
|
1415
|
+
*/
|
|
1416
|
+
delete(id: string): Promise<void>;
|
|
1417
|
+
/**
|
|
1418
|
+
* Update artifact label or metadata.
|
|
1419
|
+
*/
|
|
1420
|
+
update(id: string, patch: {
|
|
1421
|
+
label?: string;
|
|
1422
|
+
metadata?: Record<string, unknown>;
|
|
1423
|
+
}): Promise<Artifact>;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1188
1426
|
/**
|
|
1189
1427
|
* Custom error classes for Slotly SDK
|
|
1190
1428
|
*/
|
|
@@ -1347,6 +1585,8 @@ interface SlotlyApi {
|
|
|
1347
1585
|
notification: NotificationClient;
|
|
1348
1586
|
dataQuality: DataQualityClient;
|
|
1349
1587
|
organization: OrganizationClient;
|
|
1588
|
+
/** Upload and retrieve file artifacts (CVs, invoices, images) linked to any Slotly entity */
|
|
1589
|
+
document: DocumentClient;
|
|
1350
1590
|
}
|
|
1351
1591
|
/**
|
|
1352
1592
|
* Initialize and configure a new Slotly API client with dual authentication.
|
|
@@ -1411,4 +1651,4 @@ interface SlotlyApi {
|
|
|
1411
1651
|
*/
|
|
1412
1652
|
declare const useSlotly: (options: SlotlyClientOptions) => SlotlyApi;
|
|
1413
1653
|
|
|
1414
|
-
export { type ApiResponse, type Booking, type BookingWithSlot, type Category, type Customer, type DataQualityIssue, type Flow, type FlowStep, type GetOrganizationOptions, type ListBookingsOptions, type Notification, type Organization, type OrganizationFullConfig, type Service, type ServiceItem, type ServiceItemWithService, type ServiceWithItems, type Slot, type SlotServiceWithItems, type SlotlyApi, SlotlyApiError, type SlotlyAuthContext, SlotlyAuthError, type SlotlyClientOptions, SlotlyConfigurationError, SlotlyNetworkError, type SlotlyRequest, type Studio, type Tenant, type TenantBranding, type TenantFullConfig, useSlotly as default, getSlotlyContext, useSlotly, validateSlotlyRequest };
|
|
1654
|
+
export { type ApiResponse, type Artifact, type ArtifactEntityType, type ArtifactMimeCategory, type ArtifactWithUrl, type Booking, type BookingWithSlot, type Category, type Customer, type CustomerIdentity, type CustomerWithBookings, type CustomerWithIdentities, type DataQualityIssue, type FindOrCreateCustomerOptions, type Flow, type FlowStep, type GetOrganizationOptions, type ListArtifactsOptions, type ListBookingsOptions, type Notification, type NotificationPreferences, type Organization, type OrganizationFullConfig, type ResolveCustomerOptions, type Service, type ServiceItem, type ServiceItemWithService, type ServiceWithItems, type Slot, type SlotServiceWithItems, type SlotlyApi, SlotlyApiError, type SlotlyAuthContext, SlotlyAuthError, type SlotlyClientOptions, SlotlyConfigurationError, SlotlyNetworkError, type SlotlyRequest, type Studio, type Tenant, type TenantBranding, type TenantFullConfig, type UploadArtifactOptions, useSlotly as default, getSlotlyContext, useSlotly, validateSlotlyRequest };
|