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.
- package/dist/api/job.api.service.d.ts +16 -7
- package/dist/api/job.api.service.js +21 -5
- package/dist/api/postprocessor.api.service.d.ts +61 -1
- package/dist/api/postprocessor.api.service.js +35 -0
- package/dist/api/preprocessor.api.service.d.ts +61 -1
- package/dist/api/preprocessor.api.service.js +35 -0
- package/dist/api-exports.d.ts +26 -6
- package/dist/api-exports.js +42 -29
- package/dist/cli/command-definitions.js +13 -6
- package/dist/commands/chat.js +32 -5
- package/dist/commands/compile.js +16 -2
- package/dist/commands/dev.js +23 -2
- package/dist/commands/push.d.ts +6 -2
- package/dist/commands/push.js +412 -6
- package/dist/commands/test.js +18 -2
- package/dist/common/job.instance.d.ts +3 -0
- package/dist/common/job.instance.js +8 -0
- package/dist/config/constants.d.ts +6 -5
- package/dist/config/constants.js +12 -10
- package/dist/interfaces/chat.d.ts +30 -1
- package/dist/interfaces/jobs.d.ts +21 -0
- package/dist/types/skill.d.ts +75 -56
- package/dist/types/skill.js +53 -59
- package/dist/utils/bundling.d.ts +13 -4
- package/dist/utils/bundling.js +83 -26
- package/dist/utils/compile.js +27 -6
- package/dist/utils/dev-api.d.ts +42 -2
- package/dist/utils/dev-api.js +177 -4
- package/dist/utils/dev-server.d.ts +1 -1
- package/dist/utils/dev-server.js +4 -4
- package/dist/utils/dynamic-job-bundler.d.ts +17 -0
- package/dist/utils/dynamic-job-bundler.js +143 -0
- package/dist/utils/pre-bundle-jobs.d.ts +26 -0
- package/dist/utils/pre-bundle-jobs.js +176 -0
- package/dist/utils/sandbox-storage.d.ts +48 -0
- package/dist/utils/sandbox-storage.js +114 -0
- package/dist/utils/sandbox.d.ts +2 -2
- package/dist/utils/sandbox.js +23 -7
- package/package.json +1 -1
- package/template/lua.skill.yaml +47 -0
- package/template/package-lock.json +10505 -0
- package/template/package.json +2 -1
- package/template/src/index.ts +65 -3
- package/template/src/tools/CreateInlineJob.ts +42 -0
- package/API_REFERENCE.md +0 -1408
- package/CHANGELOG.md +0 -236
- package/CLI_REFERENCE.md +0 -908
- package/GETTING_STARTED.md +0 -1040
- package/INSTANCE_TYPES.md +0 -1158
- package/README.md +0 -865
- package/TEMPLATE_GUIDE.md +0 -1398
- package/USER_DATA_INSTANCE.md +0 -621
- package/template/AGENT_CONFIGURATION.md +0 -251
- package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
- package/template/DYNAMIC_JOB_CREATION.md +0 -371
- package/template/TOOL_EXAMPLES.md +0 -655
- package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
- package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
- package/template/src/index-agent-example.ts +0 -201
- package/template/src/postprocessors/ResponseFormatter.ts +0 -151
- 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
|