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