@oneblink/sdk-core 0.3.3 → 0.3.4-beta.1

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.
@@ -0,0 +1,6 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ import { FormElementsCtrl } from '../types';
3
+ export default function conditionallyShowElement(formElementsCtrl: FormElementsCtrl, elementToEvaluate: FormTypes.FormElement, elementsEvaluated: Array<{
4
+ id: string;
5
+ label: string;
6
+ }>): boolean;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const evaluationService_1 = require("./evaluationService");
4
+ const getParentFormElements = (formElementsCtrl, childElement) => {
5
+ const parentElement = formElementsCtrl.flattenedElements.find((element) => {
6
+ return ((element.type === 'page' || element.type === 'section') &&
7
+ element.elements.some(({ id }) => id === childElement.id));
8
+ });
9
+ if (parentElement &&
10
+ (parentElement.type === 'page' || parentElement.type === 'section')) {
11
+ return [
12
+ parentElement,
13
+ ...getParentFormElements(formElementsCtrl, parentElement),
14
+ ];
15
+ }
16
+ return [];
17
+ };
18
+ const conditionallyShowByPredicate = (formElementsCtrl, predicate, elementsEvaluated) => {
19
+ const predicateElement = formElementsCtrl.flattenedElements.find((element) => {
20
+ return element.id === predicate.elementId;
21
+ });
22
+ // If we cant find the element used for the predicate,
23
+ // we can check to see if the element being evaluated
24
+ // is in a repeatable set and the predicate element is
25
+ // in a parent list of elements.
26
+ if (!predicateElement) {
27
+ if (formElementsCtrl.parentFormElementsCtrl) {
28
+ return conditionallyShowByPredicate(formElementsCtrl.parentFormElementsCtrl, predicate, elementsEvaluated);
29
+ }
30
+ else {
31
+ return false;
32
+ }
33
+ }
34
+ // Here we will also need to check if the predicate element
35
+ // is on a page/section element and the page/section element
36
+ // is also hidden. If it is hidden we will treat this
37
+ // predicate element as hidden as well.
38
+ const parentFormElements = getParentFormElements(formElementsCtrl, predicateElement);
39
+ for (const parentFormElement of parentFormElements) {
40
+ if (!conditionallyShowElement(formElementsCtrl, parentFormElement, [
41
+ ...elementsEvaluated,
42
+ ])) {
43
+ return false;
44
+ }
45
+ }
46
+ // Check to see if the model has one of the valid values to show the element
47
+ return (conditionallyShowElement(formElementsCtrl, predicateElement, elementsEvaluated) &&
48
+ (0, evaluationService_1.evaluateConditionalPredicate)({
49
+ predicate,
50
+ submission: formElementsCtrl.model,
51
+ predicateElement,
52
+ }));
53
+ };
54
+ function conditionallyShowElement(formElementsCtrl, elementToEvaluate, elementsEvaluated) {
55
+ // If the element does not have the `conditionallyShow` flag set,
56
+ // we can always show the element.
57
+ if (!elementToEvaluate ||
58
+ !elementToEvaluate.conditionallyShow ||
59
+ !Array.isArray(elementToEvaluate.conditionallyShowPredicates) ||
60
+ !elementToEvaluate.conditionallyShowPredicates.length) {
61
+ return true;
62
+ }
63
+ const conditionallyShowPredicates = elementToEvaluate.conditionallyShowPredicates;
64
+ // Check to see if this element has already been used to evaluate
65
+ // if the element should be shown based on parent element conditional logic
66
+ const elementAlreadyEvaluated = elementsEvaluated.find(({ id }) => id === elementToEvaluate.id);
67
+ if (elementAlreadyEvaluated) {
68
+ throw new Error(`Your conditional logic has caused an infinite loop. Check the "${elementAlreadyEvaluated.label}" form element to ensure element A does not rely on element B if element B also relies on element A.`);
69
+ }
70
+ else {
71
+ elementsEvaluated.push({
72
+ id: elementToEvaluate.id,
73
+ label: elementToEvaluate.type === 'form' ||
74
+ elementToEvaluate.type === 'infoPage'
75
+ ? elementToEvaluate.name
76
+ : elementToEvaluate.label,
77
+ });
78
+ }
79
+ const predicateFunction = (predicate) => {
80
+ // Spread the array of elements evaluated so that each predicate can
81
+ // evaluate the tree without causing false positives for infinite
82
+ // loop conditional logic
83
+ return conditionallyShowByPredicate(formElementsCtrl, predicate, [
84
+ ...elementsEvaluated,
85
+ ]);
86
+ };
87
+ if (elementToEvaluate.requiresAllConditionallyShowPredicates) {
88
+ return conditionallyShowPredicates.every(predicateFunction);
89
+ }
90
+ else {
91
+ return conditionallyShowPredicates.some(predicateFunction);
92
+ }
93
+ }
94
+ exports.default = conditionallyShowElement;
95
+ //# sourceMappingURL=conditionallyShowElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditionallyShowElement.js","sourceRoot":"","sources":["../../src/conditionalLogicService/conditionallyShowElement.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, ConditionTypes } from '@oneblink/types'\nimport { evaluateConditionalPredicate } from './evaluationService'\nimport { FormElementsCtrl } from '../types'\n\nconst getParentFormElements = (\n formElementsCtrl: FormElementsCtrl,\n childElement: FormTypes.FormElement,\n): Array<FormTypes.SectionElement | FormTypes.PageElement> => {\n const parentElement = formElementsCtrl.flattenedElements.find((element) => {\n return (\n (element.type === 'page' || element.type === 'section') &&\n element.elements.some(({ id }) => id === childElement.id)\n )\n })\n if (\n parentElement &&\n (parentElement.type === 'page' || parentElement.type === 'section')\n ) {\n return [\n parentElement,\n ...getParentFormElements(formElementsCtrl, parentElement),\n ]\n }\n return []\n}\n\nconst conditionallyShowByPredicate = (\n formElementsCtrl: FormElementsCtrl,\n predicate: ConditionTypes.ConditionalPredicate,\n elementsEvaluated: Array<{ id: string; label: string }>,\n): FormTypes.FormElement | boolean => {\n const predicateElement = formElementsCtrl.flattenedElements.find(\n (element: FormTypes.FormElement) => {\n return element.id === predicate.elementId\n },\n )\n\n // If we cant find the element used for the predicate,\n // we can check to see if the element being evaluated\n // is in a repeatable set and the predicate element is\n // in a parent list of elements.\n if (!predicateElement) {\n if (formElementsCtrl.parentFormElementsCtrl) {\n return conditionallyShowByPredicate(\n formElementsCtrl.parentFormElementsCtrl,\n predicate,\n elementsEvaluated,\n )\n } else {\n return false\n }\n }\n\n // Here we will also need to check if the predicate element\n // is on a page/section element and the page/section element\n // is also hidden. If it is hidden we will treat this\n // predicate element as hidden as well.\n const parentFormElements = getParentFormElements(\n formElementsCtrl,\n predicateElement,\n )\n for (const parentFormElement of parentFormElements) {\n if (\n !conditionallyShowElement(formElementsCtrl, parentFormElement, [\n ...elementsEvaluated,\n ])\n ) {\n return false\n }\n }\n\n // Check to see if the model has one of the valid values to show the element\n return (\n conditionallyShowElement(\n formElementsCtrl,\n predicateElement,\n elementsEvaluated,\n ) &&\n evaluateConditionalPredicate({\n predicate,\n submission: formElementsCtrl.model,\n predicateElement,\n })\n )\n}\n\nexport default function conditionallyShowElement(\n formElementsCtrl: FormElementsCtrl,\n elementToEvaluate: FormTypes.FormElement,\n elementsEvaluated: Array<{ id: string; label: string }>,\n): boolean {\n // If the element does not have the `conditionallyShow` flag set,\n // we can always show the element.\n if (\n !elementToEvaluate ||\n !elementToEvaluate.conditionallyShow ||\n !Array.isArray(elementToEvaluate.conditionallyShowPredicates) ||\n !elementToEvaluate.conditionallyShowPredicates.length\n ) {\n return true\n }\n const conditionallyShowPredicates =\n elementToEvaluate.conditionallyShowPredicates\n\n // Check to see if this element has already been used to evaluate\n // if the element should be shown based on parent element conditional logic\n const elementAlreadyEvaluated = elementsEvaluated.find(\n ({ id }) => id === elementToEvaluate.id,\n )\n if (elementAlreadyEvaluated) {\n throw new Error(\n `Your conditional logic has caused an infinite loop. Check the \"${elementAlreadyEvaluated.label}\" form element to ensure element A does not rely on element B if element B also relies on element A.`,\n )\n } else {\n elementsEvaluated.push({\n id: elementToEvaluate.id,\n label:\n elementToEvaluate.type === 'form' ||\n elementToEvaluate.type === 'infoPage'\n ? elementToEvaluate.name\n : elementToEvaluate.label,\n })\n }\n\n const predicateFunction = (\n predicate: ConditionTypes.ConditionalPredicate,\n ) => {\n // Spread the array of elements evaluated so that each predicate can\n // evaluate the tree without causing false positives for infinite\n // loop conditional logic\n return conditionallyShowByPredicate(formElementsCtrl, predicate, [\n ...elementsEvaluated,\n ])\n }\n\n if (elementToEvaluate.requiresAllConditionallyShowPredicates) {\n return conditionallyShowPredicates.every(predicateFunction)\n } else {\n return conditionallyShowPredicates.some(predicateFunction)\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ import { FormElementsCtrl } from '../types';
3
+ export default function conditionallyShowOption(formElementsCtrl: FormElementsCtrl, elementToEvaluate: FormTypes.FormElementWithOptions, optionToEvaluate: FormTypes.ChoiceElementOption, optionsEvaluated: string[]): boolean;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const evaluationService_1 = require("./evaluationService");
7
+ const conditionallyShowElement_1 = __importDefault(require("./conditionallyShowElement"));
8
+ const handleAttributePredicate = (predicate, model, predicateElement) => {
9
+ const values = model[predicateElement.name];
10
+ if (!values)
11
+ return true;
12
+ if (Array.isArray(values) &&
13
+ (!values.length ||
14
+ !values.filter((value) => typeof value !== 'undefined').length)) {
15
+ return true;
16
+ }
17
+ return (0, evaluationService_1.evaluateConditionalOptionsPredicate)({
18
+ predicate: {
19
+ type: 'OPTIONS',
20
+ elementId: predicate.elementId,
21
+ optionIds: predicate.optionIds,
22
+ },
23
+ submission: model,
24
+ predicateElement,
25
+ });
26
+ };
27
+ const conditionallyShowOptionByPredicate = (formElementsCtrl, predicate, elementsEvaluated) => {
28
+ // Validate the predicate data, if it is invalid,
29
+ // we will always show the field
30
+ if (!predicate ||
31
+ !predicate.elementId ||
32
+ !predicate.optionIds ||
33
+ !predicate.optionIds.length) {
34
+ return true;
35
+ }
36
+ const predicateElement = formElementsCtrl.flattenedElements.find((element) => {
37
+ return element.id === predicate.elementId;
38
+ });
39
+ // If we cant find the element used for the predicate,
40
+ // we can check to see if the element being evaluated
41
+ // is in a repeatable set and the predicate element is
42
+ // in a parent list of elements.
43
+ if (!predicateElement) {
44
+ if (formElementsCtrl.parentFormElementsCtrl) {
45
+ return conditionallyShowOptionByPredicate(formElementsCtrl.parentFormElementsCtrl, predicate, elementsEvaluated);
46
+ }
47
+ else {
48
+ return false;
49
+ }
50
+ }
51
+ if (predicateElement.type !== 'compliance' &&
52
+ predicateElement.type !== 'select' &&
53
+ predicateElement.type !== 'autocomplete' &&
54
+ predicateElement.type !== 'checkboxes' &&
55
+ predicateElement.type !== 'radio') {
56
+ return false;
57
+ }
58
+ // If the predicate element does not have any options to evaluate,
59
+ // we will show the element.
60
+ // Unless the predicate element has dynamic options and
61
+ // options have not been fetched yet.
62
+ if (!Array.isArray(predicateElement.options)) {
63
+ return predicateElement.optionsType !== 'DYNAMIC';
64
+ }
65
+ const everyOptionIsShowing = predicate.optionIds.every((id) => {
66
+ var _a;
67
+ const predicateOption = (_a = predicateElement.options) === null || _a === void 0 ? void 0 : _a.find((o) => o.id === id);
68
+ if (!predicateOption)
69
+ return false;
70
+ return conditionallyShowOption({ model: formElementsCtrl.model, flattenedElements: [] }, predicateElement, predicateOption, elementsEvaluated);
71
+ });
72
+ if (!everyOptionIsShowing) {
73
+ return false;
74
+ }
75
+ // Check to see if the model has one of the valid values to show the element
76
+ return handleAttributePredicate(predicate, formElementsCtrl.model, predicateElement);
77
+ };
78
+ const isAttributeFilterValid = (formElementsCtrl, predicate, elementsEvaluated) => {
79
+ const predicateElement = formElementsCtrl.flattenedElements.find((element) => {
80
+ return element.id === predicate.elementId;
81
+ });
82
+ // If we cant find the element used for the predicate,
83
+ // we can check to see if the element being evaluated
84
+ // is in a repeatable set and the predicate element is
85
+ // in a parent list of elements.
86
+ if (!predicateElement) {
87
+ if (formElementsCtrl.parentFormElementsCtrl) {
88
+ return isAttributeFilterValid(formElementsCtrl.parentFormElementsCtrl, predicate, elementsEvaluated);
89
+ }
90
+ else {
91
+ return false;
92
+ }
93
+ }
94
+ // now we have the model and predicate element, verify that the predicate element
95
+ // is not hidden
96
+ if (
97
+ // Will never be a page, just making typescript happy :)
98
+ predicateElement.type === 'page' ||
99
+ predicateElement.type === 'section' ||
100
+ !(0, conditionallyShowElement_1.default)(formElementsCtrl, predicateElement, [])) {
101
+ return false;
102
+ }
103
+ // verify that at least one option is selected
104
+ const values = formElementsCtrl.model[predicateElement.name];
105
+ if (!values)
106
+ return false;
107
+ // if the model value is an array, verify that it has a selection
108
+ if (Array.isArray(values) &&
109
+ (!values.length ||
110
+ !values.filter((value) => typeof value !== 'undefined').length)) {
111
+ return false;
112
+ }
113
+ return true;
114
+ };
115
+ function conditionallyShowOption(formElementsCtrl, elementToEvaluate, optionToEvaluate, optionsEvaluated) {
116
+ // If the element does not have the `conditionallyShow` flag set,
117
+ // we can always show the element.
118
+ if (!elementToEvaluate.conditionallyShowOptions ||
119
+ !optionToEvaluate ||
120
+ !optionToEvaluate.attributes ||
121
+ !Array.isArray(optionToEvaluate.attributes) ||
122
+ !optionToEvaluate.attributes.length) {
123
+ return true;
124
+ }
125
+ // Check to see if this element has already been used to evaluate
126
+ // if the element should be shown based on parent element conditional logic
127
+ if (optionsEvaluated.some((optionId) => optionId === optionToEvaluate.id)) {
128
+ throw new Error('Your conditional logic has caused an infinite loop. Check the following Fields to ensure element A does not rely on element B if element B also relies on element A.');
129
+ }
130
+ else {
131
+ optionsEvaluated.push(optionToEvaluate.id);
132
+ }
133
+ const validPredicates = (optionToEvaluate.attributes || []).filter((predicate) => {
134
+ return isAttributeFilterValid(formElementsCtrl, predicate, optionsEvaluated);
135
+ });
136
+ if (!validPredicates.length)
137
+ return true;
138
+ return validPredicates.some((predicate) => conditionallyShowOptionByPredicate(formElementsCtrl, predicate, optionsEvaluated));
139
+ }
140
+ exports.default = conditionallyShowOption;
141
+ //# sourceMappingURL=conditionallyShowOption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditionallyShowOption.js","sourceRoot":"","sources":["../../src/conditionalLogicService/conditionallyShowOption.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { evaluateConditionalOptionsPredicate } from './evaluationService'\nimport { FormElementsCtrl } from '../types'\n\nimport conditionallyShowElement from './conditionallyShowElement'\n\nconst handleAttributePredicate = (\n predicate: FormTypes.ChoiceElementOptionAttribute,\n model: Record<string, unknown>,\n predicateElement: FormTypes.FormElementWithOptions,\n) => {\n const values = model[predicateElement.name]\n if (!values) return true\n\n if (\n Array.isArray(values) &&\n (!values.length ||\n !values.filter((value) => typeof value !== 'undefined').length)\n ) {\n return true\n }\n\n return evaluateConditionalOptionsPredicate({\n predicate: {\n type: 'OPTIONS',\n elementId: predicate.elementId,\n optionIds: predicate.optionIds,\n },\n submission: model,\n predicateElement,\n })\n}\n\nconst conditionallyShowOptionByPredicate = (\n formElementsCtrl: FormElementsCtrl,\n predicate: FormTypes.ChoiceElementOptionAttribute,\n elementsEvaluated: string[],\n): boolean => {\n // Validate the predicate data, if it is invalid,\n // we will always show the field\n if (\n !predicate ||\n !predicate.elementId ||\n !predicate.optionIds ||\n !predicate.optionIds.length\n ) {\n return true\n }\n\n const predicateElement = formElementsCtrl.flattenedElements.find(\n (element) => {\n return element.id === predicate.elementId\n },\n )\n\n // If we cant find the element used for the predicate,\n // we can check to see if the element being evaluated\n // is in a repeatable set and the predicate element is\n // in a parent list of elements.\n if (!predicateElement) {\n if (formElementsCtrl.parentFormElementsCtrl) {\n return conditionallyShowOptionByPredicate(\n formElementsCtrl.parentFormElementsCtrl,\n predicate,\n elementsEvaluated,\n )\n } else {\n return false\n }\n }\n\n if (\n predicateElement.type !== 'compliance' &&\n predicateElement.type !== 'select' &&\n predicateElement.type !== 'autocomplete' &&\n predicateElement.type !== 'checkboxes' &&\n predicateElement.type !== 'radio'\n ) {\n return false\n }\n\n // If the predicate element does not have any options to evaluate,\n // we will show the element.\n // Unless the predicate element has dynamic options and\n // options have not been fetched yet.\n if (!Array.isArray(predicateElement.options)) {\n return predicateElement.optionsType !== 'DYNAMIC'\n }\n\n const everyOptionIsShowing = predicate.optionIds.every((id) => {\n const predicateOption = predicateElement.options?.find((o) => o.id === id)\n if (!predicateOption) return false\n\n return conditionallyShowOption(\n { model: formElementsCtrl.model, flattenedElements: [] },\n predicateElement,\n predicateOption,\n elementsEvaluated,\n )\n })\n\n if (!everyOptionIsShowing) {\n return false\n }\n\n // Check to see if the model has one of the valid values to show the element\n return handleAttributePredicate(\n predicate,\n formElementsCtrl.model,\n predicateElement,\n )\n}\n\nconst isAttributeFilterValid = (\n formElementsCtrl: FormElementsCtrl,\n predicate: FormTypes.ChoiceElementOptionAttribute,\n elementsEvaluated: string[],\n): boolean => {\n const predicateElement = formElementsCtrl.flattenedElements.find(\n (element) => {\n return element.id === predicate.elementId\n },\n )\n\n // If we cant find the element used for the predicate,\n // we can check to see if the element being evaluated\n // is in a repeatable set and the predicate element is\n // in a parent list of elements.\n if (!predicateElement) {\n if (formElementsCtrl.parentFormElementsCtrl) {\n return isAttributeFilterValid(\n formElementsCtrl.parentFormElementsCtrl,\n predicate,\n elementsEvaluated,\n )\n } else {\n return false\n }\n }\n\n // now we have the model and predicate element, verify that the predicate element\n // is not hidden\n if (\n // Will never be a page, just making typescript happy :)\n predicateElement.type === 'page' ||\n predicateElement.type === 'section' ||\n !conditionallyShowElement(formElementsCtrl, predicateElement, [])\n ) {\n return false\n }\n\n // verify that at least one option is selected\n const values = formElementsCtrl.model[predicateElement.name]\n if (!values) return false\n // if the model value is an array, verify that it has a selection\n if (\n Array.isArray(values) &&\n (!values.length ||\n !values.filter((value) => typeof value !== 'undefined').length)\n ) {\n return false\n }\n\n return true\n}\n\nexport default function conditionallyShowOption(\n formElementsCtrl: FormElementsCtrl,\n elementToEvaluate: FormTypes.FormElementWithOptions,\n optionToEvaluate: FormTypes.ChoiceElementOption,\n optionsEvaluated: string[],\n): boolean {\n // If the element does not have the `conditionallyShow` flag set,\n // we can always show the element.\n\n if (\n !elementToEvaluate.conditionallyShowOptions ||\n !optionToEvaluate ||\n !optionToEvaluate.attributes ||\n !Array.isArray(optionToEvaluate.attributes) ||\n !optionToEvaluate.attributes.length\n ) {\n return true\n }\n\n // Check to see if this element has already been used to evaluate\n // if the element should be shown based on parent element conditional logic\n if (optionsEvaluated.some((optionId) => optionId === optionToEvaluate.id)) {\n throw new Error(\n 'Your conditional logic has caused an infinite loop. Check the following Fields to ensure element A does not rely on element B if element B also relies on element A.',\n )\n } else {\n optionsEvaluated.push(optionToEvaluate.id)\n }\n\n const validPredicates = (optionToEvaluate.attributes || []).filter(\n (predicate) => {\n return isAttributeFilterValid(\n formElementsCtrl,\n predicate,\n optionsEvaluated,\n )\n },\n )\n\n if (!validPredicates.length) return true\n return validPredicates.some((predicate) =>\n conditionallyShowOptionByPredicate(\n formElementsCtrl,\n predicate,\n optionsEvaluated,\n ),\n )\n}\n"]}
@@ -136,4 +136,4 @@ function evaluateConditionalPredicates({ isConditional, requiresAllConditionalPr
136
136
  }
137
137
  }
138
138
  exports.evaluateConditionalPredicates = evaluateConditionalPredicates;
139
- //# sourceMappingURL=conditionalLogicService.js.map
139
+ //# sourceMappingURL=evaluationService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluationService.js","sourceRoot":"","sources":["../../src/conditionalLogicService/evaluationService.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, ConditionTypes, SubmissionTypes } from '@oneblink/types'\n\nconst fnMap = {\n '>': (lhs: number, rhs: number) => lhs > rhs,\n '>=': (lhs: number, rhs: number) => lhs >= rhs,\n '===': (lhs: number, rhs: number) => lhs === rhs,\n '!==': (lhs: number, rhs: number) => lhs !== rhs,\n '<=': (lhs: number, rhs: number) => lhs <= rhs,\n '<': (lhs: number, rhs: number) => lhs < rhs,\n}\n\nfunction evaluateConditionalOptionsPredicate({\n predicate,\n predicateElement,\n submission,\n}: {\n predicate: ConditionTypes.ConditionalPredicateOptions\n submission: SubmissionTypes.S3SubmissionData['submission']\n predicateElement: FormTypes.FormElementWithOptions\n}): boolean {\n return predicate.optionIds.some((optionId) => {\n const option = predicateElement.options?.find((o) => o.id === optionId)\n if (option) {\n const value = submission[predicateElement.name]\n if (Array.isArray(value)) {\n return value.some((modelValue) => {\n return modelValue === option.value\n })\n } else if (predicateElement.type === 'compliance' && value) {\n return option.value === (value as { value: unknown }).value\n } else {\n return option.value === value\n }\n } else {\n return false\n }\n })\n}\n\nfunction evaluateConditionalPredicate({\n predicate,\n predicateElement,\n submission,\n}: {\n predicate: ConditionTypes.ConditionalPredicate\n predicateElement: FormTypes.FormElement\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): boolean {\n if (\n !predicateElement ||\n predicateElement.type === 'page' ||\n predicateElement.type === 'section'\n ) {\n return false\n }\n switch (predicate.type) {\n case 'VALUE': {\n return !predicate.hasValue === !submission[predicateElement.name]\n }\n case 'NUMERIC': {\n const lhs = Number.parseFloat(submission[predicateElement.name] as string)\n const rhs =\n typeof predicate.value === 'string'\n ? Number.parseFloat(predicate.value)\n : predicate.value\n\n // if either of the values is not a number or the operator fn doesn't exist, hide the control\n const operatorFn = fnMap[predicate.operator]\n if (!operatorFn || Number.isNaN(lhs) || Number.isNaN(rhs)) return false\n\n return operatorFn(lhs, rhs)\n }\n case 'BETWEEN': {\n const value = Number.parseFloat(\n submission[predicateElement.name] as string,\n )\n if (Number.isNaN(value)) {\n return false\n }\n\n return value >= predicate.min && value <= predicate.max\n }\n case 'OPTIONS':\n default: {\n if (\n predicateElement.type !== 'select' &&\n predicateElement.type !== 'autocomplete' &&\n predicateElement.type !== 'radio' &&\n predicateElement.type !== 'checkboxes' &&\n predicateElement.type !== 'compliance'\n ) {\n return false\n }\n\n // If the predicate element does not have any options to evaluate,\n // we will show the element.\n // Unless the predicate element has dynamic options and\n // options have not been fetched yet.\n if (!Array.isArray(predicateElement.options)) {\n return predicateElement.optionsType !== 'DYNAMIC'\n } else {\n return evaluateConditionalOptionsPredicate({\n predicate,\n submission,\n predicateElement,\n })\n }\n }\n }\n}\n\nconst getPredicateElement = (\n elements: Array<FormTypes.FormElement>,\n elementId: string,\n): FormTypes.FormElement | void => {\n for (const element of elements) {\n if (element.type === 'page' || element.type === 'section') {\n const predicateElement = getPredicateElement(element.elements, elementId)\n if (predicateElement) {\n return predicateElement\n }\n } else if (element.id === elementId) {\n return element\n }\n }\n}\n\nfunction evaluateConditionalPredicates({\n isConditional,\n requiresAllConditionalPredicates,\n conditionalPredicates,\n formElements,\n submission,\n}: {\n isConditional: boolean\n requiresAllConditionalPredicates: boolean\n conditionalPredicates: ConditionTypes.ConditionalPredicate[]\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): boolean {\n if (!isConditional || !conditionalPredicates.length) {\n return true\n }\n\n const predicateResults = []\n for (const predicate of conditionalPredicates) {\n const predicateElement = getPredicateElement(\n formElements,\n predicate.elementId,\n )\n if (!predicateElement) {\n throw new Error(\n 'Could not find element referenced in execution condition',\n )\n }\n\n const predicateIsSatisfied = evaluateConditionalPredicate({\n predicate,\n predicateElement,\n submission,\n })\n predicateResults.push(predicateIsSatisfied)\n if (requiresAllConditionalPredicates) {\n if (!predicateIsSatisfied) break\n } else {\n // Doesn't require all predicates\n if (predicateIsSatisfied) break\n }\n }\n\n if (requiresAllConditionalPredicates) {\n return !predicateResults.includes(false)\n } else {\n // Doesn't require all predicates\n return predicateResults.includes(true)\n }\n}\n\n\n\nexport {\n evaluateConditionalOptionsPredicate,\n evaluateConditionalPredicate,\n evaluateConditionalPredicates,\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ import { FormElementsCtrl, FormElementsConditionallyShown } from '../types';
3
+ declare type ErrorCallback = (error: Error) => void;
4
+ declare const generateFormElementsConditionallyShown: ({ formElements, submission, parentFormElementsCtrl, errorCallback, }: {
5
+ formElements: FormTypes.FormElement[];
6
+ submission: Record<string, unknown>;
7
+ parentFormElementsCtrl?: FormElementsCtrl['parentFormElementsCtrl'];
8
+ errorCallback?: ErrorCallback | undefined;
9
+ }) => FormElementsConditionallyShown;
10
+ export default generateFormElementsConditionallyShown;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const formElementsService_1 = require("../formElementsService");
7
+ const conditionallyShowElement_1 = __importDefault(require("./conditionallyShowElement"));
8
+ const conditionallyShowOption_1 = __importDefault(require("./conditionallyShowOption"));
9
+ const handleConditionallyShowElement = (formElementsCtrl, element, errorCallback) => {
10
+ try {
11
+ return (0, conditionallyShowElement_1.default)(formElementsCtrl, element, []);
12
+ }
13
+ catch (error) {
14
+ console.warn('Error while checking if element is conditional shown', error);
15
+ errorCallback && errorCallback(error);
16
+ return false;
17
+ }
18
+ };
19
+ const handleConditionallyShowOption = (formElementsCtrl, element, option, errorCallback) => {
20
+ try {
21
+ return (0, conditionallyShowOption_1.default)(formElementsCtrl, element, option, []);
22
+ }
23
+ catch (error) {
24
+ errorCallback && errorCallback(error);
25
+ return false;
26
+ }
27
+ };
28
+ const generateFormElementsConditionallyShown = ({ formElements, submission, parentFormElementsCtrl, errorCallback, }) => {
29
+ const formElementsCtrl = {
30
+ flattenedElements: (0, formElementsService_1.flattenFormElements)(formElements),
31
+ model: submission,
32
+ parentFormElementsCtrl,
33
+ };
34
+ return formElementsCtrl.flattenedElements.reduce((formElementsConditionallyShown, element) => {
35
+ switch (element.type) {
36
+ case 'section':
37
+ case 'page': {
38
+ const formElementConditionallyShown = formElementsConditionallyShown[element.id];
39
+ const isHidden = formElementConditionallyShown
40
+ ? formElementConditionallyShown.isHidden
41
+ : !handleConditionallyShowElement(formElementsCtrl, element, errorCallback);
42
+ formElementsConditionallyShown[element.id] = {
43
+ type: 'formElement',
44
+ isHidden,
45
+ };
46
+ // If the parent element is hidden, hide all the child elements
47
+ if (isHidden) {
48
+ element.elements.forEach((childElement) => {
49
+ switch (childElement.type) {
50
+ case 'section':
51
+ case 'page': {
52
+ formElementsConditionallyShown[childElement.id] = {
53
+ type: 'formElement',
54
+ isHidden: true,
55
+ };
56
+ break;
57
+ }
58
+ default: {
59
+ formElementsConditionallyShown[childElement.name] = {
60
+ type: 'formElement',
61
+ isHidden: true,
62
+ };
63
+ }
64
+ }
65
+ });
66
+ }
67
+ break;
68
+ }
69
+ case 'infoPage':
70
+ case 'form': {
71
+ if (formElementsConditionallyShown[element.name]) {
72
+ break;
73
+ }
74
+ const nestedModel = submission[element.name];
75
+ formElementsConditionallyShown[element.name] = {
76
+ type: 'formElements',
77
+ isHidden: !handleConditionallyShowElement(formElementsCtrl, element, errorCallback),
78
+ formElements: generateFormElementsConditionallyShown({
79
+ formElements: element.elements || [],
80
+ submission: nestedModel || {},
81
+ parentFormElementsCtrl: formElementsCtrl,
82
+ }),
83
+ };
84
+ break;
85
+ }
86
+ case 'repeatableSet': {
87
+ if (formElementsConditionallyShown[element.name]) {
88
+ break;
89
+ }
90
+ const entries = formElementsCtrl.model[element.name];
91
+ formElementsConditionallyShown[element.name] = {
92
+ type: 'repeatableSet',
93
+ isHidden: !handleConditionallyShowElement(formElementsCtrl, element, errorCallback),
94
+ entries: (entries || []).reduce((result, entry, index) => {
95
+ result[index.toString()] =
96
+ generateFormElementsConditionallyShown({
97
+ formElements: element.elements,
98
+ submission: entry,
99
+ parentFormElementsCtrl: formElementsCtrl,
100
+ });
101
+ return result;
102
+ }, {}),
103
+ };
104
+ break;
105
+ }
106
+ default: {
107
+ if (formElementsConditionallyShown[element.name]) {
108
+ break;
109
+ }
110
+ const formElementConditionallyShown = {
111
+ type: 'formElement',
112
+ isHidden: !handleConditionallyShowElement(formElementsCtrl, element, errorCallback),
113
+ };
114
+ if (!formElementConditionallyShown.isHidden) {
115
+ switch (element.type) {
116
+ case 'compliance':
117
+ case 'autocomplete':
118
+ case 'radio':
119
+ case 'checkboxes':
120
+ case 'select': {
121
+ if (element.conditionallyShowOptions &&
122
+ Array.isArray(element.options)) {
123
+ formElementConditionallyShown.options =
124
+ element.options.filter((option) => handleConditionallyShowOption(formElementsCtrl, element, option, errorCallback));
125
+ }
126
+ break;
127
+ }
128
+ }
129
+ }
130
+ formElementsConditionallyShown[element.name] =
131
+ formElementConditionallyShown;
132
+ }
133
+ }
134
+ return formElementsConditionallyShown;
135
+ }, {});
136
+ };
137
+ exports.default = generateFormElementsConditionallyShown;
138
+ //# sourceMappingURL=generateFormElementsConditionallyShown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateFormElementsConditionallyShown.js","sourceRoot":"","sources":["../../src/conditionalLogicService/generateFormElementsConditionallyShown.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport {\n FormElementsCtrl,\n FormElementsConditionallyShown,\n FormElementConditionallyShown,\n} from '../types'\nimport { flattenFormElements } from '../formElementsService'\nimport conditionallyShowElement from './conditionallyShowElement'\nimport conditionallyShowOption from './conditionallyShowOption'\n\ntype ErrorCallback = (error: Error) => void\n\nconst handleConditionallyShowElement = (\n formElementsCtrl: FormElementsCtrl,\n element: FormTypes.FormElement,\n errorCallback?: ErrorCallback,\n) => {\n try {\n return conditionallyShowElement(formElementsCtrl, element, [])\n } catch (error) {\n console.warn('Error while checking if element is conditional shown', error)\n errorCallback && errorCallback(error as Error)\n return false\n }\n}\n\nconst handleConditionallyShowOption = (\n formElementsCtrl: FormElementsCtrl,\n element: FormTypes.FormElementWithOptions,\n option: FormTypes.ChoiceElementOption,\n errorCallback?: ErrorCallback,\n) => {\n try {\n return conditionallyShowOption(formElementsCtrl, element, option, [])\n } catch (error) {\n errorCallback && errorCallback(error as Error)\n return false\n }\n}\n\nconst generateFormElementsConditionallyShown = ({\n formElements,\n submission,\n parentFormElementsCtrl,\n errorCallback,\n}: {\n formElements: FormTypes.FormElement[]\n submission: Record<string, unknown>\n parentFormElementsCtrl?: FormElementsCtrl['parentFormElementsCtrl']\n errorCallback?: ErrorCallback\n}): FormElementsConditionallyShown => {\n const formElementsCtrl = {\n flattenedElements: flattenFormElements(formElements),\n model: submission,\n parentFormElementsCtrl,\n }\n return formElementsCtrl.flattenedElements.reduce<FormElementsConditionallyShown>(\n (formElementsConditionallyShown, element) => {\n switch (element.type) {\n case 'section':\n case 'page': {\n const formElementConditionallyShown =\n formElementsConditionallyShown[element.id]\n const isHidden = formElementConditionallyShown\n ? formElementConditionallyShown.isHidden\n : !handleConditionallyShowElement(\n formElementsCtrl,\n element,\n errorCallback,\n )\n\n formElementsConditionallyShown[element.id] = {\n type: 'formElement',\n isHidden,\n }\n\n // If the parent element is hidden, hide all the child elements\n if (isHidden) {\n element.elements.forEach((childElement) => {\n switch (childElement.type) {\n case 'section':\n case 'page': {\n formElementsConditionallyShown[childElement.id] = {\n type: 'formElement',\n isHidden: true,\n }\n break\n }\n default: {\n formElementsConditionallyShown[childElement.name] = {\n type: 'formElement',\n isHidden: true,\n }\n }\n }\n })\n }\n break\n }\n case 'infoPage':\n case 'form': {\n if (formElementsConditionallyShown[element.name]) {\n break\n }\n const nestedModel = submission[element.name] as\n | Record<string, unknown>\n | undefined\n formElementsConditionallyShown[element.name] = {\n type: 'formElements',\n isHidden: !handleConditionallyShowElement(\n formElementsCtrl,\n element,\n errorCallback,\n ),\n formElements: generateFormElementsConditionallyShown({\n formElements: element.elements || [],\n submission: nestedModel || {},\n parentFormElementsCtrl: formElementsCtrl,\n }),\n }\n break\n }\n case 'repeatableSet': {\n if (formElementsConditionallyShown[element.name]) {\n break\n }\n const entries = formElementsCtrl.model[element.name] as\n | Array<Record<string, unknown>>\n | undefined\n formElementsConditionallyShown[element.name] = {\n type: 'repeatableSet',\n isHidden: !handleConditionallyShowElement(\n formElementsCtrl,\n element,\n errorCallback,\n ),\n entries: (entries || []).reduce(\n (\n result: Record<\n string,\n FormElementsConditionallyShown | undefined\n >,\n entry,\n index,\n ) => {\n result[index.toString()] =\n generateFormElementsConditionallyShown({\n formElements: element.elements,\n submission: entry,\n parentFormElementsCtrl: formElementsCtrl,\n })\n return result\n },\n {},\n ),\n }\n break\n }\n default: {\n if (formElementsConditionallyShown[element.name]) {\n break\n }\n const formElementConditionallyShown: FormElementConditionallyShown = {\n type: 'formElement',\n isHidden: !handleConditionallyShowElement(\n formElementsCtrl,\n element,\n errorCallback,\n ),\n }\n\n if (!formElementConditionallyShown.isHidden) {\n switch (element.type) {\n case 'compliance':\n case 'autocomplete':\n case 'radio':\n case 'checkboxes':\n case 'select': {\n if (\n element.conditionallyShowOptions &&\n Array.isArray(element.options)\n ) {\n formElementConditionallyShown.options =\n element.options.filter((option) =>\n handleConditionallyShowOption(\n formElementsCtrl,\n element,\n option,\n errorCallback,\n ),\n )\n }\n break\n }\n }\n }\n\n formElementsConditionallyShown[element.name] =\n formElementConditionallyShown\n }\n }\n\n return formElementsConditionallyShown\n },\n {},\n )\n}\n\nexport default generateFormElementsConditionallyShown\n"]}
@@ -0,0 +1,2 @@
1
+ export { evaluateConditionalOptionsPredicate, evaluateConditionalPredicate, evaluateConditionalPredicates, } from './evaluationService';
2
+ export { default as generateFormElementsConditionallyShown } from './generateFormElementsConditionallyShown';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateFormElementsConditionallyShown = exports.evaluateConditionalPredicates = exports.evaluateConditionalPredicate = exports.evaluateConditionalOptionsPredicate = void 0;
7
+ var evaluationService_1 = require("./evaluationService");
8
+ Object.defineProperty(exports, "evaluateConditionalOptionsPredicate", { enumerable: true, get: function () { return evaluationService_1.evaluateConditionalOptionsPredicate; } });
9
+ Object.defineProperty(exports, "evaluateConditionalPredicate", { enumerable: true, get: function () { return evaluationService_1.evaluateConditionalPredicate; } });
10
+ Object.defineProperty(exports, "evaluateConditionalPredicates", { enumerable: true, get: function () { return evaluationService_1.evaluateConditionalPredicates; } });
11
+ var generateFormElementsConditionallyShown_1 = require("./generateFormElementsConditionallyShown");
12
+ Object.defineProperty(exports, "generateFormElementsConditionallyShown", { enumerable: true, get: function () { return __importDefault(generateFormElementsConditionallyShown_1).default; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/conditionalLogicService/index.ts"],"names":[],"mappings":";;;;;;AAAA,yDAI4B;AAH1B,wIAAA,mCAAmC,OAAA;AACnC,iIAAA,4BAA4B,OAAA;AAC5B,kIAAA,6BAA6B,OAAA;AAG/B,mGAA4G;AAAnG,iLAAA,OAAO,OAA0C","sourcesContent":["export {\n evaluateConditionalOptionsPredicate,\n evaluateConditionalPredicate,\n evaluateConditionalPredicates,\n} from './evaluationService'\n\nexport { default as generateFormElementsConditionallyShown } from './generateFormElementsConditionallyShown'\n"]}
@@ -3,4 +3,5 @@ declare function forEachFormElement(elements: FormTypes.FormElement[], forEach:
3
3
  declare function forEachFormElementWithOptions(elements: FormTypes.FormElement[], forEach: (elementWithOptions: FormTypes.FormElementWithOptions, elements: FormTypes.FormElement[]) => void): void;
4
4
  declare function findFormElement(elements: FormTypes.FormElement[], predicate: (element: FormTypes.FormElement, elements: FormTypes.FormElement[]) => boolean, parentElements?: FormTypes.FormElement[]): FormTypes.FormElement | void;
5
5
  declare function parseFormElementOptionsSet(data: unknown): FormTypes.ChoiceElementOption[];
6
- export { forEachFormElement, forEachFormElementWithOptions, findFormElement, parseFormElementOptionsSet, };
6
+ declare function flattenFormElements(elements: FormTypes.FormElement[]): FormTypes.FormElement[];
7
+ export { forEachFormElement, forEachFormElementWithOptions, findFormElement, parseFormElementOptionsSet, flattenFormElements };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseFormElementOptionsSet = exports.findFormElement = exports.forEachFormElementWithOptions = exports.forEachFormElement = void 0;
3
+ exports.flattenFormElements = exports.parseFormElementOptionsSet = exports.findFormElement = exports.forEachFormElementWithOptions = exports.forEachFormElement = void 0;
4
4
  function forEachFormElement(elements, forEach) {
5
5
  findFormElement(elements, (formElement, parentElements) => {
6
6
  forEach(formElement, parentElements);
@@ -79,4 +79,17 @@ function parseFormElementOptionsSet(data) {
79
79
  }, []);
80
80
  }
81
81
  exports.parseFormElementOptionsSet = parseFormElementOptionsSet;
82
+ function flattenFormElements(elements) {
83
+ return elements.reduce((flattenedElements, element) => {
84
+ flattenedElements.push(element);
85
+ switch (element.type) {
86
+ case 'section':
87
+ case 'page': {
88
+ flattenedElements.push(...flattenFormElements(element.elements));
89
+ }
90
+ }
91
+ return flattenedElements;
92
+ }, []);
93
+ }
94
+ exports.flattenFormElements = flattenFormElements;
82
95
  //# sourceMappingURL=formElementsService.js.map
@@ -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'\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\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 if (\n formElement.type === 'select' ||\n formElement.type === 'autocomplete' ||\n formElement.type === 'checkboxes' ||\n formElement.type === 'radio' ||\n formElement.type === 'compliance'\n ) {\n forEach(formElement, parentElements)\n }\n return false\n })\n}\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\nfunction parseFormElementOptionsSet(\n data: unknown,\n): FormTypes.ChoiceElementOption[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.reduce(\n (\n options: FormTypes.ChoiceElementOption[],\n record: unknown,\n index: number,\n ) => {\n if (typeof record === 'string') {\n options.push({\n id: index.toString(),\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 id =\n typeof option.id === 'string' && option.id ? option.id : value\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 options.push({\n ...option,\n id,\n value,\n label,\n colour,\n })\n }\n return options\n },\n [],\n )\n}\n\nexport {\n forEachFormElement,\n forEachFormElementWithOptions,\n findFormElement,\n parseFormElementOptionsSet,\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'\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\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 if (\n formElement.type === 'select' ||\n formElement.type === 'autocomplete' ||\n formElement.type === 'checkboxes' ||\n formElement.type === 'radio' ||\n formElement.type === 'compliance'\n ) {\n forEach(formElement, parentElements)\n }\n return false\n })\n}\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\nfunction parseFormElementOptionsSet(\n data: unknown,\n): FormTypes.ChoiceElementOption[] {\n if (!Array.isArray(data)) {\n return []\n }\n return data.reduce(\n (\n options: FormTypes.ChoiceElementOption[],\n record: unknown,\n index: number,\n ) => {\n if (typeof record === 'string') {\n options.push({\n id: index.toString(),\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 id =\n typeof option.id === 'string' && option.id ? option.id : value\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 options.push({\n ...option,\n id,\n value,\n label,\n colour,\n })\n }\n return options\n },\n [],\n )\n}\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\nexport {\n forEachFormElement,\n forEachFormElementWithOptions,\n findFormElement,\n parseFormElementOptionsSet,\n flattenFormElements\n}\n"]}
@@ -0,0 +1,19 @@
1
+ export declare type FormElementsCtrl = {
2
+ model: Record<string, unknown>;
3
+ flattenedElements: import('@oneblink/types').FormTypes.FormElement[];
4
+ parentFormElementsCtrl?: FormElementsCtrl;
5
+ };
6
+ export declare type FormElementsConditionallyShown = Record<string, FormElementConditionallyShown>;
7
+ export declare type FormElementConditionallyShown = undefined | {
8
+ type: 'formElement';
9
+ isHidden: boolean;
10
+ options?: import('@oneblink/types').FormTypes.ChoiceElementOption[];
11
+ } | {
12
+ type: 'formElements';
13
+ isHidden: boolean;
14
+ formElements: FormElementsConditionallyShown | undefined;
15
+ } | {
16
+ type: 'repeatableSet';
17
+ isHidden: boolean;
18
+ entries: Record<string, FormElementsConditionallyShown | undefined>;
19
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"","sourcesContent":["export type FormElementsCtrl = {\n model: Record<string, unknown>\n flattenedElements: import('@oneblink/types').FormTypes.FormElement[]\n parentFormElementsCtrl?: FormElementsCtrl\n}\n\nexport type FormElementsConditionallyShown = Record<\n string,\n FormElementConditionallyShown\n>\n\nexport type FormElementConditionallyShown =\n | undefined\n | {\n type: 'formElement'\n isHidden: boolean\n options?: import('@oneblink/types').FormTypes.ChoiceElementOption[]\n }\n | {\n type: 'formElements'\n isHidden: boolean\n formElements: FormElementsConditionallyShown | undefined\n }\n | {\n type: 'repeatableSet'\n isHidden: boolean\n entries: Record<string, FormElementsConditionallyShown | undefined>\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": "0.3.3",
4
+ "version": "0.3.4-beta.1",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/sdk-core-js/issues"
@@ -1 +0,0 @@
1
- {"version":3,"file":"conditionalLogicService.js","sourceRoot":"","sources":["../src/conditionalLogicService.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, ConditionTypes, SubmissionTypes } from '@oneblink/types'\n\nconst fnMap = {\n '>': (lhs: number, rhs: number) => lhs > rhs,\n '>=': (lhs: number, rhs: number) => lhs >= rhs,\n '===': (lhs: number, rhs: number) => lhs === rhs,\n '!==': (lhs: number, rhs: number) => lhs !== rhs,\n '<=': (lhs: number, rhs: number) => lhs <= rhs,\n '<': (lhs: number, rhs: number) => lhs < rhs,\n}\n\nfunction evaluateConditionalOptionsPredicate({\n predicate,\n predicateElement,\n submission,\n}: {\n predicate: ConditionTypes.ConditionalPredicateOptions\n submission: SubmissionTypes.S3SubmissionData['submission']\n predicateElement: FormTypes.FormElementWithOptions\n}): boolean {\n return predicate.optionIds.some((optionId) => {\n const option = predicateElement.options?.find((o) => o.id === optionId)\n if (option) {\n const value = submission[predicateElement.name]\n if (Array.isArray(value)) {\n return value.some((modelValue) => {\n return modelValue === option.value\n })\n } else if (predicateElement.type === 'compliance' && value) {\n return option.value === (value as { value: unknown }).value\n } else {\n return option.value === value\n }\n } else {\n return false\n }\n })\n}\n\nfunction evaluateConditionalPredicate({\n predicate,\n predicateElement,\n submission,\n}: {\n predicate: ConditionTypes.ConditionalPredicate\n predicateElement: FormTypes.FormElement\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): boolean {\n if (\n !predicateElement ||\n predicateElement.type === 'page' ||\n predicateElement.type === 'section'\n ) {\n return false\n }\n switch (predicate.type) {\n case 'VALUE': {\n return !predicate.hasValue === !submission[predicateElement.name]\n }\n case 'NUMERIC': {\n const lhs = Number.parseFloat(submission[predicateElement.name] as string)\n const rhs =\n typeof predicate.value === 'string'\n ? Number.parseFloat(predicate.value)\n : predicate.value\n\n // if either of the values is not a number or the operator fn doesn't exist, hide the control\n const operatorFn = fnMap[predicate.operator]\n if (!operatorFn || Number.isNaN(lhs) || Number.isNaN(rhs)) return false\n\n return operatorFn(lhs, rhs)\n }\n case 'BETWEEN': {\n const value = Number.parseFloat(\n submission[predicateElement.name] as string,\n )\n if (Number.isNaN(value)) {\n return false\n }\n\n return value >= predicate.min && value <= predicate.max\n }\n case 'OPTIONS':\n default: {\n if (\n predicateElement.type !== 'select' &&\n predicateElement.type !== 'autocomplete' &&\n predicateElement.type !== 'radio' &&\n predicateElement.type !== 'checkboxes' &&\n predicateElement.type !== 'compliance'\n ) {\n return false\n }\n\n // If the predicate element does not have any options to evaluate,\n // we will show the element.\n // Unless the predicate element has dynamic options and\n // options have not been fetched yet.\n if (!Array.isArray(predicateElement.options)) {\n return predicateElement.optionsType !== 'DYNAMIC'\n } else {\n return evaluateConditionalOptionsPredicate({\n predicate,\n submission,\n predicateElement,\n })\n }\n }\n }\n}\n\nconst getPredicateElement = (\n elements: Array<FormTypes.FormElement>,\n elementId: string,\n): FormTypes.FormElement | void => {\n for (const element of elements) {\n if (element.type === 'page' || element.type === 'section') {\n const predicateElement = getPredicateElement(element.elements, elementId)\n if (predicateElement) {\n return predicateElement\n }\n } else if (element.id === elementId) {\n return element\n }\n }\n}\n\nfunction evaluateConditionalPredicates({\n isConditional,\n requiresAllConditionalPredicates,\n conditionalPredicates,\n formElements,\n submission,\n}: {\n isConditional: boolean\n requiresAllConditionalPredicates: boolean\n conditionalPredicates: ConditionTypes.ConditionalPredicate[]\n formElements: FormTypes.FormElement[]\n submission: SubmissionTypes.S3SubmissionData['submission']\n}): boolean {\n if (!isConditional || !conditionalPredicates.length) {\n return true\n }\n\n const predicateResults = []\n for (const predicate of conditionalPredicates) {\n const predicateElement = getPredicateElement(\n formElements,\n predicate.elementId,\n )\n if (!predicateElement) {\n throw new Error(\n 'Could not find element referenced in execution condition',\n )\n }\n\n const predicateIsSatisfied = evaluateConditionalPredicate({\n predicate,\n predicateElement,\n submission,\n })\n predicateResults.push(predicateIsSatisfied)\n if (requiresAllConditionalPredicates) {\n if (!predicateIsSatisfied) break\n } else {\n // Doesn't require all predicates\n if (predicateIsSatisfied) break\n }\n }\n\n if (requiresAllConditionalPredicates) {\n return !predicateResults.includes(false)\n } else {\n // Doesn't require all predicates\n return predicateResults.includes(true)\n }\n}\n\nexport {\n evaluateConditionalOptionsPredicate,\n evaluateConditionalPredicate,\n evaluateConditionalPredicates,\n}\n"]}