resolveConfig.js 9.1 KB

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