index.cjs.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. 'use strict';
  2. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  3. var parser = _interopDefault(require('postcss-values-parser'));
  4. var fs = _interopDefault(require('fs'));
  5. var path = _interopDefault(require('path'));
  6. var postcss = _interopDefault(require('postcss'));
  7. function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  8. try {
  9. var info = gen[key](arg);
  10. var value = info.value;
  11. } catch (error) {
  12. reject(error);
  13. return;
  14. }
  15. if (info.done) {
  16. resolve(value);
  17. } else {
  18. Promise.resolve(value).then(_next, _throw);
  19. }
  20. }
  21. function _asyncToGenerator(fn) {
  22. return function () {
  23. var self = this,
  24. args = arguments;
  25. return new Promise(function (resolve, reject) {
  26. var gen = fn.apply(self, args);
  27. function _next(value) {
  28. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
  29. }
  30. function _throw(err) {
  31. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
  32. }
  33. _next(undefined);
  34. });
  35. };
  36. }
  37. const dashedMatch = /^--/; // returns the value of a css function as a string
  38. var getFnValue = (node => {
  39. const value = String(node.nodes.slice(1, -1));
  40. return dashedMatch.test(value) ? value : undefined;
  41. });
  42. var updateEnvValue = ((node, variables) => {
  43. // get the value of a css function as a string
  44. const value = getFnValue(node);
  45. if (typeof value === 'string' && value in variables) {
  46. node.replaceWith(...asClonedArrayWithBeforeSpacing(variables[value], node.raws.before));
  47. }
  48. }); // return an array with its nodes cloned, preserving the raw
  49. const asClonedArrayWithBeforeSpacing = (array, beforeSpacing) => {
  50. const clonedArray = asClonedArray(array, null);
  51. if (clonedArray[0]) {
  52. clonedArray[0].raws.before = beforeSpacing;
  53. }
  54. return clonedArray;
  55. }; // return an array with its nodes cloned
  56. const asClonedArray = (array, parent) => array.map(node => asClonedNode(node, parent)); // return a cloned node
  57. const asClonedNode = (node, parent) => {
  58. const cloneNode = new node.constructor(node);
  59. for (const key in node) {
  60. if (key === 'parent') {
  61. cloneNode.parent = parent;
  62. } else if (Object(node[key]).constructor === Array) {
  63. cloneNode[key] = asClonedArray(node.nodes, cloneNode);
  64. } else if (Object(node[key]).constructor === Object) {
  65. cloneNode[key] = Object.assign({}, node[key]);
  66. }
  67. }
  68. return cloneNode;
  69. };
  70. // returns whether a node is a css env() function
  71. var isEnvFunc = (node => node && node.type === 'func' && node.value === 'env');
  72. function walk(node, fn) {
  73. node.nodes.slice(0).forEach(childNode => {
  74. if (childNode.nodes) {
  75. walk(childNode, fn);
  76. }
  77. if (isEnvFunc(childNode)) {
  78. fn(childNode);
  79. }
  80. });
  81. }
  82. var getReplacedValue = ((originalValue, variables) => {
  83. // get the ast of the original value
  84. const ast = parser(originalValue).parse(); // walk all of the css env() functions
  85. walk(ast, node => {
  86. // update the environment value for the css env() function
  87. updateEnvValue(node, variables);
  88. }); // return the stringified ast
  89. return String(ast);
  90. });
  91. // returns whether a node is an at-rule
  92. var isAtrule = (node => node && node.type === 'atrule');
  93. // returns whether a node is a declaration
  94. var isDecl = (node => node && node.type === 'decl');
  95. var getSupportedValue = (node => isAtrule(node) && node.params || isDecl(node) && node.value);
  96. function setSupportedValue (node, value) {
  97. if (isAtrule(node)) {
  98. node.params = value;
  99. }
  100. if (isDecl(node)) {
  101. node.value = value;
  102. }
  103. }
  104. /* Import Custom Properties from Object
  105. /* ========================================================================== */
  106. function importEnvironmentVariablesFromObject(object) {
  107. const environmentVariables = Object.assign({}, Object(object).environmentVariables || Object(object)['environment-variables']);
  108. for (const key in environmentVariables) {
  109. environmentVariables[key] = parser(environmentVariables[key]).parse().nodes;
  110. }
  111. return environmentVariables;
  112. }
  113. /* Import Custom Properties from JSON file
  114. /* ========================================================================== */
  115. function importEnvironmentVariablesFromJSONFile(_x) {
  116. return _importEnvironmentVariablesFromJSONFile.apply(this, arguments);
  117. }
  118. /* Import Custom Properties from JS file
  119. /* ========================================================================== */
  120. function _importEnvironmentVariablesFromJSONFile() {
  121. _importEnvironmentVariablesFromJSONFile = _asyncToGenerator(function* (from) {
  122. const object = yield readJSON(path.resolve(from));
  123. return importEnvironmentVariablesFromObject(object);
  124. });
  125. return _importEnvironmentVariablesFromJSONFile.apply(this, arguments);
  126. }
  127. function importEnvironmentVariablesFromJSFile(_x2) {
  128. return _importEnvironmentVariablesFromJSFile.apply(this, arguments);
  129. }
  130. /* Import Custom Properties from Sources
  131. /* ========================================================================== */
  132. function _importEnvironmentVariablesFromJSFile() {
  133. _importEnvironmentVariablesFromJSFile = _asyncToGenerator(function* (from) {
  134. const object = yield Promise.resolve(require(path.resolve(from)));
  135. return importEnvironmentVariablesFromObject(object);
  136. });
  137. return _importEnvironmentVariablesFromJSFile.apply(this, arguments);
  138. }
  139. function importEnvironmentVariablesFromSources(sources) {
  140. return sources.map(source => {
  141. if (source instanceof Promise) {
  142. return source;
  143. } else if (source instanceof Function) {
  144. return source();
  145. } // read the source as an object
  146. const opts = source === Object(source) ? source : {
  147. from: String(source)
  148. }; // skip objects with Custom Properties
  149. if (opts.environmentVariables || opts['environment-variables']) {
  150. return opts;
  151. } // source pathname
  152. const from = String(opts.from || ''); // type of file being read from
  153. const type = (opts.type || path.extname(from).slice(1)).toLowerCase();
  154. return {
  155. type,
  156. from
  157. };
  158. }).reduce(
  159. /*#__PURE__*/
  160. function () {
  161. var _ref = _asyncToGenerator(function* (environmentVariables, source) {
  162. const _ref2 = yield source,
  163. type = _ref2.type,
  164. from = _ref2.from;
  165. if (type === 'js') {
  166. return Object.assign(environmentVariables, (yield importEnvironmentVariablesFromJSFile(from)));
  167. }
  168. if (type === 'json') {
  169. return Object.assign(environmentVariables, (yield importEnvironmentVariablesFromJSONFile(from)));
  170. }
  171. return Object.assign(environmentVariables, importEnvironmentVariablesFromObject((yield source)));
  172. });
  173. return function (_x3, _x4) {
  174. return _ref.apply(this, arguments);
  175. };
  176. }(), {});
  177. }
  178. /* Helper utilities
  179. /* ========================================================================== */
  180. const readFile = from => new Promise((resolve, reject) => {
  181. fs.readFile(from, 'utf8', (error, result) => {
  182. if (error) {
  183. reject(error);
  184. } else {
  185. resolve(result);
  186. }
  187. });
  188. });
  189. const readJSON =
  190. /*#__PURE__*/
  191. function () {
  192. var _ref3 = _asyncToGenerator(function* (from) {
  193. return JSON.parse((yield readFile(from)));
  194. });
  195. return function readJSON(_x5) {
  196. return _ref3.apply(this, arguments);
  197. };
  198. }();
  199. var index = postcss.plugin('postcss-env-fn', opts => {
  200. // sources to import environment variables from
  201. const importFrom = [].concat(Object(opts).importFrom || []); // promise any environment variables are imported
  202. const environmentVariablesPromise = importEnvironmentVariablesFromSources(importFrom);
  203. return (
  204. /*#__PURE__*/
  205. function () {
  206. var _ref = _asyncToGenerator(function* (root) {
  207. const environmentVariables = yield environmentVariablesPromise;
  208. root.walk(node => {
  209. const supportedValue = getSupportedValue(node);
  210. if (supportedValue) {
  211. const replacedValue = getReplacedValue(supportedValue, environmentVariables);
  212. if (replacedValue !== supportedValue) {
  213. setSupportedValue(node, replacedValue);
  214. }
  215. }
  216. });
  217. });
  218. return function (_x) {
  219. return _ref.apply(this, arguments);
  220. };
  221. }()
  222. );
  223. });
  224. module.exports = index;
  225. //# sourceMappingURL=index.cjs.js.map