UNPKG

@atomic-ehr/fhirpath

Version:

A TypeScript implementation of FHIRPath

86 lines (70 loc) 2.5 kB
import type { FunctionDefinition, FunctionEvaluator, LiteralNode } from '../types'; import { Errors } from '../errors'; import { box, unbox } from '../boxing'; export const evaluate: FunctionEvaluator = async (input, context, args, evaluator) => { // Check single item in input if (input.length === 0) { return { value: [], context }; } if (input.length > 1) { throw Errors.stringSingletonRequired('indexOf', input.length); } const boxedInputValue = input[0]; if (!boxedInputValue) { return { value: [], context }; } const inputValue = unbox(boxedInputValue); if (typeof inputValue !== 'string') { throw Errors.stringOperationOnNonString('indexOf'); } // Check arguments if (args.length !== 1) { throw Errors.wrongArgumentCount('indexOf', 1, args.length); } // Evaluate substring argument const substringArg = args[0]; if (!substringArg) { throw Errors.argumentRequired('indexOf', 'substring argument'); } const substringResult = await evaluator(substringArg, input, context); if (substringResult.value.length === 0) { return { value: [], context }; } if (substringResult.value.length > 1) { throw Errors.singletonRequired('indexOf substring', substringResult.value.length); } const boxedSubstring = substringResult.value[0]; if (!boxedSubstring) { return { value: [], context }; } const substring = unbox(boxedSubstring); if (typeof substring !== 'string') { throw Errors.invalidStringOperation('indexOf', 'substring argument'); } // Handle empty substring - returns 0 per spec if (substring === '') { return { value: [box(0, { type: 'Integer', singleton: true })], context }; } // Find the index const index = inputValue.indexOf(substring); return { value: [box(index, { type: 'Integer', singleton: true })], context }; }; export const indexOfFunction: FunctionDefinition & { evaluate: FunctionEvaluator } = { name: 'indexOf', category: ['string'], description: 'Returns the 0-based index of the first position substring is found in the input string, or -1 if it is not found', examples: [ "'abcdefg'.indexOf('bc')", "'abcdefg'.indexOf('x')", "'abcdefg'.indexOf('abcdefg')" ], signatures: [{ name: 'indexOf', input: { type: 'String', singleton: true }, parameters: [ { name: 'substring', type: { type: 'String', singleton: true } } ], result: { type: 'Integer', singleton: true } }], evaluate };