index.es.mjs 7.9 KB

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