@oneblink/sdk-core 8.11.1 → 9.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abnService.d.ts +5 -5
- package/dist/abnService.js +9 -17
- package/dist/abnService.js.map +1 -1
- package/dist/conditionalLogicService/conditionallyShowElement.d.ts +1 -1
- package/dist/conditionalLogicService/conditionallyShowElement.js +4 -11
- package/dist/conditionalLogicService/conditionallyShowElement.js.map +1 -1
- package/dist/conditionalLogicService/conditionallyShowOption.d.ts +1 -1
- package/dist/conditionalLogicService/conditionallyShowOption.js +10 -18
- package/dist/conditionalLogicService/conditionallyShowOption.js.map +1 -1
- package/dist/conditionalLogicService/evaluateConditionalOptionsPredicate.js +2 -6
- package/dist/conditionalLogicService/evaluateConditionalOptionsPredicate.js.map +1 -1
- package/dist/conditionalLogicService/evaluateConditionalPredicate.d.ts +1 -1
- package/dist/conditionalLogicService/evaluateConditionalPredicate.js +14 -22
- package/dist/conditionalLogicService/evaluateConditionalPredicate.js.map +1 -1
- package/dist/conditionalLogicService/generateFormElementsConditionallyShown.js +12 -19
- package/dist/conditionalLogicService/generateFormElementsConditionallyShown.js.map +1 -1
- package/dist/conditionalLogicService/types.js +1 -2
- package/dist/conditionalLogicService.d.ts +1 -1
- package/dist/conditionalLogicService.js +6 -26
- package/dist/conditionalLogicService.js.map +1 -1
- package/dist/fileUploadService.js +2 -6
- package/dist/fileUploadService.js.map +1 -1
- package/dist/form-elements-regex.js +10 -14
- package/dist/form-elements-regex.js.map +1 -1
- package/dist/formElementsService.d.ts +2 -3
- package/dist/formElementsService.js +4 -15
- package/dist/formElementsService.js.map +1 -1
- package/dist/freshdeskService.d.ts +1 -1
- package/dist/freshdeskService.js +23 -31
- package/dist/freshdeskService.js.map +1 -1
- package/dist/goodToGoService.d.ts +1 -1
- package/dist/goodToGoService.js +2 -6
- package/dist/goodToGoService.js.map +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +14 -50
- package/dist/index.js.map +1 -1
- package/dist/paymentService.d.ts +1 -1
- package/dist/paymentService.js +11 -18
- package/dist/paymentService.js.map +1 -1
- package/dist/replaceCustomValues.js +42 -50
- package/dist/replaceCustomValues.js.map +1 -1
- package/dist/schedulingService.js +3 -6
- package/dist/schedulingService.js.map +1 -1
- package/dist/sharepointService.d.ts +1 -1
- package/dist/sharepointService.js +4 -8
- package/dist/sharepointService.js.map +1 -1
- package/dist/submissionService.d.ts +1 -1
- package/dist/submissionService.js +4 -21
- package/dist/submissionService.js.map +1 -1
- package/dist/typeCastService.js +1 -5
- package/dist/typeCastService.js.map +1 -1
- package/dist/typedoc.d.ts +1 -1
- package/dist/typedoc.js +2 -18
- package/dist/typedoc.js.map +1 -1
- package/dist/types/resource-definitions.js +1 -2
- package/dist/userService.js +8 -11
- package/dist/userService.js.map +1 -1
- package/dist/webhookSubscriptionService.js +1 -3
- package/dist/webhookSubscriptionService.js.map +1 -1
- package/package.json +25 -27
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
exports.replaceInjectablesWithElementValues = replaceInjectablesWithElementValues;
|
|
5
|
-
exports.replaceInjectablesWithSubmissionValues = replaceInjectablesWithSubmissionValues;
|
|
6
|
-
exports.processInjectablesInCustomResource = processInjectablesInCustomResource;
|
|
7
|
-
const abnService_1 = require("./abnService");
|
|
8
|
-
const form_elements_regex_1 = require("./form-elements-regex");
|
|
9
|
-
const formElementsService_1 = require("./formElementsService");
|
|
1
|
+
import { getABNNumberFromABNRecord } from './abnService.js';
|
|
2
|
+
import { RootElementRegex, NestedElementRegex, matchElementsTagRegex, RootSubmissionValueElementRegex, NestedSubmissionValueElementRegex, } from './form-elements-regex.js';
|
|
3
|
+
import { findFormElement, flattenFormElements } from './formElementsService.js';
|
|
10
4
|
const SUBMISSION_VALUES = [
|
|
11
5
|
{
|
|
12
6
|
string: '{INFO_PAGE_ID}',
|
|
@@ -53,26 +47,26 @@ const SUBMISSION_VALUES = [
|
|
|
53
47
|
const ELEMENT_VALUES = [
|
|
54
48
|
{
|
|
55
49
|
string: '{USER:email}',
|
|
56
|
-
value: ({ userProfile }) => userProfile
|
|
50
|
+
value: ({ userProfile }) => userProfile?.email,
|
|
57
51
|
},
|
|
58
52
|
{
|
|
59
53
|
string: '{USER:username}',
|
|
60
|
-
value: ({ userProfile }) => userProfile
|
|
54
|
+
value: ({ userProfile }) => userProfile?.username,
|
|
61
55
|
},
|
|
62
56
|
{
|
|
63
57
|
string: '{TASK_NAME}',
|
|
64
|
-
value: ({ task }) => task
|
|
58
|
+
value: ({ task }) => task?.name,
|
|
65
59
|
},
|
|
66
60
|
{
|
|
67
61
|
string: '{TASK_GROUP_NAME}',
|
|
68
|
-
value: ({ taskGroup }) => taskGroup
|
|
62
|
+
value: ({ taskGroup }) => taskGroup?.name,
|
|
69
63
|
},
|
|
70
64
|
{
|
|
71
65
|
string: '{TASK_GROUP_INSTANCE_LABEL}',
|
|
72
|
-
value: ({ taskGroupInstance }) => taskGroupInstance
|
|
66
|
+
value: ({ taskGroupInstance }) => taskGroupInstance?.label,
|
|
73
67
|
},
|
|
74
68
|
];
|
|
75
|
-
function getElementSubmissionValue({ elementId, propertyName, submission, formElements, useSubmissionValue, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }) {
|
|
69
|
+
export function getElementSubmissionValue({ elementId, propertyName, submission, formElements, useSubmissionValue, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }) {
|
|
76
70
|
if (elementId === undefined && propertyName === undefined) {
|
|
77
71
|
return undefined;
|
|
78
72
|
}
|
|
@@ -110,18 +104,17 @@ function getElementSubmissionValueByName({ propertyName, formElements, submissio
|
|
|
110
104
|
if (unknownValue === undefined || unknownValue === null) {
|
|
111
105
|
return undefined;
|
|
112
106
|
}
|
|
113
|
-
const formElement =
|
|
107
|
+
const formElement = findFormElement(formElements, (element) => element.type !== 'page' &&
|
|
114
108
|
element.type !== 'section' &&
|
|
115
109
|
element.name === propertyName);
|
|
116
110
|
return { formElement, unknownValue };
|
|
117
111
|
}
|
|
118
112
|
function getElementSubmissionValueById({ elementId, formElements, submission, }) {
|
|
119
|
-
var _a;
|
|
120
113
|
// make sure submission is an object
|
|
121
114
|
if (Object(submission) !== submission) {
|
|
122
115
|
return undefined;
|
|
123
116
|
}
|
|
124
|
-
const flattenedElements =
|
|
117
|
+
const flattenedElements = flattenFormElements(formElements);
|
|
125
118
|
let unknown = undefined;
|
|
126
119
|
let formElement = undefined;
|
|
127
120
|
for (const element of flattenedElements) {
|
|
@@ -136,7 +129,7 @@ function getElementSubmissionValueById({ elementId, formElements, submission, })
|
|
|
136
129
|
const newSubmissionData = submission[element.name];
|
|
137
130
|
const result = getElementSubmissionValueById({
|
|
138
131
|
elementId,
|
|
139
|
-
formElements:
|
|
132
|
+
formElements: element.elements ?? [],
|
|
140
133
|
submission: newSubmissionData,
|
|
141
134
|
});
|
|
142
135
|
if (result) {
|
|
@@ -152,8 +145,7 @@ function getElementSubmissionValueById({ elementId, formElements, submission, })
|
|
|
152
145
|
return { unknownValue: unknown, formElement };
|
|
153
146
|
}
|
|
154
147
|
function formatValue({ element, unknownValue, useSubmissionValue, formatDate, formatTime, formatDateTime, formatCurrency, formatNumber, }) {
|
|
155
|
-
|
|
156
|
-
switch (element === null || element === void 0 ? void 0 : element.type) {
|
|
148
|
+
switch (element?.type) {
|
|
157
149
|
case 'datetime': {
|
|
158
150
|
const value = unknownValue;
|
|
159
151
|
return { element: element, value: formatDateTime(value) };
|
|
@@ -172,8 +164,8 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
172
164
|
if (useSubmissionValue) {
|
|
173
165
|
return { element: element, value: value };
|
|
174
166
|
}
|
|
175
|
-
const option =
|
|
176
|
-
return { element: element, value:
|
|
167
|
+
const option = element.options?.find((opt) => opt.value === value);
|
|
168
|
+
return { element: element, value: option?.label || value };
|
|
177
169
|
}
|
|
178
170
|
case 'checkboxes': {
|
|
179
171
|
const value = unknownValue;
|
|
@@ -182,7 +174,7 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
182
174
|
}
|
|
183
175
|
const options = element.options;
|
|
184
176
|
const selectedOptionLabels = value.reduce((labels, selectedOption) => {
|
|
185
|
-
const foundOption = options
|
|
177
|
+
const foundOption = options?.find((o) => o.value === selectedOption);
|
|
186
178
|
if (foundOption)
|
|
187
179
|
labels.push(foundOption.label);
|
|
188
180
|
return labels;
|
|
@@ -202,7 +194,7 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
202
194
|
element: element,
|
|
203
195
|
value: {
|
|
204
196
|
...value,
|
|
205
|
-
value:
|
|
197
|
+
value: option?.label || value.value,
|
|
206
198
|
},
|
|
207
199
|
};
|
|
208
200
|
}
|
|
@@ -214,7 +206,7 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
214
206
|
}
|
|
215
207
|
const options = element.options;
|
|
216
208
|
const selectedOptionLabels = value.reduce((labels, selectedOption) => {
|
|
217
|
-
const foundOption = options
|
|
209
|
+
const foundOption = options?.find((o) => o.value === selectedOption);
|
|
218
210
|
if (foundOption)
|
|
219
211
|
labels.push(foundOption.label);
|
|
220
212
|
return labels;
|
|
@@ -229,8 +221,8 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
229
221
|
if (useSubmissionValue) {
|
|
230
222
|
return { element: element, value: value };
|
|
231
223
|
}
|
|
232
|
-
const option =
|
|
233
|
-
return { element: element, value: option
|
|
224
|
+
const option = element.options?.find((opt) => opt.value === value);
|
|
225
|
+
return { element: element, value: option?.label };
|
|
234
226
|
}
|
|
235
227
|
}
|
|
236
228
|
case 'boolean': {
|
|
@@ -259,7 +251,7 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
259
251
|
const value = unknownValue;
|
|
260
252
|
return {
|
|
261
253
|
element: element,
|
|
262
|
-
value:
|
|
254
|
+
value: value?.parcelBundle?.[0]?.parcelId,
|
|
263
255
|
};
|
|
264
256
|
}
|
|
265
257
|
case 'pointAddress':
|
|
@@ -267,14 +259,14 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
267
259
|
const value = unknownValue;
|
|
268
260
|
return {
|
|
269
261
|
element: element,
|
|
270
|
-
value:
|
|
262
|
+
value: value?.addressDetails?.formattedAddress || value?.addressId,
|
|
271
263
|
};
|
|
272
264
|
}
|
|
273
265
|
case 'pointAddressV3': {
|
|
274
266
|
const value = unknownValue;
|
|
275
267
|
return {
|
|
276
268
|
element: element,
|
|
277
|
-
value:
|
|
269
|
+
value: value.properties?.formattedAddress || value.properties?.addressId,
|
|
278
270
|
};
|
|
279
271
|
}
|
|
280
272
|
case 'googleAddress': {
|
|
@@ -286,29 +278,29 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
286
278
|
}
|
|
287
279
|
case 'civicaStreetName': {
|
|
288
280
|
const value = unknownValue;
|
|
289
|
-
return { element: element, value: value
|
|
281
|
+
return { element: element, value: value?.formattedStreet };
|
|
290
282
|
}
|
|
291
283
|
case 'civicaNameRecord': {
|
|
292
284
|
const value = unknownValue;
|
|
293
285
|
return {
|
|
294
286
|
element: element,
|
|
295
|
-
value: [value
|
|
287
|
+
value: [value?.title, value?.givenName1, value?.familyName]
|
|
296
288
|
.filter((t) => t)
|
|
297
|
-
.join(' ') ||
|
|
289
|
+
.join(' ') || value?.emailAddress,
|
|
298
290
|
};
|
|
299
291
|
}
|
|
300
292
|
case 'abn': {
|
|
301
293
|
const value = unknownValue;
|
|
302
294
|
return {
|
|
303
295
|
element: element,
|
|
304
|
-
value: value ?
|
|
296
|
+
value: value ? getABNNumberFromABNRecord(value) : undefined,
|
|
305
297
|
};
|
|
306
298
|
}
|
|
307
299
|
case 'apiNSWLiquorLicence': {
|
|
308
300
|
const value = unknownValue;
|
|
309
301
|
return {
|
|
310
302
|
element: element,
|
|
311
|
-
value: `${
|
|
303
|
+
value: `${value?.licenceDetail?.licenceNumber} | ${value?.licenceDetail?.licenceName}`.trim(),
|
|
312
304
|
};
|
|
313
305
|
}
|
|
314
306
|
case 'freshdeskDependentField': {
|
|
@@ -373,7 +365,7 @@ function formatValue({ element, unknownValue, useSubmissionValue, formatDate, fo
|
|
|
373
365
|
* @param options
|
|
374
366
|
* @returns
|
|
375
367
|
*/
|
|
376
|
-
function replaceInjectablesWithElementValues(text, options) {
|
|
368
|
+
export function replaceInjectablesWithElementValues(text, options) {
|
|
377
369
|
let hadAllInjectablesReplaced = true;
|
|
378
370
|
text = ELEMENT_VALUES.reduce((newString, customValue) => {
|
|
379
371
|
if (!newString.includes(customValue.string)) {
|
|
@@ -385,9 +377,9 @@ function replaceInjectablesWithElementValues(text, options) {
|
|
|
385
377
|
}
|
|
386
378
|
return newString.replaceAll(customValue.string, replacedValue || '');
|
|
387
379
|
}, text);
|
|
388
|
-
const matchesElement = text.match(options.excludeNestedElements ?
|
|
380
|
+
const matchesElement = text.match(options.excludeNestedElements ? RootElementRegex : NestedElementRegex);
|
|
389
381
|
if (matchesElement) {
|
|
390
|
-
|
|
382
|
+
matchElementsTagRegex({
|
|
391
383
|
text,
|
|
392
384
|
excludeNestedElements: !!options.excludeNestedElements,
|
|
393
385
|
}, ({ elementName, elementMatch }) => {
|
|
@@ -403,10 +395,10 @@ function replaceInjectablesWithElementValues(text, options) {
|
|
|
403
395
|
});
|
|
404
396
|
}
|
|
405
397
|
const valueMatchesElement = text.match(options.excludeNestedElements
|
|
406
|
-
?
|
|
407
|
-
:
|
|
398
|
+
? RootSubmissionValueElementRegex
|
|
399
|
+
: NestedSubmissionValueElementRegex);
|
|
408
400
|
if (valueMatchesElement) {
|
|
409
|
-
|
|
401
|
+
matchElementsTagRegex({
|
|
410
402
|
text,
|
|
411
403
|
excludeNestedElements: !!options.excludeNestedElements,
|
|
412
404
|
useSubmissionValue: true,
|
|
@@ -484,7 +476,7 @@ function replaceInjectablesWithElementValues(text, options) {
|
|
|
484
476
|
* @param options
|
|
485
477
|
* @returns
|
|
486
478
|
*/
|
|
487
|
-
function replaceInjectablesWithSubmissionValues(text, options) {
|
|
479
|
+
export function replaceInjectablesWithSubmissionValues(text, options) {
|
|
488
480
|
const result = replaceInjectablesWithElementValues(text, {
|
|
489
481
|
formElements: options.form.elements,
|
|
490
482
|
...options,
|
|
@@ -577,7 +569,7 @@ function replaceInjectablesWithSubmissionValues(text, options) {
|
|
|
577
569
|
* @param options
|
|
578
570
|
* @returns
|
|
579
571
|
*/
|
|
580
|
-
function processInjectablesInCustomResource({ resource, submission, formElements, replaceRootInjectables, prepareNestedInjectables = (resource, prepare) => prepare(String(resource)), }) {
|
|
572
|
+
export function processInjectablesInCustomResource({ resource, submission, formElements, replaceRootInjectables, prepareNestedInjectables = (resource, prepare) => prepare(String(resource)), }) {
|
|
581
573
|
const newResources = new Map();
|
|
582
574
|
const injectorResult = replaceRootInjectables(resource, submission, formElements);
|
|
583
575
|
if (!injectorResult) {
|
|
@@ -588,7 +580,7 @@ function processInjectablesInCustomResource({ resource, submission, formElements
|
|
|
588
580
|
: injectorResult;
|
|
589
581
|
// Find nested form elements
|
|
590
582
|
const matches = new Map();
|
|
591
|
-
|
|
583
|
+
matchElementsTagRegex({
|
|
592
584
|
text,
|
|
593
585
|
excludeNestedElements: false,
|
|
594
586
|
}, ({ elementName }) => {
|
|
@@ -599,9 +591,9 @@ function processInjectablesInCustomResource({ resource, submission, formElements
|
|
|
599
591
|
matches.forEach((hasNestedFormElements, repeatableSetElementName) => {
|
|
600
592
|
if (hasNestedFormElements) {
|
|
601
593
|
// Attempt to create a new resource for each entry in the repeatable set.
|
|
602
|
-
const entries = submission
|
|
594
|
+
const entries = submission?.[repeatableSetElementName];
|
|
603
595
|
if (Array.isArray(entries)) {
|
|
604
|
-
const repeatableSetElement =
|
|
596
|
+
const repeatableSetElement = findFormElement(formElements, (formElement) => {
|
|
605
597
|
return ('name' in formElement &&
|
|
606
598
|
formElement.name === repeatableSetElementName);
|
|
607
599
|
});
|
|
@@ -634,7 +626,7 @@ function processInjectablesInCustomResource({ resource, submission, formElements
|
|
|
634
626
|
}
|
|
635
627
|
// Find nested form elements using ELEMENT_VALUE:
|
|
636
628
|
const valueMatches = new Map();
|
|
637
|
-
|
|
629
|
+
matchElementsTagRegex({
|
|
638
630
|
text,
|
|
639
631
|
excludeNestedElements: false,
|
|
640
632
|
useSubmissionValue: true,
|
|
@@ -646,9 +638,9 @@ function processInjectablesInCustomResource({ resource, submission, formElements
|
|
|
646
638
|
valueMatches.forEach((hasNestedFormElements, repeatableSetElementName) => {
|
|
647
639
|
if (hasNestedFormElements) {
|
|
648
640
|
// Attempt to create a new resource for each entry in the repeatable set.
|
|
649
|
-
const entries = submission
|
|
641
|
+
const entries = submission?.[repeatableSetElementName];
|
|
650
642
|
if (Array.isArray(entries)) {
|
|
651
|
-
const repeatableSetElement =
|
|
643
|
+
const repeatableSetElement = findFormElement(formElements, (formElement) => {
|
|
652
644
|
return ('name' in formElement &&
|
|
653
645
|
formElement.name === repeatableSetElementName);
|
|
654
646
|
});
|
|
@@ -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 GoogleTypes,\n MiscTypes,\n PointTypes,\n ScheduledTasksTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { getABNNumberFromABNRecord } from './abnService'\nimport {\n RootElementRegex,\n NestedElementRegex,\n matchElementsTagRegex,\n RootSubmissionValueElementRegex,\n NestedSubmissionValueElementRegex,\n} from './form-elements-regex'\nimport { findFormElement, flattenFormElements } from './formElementsService'\n\nexport type ReplaceInjectablesFormatters = {\n /** A function to format any date/times. */\n formatDateTime: (value: string) => string\n /** A function to format any dates. */\n formatDate: (value: string) => string\n /** A function to format any times. */\n formatTime: (value: string) => string\n /** A function to format any numbers. */\n formatNumber: (value: number) => string\n /** A function to format any numbers as currency. */\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 propertyName,\n submission,\n formElements,\n useSubmissionValue,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n propertyName: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined\nexport function getElementSubmissionValue({\n elementId,\n submission,\n formElements,\n useSubmissionValue,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n elementId: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined\nexport function getElementSubmissionValue({\n elementId,\n propertyName,\n submission,\n formElements,\n useSubmissionValue,\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 useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters) {\n if (elementId === undefined && propertyName === undefined) {\n return undefined\n }\n\n let result: ReturnType<typeof getElementSubmissionValueByName> | undefined =\n undefined\n if (elementId) {\n result = getElementSubmissionValueById({\n elementId,\n formElements,\n submission,\n })\n } else if (propertyName) {\n result = getElementSubmissionValueByName({\n propertyName,\n formElements,\n submission,\n })\n }\n if (!result) {\n return\n }\n return formatValue({\n element: result.formElement,\n unknownValue: result.unknownValue,\n useSubmissionValue,\n formatDate,\n formatTime,\n formatDateTime,\n formatCurrency,\n formatNumber,\n })\n}\n\nfunction getElementSubmissionValueByName({\n propertyName,\n formElements,\n submission,\n}: {\n propertyName: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}):\n | { formElement: FormTypes.FormElement | undefined; unknownValue: unknown }\n | undefined {\n const unknownValue = submission[propertyName]\n if (unknownValue === undefined || unknownValue === null) {\n return undefined\n }\n\n const formElement = findFormElement(\n formElements,\n (element) =>\n element.type !== 'page' &&\n element.type !== 'section' &&\n element.name === propertyName,\n )\n\n return { formElement, unknownValue }\n}\n\nfunction getElementSubmissionValueById({\n elementId,\n formElements,\n submission,\n}: {\n elementId: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): { formElement: FormTypes.FormElement; unknownValue: unknown } | undefined {\n // make sure submission is an object\n if (Object(submission) !== submission) {\n return undefined\n }\n const flattenedElements = flattenFormElements(formElements)\n\n let unknown: unknown = undefined\n let formElement: FormTypes.FormElement | undefined = undefined\n for (const element of flattenedElements) {\n if (elementId === element.id) {\n if ('name' in element) {\n unknown = submission[element.name]\n formElement = element\n }\n break\n }\n if (element.type === 'form') {\n const newSubmissionData = submission[element.name]\n\n const result = getElementSubmissionValueById({\n elementId,\n formElements: element.elements ?? [],\n submission:\n newSubmissionData as SubmissionTypes.S3SubmissionData['submission'],\n })\n if (result) {\n unknown = result.unknownValue\n formElement = result.formElement\n break\n }\n }\n }\n if (unknown === undefined || unknown === null || formElement === undefined) {\n return undefined\n }\n\n return { unknownValue: unknown, formElement }\n}\n\nfunction formatValue({\n element,\n unknownValue,\n useSubmissionValue,\n formatDate,\n formatTime,\n formatDateTime,\n formatCurrency,\n formatNumber,\n}: {\n element: FormTypes.FormElement | undefined\n unknownValue: unknown\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters) {\n switch (element?.type) {\n case 'datetime': {\n const value = unknownValue as string\n return { element: element, value: formatDateTime(value) }\n }\n case 'date': {\n const value = unknownValue as string\n return { element: element, value: formatDate(value) }\n }\n case 'time': {\n const value = unknownValue as string\n return { element: element, value: formatTime(value) }\n }\n case 'radio':\n case 'autocomplete': {\n const value = unknownValue as string\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const option = element.options?.find((opt) => opt.value === value)\n return { element: element, value: option?.label || value }\n }\n\n case 'checkboxes': {\n const value = unknownValue as string[]\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const options = element.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: element,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n }\n case 'compliance': {\n const value = unknownValue as {\n value?: string\n }\n if (useSubmissionValue) {\n return { element: element, value: value.value }\n }\n const option = (element.options || []).find(\n (option: FormTypes.ChoiceElementOption) => option.value === value.value,\n )\n return {\n element: element,\n value: {\n ...value,\n value: option?.label || value.value,\n },\n }\n }\n case 'select': {\n if (element.multi) {\n const value = unknownValue as string[]\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const options = element.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: element,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n } else {\n const value = unknownValue as string\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const option = element.options?.find((opt) => opt.value === value)\n return { element: element, value: option?.label }\n }\n }\n case 'boolean': {\n const value = unknownValue as boolean\n return { element: element, value: value ? 'Yes' : 'No' }\n }\n case 'calculation':\n case 'number': {\n const getValue = (value: number) => {\n if (element.displayAsCurrency) {\n return formatCurrency(value)\n }\n if (element.type === 'calculation') {\n return formatNumber(value)\n }\n return value\n }\n\n const value = unknownValue as number\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n const formattedValue = getValue(value)\n return { element, value: formattedValue }\n }\n return undefined\n }\n case 'pointCadastralParcel': {\n const value = unknownValue as PointTypes.PointCadastralParcelResponse\n return {\n element: element,\n value: value?.parcelBundle?.[0]?.parcelId,\n }\n }\n case 'pointAddress':\n case 'geoscapeAddress': {\n const value = unknownValue as\n | PointTypes.PointAddress\n | GeoscapeTypes.GeoscapeAddress\n return {\n element: element,\n value: value?.addressDetails?.formattedAddress || value?.addressId,\n }\n }\n case 'pointAddressV3': {\n const value =\n unknownValue as PointTypes.PointAddressV3GetAddressDetailsResponse\n return {\n element: element,\n value:\n value.properties?.formattedAddress || value.properties?.addressId,\n }\n }\n case 'googleAddress': {\n const value = unknownValue as GoogleTypes.GoogleMapsAddress\n return {\n element: element,\n value: value.formatted_address || value.place_id,\n }\n }\n case 'civicaStreetName': {\n const value = unknownValue as CivicaTypes.CivicaStreetName\n return { element: element, value: value?.formattedStreet }\n }\n case 'civicaNameRecord': {\n const value = unknownValue as CivicaTypes.CivicaNameRecord\n return {\n element: element,\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 = unknownValue as MiscTypes.ABNRecord\n return {\n element: element,\n value: value ? getABNNumberFromABNRecord(value) : undefined,\n }\n }\n case 'apiNSWLiquorLicence': {\n const value = unknownValue as APINSWTypes.LiquorLicenceDetails | undefined\n return {\n element: element,\n value:\n `${value?.licenceDetail?.licenceNumber} | ${value?.licenceDetail?.licenceName}`.trim(),\n }\n }\n case 'freshdeskDependentField': {\n const value =\n unknownValue as FormTypes.FreshdeskDependentFieldElementValue\n return {\n element,\n value:\n [value.category, value.subCategory, value.item]\n .filter((text) => !!text)\n .join(' / ') || undefined,\n }\n }\n default: {\n return { element: element, value: unknownValue }\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 const valueMatchesElement = text.match(\n options.excludeNestedElements\n ? RootSubmissionValueElementRegex\n : NestedSubmissionValueElementRegex,\n )\n if (valueMatchesElement) {\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: !!options.excludeNestedElements,\n useSubmissionValue: true,\n },\n ({ elementName, elementMatch }) => {\n const result = getElementSubmissionValue({\n propertyName: elementName,\n ...options,\n useSubmissionValue: true,\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\n/**\n * Process a resource with injectable element values to turn a single resource\n * (could be a single) into multiple resources. e.g.\n * `\"{ELEMENT:Children|Child_Name} {ELEMENT:Family_Name}\"` with the following\n * submission data:\n *\n * ```json\n * {\n * \"Family_Name\": \"Smith\",\n * \"Children\": [\n * {\n * \"Child_Name\": \"John\"\n * },\n * {\n * \"Child_Name\": \"Jane\"\n * }\n * ]\n * }\n * ```\n *\n * Would result in the following resources:\n *\n * - `\"John Smith\"`\n * - `\"Jane Smith\"`\n *\n * #### Example\n *\n * ```js\n * const emailAddresses = processInjectablesInCustomResource({\n * resource: '{ELEMENT:People|Email_Address}',\n * submission: {\n * People: [\n * {\n * Email_Address: 'user@oneblink.io',\n * },\n * {\n * Email_Address: 'admin@oneblink.io',\n * },\n * ],\n * },\n * formElements: [\n * {\n * id: '18dcd3e0-6e2f-462e-803b-e24562d9fa6d',\n * type: 'repeatableSet',\n * name: 'People',\n * label: 'People',\n * elements: [\n * {\n * id: 'd0902113-3f77-4070-adbd-ca3ae95ce091',\n * type: 'email',\n * name: 'Email_Address',\n * label: 'Email_Address',\n * },\n * ],\n * },\n * ],\n * replaceRootInjectables: (resource, submission, formElements) => {\n * const { text } = replaceInjectablesWithElementValues(resource, {\n * submission,\n * formElements,\n * excludeNestedElements: true,\n * // other options\n * })\n * return text\n * },\n * })\n * // emailAddresses === [\"user@oneblink.io\", \"admin@oneblink.io\"]\n * ```\n *\n * @param options\n * @returns\n */\nexport function processInjectablesInCustomResource<T>({\n resource,\n submission,\n formElements,\n replaceRootInjectables,\n prepareNestedInjectables = (resource, prepare) =>\n prepare(String(resource)) as T,\n}: {\n /** The resource that contains properties that support injection or a string */\n resource: T\n /** The form submission data to process */\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** The form elements to process */\n formElements: FormTypes.FormElement[]\n /**\n * A function to inject values, this allows custom formatters to be used.\n * Return `undefined` to prevent the injection from recursively continuing.\n *\n * @param resource The current resource that contains properties that support\n * injection or a string\n * @param submission The current form submission data to process (may be an\n * entry in a repeatable set)\n * @param formElements The current form elements to process (may be the\n * elements from a repeatable set)\n * @returns\n */\n replaceRootInjectables: (\n resource: T,\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElements: FormTypes.FormElement[],\n ) =>\n | [injectedText: string, resourceKey: string, newResource: T]\n | string\n | undefined\n /**\n * An optional function to replace nested injectables when creating multiple\n * resources from repeatable sets. Only required if the `resource` param is\n * not a `string`.\n *\n * @param resource The current resource that contains properties that support\n * injection or a string\n * @param prepare A function to prepare the resource string(s) for another\n * iteration\n * @returns\n */\n prepareNestedInjectables?: (\n resource: T,\n preparer: (resourceText: string) => string,\n ) => T\n}): Map<string, T> {\n const newResources: Map<string, T> = new Map<string, T>()\n\n const injectorResult = replaceRootInjectables(\n resource,\n submission,\n formElements,\n )\n if (!injectorResult) {\n return newResources\n }\n\n const [text, resourceKey, newResource] =\n typeof injectorResult === 'string'\n ? [injectorResult, injectorResult, injectorResult as T]\n : injectorResult\n\n // Find nested form elements\n const matches: Map<string, boolean> = new Map()\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: false,\n },\n ({ elementName }) => {\n const [repeatableSetElementName, ...elementNames] = elementName.split('|')\n matches.set(repeatableSetElementName, !!elementNames.length)\n },\n )\n\n if (matches.size) {\n matches.forEach((hasNestedFormElements, repeatableSetElementName) => {\n if (hasNestedFormElements) {\n // Attempt to create a new resource for each entry in the repeatable set.\n const entries = submission?.[repeatableSetElementName]\n if (Array.isArray(entries)) {\n const repeatableSetElement = findFormElement(\n formElements,\n (formElement) => {\n return (\n 'name' in formElement &&\n formElement.name === repeatableSetElementName\n )\n },\n )\n if (\n repeatableSetElement &&\n 'elements' in repeatableSetElement &&\n Array.isArray(repeatableSetElement.elements)\n ) {\n for (const entry of entries) {\n const replacedResource = prepareNestedInjectables(\n newResource,\n (resourceText) => {\n return resourceText.replaceAll(\n `{ELEMENT:${repeatableSetElementName}|`,\n '{ELEMENT:',\n )\n },\n )\n const nestedResources = processInjectablesInCustomResource<T>({\n resource: replacedResource,\n submission: entry,\n formElements: repeatableSetElement.elements,\n replaceRootInjectables,\n prepareNestedInjectables,\n })\n if (nestedResources.size) {\n nestedResources.forEach((nestedResource, nestedResourceKey) => {\n if (!newResources.has(nestedResourceKey)) {\n newResources.set(nestedResourceKey, nestedResource)\n }\n })\n }\n }\n }\n }\n }\n })\n }\n\n // Find nested form elements using ELEMENT_VALUE:\n const valueMatches: Map<string, boolean> = new Map()\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: false,\n useSubmissionValue: true,\n },\n ({ elementName }) => {\n const [repeatableSetElementName, ...elementNames] = elementName.split('|')\n valueMatches.set(repeatableSetElementName, !!elementNames.length)\n },\n )\n\n if (valueMatches.size) {\n valueMatches.forEach((hasNestedFormElements, repeatableSetElementName) => {\n if (hasNestedFormElements) {\n // Attempt to create a new resource for each entry in the repeatable set.\n const entries = submission?.[repeatableSetElementName]\n if (Array.isArray(entries)) {\n const repeatableSetElement = findFormElement(\n formElements,\n (formElement) => {\n return (\n 'name' in formElement &&\n formElement.name === repeatableSetElementName\n )\n },\n )\n if (\n repeatableSetElement &&\n 'elements' in repeatableSetElement &&\n Array.isArray(repeatableSetElement.elements)\n ) {\n for (const entry of entries) {\n const replacedResource = prepareNestedInjectables(\n newResource,\n (resourceText) => {\n return resourceText.replaceAll(\n `{ELEMENT_VALUE:${repeatableSetElementName}|`,\n '{ELEMENT_VALUE:',\n )\n },\n )\n const nestedResources = processInjectablesInCustomResource<T>({\n resource: replacedResource,\n submission: entry,\n formElements: repeatableSetElement.elements,\n replaceRootInjectables,\n prepareNestedInjectables,\n })\n if (nestedResources.size) {\n nestedResources.forEach((nestedResource, nestedResourceKey) => {\n if (!newResources.has(nestedResourceKey)) {\n newResources.set(nestedResourceKey, nestedResource)\n }\n })\n }\n }\n }\n }\n }\n })\n }\n\n if (!matches.size && !valueMatches.size) {\n newResources.set(resourceKey, newResource)\n }\n\n return newResources\n}\n"]}
|
|
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 GoogleTypes,\n MiscTypes,\n PointTypes,\n ScheduledTasksTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { getABNNumberFromABNRecord } from './abnService.js'\nimport {\n RootElementRegex,\n NestedElementRegex,\n matchElementsTagRegex,\n RootSubmissionValueElementRegex,\n NestedSubmissionValueElementRegex,\n} from './form-elements-regex.js'\nimport { findFormElement, flattenFormElements } from './formElementsService.js'\n\nexport type ReplaceInjectablesFormatters = {\n /** A function to format any date/times. */\n formatDateTime: (value: string) => string\n /** A function to format any dates. */\n formatDate: (value: string) => string\n /** A function to format any times. */\n formatTime: (value: string) => string\n /** A function to format any numbers. */\n formatNumber: (value: number) => string\n /** A function to format any numbers as currency. */\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 propertyName,\n submission,\n formElements,\n useSubmissionValue,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n propertyName: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined\nexport function getElementSubmissionValue({\n elementId,\n submission,\n formElements,\n useSubmissionValue,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n elementId: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined\nexport function getElementSubmissionValue({\n elementId,\n propertyName,\n submission,\n formElements,\n useSubmissionValue,\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 useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters) {\n if (elementId === undefined && propertyName === undefined) {\n return undefined\n }\n\n let result: ReturnType<typeof getElementSubmissionValueByName> | undefined =\n undefined\n if (elementId) {\n result = getElementSubmissionValueById({\n elementId,\n formElements,\n submission,\n })\n } else if (propertyName) {\n result = getElementSubmissionValueByName({\n propertyName,\n formElements,\n submission,\n })\n }\n if (!result) {\n return\n }\n return formatValue({\n element: result.formElement,\n unknownValue: result.unknownValue,\n useSubmissionValue,\n formatDate,\n formatTime,\n formatDateTime,\n formatCurrency,\n formatNumber,\n })\n}\n\nfunction getElementSubmissionValueByName({\n propertyName,\n formElements,\n submission,\n}: {\n propertyName: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}):\n | { formElement: FormTypes.FormElement | undefined; unknownValue: unknown }\n | undefined {\n const unknownValue = submission[propertyName]\n if (unknownValue === undefined || unknownValue === null) {\n return undefined\n }\n\n const formElement = findFormElement(\n formElements,\n (element) =>\n element.type !== 'page' &&\n element.type !== 'section' &&\n element.name === propertyName,\n )\n\n return { formElement, unknownValue }\n}\n\nfunction getElementSubmissionValueById({\n elementId,\n formElements,\n submission,\n}: {\n elementId: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): { formElement: FormTypes.FormElement; unknownValue: unknown } | undefined {\n // make sure submission is an object\n if (Object(submission) !== submission) {\n return undefined\n }\n const flattenedElements = flattenFormElements(formElements)\n\n let unknown: unknown = undefined\n let formElement: FormTypes.FormElement | undefined = undefined\n for (const element of flattenedElements) {\n if (elementId === element.id) {\n if ('name' in element) {\n unknown = submission[element.name]\n formElement = element\n }\n break\n }\n if (element.type === 'form') {\n const newSubmissionData = submission[element.name]\n\n const result = getElementSubmissionValueById({\n elementId,\n formElements: element.elements ?? [],\n submission:\n newSubmissionData as SubmissionTypes.S3SubmissionData['submission'],\n })\n if (result) {\n unknown = result.unknownValue\n formElement = result.formElement\n break\n }\n }\n }\n if (unknown === undefined || unknown === null || formElement === undefined) {\n return undefined\n }\n\n return { unknownValue: unknown, formElement }\n}\n\nfunction formatValue({\n element,\n unknownValue,\n useSubmissionValue,\n formatDate,\n formatTime,\n formatDateTime,\n formatCurrency,\n formatNumber,\n}: {\n element: FormTypes.FormElement | undefined\n unknownValue: unknown\n useSubmissionValue?: boolean\n} & ReplaceInjectablesFormatters) {\n switch (element?.type) {\n case 'datetime': {\n const value = unknownValue as string\n return { element: element, value: formatDateTime(value) }\n }\n case 'date': {\n const value = unknownValue as string\n return { element: element, value: formatDate(value) }\n }\n case 'time': {\n const value = unknownValue as string\n return { element: element, value: formatTime(value) }\n }\n case 'radio':\n case 'autocomplete': {\n const value = unknownValue as string\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const option = element.options?.find((opt) => opt.value === value)\n return { element: element, value: option?.label || value }\n }\n\n case 'checkboxes': {\n const value = unknownValue as string[]\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const options = element.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: element,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n }\n case 'compliance': {\n const value = unknownValue as {\n value?: string\n }\n if (useSubmissionValue) {\n return { element: element, value: value.value }\n }\n const option = (element.options || []).find(\n (option: FormTypes.ChoiceElementOption) => option.value === value.value,\n )\n return {\n element: element,\n value: {\n ...value,\n value: option?.label || value.value,\n },\n }\n }\n case 'select': {\n if (element.multi) {\n const value = unknownValue as string[]\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const options = element.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: element,\n value: selectedOptionLabels.length ? selectedOptionLabels : undefined,\n }\n } else {\n const value = unknownValue as string\n if (useSubmissionValue) {\n return { element: element, value: value }\n }\n const option = element.options?.find((opt) => opt.value === value)\n return { element: element, value: option?.label }\n }\n }\n case 'boolean': {\n const value = unknownValue as boolean\n return { element: element, value: value ? 'Yes' : 'No' }\n }\n case 'calculation':\n case 'number': {\n const getValue = (value: number) => {\n if (element.displayAsCurrency) {\n return formatCurrency(value)\n }\n if (element.type === 'calculation') {\n return formatNumber(value)\n }\n return value\n }\n\n const value = unknownValue as number\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n const formattedValue = getValue(value)\n return { element, value: formattedValue }\n }\n return undefined\n }\n case 'pointCadastralParcel': {\n const value = unknownValue as PointTypes.PointCadastralParcelResponse\n return {\n element: element,\n value: value?.parcelBundle?.[0]?.parcelId,\n }\n }\n case 'pointAddress':\n case 'geoscapeAddress': {\n const value = unknownValue as\n | PointTypes.PointAddress\n | GeoscapeTypes.GeoscapeAddress\n return {\n element: element,\n value: value?.addressDetails?.formattedAddress || value?.addressId,\n }\n }\n case 'pointAddressV3': {\n const value =\n unknownValue as PointTypes.PointAddressV3GetAddressDetailsResponse\n return {\n element: element,\n value:\n value.properties?.formattedAddress || value.properties?.addressId,\n }\n }\n case 'googleAddress': {\n const value = unknownValue as GoogleTypes.GoogleMapsAddress\n return {\n element: element,\n value: value.formatted_address || value.place_id,\n }\n }\n case 'civicaStreetName': {\n const value = unknownValue as CivicaTypes.CivicaStreetName\n return { element: element, value: value?.formattedStreet }\n }\n case 'civicaNameRecord': {\n const value = unknownValue as CivicaTypes.CivicaNameRecord\n return {\n element: element,\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 = unknownValue as MiscTypes.ABNRecord\n return {\n element: element,\n value: value ? getABNNumberFromABNRecord(value) : undefined,\n }\n }\n case 'apiNSWLiquorLicence': {\n const value = unknownValue as APINSWTypes.LiquorLicenceDetails | undefined\n return {\n element: element,\n value:\n `${value?.licenceDetail?.licenceNumber} | ${value?.licenceDetail?.licenceName}`.trim(),\n }\n }\n case 'freshdeskDependentField': {\n const value =\n unknownValue as FormTypes.FreshdeskDependentFieldElementValue\n return {\n element,\n value:\n [value.category, value.subCategory, value.item]\n .filter((text) => !!text)\n .join(' / ') || undefined,\n }\n }\n default: {\n return { element: element, value: unknownValue }\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 const valueMatchesElement = text.match(\n options.excludeNestedElements\n ? RootSubmissionValueElementRegex\n : NestedSubmissionValueElementRegex,\n )\n if (valueMatchesElement) {\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: !!options.excludeNestedElements,\n useSubmissionValue: true,\n },\n ({ elementName, elementMatch }) => {\n const result = getElementSubmissionValue({\n propertyName: elementName,\n ...options,\n useSubmissionValue: true,\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\n/**\n * Process a resource with injectable element values to turn a single resource\n * (could be a single) into multiple resources. e.g.\n * `\"{ELEMENT:Children|Child_Name} {ELEMENT:Family_Name}\"` with the following\n * submission data:\n *\n * ```json\n * {\n * \"Family_Name\": \"Smith\",\n * \"Children\": [\n * {\n * \"Child_Name\": \"John\"\n * },\n * {\n * \"Child_Name\": \"Jane\"\n * }\n * ]\n * }\n * ```\n *\n * Would result in the following resources:\n *\n * - `\"John Smith\"`\n * - `\"Jane Smith\"`\n *\n * #### Example\n *\n * ```js\n * const emailAddresses = processInjectablesInCustomResource({\n * resource: '{ELEMENT:People|Email_Address}',\n * submission: {\n * People: [\n * {\n * Email_Address: 'user@oneblink.io',\n * },\n * {\n * Email_Address: 'admin@oneblink.io',\n * },\n * ],\n * },\n * formElements: [\n * {\n * id: '18dcd3e0-6e2f-462e-803b-e24562d9fa6d',\n * type: 'repeatableSet',\n * name: 'People',\n * label: 'People',\n * elements: [\n * {\n * id: 'd0902113-3f77-4070-adbd-ca3ae95ce091',\n * type: 'email',\n * name: 'Email_Address',\n * label: 'Email_Address',\n * },\n * ],\n * },\n * ],\n * replaceRootInjectables: (resource, submission, formElements) => {\n * const { text } = replaceInjectablesWithElementValues(resource, {\n * submission,\n * formElements,\n * excludeNestedElements: true,\n * // other options\n * })\n * return text\n * },\n * })\n * // emailAddresses === [\"user@oneblink.io\", \"admin@oneblink.io\"]\n * ```\n *\n * @param options\n * @returns\n */\nexport function processInjectablesInCustomResource<T>({\n resource,\n submission,\n formElements,\n replaceRootInjectables,\n prepareNestedInjectables = (resource, prepare) =>\n prepare(String(resource)) as T,\n}: {\n /** The resource that contains properties that support injection or a string */\n resource: T\n /** The form submission data to process */\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** The form elements to process */\n formElements: FormTypes.FormElement[]\n /**\n * A function to inject values, this allows custom formatters to be used.\n * Return `undefined` to prevent the injection from recursively continuing.\n *\n * @param resource The current resource that contains properties that support\n * injection or a string\n * @param submission The current form submission data to process (may be an\n * entry in a repeatable set)\n * @param formElements The current form elements to process (may be the\n * elements from a repeatable set)\n * @returns\n */\n replaceRootInjectables: (\n resource: T,\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElements: FormTypes.FormElement[],\n ) =>\n | [injectedText: string, resourceKey: string, newResource: T]\n | string\n | undefined\n /**\n * An optional function to replace nested injectables when creating multiple\n * resources from repeatable sets. Only required if the `resource` param is\n * not a `string`.\n *\n * @param resource The current resource that contains properties that support\n * injection or a string\n * @param prepare A function to prepare the resource string(s) for another\n * iteration\n * @returns\n */\n prepareNestedInjectables?: (\n resource: T,\n preparer: (resourceText: string) => string,\n ) => T\n}): Map<string, T> {\n const newResources: Map<string, T> = new Map<string, T>()\n\n const injectorResult = replaceRootInjectables(\n resource,\n submission,\n formElements,\n )\n if (!injectorResult) {\n return newResources\n }\n\n const [text, resourceKey, newResource] =\n typeof injectorResult === 'string'\n ? [injectorResult, injectorResult, injectorResult as T]\n : injectorResult\n\n // Find nested form elements\n const matches: Map<string, boolean> = new Map()\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: false,\n },\n ({ elementName }) => {\n const [repeatableSetElementName, ...elementNames] = elementName.split('|')\n matches.set(repeatableSetElementName, !!elementNames.length)\n },\n )\n\n if (matches.size) {\n matches.forEach((hasNestedFormElements, repeatableSetElementName) => {\n if (hasNestedFormElements) {\n // Attempt to create a new resource for each entry in the repeatable set.\n const entries = submission?.[repeatableSetElementName]\n if (Array.isArray(entries)) {\n const repeatableSetElement = findFormElement(\n formElements,\n (formElement) => {\n return (\n 'name' in formElement &&\n formElement.name === repeatableSetElementName\n )\n },\n )\n if (\n repeatableSetElement &&\n 'elements' in repeatableSetElement &&\n Array.isArray(repeatableSetElement.elements)\n ) {\n for (const entry of entries) {\n const replacedResource = prepareNestedInjectables(\n newResource,\n (resourceText) => {\n return resourceText.replaceAll(\n `{ELEMENT:${repeatableSetElementName}|`,\n '{ELEMENT:',\n )\n },\n )\n const nestedResources = processInjectablesInCustomResource<T>({\n resource: replacedResource,\n submission: entry,\n formElements: repeatableSetElement.elements,\n replaceRootInjectables,\n prepareNestedInjectables,\n })\n if (nestedResources.size) {\n nestedResources.forEach((nestedResource, nestedResourceKey) => {\n if (!newResources.has(nestedResourceKey)) {\n newResources.set(nestedResourceKey, nestedResource)\n }\n })\n }\n }\n }\n }\n }\n })\n }\n\n // Find nested form elements using ELEMENT_VALUE:\n const valueMatches: Map<string, boolean> = new Map()\n matchElementsTagRegex(\n {\n text,\n excludeNestedElements: false,\n useSubmissionValue: true,\n },\n ({ elementName }) => {\n const [repeatableSetElementName, ...elementNames] = elementName.split('|')\n valueMatches.set(repeatableSetElementName, !!elementNames.length)\n },\n )\n\n if (valueMatches.size) {\n valueMatches.forEach((hasNestedFormElements, repeatableSetElementName) => {\n if (hasNestedFormElements) {\n // Attempt to create a new resource for each entry in the repeatable set.\n const entries = submission?.[repeatableSetElementName]\n if (Array.isArray(entries)) {\n const repeatableSetElement = findFormElement(\n formElements,\n (formElement) => {\n return (\n 'name' in formElement &&\n formElement.name === repeatableSetElementName\n )\n },\n )\n if (\n repeatableSetElement &&\n 'elements' in repeatableSetElement &&\n Array.isArray(repeatableSetElement.elements)\n ) {\n for (const entry of entries) {\n const replacedResource = prepareNestedInjectables(\n newResource,\n (resourceText) => {\n return resourceText.replaceAll(\n `{ELEMENT_VALUE:${repeatableSetElementName}|`,\n '{ELEMENT_VALUE:',\n )\n },\n )\n const nestedResources = processInjectablesInCustomResource<T>({\n resource: replacedResource,\n submission: entry,\n formElements: repeatableSetElement.elements,\n replaceRootInjectables,\n prepareNestedInjectables,\n })\n if (nestedResources.size) {\n nestedResources.forEach((nestedResource, nestedResourceKey) => {\n if (!newResources.has(nestedResourceKey)) {\n newResources.set(nestedResourceKey, nestedResource)\n }\n })\n }\n }\n }\n }\n }\n })\n }\n\n if (!matches.size && !valueMatches.size) {\n newResources.set(resourceKey, newResource)\n }\n\n return newResources\n}\n"]}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkForSchedulingEvent = checkForSchedulingEvent;
|
|
4
|
-
const _1 = require(".");
|
|
1
|
+
import { conditionalLogicService } from './index.js';
|
|
5
2
|
/**
|
|
6
3
|
* Examine a submission and its form definition to validate whether a scheduling
|
|
7
4
|
* workflow event needs to run.
|
|
@@ -19,9 +16,9 @@ const _1 = require(".");
|
|
|
19
16
|
* @param submission
|
|
20
17
|
* @returns
|
|
21
18
|
*/
|
|
22
|
-
function checkForSchedulingEvent(definition, submission) {
|
|
19
|
+
export function checkForSchedulingEvent(definition, submission) {
|
|
23
20
|
const schedulingSubmissionEvents = definition.schedulingEvents || [];
|
|
24
|
-
return schedulingSubmissionEvents.find((schedulingSubmissionEvent) =>
|
|
21
|
+
return schedulingSubmissionEvents.find((schedulingSubmissionEvent) => conditionalLogicService.evaluateConditionalPredicates({
|
|
25
22
|
isConditional: !!schedulingSubmissionEvent.conditionallyExecute,
|
|
26
23
|
requiresAllConditionalPredicates: !!schedulingSubmissionEvent.requiresAllConditionallyExecutePredicates,
|
|
27
24
|
conditionalPredicates: schedulingSubmissionEvent.conditionallyExecutePredicates || [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedulingService.js","sourceRoot":"","sources":["../src/schedulingService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schedulingService.js","sourceRoot":"","sources":["../src/schedulingService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA0B,EAC1B,UAA0D;IAE1D,MAAM,0BAA0B,GAAG,UAAU,CAAC,gBAAgB,IAAI,EAAE,CAAA;IACpE,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,yBAAyB,EAAE,EAAE,CACnE,uBAAuB,CAAC,6BAA6B,CAAC;QACpD,aAAa,EAAE,CAAC,CAAC,yBAAyB,CAAC,oBAAoB;QAC/D,gCAAgC,EAC9B,CAAC,CAAC,yBAAyB,CAAC,yCAAyC;QACvE,qBAAqB,EACnB,yBAAyB,CAAC,8BAA8B,IAAI,EAAE;QAChE,UAAU,EAAE,UAAU;QACtB,YAAY,EAAE,UAAU,CAAC,QAAQ;KAClC,CAAC,CACH,CAAA;AACH,CAAC","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n} from '@oneblink/types'\nimport { conditionalLogicService } from './index.js'\n\n/**\n * Examine a submission and its form definition to validate whether a scheduling\n * workflow event needs to run.\n *\n * #### Example\n *\n * ```js\n * const result = schedulingService.checkFormSchedulingEvent(\n * form,\n * submission,\n * )\n * ```\n *\n * @param definition\n * @param submission\n * @returns\n */\nexport function checkForSchedulingEvent(\n definition: FormTypes.Form,\n submission: SubmissionTypes.S3SubmissionData['submission'],\n): SubmissionEventTypes.FormSchedulingEvent | undefined {\n const schedulingSubmissionEvents = definition.schedulingEvents || []\n return schedulingSubmissionEvents.find((schedulingSubmissionEvent) =>\n conditionalLogicService.evaluateConditionalPredicates({\n isConditional: !!schedulingSubmissionEvent.conditionallyExecute,\n requiresAllConditionalPredicates:\n !!schedulingSubmissionEvent.requiresAllConditionallyExecutePredicates,\n conditionalPredicates:\n schedulingSubmissionEvent.conditionallyExecutePredicates || [],\n submission: submission,\n formElements: definition.elements,\n }),\n )\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColumnDefinition } from '@microsoft/microsoft-graph-types';
|
|
2
2
|
import { SubmissionEventTypes } from '@oneblink/types';
|
|
3
|
-
import { ResourceDefinition } from './types/resource-definitions';
|
|
3
|
+
import { ResourceDefinition } from './types/resource-definitions.js';
|
|
4
4
|
export type SharepointColumnResourceDefinition = ResourceDefinition<SubmissionEventTypes.SharepointColumnResourceDefinitionBase>;
|
|
5
5
|
export declare function generateSharepointColumnResourceDefinitions(columnDefinitions: ColumnDefinition[]): SharepointColumnResourceDefinition[];
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateSharepointColumnResourceDefinitions = generateSharepointColumnResourceDefinitions;
|
|
4
|
-
function generateSharepointColumnResourceDefinitions(columnDefinitions) {
|
|
1
|
+
export function generateSharepointColumnResourceDefinitions(columnDefinitions) {
|
|
5
2
|
return columnDefinitions.reduce((memo, columnDefinition) => {
|
|
6
|
-
var _a, _b, _c, _d;
|
|
7
3
|
if (!columnDefinition.readOnly &&
|
|
8
4
|
columnDefinition.columnGroup !== '_Hidden' &&
|
|
9
5
|
columnDefinition.name &&
|
|
10
6
|
columnDefinition.id &&
|
|
11
7
|
columnDefinition.displayName) {
|
|
12
|
-
if (
|
|
8
|
+
if (columnDefinition.text?.allowMultipleLines) {
|
|
13
9
|
memo.push({
|
|
14
10
|
id: columnDefinition.id,
|
|
15
11
|
isRequired: false,
|
|
@@ -27,7 +23,7 @@ function generateSharepointColumnResourceDefinitions(columnDefinitions) {
|
|
|
27
23
|
type: 'TEXT_SINGLE_LINE',
|
|
28
24
|
});
|
|
29
25
|
}
|
|
30
|
-
else if (
|
|
26
|
+
else if (columnDefinition.choice?.choices?.length) {
|
|
31
27
|
memo.push({
|
|
32
28
|
id: columnDefinition.id,
|
|
33
29
|
isRequired: false,
|
|
@@ -40,7 +36,7 @@ function generateSharepointColumnResourceDefinitions(columnDefinitions) {
|
|
|
40
36
|
})),
|
|
41
37
|
});
|
|
42
38
|
}
|
|
43
|
-
else if (
|
|
39
|
+
else if (columnDefinition.dateTime?.format === 'dateOnly') {
|
|
44
40
|
memo.push({
|
|
45
41
|
id: columnDefinition.id,
|
|
46
42
|
isRequired: false,
|