@oneblink/sdk-core 6.0.0 → 6.0.1-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.
@@ -57,7 +57,7 @@ declare function forEachFormElementWithOptions(elements: FormTypes.FormElement[]
57
57
  * @param parentElements
58
58
  * @returns
59
59
  */
60
- declare function findFormElement(elements: FormTypes.FormElement[], predicate: (element: FormTypes.FormElement, elements: FormTypes.FormElement[]) => boolean, parentElements?: FormTypes.FormElement[]): FormTypes.FormElement | void;
60
+ declare function findFormElement(elements: FormTypes.FormElement[], predicate: (element: FormTypes.FormElement, elements: FormTypes.FormElement[]) => boolean, parentElements?: FormTypes.FormElement[]): FormTypes.FormElement | undefined;
61
61
  /**
62
62
  * Parse unknown data as valid dynamic options for a forms element. This will
63
63
  * always return an Array of valid dynamic options.
@@ -1 +1 @@
1
- {"version":3,"file":"formElementsService.js","sourceRoot":"","sources":["../src/formElementsService.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { typeCastService } from '.'\nimport {\n Form,\n FormElement,\n HtmlElement,\n} from '@oneblink/types/typescript/forms'\nexport { matchElementsTagRegex } from './form-elements-regex'\n\n/**\n * Iterate over all form elements, also iterating over nested form element (e.g.\n * page elements).\n *\n * #### Example\n *\n * ```js\n * formElementsService.forEachFormElement(form.elements, (formElement) => {\n * // do something with formElement\n * })\n * ```\n *\n * @param elements The form elements to iterate over\n * @param forEach Function to execute on each form element\n */\nfunction forEachFormElement(\n elements: FormTypes.FormElement[],\n forEach: (\n element: FormTypes.FormElement,\n elements: FormTypes.FormElement[],\n ) => void,\n): void {\n findFormElement(elements, (formElement, parentElements) => {\n forEach(formElement, parentElements)\n return false\n })\n}\n\n/**\n * Iterate over all form elements that have options (e.g. `'select'` type\n * elements), also iterating over nested form element (e.g. page elements).\n *\n * #### Example\n *\n * ```js\n * formElementsService.forEachFormElementWithOptions(\n * form.elements,\n * (formElementWithOptions) => {\n * // do something with formElementWithOptions\n * },\n * )\n * ```\n *\n * @param elements The form elements to iterate over\n * @param forEach Function to execute on each form element with options\n */\nfunction forEachFormElementWithOptions(\n elements: FormTypes.FormElement[],\n forEach: (\n elementWithOptions: FormTypes.FormElementWithOptions,\n elements: FormTypes.FormElement[],\n ) => void,\n): void {\n findFormElement(elements, (formElement, parentElements) => {\n const optionsFormElement =\n typeCastService.formElements.toOptionsElement(formElement)\n if (optionsFormElement) {\n forEach(optionsFormElement, parentElements)\n }\n return false\n })\n}\n\n/**\n * Iterate over all form elements and return an element that matches a\n * predicate, also iterating over nested form element (e.g. page elements). Will\n * return `undefined` if no matching element is found.\n *\n * #### Example\n *\n * ```js\n * const formElement = formElementsService.findFormElement(\n * form.elements,\n * (formElement) => {\n * return formElement.id === '123-abc'\n * },\n * )\n * ```\n *\n * @param elements The form elements to iterate over\n * @param predicate Predicate function to execute on each form element\n * @param parentElements\n * @returns\n */\nfunction findFormElement(\n elements: FormTypes.FormElement[],\n predicate: (\n element: FormTypes.FormElement,\n elements: FormTypes.FormElement[],\n ) => boolean,\n parentElements: FormTypes.FormElement[] = [],\n): FormTypes.FormElement | void {\n for (const element of elements) {\n if (predicate(element, parentElements)) {\n return element\n }\n\n if (\n (element.type === 'repeatableSet' ||\n element.type === 'page' ||\n element.type === 'form' ||\n element.type === 'infoPage' ||\n element.type === 'section') &&\n Array.isArray(element.elements)\n ) {\n const nestedElement = findFormElement(element.elements, predicate, [\n ...parentElements,\n element,\n ])\n\n if (nestedElement) {\n return nestedElement\n }\n }\n }\n}\n\n/**\n * Parse unknown data as valid dynamic options for a forms element. This will\n * always return an Array of valid dynamic options.\n *\n * #### Example\n *\n * ```js\n * const options = formElementsService.parseDynamicFormElementOptions(data)\n * // \"options\" are valid for a form element\n * ```\n *\n * @param data\n * @returns\n */\nfunction parseDynamicFormElementOptions(\n data: unknown,\n): FormTypes.DynamicChoiceElementOption[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.reduce<FormTypes.DynamicChoiceElementOption[]>(\n (options, record, index) => {\n if (typeof record === 'string') {\n options.push({\n value: record,\n label: record,\n })\n } else if (typeof record === 'object') {\n const option = record as Record<string, unknown>\n const value =\n typeof option.value === 'string' && option.value\n ? option.value\n : index.toString()\n const label =\n typeof option.label === 'string' && option.label\n ? option.label\n : value\n const colour =\n typeof option.colour === 'string' && option.colour\n ? option.colour\n : undefined\n const displayAlways =\n typeof option.displayAlways === 'boolean'\n ? option.displayAlways\n : undefined\n const attributes = Array.isArray(option.attributes)\n ? option.attributes.reduce<\n FormTypes.DynamicChoiceElementOptionAttribute[]\n >((memo, attribute: unknown) => {\n if (\n typeof attribute === 'object' &&\n attribute &&\n 'value' in attribute &&\n typeof attribute.value === 'string' &&\n 'label' in attribute &&\n typeof attribute.label === 'string'\n ) {\n memo.push({\n value: attribute.value,\n label: attribute.label,\n })\n }\n return memo\n }, [])\n : undefined\n options.push({\n value,\n label,\n colour,\n attributes,\n displayAlways,\n options: Array.isArray(option.options)\n ? parseDynamicFormElementOptions(option.options)\n : undefined,\n })\n }\n return options\n },\n [],\n )\n}\n\n/**\n * Takes the nested definition structure and returns all form elements as 1d\n * array.\n *\n * #### Example\n *\n * ```js\n * const flattenedElements = formElementsService.flattenFormElements(\n * form.elements,\n * )\n * ```\n *\n * @param elements\n * @returns\n */\nfunction flattenFormElements(\n elements: FormTypes.FormElement[],\n): FormTypes.FormElement[] {\n return elements.reduce<FormTypes.FormElement[]>(\n (flattenedElements, element) => {\n flattenedElements.push(element)\n switch (element.type) {\n case 'section':\n case 'page': {\n flattenedElements.push(...flattenFormElements(element.elements))\n }\n }\n return flattenedElements\n },\n [],\n )\n}\n\nconst infoPageElements: FormTypes.FormElementType[] = [\n 'heading',\n 'html',\n 'image',\n 'section',\n 'page',\n 'infoPage',\n 'form',\n 'arcGISWebMap',\n]\n/**\n * Determine a form is considered an info page. This means the form does not\n * allow any user input.\n *\n * @param form\n * @returns\n */\nfunction determineIsInfoPage(form: FormTypes.Form): boolean {\n const foundInputElement = findFormElement(form.elements, (e) => {\n return !infoPageElements.includes(e.type)\n })\n return !foundInputElement\n}\n\n/**\n * Remove invalid characters from a form element name.\n *\n * @param elementName\n * @returns\n */\nconst fixElementName = (elementName: string) => {\n // removes characters that aren't letters, numbers, underscores or dashes\n // replaces empty spaces with _\n return elementName\n .replace(/[^-\\w\\s]/g, '')\n .replace(/\\s/g, '_')\n .trim()\n}\n\n/**\n * Injects the elements of any elements with type `FORM` or `INFOPAGE` into the\n * form\n *\n * @param form The form to inject elements into\n * @param forms The forms that will be used to inject elements from if\n * referenced\n * @param injectAuthenticatedForms Indicates whether forms requiring\n * authentication should be injected, defaults to true\n * @returns\n */\nfunction injectFormElementsIntoForm(\n form: Form,\n forms: Form[],\n injectAuthenticatedForms = true,\n): FormElement[] {\n const elementsWithInjectedForms = injectFormElements(\n form.elements,\n forms,\n [form.id],\n injectAuthenticatedForms,\n )\n form.elements = elementsWithInjectedForms\n return form.elements\n}\n\nfunction injectFormElements(\n elements: FormElement[],\n forms: Form[],\n parentIds: number[],\n injectAuthenticatedForms: boolean,\n): FormElement[] {\n return elements.reduce<FormElement[]>((newElements, element) => {\n if (\n (element.type === 'page' ||\n element.type === 'repeatableSet' ||\n element.type === 'section') &&\n Array.isArray(element.elements)\n ) {\n const childElements = injectFormElements(\n element.elements,\n forms,\n parentIds,\n injectAuthenticatedForms,\n )\n element.elements = childElements\n }\n\n if (element.type === 'form' || element.type === 'infoPage') {\n const formToInject = forms.find((form) => element.formId === form.id)\n\n if (!formToInject) {\n const newElement: HtmlElement = {\n ...element,\n type: 'html',\n name: 'Form_not_found',\n label: 'Form not found.',\n defaultValue:\n 'Unable to display the embedded form for this element, as the form was not found. Please contact your Administrator.',\n }\n newElements.push(newElement)\n return newElements\n }\n\n if (formToInject.isAuthenticated && !injectAuthenticatedForms) {\n console.log(\n `No form elements injected for element id: ${element.id}, as request was unauthenticated and target form (form id: ${formToInject.id}) requires authentication.`,\n )\n\n const newElement: HtmlElement = {\n ...element,\n type: 'html',\n name: 'Form_requires_authenticated',\n label: 'Form Requires Authentication.',\n defaultValue:\n 'Unable to display the embedded form for this element, as the form requires authentication. Please login and refresh to view this embedded form.',\n }\n newElements.push(newElement)\n return newElements\n }\n\n const injectingParentForm =\n parentIds && parentIds.find((id) => element.formId === id)\n\n if (injectingParentForm) {\n console.log(\n `Infinite loop was detected while attempting to inject form id: ${injectingParentForm}. Ignoring elements...`,\n )\n return newElements\n }\n\n element.elements = injectFormElements(\n formToInject.elements,\n forms,\n [...parentIds, formToInject.id],\n injectAuthenticatedForms,\n )\n newElements.push(element)\n } else {\n newElements.push(element)\n }\n\n return newElements\n }, [])\n}\n\nexport {\n forEachFormElement,\n forEachFormElementWithOptions,\n findFormElement,\n parseDynamicFormElementOptions,\n flattenFormElements,\n determineIsInfoPage,\n fixElementName,\n injectFormElementsIntoForm,\n}\n"]}
1
+ {"version":3,"file":"formElementsService.js","sourceRoot":"","sources":["../src/formElementsService.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { typeCastService } from '.'\nimport {\n Form,\n FormElement,\n HtmlElement,\n} from '@oneblink/types/typescript/forms'\nexport { matchElementsTagRegex } from './form-elements-regex'\n\n/**\n * Iterate over all form elements, also iterating over nested form element (e.g.\n * page elements).\n *\n * #### Example\n *\n * ```js\n * formElementsService.forEachFormElement(form.elements, (formElement) => {\n * // do something with formElement\n * })\n * ```\n *\n * @param elements The form elements to iterate over\n * @param forEach Function to execute on each form element\n */\nfunction forEachFormElement(\n elements: FormTypes.FormElement[],\n forEach: (\n element: FormTypes.FormElement,\n elements: FormTypes.FormElement[],\n ) => void,\n): void {\n findFormElement(elements, (formElement, parentElements) => {\n forEach(formElement, parentElements)\n return false\n })\n}\n\n/**\n * Iterate over all form elements that have options (e.g. `'select'` type\n * elements), also iterating over nested form element (e.g. page elements).\n *\n * #### Example\n *\n * ```js\n * formElementsService.forEachFormElementWithOptions(\n * form.elements,\n * (formElementWithOptions) => {\n * // do something with formElementWithOptions\n * },\n * )\n * ```\n *\n * @param elements The form elements to iterate over\n * @param forEach Function to execute on each form element with options\n */\nfunction forEachFormElementWithOptions(\n elements: FormTypes.FormElement[],\n forEach: (\n elementWithOptions: FormTypes.FormElementWithOptions,\n elements: FormTypes.FormElement[],\n ) => void,\n): void {\n findFormElement(elements, (formElement, parentElements) => {\n const optionsFormElement =\n typeCastService.formElements.toOptionsElement(formElement)\n if (optionsFormElement) {\n forEach(optionsFormElement, parentElements)\n }\n return false\n })\n}\n\n/**\n * Iterate over all form elements and return an element that matches a\n * predicate, also iterating over nested form element (e.g. page elements). Will\n * return `undefined` if no matching element is found.\n *\n * #### Example\n *\n * ```js\n * const formElement = formElementsService.findFormElement(\n * form.elements,\n * (formElement) => {\n * return formElement.id === '123-abc'\n * },\n * )\n * ```\n *\n * @param elements The form elements to iterate over\n * @param predicate Predicate function to execute on each form element\n * @param parentElements\n * @returns\n */\nfunction findFormElement(\n elements: FormTypes.FormElement[],\n predicate: (\n element: FormTypes.FormElement,\n elements: FormTypes.FormElement[],\n ) => boolean,\n parentElements: FormTypes.FormElement[] = [],\n): FormTypes.FormElement | undefined {\n for (const element of elements) {\n if (predicate(element, parentElements)) {\n return element\n }\n\n if (\n (element.type === 'repeatableSet' ||\n element.type === 'page' ||\n element.type === 'form' ||\n element.type === 'infoPage' ||\n element.type === 'section') &&\n Array.isArray(element.elements)\n ) {\n const nestedElement = findFormElement(element.elements, predicate, [\n ...parentElements,\n element,\n ])\n\n if (nestedElement) {\n return nestedElement\n }\n }\n }\n}\n\n/**\n * Parse unknown data as valid dynamic options for a forms element. This will\n * always return an Array of valid dynamic options.\n *\n * #### Example\n *\n * ```js\n * const options = formElementsService.parseDynamicFormElementOptions(data)\n * // \"options\" are valid for a form element\n * ```\n *\n * @param data\n * @returns\n */\nfunction parseDynamicFormElementOptions(\n data: unknown,\n): FormTypes.DynamicChoiceElementOption[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.reduce<FormTypes.DynamicChoiceElementOption[]>(\n (options, record, index) => {\n if (typeof record === 'string') {\n options.push({\n value: record,\n label: record,\n })\n } else if (typeof record === 'object') {\n const option = record as Record<string, unknown>\n const value =\n typeof option.value === 'string' && option.value\n ? option.value\n : index.toString()\n const label =\n typeof option.label === 'string' && option.label\n ? option.label\n : value\n const colour =\n typeof option.colour === 'string' && option.colour\n ? option.colour\n : undefined\n const displayAlways =\n typeof option.displayAlways === 'boolean'\n ? option.displayAlways\n : undefined\n const attributes = Array.isArray(option.attributes)\n ? option.attributes.reduce<\n FormTypes.DynamicChoiceElementOptionAttribute[]\n >((memo, attribute: unknown) => {\n if (\n typeof attribute === 'object' &&\n attribute &&\n 'value' in attribute &&\n typeof attribute.value === 'string' &&\n 'label' in attribute &&\n typeof attribute.label === 'string'\n ) {\n memo.push({\n value: attribute.value,\n label: attribute.label,\n })\n }\n return memo\n }, [])\n : undefined\n options.push({\n value,\n label,\n colour,\n attributes,\n displayAlways,\n options: Array.isArray(option.options)\n ? parseDynamicFormElementOptions(option.options)\n : undefined,\n })\n }\n return options\n },\n [],\n )\n}\n\n/**\n * Takes the nested definition structure and returns all form elements as 1d\n * array.\n *\n * #### Example\n *\n * ```js\n * const flattenedElements = formElementsService.flattenFormElements(\n * form.elements,\n * )\n * ```\n *\n * @param elements\n * @returns\n */\nfunction flattenFormElements(\n elements: FormTypes.FormElement[],\n): FormTypes.FormElement[] {\n return elements.reduce<FormTypes.FormElement[]>(\n (flattenedElements, element) => {\n flattenedElements.push(element)\n switch (element.type) {\n case 'section':\n case 'page': {\n flattenedElements.push(...flattenFormElements(element.elements))\n }\n }\n return flattenedElements\n },\n [],\n )\n}\n\nconst infoPageElements: FormTypes.FormElementType[] = [\n 'heading',\n 'html',\n 'image',\n 'section',\n 'page',\n 'infoPage',\n 'form',\n 'arcGISWebMap',\n]\n/**\n * Determine a form is considered an info page. This means the form does not\n * allow any user input.\n *\n * @param form\n * @returns\n */\nfunction determineIsInfoPage(form: FormTypes.Form): boolean {\n const foundInputElement = findFormElement(form.elements, (e) => {\n return !infoPageElements.includes(e.type)\n })\n return !foundInputElement\n}\n\n/**\n * Remove invalid characters from a form element name.\n *\n * @param elementName\n * @returns\n */\nconst fixElementName = (elementName: string) => {\n // removes characters that aren't letters, numbers, underscores or dashes\n // replaces empty spaces with _\n return elementName\n .replace(/[^-\\w\\s]/g, '')\n .replace(/\\s/g, '_')\n .trim()\n}\n\n/**\n * Injects the elements of any elements with type `FORM` or `INFOPAGE` into the\n * form\n *\n * @param form The form to inject elements into\n * @param forms The forms that will be used to inject elements from if\n * referenced\n * @param injectAuthenticatedForms Indicates whether forms requiring\n * authentication should be injected, defaults to true\n * @returns\n */\nfunction injectFormElementsIntoForm(\n form: Form,\n forms: Form[],\n injectAuthenticatedForms = true,\n): FormElement[] {\n const elementsWithInjectedForms = injectFormElements(\n form.elements,\n forms,\n [form.id],\n injectAuthenticatedForms,\n )\n form.elements = elementsWithInjectedForms\n return form.elements\n}\n\nfunction injectFormElements(\n elements: FormElement[],\n forms: Form[],\n parentIds: number[],\n injectAuthenticatedForms: boolean,\n): FormElement[] {\n return elements.reduce<FormElement[]>((newElements, element) => {\n if (\n (element.type === 'page' ||\n element.type === 'repeatableSet' ||\n element.type === 'section') &&\n Array.isArray(element.elements)\n ) {\n const childElements = injectFormElements(\n element.elements,\n forms,\n parentIds,\n injectAuthenticatedForms,\n )\n element.elements = childElements\n }\n\n if (element.type === 'form' || element.type === 'infoPage') {\n const formToInject = forms.find((form) => element.formId === form.id)\n\n if (!formToInject) {\n const newElement: HtmlElement = {\n ...element,\n type: 'html',\n name: 'Form_not_found',\n label: 'Form not found.',\n defaultValue:\n 'Unable to display the embedded form for this element, as the form was not found. Please contact your Administrator.',\n }\n newElements.push(newElement)\n return newElements\n }\n\n if (formToInject.isAuthenticated && !injectAuthenticatedForms) {\n console.log(\n `No form elements injected for element id: ${element.id}, as request was unauthenticated and target form (form id: ${formToInject.id}) requires authentication.`,\n )\n\n const newElement: HtmlElement = {\n ...element,\n type: 'html',\n name: 'Form_requires_authenticated',\n label: 'Form Requires Authentication.',\n defaultValue:\n 'Unable to display the embedded form for this element, as the form requires authentication. Please login and refresh to view this embedded form.',\n }\n newElements.push(newElement)\n return newElements\n }\n\n const injectingParentForm =\n parentIds && parentIds.find((id) => element.formId === id)\n\n if (injectingParentForm) {\n console.log(\n `Infinite loop was detected while attempting to inject form id: ${injectingParentForm}. Ignoring elements...`,\n )\n return newElements\n }\n\n element.elements = injectFormElements(\n formToInject.elements,\n forms,\n [...parentIds, formToInject.id],\n injectAuthenticatedForms,\n )\n newElements.push(element)\n } else {\n newElements.push(element)\n }\n\n return newElements\n }, [])\n}\n\nexport {\n forEachFormElement,\n forEachFormElementWithOptions,\n findFormElement,\n parseDynamicFormElementOptions,\n flattenFormElements,\n determineIsInfoPage,\n fixElementName,\n injectFormElementsIntoForm,\n}\n"]}
@@ -67,9 +67,16 @@ export type ReplaceInjectablesOptions = ReplaceInjectablesBaseOptions & {
67
67
  * @param options
68
68
  * @returns
69
69
  */
70
- export declare function getElementSubmissionValue({ elementId, propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }: {
71
- elementId?: string;
72
- propertyName?: string;
70
+ export declare function getElementSubmissionValue({ propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }: {
71
+ propertyName: string;
72
+ formElements: FormTypes.FormElement[];
73
+ submission: SubmissionTypes.S3SubmissionData['submission'];
74
+ } & ReplaceInjectablesFormatters): {
75
+ element: FormTypes.FormElement | undefined;
76
+ value: unknown;
77
+ } | undefined;
78
+ export declare function getElementSubmissionValue({ elementId, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }: {
79
+ elementId: string;
73
80
  formElements: FormTypes.FormElement[];
74
81
  submission: SubmissionTypes.S3SubmissionData['submission'];
75
82
  } & ReplaceInjectablesFormatters): {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.replaceInjectablesWithSubmissionValues = exports.replaceInjectablesWithElementValues = exports.getElementSubmissionValue = void 0;
4
4
  const abnService_1 = require("./abnService");
5
5
  const form_elements_regex_1 = require("./form-elements-regex");
6
+ const formElementsService_1 = require("./formElementsService");
6
7
  const SUBMISSION_VALUES = [
7
8
  {
8
9
  string: '{INFO_PAGE_ID}',
@@ -68,115 +69,109 @@ const ELEMENT_VALUES = [
68
69
  value: ({ taskGroupInstance }) => taskGroupInstance === null || taskGroupInstance === void 0 ? void 0 : taskGroupInstance.label,
69
70
  },
70
71
  ];
71
- /**
72
- * Function to get the display value of a property in submission, if elementId
73
- * is provided propertyName will be ignored
74
- *
75
- * #### Example
76
- *
77
- * ```typescript
78
- * const result = submissionService.getElementSubmissionValue({
79
- * propertyName: 'search',
80
- * submission: {
81
- * search: 'Entered By User',
82
- * },
83
- * formElements: [
84
- * {
85
- * id: 'd4135b47-9004-4d75-aeb3-d2f6232da111',
86
- * name: 'search',
87
- * type: 'text',
88
- * label: 'Search',
89
- * readOnly: false,
90
- * required: false,
91
- * conditionallyShow: false,
92
- * requiresAllConditionallyShowPredicates: false,
93
- * isElementLookup: false,
94
- * isDataLookup: false,
95
- * },
96
- * ],
97
- * formatDate: (value) => new Date(value).toDateString(),
98
- * formatDateTime: (value) => new Date(value).toString(),
99
- * formatTime: (value) => new Date(value).toTimeString(),
100
- * formatNumber: (value) => Number(value).toString(),
101
- * formatCurrency: (value) => Number(value).toFixed(2),
102
- * })
103
- * ```
104
- *
105
- * @param options
106
- * @returns
107
- */
108
72
  function getElementSubmissionValue({ elementId, propertyName, submission, formElements, formatDate, formatDateTime, formatTime, formatNumber, formatCurrency, }) {
109
- var _a, _b, _c, _d, _e;
110
73
  if (elementId === undefined && propertyName === undefined) {
111
74
  return undefined;
112
75
  }
76
+ let result = undefined;
77
+ if (elementId) {
78
+ result = getElementSubmissionValueById({
79
+ elementId,
80
+ formElements,
81
+ submission,
82
+ });
83
+ }
84
+ else if (propertyName) {
85
+ result = getElementSubmissionValueByName({
86
+ propertyName,
87
+ formElements,
88
+ submission,
89
+ });
90
+ }
91
+ if (!result) {
92
+ return;
93
+ }
94
+ return formatValue({
95
+ element: result.formElement,
96
+ unknownValue: result.unknownValue,
97
+ formatDate,
98
+ formatTime,
99
+ formatDateTime,
100
+ formatCurrency,
101
+ formatNumber,
102
+ });
103
+ }
104
+ exports.getElementSubmissionValue = getElementSubmissionValue;
105
+ function getElementSubmissionValueByName({ propertyName, formElements, submission, }) {
106
+ const unknownValue = submission[propertyName];
107
+ if (unknownValue === undefined || unknownValue === null) {
108
+ return undefined;
109
+ }
110
+ const formElement = (0, formElementsService_1.findFormElement)(formElements, (element) => element.type !== 'page' &&
111
+ element.type !== 'section' &&
112
+ element.name === propertyName);
113
+ return { formElement, unknownValue };
114
+ }
115
+ function getElementSubmissionValueById({ elementId, formElements, submission, }) {
116
+ var _a;
113
117
  // make sure submission is an object
114
118
  if (Object(submission) !== submission) {
115
119
  return undefined;
116
120
  }
117
- // initialise if propertyName provided and not elementId
118
- let unknown = elementId ? undefined : submission[propertyName !== null && propertyName !== void 0 ? propertyName : ''];
121
+ const flattenedElements = (0, formElementsService_1.flattenFormElements)(formElements);
122
+ let unknown = undefined;
119
123
  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)) {
124
+ for (const element of flattenedElements) {
125
+ if (elementId === element.id) {
128
126
  if ('name' in element) {
129
127
  unknown = submission[element.name];
130
128
  formElement = element;
131
- break;
132
129
  }
130
+ break;
133
131
  }
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({
132
+ if (element.type === 'form') {
133
+ const newSubmissionData = submission[element.name];
134
+ const result = getElementSubmissionValueById({
140
135
  elementId,
141
- formElements: element.elements,
136
+ formElements: (_a = element.elements) !== null && _a !== void 0 ? _a : [],
142
137
  submission: newSubmissionData,
143
- formatDate,
144
- formatDateTime,
145
- formatTime,
146
- formatNumber,
147
- formatCurrency,
148
138
  });
149
139
  if (result) {
150
- unknown = result.value;
151
- formElement = result.element;
140
+ unknown = result.unknownValue;
141
+ formElement = result.formElement;
142
+ break;
152
143
  }
153
144
  }
154
145
  }
155
- if (unknown === undefined || unknown === null) {
146
+ if (unknown === undefined || unknown === null || formElement === undefined) {
156
147
  return undefined;
157
148
  }
158
- switch (formElement === null || formElement === void 0 ? void 0 : formElement.type) {
149
+ return { unknownValue: unknown, formElement };
150
+ }
151
+ function formatValue({ element, unknownValue, formatDate, formatTime, formatDateTime, formatCurrency, formatNumber, }) {
152
+ var _a, _b, _c, _d, _e;
153
+ switch (element === null || element === void 0 ? void 0 : element.type) {
159
154
  case 'datetime': {
160
- const value = unknown;
161
- return { element: formElement, value: formatDateTime(value) };
155
+ const value = unknownValue;
156
+ return { element: element, value: formatDateTime(value) };
162
157
  }
163
158
  case 'date': {
164
- const value = unknown;
165
- return { element: formElement, value: formatDate(value) };
159
+ const value = unknownValue;
160
+ return { element: element, value: formatDate(value) };
166
161
  }
167
162
  case 'time': {
168
- const value = unknown;
169
- return { element: formElement, value: formatTime(value) };
163
+ const value = unknownValue;
164
+ return { element: element, value: formatTime(value) };
170
165
  }
171
166
  case 'radio':
172
167
  case 'autocomplete': {
173
- const value = unknown;
174
- const option = (_a = formElement.options) === null || _a === void 0 ? void 0 : _a.find((opt) => opt.value === value);
175
- return { element: formElement, value: (option === null || option === void 0 ? void 0 : option.label) || value };
168
+ const value = unknownValue;
169
+ const option = (_a = element.options) === null || _a === void 0 ? void 0 : _a.find((opt) => opt.value === value);
170
+ return { element: element, value: (option === null || option === void 0 ? void 0 : option.label) || value };
176
171
  }
177
172
  case 'checkboxes': {
178
- const value = unknown;
179
- const options = formElement.options;
173
+ const value = unknownValue;
174
+ const options = element.options;
180
175
  const selectedOptionLabels = value.reduce((labels, selectedOption) => {
181
176
  const foundOption = options === null || options === void 0 ? void 0 : options.find((o) => o.value === selectedOption);
182
177
  if (foundOption)
@@ -184,15 +179,15 @@ function getElementSubmissionValue({ elementId, propertyName, submission, formEl
184
179
  return labels;
185
180
  }, []);
186
181
  return {
187
- element: formElement,
182
+ element: element,
188
183
  value: selectedOptionLabels.length ? selectedOptionLabels : undefined,
189
184
  };
190
185
  }
191
186
  case 'compliance': {
192
- const value = unknown;
193
- const option = (formElement.options || []).find((option) => option.value === value.value);
187
+ const value = unknownValue;
188
+ const option = (element.options || []).find((option) => option.value === value.value);
194
189
  return {
195
- element: formElement,
190
+ element: element,
196
191
  value: {
197
192
  ...value,
198
193
  value: (option === null || option === void 0 ? void 0 : option.label) || value.value,
@@ -200,9 +195,9 @@ function getElementSubmissionValue({ elementId, propertyName, submission, formEl
200
195
  };
201
196
  }
202
197
  case 'select': {
203
- if (formElement.multi) {
204
- const value = unknown;
205
- const options = formElement.options;
198
+ if (element.multi) {
199
+ const value = unknownValue;
200
+ const options = element.options;
206
201
  const selectedOptionLabels = value.reduce((labels, selectedOption) => {
207
202
  const foundOption = options === null || options === void 0 ? void 0 : options.find((o) => o.value === selectedOption);
208
203
  if (foundOption)
@@ -210,75 +205,74 @@ function getElementSubmissionValue({ elementId, propertyName, submission, formEl
210
205
  return labels;
211
206
  }, []);
212
207
  return {
213
- element: formElement,
208
+ element: element,
214
209
  value: selectedOptionLabels.length ? selectedOptionLabels : undefined,
215
210
  };
216
211
  }
217
212
  else {
218
- const value = unknown;
219
- const option = (_b = formElement.options) === null || _b === void 0 ? void 0 : _b.find((opt) => opt.value === value);
220
- return { element: formElement, value: option === null || option === void 0 ? void 0 : option.label };
213
+ const value = unknownValue;
214
+ const option = (_b = element.options) === null || _b === void 0 ? void 0 : _b.find((opt) => opt.value === value);
215
+ return { element: element, value: option === null || option === void 0 ? void 0 : option.label };
221
216
  }
222
217
  }
223
218
  case 'boolean': {
224
- const value = unknown;
225
- return { element: formElement, value: value ? 'Yes' : 'No' };
219
+ const value = unknownValue;
220
+ return { element: element, value: value ? 'Yes' : 'No' };
226
221
  }
227
222
  case 'calculation': {
228
- const value = unknown;
223
+ const value = unknownValue;
229
224
  if (!Number.isNaN(value) && Number.isFinite(value)) {
230
225
  let text;
231
- if (formElement.displayAsCurrency) {
226
+ if (element.displayAsCurrency) {
232
227
  text = formatCurrency(value);
233
228
  }
234
229
  else {
235
230
  text = formatNumber(value);
236
231
  }
237
- return { element: formElement, value: text };
232
+ return { element: element, value: text };
238
233
  }
239
234
  return undefined;
240
235
  }
241
236
  case 'pointAddress':
242
237
  case 'geoscapeAddress': {
243
- const value = unknown;
238
+ const value = unknownValue;
244
239
  return {
245
- element: formElement,
240
+ element: element,
246
241
  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
242
  };
248
243
  }
249
244
  case 'civicaStreetName': {
250
- const value = unknown;
251
- return { element: formElement, value: value === null || value === void 0 ? void 0 : value.formattedStreet };
245
+ const value = unknownValue;
246
+ return { element: element, value: value === null || value === void 0 ? void 0 : value.formattedStreet };
252
247
  }
253
248
  case 'civicaNameRecord': {
254
- const value = unknown;
249
+ const value = unknownValue;
255
250
  return {
256
- element: formElement,
251
+ element: element,
257
252
  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
253
  .filter((t) => t)
259
254
  .join(' ') || (value === null || value === void 0 ? void 0 : value.emailAddress),
260
255
  };
261
256
  }
262
257
  case 'abn': {
263
- const value = unknown;
258
+ const value = unknownValue;
264
259
  return {
265
- element: formElement,
260
+ element: element,
266
261
  value: value ? (0, abnService_1.getABNNumberFromABNRecord)(value) : undefined,
267
262
  };
268
263
  }
269
264
  case 'apiNSWLiquorLicence': {
270
- const value = unknown;
265
+ const value = unknownValue;
271
266
  return {
272
- element: formElement,
267
+ element: element,
273
268
  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
269
  };
275
270
  }
276
271
  default: {
277
- return { element: formElement, value: unknown };
272
+ return { element: element, value: unknownValue };
278
273
  }
279
274
  }
280
275
  }
281
- exports.getElementSubmissionValue = getElementSubmissionValue;
282
276
  /**
283
277
  * Replace the `{ELEMENT:<elementName>}` values in text while a form is being
284
278
  * filled out. The replacements are suppose to be user friendly and for display
@@ -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 { 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"]}
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 { getABNNumberFromABNRecord } from './abnService'\nimport {\n RootElementRegex,\n NestedElementRegex,\n matchElementsTagRegex,\n} from './form-elements-regex'\nimport { findFormElement, flattenFormElements } from './formElementsService'\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 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):\n | {\n element: FormTypes.FormElement | undefined\n value: unknown\n }\n | undefined\nexport function getElementSubmissionValue({\n elementId,\n submission,\n formElements,\n formatDate,\n formatDateTime,\n formatTime,\n formatNumber,\n formatCurrency,\n}: {\n elementId: string\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\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 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 if (elementId === undefined && propertyName === undefined) {\n return undefined\n }\n\n let result: ReturnType<typeof getElementSubmissionValueByName> | undefined =\n undefined\n\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\n if (!result) {\n return\n }\n return formatValue({\n element: result.formElement,\n unknownValue: result.unknownValue,\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\n const flattenedElements = flattenFormElements(formElements)\n\n let unknown: unknown = undefined\n let formElement: FormTypes.FormElement | undefined = undefined\n\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\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 formatDate,\n formatTime,\n formatDateTime,\n formatCurrency,\n formatNumber,\n}: {\n element: FormTypes.FormElement | undefined\n unknownValue: unknown\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 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 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 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 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 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 const value = unknownValue as number\n if (!Number.isNaN(value) && Number.isFinite(value)) {\n let text\n if (element.displayAsCurrency) {\n text = formatCurrency(value)\n } else {\n text = formatNumber(value)\n }\n return { element: element, value: text }\n }\n return undefined\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 '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 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 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",
4
+ "version": "6.0.1-beta.2",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/sdk-core-js/issues"