xref: /expo/packages/@expo/cli/src/utils/template.ts (revision 1117330a)
1*1117330aSMark Lawlor/**
2*1117330aSMark Lawlor * Simple unsafe interpolation for template strings. Does NOT escape values.
3*1117330aSMark Lawlor *
4*1117330aSMark Lawlor * Arguments can be named or numeric.
5*1117330aSMark Lawlor *
6*1117330aSMark Lawlor * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
7*1117330aSMark Lawlor *
8*1117330aSMark Lawlor * @example
9*1117330aSMark Lawlor * const t1Closure = unsafeTemplate`${0}${1}${0}!`;
10*1117330aSMark Lawlor * // const t1Closure = unsafeTemplate(["","","","!"],0,1,0);
11*1117330aSMark Lawlor * t1Closure("Y", "A"); // "YAY!"
12*1117330aSMark Lawlor *
13*1117330aSMark Lawlor * @example
14*1117330aSMark Lawlor * const t2Closure = unsafeTemplate`${0} ${"foo"}!`;
15*1117330aSMark Lawlor * // const t2Closure = unsafeTemplate([""," ","!"],0,"foo");
16*1117330aSMark Lawlor * t2Closure("Hello", { foo: "World" }); // "Hello World!"
17*1117330aSMark Lawlor *
18*1117330aSMark Lawlor * @example
19*1117330aSMark Lawlor * const t3Closure = unsafeTemplate`I'm ${"name"}. I'm almost ${"age"} years old.`;
20*1117330aSMark Lawlor * // const t3Closure = unsafeTemplate(["I'm ", ". I'm almost ", " years old."], "name", "age");
21*1117330aSMark Lawlor * t3Closure("foo", { name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
22*1117330aSMark Lawlor * t3Closure({ name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
23*1117330aSMark Lawlor */
24*1117330aSMark Lawlorexport function unsafeTemplate(strings: TemplateStringsArray, ...keys: (string | number)[]) {
25*1117330aSMark Lawlor  return (
26*1117330aSMark Lawlor    ...values: (string | number)[] | [...(string | number)[], Record<string | number, string>]
27*1117330aSMark Lawlor  ) => {
28*1117330aSMark Lawlor    const lastValue = values[values.length - 1];
29*1117330aSMark Lawlor    const dict = typeof lastValue === 'object' ? lastValue : {};
30*1117330aSMark Lawlor    const result = [strings[0]];
31*1117330aSMark Lawlor    keys.forEach((key, i) => {
32*1117330aSMark Lawlor      const value = typeof key === 'number' && Number.isInteger(key) ? values[key] : dict[key];
33*1117330aSMark Lawlor      result.push(value as string, strings[i + 1]);
34*1117330aSMark Lawlor    });
35*1117330aSMark Lawlor    return result.join('');
36*1117330aSMark Lawlor  };
37*1117330aSMark Lawlor}
38