UNPKG

1.98 kBJavaScriptView Raw
1// tooling
2import getClosestVariable from './get-closest-variable';
3
4// return content with its variables replaced by the corresponding values of a node
5export default function getReplacedString(string, node, result, opts) {
6 const replacedString = string.replace(
7 matchVariables,
8 (match, before, name1, name2, name3) => {
9 // conditionally return an (unescaped) match
10 if (before === '\\') {
11 return match.slice(1);
12 }
13
14 // the first matching variable name
15 const name = name1 || name2 || name3;
16
17 // the closest variable value
18 const value = getClosestVariable(name, node.parent, opts);
19
20 // if a variable has not been resolved
21 if (undefined === value) {
22 const unresolvedOption = getUnresolvedOption(opts);
23 const message = `Could not resolve the variable "$${name}" within "${string}"`;
24
25 // conditionally throw or warn the user of the unresolved variable
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 // the stringified value
36 const stringifiedValue = `${before}${stringify(value)}`;
37
38 return stringifiedValue;
39 }
40 );
41
42 return replacedString;
43}
44
45// match all $name, $(name), and #{$name} variables (and catch the character before it)
46const matchVariables = /(.?)(?:\$([A-z][\w-]*)|\$\(([A-z][\w-]*)\)|#\{\$([A-z][\w-]*)\})/g;
47
48// get the unresolved variables option
49const getUnresolvedOption = opts => matchUnresolvedOptions.test(Object(opts).unresolved) ? String(opts.unresolved).toLowerCase() : 'throw'
50
51// match unresolved variables options
52const matchUnresolvedOptions = /^(ignore|throw|warn)$/i;
53
54// return a sass stringified variable
55const 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);