@halix/action-sdk 1.0.6 → 1.0.7
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/LICENSE +22 -193
- package/README.md +121 -2
- package/lib/cjs/index.js +201 -17
- package/lib/cjs/types/index.d.ts +379 -13
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/esm/index.mjs +230 -32
- package/lib/esm/types/index.d.ts +379 -13
- package/lib/esm/types/index.d.ts.map +1 -1
- package/package.json +6 -5
package/lib/esm/index.mjs
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.useBody = exports.params = exports.userContext = exports.actionSubject = exports.serviceAddress = exports.sandboxKey = exports.authToken = void 0;
|
|
15
|
+
exports.getRelatedObjects = getRelatedObjects;
|
|
16
|
+
exports.getRelatedObjectsAsObservable = getRelatedObjectsAsObservable;
|
|
17
|
+
exports.getObject = getObject;
|
|
18
|
+
exports.getObjectAsObservable = getObjectAsObservable;
|
|
19
|
+
exports.saveRelatedObject = saveRelatedObject;
|
|
20
|
+
exports.saveRelatedObjectAsObservable = saveRelatedObjectAsObservable;
|
|
21
|
+
exports.sortObjectArray = sortObjectArray;
|
|
22
|
+
exports.compareValues = compareValues;
|
|
23
|
+
exports.getValueFromObject = getValueFromObject;
|
|
24
|
+
exports.prepareSuccessResponse = prepareSuccessResponse;
|
|
25
|
+
exports.prepareErrorResponse = prepareErrorResponse;
|
|
26
|
+
exports.initialize = initialize;
|
|
27
|
+
/**
|
|
28
|
+
* @module @halix/action-sdk
|
|
29
|
+
* @description Halix Platform action SDK for developing NodeJS Lambda-based actions on the Halix
|
|
30
|
+
* platform. Defines a framework for accepting incoming events from the Halix platform, making API
|
|
31
|
+
* requests to the Halix data service, and returning structured action responses back to the Halix
|
|
32
|
+
* platform.
|
|
33
|
+
*/
|
|
34
|
+
const axios_1 = __importDefault(require("axios"));
|
|
35
|
+
const rxjs_1 = require("rxjs");
|
|
36
|
+
/**
|
|
37
|
+
* getRelatedObjects retrieves an array of objects from the the database. The objects returned are
|
|
38
|
+
* related to a parent through a defined relationship in the schema. In a typical setup, action's
|
|
39
|
+
* auth token must have scope access to the parent object in order to access all of its related
|
|
40
|
+
* objects.
|
|
41
|
+
*
|
|
42
|
+
* It is common to use getRelatedObjects to retrieve all objects belonging to the current user proxy
|
|
43
|
+
* or organization proxy. For example, in a user context where the current user proxy element is
|
|
44
|
+
* "customer," an action might want to retrieve all "purchase" objects related to the current
|
|
45
|
+
* customer. Similarly, in an organization context where the current organization proxy is
|
|
46
|
+
* "business," an action might want to retrieve all "employee" objects related to the current
|
|
47
|
+
* business.
|
|
48
|
+
*
|
|
49
|
+
* @param parentElementId - The ID of the parent element
|
|
50
|
+
* @param parentKey - The key of the parent object
|
|
51
|
+
* @param elementId - The ID of the element
|
|
52
|
+
* @param filter - Optional filter criteria for the query; if not provided, all related objects will
|
|
53
|
+
* be returned
|
|
54
|
+
* @param fetchedRelationships - Optional array of relationships to fetch; if provided, the returned
|
|
55
|
+
* objects will include the specified related objects as nested objects
|
|
56
|
+
*
|
|
57
|
+
* @returns Promise resolving to an array of objects
|
|
58
|
+
*/
|
|
59
|
+
async function getRelatedObjects(parentElementId, parentKey, elementId, filter, fetchedRelationships) {
|
|
4
60
|
let params;
|
|
5
61
|
if (filter || fetchedRelationships) {
|
|
6
62
|
let p = {};
|
|
@@ -12,15 +68,50 @@ export async function getRelatedObjects(parentElementId, parentKey, elementId, f
|
|
|
12
68
|
}
|
|
13
69
|
params = new URLSearchParams(p);
|
|
14
70
|
}
|
|
15
|
-
let url = `${serviceAddress}/schema/sandboxes/${sandboxKey}/${parentElementId}/${parentKey}/${elementId}`;
|
|
16
|
-
console.log("Sending GET request to " + url + " with token " + authToken);
|
|
17
|
-
let response = await
|
|
18
|
-
headers: { "Authorization": `Bearer ${authToken}` },
|
|
71
|
+
let url = `${exports.serviceAddress}/schema/sandboxes/${exports.sandboxKey}/${parentElementId}/${parentKey}/${elementId}`;
|
|
72
|
+
console.log("Sending GET request to " + url + " with token " + exports.authToken);
|
|
73
|
+
let response = await axios_1.default.get(url, {
|
|
74
|
+
headers: { "Authorization": `Bearer ${exports.authToken}` },
|
|
19
75
|
params: params,
|
|
20
76
|
});
|
|
21
77
|
return response.data;
|
|
22
78
|
}
|
|
23
|
-
|
|
79
|
+
/**
|
|
80
|
+
* getRelatedObjectsAsObservable retrieves an array of objects from the the database. The objects
|
|
81
|
+
* returned are related to a parent through a defined relationship in the schema. In a typical
|
|
82
|
+
* setup, action's auth token must have scope access to the parent object in order to access all of
|
|
83
|
+
* its related objects.
|
|
84
|
+
*
|
|
85
|
+
* It is common to use getRelatedObjects to retrieve all objects belonging to the current user proxy
|
|
86
|
+
* or organization proxy. For example, in a user context where the current user proxy element is
|
|
87
|
+
* "customer," an action might want to retrieve all "purchase" objects related to the current
|
|
88
|
+
* customer. Similarly, in an organization context where the current organization proxy is
|
|
89
|
+
* "business," an action might want to retrieve all "employee" objects related to the current
|
|
90
|
+
* business.
|
|
91
|
+
*
|
|
92
|
+
* @param parentElementId - The ID of the parent element
|
|
93
|
+
* @param parentKey - The key of the parent element
|
|
94
|
+
* @param elementId - The ID of the element
|
|
95
|
+
* @param filter - Optional filter criteria for the query; if not provided, all related objects will
|
|
96
|
+
* be returned
|
|
97
|
+
* @param fetchedRelationships - Optional array of relationships to fetch; if provided, the returned
|
|
98
|
+
* objects will include the specified related objects as nested objects
|
|
99
|
+
*
|
|
100
|
+
* @returns Observable resolving to an array of objects
|
|
101
|
+
*/
|
|
102
|
+
function getRelatedObjectsAsObservable(parentElementId, parentKey, elementId, filter, fetchedRelationships) {
|
|
103
|
+
return (0, rxjs_1.from)(getRelatedObjects(parentElementId, parentKey, elementId, filter, fetchedRelationships));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* getObject retrieves a single object from the database by its data element ID and key.
|
|
107
|
+
*
|
|
108
|
+
* @param dataElementId - The ID of the data element
|
|
109
|
+
* @param key - The key of the object
|
|
110
|
+
* @param fetchedRelationships - Optional array of relationships to fetch; if provided, the returned
|
|
111
|
+
* object will include the specified related objects as nested objects
|
|
112
|
+
* @returns Promise resolving to the object data
|
|
113
|
+
*/
|
|
114
|
+
async function getObject(dataElementId, key, fetchedRelationships) {
|
|
24
115
|
let params;
|
|
25
116
|
if (fetchedRelationships) {
|
|
26
117
|
let p = {};
|
|
@@ -29,30 +120,83 @@ export async function getObject(dataElementId, key, fetchedRelationships) {
|
|
|
29
120
|
}
|
|
30
121
|
params = new URLSearchParams(p);
|
|
31
122
|
}
|
|
32
|
-
let url = `${serviceAddress}/schema/sandboxes/${sandboxKey}/${dataElementId}/${key}`;
|
|
33
|
-
console.log("Sending GET request to " + url + " with token " + authToken);
|
|
34
|
-
let response = await
|
|
35
|
-
headers: { "Authorization": `Bearer ${authToken}` },
|
|
123
|
+
let url = `${exports.serviceAddress}/schema/sandboxes/${exports.sandboxKey}/${dataElementId}/${key}`;
|
|
124
|
+
console.log("Sending GET request to " + url + " with token " + exports.authToken);
|
|
125
|
+
let response = await axios_1.default.get(url, {
|
|
126
|
+
headers: { "Authorization": `Bearer ${exports.authToken}` },
|
|
36
127
|
params: params,
|
|
37
128
|
});
|
|
38
129
|
return response.data;
|
|
39
130
|
}
|
|
40
|
-
|
|
41
|
-
|
|
131
|
+
/**
|
|
132
|
+
* getObjectAsObservable retrieves a single object from the database by its data element ID and key.
|
|
133
|
+
*
|
|
134
|
+
* @param dataElementId - The ID of the data element
|
|
135
|
+
* @param key - The key of the object
|
|
136
|
+
* @param fetchedRelationships - Optional array of relationships to fetch; if provided, the returned
|
|
137
|
+
* object will include the specified related objects as nested objects
|
|
138
|
+
*
|
|
139
|
+
* @returns Observable resolving to the object data
|
|
140
|
+
*/
|
|
141
|
+
function getObjectAsObservable(dataElementId, key, fetchedRelationships) {
|
|
142
|
+
return (0, rxjs_1.from)(getObject(dataElementId, key, fetchedRelationships));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* saveRelatedObject saves a related object to the database. The objectToSave is saved, and its
|
|
146
|
+
* relationship to the parent object is established based on the relationship specified in the
|
|
147
|
+
* schema. The objectToSave must have a relationship to the parent object and the user must have
|
|
148
|
+
* scope access to the parent object.
|
|
149
|
+
*
|
|
150
|
+
* @param parentElementId - The ID of the parent element
|
|
151
|
+
* @param parentKey - The key of the parent object
|
|
152
|
+
* @param elementId - The element ID of the object to save
|
|
153
|
+
* @param objectToSave - The object data to save (as a JSON string)
|
|
154
|
+
* @param opts - Optional save options
|
|
155
|
+
*
|
|
156
|
+
* @returns Promise resolving to saved object, including any updates made to the object during the
|
|
157
|
+
* save operation (such as assigning an objKey if the object is new), or the assignment of
|
|
158
|
+
* calculated values
|
|
159
|
+
*/
|
|
160
|
+
async function saveRelatedObject(parentElementId, parentKey, elementId, objectToSave, opts) {
|
|
161
|
+
let url = `${exports.serviceAddress}/schema/sandboxes/${exports.sandboxKey}/${parentElementId}/${parentKey}/${elementId}`;
|
|
42
162
|
if (opts?.bypassValidation) {
|
|
43
163
|
url += "?bypassValidation=true";
|
|
44
164
|
}
|
|
45
|
-
console.log("Sending POST request to " + url + " with token " + authToken);
|
|
46
|
-
let response = await
|
|
47
|
-
headers: { "Authorization": `Bearer ${authToken}` },
|
|
165
|
+
console.log("Sending POST request to " + url + " with token " + exports.authToken);
|
|
166
|
+
let response = await axios_1.default.post(url, objectToSave, {
|
|
167
|
+
headers: { "Authorization": `Bearer ${exports.authToken}` },
|
|
48
168
|
});
|
|
49
169
|
return response.data;
|
|
50
170
|
}
|
|
51
|
-
|
|
52
|
-
*
|
|
53
|
-
*
|
|
171
|
+
/**
|
|
172
|
+
* saveRelatedObjectAsObservable saves a related object to the database. The objectToSave is saved,
|
|
173
|
+
* and its relationship to the parent object is established based on the relationship specified in
|
|
174
|
+
* the schema. The objectToSave must have a relationship to the parent object and the user must have
|
|
175
|
+
* scope access to the parent object.
|
|
176
|
+
*
|
|
177
|
+
* @param parentElementId - The ID of the parent element
|
|
178
|
+
* @param parentKey - The key of the parent object
|
|
179
|
+
* @param elementId - The element ID of the object to save
|
|
180
|
+
* @param objectToSave - The object data to save (as a JSON string)
|
|
181
|
+
* @param opts - Optional save options
|
|
182
|
+
*
|
|
183
|
+
* @returns Observable resolving to saved object, including any updates made to the object during
|
|
184
|
+
* the save operation (such as assigning an objKey if the object is new), or the assignment of
|
|
185
|
+
* calculated values
|
|
54
186
|
*/
|
|
55
|
-
|
|
187
|
+
function saveRelatedObjectAsObservable(parentElementId, parentKey, elementId, objectToSave, opts) {
|
|
188
|
+
return (0, rxjs_1.from)(saveRelatedObject(parentElementId, parentKey, elementId, objectToSave, opts));
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* sortObjectArray is a helper function that sorts the passed array in place by the given
|
|
192
|
+
* attributes. Sorting by nested attributes in the form of a delimited attribute string are
|
|
193
|
+
* supported (e.g., "attribute.nestedAttribute").
|
|
194
|
+
*
|
|
195
|
+
* @param array - The array to sort
|
|
196
|
+
* @param sort - Array of sort field specifications
|
|
197
|
+
* @returns The sorted array
|
|
198
|
+
*/
|
|
199
|
+
function sortObjectArray(array, sort) {
|
|
56
200
|
return array.sort((a, b) => {
|
|
57
201
|
let comparison = 0;
|
|
58
202
|
for (let s of sort) {
|
|
@@ -66,7 +210,19 @@ export function sortObjectArray(array, sort) {
|
|
|
66
210
|
return comparison;
|
|
67
211
|
});
|
|
68
212
|
}
|
|
69
|
-
|
|
213
|
+
/**
|
|
214
|
+
* compareValues is a helper function that compares two values for sorting purposes. If the values
|
|
215
|
+
* are strings, the comparison is case-insensitive. If the values are numbers, the comparison is
|
|
216
|
+
* performed numerically.
|
|
217
|
+
*
|
|
218
|
+
* @param valueA - First value to compare
|
|
219
|
+
* @param valueB - Second value to compare
|
|
220
|
+
* @param descending - Whether to sort in descending order
|
|
221
|
+
* @param caseInsensitive - Whether to perform case-insensitive comparison for strings
|
|
222
|
+
*
|
|
223
|
+
* @returns Comparison result (-1, 0, or 1)
|
|
224
|
+
*/
|
|
225
|
+
function compareValues(valueA, valueB, descending, caseInsensitive) {
|
|
70
226
|
if (caseInsensitive && (typeof valueA === 'string' || valueA instanceof String)) {
|
|
71
227
|
if (valueA && valueB) {
|
|
72
228
|
let comp = valueA.toLowerCase().localeCompare(valueB.toLowerCase());
|
|
@@ -95,7 +251,20 @@ export function compareValues(valueA, valueB, descending, caseInsensitive) {
|
|
|
95
251
|
}
|
|
96
252
|
return 0;
|
|
97
253
|
}
|
|
98
|
-
|
|
254
|
+
/**
|
|
255
|
+
* getValueFromObject is a helper function that extracts a value from an object using a dot-notation
|
|
256
|
+
* path. The path can include relationships. Relationship IDs may include a colon delimiter (e.g.,
|
|
257
|
+
* "accountMember:ownerAccountMemberKey") to specify the key of the related object. This is useful
|
|
258
|
+
* when an element has more than one relationship to the same object type. Otherwise, if only one
|
|
259
|
+
* relationship to the same object type exists, the key may be specified without the relationship ID
|
|
260
|
+
* (e.g., simply, "accountMember").
|
|
261
|
+
*
|
|
262
|
+
* @param object - The object to extract value from
|
|
263
|
+
* @param attribute - The attribute path (e.g., "user.address.city")
|
|
264
|
+
*
|
|
265
|
+
* @returns The extracted value
|
|
266
|
+
*/
|
|
267
|
+
function getValueFromObject(object, attribute) {
|
|
99
268
|
let components = attribute.split(".");
|
|
100
269
|
let value = object;
|
|
101
270
|
for (let component of components) {
|
|
@@ -116,17 +285,37 @@ export function getValueFromObject(object, attribute) {
|
|
|
116
285
|
}
|
|
117
286
|
return value;
|
|
118
287
|
}
|
|
119
|
-
|
|
120
|
-
|
|
288
|
+
/**
|
|
289
|
+
* prepareSuccessResponse prepares a success response in the appropriate format. The action handler
|
|
290
|
+
* should return an ActionResponse response when the action is successful. If useBody is true, the
|
|
291
|
+
* response will be returned as an object with the HTTP response code and the ActionResponse in the
|
|
292
|
+
* body field. If useBody is false, the ActionResponse will be returned directly.
|
|
293
|
+
*
|
|
294
|
+
* @param successResponse - The value to return
|
|
295
|
+
*
|
|
296
|
+
* @returns Formatted success response; an ActionResponse unless useBody is true
|
|
297
|
+
*/
|
|
298
|
+
function prepareSuccessResponse(successResponse) {
|
|
299
|
+
if (exports.useBody) {
|
|
121
300
|
return {
|
|
122
301
|
statusCode: 200,
|
|
123
|
-
body: JSON.stringify(
|
|
302
|
+
body: JSON.stringify(successResponse)
|
|
124
303
|
};
|
|
125
304
|
}
|
|
126
|
-
return
|
|
305
|
+
return successResponse;
|
|
127
306
|
}
|
|
128
|
-
|
|
129
|
-
|
|
307
|
+
/**
|
|
308
|
+
* prepareErrorResponse prepares an error response in the appropriate format. The action handler
|
|
309
|
+
* should return an ErrorResponse response when the action is not successful. If useBody is true,
|
|
310
|
+
* the response will be returned as an object with the HTTP response code and the ErrorResponse in
|
|
311
|
+
* the body field. If useBody is false, the ErrorResponse will be returned directly.
|
|
312
|
+
*
|
|
313
|
+
* @param errorMessage - The error message
|
|
314
|
+
*
|
|
315
|
+
* @returns Formatted error response; an ErrorResponse unless useBody is true
|
|
316
|
+
*/
|
|
317
|
+
function prepareErrorResponse(errorMessage) {
|
|
318
|
+
if (exports.useBody) {
|
|
130
319
|
return {
|
|
131
320
|
statusCode: 400,
|
|
132
321
|
body: JSON.stringify({ errorMessage })
|
|
@@ -134,11 +323,20 @@ export function prepareErrorResponse(errorMessage) {
|
|
|
134
323
|
}
|
|
135
324
|
return { errorMessage, responseType: "error" };
|
|
136
325
|
}
|
|
137
|
-
|
|
326
|
+
/**
|
|
327
|
+
* initialize initializes the SDK with event data. This should be called at the beginning of the
|
|
328
|
+
* action handler to set up the SDK with incoming information, including context information, input
|
|
329
|
+
* parameters, and authentication information needed to make API requests to the Halix service.
|
|
330
|
+
*
|
|
331
|
+
* @param event - The event object containing authentication and context information
|
|
332
|
+
*/
|
|
333
|
+
function initialize(event) {
|
|
138
334
|
let body = event;
|
|
139
335
|
if (event.body) {
|
|
140
336
|
body = event.body;
|
|
141
|
-
useBody = true;
|
|
337
|
+
exports.useBody = true;
|
|
338
|
+
}
|
|
339
|
+
if (body) {
|
|
340
|
+
({ authToken: exports.authToken, sandboxKey: exports.sandboxKey, serviceAddress: exports.serviceAddress, actionSubject: exports.actionSubject, userContext: exports.userContext, params: exports.params } = body);
|
|
142
341
|
}
|
|
143
|
-
({ authToken, sandboxKey, serviceAddress, actionSubject, userContext, params } = body);
|
|
144
342
|
}
|