Skip to content

Commit 65d4568

Browse files
committed
Allow plugins to provide their own config object
1 parent cf9c991 commit 65d4568

3 files changed

Lines changed: 151 additions & 29 deletions

File tree

__tests__/resolveConfig.test.js

Lines changed: 123 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,15 +1359,13 @@ test('more than two config objects can be resolved', () => {
13591359
},
13601360
})
13611361
})
1362+
13621363
test('plugin config modifications are applied', () => {
13631364
const userConfig = {
13641365
plugins: [
13651366
{
1366-
modifyConfig(config) {
1367-
return {
1368-
...config,
1369-
prefix: 'tw-',
1370-
}
1367+
config: {
1368+
prefix: 'tw-',
13711369
},
13721370
handler() {},
13731371
},
@@ -1415,11 +1413,8 @@ test('user config takes precedence over plugin config modifications', () => {
14151413
prefix: 'user-',
14161414
plugins: [
14171415
{
1418-
modifyConfig(config) {
1419-
return {
1420-
...config,
1421-
prefix: 'plugin-',
1422-
}
1416+
config: {
1417+
prefix: 'tw-',
14231418
},
14241419
handler() {},
14251420
},
@@ -1461,3 +1456,121 @@ test('user config takes precedence over plugin config modifications', () => {
14611456
plugins: userConfig.plugins,
14621457
})
14631458
})
1459+
1460+
test('plugin config can register plugins that also have config', () => {
1461+
const userConfig = {
1462+
plugins: [
1463+
{
1464+
config: {
1465+
prefix: 'tw-',
1466+
plugins: [
1467+
{
1468+
config: {
1469+
important: true,
1470+
},
1471+
handler() {}
1472+
},
1473+
{
1474+
config: {
1475+
separator: '__',
1476+
},
1477+
handler() {}
1478+
},
1479+
]
1480+
},
1481+
handler() {},
1482+
},
1483+
],
1484+
}
1485+
1486+
const defaultConfig = {
1487+
prefix: '',
1488+
important: false,
1489+
separator: ':',
1490+
theme: {
1491+
screens: {
1492+
mobile: '400px',
1493+
},
1494+
},
1495+
variants: {
1496+
appearance: ['responsive'],
1497+
borderCollapse: [],
1498+
borderColors: ['responsive', 'hover', 'focus'],
1499+
},
1500+
}
1501+
1502+
const result = resolveConfig([userConfig, defaultConfig])
1503+
1504+
expect(result).toEqual({
1505+
prefix: 'tw-',
1506+
important: true,
1507+
separator: '__',
1508+
theme: {
1509+
screens: {
1510+
mobile: '400px',
1511+
},
1512+
},
1513+
variants: {
1514+
appearance: ['responsive'],
1515+
borderCollapse: [],
1516+
borderColors: ['responsive', 'hover', 'focus'],
1517+
},
1518+
plugins: userConfig.plugins,
1519+
})
1520+
})
1521+
1522+
test('plugin configs take precedence over plugin configs registered by that plugin', () => {
1523+
const userConfig = {
1524+
plugins: [
1525+
{
1526+
config: {
1527+
prefix: 'outer-',
1528+
plugins: [
1529+
{
1530+
config: {
1531+
prefix: 'inner-',
1532+
},
1533+
handler() {}
1534+
}
1535+
]
1536+
},
1537+
handler() {},
1538+
},
1539+
],
1540+
}
1541+
1542+
const defaultConfig = {
1543+
prefix: '',
1544+
important: false,
1545+
separator: ':',
1546+
theme: {
1547+
screens: {
1548+
mobile: '400px',
1549+
},
1550+
},
1551+
variants: {
1552+
appearance: ['responsive'],
1553+
borderCollapse: [],
1554+
borderColors: ['responsive', 'hover', 'focus'],
1555+
},
1556+
}
1557+
1558+
const result = resolveConfig([userConfig, defaultConfig])
1559+
1560+
expect(result).toEqual({
1561+
prefix: 'outer-',
1562+
important: false,
1563+
separator: ':',
1564+
theme: {
1565+
screens: {
1566+
mobile: '400px',
1567+
},
1568+
},
1569+
variants: {
1570+
appearance: ['responsive'],
1571+
borderCollapse: [],
1572+
borderColors: ['responsive', 'hover', 'focus'],
1573+
},
1574+
plugins: userConfig.plugins,
1575+
})
1576+
})

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const getConfigFunction = config => () => {
5656
}
5757

5858
const configObject = _.isObject(config) ? _.get(config, 'config', config) : require(config)
59-
59+
6060
return resolveConfig([configObject, defaultConfig])
6161
}
6262

src/util/resolveConfig.js

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import some from 'lodash/some'
22
import mergeWith from 'lodash/mergeWith'
3+
import isEmpty from 'lodash/isEmpty'
34
import isFunction from 'lodash/isFunction'
45
import isUndefined from 'lodash/isUndefined'
56
import defaults from 'lodash/defaults'
6-
import identity from 'lodash/identity'
7-
import get from 'lodash/get'
87
import map from 'lodash/map'
98
import get from 'lodash/get'
109
import toPath from 'lodash/toPath'
@@ -24,12 +23,6 @@ const configUtils = {
2423
},
2524
}
2625

27-
function applyPluginConfigModifications(config, plugins) {
28-
return plugins.reduce((modified, plugin) => {
29-
return get(plugin, 'modifyConfig', identity)(modified)
30-
}, config)
31-
}
32-
3326
function value(valueToResolve, ...args) {
3427
return isFunction(valueToResolve) ? valueToResolve(...args) : valueToResolve
3528
}
@@ -102,25 +95,41 @@ function resolveFunctionKeys(object) {
10295
}, {})
10396
}
10497

105-
export default function resolveConfig([userConfig, defaultConfig]) {
106-
const modifiedDefaultConfig = applyPluginConfigModifications(
107-
defaultConfig,
108-
get(userConfig, 'plugins', [])
109-
)
110-
const configs = [userConfig, modifiedDefaultConfig]
98+
function extractPluginConfigs(configs) {
99+
let allConfigs = []
100+
101+
configs.forEach(config => {
102+
allConfigs = [...allConfigs, config]
103+
104+
const plugins = get(config, 'plugins', [])
105+
106+
if (plugins.length === 0) {
107+
return
108+
}
109+
110+
plugins.forEach(plugin => {
111+
allConfigs = [...allConfigs, ...extractPluginConfigs([get(plugin, 'config', {})])]
112+
})
113+
})
114+
115+
return allConfigs
116+
}
117+
118+
export default function resolveConfig(configs) {
119+
const allConfigs = extractPluginConfigs(configs)
111120

112121
return defaults(
113122
{
114123
// Need to get a default empty object if the config has no theme
115124
theme: resolveFunctionKeys(
116-
mergeExtensions(mergeThemes(map(configs, t => get(t, 'theme', {}))))
125+
mergeExtensions(mergeThemes(map(allConfigs, t => get(t, 'theme', {}))))
117126
),
118127
variants: (firstVariants => {
119128
return Array.isArray(firstVariants)
120129
? firstVariants
121-
: defaults({}, ...map(configs, 'variants'))
122-
})(defaults({}, ...map(configs)).variants),
130+
: defaults({}, ...map(allConfigs, 'variants'))
131+
})(defaults({}, ...map(allConfigs)).variants),
123132
},
124-
...configs
133+
...allConfigs
125134
)
126135
}

0 commit comments

Comments
 (0)