-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmatchCodeListFormatting.ts
78 lines (71 loc) · 3.34 KB
/
matchCodeListFormatting.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
* Copyright (c) 2024 The Ontario Institute for Cancer Research. All rights reserved
*
* This program and the accompanying materials are made available under the terms of
* the GNU Affero General Public License v3.0. You should have received a copy of the
* GNU Affero General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import { TypeUtils, type SchemaField, type StringFieldRestrictionsObject } from '@overture-stack/lectern-dictionary';
/**
* Loop through restrictins and nested conditional restrictions finding every codeList restriction and collect all their
* values into a single array. This is used to format data values during parsing.
*/
const collectAllNestedCodeLists = (
restrictions: StringFieldRestrictionsObject | StringFieldRestrictionsObject[],
): string[] => {
return TypeUtils.asArray(restrictions).flatMap((restrictionsObject) => {
if ('if' in restrictionsObject) {
const thenCodeLists = restrictionsObject.then ? collectAllNestedCodeLists(restrictionsObject.then) : [];
const elseCodeLists = restrictionsObject.else ? collectAllNestedCodeLists(restrictionsObject.else) : [];
return [...thenCodeLists, ...elseCodeLists];
} else {
return restrictionsObject.codeList ? restrictionsObject.codeList : [];
}
});
};
/**
* Given a string value, look for any matching values in code list restrictions and return that
* value. This is used by the convertValue functions to ensure the value returned matches the letter
* cases of the corresponding value in the code list.
*
* @example
* // Given a field `fieldWithCodeList` that has a code list restriction `["Apple", "Banana"]`
* const originalValue = 'banana';
* const matchingValue = matchCodeListFormatting(originalValue, fieldWithCodeList);
*
* // matchingValue will equal `Banana`;
*
* @param value
* @param fieldDefinition
* @returns
*/
export function matchCodeListFormatting(value: string, fieldDefinition: SchemaField): string {
const { valueType } = fieldDefinition;
if (valueType === 'string') {
const codeList = fieldDefinition.restrictions && collectAllNestedCodeLists(fieldDefinition.restrictions);
if (Array.isArray(codeList)) {
// We have found a code list to compare to!
// prepare the value for comparison by making it lower case
const candidate = value.toLowerCase();
// look for a match
const match = codeList.find((option) => option.trim().toLowerCase() === candidate);
if (match !== undefined) {
// we have a match! return it!
return match;
}
}
}
// no match was found, return original value
return value;
}