lua-cli 3.0.0-alpha.1 → 3.0.0-alpha.5

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.
Files changed (61) hide show
  1. package/dist/api/job.api.service.d.ts +16 -7
  2. package/dist/api/job.api.service.js +21 -5
  3. package/dist/api/postprocessor.api.service.d.ts +61 -1
  4. package/dist/api/postprocessor.api.service.js +35 -0
  5. package/dist/api/preprocessor.api.service.d.ts +61 -1
  6. package/dist/api/preprocessor.api.service.js +35 -0
  7. package/dist/api-exports.d.ts +26 -6
  8. package/dist/api-exports.js +42 -29
  9. package/dist/cli/command-definitions.js +13 -6
  10. package/dist/commands/chat.js +32 -5
  11. package/dist/commands/compile.js +16 -2
  12. package/dist/commands/dev.js +23 -2
  13. package/dist/commands/push.d.ts +6 -2
  14. package/dist/commands/push.js +412 -6
  15. package/dist/commands/test.js +18 -2
  16. package/dist/common/job.instance.d.ts +3 -0
  17. package/dist/common/job.instance.js +8 -0
  18. package/dist/config/constants.d.ts +6 -5
  19. package/dist/config/constants.js +12 -10
  20. package/dist/interfaces/chat.d.ts +30 -1
  21. package/dist/interfaces/jobs.d.ts +21 -0
  22. package/dist/types/skill.d.ts +75 -56
  23. package/dist/types/skill.js +53 -59
  24. package/dist/utils/bundling.d.ts +13 -4
  25. package/dist/utils/bundling.js +83 -26
  26. package/dist/utils/compile.js +27 -6
  27. package/dist/utils/dev-api.d.ts +42 -2
  28. package/dist/utils/dev-api.js +177 -4
  29. package/dist/utils/dev-server.d.ts +1 -1
  30. package/dist/utils/dev-server.js +4 -4
  31. package/dist/utils/dynamic-job-bundler.d.ts +17 -0
  32. package/dist/utils/dynamic-job-bundler.js +143 -0
  33. package/dist/utils/pre-bundle-jobs.d.ts +26 -0
  34. package/dist/utils/pre-bundle-jobs.js +176 -0
  35. package/dist/utils/sandbox-storage.d.ts +48 -0
  36. package/dist/utils/sandbox-storage.js +114 -0
  37. package/dist/utils/sandbox.d.ts +2 -2
  38. package/dist/utils/sandbox.js +23 -7
  39. package/package.json +1 -1
  40. package/template/lua.skill.yaml +47 -0
  41. package/template/package-lock.json +10505 -0
  42. package/template/package.json +2 -1
  43. package/template/src/index.ts +65 -3
  44. package/template/src/tools/CreateInlineJob.ts +42 -0
  45. package/API_REFERENCE.md +0 -1408
  46. package/CHANGELOG.md +0 -236
  47. package/CLI_REFERENCE.md +0 -908
  48. package/GETTING_STARTED.md +0 -1040
  49. package/INSTANCE_TYPES.md +0 -1158
  50. package/README.md +0 -865
  51. package/TEMPLATE_GUIDE.md +0 -1398
  52. package/USER_DATA_INSTANCE.md +0 -621
  53. package/template/AGENT_CONFIGURATION.md +0 -251
  54. package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
  55. package/template/DYNAMIC_JOB_CREATION.md +0 -371
  56. package/template/TOOL_EXAMPLES.md +0 -655
  57. package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
  58. package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
  59. package/template/src/index-agent-example.ts +0 -201
  60. package/template/src/postprocessors/ResponseFormatter.ts +0 -151
  61. package/template/src/preprocessors/MessageFilter.ts +0 -91
package/INSTANCE_TYPES.md DELETED
@@ -1,1158 +0,0 @@
1
- # Instance Types API Reference
2
-
3
- Complete guide to all instance types in lua-cli, when they're returned, and how to use them.
4
-
5
- ## Table of Contents
6
-
7
- - [Overview](#overview)
8
- - [UserDataInstance](#userdatainstance)
9
- - [ProductInstance](#productinstance)
10
- - [ProductSearchInstance](#productsearchinstance)
11
- - [ProductPaginationInstance](#productpaginationinstance)
12
- - [BasketInstance](#basketinstance)
13
- - [OrderInstance](#orderinstance)
14
- - [DataEntryInstance](#dataentryinstance)
15
- - [Common Patterns](#common-patterns)
16
- - [TypeScript Support](#typescript-support)
17
-
18
- ---
19
-
20
- ## Overview
21
-
22
- All instance classes in lua-cli now support **direct property access** via JavaScript Proxy. This means you can access nested data properties directly without going through `.data` or `.common` objects.
23
-
24
- ### Key Features
25
-
26
- ✅ **Direct Property Access** - `instance.name` instead of `instance.data.name`
27
- ✅ **Backward Compatible** - Old patterns still work
28
- ✅ **Type Safe** - Full TypeScript support
29
- ✅ **Array Methods** - Collections support `.map()`, `.filter()`, etc.
30
- ✅ **Iteration** - Use `for...of` loops and spread operators
31
-
32
- ---
33
-
34
- ## UserDataInstance
35
-
36
- User-specific data storage with automatic sanitization.
37
-
38
- ### When It's Returned
39
-
40
- ```typescript
41
- // Available in tool context
42
- class MyTool extends LuaTool {
43
- async execute(input: any, context: ToolContext) {
44
- const user = context.user; // UserDataInstance
45
- }
46
- }
47
- ```
48
-
49
- ### Properties
50
-
51
- - **`data`** - The sanitized user data object
52
- - All user data fields accessible directly
53
-
54
- ### Methods
55
-
56
- #### `update(data: Record<string, any>): Promise<any>`
57
-
58
- Updates user data on the server.
59
-
60
- ```typescript
61
- await user.update({
62
- name: "John Doe",
63
- email: "john@example.com",
64
- preferences: {
65
- theme: "dark",
66
- notifications: true
67
- }
68
- });
69
- ```
70
-
71
- #### `clear(): Promise<boolean>`
72
-
73
- Clears all user data.
74
-
75
- ```typescript
76
- await user.clear();
77
- ```
78
-
79
- ### Usage Examples
80
-
81
- ```typescript
82
- // Direct property access
83
- const name = user.name;
84
- const email = user.email;
85
- const prefs = user.preferences;
86
-
87
- // Setting properties (local only)
88
- user.favoriteColor = "blue";
89
-
90
- // Persist to server
91
- await user.update({ favoriteColor: user.favoriteColor });
92
-
93
- // Check property existence
94
- if ('preferences' in user) {
95
- console.log('User has preferences');
96
- }
97
-
98
- // Get all keys
99
- const keys = Object.keys(user);
100
- ```
101
-
102
- ### Data Sanitization
103
-
104
- The following fields are automatically removed:
105
- - `agentId`
106
- - `userId`
107
-
108
- All other fields are accessible including custom data, preferences, and metadata.
109
-
110
- ---
111
-
112
- ## ProductInstance
113
-
114
- Individual product with update and delete capabilities.
115
-
116
- ### When It's Returned
117
-
118
- ```typescript
119
- // From product search
120
- const results = await products.search("laptop");
121
- const product = results.products[0]; // ProductInstance
122
-
123
- // From pagination
124
- const page = await products.get(1, 10);
125
- const product = page.products[0]; // ProductInstance
126
-
127
- // From create
128
- const newProduct = await products.create({
129
- name: "Gaming Laptop",
130
- price: 1299.99
131
- }); // ProductInstance
132
- ```
133
-
134
- ### Properties
135
-
136
- - **`data`** - The product data object
137
- - All product fields accessible directly (name, price, sku, etc.)
138
-
139
- ### Methods
140
-
141
- #### `update(data: Record<string, any>): Promise<Product>`
142
-
143
- Updates the product data.
144
-
145
- ```typescript
146
- await product.update({
147
- price: 999.99,
148
- stock: 50,
149
- description: "Updated description"
150
- });
151
- ```
152
-
153
- #### `delete(): Promise<Product>`
154
-
155
- Deletes the product from the catalog.
156
-
157
- ```typescript
158
- await product.delete();
159
- ```
160
-
161
- ### Usage Examples
162
-
163
- ```typescript
164
- // Direct property access
165
- const name = product.name;
166
- const price = product.price;
167
- const sku = product.sku;
168
- const inStock = product.stock > 0;
169
-
170
- // Update product
171
- await product.update({
172
- price: product.price * 0.9, // 10% discount
173
- onSale: true
174
- });
175
-
176
- // Conditional operations
177
- if (product.stock < 10) {
178
- await product.update({ lowStock: true });
179
- }
180
-
181
- // Delete out of stock items
182
- if (product.stock === 0) {
183
- await product.delete();
184
- }
185
-
186
- // Console output shows clean data
187
- console.log(product);
188
- // { name: "Gaming Laptop", price: 1299.99, sku: "LAP-001", ... }
189
- ```
190
-
191
- ### Backward Compatibility
192
-
193
- ```typescript
194
- // Both work:
195
- product.name; // ✅ New way
196
- product.data.name; // ✅ Old way still works
197
- ```
198
-
199
- ---
200
-
201
- ## ProductSearchInstance
202
-
203
- Collection of products from a search query with array-like methods.
204
-
205
- ### When It's Returned
206
-
207
- ```typescript
208
- // From search operations
209
- const results = await products.search("laptop");
210
- // Returns ProductSearchInstance
211
- ```
212
-
213
- ### Properties
214
-
215
- - **`products`** - Array of ProductInstance objects
216
- - **`length`** - Number of products (getter)
217
-
218
- ### Array Methods
219
-
220
- All standard array methods are available:
221
-
222
- - `map<T>(callback)` - Transform each product
223
- - `filter(callback)` - Filter products
224
- - `forEach(callback)` - Iterate over products
225
- - `find(callback)` - Find first matching product
226
- - `findIndex(callback)` - Find index of product
227
- - `some(callback)` - Test if some match
228
- - `every(callback)` - Test if all match
229
- - `reduce<T>(callback, initial)` - Reduce to single value
230
- - `[Symbol.iterator]()` - Make iterable
231
-
232
- ### Usage Examples
233
-
234
- ```typescript
235
- // Search for products
236
- const results = await products.search("laptop");
237
-
238
- // Direct array methods
239
- const names = results.map(p => p.name);
240
- const expensive = results.filter(p => p.price > 1000);
241
- const cheapest = results.reduce((min, p) =>
242
- p.price < min.price ? p : min
243
- );
244
-
245
- // Check length
246
- if (results.length > 0) {
247
- console.log(`Found ${results.length} products`);
248
- }
249
-
250
- // Find specific product
251
- const product = results.find(p => p.sku === "LAP-001");
252
-
253
- // For...of iteration
254
- for (const product of results) {
255
- console.log(`${product.name}: $${product.price}`);
256
- }
257
-
258
- // Spread operator
259
- const allProducts = [...results];
260
-
261
- // Array destructuring
262
- const [first, second, ...rest] = results;
263
-
264
- // Check if any match
265
- const hasExpensive = results.some(p => p.price > 2000);
266
- const allInStock = results.every(p => p.stock > 0);
267
-
268
- // forEach for side effects
269
- results.forEach(async (product) => {
270
- if (product.stock < 5) {
271
- await product.update({ lowStock: true });
272
- }
273
- });
274
-
275
- // Calculate total value
276
- const totalValue = results.reduce((sum, p) =>
277
- sum + (p.price * p.stock), 0
278
- );
279
-
280
- // Chain methods
281
- const availableNames = results
282
- .filter(p => p.stock > 0)
283
- .map(p => p.name)
284
- .sort();
285
- ```
286
-
287
- ### Backward Compatibility
288
-
289
- ```typescript
290
- // Both work:
291
- results.map(p => p.name); // ✅ New way
292
- results.products.map(p => p.name); // ✅ Old way still works
293
- ```
294
-
295
- ---
296
-
297
- ## ProductPaginationInstance
298
-
299
- Paginated collection of products with navigation methods.
300
-
301
- ### When It's Returned
302
-
303
- ```typescript
304
- // From get operations with pagination
305
- const page = await products.get(1, 10);
306
- // Returns ProductPaginationInstance
307
-
308
- // From nextPage/prevPage calls
309
- const nextPage = await page.nextPage();
310
- // Returns ProductPaginationInstance
311
- ```
312
-
313
- ### Properties
314
-
315
- - **`products`** - Array of ProductInstance objects
316
- - **`pagination`** - Pagination metadata object:
317
- - `currentPage` - Current page number
318
- - `totalPages` - Total number of pages
319
- - `totalCount` - Total number of products
320
- - `limit` - Items per page
321
- - `hasNextPage` - Whether next page exists
322
- - `hasPrevPage` - Whether previous page exists
323
- - `nextPage` - Next page number or null
324
- - `prevPage` - Previous page number or null
325
- - **`length`** - Number of products on current page (getter)
326
-
327
- ### Array Methods
328
-
329
- Same as ProductSearchInstance:
330
- - `map`, `filter`, `forEach`, `find`, `findIndex`, `some`, `every`, `reduce`, `[Symbol.iterator]`
331
-
332
- ### Methods
333
-
334
- #### `nextPage(): Promise<ProductPaginationInstance>`
335
-
336
- Fetches the next page of products.
337
-
338
- ```typescript
339
- if (page.pagination.hasNextPage) {
340
- const next = await page.nextPage();
341
- }
342
- ```
343
-
344
- #### `prevPage(): Promise<ProductPaginationInstance>`
345
-
346
- Fetches the previous page of products.
347
-
348
- ```typescript
349
- if (page.pagination.hasPrevPage) {
350
- const prev = await page.prevPage();
351
- }
352
- ```
353
-
354
- ### Usage Examples
355
-
356
- ```typescript
357
- // Get first page
358
- const page = await products.get(1, 10);
359
-
360
- // Direct array methods
361
- const names = page.map(p => p.name);
362
- const inStock = page.filter(p => p.stock > 0);
363
-
364
- // Check pagination info
365
- console.log(`Page ${page.pagination.currentPage} of ${page.pagination.totalPages}`);
366
- console.log(`Showing ${page.length} of ${page.pagination.totalCount} products`);
367
-
368
- // Navigate pages
369
- if (page.pagination.hasNextPage) {
370
- const nextPage = await page.nextPage();
371
- console.log(`Now on page ${nextPage.pagination.currentPage}`);
372
- }
373
-
374
- // Iterate current page
375
- for (const product of page) {
376
- console.log(product.name);
377
- }
378
-
379
- // Process all pages
380
- let currentPage = await products.get(1, 20);
381
- const allProducts = [];
382
-
383
- while (true) {
384
- allProducts.push(...currentPage.products);
385
-
386
- if (!currentPage.pagination.hasNextPage) {
387
- break;
388
- }
389
-
390
- currentPage = await currentPage.nextPage();
391
- }
392
-
393
- // Conditional rendering based on pagination
394
- if (page.pagination.totalPages > 1) {
395
- console.log('Multiple pages available');
396
- }
397
-
398
- // Calculate page-specific metrics
399
- const pageTotal = page.reduce((sum, p) => sum + p.price, 0);
400
- const pageAverage = pageTotal / page.length;
401
- ```
402
-
403
- ### Backward Compatibility
404
-
405
- ```typescript
406
- // Both work:
407
- page.map(p => p.name); // ✅ New way
408
- page.products.map(p => p.name); // ✅ Old way still works
409
- ```
410
-
411
- ---
412
-
413
- ## BasketInstance
414
-
415
- Shopping basket/cart with items and metadata.
416
-
417
- ### When It's Returned
418
-
419
- ```typescript
420
- // Get current basket
421
- const basket = await context.basket.get();
422
- // Returns BasketInstance
423
-
424
- // Create new basket
425
- const basket = await context.basket.create();
426
- // Returns BasketInstance
427
- ```
428
-
429
- ### Properties
430
-
431
- All properties from both `data` and `common` are directly accessible:
432
-
433
- **Instance Properties:**
434
- - `id` - Basket ID
435
- - `userId` - User ID (private)
436
- - `agentId` - Agent ID (private)
437
- - `metadata` - Basket metadata
438
- - `totalAmount` - Total basket value
439
- - `itemCount` - Number of items
440
- - `status` - Basket status
441
-
442
- **Data Properties (via proxy):**
443
- - `items` - Array of basket items
444
- - `currency` - Currency code
445
- - And any custom data fields
446
-
447
- **Common Properties (via proxy):**
448
- - `createdAt` - Creation timestamp
449
- - `updatedAt` - Last update timestamp
450
- - And any common fields
451
-
452
- ### Methods
453
-
454
- #### `addItem(item: BasketItem): Promise<any>`
455
-
456
- Adds an item to the basket.
457
-
458
- ```typescript
459
- await basket.addItem({
460
- productId: "prod-123",
461
- quantity: 2,
462
- price: 29.99
463
- });
464
- ```
465
-
466
- #### `removeItem(itemId: string): Promise<any>`
467
-
468
- Removes an item from the basket.
469
-
470
- ```typescript
471
- await basket.removeItem("item-456");
472
- ```
473
-
474
- #### `updateMetadata(metadata: any): Promise<any>`
475
-
476
- Updates basket metadata.
477
-
478
- ```typescript
479
- await basket.updateMetadata({
480
- giftWrap: true,
481
- message: "Happy Birthday!"
482
- });
483
- ```
484
-
485
- #### `updateStatus(status: BasketStatus): Promise<any>`
486
-
487
- Updates basket status.
488
-
489
- ```typescript
490
- await basket.updateStatus(BasketStatus.CHECKED_OUT);
491
- ```
492
-
493
- #### `clear(): Promise<any>`
494
-
495
- Removes all items from the basket.
496
-
497
- ```typescript
498
- await basket.clear();
499
- ```
500
-
501
- #### `placeOrder(data: Record<string, any>): Promise<OrderInstance>`
502
-
503
- Places an order from basket contents.
504
-
505
- ```typescript
506
- const order = await basket.placeOrder({
507
- shippingAddress: {
508
- street: "123 Main St",
509
- city: "New York",
510
- zip: "10001"
511
- },
512
- paymentMethod: "credit_card"
513
- });
514
- ```
515
-
516
- ### Usage Examples
517
-
518
- ```typescript
519
- // Get basket
520
- const basket = await context.basket.get();
521
-
522
- // Direct property access
523
- const items = basket.items;
524
- const total = basket.totalAmount;
525
- const count = basket.itemCount;
526
- const status = basket.status;
527
-
528
- // Add items
529
- await basket.addItem({
530
- productId: "laptop-001",
531
- quantity: 1,
532
- price: 1299.99,
533
- name: "Gaming Laptop"
534
- });
535
-
536
- // Access items
537
- basket.items.forEach(item => {
538
- console.log(`${item.name}: ${item.quantity} x $${item.price}`);
539
- });
540
-
541
- // Calculate custom total
542
- const subtotal = basket.items.reduce((sum, item) =>
543
- sum + (item.price * item.quantity), 0
544
- );
545
-
546
- // Update metadata
547
- await basket.updateMetadata({
548
- couponCode: "SAVE10",
549
- giftWrap: true
550
- });
551
-
552
- // Check metadata
553
- if (basket.metadata.couponCode) {
554
- console.log('Coupon applied:', basket.metadata.couponCode);
555
- }
556
-
557
- // Clear basket
558
- if (basket.itemCount > 0) {
559
- await basket.clear();
560
- }
561
-
562
- // Place order
563
- const order = await basket.placeOrder({
564
- shippingAddress: userAddress,
565
- paymentMethod: "stripe",
566
- notes: "Please ring doorbell"
567
- });
568
- ```
569
-
570
- ### Multi-Level Property Access
571
-
572
- The basket checks three levels for properties:
573
- 1. Instance properties (id, metadata, totalAmount, etc.)
574
- 2. Data properties (items, custom fields)
575
- 3. Common properties (createdAt, updatedAt, etc.)
576
-
577
- ```typescript
578
- // All accessible directly
579
- basket.id; // Instance property
580
- basket.items; // Data property
581
- basket.totalAmount; // Instance property
582
- basket.createdAt; // Common property (via proxy)
583
- ```
584
-
585
- ---
586
-
587
- ## OrderInstance
588
-
589
- Completed order with status and data management.
590
-
591
- ### When It's Returned
592
-
593
- ```typescript
594
- // From placing an order
595
- const order = await basket.placeOrder(orderData);
596
- // Returns OrderInstance
597
-
598
- // From order history
599
- const orders = await context.orders.getAll();
600
- const order = orders[0]; // OrderInstance
601
- ```
602
-
603
- ### Properties
604
-
605
- All properties from both `data` and `common` are directly accessible:
606
-
607
- **Instance Properties:**
608
- - `id` - Order ID (private)
609
- - `userId` - User ID (private)
610
- - `agentId` - Agent ID (private)
611
- - `orderId` - Public order ID (private)
612
-
613
- **Data Properties (via proxy):**
614
- - `items` - Order items array
615
- - `shippingAddress` - Shipping address object
616
- - `billingAddress` - Billing address object
617
- - `paymentMethod` - Payment method
618
- - `notes` - Order notes
619
- - And any custom data fields
620
-
621
- **Common Properties (via proxy):**
622
- - `status` - Order status
623
- - `totalAmount` - Total order value
624
- - `createdAt` - Order creation time
625
- - `updatedAt` - Last update time
626
- - And any common fields
627
-
628
- ### Methods
629
-
630
- #### `updateStatus(status: OrderStatus): Promise<any>`
631
-
632
- Updates the order status.
633
-
634
- ```typescript
635
- await order.updateStatus(OrderStatus.SHIPPED);
636
- ```
637
-
638
- #### `update(data: Record<string, any>): Promise<any>`
639
-
640
- Updates order data fields.
641
-
642
- ```typescript
643
- await order.update({
644
- trackingNumber: "1Z999AA10123456784",
645
- estimatedDelivery: "2025-10-15",
646
- notes: "Package shipped via express"
647
- });
648
- ```
649
-
650
- ### Order Status Values
651
-
652
- - `PENDING` - Order placed, awaiting processing
653
- - `PROCESSING` - Order being prepared
654
- - `SHIPPED` - Order shipped to customer
655
- - `DELIVERED` - Order delivered
656
- - `CANCELLED` - Order cancelled
657
-
658
- ### Usage Examples
659
-
660
- ```typescript
661
- // Get order
662
- const order = await basket.placeOrder(orderData);
663
-
664
- // Direct property access
665
- const items = order.items;
666
- const total = order.totalAmount;
667
- const status = order.status;
668
- const shipping = order.shippingAddress;
669
-
670
- // Display order summary
671
- console.log(`Order #${order.orderId}`);
672
- console.log(`Status: ${order.status}`);
673
- console.log(`Total: $${order.totalAmount}`);
674
-
675
- // Access order items
676
- order.items.forEach(item => {
677
- console.log(`- ${item.name}: ${item.quantity} x $${item.price}`);
678
- });
679
-
680
- // Update shipping info
681
- await order.update({
682
- trackingNumber: "1Z999AA10123456784",
683
- carrier: "UPS",
684
- estimatedDelivery: "2025-10-15"
685
- });
686
-
687
- // Update order status
688
- if (order.status === 'pending') {
689
- await order.updateStatus(OrderStatus.PROCESSING);
690
- }
691
-
692
- // Add order notes
693
- await order.update({
694
- notes: order.notes ?
695
- `${order.notes}\nPackage dispatched` :
696
- "Package dispatched"
697
- });
698
-
699
- // Check delivery address
700
- if (order.shippingAddress) {
701
- console.log('Shipping to:', order.shippingAddress.city);
702
- }
703
-
704
- // Process based on status
705
- switch (order.status) {
706
- case 'pending':
707
- await order.updateStatus(OrderStatus.PROCESSING);
708
- break;
709
- case 'processing':
710
- // Prepare shipment
711
- break;
712
- case 'shipped':
713
- // Send tracking email
714
- break;
715
- }
716
- ```
717
-
718
- ### Multi-Level Property Access
719
-
720
- The order checks three levels for properties:
721
- 1. Instance properties (id, orderId, etc.)
722
- 2. Data properties (items, shippingAddress, etc.)
723
- 3. Common properties (status, totalAmount, createdAt, etc.)
724
-
725
- ```typescript
726
- // All accessible directly
727
- order.orderId; // Instance property
728
- order.items; // Data property
729
- order.shippingAddress; // Data property
730
- order.status; // Common property (via proxy)
731
- order.totalAmount; // Common property (via proxy)
732
- ```
733
-
734
- ---
735
-
736
- ## DataEntryInstance
737
-
738
- Custom data entry with search and update capabilities.
739
-
740
- ### When It's Returned
741
-
742
- ```typescript
743
- // From creating an entry
744
- const entry = await customData.create("users", {
745
- name: "John Doe",
746
- email: "john@example.com"
747
- }, "john doe email");
748
- // Returns DataEntryInstance
749
-
750
- // From search results
751
- const results = await customData.search("users", "john");
752
- const entry = results[0]; // DataEntryInstance
753
-
754
- // From getting by ID
755
- const entry = await customData.get("users", "entry-123");
756
- // Returns DataEntryInstance
757
- ```
758
-
759
- ### Properties
760
-
761
- - **`data`** - The custom data object
762
- - **`id`** - Entry ID
763
- - **`collectionName`** - Collection name
764
- - **`score`** - Search relevance score (optional)
765
- - All data fields accessible directly
766
-
767
- ### Methods
768
-
769
- #### `update(data: Record<string, any>, searchText?: string): Promise<any>`
770
-
771
- Updates the entry data.
772
-
773
- ```typescript
774
- await entry.update({
775
- email: "newemail@example.com",
776
- phone: "+1234567890"
777
- }, "john doe newemail phone");
778
- ```
779
-
780
- #### `delete(): Promise<boolean>`
781
-
782
- Deletes the entry.
783
-
784
- ```typescript
785
- await entry.delete();
786
- ```
787
-
788
- ### Usage Examples
789
-
790
- ```typescript
791
- // Create entry
792
- const entry = await customData.create("contacts", {
793
- name: "John Doe",
794
- email: "john@example.com",
795
- phone: "+1234567890",
796
- company: "Acme Inc"
797
- }, "john doe acme email");
798
-
799
- // Direct property access
800
- const name = entry.name;
801
- const email = entry.email;
802
- const phone = entry.phone;
803
- const company = entry.company;
804
-
805
- // Check metadata
806
- console.log(`Entry ID: ${entry.id}`);
807
- console.log(`Collection: ${entry.collectionName}`);
808
-
809
- // Update entry
810
- await entry.update({
811
- phone: "+9876543210",
812
- department: "Engineering"
813
- }, "john doe engineering");
814
-
815
- // Search and update
816
- const results = await customData.search("contacts", "acme");
817
-
818
- for (const entry of results) {
819
- if (entry.score > 0.8) {
820
- console.log(`High relevance: ${entry.name} (score: ${entry.score})`);
821
- }
822
-
823
- // Update based on search
824
- if (entry.company === "Acme Inc") {
825
- await entry.update({
826
- verified: true,
827
- lastContacted: new Date().toISOString()
828
- });
829
- }
830
- }
831
-
832
- // Delete old entries
833
- const oldEntries = await customData.search("contacts", "inactive");
834
- for (const entry of oldEntries) {
835
- await entry.delete();
836
- }
837
-
838
- // Conditional updates
839
- if (entry.email && !entry.emailVerified) {
840
- await entry.update({ emailVerified: true });
841
- }
842
-
843
- // Nested data access
844
- if (entry.address) {
845
- console.log(`City: ${entry.address.city}`);
846
- }
847
- ```
848
-
849
- ### Search Scores
850
-
851
- When entries are returned from a search, they include a `score` property indicating relevance:
852
-
853
- ```typescript
854
- const results = await customData.search("contacts", "john engineer");
855
-
856
- results.forEach(entry => {
857
- console.log(`${entry.name}: ${entry.score}`);
858
- });
859
-
860
- // Filter by score
861
- const highRelevance = results.filter(entry => entry.score > 0.7);
862
- ```
863
-
864
- ---
865
-
866
- ## Common Patterns
867
-
868
- ### Chaining Operations
869
-
870
- ```typescript
871
- // Update and use result
872
- const user = await context.user.update({ name: "John" });
873
- console.log(user.name);
874
-
875
- // Create, update, and use
876
- const product = await products.create({ name: "Laptop" });
877
- await product.update({ price: 1299.99 });
878
- console.log(product.price);
879
- ```
880
-
881
- ### Error Handling
882
-
883
- ```typescript
884
- try {
885
- await product.update({ price: newPrice });
886
- } catch (error) {
887
- console.error('Failed to update product:', error);
888
- }
889
-
890
- try {
891
- await user.clear();
892
- } catch (error) {
893
- console.error('Failed to clear user data:', error);
894
- }
895
- ```
896
-
897
- ### Conditional Operations
898
-
899
- ```typescript
900
- // Check before operating
901
- if (product.stock < 10) {
902
- await product.update({ lowStock: true });
903
- }
904
-
905
- if (basket.itemCount > 0) {
906
- const order = await basket.placeOrder(orderData);
907
- }
908
-
909
- // Check existence
910
- if ('preferences' in user) {
911
- const theme = user.preferences.theme;
912
- }
913
- ```
914
-
915
- ### Batch Operations
916
-
917
- ```typescript
918
- // Update multiple products
919
- const products = await productsAPI.search("laptop");
920
-
921
- for (const product of products) {
922
- if (product.price > 1000) {
923
- await product.update({ premium: true });
924
- }
925
- }
926
-
927
- // Process all pages
928
- let page = await productsAPI.get(1, 50);
929
- const allProducts = [];
930
-
931
- do {
932
- allProducts.push(...page.products);
933
- if (page.pagination.hasNextPage) {
934
- page = await page.nextPage();
935
- }
936
- } while (page.pagination.hasNextPage);
937
- ```
938
-
939
- ### Array Operations on Collections
940
-
941
- ```typescript
942
- // Map and filter
943
- const searchResults = await products.search("laptop");
944
-
945
- const names = searchResults.map(p => p.name);
946
- const available = searchResults.filter(p => p.stock > 0);
947
- const sorted = [...searchResults].sort((a, b) => a.price - b.price);
948
-
949
- // Reduce for calculations
950
- const totalValue = searchResults.reduce((sum, p) =>
951
- sum + (p.price * p.stock), 0
952
- );
953
-
954
- // Find specific items
955
- const cheapest = searchResults.reduce((min, p) =>
956
- p.price < min.price ? p : min
957
- );
958
-
959
- const specific = searchResults.find(p => p.sku === "LAP-001");
960
- ```
961
-
962
- ### Iteration Patterns
963
-
964
- ```typescript
965
- // For...of
966
- for (const product of searchResults) {
967
- console.log(product.name);
968
- }
969
-
970
- // forEach with async
971
- searchResults.forEach(async (product) => {
972
- await product.update({ viewed: true });
973
- });
974
-
975
- // Spread operator
976
- const allProducts = [...searchResults];
977
-
978
- // Array destructuring
979
- const [first, ...rest] = searchResults;
980
- ```
981
-
982
- ### Property Checks
983
-
984
- ```typescript
985
- // Check if property exists
986
- if ('name' in user) {
987
- console.log(user.name);
988
- }
989
-
990
- // Check if has value
991
- if (product.description) {
992
- console.log(product.description);
993
- }
994
-
995
- // Get all keys
996
- const userKeys = Object.keys(user);
997
- const productKeys = Object.keys(product);
998
- ```
999
-
1000
- ---
1001
-
1002
- ## TypeScript Support
1003
-
1004
- ### Type Definitions
1005
-
1006
- All instances have proper TypeScript support with index signatures:
1007
-
1008
- ```typescript
1009
- // UserDataInstance
1010
- interface UserDataInstance {
1011
- data: Record<string, any>;
1012
- [key: string]: any; // Allows dynamic property access
1013
- update(data: Record<string, any>): Promise<any>;
1014
- clear(): Promise<boolean>;
1015
- }
1016
-
1017
- // ProductInstance
1018
- interface ProductInstance {
1019
- data: Product;
1020
- [key: string]: any;
1021
- update(data: Record<string, any>): Promise<Product>;
1022
- delete(): Promise<Product>;
1023
- }
1024
-
1025
- // ProductSearchInstance
1026
- interface ProductSearchInstance {
1027
- products: ProductInstance[];
1028
- length: number;
1029
- map<T>(callback: ...): T[];
1030
- filter(callback: ...): ProductInstance[];
1031
- // ... other array methods
1032
- }
1033
- ```
1034
-
1035
- ### Using with Custom Types
1036
-
1037
- ```typescript
1038
- // Define your data shape
1039
- interface UserPreferences {
1040
- theme: 'light' | 'dark';
1041
- notifications: boolean;
1042
- language: string;
1043
- }
1044
-
1045
- interface MyUserData {
1046
- name: string;
1047
- email: string;
1048
- preferences: UserPreferences;
1049
- }
1050
-
1051
- // Access with type checking
1052
- const user = context.user;
1053
- const prefs: UserPreferences = user.preferences;
1054
- const theme: 'light' | 'dark' = user.preferences.theme;
1055
-
1056
- // Product data
1057
- interface MyProduct {
1058
- name: string;
1059
- price: number;
1060
- sku: string;
1061
- stock: number;
1062
- }
1063
-
1064
- const product = await products.create({...});
1065
- const name: string = product.name;
1066
- const price: number = product.price;
1067
- ```
1068
-
1069
- ### Generic Array Methods
1070
-
1071
- ```typescript
1072
- // Map with type inference
1073
- const prices: number[] = searchResults.map(p => p.price);
1074
- const names: string[] = searchResults.map(p => p.name);
1075
-
1076
- // Type-safe reduce
1077
- const total: number = searchResults.reduce((sum, p) =>
1078
- sum + p.price, 0
1079
- );
1080
-
1081
- // Type-safe filter
1082
- const available: ProductInstance[] = searchResults.filter(p =>
1083
- p.stock > 0
1084
- );
1085
- ```
1086
-
1087
- ---
1088
-
1089
- ## Best Practices
1090
-
1091
- ### ✅ DO
1092
-
1093
- ```typescript
1094
- // Use direct property access
1095
- const name = user.name;
1096
- const price = product.price;
1097
-
1098
- // Use array methods on collections
1099
- searchResults.map(p => p.name);
1100
- paginatedResults.filter(p => p.stock > 0);
1101
-
1102
- // Update multiple fields at once
1103
- await user.update({
1104
- field1: value1,
1105
- field2: value2
1106
- });
1107
-
1108
- // Check property existence
1109
- if ('preferences' in user) {
1110
- // Use preferences
1111
- }
1112
-
1113
- // Use for...of for async operations
1114
- for (const product of searchResults) {
1115
- await product.update({ viewed: true });
1116
- }
1117
- ```
1118
-
1119
- ### ❌ DON'T
1120
-
1121
- ```typescript
1122
- // Don't mutate without calling update()
1123
- product.price = 999;
1124
- // ❌ Only updates locally! Must call update()
1125
-
1126
- // Don't make multiple update calls
1127
- await user.update({ field1: value1 });
1128
- await user.update({ field2: value2 });
1129
- // ✅ Combine: await user.update({ field1: value1, field2: value2 });
1130
-
1131
- // Don't assume sanitized fields exist
1132
- console.log(user.userId); // undefined (sanitized)
1133
- console.log(user.agentId); // undefined (sanitized)
1134
-
1135
- // Don't use products.products when you can use products directly
1136
- results.products.map(p => p.name); // ❌ Verbose
1137
- results.map(p => p.name); // ✅ Better
1138
- ```
1139
-
1140
- ---
1141
-
1142
- ## Summary
1143
-
1144
- All instance classes now provide:
1145
-
1146
- 1. **Direct Property Access** - Access nested data without `.data`
1147
- 2. **Array Methods** - Collections support `.map()`, `.filter()`, etc.
1148
- 3. **Iteration** - Use `for...of` loops and spread operators
1149
- 4. **Type Safety** - Full TypeScript support with index signatures
1150
- 5. **Backward Compatibility** - Old patterns still work
1151
-
1152
- This creates a more intuitive and JavaScript-friendly API while maintaining full backward compatibility with existing code.
1153
-
1154
- ---
1155
-
1156
- **Version:** 2.5.2
1157
- **Last Updated:** October 7, 2025
1158
- **License:** MIT