@slotchain/sdk 1.1.0 → 1.1.2
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 +47 -0
- package/dist/index.cjs.js +145 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.mts +204 -17
- package/dist/index.d.ts +204 -17
- package/dist/index.esm.js +145 -2
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/clients/booking-client.ts +87 -10
- package/src/clients/organization-client.ts +83 -0
- package/src/index.ts +8 -0
- package/src/types/api.ts +94 -11
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ console.log(tenant.data);
|
|
|
62
62
|
The SDK provides typed clients for each domain:
|
|
63
63
|
|
|
64
64
|
- **TenantClient** - Tenant configuration and management
|
|
65
|
+
- **OrganizationClient** - Organization management and tenant associations
|
|
65
66
|
- **BookingClient** - Booking CRUD operations
|
|
66
67
|
- **ServiceClient** - Service management (listServices, create, update, delete, bulkCreate)
|
|
67
68
|
- **SlotClient** - Time slot management and availability
|
|
@@ -106,6 +107,30 @@ const booking = await slotly.booking.create({
|
|
|
106
107
|
});
|
|
107
108
|
```
|
|
108
109
|
|
|
110
|
+
### List Bookings by Tenant
|
|
111
|
+
```ts
|
|
112
|
+
// List bookings for a tenant (single query - fast!)
|
|
113
|
+
const bookings = await slotly.booking.list({
|
|
114
|
+
tenant_id: 'tenant-123',
|
|
115
|
+
includeSlot: true,
|
|
116
|
+
page: 1,
|
|
117
|
+
limit: 20
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Convenience methods
|
|
121
|
+
const tenantBookings = await slotly.booking.listByTenant('tenant-123');
|
|
122
|
+
const tenantBookingsWithSlots = await slotly.booking.listByTenantWithSlots('tenant-123');
|
|
123
|
+
|
|
124
|
+
// Access slot information
|
|
125
|
+
if (bookings.success && bookings.data) {
|
|
126
|
+
bookings.data.forEach(booking => {
|
|
127
|
+
if ('slots' in booking && booking.slots) {
|
|
128
|
+
console.log('Slot name:', booking.slots.name);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
109
134
|
### Service Management
|
|
110
135
|
```ts
|
|
111
136
|
const services = await slotly.service.listServices('bright-accountants');
|
|
@@ -114,6 +139,28 @@ if (services.success) {
|
|
|
114
139
|
}
|
|
115
140
|
```
|
|
116
141
|
|
|
142
|
+
### Organization Management
|
|
143
|
+
```ts
|
|
144
|
+
// Get organization only
|
|
145
|
+
const org = await slotly.organization.getById('org-123');
|
|
146
|
+
|
|
147
|
+
// Get organization with nested tenants
|
|
148
|
+
const orgWithTenants = await slotly.organization.getById('org-123', {
|
|
149
|
+
includeTenants: true,
|
|
150
|
+
page: 1,
|
|
151
|
+
limit: 10,
|
|
152
|
+
is_public: true
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (orgWithTenants.success && orgWithTenants.data) {
|
|
156
|
+
const org = orgWithTenants.data;
|
|
157
|
+
if ('tenants' in org) {
|
|
158
|
+
console.log('Organization:', org.name);
|
|
159
|
+
console.log('Tenants:', org.tenants.map(t => t.name));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
117
164
|
## Middleware & Auth
|
|
118
165
|
For your API routes, use the `validateSlotlyRequest()` middleware to enforce both client and optional user auth:
|
|
119
166
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -218,8 +218,30 @@ var BookingClient = class {
|
|
|
218
218
|
return response.data;
|
|
219
219
|
}
|
|
220
220
|
/**
|
|
221
|
-
* List bookings
|
|
221
|
+
* List bookings with enhanced filtering
|
|
222
222
|
* GET /api/v1/bookings
|
|
223
|
+
*
|
|
224
|
+
* Supports filtering by tenant_id, slot_id, customer_id, status, and optional nested slot information.
|
|
225
|
+
*
|
|
226
|
+
* @param params - Query options (tenant_id, slot_id, customer_id, status, includeSlot, page, limit)
|
|
227
|
+
* @returns Bookings or BookingsWithSlot based on includeSlot parameter
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* // List bookings by tenant (single query - fast!)
|
|
232
|
+
* const bookings = await slotly.booking.list({
|
|
233
|
+
* tenant_id: 'tenant-123',
|
|
234
|
+
* includeSlot: true,
|
|
235
|
+
* page: 1,
|
|
236
|
+
* limit: 20
|
|
237
|
+
* });
|
|
238
|
+
*
|
|
239
|
+
* // List bookings by slot
|
|
240
|
+
* const slotBookings = await slotly.booking.list({
|
|
241
|
+
* slot_id: 'slot-456',
|
|
242
|
+
* status: 'confirmed'
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
223
245
|
*/
|
|
224
246
|
async list(params) {
|
|
225
247
|
const response = await this.client.get(
|
|
@@ -228,6 +250,59 @@ var BookingClient = class {
|
|
|
228
250
|
);
|
|
229
251
|
return response.data;
|
|
230
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* List bookings by tenant (convenience method)
|
|
255
|
+
* GET /api/v1/bookings?tenant_id=:id
|
|
256
|
+
*
|
|
257
|
+
* @param tenantId - Tenant ID
|
|
258
|
+
* @param options - Additional options (includeSlot, page, limit, status)
|
|
259
|
+
* @returns Bookings or BookingsWithSlot based on includeSlot parameter
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const bookings = await slotly.booking.listByTenant('tenant-123', {
|
|
264
|
+
* page: 1,
|
|
265
|
+
* limit: 20,
|
|
266
|
+
* status: 'confirmed'
|
|
267
|
+
* });
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
async listByTenant(tenantId, options) {
|
|
271
|
+
return this.list({
|
|
272
|
+
tenant_id: tenantId,
|
|
273
|
+
...options
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* List bookings by tenant with nested slot information (convenience method)
|
|
278
|
+
* GET /api/v1/bookings?tenant_id=:id&includeSlot=true
|
|
279
|
+
*
|
|
280
|
+
* @param tenantId - Tenant ID
|
|
281
|
+
* @param options - Additional options (page, limit, status)
|
|
282
|
+
* @returns BookingsWithSlot (includes nested slot information)
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* const bookings = await slotly.booking.listByTenantWithSlots('tenant-123', {
|
|
287
|
+
* page: 1,
|
|
288
|
+
* limit: 20
|
|
289
|
+
* });
|
|
290
|
+
*
|
|
291
|
+
* // Access slot information
|
|
292
|
+
* bookings.data.forEach(booking => {
|
|
293
|
+
* if (booking.slots) {
|
|
294
|
+
* console.log('Slot name:', booking.slots.name);
|
|
295
|
+
* }
|
|
296
|
+
* });
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
async listByTenantWithSlots(tenantId, options) {
|
|
300
|
+
return this.list({
|
|
301
|
+
tenant_id: tenantId,
|
|
302
|
+
includeSlot: true,
|
|
303
|
+
...options
|
|
304
|
+
});
|
|
305
|
+
}
|
|
231
306
|
/**
|
|
232
307
|
* Create a new booking (publishes booking.created event)
|
|
233
308
|
* POST /api/v1/bookings
|
|
@@ -1143,6 +1218,73 @@ var DataQualityClient = class {
|
|
|
1143
1218
|
}
|
|
1144
1219
|
};
|
|
1145
1220
|
|
|
1221
|
+
// src/clients/organization-client.ts
|
|
1222
|
+
var OrganizationClient = class {
|
|
1223
|
+
constructor(client) {
|
|
1224
|
+
this.client = client;
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Get organization by ID or slug
|
|
1228
|
+
* GET /api/v1/organizations/:id
|
|
1229
|
+
*
|
|
1230
|
+
* @param identifier - Organization ID or slug
|
|
1231
|
+
* @param options - Query options (includeTenants, page, limit, is_public)
|
|
1232
|
+
* @returns Organization or OrganizationFullConfig (with nested tenants if includeTenants=true)
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* ```typescript
|
|
1236
|
+
* // Get organization only
|
|
1237
|
+
* const org = await slotly.organization.getById('org-123');
|
|
1238
|
+
*
|
|
1239
|
+
* // Get organization with tenants
|
|
1240
|
+
* const orgWithTenants = await slotly.organization.getById('org-123', {
|
|
1241
|
+
* includeTenants: true,
|
|
1242
|
+
* page: 1,
|
|
1243
|
+
* limit: 10,
|
|
1244
|
+
* is_public: true
|
|
1245
|
+
* });
|
|
1246
|
+
* ```
|
|
1247
|
+
*/
|
|
1248
|
+
async getById(identifier, options) {
|
|
1249
|
+
const params = {};
|
|
1250
|
+
if (options?.includeTenants) {
|
|
1251
|
+
params.includeTenants = "true";
|
|
1252
|
+
}
|
|
1253
|
+
if (options?.page !== void 0) {
|
|
1254
|
+
params.page = options.page;
|
|
1255
|
+
}
|
|
1256
|
+
if (options?.limit !== void 0) {
|
|
1257
|
+
params.limit = options.limit;
|
|
1258
|
+
}
|
|
1259
|
+
if (options?.is_public !== void 0) {
|
|
1260
|
+
params.is_public = options.is_public;
|
|
1261
|
+
}
|
|
1262
|
+
const response = await this.client.get(
|
|
1263
|
+
`/api/v1/organizations/${identifier}`,
|
|
1264
|
+
{ params }
|
|
1265
|
+
);
|
|
1266
|
+
return response.data;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Get organization by slug (alias for getById)
|
|
1270
|
+
* GET /api/v1/organizations/:slug
|
|
1271
|
+
*
|
|
1272
|
+
* @param slug - Organization slug
|
|
1273
|
+
* @param options - Query options (includeTenants, page, limit, is_public)
|
|
1274
|
+
* @returns Organization or OrganizationFullConfig (with nested tenants if includeTenants=true)
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* ```typescript
|
|
1278
|
+
* const org = await slotly.organization.getBySlug('acme-corp', {
|
|
1279
|
+
* includeTenants: true
|
|
1280
|
+
* });
|
|
1281
|
+
* ```
|
|
1282
|
+
*/
|
|
1283
|
+
async getBySlug(slug, options) {
|
|
1284
|
+
return this.getById(slug, options);
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1146
1288
|
// src/errors.ts
|
|
1147
1289
|
var SlotlyApiError = class _SlotlyApiError extends Error {
|
|
1148
1290
|
constructor(code, message, statusCode, details) {
|
|
@@ -1474,7 +1616,8 @@ var useSlotly = (options) => {
|
|
|
1474
1616
|
flow: new FlowClient(client),
|
|
1475
1617
|
studio: new StudioClient(client),
|
|
1476
1618
|
notification: new NotificationClient(client),
|
|
1477
|
-
dataQuality: new DataQualityClient(client)
|
|
1619
|
+
dataQuality: new DataQualityClient(client),
|
|
1620
|
+
organization: new OrganizationClient(client)
|
|
1478
1621
|
};
|
|
1479
1622
|
};
|
|
1480
1623
|
var index_default = useSlotly;
|