1 |
|
2 | import getClosestVariable from './get-closest-variable';
|
3 |
|
4 |
|
5 | export default function getReplacedString(string, node, result, opts) {
|
6 | const replacedString = string.replace(
|
7 | matchVariables,
|
8 | (match, before, name1, name2, name3) => {
|
9 |
|
10 | if (before === '\\') {
|
11 | return match.slice(1);
|
12 | }
|
13 |
|
14 |
|
15 | const name = name1 || name2 || name3;
|
16 |
|
17 |
|
18 | const value = getClosestVariable(name, node.parent, opts);
|
19 |
|
20 |
|
21 | if (undefined === value) {
|
22 | const unresolvedOption = getUnresolvedOption(opts);
|
23 | const message = `Could not resolve the variable "$${name}" within "${string}"`;
|
24 |
|
25 |
|
26 | if ('throw' === unresolvedOption) {
|
27 | throw node.error(message, { word: name });
|
28 | } else if ('warn' === unresolvedOption) {
|
29 | node.warn(result, message, { word: name });
|
30 | }
|
31 |
|
32 | return match;
|
33 | }
|
34 |
|
35 |
|
36 | const stringifiedValue = `${before}${stringify(value)}`;
|
37 |
|
38 | return stringifiedValue;
|
39 | }
|
40 | );
|
41 |
|
42 | return replacedString;
|
43 | }
|
44 |
|
45 |
|
46 | const matchVariables = /(.?)(?:\$([A-z][\w-]*)|\$\(([A-z][\w-]*)\)|#\{\$([A-z][\w-]*)\})/g;
|
47 |
|
48 |
|
49 | const getUnresolvedOption = opts => matchUnresolvedOptions.test(Object(opts).unresolved) ? String(opts.unresolved).toLowerCase() : 'throw'
|
50 |
|
51 |
|
52 | const matchUnresolvedOptions = /^(ignore|throw|warn)$/i;
|
53 |
|
54 |
|
55 | const stringify = object => Array.isArray(object)
|
56 | ? `(${object.map(stringify).join(',')})`
|
57 | : Object(object) === object
|
58 | ? Object.keys(object).map(
|
59 | key => `${key}:${stringify(object[key])}`
|
60 | ).join(',')
|
61 | : String(object);
|