/
interpolation.ts
86 lines (79 loc) · 2.4 KB
/
interpolation.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
79
80
81
82
83
84
85
86
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import {isPrimitive} from 'jest-get-type';
import {format as pretty} from 'pretty-format';
export type Template = Record<string, unknown>;
export type Templates = Array<Template>;
export type Headings = Array<string>;
export const interpolateVariables = (
title: string,
template: Template,
index: number,
): string =>
Object.keys(template)
.reduce(getMatchingKeyPaths(title), []) // aka flatMap
.reduce(replaceKeyPathWithValue(template), title)
.replace('$#', '' + index);
const getMatchingKeyPaths = (title: string) => (
matches: Headings,
key: string,
) => matches.concat(title.match(new RegExp(`\\$${key}[\\.\\w]*`, 'g')) || []);
const replaceKeyPathWithValue = (template: Template) => (
title: string,
match: string,
) => {
const keyPath = match.replace('$', '').split('.');
const value = getPath(template, keyPath);
if (isPrimitive(value)) {
return title.replace(match, String(value));
}
return title.replace(match, pretty(value, {maxDepth: 1, min: true}));
};
/* eslint import/export: 0*/
export function getPath<
Obj extends Template,
A extends keyof Obj,
B extends keyof Obj[A],
C extends keyof Obj[A][B],
D extends keyof Obj[A][B][C],
E extends keyof Obj[A][B][C][D]
>(obj: Obj, path: [A, B, C, D, E]): Obj[A][B][C][D][E];
export function getPath<
Obj extends Template,
A extends keyof Obj,
B extends keyof Obj[A],
C extends keyof Obj[A][B],
D extends keyof Obj[A][B][C]
>(obj: Obj, path: [A, B, C, D]): Obj[A][B][C][D];
export function getPath<
Obj extends Template,
A extends keyof Obj,
B extends keyof Obj[A],
C extends keyof Obj[A][B]
>(obj: Obj, path: [A, B, C]): Obj[A][B][C];
export function getPath<
Obj extends Template,
A extends keyof Obj,
B extends keyof Obj[A]
>(obj: Obj, path: [A, B]): Obj[A][B];
export function getPath<Obj extends Template, A extends keyof Obj>(
obj: Obj,
path: [A],
): Obj[A];
export function getPath<Obj extends Template>(
obj: Obj,
path: Array<string>,
): unknown;
export function getPath(
template: Template,
[head, ...tail]: Array<string>,
): unknown {
if (!head || !template.hasOwnProperty || !template.hasOwnProperty(head))
return template;
return getPath(template[head] as Template, tail);
}