@halix/action-sdk 1.0.21 → 1.0.22

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.
@@ -112,6 +112,8 @@ function getObjectAsObservable(dataElementId, key, fetchedRelationships) {
112
112
  * objects will include the specified related objects as nested objects
113
113
  *
114
114
  * @returns Promise resolving to an array of objects
115
+ *
116
+ * @see {@link FilterExpression} for filter syntax and examples
115
117
  */
116
118
  function getRelatedObjects(parentElementId, parentKey, elementId, filter, fetchedRelationships) {
117
119
  return __awaiter(this, void 0, void 0, function* () {
@@ -158,6 +160,8 @@ function getRelatedObjects(parentElementId, parentKey, elementId, filter, fetche
158
160
  * objects will include the specified related objects as nested objects
159
161
  *
160
162
  * @returns Observable resolving to an array of objects
163
+ *
164
+ * @see {@link FilterExpression} for filter syntax and examples
161
165
  */
162
166
  function getRelatedObjectsAsObservable(parentElementId, parentKey, elementId, filter, fetchedRelationships) {
163
167
  return (0, rxjs_1.from)(getRelatedObjects(parentElementId, parentKey, elementId, filter, fetchedRelationships));
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ // Halix SDK License v1.0
3
+ // Copyright (c) 2025 halix.io LLC.
4
+ //
5
+ // This source code is licensed for use **only** within applications
6
+ // running on the Halix platform, in accordance with Halix SDK guidelines.
7
+ //
8
+ // Unauthorized use outside the Halix platform is prohibited.
9
+ // Full license terms available in the LICENSE file.
10
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/cjs/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // Unauthorized use outside the Halix platform is prohibited.
9
9
  // Full license terms available in the LICENSE file.
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.debounceFn = exports.getValueFromObject = exports.compareValues = exports.sortObjectArray = exports.getListDataAsObservable = exports.getListData = exports.createOrUpdateResourceAsObservable = exports.createOrUpdateResource = exports.sendFileContentsAsObservable = exports.sendFileContents = exports.saveResourceAsObservable = exports.saveResource = exports.getOrCreateResourceAsObservable = exports.getOrCreateResource = exports.deleteRelatedObjectsAsObservable = exports.deleteRelatedObjects = exports.deleteRelatedObjectAsObservable = exports.deleteRelatedObject = exports.saveRelatedObjectAsObservable = exports.saveRelatedObject = exports.getRelatedObjectsAsObservable = exports.getRelatedObjects = exports.getObjectAsObservable = exports.getObject = exports.prepareErrorResponse = exports.prepareSuccessResponse = exports.initialize = exports.useBody = exports.params = exports.userContext = exports.actionSubject = exports.serviceAddress = exports.sandboxKey = exports.getAuthToken = void 0;
11
+ exports.debounceFn = exports.getValueFromObject = exports.compareValues = exports.sortObjectArray = exports.massDeleteAsObservable = exports.massDelete = exports.massEditAsObservable = exports.massEdit = exports.getListDataAsObservable = exports.getListData = exports.sendMessageAsObservable = exports.sendMessage = exports.MessageMethod = exports.createOrUpdateResourceAsObservable = exports.createOrUpdateResource = exports.sendFileContentsAsObservable = exports.sendFileContents = exports.saveResourceAsObservable = exports.saveResource = exports.getOrCreateResourceAsObservable = exports.getOrCreateResource = exports.deleteRelatedObjectsAsObservable = exports.deleteRelatedObjects = exports.deleteRelatedObjectAsObservable = exports.deleteRelatedObject = exports.saveRelatedObjectAsObservable = exports.saveRelatedObject = exports.getRelatedObjectsAsObservable = exports.getRelatedObjects = exports.getObjectAsObservable = exports.getObject = exports.prepareErrorResponse = exports.prepareSuccessResponse = exports.initialize = exports.useBody = exports.params = exports.userContext = exports.actionSubject = exports.serviceAddress = exports.sandboxKey = exports.getAuthToken = void 0;
12
12
  /**
13
13
  * @module @halix/action-sdk
14
14
  * @description Halix Platform action SDK for developing NodeJS Lambda-based actions on the Halix
@@ -62,12 +62,25 @@ Object.defineProperty(exports, "sendFileContentsAsObservable", { enumerable: tru
62
62
  Object.defineProperty(exports, "createOrUpdateResource", { enumerable: true, get: function () { return content_1.createOrUpdateResource; } });
63
63
  Object.defineProperty(exports, "createOrUpdateResourceAsObservable", { enumerable: true, get: function () { return content_1.createOrUpdateResourceAsObservable; } });
64
64
  // ================================================================================
65
+ // MESSAGING FUNCTIONS
66
+ // ================================================================================
67
+ var messaging_1 = require("./messaging");
68
+ // Messaging Enums
69
+ Object.defineProperty(exports, "MessageMethod", { enumerable: true, get: function () { return messaging_1.MessageMethod; } });
70
+ // Messaging Functions
71
+ Object.defineProperty(exports, "sendMessage", { enumerable: true, get: function () { return messaging_1.sendMessage; } });
72
+ Object.defineProperty(exports, "sendMessageAsObservable", { enumerable: true, get: function () { return messaging_1.sendMessageAsObservable; } });
73
+ // ================================================================================
65
74
  // LIST DATA FUNCTIONS
66
75
  // ================================================================================
67
76
  var lists_1 = require("./lists");
68
77
  // Functions
69
78
  Object.defineProperty(exports, "getListData", { enumerable: true, get: function () { return lists_1.getListData; } });
70
79
  Object.defineProperty(exports, "getListDataAsObservable", { enumerable: true, get: function () { return lists_1.getListDataAsObservable; } });
80
+ Object.defineProperty(exports, "massEdit", { enumerable: true, get: function () { return lists_1.massEdit; } });
81
+ Object.defineProperty(exports, "massEditAsObservable", { enumerable: true, get: function () { return lists_1.massEditAsObservable; } });
82
+ Object.defineProperty(exports, "massDelete", { enumerable: true, get: function () { return lists_1.massDelete; } });
83
+ Object.defineProperty(exports, "massDeleteAsObservable", { enumerable: true, get: function () { return lists_1.massDeleteAsObservable; } });
71
84
  // ================================================================================
72
85
  // UTILITY FUNCTIONS
73
86
  // ================================================================================
package/lib/cjs/lists.js CHANGED
@@ -22,9 +22,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.getListData = getListData;
24
24
  exports.getListDataAsObservable = getListDataAsObservable;
25
+ exports.massEdit = massEdit;
26
+ exports.massEditAsObservable = massEditAsObservable;
27
+ exports.massDelete = massDelete;
28
+ exports.massDeleteAsObservable = massDeleteAsObservable;
25
29
  /**
26
30
  * @module @halix/action-sdk/lists
27
- * @description List data retrieval functions. Use this to efficiently retrieve objects
31
+ * @description List data retrieval and bulk operations. Use this to efficiently retrieve objects
28
32
  * from the database for display in list-like user interfaces. This is preferred over
29
33
  * the `data-crud` module when showing one page of data at a time.
30
34
  *
@@ -34,6 +38,8 @@ exports.getListDataAsObservable = getListDataAsObservable;
34
38
  * - Sorting
35
39
  * - Filtering
36
40
  * - Search
41
+ * - Mass edit operations (bulk update multiple records)
42
+ * - Mass delete operations (bulk delete multiple records)
37
43
  */
38
44
  const axios_1 = __importDefault(require("axios"));
39
45
  const rxjs_1 = require("rxjs");
@@ -173,3 +179,176 @@ function getListData(request, options) {
173
179
  function getListDataAsObservable(request, options) {
174
180
  return (0, rxjs_1.from)(getListData(request, options));
175
181
  }
182
+ // ================================================================================
183
+ // MASS EDIT AND DELETE FUNCTIONS
184
+ // ================================================================================
185
+ /**
186
+ * massEdit performs a bulk update operation on multiple records. This function allows you to
187
+ * update a specific property on multiple objects in a single request.
188
+ *
189
+ * **Security Scoping**: The dataRequest serves as a security boundary. Only records that would
190
+ * be returned by the dataRequest can be updated. The keys array must reference records within
191
+ * this scope. This allows efficient security validation without checking each record individually.
192
+ *
193
+ * The value can be set in two ways based on valueType:
194
+ * - 'literal': Set the property to a literal value
195
+ * - 'property': Copy the value from another property on the same object
196
+ *
197
+ * @param request - The mass edit request specifying what to update and how
198
+ *
199
+ * @returns Promise resolving to statistics about the operation
200
+ *
201
+ * @example
202
+ * // Update the status of multiple orders to 'shipped'
203
+ * const result = await massEdit({
204
+ * keys: ['order-123', 'order-456', 'order-789'],
205
+ * dataRequest: {
206
+ * dataElementId: 'order',
207
+ * parentDataElementId: 'company',
208
+ * parentKey: orgProxyKey
209
+ * },
210
+ * dataElementId: 'order',
211
+ * property: 'status',
212
+ * valueType: 'literal',
213
+ * value: 'shipped'
214
+ * });
215
+ * console.log(`Updated ${result.succeeded} of ${result.tried} orders`);
216
+ *
217
+ * @example
218
+ * // Copy shipping address to billing address for multiple customers
219
+ * const result = await massEdit({
220
+ * keys: selectedCustomerKeys,
221
+ * dataRequest: {
222
+ * dataElementId: 'customer',
223
+ * parentDataElementId: 'company',
224
+ * parentKey: orgProxyKey
225
+ * },
226
+ * dataElementId: 'customer',
227
+ * property: 'billingAddress',
228
+ * valueType: 'property',
229
+ * value: 'shippingAddress'
230
+ * });
231
+ */
232
+ function massEdit(request) {
233
+ return __awaiter(this, void 0, void 0, function* () {
234
+ const url = `${sdk_general_1.serviceAddress}/list/sandboxes/${sdk_general_1.sandboxKey}/massedit`;
235
+ // Build headers with authentication token
236
+ let authToken = yield (0, rxjs_1.lastValueFrom)((0, sdk_general_1.getAuthToken)());
237
+ let headers = {
238
+ Authorization: `Bearer ${authToken}`
239
+ };
240
+ console.log("Sending POST request to " + url + " with token " + authToken);
241
+ // Make the API request
242
+ let response = yield axios_1.default.post(url, request, { headers });
243
+ return response.data;
244
+ });
245
+ }
246
+ /**
247
+ * massEditAsObservable performs a bulk update operation on multiple records, returning an Observable.
248
+ * See massEdit for detailed documentation.
249
+ *
250
+ * @param request - The mass edit request specifying what to update and how
251
+ *
252
+ * @returns Observable resolving to statistics about the operation
253
+ *
254
+ * @example
255
+ * massEditAsObservable({
256
+ * keys: ['order-123', 'order-456'],
257
+ * dataRequest: {
258
+ * dataElementId: 'order',
259
+ * parentDataElementId: 'company',
260
+ * parentKey: orgProxyKey
261
+ * },
262
+ * dataElementId: 'order',
263
+ * property: 'status',
264
+ * valueType: 'literal',
265
+ * value: 'shipped'
266
+ * }).subscribe(result => {
267
+ * console.log(`Updated ${result.succeeded} of ${result.tried} orders`);
268
+ * });
269
+ */
270
+ function massEditAsObservable(request) {
271
+ return (0, rxjs_1.from)(massEdit(request));
272
+ }
273
+ /**
274
+ * massDelete performs a bulk delete operation on multiple records. This function allows you to
275
+ * soft-delete multiple objects in a single request.
276
+ *
277
+ * **Security Scoping**: The dataRequest serves as a security boundary. Only records that would
278
+ * be returned by the dataRequest can be deleted. The keys array must reference records within
279
+ * this scope. This allows efficient security validation without checking each record individually.
280
+ *
281
+ * If emptyList is set to true, all records returned by the dataRequest will be deleted,
282
+ * ignoring the keys array.
283
+ *
284
+ * @param request - The mass delete request specifying what to delete
285
+ *
286
+ * @returns Promise resolving to statistics about the operation
287
+ *
288
+ * @example
289
+ * // Delete specific orders
290
+ * const result = await massDelete({
291
+ * keys: ['order-123', 'order-456', 'order-789'],
292
+ * dataRequest: {
293
+ * dataElementId: 'order',
294
+ * parentDataElementId: 'company',
295
+ * parentKey: orgProxyKey,
296
+ * filter: { field: 'status', operator: '==', value: 'cancelled' }
297
+ * },
298
+ * dataElementId: 'order'
299
+ * });
300
+ * console.log(`Deleted ${result.succeeded} of ${result.tried} orders`);
301
+ *
302
+ * @example
303
+ * // Delete all records matching the filter
304
+ * const result = await massDelete({
305
+ * keys: [],
306
+ * dataRequest: {
307
+ * dataElementId: 'tempRecord',
308
+ * parentDataElementId: 'company',
309
+ * parentKey: orgProxyKey,
310
+ * filter: { field: 'createdDate', operator: '<', value: '2023-01-01' }
311
+ * },
312
+ * dataElementId: 'tempRecord',
313
+ * emptyList: true
314
+ * });
315
+ * console.log(`Deleted ${result.succeeded} old records`);
316
+ */
317
+ function massDelete(request) {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ const url = `${sdk_general_1.serviceAddress}/list/sandboxes/${sdk_general_1.sandboxKey}/massdelete`;
320
+ // Build headers with authentication token
321
+ let authToken = yield (0, rxjs_1.lastValueFrom)((0, sdk_general_1.getAuthToken)());
322
+ let headers = {
323
+ Authorization: `Bearer ${authToken}`
324
+ };
325
+ console.log("Sending POST request to " + url + " with token " + authToken);
326
+ // Make the API request
327
+ let response = yield axios_1.default.post(url, request, { headers });
328
+ return response.data;
329
+ });
330
+ }
331
+ /**
332
+ * massDeleteAsObservable performs a bulk delete operation on multiple records, returning an Observable.
333
+ * See massDelete for detailed documentation.
334
+ *
335
+ * @param request - The mass delete request specifying what to delete
336
+ *
337
+ * @returns Observable resolving to statistics about the operation
338
+ *
339
+ * @example
340
+ * massDeleteAsObservable({
341
+ * keys: ['order-123', 'order-456'],
342
+ * dataRequest: {
343
+ * dataElementId: 'order',
344
+ * parentDataElementId: 'company',
345
+ * parentKey: orgProxyKey
346
+ * },
347
+ * dataElementId: 'order'
348
+ * }).subscribe(result => {
349
+ * console.log(`Deleted ${result.succeeded} of ${result.tried} orders`);
350
+ * });
351
+ */
352
+ function massDeleteAsObservable(request) {
353
+ return (0, rxjs_1.from)(massDelete(request));
354
+ }
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ // Halix SDK License v1.0
3
+ // Copyright (c) 2025 halix.io LLC.
4
+ //
5
+ // This source code is licensed for use **only** within applications
6
+ // running on the Halix platform, in accordance with Halix SDK guidelines.
7
+ //
8
+ // Unauthorized use outside the Halix platform is prohibited.
9
+ // Full license terms available in the LICENSE file.
10
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
11
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
12
+ return new (P || (P = Promise))(function (resolve, reject) {
13
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
14
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
15
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
16
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
17
+ });
18
+ };
19
+ var __importDefault = (this && this.__importDefault) || function (mod) {
20
+ return (mod && mod.__esModule) ? mod : { "default": mod };
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.MessageMethod = void 0;
24
+ exports.sendMessage = sendMessage;
25
+ exports.sendMessageAsObservable = sendMessageAsObservable;
26
+ /**
27
+ * @module @halix/action-sdk/messaging
28
+ * @description Messaging and notification functions for the Halix Platform action SDK. This module
29
+ * provides functions for sending messages (email, text) through the Halix notification service.
30
+ */
31
+ const axios_1 = __importDefault(require("axios"));
32
+ const rxjs_1 = require("rxjs");
33
+ const sdk_general_1 = require("./sdk-general");
34
+ // ================================================================================
35
+ // ENUMS & CONSTANTS
36
+ // ================================================================================
37
+ /**
38
+ * MessageMethod represents the delivery method for a message.
39
+ */
40
+ var MessageMethod;
41
+ (function (MessageMethod) {
42
+ /** Send as email */
43
+ MessageMethod["Email"] = "email";
44
+ /** Send as text/SMS */
45
+ MessageMethod["Text"] = "text";
46
+ /** Send as both email and text */
47
+ MessageMethod["EmailAndText"] = "email,text";
48
+ })(MessageMethod || (exports.MessageMethod = MessageMethod = {}));
49
+ // ================================================================================
50
+ // MESSAGING FUNCTIONS
51
+ // ================================================================================
52
+ /**
53
+ * sendMessage sends a message (email and/or text) to recipients through the Halix notification
54
+ * service. The message is sent asynchronously - this function returns immediately after the
55
+ * message is queued for sending.
56
+ *
57
+ * @param orgProxyElementId - The ID of the organization proxy element (e.g., "business", "school")
58
+ * @param orgProxyKey - The key of the organization proxy object
59
+ * @param message - The message request object containing recipients, content, and delivery options
60
+ *
61
+ * @returns Promise that resolves when the message has been queued for sending
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Send an email to customers (sentAs defaults to email)
66
+ * await sendMessage('business', businessKey, {
67
+ * userProxyKeys: [customerKey1, customerKey2, customerKey3],
68
+ * subject: 'Important Announcement',
69
+ * body: '<p>This is an important announcement.</p>',
70
+ * replyToEmail: 'sender@example.com'
71
+ * });
72
+ * ```
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // Send to user proxies and direct email addresses
77
+ * await sendMessage('business', businessKey, {
78
+ * userProxyKeys: [clientKey1, clientKey2],
79
+ * directEmailAddresses: ['manager@example.com'],
80
+ * sentAs: MessageMethod.EmailAndText,
81
+ * subject: 'Project Reminder',
82
+ * body: '<p>Don\'t forget about the deadline.</p>',
83
+ * resourceKeys: [attachmentKey]
84
+ * });
85
+ * ```
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Send email to direct addresses only (no user proxies)
90
+ * await sendMessage('business', businessKey, {
91
+ * directEmailAddresses: ['partner@example.com', 'vendor@example.com'],
92
+ * subject: 'External Notification',
93
+ * body: '<p>Important information for external stakeholders.</p>'
94
+ * });
95
+ * ```
96
+ */
97
+ function sendMessage(orgProxyElementId, orgProxyKey, message) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ var _a;
100
+ // Build the server request from the simplified client request
101
+ const serverRequest = {
102
+ recipientGroups: message.userProxyKeys && message.userProxyKeys.length > 0 ? [
103
+ {
104
+ type: "",
105
+ recipientKeys: message.userProxyKeys
106
+ }
107
+ ] : [],
108
+ sentAs: ((_a = message.sentAs) === null || _a === void 0 ? void 0 : _a.toString()) || MessageMethod.Email,
109
+ type: "direct",
110
+ subject: message.subject,
111
+ body: message.body,
112
+ replyToEmail: message.replyToEmail,
113
+ resourceKeys: message.resourceKeys,
114
+ additionalEmails: message.directEmailAddresses
115
+ };
116
+ let url = `${sdk_general_1.serviceAddress}/notification/sandboxes/${sdk_general_1.sandboxKey}/${orgProxyElementId}/${orgProxyKey}/sendMessage`;
117
+ let authToken = yield (0, rxjs_1.lastValueFrom)((0, sdk_general_1.getAuthToken)());
118
+ console.log("Sending POST request to " + url + " with token " + authToken);
119
+ yield axios_1.default.post(url, serverRequest, {
120
+ headers: { "Authorization": `Bearer ${authToken}` },
121
+ });
122
+ // Note: The message is sent asynchronously by the notification service
123
+ // This function returns once the message has been queued, not when delivery is complete
124
+ });
125
+ }
126
+ /**
127
+ * sendMessageAsObservable sends a message (email and/or text) to recipients through the Halix
128
+ * notification service. The message is sent asynchronously - this observable completes immediately
129
+ * after the message is queued for sending.
130
+ *
131
+ * @param orgProxyElementId - The ID of the organization proxy element (e.g., "business", "school")
132
+ * @param orgProxyKey - The key of the organization proxy object
133
+ * @param message - The message request object containing recipients, content, and delivery options
134
+ *
135
+ * @returns Observable that completes when the message has been queued for sending
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * sendMessageAsObservable('business', businessKey, {
140
+ * userProxyKeys: [customerKey1, customerKey2],
141
+ * directEmailAddresses: ['admin@example.com'],
142
+ * subject: 'Monthly Newsletter',
143
+ * body: '<p>Newsletter content here...</p>'
144
+ * }).subscribe({
145
+ * next: () => console.log('Message queued for sending'),
146
+ * error: (err) => console.error('Failed to send message:', err)
147
+ * });
148
+ * ```
149
+ */
150
+ function sendMessageAsObservable(orgProxyElementId, orgProxyKey, message) {
151
+ return (0, rxjs_1.from)(sendMessage(orgProxyElementId, orgProxyKey, message));
152
+ }
@@ -1,4 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
+ import { FilterExpression } from './filter-expressions';
2
3
  /**
3
4
  * SaveOptions is an interface for specifying save operation options.
4
5
  */
@@ -49,8 +50,10 @@ export declare function getObjectAsObservable(dataElementId: string, key: string
49
50
  * objects will include the specified related objects as nested objects
50
51
  *
51
52
  * @returns Promise resolving to an array of objects
53
+ *
54
+ * @see {@link FilterExpression} for filter syntax and examples
52
55
  */
53
- export declare function getRelatedObjects(parentElementId: string, parentKey: string, elementId: string, filter?: string, fetchedRelationships?: string[]): Promise<any[]>;
56
+ export declare function getRelatedObjects(parentElementId: string, parentKey: string, elementId: string, filter?: FilterExpression, fetchedRelationships?: string[]): Promise<any[]>;
54
57
  /**
55
58
  * getRelatedObjectsAsObservable retrieves an array of objects from the the database. The objects
56
59
  * returned are related to a parent through a defined relationship in the schema. In a typical
@@ -73,8 +76,10 @@ export declare function getRelatedObjects(parentElementId: string, parentKey: st
73
76
  * objects will include the specified related objects as nested objects
74
77
  *
75
78
  * @returns Observable resolving to an array of objects
79
+ *
80
+ * @see {@link FilterExpression} for filter syntax and examples
76
81
  */
77
- export declare function getRelatedObjectsAsObservable(parentElementId: string, parentKey: string, elementId: string, filter?: string, fetchedRelationships?: string[]): Observable<any[]>;
82
+ export declare function getRelatedObjectsAsObservable(parentElementId: string, parentKey: string, elementId: string, filter?: FilterExpression, fetchedRelationships?: string[]): Observable<any[]>;
78
83
  /**
79
84
  * saveRelatedObject saves a related object to the database. The objectToSave is saved, and its
80
85
  * relationship to the parent object is established based on the relationship specified in the
@@ -1 +1 @@
1
- {"version":3,"file":"data-crud.d.ts","sourceRoot":"","sources":["../../../src/data-crud.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAQ,UAAU,EAAiB,MAAM,MAAM,CAAC;AAOvD;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAMD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,gBAwBlG;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAE1H;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CA2BvK;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAEhL;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAmB7J;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAEtK;AAMD;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBhJ;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAEzJ;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBpJ;AAED;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAE7J"}
1
+ {"version":3,"file":"data-crud.d.ts","sourceRoot":"","sources":["../../../src/data-crud.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAQ,UAAU,EAAiB,MAAM,MAAM,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAMxD;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAMD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,gBAwBlG;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAE1H;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CA2BjL;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAE1L;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAmB7J;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAEtK;AAMD;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBhJ;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAEzJ;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBpJ;AAED;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAE7J"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * @module @halix/action-sdk/filter-expressions
3
+ * @description Filter expression language (dataexpr format) used throughout the SDK for filtering
4
+ * data in queries.
5
+ */
6
+ /**
7
+ * FilterExpression represents a filter expression string in the Halix dataexpr format.
8
+ *
9
+ * Filter expressions are used to filter data based on logical comparisons and boolean conditions.
10
+ * They support a wide range of operators, boolean logic, arrays, and special variables.
11
+ *
12
+ * ## Expression Structure
13
+ *
14
+ * An expression consists of:
15
+ * - One or more comparisons
16
+ * - Optionally combined using boolean operators (`AND`, `OR`)
17
+ * - Grouped using parentheses `(...)` for logical grouping and precedence
18
+ *
19
+ * ### Basic Forms
20
+ * ```
21
+ * <left> <operator> <right>
22
+ * (<expression1>) AND (<expression2>)
23
+ * (<expression1>) OR (<expression2>)
24
+ * ```
25
+ *
26
+ * ## Supported Operators
27
+ *
28
+ * | Operator | Description | Example |
29
+ * |----------|-------------|---------|
30
+ * | `=` | Equals | `status = 'active'` |
31
+ * | `!=` | Not equals | `status != 'closed'` |
32
+ * | `~` | Equals (case-insensitive) | `name ~ 'ADMIN'` |
33
+ * | `!~` | Not equals (case-insensitive) | `role !~ 'ADMIN'` |
34
+ * | `<` | Less than | `score < '80'` |
35
+ * | `>` | Greater than | `score > '90'` |
36
+ * | `<=` | Less than or equal to | `score <= '90'` |
37
+ * | `>=` | Greater than or equal to | `score >= '70'` |
38
+ * | `!>` | Begins with | `name !> 'Jo'` |
39
+ * | `<!` | Ends with | `email <! '@example.com'` |
40
+ * | `<>` | Contains (string or array) | `tags <> 'urgent'` |
41
+ * | `!<>` | Does not contain | `tags !<> 'archived'` |
42
+ * | `<empty> $void` | Value is empty | `notes <empty> $void` |
43
+ * | `!<empty> $void` | Value is not empty | `notes !<empty> $void` |
44
+ *
45
+ * ## Value Types
46
+ *
47
+ * Values in expressions can be:
48
+ * - **String literals**: Must be wrapped in single quotes - `'value'`
49
+ * - **Attribute references**: Must not be quoted - `status`, `score`
50
+ * - **Arrays**: Literal arrays - `['A', 'B', 'C']`
51
+ * - **Variables**: Special variables - `$today`, `$daysAgo:5`
52
+ * - **Page/group variables**: Must be quoted - `'@{page.fieldName}'`, `'@{group.fieldName}'`
53
+ *
54
+ * ## Boolean Logic
55
+ *
56
+ * Combine comparisons using:
57
+ * - `AND` – all subexpressions must be true
58
+ * - `OR` – at least one subexpression must be true
59
+ *
60
+ * **Important**: Each operand of `AND`/`OR` must be enclosed in parentheses.
61
+ *
62
+ * ### Examples
63
+ * ```
64
+ * (status = 'active') AND (priority = 'high')
65
+ * (status = 'active') AND ((priority = 'high') OR (escalated = 'true'))
66
+ * ```
67
+ *
68
+ * ## Expression Variables
69
+ *
70
+ * Use special `$variables` for dynamic time-based filtering:
71
+ *
72
+ * | Variable | Meaning |
73
+ * |----------|---------|
74
+ * | `$today` | Current date (e.g. `2023-06-25`) |
75
+ * | `$todayTimestamp` | Timestamp for midnight today |
76
+ * | `$todayUnixTimestamp` | Unix timestamp (ms) for today |
77
+ * | `$startOfMonth` | First day of the current month |
78
+ * | `$endOfMonth` | Last day of the current month |
79
+ * | `$yearsAgo:N` | Timestamp N years ago |
80
+ * | `$monthsAgo:N` | Timestamp N months ago |
81
+ * | `$weeksAgo:N` | Timestamp N weeks ago |
82
+ * | `$daysAgo:N` | Timestamp N days ago |
83
+ * | `$hoursAgo:N` | Timestamp N hours ago |
84
+ * | `$minutesAgo:N` | Timestamp N minutes ago |
85
+ * | `$secondsAgo:N` | Timestamp N seconds ago |
86
+ * | `$yearsAhead:N` | Timestamp N years in the future |
87
+ * | `$monthsAhead:N` | Timestamp N months in the future |
88
+ * | `$weeksAhead:N` | Timestamp N weeks in the future |
89
+ * | `$daysAhead:N` | Timestamp N days in the future |
90
+ * | `$hoursAhead:N` | Timestamp N hours in the future |
91
+ * | `$minutesAhead:N` | Timestamp N minutes in the future |
92
+ * | `$secondsAhead:N` | Timestamp N seconds in the future |
93
+ *
94
+ * ## Common Examples
95
+ *
96
+ * ### Simple Comparison
97
+ * ```typescript
98
+ * const filter = "status = 'active'";
99
+ * ```
100
+ *
101
+ * ### Case-Insensitive Match
102
+ * ```typescript
103
+ * const filter = "role ~ 'ADMIN'";
104
+ * ```
105
+ *
106
+ * ### Contains Check
107
+ * ```typescript
108
+ * const filter = "notes <> 'important'";
109
+ * ```
110
+ *
111
+ * ### Array Contains
112
+ * ```typescript
113
+ * const filter = "['pending', 'active', 'review'] <> status";
114
+ * ```
115
+ *
116
+ * ### Empty/Not Empty
117
+ * ```typescript
118
+ * const filter = "notes !<empty> $void"; // Has notes
119
+ * ```
120
+ *
121
+ * ### Compound Expression
122
+ * ```typescript
123
+ * const filter = "(status = 'active') AND (priority = 'high')";
124
+ * ```
125
+ *
126
+ * ### Nested Logic
127
+ * ```typescript
128
+ * const filter = "(status = 'active') AND ((score > '90') OR (grade = 'A'))";
129
+ * ```
130
+ *
131
+ * ### Time-Based Filtering
132
+ * ```typescript
133
+ * const filter = "createdAt > $daysAgo:30"; // Created in last 30 days
134
+ * ```
135
+ *
136
+ * ### Boolean Values
137
+ * ```typescript
138
+ * const filter = "enabled = boolean:true";
139
+ * ```
140
+ *
141
+ * ### Using Page Variables
142
+ * ```typescript
143
+ * const filter = "category = '@{page.selectedCategory.value}'";
144
+ * ```
145
+ *
146
+ * ### Complex Multi-Condition Filter
147
+ * ```typescript
148
+ * const filter = "(status = 'active') AND " +
149
+ * "((priority = 'high') OR (dueDate < $today)) AND " +
150
+ * "(assignedTo !<empty> $void)";
151
+ * ```
152
+ */
153
+ export type FilterExpression = string;
154
+ //# sourceMappingURL=filter-expressions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-expressions.d.ts","sourceRoot":"","sources":["../../../src/filter-expressions.ts"],"names":[],"mappings":"AASA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkJG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC"}
@@ -6,6 +6,8 @@
6
6
  export { getAuthToken, sandboxKey, serviceAddress, actionSubject, userContext, params, useBody, initialize, type UserContext, type IncomingEventBody, type BaseActionResponse, type ActionResponse, type NotificationConfig, type ListActionResponse, type FormTemplateActionResponse, type PageTemplateActionResponse, type ObjectSaveActionResponse, type CalculatedFieldActionResponse, type SingleValueActionResponse, type ErrorResponse, prepareSuccessResponse, prepareErrorResponse } from './sdk-general';
7
7
  export { type SaveOptions, getObject, getObjectAsObservable, getRelatedObjects, getRelatedObjectsAsObservable, saveRelatedObject, saveRelatedObjectAsObservable, deleteRelatedObject, deleteRelatedObjectAsObservable, deleteRelatedObjects, deleteRelatedObjectsAsObservable } from './data-crud';
8
8
  export { type ContentResource, getOrCreateResource, getOrCreateResourceAsObservable, saveResource, saveResourceAsObservable, sendFileContents, sendFileContentsAsObservable, createOrUpdateResource, createOrUpdateResourceAsObservable } from './content';
9
- export { type SortField, type DataSortField, type ListDataRequest, type ListDataResponse, type ListDataOptions, type ListDataSearchOptions, getListData, getListDataAsObservable } from './lists';
9
+ export { MessageMethod, type MessageRequest, sendMessage, sendMessageAsObservable } from './messaging';
10
+ export { type FilterExpression } from './filter-expressions';
11
+ export { type SortField, type DataSortField, type BaseListDataRequest, type PagedListDataRequest, type ListDataResponse, type ListDataOptions, type ListDataSearchOptions, type MassEditValueType, type MassEditRequest, type MassDeleteRequest, type MassChangeResponse, getListData, getListDataAsObservable, massEdit, massEditAsObservable, massDelete, massDeleteAsObservable } from './lists';
10
12
  export { sortObjectArray, compareValues, getValueFromObject, debounceFn } from './utilities';
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AASA;;;;GAIG;AAMH,OAAO,EAEH,YAAY,EACZ,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,MAAM,EACN,OAAO,EAGP,UAAU,EAGV,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAGtB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAGlB,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,eAAe,CAAC;AAMvB,OAAO,EAEH,KAAK,WAAW,EAGhB,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,EAG7B,iBAAiB,EACjB,6BAA6B,EAG7B,mBAAmB,EACnB,+BAA+B,EAC/B,oBAAoB,EACpB,gCAAgC,EACnC,MAAM,aAAa,CAAC;AAMrB,OAAO,EAEH,KAAK,eAAe,EAGpB,mBAAmB,EACnB,+BAA+B,EAC/B,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,kCAAkC,EACrC,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEH,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAG1B,WAAW,EACX,uBAAuB,EAC1B,MAAM,SAAS,CAAC;AAMjB,OAAO,EACH,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,UAAU,EACb,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AASA;;;;GAIG;AAMH,OAAO,EAEH,YAAY,EACZ,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,MAAM,EACN,OAAO,EAGP,UAAU,EAGV,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAGtB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAGlB,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,eAAe,CAAC;AAMvB,OAAO,EAEH,KAAK,WAAW,EAGhB,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EACjB,6BAA6B,EAG7B,iBAAiB,EACjB,6BAA6B,EAG7B,mBAAmB,EACnB,+BAA+B,EAC/B,oBAAoB,EACpB,gCAAgC,EACnC,MAAM,aAAa,CAAC;AAMrB,OAAO,EAEH,KAAK,eAAe,EAGpB,mBAAmB,EACnB,+BAA+B,EAC/B,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,kCAAkC,EACrC,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEH,aAAa,EAGb,KAAK,cAAc,EAGnB,WAAW,EACX,uBAAuB,EAC1B,MAAM,aAAa,CAAC;AAMrB,OAAO,EACH,KAAK,gBAAgB,EACxB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAEH,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAGvB,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,oBAAoB,EACpB,UAAU,EACV,sBAAsB,EACzB,MAAM,SAAS,CAAC;AAMjB,OAAO,EACH,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,UAAU,EACb,MAAM,aAAa,CAAC"}