@back23/promptly-sdk 2.5.0 → 2.6.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 +213 -213
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +45 -5
- package/dist/index.mjs +45 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,16 +26,16 @@ const products = await client.shop.listProducts();
|
|
|
26
26
|
|
|
27
27
|
## v2.5.0 Changes
|
|
28
28
|
|
|
29
|
-
### BoardPost
|
|
29
|
+
### BoardPost Type Extension
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Added `is_secret` and `is_mine` fields to posts.
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
34
|
interface BoardPost {
|
|
35
|
-
// ...
|
|
36
|
-
is_notice: boolean; //
|
|
37
|
-
is_secret: boolean; //
|
|
38
|
-
is_mine: boolean; //
|
|
35
|
+
// ... existing fields
|
|
36
|
+
is_notice: boolean; // Whether it's a notice
|
|
37
|
+
is_secret: boolean; // Whether it's a secret post
|
|
38
|
+
is_mine: boolean; // Whether current logged-in user is the author
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
@@ -45,19 +45,19 @@ interface BoardPost {
|
|
|
45
45
|
|
|
46
46
|
### Dual Authentication Support Fixed
|
|
47
47
|
|
|
48
|
-
API Key
|
|
48
|
+
Fixed issue where API Key and Bearer Token are now sent simultaneously. In previous versions, when API Key was set, the Authorization header was ignored, causing member-only API calls to fail after login.
|
|
49
49
|
|
|
50
50
|
```typescript
|
|
51
|
-
//
|
|
51
|
+
// API Key + Bearer Token now work together
|
|
52
52
|
const client = new Promptly({
|
|
53
53
|
tenantId: 'demo',
|
|
54
|
-
apiKey: 'pky_xxx', // X-API-Key
|
|
54
|
+
apiKey: 'pky_xxx', // X-API-Key header
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
//
|
|
57
|
+
// Set token after login
|
|
58
58
|
await client.auth.login({ email, password });
|
|
59
59
|
|
|
60
|
-
//
|
|
60
|
+
// Member-only APIs work correctly (Authorization: Bearer xxx header included)
|
|
61
61
|
const profile = await client.members.getProfile();
|
|
62
62
|
const orders = await client.orders.list();
|
|
63
63
|
```
|
|
@@ -68,33 +68,33 @@ const orders = await client.orders.list();
|
|
|
68
68
|
|
|
69
69
|
### Polymorphic Comments API
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
The comment system has been redesigned to support various use cases including boards, blogs, and guestbooks (standalone pages).
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
|
-
//
|
|
74
|
+
// Board post comments
|
|
75
75
|
const boardComments = await client.comments.boardPost(postId);
|
|
76
76
|
await client.comments.createBoardPost(postId, {
|
|
77
|
-
author_name: '
|
|
78
|
-
content: '
|
|
79
|
-
password: '1234', //
|
|
77
|
+
author_name: 'John Doe',
|
|
78
|
+
content: 'Comment content',
|
|
79
|
+
password: '1234', // For guest comments
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
//
|
|
82
|
+
// Blog post comments
|
|
83
83
|
const blogComments = await client.comments.blogPost('post-slug');
|
|
84
84
|
await client.comments.createBlogPost('post-slug', {
|
|
85
85
|
author_name: 'Jane',
|
|
86
86
|
content: 'Great post!',
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
//
|
|
89
|
+
// Guestbook (standalone page)
|
|
90
90
|
const guestbook = await client.comments.standalone('guestbook');
|
|
91
91
|
await client.comments.createStandalone('guestbook', {
|
|
92
|
-
author_name: '
|
|
93
|
-
content: '
|
|
92
|
+
author_name: 'Visitor',
|
|
93
|
+
content: 'Hello!',
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
//
|
|
97
|
-
await client.comments.update(commentId, { content: '
|
|
96
|
+
// Common features
|
|
97
|
+
await client.comments.update(commentId, { content: 'Updated comment' });
|
|
98
98
|
await client.comments.delete(commentId, { password: '1234' });
|
|
99
99
|
await client.comments.like(commentId);
|
|
100
100
|
```
|
|
@@ -105,46 +105,46 @@ await client.comments.like(commentId);
|
|
|
105
105
|
|
|
106
106
|
### Entity Definition CRUD
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
You can now create/update/delete custom entity definitions directly from the API/SDK.
|
|
109
109
|
|
|
110
110
|
```typescript
|
|
111
|
-
//
|
|
111
|
+
// Create entity definition
|
|
112
112
|
const entity = await client.entities.create({
|
|
113
|
-
name: '
|
|
113
|
+
name: 'Customer',
|
|
114
114
|
slug: 'customers', // optional, auto-generated from name
|
|
115
|
-
description: '
|
|
115
|
+
description: 'Customer management',
|
|
116
116
|
schema: {
|
|
117
117
|
fields: [
|
|
118
|
-
{ name: 'company', label: '
|
|
119
|
-
{ name: 'email', label: '
|
|
120
|
-
{ name: 'status', label: '
|
|
121
|
-
{ value: 'active', label: '
|
|
122
|
-
{ value: 'inactive', label: '
|
|
118
|
+
{ name: 'company', label: 'Company Name', type: 'text', required: true },
|
|
119
|
+
{ name: 'email', label: 'Email', type: 'email', required: true },
|
|
120
|
+
{ name: 'status', label: 'Status', type: 'select', options: [
|
|
121
|
+
{ value: 'active', label: 'Active' },
|
|
122
|
+
{ value: 'inactive', label: 'Inactive' }
|
|
123
123
|
]}
|
|
124
124
|
]
|
|
125
125
|
},
|
|
126
126
|
icon: 'users'
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
-
//
|
|
129
|
+
// Get entity definition
|
|
130
130
|
const entity = await client.entities.get('customers');
|
|
131
131
|
|
|
132
|
-
//
|
|
133
|
-
await client.entities.update('customers', { name: '
|
|
132
|
+
// Update entity definition
|
|
133
|
+
await client.entities.update('customers', { name: 'Clients' });
|
|
134
134
|
|
|
135
|
-
//
|
|
135
|
+
// Delete entity definition (requires force if records exist)
|
|
136
136
|
await client.entities.delete('customers', true);
|
|
137
137
|
```
|
|
138
138
|
|
|
139
139
|
### Record API Path Change
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
The record API path has changed:
|
|
142
142
|
|
|
143
143
|
```typescript
|
|
144
|
-
// v2.1.0
|
|
144
|
+
// Before v2.1.0
|
|
145
145
|
await client.entities.createRecord('customers', { data: { company: 'ACME' } });
|
|
146
146
|
|
|
147
|
-
// v2.2.0
|
|
147
|
+
// v2.2.0 and later - no data wrapper needed
|
|
148
148
|
await client.entities.createRecord('customers', { company: 'ACME' });
|
|
149
149
|
```
|
|
150
150
|
|
|
@@ -225,275 +225,275 @@ data.map(post => ...); // data is always an array
|
|
|
225
225
|
|
|
226
226
|
## API Reference
|
|
227
227
|
|
|
228
|
-
### Boards
|
|
228
|
+
### Boards
|
|
229
229
|
|
|
230
230
|
```typescript
|
|
231
|
-
//
|
|
231
|
+
// List boards
|
|
232
232
|
const { data: boards, meta } = await client.boards.list();
|
|
233
233
|
// Returns: ListResponse<Board>
|
|
234
234
|
|
|
235
|
-
//
|
|
235
|
+
// Get board details
|
|
236
236
|
const board = await client.boards.get('first'); // slug or id
|
|
237
237
|
// Returns: Board
|
|
238
238
|
|
|
239
|
-
//
|
|
239
|
+
// List board posts
|
|
240
240
|
const { data: posts, meta } = await client.boards.listPosts('first', {
|
|
241
241
|
page: 1,
|
|
242
242
|
per_page: 10,
|
|
243
|
-
search: '
|
|
243
|
+
search: 'keyword', // optional
|
|
244
244
|
});
|
|
245
245
|
// Returns: ListResponse<BoardPost>
|
|
246
246
|
|
|
247
|
-
//
|
|
247
|
+
// Get post details
|
|
248
248
|
const post = await client.boards.getPost(1);
|
|
249
249
|
// Returns: BoardPost
|
|
250
250
|
|
|
251
|
-
//
|
|
251
|
+
// List comments
|
|
252
252
|
const comments = await client.boards.listComments(1);
|
|
253
253
|
// Returns: BoardComment[] (always an array)
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
### Posts & Comments - Protected (
|
|
256
|
+
### Posts & Comments - Protected (Login Required)
|
|
257
257
|
|
|
258
258
|
```typescript
|
|
259
|
-
//
|
|
259
|
+
// Login first
|
|
260
260
|
await client.auth.login({ email: 'user@example.com', password: 'password' });
|
|
261
261
|
|
|
262
|
-
//
|
|
262
|
+
// Create post
|
|
263
263
|
const newPost = await client.boards.createPost({
|
|
264
264
|
board_id: 1,
|
|
265
|
-
title: '
|
|
266
|
-
content: '
|
|
265
|
+
title: 'Title',
|
|
266
|
+
content: 'Content',
|
|
267
267
|
is_notice: false,
|
|
268
268
|
});
|
|
269
269
|
|
|
270
|
-
//
|
|
270
|
+
// Update post
|
|
271
271
|
await client.boards.updatePost(postId, {
|
|
272
|
-
title: '
|
|
273
|
-
content: '
|
|
272
|
+
title: 'Updated title',
|
|
273
|
+
content: 'Updated content',
|
|
274
274
|
});
|
|
275
275
|
|
|
276
|
-
//
|
|
276
|
+
// Delete post
|
|
277
277
|
await client.boards.deletePost(postId);
|
|
278
278
|
|
|
279
|
-
//
|
|
279
|
+
// Create comment
|
|
280
280
|
await client.boards.createComment(postId, {
|
|
281
|
-
content: '
|
|
282
|
-
parent_id: null, //
|
|
281
|
+
content: 'Comment content',
|
|
282
|
+
parent_id: null, // Parent comment ID for replies
|
|
283
283
|
});
|
|
284
284
|
|
|
285
|
-
//
|
|
285
|
+
// Update comment
|
|
286
286
|
await client.boards.updateComment(commentId, {
|
|
287
|
-
content: '
|
|
287
|
+
content: 'Updated comment',
|
|
288
288
|
});
|
|
289
289
|
|
|
290
|
-
//
|
|
290
|
+
// Delete comment
|
|
291
291
|
await client.boards.deleteComment(commentId);
|
|
292
292
|
```
|
|
293
293
|
|
|
294
|
-
### Blog
|
|
294
|
+
### Blog
|
|
295
295
|
|
|
296
296
|
```typescript
|
|
297
|
-
//
|
|
297
|
+
// List blog posts
|
|
298
298
|
const { data: posts, meta } = await client.blog.list({
|
|
299
299
|
page: 1,
|
|
300
300
|
per_page: 10,
|
|
301
301
|
category: 'news', // optional
|
|
302
302
|
tag: 'featured', // optional
|
|
303
|
-
search: '
|
|
303
|
+
search: 'keyword', // optional
|
|
304
304
|
});
|
|
305
305
|
// Returns: ListResponse<BlogPost>
|
|
306
306
|
|
|
307
|
-
//
|
|
307
|
+
// Get blog post details
|
|
308
308
|
const post = await client.blog.get('post-slug');
|
|
309
309
|
// Returns: BlogPost
|
|
310
310
|
|
|
311
|
-
//
|
|
311
|
+
// Featured posts
|
|
312
312
|
const featured = await client.blog.featured(5);
|
|
313
313
|
// Returns: BlogPost[] (always an array)
|
|
314
314
|
|
|
315
|
-
//
|
|
315
|
+
// Get posts by category
|
|
316
316
|
const { data: newsPosts } = await client.blog.byCategory('news');
|
|
317
317
|
|
|
318
|
-
//
|
|
318
|
+
// Get posts by tag
|
|
319
319
|
const { data: taggedPosts } = await client.blog.byTag('featured');
|
|
320
320
|
|
|
321
|
-
//
|
|
321
|
+
// List categories
|
|
322
322
|
const categories = await client.blog.categories();
|
|
323
323
|
// Returns: string[] (always an array)
|
|
324
324
|
|
|
325
|
-
//
|
|
325
|
+
// List tags
|
|
326
326
|
const tags = await client.blog.tags();
|
|
327
327
|
// Returns: string[] (always an array)
|
|
328
328
|
```
|
|
329
329
|
|
|
330
|
-
### Comments
|
|
330
|
+
### Comments
|
|
331
331
|
|
|
332
|
-
|
|
333
|
-
-
|
|
334
|
-
-
|
|
335
|
-
-
|
|
332
|
+
Three comment types are supported:
|
|
333
|
+
- **Board comments** (`board_post`)
|
|
334
|
+
- **Blog comments** (`blog_post`)
|
|
335
|
+
- **Guestbook/Standalone comments** (`page`)
|
|
336
336
|
|
|
337
337
|
```typescript
|
|
338
|
-
//
|
|
338
|
+
// Get board post comments
|
|
339
339
|
const { data: comments, meta } = await client.comments.boardPost(postId, {
|
|
340
340
|
page: 1,
|
|
341
341
|
per_page: 20,
|
|
342
342
|
});
|
|
343
343
|
// Returns: ListResponse<Comment>
|
|
344
344
|
|
|
345
|
-
//
|
|
345
|
+
// Create board post comment
|
|
346
346
|
await client.comments.createBoardPost(postId, {
|
|
347
|
-
author_name: '
|
|
347
|
+
author_name: 'John Doe',
|
|
348
348
|
author_email: 'user@example.com',
|
|
349
|
-
content: '
|
|
350
|
-
password: '1234', //
|
|
351
|
-
parent_id: null, //
|
|
352
|
-
is_secret: false, //
|
|
349
|
+
content: 'Comment content',
|
|
350
|
+
password: '1234', // For guest comments
|
|
351
|
+
parent_id: null, // Parent comment ID for replies
|
|
352
|
+
is_secret: false, // Secret comment flag
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
-
//
|
|
355
|
+
// Get blog post comments
|
|
356
356
|
const { data: blogComments } = await client.comments.blogPost('post-slug');
|
|
357
357
|
// Returns: ListResponse<Comment>
|
|
358
358
|
|
|
359
|
-
//
|
|
359
|
+
// Create blog post comment
|
|
360
360
|
await client.comments.createBlogPost('post-slug', {
|
|
361
361
|
author_name: 'Jane',
|
|
362
362
|
content: 'Great post!',
|
|
363
363
|
});
|
|
364
364
|
|
|
365
|
-
//
|
|
365
|
+
// Get guestbook comments (identified by page_slug)
|
|
366
366
|
const { data: guestbook } = await client.comments.standalone('guestbook');
|
|
367
367
|
// Returns: ListResponse<Comment>
|
|
368
368
|
|
|
369
|
-
//
|
|
369
|
+
// Create guestbook comment
|
|
370
370
|
await client.comments.createStandalone('guestbook', {
|
|
371
|
-
author_name: '
|
|
372
|
-
content: '
|
|
371
|
+
author_name: 'Visitor',
|
|
372
|
+
content: 'Hello!',
|
|
373
373
|
});
|
|
374
374
|
|
|
375
|
-
//
|
|
375
|
+
// Update comment
|
|
376
376
|
await client.comments.update(commentId, {
|
|
377
|
-
content: '
|
|
378
|
-
password: '1234', //
|
|
377
|
+
content: 'Updated comment',
|
|
378
|
+
password: '1234', // Required for guest comments
|
|
379
379
|
});
|
|
380
380
|
|
|
381
|
-
//
|
|
381
|
+
// Delete comment
|
|
382
382
|
await client.comments.delete(commentId, {
|
|
383
|
-
password: '1234', //
|
|
383
|
+
password: '1234', // Required for guest comments
|
|
384
384
|
});
|
|
385
385
|
|
|
386
|
-
//
|
|
386
|
+
// Like comment
|
|
387
387
|
const result = await client.comments.like(commentId);
|
|
388
388
|
// Returns: { data: { likes: number } }
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
### Shop
|
|
391
|
+
### Shop
|
|
392
392
|
|
|
393
|
-
#### Public (
|
|
393
|
+
#### Public (No Login Required)
|
|
394
394
|
|
|
395
395
|
```typescript
|
|
396
|
-
//
|
|
396
|
+
// List products
|
|
397
397
|
const { data: products, meta } = await client.shop.listProducts({
|
|
398
398
|
page: 1,
|
|
399
399
|
per_page: 10,
|
|
400
400
|
category: 'electronics', // optional
|
|
401
401
|
is_featured: true, // optional
|
|
402
|
-
search: '
|
|
402
|
+
search: 'keyword', // optional
|
|
403
403
|
});
|
|
404
404
|
// Returns: ListResponse<Product>
|
|
405
405
|
|
|
406
|
-
//
|
|
406
|
+
// Get product details
|
|
407
407
|
const product = await client.shop.getProduct('product-slug');
|
|
408
408
|
// Returns: Product
|
|
409
409
|
|
|
410
|
-
//
|
|
410
|
+
// Featured products
|
|
411
411
|
const featured = await client.shop.featuredProducts(8);
|
|
412
412
|
// Returns: Product[] (always an array)
|
|
413
413
|
|
|
414
|
-
//
|
|
414
|
+
// List categories
|
|
415
415
|
const categories = await client.shop.listCategories();
|
|
416
416
|
// Returns: ProductCategory[] (always an array)
|
|
417
417
|
```
|
|
418
418
|
|
|
419
|
-
#### Protected (
|
|
419
|
+
#### Protected (Login Required)
|
|
420
420
|
|
|
421
421
|
```typescript
|
|
422
|
-
//
|
|
422
|
+
// Get cart
|
|
423
423
|
const cart = await client.shop.getCart();
|
|
424
424
|
// Returns: Cart
|
|
425
425
|
|
|
426
|
-
//
|
|
426
|
+
// Add to cart
|
|
427
427
|
await client.shop.addToCart({
|
|
428
428
|
product_id: 1,
|
|
429
429
|
quantity: 2,
|
|
430
|
-
variant_id: 10, // optional -
|
|
430
|
+
variant_id: 10, // optional - for variant products
|
|
431
431
|
});
|
|
432
432
|
|
|
433
|
-
//
|
|
433
|
+
// Update cart item quantity
|
|
434
434
|
await client.shop.updateCartItem(itemId, { quantity: 3 });
|
|
435
435
|
|
|
436
|
-
//
|
|
436
|
+
// Remove from cart
|
|
437
437
|
await client.shop.removeFromCart(itemId);
|
|
438
438
|
|
|
439
|
-
//
|
|
439
|
+
// Clear cart
|
|
440
440
|
await client.shop.clearCart();
|
|
441
441
|
|
|
442
|
-
//
|
|
442
|
+
// Create order
|
|
443
443
|
const order = await client.shop.createOrder({
|
|
444
|
-
orderer_name: '
|
|
445
|
-
orderer_email: '
|
|
446
|
-
orderer_phone: '
|
|
447
|
-
shipping_name: '
|
|
448
|
-
shipping_phone: '
|
|
444
|
+
orderer_name: 'John Doe',
|
|
445
|
+
orderer_email: 'john@example.com',
|
|
446
|
+
orderer_phone: '555-123-4567',
|
|
447
|
+
shipping_name: 'John Doe',
|
|
448
|
+
shipping_phone: '555-123-4567',
|
|
449
449
|
shipping_zipcode: '12345',
|
|
450
|
-
shipping_address: '
|
|
451
|
-
shipping_address_detail: '101
|
|
452
|
-
shipping_memo: '
|
|
450
|
+
shipping_address: '123 Main St',
|
|
451
|
+
shipping_address_detail: 'Apt 101',
|
|
452
|
+
shipping_memo: 'Leave at door',
|
|
453
453
|
coupon_code: 'SAVE10', // optional
|
|
454
454
|
});
|
|
455
455
|
|
|
456
|
-
//
|
|
456
|
+
// List orders
|
|
457
457
|
const { data: orders, meta } = await client.shop.listOrders();
|
|
458
458
|
// Returns: ListResponse<Order>
|
|
459
459
|
|
|
460
|
-
//
|
|
460
|
+
// Get order details
|
|
461
461
|
const order = await client.shop.getOrder(orderId);
|
|
462
462
|
// Returns: Order
|
|
463
463
|
|
|
464
|
-
//
|
|
464
|
+
// Cancel order
|
|
465
465
|
await client.shop.cancelOrder(orderId);
|
|
466
466
|
|
|
467
|
-
//
|
|
467
|
+
// Validate coupon
|
|
468
468
|
const validation = await client.shop.validateCoupon('SAVE10', 50000);
|
|
469
469
|
// Returns: { valid: boolean, discount_amount: number, coupon: Coupon }
|
|
470
470
|
|
|
471
|
-
//
|
|
471
|
+
// My coupons
|
|
472
472
|
const coupons = await client.shop.myCoupons();
|
|
473
473
|
// Returns: Coupon[] (always an array)
|
|
474
474
|
```
|
|
475
475
|
|
|
476
|
-
### Reservation
|
|
476
|
+
### Reservation - NEW in v1.3.0
|
|
477
477
|
|
|
478
|
-
#### Public (
|
|
478
|
+
#### Public (No Login Required)
|
|
479
479
|
|
|
480
480
|
```typescript
|
|
481
|
-
//
|
|
481
|
+
// Get reservation settings
|
|
482
482
|
const settings = await client.reservation.getSettings();
|
|
483
483
|
// Returns: ReservationSettings
|
|
484
484
|
|
|
485
|
-
//
|
|
485
|
+
// List services
|
|
486
486
|
const services = await client.reservation.listServices();
|
|
487
487
|
// Returns: ReservationService[] (always an array)
|
|
488
488
|
|
|
489
|
-
//
|
|
489
|
+
// List staff
|
|
490
490
|
const staffs = await client.reservation.listStaff();
|
|
491
491
|
// Returns: ReservationStaff[] (always an array)
|
|
492
492
|
|
|
493
|
-
//
|
|
493
|
+
// Get staff for specific service
|
|
494
494
|
const serviceStaffs = await client.reservation.listStaff(serviceId);
|
|
495
495
|
|
|
496
|
-
//
|
|
496
|
+
// Get available dates
|
|
497
497
|
const dates = await client.reservation.getAvailableDates({
|
|
498
498
|
service_id: 1,
|
|
499
499
|
staff_id: 2, // optional
|
|
@@ -502,7 +502,7 @@ const dates = await client.reservation.getAvailableDates({
|
|
|
502
502
|
});
|
|
503
503
|
// Returns: string[] (YYYY-MM-DD format)
|
|
504
504
|
|
|
505
|
-
//
|
|
505
|
+
// Get available time slots
|
|
506
506
|
const slots = await client.reservation.getAvailableSlots({
|
|
507
507
|
service_id: 1,
|
|
508
508
|
date: '2026-01-15',
|
|
@@ -511,23 +511,23 @@ const slots = await client.reservation.getAvailableSlots({
|
|
|
511
511
|
// Returns: ReservationSlot[]
|
|
512
512
|
```
|
|
513
513
|
|
|
514
|
-
#### Protected (
|
|
514
|
+
#### Protected (Login Required)
|
|
515
515
|
|
|
516
516
|
```typescript
|
|
517
|
-
//
|
|
517
|
+
// Create reservation
|
|
518
518
|
const result = await client.reservation.create({
|
|
519
519
|
service_id: 1,
|
|
520
520
|
staff_id: 2, // optional
|
|
521
521
|
reservation_date: '2026-01-15',
|
|
522
522
|
start_time: '14:00',
|
|
523
|
-
customer_name: '
|
|
524
|
-
customer_phone: '
|
|
525
|
-
customer_email: '
|
|
526
|
-
customer_memo: '
|
|
523
|
+
customer_name: 'John Doe',
|
|
524
|
+
customer_phone: '555-123-4567', // optional
|
|
525
|
+
customer_email: 'john@example.com', // optional
|
|
526
|
+
customer_memo: 'Special requests', // optional
|
|
527
527
|
});
|
|
528
528
|
// Returns: { reservation: Reservation, requires_payment: boolean, deposit: number }
|
|
529
529
|
|
|
530
|
-
//
|
|
530
|
+
// List my reservations
|
|
531
531
|
const { data: reservations, meta } = await client.reservation.list({
|
|
532
532
|
status: 'confirmed', // optional
|
|
533
533
|
upcoming: true, // optional
|
|
@@ -535,124 +535,124 @@ const { data: reservations, meta } = await client.reservation.list({
|
|
|
535
535
|
});
|
|
536
536
|
// Returns: ListResponse<Reservation>
|
|
537
537
|
|
|
538
|
-
//
|
|
538
|
+
// Upcoming reservations
|
|
539
539
|
const upcoming = await client.reservation.upcoming(5);
|
|
540
540
|
// Returns: Reservation[] (always an array)
|
|
541
541
|
|
|
542
|
-
//
|
|
542
|
+
// Past reservations
|
|
543
543
|
const past = await client.reservation.past(10);
|
|
544
544
|
// Returns: Reservation[] (always an array)
|
|
545
545
|
|
|
546
|
-
//
|
|
546
|
+
// Get reservation details
|
|
547
547
|
const reservation = await client.reservation.get('RES-20260115-001');
|
|
548
548
|
// Returns: Reservation
|
|
549
549
|
|
|
550
|
-
//
|
|
551
|
-
const cancelled = await client.reservation.cancel('RES-20260115-001', '
|
|
550
|
+
// Cancel reservation
|
|
551
|
+
const cancelled = await client.reservation.cancel('RES-20260115-001', 'Schedule change');
|
|
552
552
|
// Returns: Reservation
|
|
553
553
|
```
|
|
554
554
|
|
|
555
|
-
### Auth (
|
|
555
|
+
### Auth (Authentication)
|
|
556
556
|
|
|
557
557
|
```typescript
|
|
558
|
-
//
|
|
558
|
+
// Login
|
|
559
559
|
const response = await client.auth.login({
|
|
560
560
|
email: 'user@example.com',
|
|
561
561
|
password: 'password',
|
|
562
562
|
});
|
|
563
563
|
// Returns: { member: Member, token: string }
|
|
564
|
-
//
|
|
564
|
+
// Token is automatically stored
|
|
565
565
|
|
|
566
|
-
//
|
|
566
|
+
// Register
|
|
567
567
|
await client.auth.register({
|
|
568
|
-
name: '
|
|
568
|
+
name: 'John Doe',
|
|
569
569
|
email: 'user@example.com',
|
|
570
570
|
password: 'password',
|
|
571
571
|
password_confirmation: 'password',
|
|
572
|
-
phone: '
|
|
572
|
+
phone: '555-123-4567', // optional
|
|
573
573
|
});
|
|
574
574
|
|
|
575
|
-
//
|
|
575
|
+
// Logout
|
|
576
576
|
await client.auth.logout();
|
|
577
577
|
|
|
578
|
-
//
|
|
578
|
+
// Get current user
|
|
579
579
|
const me = await client.auth.me();
|
|
580
580
|
// Returns: Member
|
|
581
581
|
|
|
582
|
-
//
|
|
582
|
+
// Update profile
|
|
583
583
|
await client.auth.updateProfile({
|
|
584
|
-
name: '
|
|
585
|
-
phone: '
|
|
584
|
+
name: 'New Name',
|
|
585
|
+
phone: '555-999-8888',
|
|
586
586
|
});
|
|
587
587
|
|
|
588
|
-
//
|
|
588
|
+
// Change password
|
|
589
589
|
await client.auth.updateProfile({
|
|
590
|
-
current_password: '
|
|
591
|
-
password: '
|
|
592
|
-
password_confirmation: '
|
|
590
|
+
current_password: 'current_password',
|
|
591
|
+
password: 'new_password',
|
|
592
|
+
password_confirmation: 'new_password',
|
|
593
593
|
});
|
|
594
594
|
|
|
595
|
-
//
|
|
595
|
+
// Check authentication status
|
|
596
596
|
client.isAuthenticated(); // true or false
|
|
597
597
|
|
|
598
|
-
//
|
|
598
|
+
// Set token directly (e.g., from localStorage)
|
|
599
599
|
client.setToken('saved-token');
|
|
600
600
|
|
|
601
|
-
//
|
|
601
|
+
// Get token
|
|
602
602
|
const token = client.getToken();
|
|
603
603
|
```
|
|
604
604
|
|
|
605
|
-
####
|
|
605
|
+
#### Social Login
|
|
606
606
|
|
|
607
607
|
```typescript
|
|
608
|
-
//
|
|
608
|
+
// Get social login providers
|
|
609
609
|
const providers = await client.auth.getSocialProviders();
|
|
610
610
|
// Returns: SocialProvider[]
|
|
611
611
|
|
|
612
|
-
//
|
|
612
|
+
// Get social auth URL
|
|
613
613
|
const { url } = await client.auth.getSocialAuthUrl('google');
|
|
614
|
-
//
|
|
614
|
+
// Redirect to this URL
|
|
615
615
|
|
|
616
|
-
//
|
|
616
|
+
// Handle callback (after redirect)
|
|
617
617
|
const response = await client.auth.socialCallback('google', code);
|
|
618
618
|
// Returns: { member: Member, token: string }
|
|
619
619
|
```
|
|
620
620
|
|
|
621
|
-
### Forms
|
|
621
|
+
### Forms
|
|
622
622
|
|
|
623
623
|
```typescript
|
|
624
|
-
//
|
|
624
|
+
// List forms
|
|
625
625
|
const { data: forms } = await client.forms.list();
|
|
626
626
|
// Returns: ListResponse<Form>
|
|
627
627
|
|
|
628
|
-
//
|
|
628
|
+
// Get form details
|
|
629
629
|
const form = await client.forms.get('contact');
|
|
630
|
-
// Returns: Form (
|
|
630
|
+
// Returns: Form (includes field definitions)
|
|
631
631
|
|
|
632
|
-
//
|
|
632
|
+
// Submit form (no login required)
|
|
633
633
|
await client.forms.submit('contact', {
|
|
634
|
-
name: '
|
|
634
|
+
name: 'John Doe',
|
|
635
635
|
email: 'user@example.com',
|
|
636
|
-
message: '
|
|
636
|
+
message: 'Inquiry content',
|
|
637
637
|
});
|
|
638
638
|
|
|
639
|
-
//
|
|
639
|
+
// My submissions (login required)
|
|
640
640
|
const { data: submissions } = await client.forms.mySubmissions();
|
|
641
641
|
// Returns: ListResponse<FormSubmission>
|
|
642
642
|
```
|
|
643
643
|
|
|
644
|
-
### Media
|
|
644
|
+
### Media - Protected
|
|
645
645
|
|
|
646
646
|
```typescript
|
|
647
|
-
//
|
|
647
|
+
// Upload file
|
|
648
648
|
const media = await client.media.upload(file); // File or Blob
|
|
649
649
|
// Returns: Media
|
|
650
650
|
|
|
651
|
-
//
|
|
651
|
+
// Upload multiple files
|
|
652
652
|
const mediaList = await client.media.uploadMultiple([file1, file2]);
|
|
653
653
|
// Returns: Media[]
|
|
654
654
|
|
|
655
|
-
//
|
|
655
|
+
// List my media
|
|
656
656
|
const { data: mediaList, meta } = await client.media.list({
|
|
657
657
|
page: 1,
|
|
658
658
|
per_page: 20,
|
|
@@ -660,94 +660,94 @@ const { data: mediaList, meta } = await client.media.list({
|
|
|
660
660
|
});
|
|
661
661
|
// Returns: ListResponse<Media>
|
|
662
662
|
|
|
663
|
-
//
|
|
663
|
+
// Delete media
|
|
664
664
|
await client.media.delete(mediaId);
|
|
665
665
|
```
|
|
666
666
|
|
|
667
|
-
### Entities (
|
|
667
|
+
### Entities (Custom Entities) - Dynamic Data Structures
|
|
668
668
|
|
|
669
|
-
|
|
669
|
+
Create entity definitions and manage data directly from the API/SDK.
|
|
670
670
|
|
|
671
671
|
#### Entity Definition CRUD
|
|
672
672
|
|
|
673
673
|
```typescript
|
|
674
|
-
//
|
|
674
|
+
// List entities
|
|
675
675
|
const entities = await client.entities.list();
|
|
676
676
|
// Returns: CustomEntity[] (always an array)
|
|
677
677
|
|
|
678
|
-
//
|
|
678
|
+
// Create entity definition
|
|
679
679
|
const entity = await client.entities.create({
|
|
680
|
-
name: '
|
|
680
|
+
name: 'Customer',
|
|
681
681
|
slug: 'customers',
|
|
682
|
-
description: '
|
|
682
|
+
description: 'Customer management',
|
|
683
683
|
schema: {
|
|
684
684
|
fields: [
|
|
685
|
-
{ name: 'company', label: '
|
|
686
|
-
{ name: 'email', label: '
|
|
687
|
-
{ name: 'status', label: '
|
|
688
|
-
{ value: 'active', label: '
|
|
689
|
-
{ value: 'inactive', label: '
|
|
685
|
+
{ name: 'company', label: 'Company Name', type: 'text', required: true },
|
|
686
|
+
{ name: 'email', label: 'Email', type: 'email', required: true },
|
|
687
|
+
{ name: 'status', label: 'Status', type: 'select', options: [
|
|
688
|
+
{ value: 'active', label: 'Active' },
|
|
689
|
+
{ value: 'inactive', label: 'Inactive' }
|
|
690
690
|
]}
|
|
691
691
|
]
|
|
692
692
|
},
|
|
693
693
|
icon: 'users'
|
|
694
694
|
});
|
|
695
695
|
|
|
696
|
-
//
|
|
696
|
+
// Get entity definition (includes schema)
|
|
697
697
|
const entity = await client.entities.get('customers');
|
|
698
698
|
// Returns: CustomEntity (includes schema)
|
|
699
699
|
|
|
700
|
-
//
|
|
700
|
+
// Update entity definition
|
|
701
701
|
await client.entities.update('customers', {
|
|
702
|
-
name: '
|
|
703
|
-
description: '
|
|
702
|
+
name: 'Clients',
|
|
703
|
+
description: 'Client management'
|
|
704
704
|
});
|
|
705
705
|
|
|
706
|
-
//
|
|
707
|
-
await client.entities.delete('customers'); //
|
|
708
|
-
await client.entities.delete('customers', true); //
|
|
706
|
+
// Delete entity definition (requires force if records exist)
|
|
707
|
+
await client.entities.delete('customers'); // When no records exist
|
|
708
|
+
await client.entities.delete('customers', true); // Force delete with records
|
|
709
709
|
```
|
|
710
710
|
|
|
711
711
|
#### Record CRUD
|
|
712
712
|
|
|
713
713
|
```typescript
|
|
714
|
-
//
|
|
714
|
+
// List records
|
|
715
715
|
const { data: customers, meta } = await client.entities.listRecords('customers', {
|
|
716
716
|
page: 1,
|
|
717
717
|
per_page: 20,
|
|
718
|
-
search: 'ACME', //
|
|
719
|
-
sort: 'company', //
|
|
720
|
-
dir: 'asc', //
|
|
721
|
-
filters: JSON.stringify({ status: 'active' }) // JSON
|
|
718
|
+
search: 'ACME', // Search
|
|
719
|
+
sort: 'company', // Sort field
|
|
720
|
+
dir: 'asc', // Sort direction
|
|
721
|
+
filters: JSON.stringify({ status: 'active' }) // JSON filter
|
|
722
722
|
});
|
|
723
723
|
// Returns: ListResponse<EntityRecord>
|
|
724
724
|
|
|
725
|
-
//
|
|
725
|
+
// Get single record
|
|
726
726
|
const customer = await client.entities.getRecord('customers', 1);
|
|
727
727
|
// Returns: EntityRecord
|
|
728
728
|
console.log(customer.data.company); // 'ABC Corp'
|
|
729
729
|
|
|
730
|
-
//
|
|
730
|
+
// Create record (pass schema fields directly)
|
|
731
731
|
const newCustomer = await client.entities.createRecord('customers', {
|
|
732
732
|
company: 'ABC Corp',
|
|
733
733
|
email: 'contact@abc.com',
|
|
734
734
|
status: 'active',
|
|
735
735
|
});
|
|
736
736
|
|
|
737
|
-
//
|
|
737
|
+
// Update record (partial update - merges with existing data)
|
|
738
738
|
await client.entities.updateRecord('customers', 1, {
|
|
739
739
|
status: 'inactive',
|
|
740
740
|
email: 'new@abc.com'
|
|
741
741
|
});
|
|
742
742
|
|
|
743
|
-
//
|
|
743
|
+
// Delete record
|
|
744
744
|
await client.entities.deleteRecord('customers', 1);
|
|
745
745
|
```
|
|
746
746
|
|
|
747
|
-
#### TypeScript
|
|
747
|
+
#### TypeScript Type Support
|
|
748
748
|
|
|
749
749
|
```typescript
|
|
750
|
-
//
|
|
750
|
+
// Typed entity accessor
|
|
751
751
|
interface Customer {
|
|
752
752
|
company: string;
|
|
753
753
|
email: string;
|
|
@@ -756,14 +756,14 @@ interface Customer {
|
|
|
756
756
|
|
|
757
757
|
const customers = client.entities.typed<Customer>('customer');
|
|
758
758
|
|
|
759
|
-
//
|
|
759
|
+
// Type inference
|
|
760
760
|
const list = await customers.list();
|
|
761
761
|
list.data[0].data.company; // string
|
|
762
762
|
|
|
763
763
|
const record = await customers.get(1);
|
|
764
764
|
record.data.tier; // 'standard' | 'vip'
|
|
765
765
|
|
|
766
|
-
//
|
|
766
|
+
// Type checking on create/update
|
|
767
767
|
await customers.create({
|
|
768
768
|
company: 'New Corp',
|
|
769
769
|
email: 'new@corp.com',
|
|
@@ -774,11 +774,11 @@ await customers.create({
|
|
|
774
774
|
### Site Settings
|
|
775
775
|
|
|
776
776
|
```typescript
|
|
777
|
-
//
|
|
777
|
+
// Get theme settings
|
|
778
778
|
const theme = await client.getTheme();
|
|
779
779
|
// Returns: { name, colors, fonts }
|
|
780
780
|
|
|
781
|
-
//
|
|
781
|
+
// Get site settings
|
|
782
782
|
const settings = await client.getSettings();
|
|
783
783
|
// Returns: Record<string, any>
|
|
784
784
|
```
|
|
@@ -998,7 +998,7 @@ const client = new Promptly({
|
|
|
998
998
|
baseUrl: 'https://promptly.webbyon.com',
|
|
999
999
|
});
|
|
1000
1000
|
|
|
1001
|
-
//
|
|
1001
|
+
// Blog post list (with pagination)
|
|
1002
1002
|
function BlogList() {
|
|
1003
1003
|
const [posts, setPosts] = useState([]);
|
|
1004
1004
|
const [meta, setMeta] = useState(null);
|
|
@@ -1042,7 +1042,7 @@ function BlogList() {
|
|
|
1042
1042
|
);
|
|
1043
1043
|
}
|
|
1044
1044
|
|
|
1045
|
-
//
|
|
1045
|
+
// Reservation form
|
|
1046
1046
|
function ReservationForm() {
|
|
1047
1047
|
const [services, setServices] = useState([]);
|
|
1048
1048
|
const [selectedService, setSelectedService] = useState(null);
|
|
@@ -1072,7 +1072,7 @@ function ReservationForm() {
|
|
|
1072
1072
|
return (
|
|
1073
1073
|
<div>
|
|
1074
1074
|
<select onChange={e => setSelectedService(Number(e.target.value))}>
|
|
1075
|
-
<option
|
|
1075
|
+
<option>Select a service</option>
|
|
1076
1076
|
{services.map(s => (
|
|
1077
1077
|
<option key={s.id} value={s.id}>{s.name}</option>
|
|
1078
1078
|
))}
|
package/dist/index.d.mts
CHANGED
|
@@ -794,6 +794,7 @@ declare class HttpClient {
|
|
|
794
794
|
private timeout;
|
|
795
795
|
private token;
|
|
796
796
|
private apiKey;
|
|
797
|
+
private cartSessionId;
|
|
797
798
|
constructor(config: PromptlyConfig);
|
|
798
799
|
/**
|
|
799
800
|
* Set authentication token
|
|
@@ -815,6 +816,14 @@ declare class HttpClient {
|
|
|
815
816
|
* Get current API key
|
|
816
817
|
*/
|
|
817
818
|
getApiKey(): string | null;
|
|
819
|
+
/**
|
|
820
|
+
* Set cart session ID (for guest cart persistence)
|
|
821
|
+
*/
|
|
822
|
+
setCartSessionId(sessionId: string | null): void;
|
|
823
|
+
/**
|
|
824
|
+
* Get cart session ID
|
|
825
|
+
*/
|
|
826
|
+
getCartSessionId(): string | null;
|
|
818
827
|
/**
|
|
819
828
|
* Build full URL with query params
|
|
820
829
|
*/
|
|
@@ -1146,6 +1155,10 @@ declare class ShopResource {
|
|
|
1146
1155
|
* @returns ListResponse with data array and pagination meta
|
|
1147
1156
|
*/
|
|
1148
1157
|
categoryProducts(categoryIdOrSlug: number | string, params?: Omit<ProductListParams, 'category'>): Promise<ListResponse<Product>>;
|
|
1158
|
+
/**
|
|
1159
|
+
* Save cart session ID from response (for guest cart persistence)
|
|
1160
|
+
*/
|
|
1161
|
+
private saveCartSession;
|
|
1149
1162
|
/**
|
|
1150
1163
|
* Get current cart
|
|
1151
1164
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -794,6 +794,7 @@ declare class HttpClient {
|
|
|
794
794
|
private timeout;
|
|
795
795
|
private token;
|
|
796
796
|
private apiKey;
|
|
797
|
+
private cartSessionId;
|
|
797
798
|
constructor(config: PromptlyConfig);
|
|
798
799
|
/**
|
|
799
800
|
* Set authentication token
|
|
@@ -815,6 +816,14 @@ declare class HttpClient {
|
|
|
815
816
|
* Get current API key
|
|
816
817
|
*/
|
|
817
818
|
getApiKey(): string | null;
|
|
819
|
+
/**
|
|
820
|
+
* Set cart session ID (for guest cart persistence)
|
|
821
|
+
*/
|
|
822
|
+
setCartSessionId(sessionId: string | null): void;
|
|
823
|
+
/**
|
|
824
|
+
* Get cart session ID
|
|
825
|
+
*/
|
|
826
|
+
getCartSessionId(): string | null;
|
|
818
827
|
/**
|
|
819
828
|
* Build full URL with query params
|
|
820
829
|
*/
|
|
@@ -1146,6 +1155,10 @@ declare class ShopResource {
|
|
|
1146
1155
|
* @returns ListResponse with data array and pagination meta
|
|
1147
1156
|
*/
|
|
1148
1157
|
categoryProducts(categoryIdOrSlug: number | string, params?: Omit<ProductListParams, 'category'>): Promise<ListResponse<Product>>;
|
|
1158
|
+
/**
|
|
1159
|
+
* Save cart session ID from response (for guest cart persistence)
|
|
1160
|
+
*/
|
|
1161
|
+
private saveCartSession;
|
|
1149
1162
|
/**
|
|
1150
1163
|
* Get current cart
|
|
1151
1164
|
*/
|
package/dist/index.js
CHANGED
|
@@ -71,10 +71,14 @@ var HttpClient = class {
|
|
|
71
71
|
constructor(config) {
|
|
72
72
|
this.token = null;
|
|
73
73
|
this.apiKey = null;
|
|
74
|
+
this.cartSessionId = null;
|
|
74
75
|
this.tenantId = config.tenantId;
|
|
75
76
|
this.baseUrl = (config.baseUrl || "https://promptly.webbyon.com").replace(/\/$/, "");
|
|
76
77
|
this.timeout = config.timeout || 3e4;
|
|
77
78
|
this.apiKey = config.apiKey || null;
|
|
79
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
80
|
+
this.cartSessionId = localStorage.getItem(`promptly_cart_session_${this.tenantId}`);
|
|
81
|
+
}
|
|
78
82
|
}
|
|
79
83
|
/**
|
|
80
84
|
* Set authentication token
|
|
@@ -106,6 +110,25 @@ var HttpClient = class {
|
|
|
106
110
|
getApiKey() {
|
|
107
111
|
return this.apiKey;
|
|
108
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Set cart session ID (for guest cart persistence)
|
|
115
|
+
*/
|
|
116
|
+
setCartSessionId(sessionId) {
|
|
117
|
+
this.cartSessionId = sessionId;
|
|
118
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
119
|
+
if (sessionId) {
|
|
120
|
+
localStorage.setItem(`promptly_cart_session_${this.tenantId}`, sessionId);
|
|
121
|
+
} else {
|
|
122
|
+
localStorage.removeItem(`promptly_cart_session_${this.tenantId}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get cart session ID
|
|
128
|
+
*/
|
|
129
|
+
getCartSessionId() {
|
|
130
|
+
return this.cartSessionId;
|
|
131
|
+
}
|
|
109
132
|
/**
|
|
110
133
|
* Build full URL with query params
|
|
111
134
|
*/
|
|
@@ -136,6 +159,9 @@ var HttpClient = class {
|
|
|
136
159
|
if (this.token) {
|
|
137
160
|
headers["Authorization"] = `Bearer ${this.token}`;
|
|
138
161
|
}
|
|
162
|
+
if (this.cartSessionId) {
|
|
163
|
+
headers["X-Cart-Session"] = this.cartSessionId;
|
|
164
|
+
}
|
|
139
165
|
return headers;
|
|
140
166
|
}
|
|
141
167
|
/**
|
|
@@ -712,35 +738,49 @@ var ShopResource = class {
|
|
|
712
738
|
// ============================================
|
|
713
739
|
// Cart
|
|
714
740
|
// ============================================
|
|
741
|
+
/**
|
|
742
|
+
* Save cart session ID from response (for guest cart persistence)
|
|
743
|
+
*/
|
|
744
|
+
saveCartSession(cart) {
|
|
745
|
+
if (cart.session_id) {
|
|
746
|
+
this.http.setCartSessionId(cart.session_id);
|
|
747
|
+
}
|
|
748
|
+
return cart;
|
|
749
|
+
}
|
|
715
750
|
/**
|
|
716
751
|
* Get current cart
|
|
717
752
|
*/
|
|
718
753
|
async getCart() {
|
|
719
|
-
|
|
754
|
+
const cart = await this.http.get("/cart");
|
|
755
|
+
return this.saveCartSession(cart);
|
|
720
756
|
}
|
|
721
757
|
/**
|
|
722
758
|
* Add item to cart
|
|
723
759
|
*/
|
|
724
760
|
async addToCart(data) {
|
|
725
|
-
|
|
761
|
+
const cart = await this.http.post("/cart/items", data);
|
|
762
|
+
return this.saveCartSession(cart);
|
|
726
763
|
}
|
|
727
764
|
/**
|
|
728
765
|
* Update cart item quantity
|
|
729
766
|
*/
|
|
730
767
|
async updateCartItem(itemId, data) {
|
|
731
|
-
|
|
768
|
+
const cart = await this.http.put(`/cart/items/${itemId}`, data);
|
|
769
|
+
return this.saveCartSession(cart);
|
|
732
770
|
}
|
|
733
771
|
/**
|
|
734
772
|
* Remove item from cart
|
|
735
773
|
*/
|
|
736
774
|
async removeFromCart(itemId) {
|
|
737
|
-
|
|
775
|
+
const cart = await this.http.delete(`/cart/items/${itemId}`);
|
|
776
|
+
return this.saveCartSession(cart);
|
|
738
777
|
}
|
|
739
778
|
/**
|
|
740
779
|
* Clear entire cart
|
|
741
780
|
*/
|
|
742
781
|
async clearCart() {
|
|
743
|
-
|
|
782
|
+
await this.http.delete("/cart");
|
|
783
|
+
this.http.setCartSessionId(null);
|
|
744
784
|
}
|
|
745
785
|
// ============================================
|
|
746
786
|
// Orders (Protected)
|
package/dist/index.mjs
CHANGED
|
@@ -43,10 +43,14 @@ var HttpClient = class {
|
|
|
43
43
|
constructor(config) {
|
|
44
44
|
this.token = null;
|
|
45
45
|
this.apiKey = null;
|
|
46
|
+
this.cartSessionId = null;
|
|
46
47
|
this.tenantId = config.tenantId;
|
|
47
48
|
this.baseUrl = (config.baseUrl || "https://promptly.webbyon.com").replace(/\/$/, "");
|
|
48
49
|
this.timeout = config.timeout || 3e4;
|
|
49
50
|
this.apiKey = config.apiKey || null;
|
|
51
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
52
|
+
this.cartSessionId = localStorage.getItem(`promptly_cart_session_${this.tenantId}`);
|
|
53
|
+
}
|
|
50
54
|
}
|
|
51
55
|
/**
|
|
52
56
|
* Set authentication token
|
|
@@ -78,6 +82,25 @@ var HttpClient = class {
|
|
|
78
82
|
getApiKey() {
|
|
79
83
|
return this.apiKey;
|
|
80
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Set cart session ID (for guest cart persistence)
|
|
87
|
+
*/
|
|
88
|
+
setCartSessionId(sessionId) {
|
|
89
|
+
this.cartSessionId = sessionId;
|
|
90
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
91
|
+
if (sessionId) {
|
|
92
|
+
localStorage.setItem(`promptly_cart_session_${this.tenantId}`, sessionId);
|
|
93
|
+
} else {
|
|
94
|
+
localStorage.removeItem(`promptly_cart_session_${this.tenantId}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get cart session ID
|
|
100
|
+
*/
|
|
101
|
+
getCartSessionId() {
|
|
102
|
+
return this.cartSessionId;
|
|
103
|
+
}
|
|
81
104
|
/**
|
|
82
105
|
* Build full URL with query params
|
|
83
106
|
*/
|
|
@@ -108,6 +131,9 @@ var HttpClient = class {
|
|
|
108
131
|
if (this.token) {
|
|
109
132
|
headers["Authorization"] = `Bearer ${this.token}`;
|
|
110
133
|
}
|
|
134
|
+
if (this.cartSessionId) {
|
|
135
|
+
headers["X-Cart-Session"] = this.cartSessionId;
|
|
136
|
+
}
|
|
111
137
|
return headers;
|
|
112
138
|
}
|
|
113
139
|
/**
|
|
@@ -684,35 +710,49 @@ var ShopResource = class {
|
|
|
684
710
|
// ============================================
|
|
685
711
|
// Cart
|
|
686
712
|
// ============================================
|
|
713
|
+
/**
|
|
714
|
+
* Save cart session ID from response (for guest cart persistence)
|
|
715
|
+
*/
|
|
716
|
+
saveCartSession(cart) {
|
|
717
|
+
if (cart.session_id) {
|
|
718
|
+
this.http.setCartSessionId(cart.session_id);
|
|
719
|
+
}
|
|
720
|
+
return cart;
|
|
721
|
+
}
|
|
687
722
|
/**
|
|
688
723
|
* Get current cart
|
|
689
724
|
*/
|
|
690
725
|
async getCart() {
|
|
691
|
-
|
|
726
|
+
const cart = await this.http.get("/cart");
|
|
727
|
+
return this.saveCartSession(cart);
|
|
692
728
|
}
|
|
693
729
|
/**
|
|
694
730
|
* Add item to cart
|
|
695
731
|
*/
|
|
696
732
|
async addToCart(data) {
|
|
697
|
-
|
|
733
|
+
const cart = await this.http.post("/cart/items", data);
|
|
734
|
+
return this.saveCartSession(cart);
|
|
698
735
|
}
|
|
699
736
|
/**
|
|
700
737
|
* Update cart item quantity
|
|
701
738
|
*/
|
|
702
739
|
async updateCartItem(itemId, data) {
|
|
703
|
-
|
|
740
|
+
const cart = await this.http.put(`/cart/items/${itemId}`, data);
|
|
741
|
+
return this.saveCartSession(cart);
|
|
704
742
|
}
|
|
705
743
|
/**
|
|
706
744
|
* Remove item from cart
|
|
707
745
|
*/
|
|
708
746
|
async removeFromCart(itemId) {
|
|
709
|
-
|
|
747
|
+
const cart = await this.http.delete(`/cart/items/${itemId}`);
|
|
748
|
+
return this.saveCartSession(cart);
|
|
710
749
|
}
|
|
711
750
|
/**
|
|
712
751
|
* Clear entire cart
|
|
713
752
|
*/
|
|
714
753
|
async clearCart() {
|
|
715
|
-
|
|
754
|
+
await this.http.delete("/cart");
|
|
755
|
+
this.http.setCartSessionId(null);
|
|
716
756
|
}
|
|
717
757
|
// ============================================
|
|
718
758
|
// Orders (Protected)
|