lua-cli 2.5.0 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.5.2] - 2025-10-07
9
+
10
+ ### ✨ New Features
11
+ - **Direct Property Access for All Instance Classes**: Extended Proxy pattern to all instance types
12
+ - `ProductInstance` now supports `product.name` instead of `product.data.name`
13
+ - `DataEntryInstance` now supports `entry.fieldName` instead of `entry.data.fieldName`
14
+ - `BasketInstance` now supports `basket.items` (checks instance → data → common)
15
+ - `OrderInstance` now supports `order.shippingAddress` (checks instance → data → common)
16
+
17
+ - **Array-Like Methods for Product Collections**: Direct iteration support
18
+ - `ProductSearchInstance` now supports `.map()`, `.filter()`, `.forEach()`, etc.
19
+ - `ProductPaginationInstance` now supports all array methods
20
+ - Both support `for...of` loops and spread operators
21
+ - Direct `.length` property access
22
+
23
+ ### 🔧 Improvements
24
+ - **Consistent API**: All instance classes now follow the same intuitive access patterns
25
+ - **Enhanced Iteration**: Product collections can be treated as arrays
26
+ - **Better TypeScript Support**: Index signatures on all instance classes
27
+
28
+ ### 📖 Documentation
29
+ - **Comprehensive Instance Types Documentation**: Added complete guide for all instance types
30
+
31
+ ### Technical Details
32
+ - Added Proxy implementations to ProductInstance, DataEntryInstance, BasketInstance, OrderInstance
33
+ - Added array method delegation to ProductSearchInstance and ProductPaginationInstance
34
+ - Added Symbol.iterator support for proper iteration
35
+ - Type-safe implementations with proper generics
36
+
37
+ ## [2.5.1] - 2025-10-07
38
+
39
+ ### 🐛 Bug Fixes
40
+ - **TypeScript Index Signature**: Added index signature to `UserDataInstance` class to fix TypeScript linting errors
41
+ - Resolves "Property does not exist on type" errors when accessing dynamic properties like `user.name`
42
+ - Now properly typed for dynamic property access via Proxy
43
+
8
44
  ## [2.5.0] - 2025-10-07
9
45
 
10
46
  ### ✨ New Features
@@ -25,9 +25,11 @@ export default class ProductApi extends HttpClient {
25
25
  * @throws Error if the request fails or products cannot be retrieved
26
26
  */
27
27
  async get(page = 1, limit = 10) {
28
+ console.log('get products', page, limit, this.agentId, this.apiKey);
28
29
  const response = await this.httpGet(`/developer/agents/${this.agentId}/products?page=${page}&limit=${limit}`, {
29
30
  Authorization: `Bearer ${this.apiKey}`,
30
31
  });
32
+ console.log('get products response', response);
31
33
  if (response.success) {
32
34
  return new ProductPaginationInstance(this, response);
33
35
  }
@@ -4,6 +4,7 @@ import OrderInstance from "./order.instance.js";
4
4
  /**
5
5
  * Basket instance class providing a fluent API for managing user baskets
6
6
  * Provides methods for adding/removing items, updating metadata, and placing orders
7
+ * Supports direct property access (e.g., basket.items) for accessing data and common properties
7
8
  */
8
9
  export default class BasketInstance {
9
10
  private id;
@@ -16,10 +17,12 @@ export default class BasketInstance {
16
17
  itemCount: number;
17
18
  status: BasketStatus;
18
19
  private basketAPI;
20
+ [key: string]: any;
19
21
  /**
20
- * Creates a new BasketInstance
22
+ * Creates a new BasketInstance with proxy support for direct property access
21
23
  * @param api - The BasketAPI instance for making API calls
22
24
  * @param basket - The basket data from the API
25
+ * @returns Proxied instance that allows direct access to data and common properties
23
26
  */
24
27
  constructor(api: BasketAPI, basket: Basket);
25
28
  /**
@@ -2,12 +2,14 @@ import { BasketStatus } from "../interfaces/baskets.js";
2
2
  /**
3
3
  * Basket instance class providing a fluent API for managing user baskets
4
4
  * Provides methods for adding/removing items, updating metadata, and placing orders
5
+ * Supports direct property access (e.g., basket.items) for accessing data and common properties
5
6
  */
6
7
  export default class BasketInstance {
7
8
  /**
8
- * Creates a new BasketInstance
9
+ * Creates a new BasketInstance with proxy support for direct property access
9
10
  * @param api - The BasketAPI instance for making API calls
10
11
  * @param basket - The basket data from the API
12
+ * @returns Proxied instance that allows direct access to data and common properties
11
13
  */
12
14
  constructor(api, basket) {
13
15
  this.data = basket.data;
@@ -26,6 +28,79 @@ export default class BasketInstance {
26
28
  enumerable: false,
27
29
  configurable: true
28
30
  });
31
+ // Return a proxy that allows direct property access
32
+ return new Proxy(this, {
33
+ get(target, prop, receiver) {
34
+ // If the property exists on the instance itself, return it
35
+ if (prop in target) {
36
+ return Reflect.get(target, prop, receiver);
37
+ }
38
+ // Check data object
39
+ if (typeof prop === 'string' && prop in target.data) {
40
+ return target.data[prop];
41
+ }
42
+ // Check common object
43
+ if (typeof prop === 'string' && prop in target.common) {
44
+ return target.common[prop];
45
+ }
46
+ return undefined;
47
+ },
48
+ set(target, prop, value, receiver) {
49
+ // Reserved properties that should be set on the instance itself
50
+ const reservedProps = ['id', 'userId', 'agentId', 'data', 'common', 'metadata', 'totalAmount', 'itemCount', 'status', 'basketAPI', 'updateMetadata', 'updateStatus', 'addItem', 'removeItem', 'clear', 'placeOrder', 'toJSON'];
51
+ if (typeof prop === 'string' && reservedProps.includes(prop)) {
52
+ return Reflect.set(target, prop, value, receiver);
53
+ }
54
+ // Check if property exists in data or common, otherwise default to data
55
+ if (typeof prop === 'string') {
56
+ if (prop in target.common) {
57
+ target.common[prop] = value;
58
+ }
59
+ else {
60
+ target.data[prop] = value;
61
+ }
62
+ return true;
63
+ }
64
+ return false;
65
+ },
66
+ has(target, prop) {
67
+ // Check if property exists on instance, in data, or in common
68
+ return prop in target || (typeof prop === 'string' && (prop in target.data || prop in target.common));
69
+ },
70
+ ownKeys(target) {
71
+ // Return instance keys, data keys, and common keys
72
+ const instanceKeys = Reflect.ownKeys(target);
73
+ const dataKeys = Object.keys(target.data);
74
+ const commonKeys = Object.keys(target.common);
75
+ return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];
76
+ },
77
+ getOwnPropertyDescriptor(target, prop) {
78
+ // First check if it's an instance property
79
+ const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);
80
+ if (instanceDesc) {
81
+ return instanceDesc;
82
+ }
83
+ // Then check data properties
84
+ if (typeof prop === 'string' && prop in target.data) {
85
+ return {
86
+ configurable: true,
87
+ enumerable: true,
88
+ writable: true,
89
+ value: target.data[prop]
90
+ };
91
+ }
92
+ // Then check common properties
93
+ if (typeof prop === 'string' && prop in target.common) {
94
+ return {
95
+ configurable: true,
96
+ enumerable: true,
97
+ writable: true,
98
+ value: target.common[prop]
99
+ };
100
+ }
101
+ return undefined;
102
+ }
103
+ });
29
104
  }
30
105
  /**
31
106
  * Custom toJSON method to control what gets serialized when logging
@@ -3,6 +3,7 @@ import { CreateCustomDataResponse } from "../interfaces/custom.data.js";
3
3
  /**
4
4
  * Data entry instance class providing a fluent API for managing custom data entries
5
5
  * Provides methods for updating and deleting individual data entries
6
+ * Supports direct property access (e.g., entry.fieldName) for accessing data properties
6
7
  */
7
8
  export default class DataEntryInstance {
8
9
  data: Record<string, any>;
@@ -10,11 +11,13 @@ export default class DataEntryInstance {
10
11
  collectionName: string;
11
12
  score?: number;
12
13
  private customDataAPI;
14
+ [key: string]: any;
13
15
  /**
14
- * Creates a new DataEntryInstance
16
+ * Creates a new DataEntryInstance with proxy support for direct property access
15
17
  * @param api - The CustomDataAPI instance for making API calls
16
18
  * @param entry - The custom data entry response from the API
17
19
  * @param collectionName - The name of the collection this entry belongs to
20
+ * @returns Proxied instance that allows direct access to data properties
18
21
  */
19
22
  constructor(api: CustomDataAPI, entry: CreateCustomDataResponse, collectionName: string);
20
23
  /**
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * Data entry instance class providing a fluent API for managing custom data entries
3
3
  * Provides methods for updating and deleting individual data entries
4
+ * Supports direct property access (e.g., entry.fieldName) for accessing data properties
4
5
  */
5
6
  export default class DataEntryInstance {
6
7
  /**
7
- * Creates a new DataEntryInstance
8
+ * Creates a new DataEntryInstance with proxy support for direct property access
8
9
  * @param api - The CustomDataAPI instance for making API calls
9
10
  * @param entry - The custom data entry response from the API
10
11
  * @param collectionName - The name of the collection this entry belongs to
12
+ * @returns Proxied instance that allows direct access to data properties
11
13
  */
12
14
  constructor(api, entry, collectionName) {
13
15
  this.data = entry.data;
@@ -21,6 +23,60 @@ export default class DataEntryInstance {
21
23
  enumerable: false,
22
24
  configurable: true
23
25
  });
26
+ // Return a proxy that allows direct property access
27
+ return new Proxy(this, {
28
+ get(target, prop, receiver) {
29
+ // If the property exists on the instance itself, return it
30
+ if (prop in target) {
31
+ return Reflect.get(target, prop, receiver);
32
+ }
33
+ // Otherwise, try to get it from the data object
34
+ if (typeof prop === 'string' && prop in target.data) {
35
+ return target.data[prop];
36
+ }
37
+ return undefined;
38
+ },
39
+ set(target, prop, value, receiver) {
40
+ // Reserved properties that should be set on the instance itself
41
+ const reservedProps = ['data', 'id', 'collectionName', 'score', 'customDataAPI', 'update', 'delete', 'toJSON'];
42
+ if (typeof prop === 'string' && reservedProps.includes(prop)) {
43
+ return Reflect.set(target, prop, value, receiver);
44
+ }
45
+ // All other properties get set on the data object
46
+ if (typeof prop === 'string') {
47
+ target.data[prop] = value;
48
+ return true;
49
+ }
50
+ return false;
51
+ },
52
+ has(target, prop) {
53
+ // Check if property exists on instance or in data
54
+ return prop in target || (typeof prop === 'string' && prop in target.data);
55
+ },
56
+ ownKeys(target) {
57
+ // Return both instance keys and data keys
58
+ const instanceKeys = Reflect.ownKeys(target);
59
+ const dataKeys = Object.keys(target.data);
60
+ return [...new Set([...instanceKeys, ...dataKeys])];
61
+ },
62
+ getOwnPropertyDescriptor(target, prop) {
63
+ // First check if it's an instance property
64
+ const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);
65
+ if (instanceDesc) {
66
+ return instanceDesc;
67
+ }
68
+ // Then check if it's a data property
69
+ if (typeof prop === 'string' && prop in target.data) {
70
+ return {
71
+ configurable: true,
72
+ enumerable: true,
73
+ writable: true,
74
+ value: target.data[prop]
75
+ };
76
+ }
77
+ return undefined;
78
+ }
79
+ });
24
80
  }
25
81
  /**
26
82
  * Custom toJSON method to control what gets serialized when logging
@@ -3,6 +3,7 @@ import { OrderResponse, OrderStatus } from "../interfaces/orders.js";
3
3
  /**
4
4
  * Order instance class providing a fluent API for managing orders
5
5
  * Provides methods for updating order status and order data
6
+ * Supports direct property access (e.g., order.shippingAddress) for accessing data and common properties
6
7
  */
7
8
  export default class OrderInstance {
8
9
  private data;
@@ -12,10 +13,12 @@ export default class OrderInstance {
12
13
  private agentId;
13
14
  private orderId;
14
15
  private orderAPI;
16
+ [key: string]: any;
15
17
  /**
16
- * Creates a new OrderInstance
18
+ * Creates a new OrderInstance with proxy support for direct property access
17
19
  * @param api - The OrderApi instance for making API calls
18
20
  * @param order - The order response data from the API
21
+ * @returns Proxied instance that allows direct access to data and common properties
19
22
  */
20
23
  constructor(api: OrderApi, order: OrderResponse);
21
24
  /**
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * Order instance class providing a fluent API for managing orders
3
3
  * Provides methods for updating order status and order data
4
+ * Supports direct property access (e.g., order.shippingAddress) for accessing data and common properties
4
5
  */
5
6
  export default class OrderInstance {
6
7
  /**
7
- * Creates a new OrderInstance
8
+ * Creates a new OrderInstance with proxy support for direct property access
8
9
  * @param api - The OrderApi instance for making API calls
9
10
  * @param order - The order response data from the API
11
+ * @returns Proxied instance that allows direct access to data and common properties
10
12
  */
11
13
  constructor(api, order) {
12
14
  this.data = order.data;
@@ -22,6 +24,79 @@ export default class OrderInstance {
22
24
  enumerable: false,
23
25
  configurable: true
24
26
  });
27
+ // Return a proxy that allows direct property access
28
+ return new Proxy(this, {
29
+ get(target, prop, receiver) {
30
+ // If the property exists on the instance itself, return it
31
+ if (prop in target) {
32
+ return Reflect.get(target, prop, receiver);
33
+ }
34
+ // Check data object
35
+ if (typeof prop === 'string' && prop in target.data) {
36
+ return target.data[prop];
37
+ }
38
+ // Check common object
39
+ if (typeof prop === 'string' && prop in target.common) {
40
+ return target.common[prop];
41
+ }
42
+ return undefined;
43
+ },
44
+ set(target, prop, value, receiver) {
45
+ // Reserved properties that should be set on the instance itself
46
+ const reservedProps = ['data', 'common', 'id', 'userId', 'agentId', 'orderId', 'orderAPI', 'updateStatus', 'update', 'toJSON'];
47
+ if (typeof prop === 'string' && reservedProps.includes(prop)) {
48
+ return Reflect.set(target, prop, value, receiver);
49
+ }
50
+ // Check if property exists in data or common, otherwise default to data
51
+ if (typeof prop === 'string') {
52
+ if (prop in target.common) {
53
+ target.common[prop] = value;
54
+ }
55
+ else {
56
+ target.data[prop] = value;
57
+ }
58
+ return true;
59
+ }
60
+ return false;
61
+ },
62
+ has(target, prop) {
63
+ // Check if property exists on instance, in data, or in common
64
+ return prop in target || (typeof prop === 'string' && (prop in target.data || prop in target.common));
65
+ },
66
+ ownKeys(target) {
67
+ // Return instance keys, data keys, and common keys
68
+ const instanceKeys = Reflect.ownKeys(target);
69
+ const dataKeys = Object.keys(target.data);
70
+ const commonKeys = Object.keys(target.common);
71
+ return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];
72
+ },
73
+ getOwnPropertyDescriptor(target, prop) {
74
+ // First check if it's an instance property
75
+ const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);
76
+ if (instanceDesc) {
77
+ return instanceDesc;
78
+ }
79
+ // Then check data properties
80
+ if (typeof prop === 'string' && prop in target.data) {
81
+ return {
82
+ configurable: true,
83
+ enumerable: true,
84
+ writable: true,
85
+ value: target.data[prop]
86
+ };
87
+ }
88
+ // Then check common properties
89
+ if (typeof prop === 'string' && prop in target.common) {
90
+ return {
91
+ configurable: true,
92
+ enumerable: true,
93
+ writable: true,
94
+ value: target.common[prop]
95
+ };
96
+ }
97
+ return undefined;
98
+ }
99
+ });
25
100
  }
26
101
  /**
27
102
  * Custom toJSON method to control what gets serialized when logging
@@ -2,14 +2,17 @@ import { Product } from "../interfaces/product.js";
2
2
  /**
3
3
  * Product instance class providing a fluent API for managing individual products
4
4
  * Provides methods for updating and deleting products
5
+ * Supports direct property access (e.g., product.name) instead of product.data.name
5
6
  */
6
7
  export default class ProductInstance {
7
8
  data: Product;
8
9
  private productAPI;
10
+ [key: string]: any;
9
11
  /**
10
- * Creates a new ProductInstance
12
+ * Creates a new ProductInstance with proxy support for direct property access
11
13
  * @param api - The ProductAPI instance for making API calls
12
14
  * @param product - The product data from the API
15
+ * @returns Proxied instance that allows direct access to product properties
13
16
  */
14
17
  constructor(api: any, product: Product);
15
18
  /**
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * Product instance class providing a fluent API for managing individual products
3
3
  * Provides methods for updating and deleting products
4
+ * Supports direct property access (e.g., product.name) instead of product.data.name
4
5
  */
5
6
  export default class ProductInstance {
6
7
  /**
7
- * Creates a new ProductInstance
8
+ * Creates a new ProductInstance with proxy support for direct property access
8
9
  * @param api - The ProductAPI instance for making API calls
9
10
  * @param product - The product data from the API
11
+ * @returns Proxied instance that allows direct access to product properties
10
12
  */
11
13
  constructor(api, product) {
12
14
  this.data = product;
@@ -17,6 +19,60 @@ export default class ProductInstance {
17
19
  enumerable: false,
18
20
  configurable: true
19
21
  });
22
+ // Return a proxy that allows direct property access
23
+ return new Proxy(this, {
24
+ get(target, prop, receiver) {
25
+ // If the property exists on the instance itself, return it
26
+ if (prop in target) {
27
+ return Reflect.get(target, prop, receiver);
28
+ }
29
+ // Otherwise, try to get it from the data object
30
+ if (typeof prop === 'string' && prop in target.data) {
31
+ return target.data[prop];
32
+ }
33
+ return undefined;
34
+ },
35
+ set(target, prop, value, receiver) {
36
+ // Reserved properties that should be set on the instance itself
37
+ const reservedProps = ['data', 'productAPI', 'update', 'delete', 'toJSON'];
38
+ if (typeof prop === 'string' && reservedProps.includes(prop)) {
39
+ return Reflect.set(target, prop, value, receiver);
40
+ }
41
+ // All other properties get set on the data object
42
+ if (typeof prop === 'string') {
43
+ target.data[prop] = value;
44
+ return true;
45
+ }
46
+ return false;
47
+ },
48
+ has(target, prop) {
49
+ // Check if property exists on instance or in data
50
+ return prop in target || (typeof prop === 'string' && prop in target.data);
51
+ },
52
+ ownKeys(target) {
53
+ // Return both instance keys and data keys
54
+ const instanceKeys = Reflect.ownKeys(target);
55
+ const dataKeys = Object.keys(target.data);
56
+ return [...new Set([...instanceKeys, ...dataKeys])];
57
+ },
58
+ getOwnPropertyDescriptor(target, prop) {
59
+ // First check if it's an instance property
60
+ const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);
61
+ if (instanceDesc) {
62
+ return instanceDesc;
63
+ }
64
+ // Then check if it's a data property
65
+ if (typeof prop === 'string' && prop in target.data) {
66
+ return {
67
+ configurable: true,
68
+ enumerable: true,
69
+ writable: true,
70
+ value: target.data[prop]
71
+ };
72
+ }
73
+ return undefined;
74
+ }
75
+ });
20
76
  }
21
77
  /**
22
78
  * Custom toJSON method to control what gets serialized when logging
@@ -3,6 +3,7 @@ import ProductInstance from "./product.instance.js";
3
3
  /**
4
4
  * Product pagination instance class providing a fluent API for paginated product results
5
5
  * Provides methods for navigating through pages of products
6
+ * Supports array methods like map, filter, forEach for direct iteration
6
7
  */
7
8
  export default class ProductPaginationInstance {
8
9
  products: ProductInstance[];
@@ -23,6 +24,63 @@ export default class ProductPaginationInstance {
23
24
  * @param results - The paginated product results from the API
24
25
  */
25
26
  constructor(api: any, results: ProductsResponse);
27
+ /**
28
+ * Returns the number of products in the current page
29
+ */
30
+ get length(): number;
31
+ /**
32
+ * Maps over the products array
33
+ * @param callback - Function to execute for each product
34
+ * @returns Array of mapped results
35
+ */
36
+ map<T>(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => T): T[];
37
+ /**
38
+ * Filters the products array
39
+ * @param callback - Function to test each product
40
+ * @returns Array of products that pass the test
41
+ */
42
+ filter(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance[];
43
+ /**
44
+ * Executes a function for each product
45
+ * @param callback - Function to execute for each product
46
+ */
47
+ forEach(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => void): void;
48
+ /**
49
+ * Finds the first product that satisfies the test
50
+ * @param callback - Function to test each product
51
+ * @returns The first product that passes the test, or undefined
52
+ */
53
+ find(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance | undefined;
54
+ /**
55
+ * Finds the index of the first product that satisfies the test
56
+ * @param callback - Function to test each product
57
+ * @returns The index of the first product that passes the test, or -1
58
+ */
59
+ findIndex(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): number;
60
+ /**
61
+ * Checks if some products satisfy the test
62
+ * @param callback - Function to test each product
63
+ * @returns true if at least one product passes the test
64
+ */
65
+ some(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean;
66
+ /**
67
+ * Checks if all products satisfy the test
68
+ * @param callback - Function to test each product
69
+ * @returns true if all products pass the test
70
+ */
71
+ every(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean;
72
+ /**
73
+ * Reduces the products array to a single value
74
+ * @param callback - Function to execute on each product
75
+ * @param initialValue - Initial value for the accumulator
76
+ * @returns The final accumulated value
77
+ */
78
+ reduce<T>(callback: (accumulator: T, product: ProductInstance, index: number, array: ProductInstance[]) => T, initialValue: T): T;
79
+ /**
80
+ * Makes the instance iterable
81
+ * @returns Iterator for the products array
82
+ */
83
+ [Symbol.iterator](): Iterator<ProductInstance>;
26
84
  /**
27
85
  * Custom toJSON method to control what gets serialized when logging
28
86
  * @returns Serialized products and pagination data
@@ -2,6 +2,7 @@ import ProductInstance from "./product.instance.js";
2
2
  /**
3
3
  * Product pagination instance class providing a fluent API for paginated product results
4
4
  * Provides methods for navigating through pages of products
5
+ * Supports array methods like map, filter, forEach for direct iteration
5
6
  */
6
7
  export default class ProductPaginationInstance {
7
8
  /**
@@ -29,6 +30,83 @@ export default class ProductPaginationInstance {
29
30
  configurable: true
30
31
  });
31
32
  }
33
+ /**
34
+ * Returns the number of products in the current page
35
+ */
36
+ get length() {
37
+ return this.products.length;
38
+ }
39
+ /**
40
+ * Maps over the products array
41
+ * @param callback - Function to execute for each product
42
+ * @returns Array of mapped results
43
+ */
44
+ map(callback) {
45
+ return this.products.map(callback);
46
+ }
47
+ /**
48
+ * Filters the products array
49
+ * @param callback - Function to test each product
50
+ * @returns Array of products that pass the test
51
+ */
52
+ filter(callback) {
53
+ return this.products.filter(callback);
54
+ }
55
+ /**
56
+ * Executes a function for each product
57
+ * @param callback - Function to execute for each product
58
+ */
59
+ forEach(callback) {
60
+ this.products.forEach(callback);
61
+ }
62
+ /**
63
+ * Finds the first product that satisfies the test
64
+ * @param callback - Function to test each product
65
+ * @returns The first product that passes the test, or undefined
66
+ */
67
+ find(callback) {
68
+ return this.products.find(callback);
69
+ }
70
+ /**
71
+ * Finds the index of the first product that satisfies the test
72
+ * @param callback - Function to test each product
73
+ * @returns The index of the first product that passes the test, or -1
74
+ */
75
+ findIndex(callback) {
76
+ return this.products.findIndex(callback);
77
+ }
78
+ /**
79
+ * Checks if some products satisfy the test
80
+ * @param callback - Function to test each product
81
+ * @returns true if at least one product passes the test
82
+ */
83
+ some(callback) {
84
+ return this.products.some(callback);
85
+ }
86
+ /**
87
+ * Checks if all products satisfy the test
88
+ * @param callback - Function to test each product
89
+ * @returns true if all products pass the test
90
+ */
91
+ every(callback) {
92
+ return this.products.every(callback);
93
+ }
94
+ /**
95
+ * Reduces the products array to a single value
96
+ * @param callback - Function to execute on each product
97
+ * @param initialValue - Initial value for the accumulator
98
+ * @returns The final accumulated value
99
+ */
100
+ reduce(callback, initialValue) {
101
+ return this.products.reduce(callback, initialValue);
102
+ }
103
+ /**
104
+ * Makes the instance iterable
105
+ * @returns Iterator for the products array
106
+ */
107
+ [Symbol.iterator]() {
108
+ return this.products[Symbol.iterator]();
109
+ }
32
110
  /**
33
111
  * Custom toJSON method to control what gets serialized when logging
34
112
  * @returns Serialized products and pagination data