@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/lib/esm/index.mjs CHANGED
@@ -1,6 +1,62 @@
1
- import axios from 'axios';
2
- export let authToken, sandboxKey, serviceAddress, actionSubject, userContext, params, useBody;
3
- export async function getRelatedObjects(parentElementId, parentKey, elementId, filter, fetchedRelationships) {
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 axios.get(url, {
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
- export async function getObject(dataElementId, key, fetchedRelationships) {
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 axios.get(url, {
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
- export async function saveRelatedObject(parentElementId, parentKey, elementId, objectToSave, opts) {
41
- let url = `${serviceAddress}/schema/sandboxes/${sandboxKey}/${parentElementId}/${parentKey}/${elementId}`;
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 axios.post(url, objectToSave, {
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
- * Sorts the passed array in place by the given attributes. Sorting by nested attributes in the form of a delimited
53
- * attribute string are supported (e.g., "attribute.nestedAttribute").
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
- export function sortObjectArray(array, sort) {
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
- export function compareValues(valueA, valueB, descending, caseInsensitive) {
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
- export function getValueFromObject(object, attribute) {
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
- export function prepareSuccessResponse(returnVal) {
120
- if (useBody) {
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(returnVal)
302
+ body: JSON.stringify(successResponse)
124
303
  };
125
304
  }
126
- return returnVal;
305
+ return successResponse;
127
306
  }
128
- export function prepareErrorResponse(errorMessage) {
129
- if (useBody) {
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
- export function initialize(event) {
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
  }