@oneblink/sdk-core 6.0.0-beta.1 → 6.0.0-beta.3

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.
@@ -31,7 +31,8 @@ export type ReplaceInjectablesOptions = ReplaceInjectablesBaseOptions & {
31
31
  previousApprovalId: string | undefined;
32
32
  };
33
33
  /**
34
- * Function to get the display value of a property in submission
34
+ * Function to get the display value of a property in submission, if elementId
35
+ * is provided propertyName will be ignored
35
36
  *
36
37
  * #### Example
37
38
  *
@@ -66,11 +67,15 @@ export type ReplaceInjectablesOptions = ReplaceInjectablesBaseOptions & {
66
67
  * @param options
67
68
  * @returns
68
69
  */
69
- export declare function getElementSubmissionValue({ propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }: {
70
- propertyName: string;
70
+ export declare function getElementSubmissionValue({ elementId, propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }: {
71
+ elementId?: string;
72
+ propertyName?: string;
71
73
  formElements: FormTypes.FormElement[];
72
74
  submission: SubmissionTypes.S3SubmissionData['submission'];
73
- } & ReplaceInjectablesFormatters): unknown;
75
+ } & ReplaceInjectablesFormatters): {
76
+ element: FormTypes.FormElement | undefined;
77
+ value: unknown;
78
+ } | undefined;
74
79
  /**
75
80
  * Replace the `{ELEMENT:<elementName>}` values in text while a form is being
76
81
  * filled out. The replacements are suppose to be user friendly and for display
@@ -80,38 +85,39 @@ export declare function getElementSubmissionValue({ propertyName, submission, fo
80
85
  * #### Example
81
86
  *
82
87
  * ```js
83
- * const result = submissionService.replaceInjectablesWithElementValues(
84
- * 'https://example.com/path?search{ELEMENT:search}',
85
- * {
86
- * formatDate: (value) => new Date(value).toDateString(),
87
- * formatDateTime: (value) => new Date(value).toString(),
88
- * formatTime: (value) => new Date(value).toTimeString(),
89
- * formatNumber: (value) => Number(value).toString(),
90
- * formatCurrency: (value) => Number(value).toFixed(2),
91
- * submission: {
92
- * search: 'Entered By User',
93
- * },
94
- * elements: [
95
- * {
96
- * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',
97
- * name: 'search',
98
- * type: 'text',
99
- * label: 'Search',
100
- * readOnly: false,
101
- * required: false,
102
- * conditionallyShow: false,
103
- * requiresAllConditionallyShowPredicates: false,
104
- * isElementLookup: false,
105
- * isDataLookup: false,
88
+ * const { text: url } =
89
+ * submissionService.replaceInjectablesWithElementValues(
90
+ * 'https://example.com/path?search{ELEMENT:search}',
91
+ * {
92
+ * formatDate: (value) => new Date(value).toDateString(),
93
+ * formatDateTime: (value) => new Date(value).toString(),
94
+ * formatTime: (value) => new Date(value).toTimeString(),
95
+ * formatNumber: (value) => Number(value).toString(),
96
+ * formatCurrency: (value) => Number(value).toFixed(2),
97
+ * submission: {
98
+ * search: 'Entered By User',
99
+ * },
100
+ * elements: [
101
+ * {
102
+ * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',
103
+ * name: 'search',
104
+ * type: 'text',
105
+ * label: 'Search',
106
+ * readOnly: false,
107
+ * required: false,
108
+ * conditionallyShow: false,
109
+ * requiresAllConditionallyShowPredicates: false,
110
+ * isElementLookup: false,
111
+ * isDataLookup: false,
112
+ * },
113
+ * ],
114
+ * userProfile: {
115
+ * userId: 'abc123',
116
+ * username: 'john-user',
117
+ * email: 'john.user@domain.com',
106
118
  * },
107
- * ],
108
- * userProfile: {
109
- * userId: 'abc123',
110
- * username: 'john-user',
111
- * email: 'john.user@domain.com',
112
119
  * },
113
- * },
114
- * )
120
+ * )
115
121
  * ```
116
122
  *
117
123
  * @param text
@@ -120,7 +126,20 @@ export declare function getElementSubmissionValue({ propertyName, submission, fo
120
126
  */
121
127
  export declare function replaceInjectablesWithElementValues(text: string, options: {
122
128
  formElements: FormTypes.FormElement[];
123
- } & ReplaceInjectablesBaseOptions): string;
129
+ } & ReplaceInjectablesBaseOptions): {
130
+ /**
131
+ * The text passed in with all injectables replaced with their corresponding
132
+ * values or empty strings.
133
+ */
134
+ text: string;
135
+ /**
136
+ * Determine if replaceable strings could all be replaced. The `text` property
137
+ * returned will replace all injectable with empty strings if the value cannot
138
+ * be found. Use this boolean to either use the replaced string with missing
139
+ * data or implement some other logic to handle missing injectables.
140
+ */
141
+ hadAllInjectablesReplaced: boolean;
142
+ };
124
143
  /**
125
144
  * Replace the `{ELEMENT:<elementName>}` values in text after a successful form
126
145
  * submission as well as other replaceable parameters e.g. `submissionId`. The
@@ -177,4 +196,17 @@ export declare function replaceInjectablesWithElementValues(text: string, option
177
196
  * @param options
178
197
  * @returns
179
198
  */
180
- export declare function replaceInjectablesWithSubmissionValues(text: string, options: ReplaceInjectablesOptions): string;
199
+ export declare function replaceInjectablesWithSubmissionValues(text: string, options: ReplaceInjectablesOptions): {
200
+ /**
201
+ * The text passed in with all injectables replaced with their corresponding
202
+ * values or empty strings.
203
+ */
204
+ text: string;
205
+ /**
206
+ * Determine if replaceable strings could all be replaced. The `text` property
207
+ * returned will replace all injectable with empty strings if the value cannot
208
+ * be found. Use this boolean to either use the replaced string with missing
209
+ * data or implement some other logic to handle missing injectables.
210
+ */
211
+ hadAllInjectablesReplaced: boolean;
212
+ };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.replaceInjectablesWithSubmissionValues = exports.replaceInjectablesWithElementValues = exports.getElementSubmissionValue = void 0;
4
- const formElementsService_1 = require("./formElementsService");
5
4
  const abnService_1 = require("./abnService");
6
5
  const form_elements_regex_1 = require("./form-elements-regex");
7
6
  const SUBMISSION_VALUES = [
@@ -25,52 +24,53 @@ const SUBMISSION_VALUES = [
25
24
  string: '{DATE}',
26
25
  value: ({ submissionTimestamp, formatDateTime, }) => {
27
26
  if (!submissionTimestamp) {
28
- return '';
27
+ return undefined;
29
28
  }
30
29
  return formatDateTime(submissionTimestamp);
31
30
  },
32
31
  },
33
32
  {
34
33
  string: '{TIMESTAMP}',
35
- value: ({ submissionTimestamp }) => submissionTimestamp || '',
34
+ value: ({ submissionTimestamp }) => submissionTimestamp,
36
35
  },
37
36
  {
38
37
  string: '{SUBMISSION_ID}',
39
- value: ({ submissionId }) => submissionId || '',
38
+ value: ({ submissionId }) => submissionId,
40
39
  },
41
40
  {
42
41
  string: '{EXTERNAL_ID}',
43
- value: ({ externalId }) => externalId || '',
42
+ value: ({ externalId }) => externalId,
44
43
  },
45
44
  {
46
45
  string: '{PREVIOUS_APPROVAL_ID}',
47
- value: ({ previousApprovalId }) => previousApprovalId || '',
46
+ value: ({ previousApprovalId }) => previousApprovalId,
48
47
  },
49
48
  ];
50
49
  const ELEMENT_VALUES = [
51
50
  {
52
51
  string: '{USER:email}',
53
- value: ({ userProfile }) => (userProfile === null || userProfile === void 0 ? void 0 : userProfile.email) || '',
52
+ value: ({ userProfile }) => userProfile === null || userProfile === void 0 ? void 0 : userProfile.email,
54
53
  },
55
54
  {
56
55
  string: '{USER:username}',
57
- value: ({ userProfile }) => (userProfile === null || userProfile === void 0 ? void 0 : userProfile.username) || '',
56
+ value: ({ userProfile }) => userProfile === null || userProfile === void 0 ? void 0 : userProfile.username,
58
57
  },
59
58
  {
60
59
  string: '{TASK_NAME}',
61
- value: ({ task }) => (task === null || task === void 0 ? void 0 : task.name) || '',
60
+ value: ({ task }) => task === null || task === void 0 ? void 0 : task.name,
62
61
  },
63
62
  {
64
63
  string: '{TASK_GROUP_NAME}',
65
- value: ({ taskGroup }) => (taskGroup === null || taskGroup === void 0 ? void 0 : taskGroup.name) || '',
64
+ value: ({ taskGroup }) => taskGroup === null || taskGroup === void 0 ? void 0 : taskGroup.name,
66
65
  },
67
66
  {
68
67
  string: '{TASK_GROUP_INSTANCE_LABEL}',
69
- value: ({ taskGroupInstance }) => (taskGroupInstance === null || taskGroupInstance === void 0 ? void 0 : taskGroupInstance.label) || '',
68
+ value: ({ taskGroupInstance }) => taskGroupInstance === null || taskGroupInstance === void 0 ? void 0 : taskGroupInstance.label,
70
69
  },
71
70
  ];
72
71
  /**
73
- * Function to get the display value of a property in submission
72
+ * Function to get the display value of a property in submission, if elementId
73
+ * is provided propertyName will be ignored
74
74
  *
75
75
  * #### Example
76
76
  *
@@ -105,74 +105,124 @@ const ELEMENT_VALUES = [
105
105
  * @param options
106
106
  * @returns
107
107
  */
108
- function getElementSubmissionValue({ propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }) {
108
+ function getElementSubmissionValue({ elementId, propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }) {
109
109
  var _a, _b, _c, _d, _e;
110
- const formElement = (0, formElementsService_1.findFormElement)(formElements, (element) => element.type !== 'page' &&
111
- element.type !== 'section' &&
112
- element.name === propertyName);
113
- const unknown = submission[propertyName];
110
+ if (elementId === undefined && propertyName === undefined) {
111
+ return undefined;
112
+ }
113
+ // make sure submission is an object
114
+ if (Object(submission) !== submission) {
115
+ return undefined;
116
+ }
117
+ // initialise if propertyName provided and not elementId
118
+ let unknown = elementId ? undefined : submission[propertyName !== null && propertyName !== void 0 ? propertyName : ''];
119
+ let formElement = undefined;
120
+ const matchFn = (element) => {
121
+ if (elementId) {
122
+ return elementId === element.id;
123
+ }
124
+ return 'name' in element && element.name === propertyName;
125
+ };
126
+ for (const element of formElements) {
127
+ if (matchFn(element)) {
128
+ if ('name' in element) {
129
+ unknown = submission[element.name];
130
+ formElement = element;
131
+ break;
132
+ }
133
+ }
134
+ if ('elements' in element) {
135
+ const newSubmissionData = 'name' in element ? submission[element.name] : submission;
136
+ if (Array.isArray(newSubmissionData) || !element.elements) {
137
+ continue;
138
+ }
139
+ const result = getElementSubmissionValue({
140
+ elementId,
141
+ formElements: element.elements,
142
+ submission: newSubmissionData,
143
+ formatDate,
144
+ formatDateTime,
145
+ formatTime,
146
+ formatNumber,
147
+ formatCurrency,
148
+ });
149
+ if (result) {
150
+ unknown = result.value;
151
+ formElement = result.element;
152
+ }
153
+ }
154
+ }
114
155
  if (unknown === undefined || unknown === null) {
115
156
  return undefined;
116
157
  }
117
158
  switch (formElement === null || formElement === void 0 ? void 0 : formElement.type) {
118
159
  case 'datetime': {
119
160
  const value = unknown;
120
- return formatDateTime(value);
161
+ return { element: formElement, value: formatDateTime(value) };
121
162
  }
122
163
  case 'date': {
123
164
  const value = unknown;
124
- return formatDate(value);
165
+ return { element: formElement, value: formatDate(value) };
125
166
  }
126
167
  case 'time': {
127
168
  const value = unknown;
128
- return formatTime(value);
169
+ return { element: formElement, value: formatTime(value) };
129
170
  }
130
171
  case 'radio':
131
172
  case 'autocomplete': {
132
173
  const value = unknown;
133
174
  const option = (_a = formElement.options) === null || _a === void 0 ? void 0 : _a.find((opt) => opt.value === value);
134
- return (option === null || option === void 0 ? void 0 : option.label) || value;
175
+ return { element: formElement, value: (option === null || option === void 0 ? void 0 : option.label) || value };
135
176
  }
136
177
  case 'checkboxes': {
137
178
  const value = unknown;
179
+ const options = formElement.options;
138
180
  const selectedOptionLabels = value.reduce((labels, selectedOption) => {
139
- var _a;
140
- const foundOption = (_a = formElement.options) === null || _a === void 0 ? void 0 : _a.find((o) => o.value === selectedOption);
181
+ const foundOption = options === null || options === void 0 ? void 0 : options.find((o) => o.value === selectedOption);
141
182
  if (foundOption)
142
183
  labels.push(foundOption.label);
143
184
  return labels;
144
185
  }, []);
145
- return selectedOptionLabels.length ? selectedOptionLabels : undefined;
186
+ return {
187
+ element: formElement,
188
+ value: selectedOptionLabels.length ? selectedOptionLabels : undefined,
189
+ };
146
190
  }
147
191
  case 'compliance': {
148
192
  const value = unknown;
149
193
  const option = (formElement.options || []).find((option) => option.value === value.value);
150
194
  return {
151
- ...value,
152
- value: (option === null || option === void 0 ? void 0 : option.label) || value.value,
195
+ element: formElement,
196
+ value: {
197
+ ...value,
198
+ value: (option === null || option === void 0 ? void 0 : option.label) || value.value,
199
+ },
153
200
  };
154
201
  }
155
202
  case 'select': {
156
203
  if (formElement.multi) {
157
204
  const value = unknown;
205
+ const options = formElement.options;
158
206
  const selectedOptionLabels = value.reduce((labels, selectedOption) => {
159
- var _a;
160
- const foundOption = (_a = formElement.options) === null || _a === void 0 ? void 0 : _a.find((o) => o.value === selectedOption);
207
+ const foundOption = options === null || options === void 0 ? void 0 : options.find((o) => o.value === selectedOption);
161
208
  if (foundOption)
162
209
  labels.push(foundOption.label);
163
210
  return labels;
164
211
  }, []);
165
- return selectedOptionLabels.length ? selectedOptionLabels : undefined;
212
+ return {
213
+ element: formElement,
214
+ value: selectedOptionLabels.length ? selectedOptionLabels : undefined,
215
+ };
166
216
  }
167
217
  else {
168
218
  const value = unknown;
169
219
  const option = (_b = formElement.options) === null || _b === void 0 ? void 0 : _b.find((opt) => opt.value === value);
170
- return (option === null || option === void 0 ? void 0 : option.label) || '';
220
+ return { element: formElement, value: option === null || option === void 0 ? void 0 : option.label };
171
221
  }
172
222
  }
173
223
  case 'boolean': {
174
224
  const value = unknown;
175
- return value ? 'Yes' : 'No';
225
+ return { element: formElement, value: value ? 'Yes' : 'No' };
176
226
  }
177
227
  case 'calculation': {
178
228
  const value = unknown;
@@ -184,35 +234,47 @@ function getElementSubmissionValue({ propertyName, submission, formElements, for
184
234
  else {
185
235
  text = formatNumber(value);
186
236
  }
187
- return text;
237
+ return { element: formElement, value: text };
188
238
  }
189
239
  return undefined;
190
240
  }
191
241
  case 'pointAddress':
192
242
  case 'geoscapeAddress': {
193
243
  const value = unknown;
194
- return ((_c = value === null || value === void 0 ? void 0 : value.addressDetails) === null || _c === void 0 ? void 0 : _c.formattedAddress) || (value === null || value === void 0 ? void 0 : value.addressId);
244
+ return {
245
+ element: formElement,
246
+ value: ((_c = value === null || value === void 0 ? void 0 : value.addressDetails) === null || _c === void 0 ? void 0 : _c.formattedAddress) || (value === null || value === void 0 ? void 0 : value.addressId),
247
+ };
195
248
  }
196
249
  case 'civicaStreetName': {
197
250
  const value = unknown;
198
- return value === null || value === void 0 ? void 0 : value.formattedStreet;
251
+ return { element: formElement, value: value === null || value === void 0 ? void 0 : value.formattedStreet };
199
252
  }
200
253
  case 'civicaNameRecord': {
201
254
  const value = unknown;
202
- return ([value === null || value === void 0 ? void 0 : value.title, value === null || value === void 0 ? void 0 : value.givenName1, value === null || value === void 0 ? void 0 : value.familyName]
203
- .filter((t) => t)
204
- .join(' ') || (value === null || value === void 0 ? void 0 : value.emailAddress));
255
+ return {
256
+ element: formElement,
257
+ value: [value === null || value === void 0 ? void 0 : value.title, value === null || value === void 0 ? void 0 : value.givenName1, value === null || value === void 0 ? void 0 : value.familyName]
258
+ .filter((t) => t)
259
+ .join(' ') || (value === null || value === void 0 ? void 0 : value.emailAddress),
260
+ };
205
261
  }
206
262
  case 'abn': {
207
263
  const value = unknown;
208
- return value ? (0, abnService_1.getABNNumberFromABNRecord)(value) : undefined;
264
+ return {
265
+ element: formElement,
266
+ value: value ? (0, abnService_1.getABNNumberFromABNRecord)(value) : undefined,
267
+ };
209
268
  }
210
269
  case 'apiNSWLiquorLicence': {
211
270
  const value = unknown;
212
- return `${(_d = value === null || value === void 0 ? void 0 : value.licenceDetail) === null || _d === void 0 ? void 0 : _d.licenceNumber} | ${(_e = value === null || value === void 0 ? void 0 : value.licenceDetail) === null || _e === void 0 ? void 0 : _e.licenceName}`.trim();
271
+ return {
272
+ element: formElement,
273
+ value: `${(_d = value === null || value === void 0 ? void 0 : value.licenceDetail) === null || _d === void 0 ? void 0 : _d.licenceNumber} | ${(_e = value === null || value === void 0 ? void 0 : value.licenceDetail) === null || _e === void 0 ? void 0 : _e.licenceName}`.trim(),
274
+ };
213
275
  }
214
276
  default: {
215
- return unknown;
277
+ return { element: formElement, value: unknown };
216
278
  }
217
279
  }
218
280
  }
@@ -226,38 +288,39 @@ exports.getElementSubmissionValue = getElementSubmissionValue;
226
288
  * #### Example
227
289
  *
228
290
  * ```js
229
- * const result = submissionService.replaceInjectablesWithElementValues(
230
- * 'https://example.com/path?search{ELEMENT:search}',
231
- * {
232
- * formatDate: (value) => new Date(value).toDateString(),
233
- * formatDateTime: (value) => new Date(value).toString(),
234
- * formatTime: (value) => new Date(value).toTimeString(),
235
- * formatNumber: (value) => Number(value).toString(),
236
- * formatCurrency: (value) => Number(value).toFixed(2),
237
- * submission: {
238
- * search: 'Entered By User',
239
- * },
240
- * elements: [
241
- * {
242
- * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',
243
- * name: 'search',
244
- * type: 'text',
245
- * label: 'Search',
246
- * readOnly: false,
247
- * required: false,
248
- * conditionallyShow: false,
249
- * requiresAllConditionallyShowPredicates: false,
250
- * isElementLookup: false,
251
- * isDataLookup: false,
291
+ * const { text: url } =
292
+ * submissionService.replaceInjectablesWithElementValues(
293
+ * 'https://example.com/path?search{ELEMENT:search}',
294
+ * {
295
+ * formatDate: (value) => new Date(value).toDateString(),
296
+ * formatDateTime: (value) => new Date(value).toString(),
297
+ * formatTime: (value) => new Date(value).toTimeString(),
298
+ * formatNumber: (value) => Number(value).toString(),
299
+ * formatCurrency: (value) => Number(value).toFixed(2),
300
+ * submission: {
301
+ * search: 'Entered By User',
302
+ * },
303
+ * elements: [
304
+ * {
305
+ * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',
306
+ * name: 'search',
307
+ * type: 'text',
308
+ * label: 'Search',
309
+ * readOnly: false,
310
+ * required: false,
311
+ * conditionallyShow: false,
312
+ * requiresAllConditionallyShowPredicates: false,
313
+ * isElementLookup: false,
314
+ * isDataLookup: false,
315
+ * },
316
+ * ],
317
+ * userProfile: {
318
+ * userId: 'abc123',
319
+ * username: 'john-user',
320
+ * email: 'john.user@domain.com',
252
321
  * },
253
- * ],
254
- * userProfile: {
255
- * userId: 'abc123',
256
- * username: 'john-user',
257
- * email: 'john.user@domain.com',
258
322
  * },
259
- * },
260
- * )
323
+ * )
261
324
  * ```
262
325
  *
263
326
  * @param text
@@ -265,24 +328,38 @@ exports.getElementSubmissionValue = getElementSubmissionValue;
265
328
  * @returns
266
329
  */
267
330
  function replaceInjectablesWithElementValues(text, options) {
331
+ let hadAllInjectablesReplaced = true;
268
332
  text = ELEMENT_VALUES.reduce((newString, customValue) => {
269
- return newString.replaceAll(customValue.string, customValue.value(options));
333
+ if (!newString.includes(customValue.string)) {
334
+ return newString;
335
+ }
336
+ const replacedValue = customValue.value(options);
337
+ if (!replacedValue) {
338
+ hadAllInjectablesReplaced = false;
339
+ }
340
+ return newString.replaceAll(customValue.string, replacedValue || '');
270
341
  }, text);
271
342
  const matchesElement = text.match(options.excludeNestedElements ? form_elements_regex_1.RootElementRegex : form_elements_regex_1.NestedElementRegex);
272
- if (!matchesElement) {
273
- return text;
343
+ if (matchesElement) {
344
+ (0, form_elements_regex_1.matchElementsTagRegex)({
345
+ text,
346
+ excludeNestedElements: !!options.excludeNestedElements,
347
+ }, ({ elementName, elementMatch }) => {
348
+ const result = getElementSubmissionValue({
349
+ propertyName: elementName,
350
+ ...options,
351
+ });
352
+ const hasNoValue = result === undefined || result.value === undefined;
353
+ if (hasNoValue) {
354
+ hadAllInjectablesReplaced = false;
355
+ }
356
+ text = text.replace(elementMatch, hasNoValue ? '' : result.value);
357
+ });
274
358
  }
275
- (0, form_elements_regex_1.matchElementsTagRegex)({
359
+ return {
276
360
  text,
277
- excludeNestedElements: !!options.excludeNestedElements,
278
- }, ({ elementName, elementMatch }) => {
279
- const value = getElementSubmissionValue({
280
- propertyName: elementName,
281
- ...options,
282
- });
283
- text = text.replace(elementMatch, value === undefined ? '' : value);
284
- });
285
- return text;
361
+ hadAllInjectablesReplaced,
362
+ };
286
363
  }
287
364
  exports.replaceInjectablesWithElementValues = replaceInjectablesWithElementValues;
288
365
  /**
@@ -342,13 +419,25 @@ exports.replaceInjectablesWithElementValues = replaceInjectablesWithElementValue
342
419
  * @returns
343
420
  */
344
421
  function replaceInjectablesWithSubmissionValues(text, options) {
345
- const string = replaceInjectablesWithElementValues(text, {
422
+ const result = replaceInjectablesWithElementValues(text, {
346
423
  formElements: options.form.elements,
347
424
  ...options,
348
425
  });
349
- return SUBMISSION_VALUES.reduce((newString, customValue) => {
350
- return newString.replaceAll(customValue.string, customValue.value(options));
351
- }, string);
426
+ let hadAllInjectablesReplaced = result.hadAllInjectablesReplaced;
427
+ const replacedText = SUBMISSION_VALUES.reduce((newString, customValue) => {
428
+ if (!newString.includes(customValue.string)) {
429
+ return newString;
430
+ }
431
+ const replacedValue = customValue.value(options);
432
+ if (!replacedValue) {
433
+ hadAllInjectablesReplaced = false;
434
+ }
435
+ return newString.replaceAll(customValue.string, replacedValue || '');
436
+ }, result.text);
437
+ return {
438
+ text: replacedText,
439
+ hadAllInjectablesReplaced,
440
+ };
352
441
  }
353
442
  exports.replaceInjectablesWithSubmissionValues = replaceInjectablesWithSubmissionValues;
354
443
  //# sourceMappingURL=replaceCustomValues.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"replaceCustomValues.js","sourceRoot":"","sources":["../src/replaceCustomValues.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n APINSWTypes,\n CivicaTypes,\n FormTypes,\n GeoscapeTypes,\n MiscTypes,\n PointTypes,\n ScheduledTasksTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { findFormElement } from './formElementsService'\nimport { getABNNumberFromABNRecord } from './abnService'\nimport {\n RootElementRegex,\n NestedElementRegex,\n matchElementsTagRegex,\n} from './form-elements-regex'\n\nexport type ReplaceInjectablesFormatters = {\n formatDateTime: (value: string) => string\n formatDate: (value: string) => string\n formatTime: (value: string) => string\n formatNumber: (value: number) => string\n formatCurrency: (value: number) => string\n}\n\nexport type ReplaceInjectablesBaseOptions = ReplaceInjectablesFormatters & {\n submission: SubmissionTypes.S3SubmissionData['submission']\n userProfile: MiscTypes.UserProfile | undefined\n task: ScheduledTasksTypes.Task | undefined\n taskGroup: ScheduledTasksTypes.TaskGroup | undefined\n taskGroupInstance: ScheduledTasksTypes.TaskGroupInstance | undefined\n /**\n * Determine if only root level elements should be replaced.\n *\n * `false` will replace `\"{ELEMENT:Parent_Name}\"` and\n * `\"{ELEMENT:Children|Name}\"`.\n *\n * `true` will replace `\"{ELEMENT:Parent_Name}\"` but will NOT replace\n * `{ELEMENT:Children|Name}`.\n */\n excludeNestedElements?: boolean\n}\n\nexport type ReplaceInjectablesOptions = ReplaceInjectablesBaseOptions & {\n form: FormTypes.Form\n submissionId: string\n submissionTimestamp: string\n externalId: string | undefined\n previousApprovalId: string | undefined\n}\n\nconst SUBMISSION_VALUES = [\n {\n string: '{INFO_PAGE_ID}',\n value: ({ form }: ReplaceInjectablesOptions) => form.id.toString(),\n },\n {\n string: '{INFO_PAGE_NAME}',\n value: ({ form }: ReplaceInjectablesOptions) => form.name,\n },\n {\n string: '{FORM_ID}',\n value: ({ form }: ReplaceInjectablesOptions) => form.id.toString(),\n },\n {\n string: '{FORM_NAME}',\n value: ({ form }: ReplaceInjectablesOptions) => form.name,\n },\n {\n string: '{DATE}',\n value: ({\n submissionTimestamp,\n formatDateTime,\n }: ReplaceInjectablesOptions) => {\n if (!submissionTimestamp) {\n return ''\n }\n return formatDateTime(submissionTimestamp)\n },\n },\n {\n string: '{TIMESTAMP}',\n value: ({ submissionTimestamp }: ReplaceInjectablesOptions) =>\n submissionTimestamp || '',\n },\n {\n string: '{SUBMISSION_ID}',\n value: ({ submissionId }: ReplaceInjectablesOptions) => submissionId || '',\n },\n {\n string: '{EXTERNAL_ID}',\n value: ({ externalId }: ReplaceInjectablesOptions) => externalId || '',\n },\n {\n string: '{PREVIOUS_APPROVAL_ID}',\n value: ({ previousApprovalId }: ReplaceInjectablesOptions) =>\n previousApprovalId || '',\n },\n]\n\nconst ELEMENT_VALUES: Array<{\n string: string\n value: (options: ReplaceInjectablesBaseOptions) => string\n}> = [\n {\n string: '{USER:email}',\n value: ({ userProfile }) => userProfile?.email || '',\n },\n {\n string: '{USER:username}',\n value: ({ userProfile }) => userProfile?.username || '',\n },\n {\n string: '{TASK_NAME}',\n value: ({ task }) => task?.name || '',\n },\n {\n string: '{TASK_GROUP_NAME}',\n value: ({ taskGroup }) => taskGroup?.name || '',\n },\n {\n string: '{TASK_GROUP_INSTANCE_LABEL}',\n value: ({ taskGroupInstance }) => taskGroupInstance?.label || '',\n },\n]\n\n/**\n * Function to get the display value of a property in submission\n *\n * #### Example\n *\n * ```typescript\n * const result = submissionService.getElementSubmissionValue({\n * propertyName: 'search',\n * submission: {\n * search: 'Entered By User',\n * },\n * formElements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * formatNumber: (value) => Number(value).toString(),\n * formatCurrency: (value) => Number(value).toFixed(2),\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function getElementSubmissionValue({\n propertyName,\n submission,\n formElements,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n propertyName: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n} & ReplaceInjectablesFormatters): unknown {\n const formElement = findFormElement(\n formElements,\n (element) =>\n element.type !== 'page' &&\n element.type !== 'section' &&\n element.name === propertyName,\n )\n\n const unknown = submission[propertyName]\n if (unknown === undefined || unknown === null) {\n return undefined\n }\n\n switch (formElement?.type) {\n case 'datetime': {\n const value = unknown as string\n return formatDateTime(value)\n }\n case 'date': {\n const value = unknown as string\n return formatDate(value)\n }\n case 'time': {\n const value = unknown as string\n return formatTime(value)\n }\n case 'radio':\n case 'autocomplete': {\n const value = unknown as string\n const option = formElement.options?.find((opt) => opt.value === value)\n return option?.label || value\n }\n\n case 'checkboxes': {\n const value = unknown as string[]\n const selectedOptionLabels: string[] = value.reduce(\n (labels: string[], selectedOption: string) => {\n const foundOption = formElement.options?.find(\n (o) => o.value === selectedOption,\n )\n if (foundOption) labels.push(foundOption.label)\n return labels\n },\n [],\n )\n return selectedOptionLabels.length ? selectedOptionLabels : undefined\n }\n case 'compliance': {\n const value = unknown as {\n value?: string\n }\n const option = (formElement.options || []).find(\n (option: FormTypes.ChoiceElementOption) => option.value === value.value,\n )\n return {\n ...value,\n value: option?.label || value.value,\n }\n }\n case 'select': {\n if (formElement.multi) {\n const value = unknown as string[]\n const selectedOptionLabels: string[] = value.reduce(\n (labels: string[], selectedOption: string) => {\n const foundOption = formElement.options?.find(\n (o) => o.value === selectedOption,\n )\n if (foundOption) labels.push(foundOption.label)\n return labels\n },\n [],\n )\n return selectedOptionLabels.length ? selectedOptionLabels : undefined\n } else {\n const value = unknown as string\n const option = formElement.options?.find((opt) => opt.value === value)\n return option?.label || ''\n }\n }\n case 'boolean': {\n const value = unknown as boolean\n return value ? 'Yes' : 'No'\n }\n case 'calculation': {\n const value = unknown as number\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n let text\n if (formElement.displayAsCurrency) {\n text = formatCurrency(value)\n } else {\n text = formatNumber(value)\n }\n return text\n }\n return undefined\n }\n case 'pointAddress':\n case 'geoscapeAddress': {\n const value = unknown as\n | PointTypes.PointAddress\n | GeoscapeTypes.GeoscapeAddress\n return value?.addressDetails?.formattedAddress || value?.addressId\n }\n case 'civicaStreetName': {\n const value = unknown as CivicaTypes.CivicaStreetName\n return value?.formattedStreet\n }\n case 'civicaNameRecord': {\n const value = unknown as CivicaTypes.CivicaNameRecord\n return (\n [value?.title, value?.givenName1, value?.familyName]\n .filter((t) => t)\n .join(' ') || value?.emailAddress\n )\n }\n case 'abn': {\n const value = unknown as MiscTypes.ABNRecord\n return value ? getABNNumberFromABNRecord(value) : undefined\n }\n case 'apiNSWLiquorLicence': {\n const value = unknown as APINSWTypes.LiquorLicenceDetails | undefined\n return `${value?.licenceDetail?.licenceNumber} | ${value?.licenceDetail?.licenceName}`.trim()\n }\n default: {\n return unknown\n }\n }\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text while a form is being\n * filled out. The replacements are suppose to be user friendly and for display\n * purposes, e.g. dates should be displayed in the user's desired format and\n * timezone.\n *\n * #### Example\n *\n * ```js\n * const result = submissionService.replaceInjectablesWithElementValues(\n * 'https://example.com/path?search{ELEMENT:search}',\n * {\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * formatNumber: (value) => Number(value).toString(),\n * formatCurrency: (value) => Number(value).toFixed(2),\n * submission: {\n * search: 'Entered By User',\n * },\n * elements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * userProfile: {\n * userId: 'abc123',\n * username: 'john-user',\n * email: 'john.user@domain.com',\n * },\n * },\n * )\n * ```\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithElementValues(\n text: string,\n options: {\n formElements: FormTypes.FormElement[]\n } & ReplaceInjectablesBaseOptions,\n): string {\n text = ELEMENT_VALUES.reduce((newString, customValue) => {\n return newString.replaceAll(customValue.string, customValue.value(options))\n }, text)\n\n const matchesElement = text.match(\n options.excludeNestedElements ? RootElementRegex : NestedElementRegex,\n )\n if (!matchesElement) {\n return text\n }\n\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: !!options.excludeNestedElements,\n },\n ({ elementName, elementMatch }) => {\n const value = getElementSubmissionValue({\n propertyName: elementName,\n ...options,\n })\n\n text = text.replace(\n elementMatch,\n value === undefined ? '' : (value as string),\n )\n },\n )\n\n return text\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text after a successful form\n * submission as well as other replaceable parameters e.g. `submissionId`. The\n * replacements are suppose to be user friendly and for display purposes, e.g.\n * dates should be displayed in the user's desired format and timezone.\n *\n * #### Example\n *\n * ```js\n * const result = submissionService.replaceInjectablesWithSubmissionValues(\n * 'https://example.com/path?submissionId={SUBMISSION_ID}&externalId={EXTERNAL_ID}&search{ELEMENT:search}',\n * {\n * submissionId: 'abc-123',\n * submissionTimestamp: '2021-07-02T02:19:13.670Z',\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * submission: {\n * search: 'Entered By User',\n * },\n * form: {\n * id: 1,\n * name: 'Form',\n * organisationId: '',\n * formsAppEnvironmentId: 1,\n * formsAppIds: [],\n * isAuthenticated: false,\n * isMultiPage: false,\n * isInfoPage: false,\n * postSubmissionAction: 'FORMS_LIBRARY',\n * cancelAction: 'FORMS_LIBRARY',\n * submissionEvents: [],\n * tags: [],\n * elements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * },\n * },\n * )\n * ```\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithSubmissionValues(\n text: string,\n options: ReplaceInjectablesOptions,\n): string {\n const string = replaceInjectablesWithElementValues(text, {\n formElements: options.form.elements,\n ...options,\n })\n return SUBMISSION_VALUES.reduce((newString, customValue) => {\n return newString.replaceAll(customValue.string, customValue.value(options))\n }, string)\n}\n"]}
1
+ {"version":3,"file":"replaceCustomValues.js","sourceRoot":"","sources":["../src/replaceCustomValues.ts"],"names":[],"mappings":";;;AAUA,6CAAwD;AACxD,+DAI8B;AAoC9B,MAAM,iBAAiB,GAGlB;IACH;QACE,MAAM,EAAE,gBAAgB;QACxB,KAAK,EAAE,CAAC,EAAE,IAAI,EAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE;KACnE;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,KAAK,EAAE,CAAC,EAAE,IAAI,EAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI;KAC1D;IACD;QACE,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,CAAC,EAAE,IAAI,EAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE;KACnE;IACD;QACE,MAAM,EAAE,aAAa;QACrB,KAAK,EAAE,CAAC,EAAE,IAAI,EAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI;KAC1D;IACD;QACE,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,CAAC,EACN,mBAAmB,EACnB,cAAc,GACY,EAAE,EAAE;YAC9B,IAAI,CAAC,mBAAmB,EAAE;gBACxB,OAAO,SAAS,CAAA;aACjB;YACD,OAAO,cAAc,CAAC,mBAAmB,CAAC,CAAA;QAC5C,CAAC;KACF;IACD;QACE,MAAM,EAAE,aAAa;QACrB,KAAK,EAAE,CAAC,EAAE,mBAAmB,EAA6B,EAAE,EAAE,CAC5D,mBAAmB;KACtB;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,CAAC,EAAE,YAAY,EAA6B,EAAE,EAAE,CAAC,YAAY;KACrE;IACD;QACE,MAAM,EAAE,eAAe;QACvB,KAAK,EAAE,CAAC,EAAE,UAAU,EAA6B,EAAE,EAAE,CAAC,UAAU;KACjE;IACD;QACE,MAAM,EAAE,wBAAwB;QAChC,KAAK,EAAE,CAAC,EAAE,kBAAkB,EAA6B,EAAE,EAAE,CAC3D,kBAAkB;KACrB;CACF,CAAA;AAED,MAAM,cAAc,GAGf;IACH;QACE,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK;KAC/C;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ;KAClD;IACD;QACE,MAAM,EAAE,aAAa;QACrB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI;KAChC;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI;KAC1C;IACD;QACE,MAAM,EAAE,6BAA6B;QACrC,KAAK,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,KAAK;KAC3D;CACF,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,SAAgB,yBAAyB,CAAC,EACxC,SAAS,EACT,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,GAMgB;;IAM9B,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE;QACzD,OAAO,SAAS,CAAA;KACjB;IAED,oCAAoC;IACpC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,UAAU,EAAE;QACrC,OAAO,SAAS,CAAA;KACjB;IAED,wDAAwD;IACxD,IAAI,OAAO,GAAY,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,CAAC,CAAA;IAC7E,IAAI,WAAW,GAAsC,SAAS,CAAA;IAE9D,MAAM,OAAO,GAAG,CAAC,OAA8B,EAAE,EAAE;QACjD,IAAI,SAAS,EAAE;YACb,OAAO,SAAS,KAAK,OAAO,CAAC,EAAE,CAAA;SAChC;QACD,OAAO,MAAM,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CAAA;IAC3D,CAAC,CAAA;IAED,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE;QAClC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YACpB,IAAI,MAAM,IAAI,OAAO,EAAE;gBACrB,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAClC,WAAW,GAAG,OAAO,CAAA;gBACrB,MAAK;aACN;SACF;QACD,IAAI,UAAU,IAAI,OAAO,EAAE;YACzB,MAAM,iBAAiB,GACrB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;YAE3D,IAAI,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzD,SAAQ;aACT;YAED,MAAM,MAAM,GAAG,yBAAyB,CAAC;gBACvC,SAAS;gBACT,YAAY,EAAE,OAAO,CAAC,QAAQ;gBAC9B,UAAU,EACR,iBAAmE;gBACrE,UAAU;gBACV,cAAc;gBACd,UAAU;gBACV,YAAY;gBACZ,cAAc;aACf,CAAC,CAAA;YACF,IAAI,MAAM,EAAE;gBACV,OAAO,GAAG,MAAM,CAAC,KAAK,CAAA;gBACtB,WAAW,GAAG,MAAM,CAAC,OAAO,CAAA;aAC7B;SACF;KACF;IAED,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE;QAC7C,OAAO,SAAS,CAAA;KACjB;IAED,QAAQ,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,EAAE;QACzB,KAAK,UAAU,CAAC,CAAC;YACf,MAAM,KAAK,GAAG,OAAiB,CAAA;YAC/B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAA;SAC9D;QACD,KAAK,MAAM,CAAC,CAAC;YACX,MAAM,KAAK,GAAG,OAAiB,CAAA;YAC/B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAA;SAC1D;QACD,KAAK,MAAM,CAAC,CAAC;YACX,MAAM,KAAK,GAAG,OAAiB,CAAA;YAC/B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAA;SAC1D;QACD,KAAK,OAAO,CAAC;QACb,KAAK,cAAc,CAAC,CAAC;YACnB,MAAM,KAAK,GAAG,OAAiB,CAAA;YAC/B,MAAM,MAAM,GAAG,MAAA,WAAW,CAAC,OAAO,0CAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;YACtE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,KAAK,EAAE,CAAA;SAC/D;QAED,KAAK,YAAY,CAAC,CAAC;YACjB,MAAM,KAAK,GAAG,OAAmB,CAAA;YACjC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAA;YACnC,MAAM,oBAAoB,GAAa,KAAK,CAAC,MAAM,CACjD,CAAC,MAAgB,EAAE,cAAsB,EAAE,EAAE;gBAC3C,MAAM,WAAW,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAA;gBACpE,IAAI,WAAW;oBAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;gBAC/C,OAAO,MAAM,CAAA;YACf,CAAC,EACD,EAAE,CACH,CAAA;YACD,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS;aACtE,CAAA;SACF;QACD,KAAK,YAAY,CAAC,CAAC;YACjB,MAAM,KAAK,GAAG,OAEb,CAAA;YACD,MAAM,MAAM,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7C,CAAC,MAAqC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CACxE,CAAA;YACD,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE;oBACL,GAAG,KAAK;oBACR,KAAK,EAAE,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,KAAI,KAAK,CAAC,KAAK;iBACpC;aACF,CAAA;SACF;QACD,KAAK,QAAQ,CAAC,CAAC;YACb,IAAI,WAAW,CAAC,KAAK,EAAE;gBACrB,MAAM,KAAK,GAAG,OAAmB,CAAA;gBACjC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAA;gBACnC,MAAM,oBAAoB,GAAa,KAAK,CAAC,MAAM,CACjD,CAAC,MAAgB,EAAE,cAAsB,EAAE,EAAE;oBAC3C,MAAM,WAAW,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAA;oBACpE,IAAI,WAAW;wBAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;oBAC/C,OAAO,MAAM,CAAA;gBACf,CAAC,EACD,EAAE,CACH,CAAA;gBACD,OAAO;oBACL,OAAO,EAAE,WAAW;oBACpB,KAAK,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS;iBACtE,CAAA;aACF;iBAAM;gBACL,MAAM,KAAK,GAAG,OAAiB,CAAA;gBAC/B,MAAM,MAAM,GAAG,MAAA,WAAW,CAAC,OAAO,0CAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;gBACtE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAE,CAAA;aACtD;SACF;QACD,KAAK,SAAS,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,OAAkB,CAAA;YAChC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;SAC7D;QACD,KAAK,aAAa,CAAC,CAAC;YAClB,MAAM,KAAK,GAAG,OAAiB,CAAA;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAClD,IAAI,IAAI,CAAA;gBACR,IAAI,WAAW,CAAC,iBAAiB,EAAE;oBACjC,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;iBAC7B;qBAAM;oBACL,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;iBAC3B;gBACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;aAC7C;YACD,OAAO,SAAS,CAAA;SACjB;QACD,KAAK,cAAc,CAAC;QACpB,KAAK,iBAAiB,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,OAEmB,CAAA;YACjC,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,CAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,0CAAE,gBAAgB,MAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,CAAA;aACnE,CAAA;SACF;QACD,KAAK,kBAAkB,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,OAAuC,CAAA;YACrD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,eAAe,EAAE,CAAA;SAC/D;QACD,KAAK,kBAAkB,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,OAAuC,CAAA;YACrD,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EACH,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,UAAU,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,UAAU,CAAC;qBACjD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;qBAChB,IAAI,CAAC,GAAG,CAAC,KAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,YAAY,CAAA;aACtC,CAAA;SACF;QACD,KAAK,KAAK,CAAC,CAAC;YACV,MAAM,KAAK,GAAG,OAA8B,CAAA;YAC5C,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAA,sCAAyB,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;aAC5D,CAAA;SACF;QACD,KAAK,qBAAqB,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,OAAuD,CAAA;YACrE,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,KAAK,EACH,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,aAAa,0CAAE,aAAa,MAAM,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,aAAa,0CAAE,WAAW,EAAE,CAAC,IAAI,EAAE;aACzF,CAAA;SACF;QACD,OAAO,CAAC,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;SAChD;KACF;AACH,CAAC;AApND,8DAoNC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,SAAgB,mCAAmC,CACjD,IAAY,EACZ,OAEiC;IAejC,IAAI,yBAAyB,GAAG,IAAI,CAAA;IACpC,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE;QACtD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE;YAC3C,OAAO,SAAS,CAAA;SACjB;QACD,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAChD,IAAI,CAAC,aAAa,EAAE;YAClB,yBAAyB,GAAG,KAAK,CAAA;SAClC;QACD,OAAO,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC,CAAA;IACtE,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,sCAAgB,CAAC,CAAC,CAAC,wCAAkB,CACtE,CAAA;IACD,IAAI,cAAc,EAAE;QAClB,IAAA,2CAAqB,EACnB;YACE,IAAI;YACJ,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB;SACvD,EACD,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,EAAE;YAChC,MAAM,MAAM,GAAG,yBAAyB,CAAC;gBACvC,YAAY,EAAE,WAAW;gBACzB,GAAG,OAAO;aACX,CAAC,CAAA;YAEF,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,CAAA;YACrE,IAAI,UAAU,EAAE;gBACd,yBAAyB,GAAG,KAAK,CAAA;aAClC;YAED,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,YAAY,EACZ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,MAAM,CAAC,KAAgB,CAC3C,CAAA;QACH,CAAC,CACF,CAAA;KACF;IAED,OAAO;QACL,IAAI;QACJ,yBAAyB;KAC1B,CAAA;AACH,CAAC;AA/DD,kFA+DC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,SAAgB,sCAAsC,CACpD,IAAY,EACZ,OAAkC;IAelC,MAAM,MAAM,GAAG,mCAAmC,CAAC,IAAI,EAAE;QACvD,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ;QACnC,GAAG,OAAO;KACX,CAAC,CAAA;IACF,IAAI,yBAAyB,GAAG,MAAM,CAAC,yBAAyB,CAAA;IAChE,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE;QACvE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE;YAC3C,OAAO,SAAS,CAAA;SACjB;QACD,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAChD,IAAI,CAAC,aAAa,EAAE;YAClB,yBAAyB,GAAG,KAAK,CAAA;SAClC;QACD,OAAO,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC,CAAA;IACtE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAEf,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,yBAAyB;KAC1B,CAAA;AACH,CAAC;AArCD,wFAqCC","sourcesContent":["import {\n APINSWTypes,\n CivicaTypes,\n FormTypes,\n GeoscapeTypes,\n MiscTypes,\n PointTypes,\n ScheduledTasksTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { getABNNumberFromABNRecord } from './abnService'\nimport {\n RootElementRegex,\n NestedElementRegex,\n matchElementsTagRegex,\n} from './form-elements-regex'\n\nexport type ReplaceInjectablesFormatters = {\n formatDateTime: (value: string) => string\n formatDate: (value: string) => string\n formatTime: (value: string) => string\n formatNumber: (value: number) => string\n formatCurrency: (value: number) => string\n}\n\nexport type ReplaceInjectablesBaseOptions = ReplaceInjectablesFormatters & {\n submission: SubmissionTypes.S3SubmissionData['submission']\n userProfile: MiscTypes.UserProfile | undefined\n task: ScheduledTasksTypes.Task | undefined\n taskGroup: ScheduledTasksTypes.TaskGroup | undefined\n taskGroupInstance: ScheduledTasksTypes.TaskGroupInstance | undefined\n /**\n * Determine if only root level elements should be replaced.\n *\n * `false` will replace `\"{ELEMENT:Parent_Name}\"` and\n * `\"{ELEMENT:Children|Name}\"`.\n *\n * `true` will replace `\"{ELEMENT:Parent_Name}\"` but will NOT replace\n * `{ELEMENT:Children|Name}`.\n */\n excludeNestedElements?: boolean\n}\n\nexport type ReplaceInjectablesOptions = ReplaceInjectablesBaseOptions & {\n form: FormTypes.Form\n submissionId: string\n submissionTimestamp: string\n externalId: string | undefined\n previousApprovalId: string | undefined\n}\n\nconst SUBMISSION_VALUES: Array<{\n string: string\n value: (options: ReplaceInjectablesOptions) => string | undefined\n}> = [\n {\n string: '{INFO_PAGE_ID}',\n value: ({ form }: ReplaceInjectablesOptions) => form.id.toString(),\n },\n {\n string: '{INFO_PAGE_NAME}',\n value: ({ form }: ReplaceInjectablesOptions) => form.name,\n },\n {\n string: '{FORM_ID}',\n value: ({ form }: ReplaceInjectablesOptions) => form.id.toString(),\n },\n {\n string: '{FORM_NAME}',\n value: ({ form }: ReplaceInjectablesOptions) => form.name,\n },\n {\n string: '{DATE}',\n value: ({\n submissionTimestamp,\n formatDateTime,\n }: ReplaceInjectablesOptions) => {\n if (!submissionTimestamp) {\n return undefined\n }\n return formatDateTime(submissionTimestamp)\n },\n },\n {\n string: '{TIMESTAMP}',\n value: ({ submissionTimestamp }: ReplaceInjectablesOptions) =>\n submissionTimestamp,\n },\n {\n string: '{SUBMISSION_ID}',\n value: ({ submissionId }: ReplaceInjectablesOptions) => submissionId,\n },\n {\n string: '{EXTERNAL_ID}',\n value: ({ externalId }: ReplaceInjectablesOptions) => externalId,\n },\n {\n string: '{PREVIOUS_APPROVAL_ID}',\n value: ({ previousApprovalId }: ReplaceInjectablesOptions) =>\n previousApprovalId,\n },\n]\n\nconst ELEMENT_VALUES: Array<{\n string: string\n value: (options: ReplaceInjectablesBaseOptions) => string | undefined\n}> = [\n {\n string: '{USER:email}',\n value: ({ userProfile }) => userProfile?.email,\n },\n {\n string: '{USER:username}',\n value: ({ userProfile }) => userProfile?.username,\n },\n {\n string: '{TASK_NAME}',\n value: ({ task }) => task?.name,\n },\n {\n string: '{TASK_GROUP_NAME}',\n value: ({ taskGroup }) => taskGroup?.name,\n },\n {\n string: '{TASK_GROUP_INSTANCE_LABEL}',\n value: ({ taskGroupInstance }) => taskGroupInstance?.label,\n },\n]\n\n/**\n * Function to get the display value of a property in submission, if elementId\n * is provided propertyName will be ignored\n *\n * #### Example\n *\n * ```typescript\n * const result = submissionService.getElementSubmissionValue({\n * propertyName: 'search',\n * submission: {\n * search: 'Entered By User',\n * },\n * formElements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * formatNumber: (value) => Number(value).toString(),\n * formatCurrency: (value) => Number(value).toFixed(2),\n * })\n * ```\n *\n * @param options\n * @returns\n */\nexport function getElementSubmissionValue({\n elementId,\n propertyName,\n submission,\n formElements,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n elementId?: string\n propertyName?: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n} & ReplaceInjectablesFormatters):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined {\n if (elementId === undefined && propertyName === undefined) {\n return undefined\n }\n\n // make sure submission is an object\n if (Object(submission) !== submission) {\n return undefined\n }\n\n // initialise if propertyName provided and not elementId\n let unknown: unknown = elementId ? undefined : submission[propertyName ?? '']\n let formElement: FormTypes.FormElement | undefined = undefined\n\n const matchFn = (element: FormTypes.FormElement) => {\n if (elementId) {\n return elementId === element.id\n }\n return 'name' in element && element.name === propertyName\n }\n\n for (const element of formElements) {\n if (matchFn(element)) {\n if ('name' in element) {\n unknown = submission[element.name]\n formElement = element\n break\n }\n }\n if ('elements' in element) {\n const newSubmissionData =\n 'name' in element ? submission[element.name] : submission\n\n if (Array.isArray(newSubmissionData) || !element.elements) {\n continue\n }\n\n const result = getElementSubmissionValue({\n elementId,\n formElements: element.elements,\n submission:\n newSubmissionData as SubmissionTypes.S3SubmissionData['submission'],\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n })\n if (result) {\n unknown = result.value\n formElement = result.element\n }\n }\n }\n\n if (unknown === undefined || unknown === null) {\n return undefined\n }\n\n switch (formElement?.type) {\n case 'datetime': {\n const value = unknown as string\n return { element: formElement, value: formatDateTime(value) }\n }\n case 'date': {\n const value = unknown as string\n return { element: formElement, value: formatDate(value) }\n }\n case 'time': {\n const value = unknown as string\n return { element: formElement, value: formatTime(value) }\n }\n case 'radio':\n case 'autocomplete': {\n const value = unknown as string\n const option = formElement.options?.find((opt) => opt.value === value)\n return { element: formElement, value: option?.label || value }\n }\n\n case 'checkboxes': {\n const value = unknown as string[]\n const options = formElement.options\n const selectedOptionLabels: string[] = value.reduce(\n (labels: string[], selectedOption: string) => {\n const foundOption = options?.find((o) => o.value === selectedOption)\n if (foundOption) labels.push(foundOption.label)\n return labels\n },\n [],\n )\n return {\n element: formElement,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n }\n case 'compliance': {\n const value = unknown as {\n value?: string\n }\n const option = (formElement.options || []).find(\n (option: FormTypes.ChoiceElementOption) => option.value === value.value,\n )\n return {\n element: formElement,\n value: {\n ...value,\n value: option?.label || value.value,\n },\n }\n }\n case 'select': {\n if (formElement.multi) {\n const value = unknown as string[]\n const options = formElement.options\n const selectedOptionLabels: string[] = value.reduce(\n (labels: string[], selectedOption: string) => {\n const foundOption = options?.find((o) => o.value === selectedOption)\n if (foundOption) labels.push(foundOption.label)\n return labels\n },\n [],\n )\n return {\n element: formElement,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n } else {\n const value = unknown as string\n const option = formElement.options?.find((opt) => opt.value === value)\n return { element: formElement, value: option?.label }\n }\n }\n case 'boolean': {\n const value = unknown as boolean\n return { element: formElement, value: value ? 'Yes' : 'No' }\n }\n case 'calculation': {\n const value = unknown as number\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n let text\n if (formElement.displayAsCurrency) {\n text = formatCurrency(value)\n } else {\n text = formatNumber(value)\n }\n return { element: formElement, value: text }\n }\n return undefined\n }\n case 'pointAddress':\n case 'geoscapeAddress': {\n const value = unknown as\n | PointTypes.PointAddress\n | GeoscapeTypes.GeoscapeAddress\n return {\n element: formElement,\n value: value?.addressDetails?.formattedAddress || value?.addressId,\n }\n }\n case 'civicaStreetName': {\n const value = unknown as CivicaTypes.CivicaStreetName\n return { element: formElement, value: value?.formattedStreet }\n }\n case 'civicaNameRecord': {\n const value = unknown as CivicaTypes.CivicaNameRecord\n return {\n element: formElement,\n value:\n [value?.title, value?.givenName1, value?.familyName]\n .filter((t) => t)\n .join(' ') || value?.emailAddress,\n }\n }\n case 'abn': {\n const value = unknown as MiscTypes.ABNRecord\n return {\n element: formElement,\n value: value ? getABNNumberFromABNRecord(value) : undefined,\n }\n }\n case 'apiNSWLiquorLicence': {\n const value = unknown as APINSWTypes.LiquorLicenceDetails | undefined\n return {\n element: formElement,\n value:\n `${value?.licenceDetail?.licenceNumber} | ${value?.licenceDetail?.licenceName}`.trim(),\n }\n }\n default: {\n return { element: formElement, value: unknown }\n }\n }\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text while a form is being\n * filled out. The replacements are suppose to be user friendly and for display\n * purposes, e.g. dates should be displayed in the user's desired format and\n * timezone.\n *\n * #### Example\n *\n * ```js\n * const { text: url } =\n * submissionService.replaceInjectablesWithElementValues(\n * 'https://example.com/path?search{ELEMENT:search}',\n * {\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * formatNumber: (value) => Number(value).toString(),\n * formatCurrency: (value) => Number(value).toFixed(2),\n * submission: {\n * search: 'Entered By User',\n * },\n * elements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * userProfile: {\n * userId: 'abc123',\n * username: 'john-user',\n * email: 'john.user@domain.com',\n * },\n * },\n * )\n * ```\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithElementValues(\n text: string,\n options: {\n formElements: FormTypes.FormElement[]\n } & ReplaceInjectablesBaseOptions,\n): {\n /**\n * The text passed in with all injectables replaced with their corresponding\n * values or empty strings.\n */\n text: string\n /**\n * Determine if replaceable strings could all be replaced. The `text` property\n * returned will replace all injectable with empty strings if the value cannot\n * be found. Use this boolean to either use the replaced string with missing\n * data or implement some other logic to handle missing injectables.\n */\n hadAllInjectablesReplaced: boolean\n} {\n let hadAllInjectablesReplaced = true\n text = ELEMENT_VALUES.reduce((newString, customValue) => {\n if (!newString.includes(customValue.string)) {\n return newString\n }\n const replacedValue = customValue.value(options)\n if (!replacedValue) {\n hadAllInjectablesReplaced = false\n }\n return newString.replaceAll(customValue.string, replacedValue || '')\n }, text)\n\n const matchesElement = text.match(\n options.excludeNestedElements ? RootElementRegex : NestedElementRegex,\n )\n if (matchesElement) {\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: !!options.excludeNestedElements,\n },\n ({ elementName, elementMatch }) => {\n const result = getElementSubmissionValue({\n propertyName: elementName,\n ...options,\n })\n\n const hasNoValue = result === undefined || result.value === undefined\n if (hasNoValue) {\n hadAllInjectablesReplaced = false\n }\n\n text = text.replace(\n elementMatch,\n hasNoValue ? '' : (result.value as string),\n )\n },\n )\n }\n\n return {\n text,\n hadAllInjectablesReplaced,\n }\n}\n\n/**\n * Replace the `{ELEMENT:<elementName>}` values in text after a successful form\n * submission as well as other replaceable parameters e.g. `submissionId`. The\n * replacements are suppose to be user friendly and for display purposes, e.g.\n * dates should be displayed in the user's desired format and timezone.\n *\n * #### Example\n *\n * ```js\n * const result = submissionService.replaceInjectablesWithSubmissionValues(\n * 'https://example.com/path?submissionId={SUBMISSION_ID}&externalId={EXTERNAL_ID}&search{ELEMENT:search}',\n * {\n * submissionId: 'abc-123',\n * submissionTimestamp: '2021-07-02T02:19:13.670Z',\n * formatDate: (value) => new Date(value).toDateString(),\n * formatDateTime: (value) => new Date(value).toString(),\n * formatTime: (value) => new Date(value).toTimeString(),\n * submission: {\n * search: 'Entered By User',\n * },\n * form: {\n * id: 1,\n * name: 'Form',\n * organisationId: '',\n * formsAppEnvironmentId: 1,\n * formsAppIds: [],\n * isAuthenticated: false,\n * isMultiPage: false,\n * isInfoPage: false,\n * postSubmissionAction: 'FORMS_LIBRARY',\n * cancelAction: 'FORMS_LIBRARY',\n * submissionEvents: [],\n * tags: [],\n * elements: [\n * {\n * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',\n * name: 'search',\n * type: 'text',\n * label: 'Search',\n * readOnly: false,\n * required: false,\n * conditionallyShow: false,\n * requiresAllConditionallyShowPredicates: false,\n * isElementLookup: false,\n * isDataLookup: false,\n * },\n * ],\n * },\n * },\n * )\n * ```\n *\n * @param text\n * @param options\n * @returns\n */\nexport function replaceInjectablesWithSubmissionValues(\n text: string,\n options: ReplaceInjectablesOptions,\n): {\n /**\n * The text passed in with all injectables replaced with their corresponding\n * values or empty strings.\n */\n text: string\n /**\n * Determine if replaceable strings could all be replaced. The `text` property\n * returned will replace all injectable with empty strings if the value cannot\n * be found. Use this boolean to either use the replaced string with missing\n * data or implement some other logic to handle missing injectables.\n */\n hadAllInjectablesReplaced: boolean\n} {\n const result = replaceInjectablesWithElementValues(text, {\n formElements: options.form.elements,\n ...options,\n })\n let hadAllInjectablesReplaced = result.hadAllInjectablesReplaced\n const replacedText = SUBMISSION_VALUES.reduce((newString, customValue) => {\n if (!newString.includes(customValue.string)) {\n return newString\n }\n const replacedValue = customValue.value(options)\n if (!replacedValue) {\n hadAllInjectablesReplaced = false\n }\n return newString.replaceAll(customValue.string, replacedValue || '')\n }, result.text)\n\n return {\n text: replacedText,\n hadAllInjectablesReplaced,\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/sdk-core",
3
3
  "description": "OneBlink SDK for JavaScript (works in Browsers and NodeJS)",
4
- "version": "6.0.0-beta.1",
4
+ "version": "6.0.0-beta.3",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/sdk-core-js/issues"