resolveConfig.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. Object.defineProperty(exports, "default", {
  6. enumerable: true,
  7. get: function() {
  8. return resolveConfig;
  9. }
  10. });
  11. const _negateValue = /*#__PURE__*/ _interop_require_default(require("./negateValue"));
  12. const _corePluginList = /*#__PURE__*/ _interop_require_default(require("../corePluginList"));
  13. const _configurePlugins = /*#__PURE__*/ _interop_require_default(require("./configurePlugins"));
  14. const _colors = /*#__PURE__*/ _interop_require_default(require("../public/colors"));
  15. const _defaults = require("./defaults");
  16. const _toPath = require("./toPath");
  17. const _normalizeConfig = require("./normalizeConfig");
  18. const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("./isPlainObject"));
  19. const _cloneDeep = require("./cloneDeep");
  20. const _pluginUtils = require("./pluginUtils");
  21. const _withAlphaVariable = require("./withAlphaVariable");
  22. const _toColorValue = /*#__PURE__*/ _interop_require_default(require("./toColorValue"));
  23. function _interop_require_default(obj) {
  24. return obj && obj.__esModule ? obj : {
  25. default: obj
  26. };
  27. }
  28. function isFunction(input) {
  29. return typeof input === "function";
  30. }
  31. function mergeWith(target, ...sources) {
  32. let customizer = sources.pop();
  33. for (let source of sources){
  34. for(let k in source){
  35. let merged = customizer(target[k], source[k]);
  36. if (merged === undefined) {
  37. if ((0, _isPlainObject.default)(target[k]) && (0, _isPlainObject.default)(source[k])) {
  38. target[k] = mergeWith({}, target[k], source[k], customizer);
  39. } else {
  40. target[k] = source[k];
  41. }
  42. } else {
  43. target[k] = merged;
  44. }
  45. }
  46. }
  47. return target;
  48. }
  49. const configUtils = {
  50. colors: _colors.default,
  51. negative (scale) {
  52. // TODO: Log that this function isn't really needed anymore?
  53. return Object.keys(scale).filter((key)=>scale[key] !== "0").reduce((negativeScale, key)=>{
  54. let negativeValue = (0, _negateValue.default)(scale[key]);
  55. if (negativeValue !== undefined) {
  56. negativeScale[`-${key}`] = negativeValue;
  57. }
  58. return negativeScale;
  59. }, {});
  60. },
  61. breakpoints (screens) {
  62. return Object.keys(screens).filter((key)=>typeof screens[key] === "string").reduce((breakpoints, key)=>({
  63. ...breakpoints,
  64. [`screen-${key}`]: screens[key]
  65. }), {});
  66. }
  67. };
  68. function value(valueToResolve, ...args) {
  69. return isFunction(valueToResolve) ? valueToResolve(...args) : valueToResolve;
  70. }
  71. function collectExtends(items) {
  72. return items.reduce((merged, { extend })=>{
  73. return mergeWith(merged, extend, (mergedValue, extendValue)=>{
  74. if (mergedValue === undefined) {
  75. return [
  76. extendValue
  77. ];
  78. }
  79. if (Array.isArray(mergedValue)) {
  80. return [
  81. extendValue,
  82. ...mergedValue
  83. ];
  84. }
  85. return [
  86. extendValue,
  87. mergedValue
  88. ];
  89. });
  90. }, {});
  91. }
  92. function mergeThemes(themes) {
  93. return {
  94. ...themes.reduce((merged, theme)=>(0, _defaults.defaults)(merged, theme), {}),
  95. // In order to resolve n config objects, we combine all of their `extend` properties
  96. // into arrays instead of objects so they aren't overridden.
  97. extend: collectExtends(themes)
  98. };
  99. }
  100. function mergeExtensionCustomizer(merged, value) {
  101. // When we have an array of objects, we do want to merge it
  102. if (Array.isArray(merged) && (0, _isPlainObject.default)(merged[0])) {
  103. return merged.concat(value);
  104. }
  105. // When the incoming value is an array, and the existing config is an object, prepend the existing object
  106. if (Array.isArray(value) && (0, _isPlainObject.default)(value[0]) && (0, _isPlainObject.default)(merged)) {
  107. return [
  108. merged,
  109. ...value
  110. ];
  111. }
  112. // Override arrays (for example for font-families, box-shadows, ...)
  113. if (Array.isArray(value)) {
  114. return value;
  115. }
  116. // Execute default behaviour
  117. return undefined;
  118. }
  119. function mergeExtensions({ extend , ...theme }) {
  120. return mergeWith(theme, extend, (themeValue, extensions)=>{
  121. // The `extend` property is an array, so we need to check if it contains any functions
  122. if (!isFunction(themeValue) && !extensions.some(isFunction)) {
  123. return mergeWith({}, themeValue, ...extensions, mergeExtensionCustomizer);
  124. }
  125. return (resolveThemePath, utils)=>mergeWith({}, ...[
  126. themeValue,
  127. ...extensions
  128. ].map((e)=>value(e, resolveThemePath, utils)), mergeExtensionCustomizer);
  129. });
  130. }
  131. /**
  132. *
  133. * @param {string} key
  134. * @return {Iterable<string[] & {alpha: string | undefined}>}
  135. */ function* toPaths(key) {
  136. let path = (0, _toPath.toPath)(key);
  137. if (path.length === 0) {
  138. return;
  139. }
  140. yield path;
  141. if (Array.isArray(key)) {
  142. return;
  143. }
  144. let pattern = /^(.*?)\s*\/\s*([^/]+)$/;
  145. let matches = key.match(pattern);
  146. if (matches !== null) {
  147. let [, prefix, alpha] = matches;
  148. let newPath = (0, _toPath.toPath)(prefix);
  149. newPath.alpha = alpha;
  150. yield newPath;
  151. }
  152. }
  153. function resolveFunctionKeys(object) {
  154. // theme('colors.red.500 / 0.5') -> ['colors', 'red', '500 / 0', '5]
  155. const resolvePath = (key, defaultValue)=>{
  156. for (const path of toPaths(key)){
  157. let index = 0;
  158. let val = object;
  159. while(val !== undefined && val !== null && index < path.length){
  160. val = val[path[index++]];
  161. let shouldResolveAsFn = isFunction(val) && (path.alpha === undefined || index <= path.length - 1);
  162. val = shouldResolveAsFn ? val(resolvePath, configUtils) : val;
  163. }
  164. if (val !== undefined) {
  165. if (path.alpha !== undefined) {
  166. let normalized = (0, _pluginUtils.parseColorFormat)(val);
  167. return (0, _withAlphaVariable.withAlphaValue)(normalized, path.alpha, (0, _toColorValue.default)(normalized));
  168. }
  169. if ((0, _isPlainObject.default)(val)) {
  170. return (0, _cloneDeep.cloneDeep)(val);
  171. }
  172. return val;
  173. }
  174. }
  175. return defaultValue;
  176. };
  177. Object.assign(resolvePath, {
  178. theme: resolvePath,
  179. ...configUtils
  180. });
  181. return Object.keys(object).reduce((resolved, key)=>{
  182. resolved[key] = isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key];
  183. return resolved;
  184. }, {});
  185. }
  186. function extractPluginConfigs(configs) {
  187. let allConfigs = [];
  188. configs.forEach((config)=>{
  189. allConfigs = [
  190. ...allConfigs,
  191. config
  192. ];
  193. var _config_plugins;
  194. const plugins = (_config_plugins = config === null || config === void 0 ? void 0 : config.plugins) !== null && _config_plugins !== void 0 ? _config_plugins : [];
  195. if (plugins.length === 0) {
  196. return;
  197. }
  198. plugins.forEach((plugin)=>{
  199. if (plugin.__isOptionsFunction) {
  200. plugin = plugin();
  201. }
  202. var _plugin_config;
  203. allConfigs = [
  204. ...allConfigs,
  205. ...extractPluginConfigs([
  206. (_plugin_config = plugin === null || plugin === void 0 ? void 0 : plugin.config) !== null && _plugin_config !== void 0 ? _plugin_config : {}
  207. ])
  208. ];
  209. });
  210. });
  211. return allConfigs;
  212. }
  213. function resolveCorePlugins(corePluginConfigs) {
  214. const result = [
  215. ...corePluginConfigs
  216. ].reduceRight((resolved, corePluginConfig)=>{
  217. if (isFunction(corePluginConfig)) {
  218. return corePluginConfig({
  219. corePlugins: resolved
  220. });
  221. }
  222. return (0, _configurePlugins.default)(corePluginConfig, resolved);
  223. }, _corePluginList.default);
  224. return result;
  225. }
  226. function resolvePluginLists(pluginLists) {
  227. const result = [
  228. ...pluginLists
  229. ].reduceRight((resolved, pluginList)=>{
  230. return [
  231. ...resolved,
  232. ...pluginList
  233. ];
  234. }, []);
  235. return result;
  236. }
  237. function resolveConfig(configs) {
  238. let allConfigs = [
  239. ...extractPluginConfigs(configs),
  240. {
  241. prefix: "",
  242. important: false,
  243. separator: ":"
  244. }
  245. ];
  246. var _t_theme, _c_plugins;
  247. return (0, _normalizeConfig.normalizeConfig)((0, _defaults.defaults)({
  248. theme: resolveFunctionKeys(mergeExtensions(mergeThemes(allConfigs.map((t)=>{
  249. return (_t_theme = t === null || t === void 0 ? void 0 : t.theme) !== null && _t_theme !== void 0 ? _t_theme : {};
  250. })))),
  251. corePlugins: resolveCorePlugins(allConfigs.map((c)=>c.corePlugins)),
  252. plugins: resolvePluginLists(configs.map((c)=>{
  253. return (_c_plugins = c === null || c === void 0 ? void 0 : c.plugins) !== null && _c_plugins !== void 0 ? _c_plugins : [];
  254. }))
  255. }, ...allConfigs));
  256. }