( nodes: ReactNode[], variables: Record<string, ReactNode>, )
| 76 | } |
| 77 | |
| 78 | function replaceVariables( |
| 79 | nodes: ReactNode[], |
| 80 | variables: Record<string, ReactNode>, |
| 81 | ): ReactNode[] { |
| 82 | if (_.isEmpty(variables)) { |
| 83 | return nodes; |
| 84 | } |
| 85 | const segments = nodes.map((node) => { |
| 86 | if (typeof node === "string") { |
| 87 | const segments: ReactNode[] = []; |
| 88 | let lastIndex = 0; |
| 89 | const variableRegex = /{([\w\.\[\]]+)}/g; |
| 90 | let match; |
| 91 | |
| 92 | while ((match = variableRegex.exec(node)) !== null) { |
| 93 | if (match.index > lastIndex) { |
| 94 | segments.push(node.slice(lastIndex, match.index)); |
| 95 | } |
| 96 | |
| 97 | const [fullMatch, name] = match; |
| 98 | const value = variables[name]; |
| 99 | segments.push(value ?? fullMatch); |
| 100 | |
| 101 | lastIndex = match.index + fullMatch.length; |
| 102 | } |
| 103 | |
| 104 | if (lastIndex < node.length) { |
| 105 | segments.push(node.slice(lastIndex)); |
| 106 | } |
| 107 | |
| 108 | return segments; |
| 109 | } else if (isReactElement(node)) { |
| 110 | const props = node.props as { children?: ReactNode }; |
| 111 | return createElement( |
| 112 | node.type, |
| 113 | { ...props }, |
| 114 | ...replaceVariables(_.castArray(props.children || []), variables), |
| 115 | ); |
| 116 | } |
| 117 | return node; |
| 118 | }); |
| 119 | |
| 120 | return _.flatMap(segments); |
| 121 | } |
| 122 | |
| 123 | function isReactElement(node: ReactNode): node is ReactElement { |
| 124 | return ( |
nothing calls this directly
no test coverage detected