tailwindcss 0.0.0-insiders.fe08e91 → 0.0.0-oxide.c7d416b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +379 -3
- package/LICENSE +1 -2
- package/README.md +12 -8
- package/colors.d.ts +3 -0
- package/defaultConfig.d.ts +3 -0
- package/defaultTheme.d.ts +4 -0
- package/lib/cli/build/deps.js +54 -0
- package/lib/cli/build/index.js +48 -0
- package/lib/cli/build/plugin.js +367 -0
- package/lib/cli/build/utils.js +78 -0
- package/lib/cli/build/watching.js +178 -0
- package/lib/cli/help/index.js +71 -0
- package/lib/cli/index.js +239 -0
- package/lib/cli/init/index.js +46 -0
- package/lib/cli/shared.js +13 -0
- package/lib/cli-peer-dependencies.js +20 -7
- package/lib/cli.js +4 -740
- package/lib/constants.js +27 -20
- package/lib/corePluginList.js +6 -3
- package/lib/corePlugins.js +2064 -1811
- package/lib/css/preflight.css +5 -5
- package/lib/featureFlags.js +31 -22
- package/lib/index.js +4 -28
- package/lib/lib/cacheInvalidation.js +90 -0
- package/lib/lib/collapseAdjacentRules.js +27 -9
- package/lib/lib/collapseDuplicateDeclarations.js +12 -9
- package/lib/lib/content.js +176 -0
- package/lib/lib/defaultExtractor.js +225 -31
- package/lib/lib/detectNesting.js +13 -10
- package/lib/lib/evaluateTailwindFunctions.js +118 -55
- package/lib/lib/expandApplyAtRules.js +439 -190
- package/lib/lib/expandTailwindAtRules.js +151 -134
- package/lib/lib/findAtConfigPath.js +44 -0
- package/lib/lib/generateRules.js +454 -187
- package/lib/lib/getModuleDependencies.js +11 -8
- package/lib/lib/normalizeTailwindDirectives.js +36 -32
- package/lib/lib/offsets.js +217 -0
- package/lib/lib/partitionApplyAtRules.js +56 -0
- package/lib/lib/regex.js +60 -0
- package/lib/lib/resolveDefaultsAtRules.js +89 -67
- package/lib/lib/setupContextUtils.js +667 -376
- package/lib/lib/setupTrackingContext.js +38 -67
- package/lib/lib/sharedState.js +27 -14
- package/lib/lib/substituteScreenAtRules.js +11 -9
- package/lib/plugin.js +48 -0
- package/{nesting → lib/postcss-plugins/nesting}/README.md +2 -2
- package/lib/postcss-plugins/nesting/index.js +19 -0
- package/lib/postcss-plugins/nesting/plugin.js +87 -0
- package/lib/processTailwindFeatures.js +35 -25
- package/lib/public/colors.js +247 -245
- package/lib/public/create-plugin.js +6 -4
- package/lib/public/default-config.js +7 -5
- package/lib/public/default-theme.js +7 -5
- package/lib/public/resolve-config.js +8 -5
- package/lib/util/bigSign.js +4 -1
- package/lib/util/buildMediaQuery.js +11 -6
- package/lib/util/cloneDeep.js +7 -6
- package/lib/util/cloneNodes.js +21 -3
- package/lib/util/color.js +53 -54
- package/lib/util/configurePlugins.js +5 -2
- package/lib/util/createPlugin.js +6 -6
- package/lib/util/createUtilityPlugin.js +12 -14
- package/lib/util/dataTypes.js +119 -110
- package/lib/util/defaults.js +4 -1
- package/lib/util/escapeClassName.js +7 -4
- package/lib/util/escapeCommas.js +5 -2
- package/lib/util/flattenColorPalette.js +9 -12
- package/lib/util/formatVariantSelector.js +184 -85
- package/lib/util/getAllConfigs.js +27 -8
- package/lib/util/hashConfig.js +6 -3
- package/lib/util/isKeyframeRule.js +5 -2
- package/lib/util/isPlainObject.js +5 -2
- package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +23 -15
- package/lib/util/log.js +20 -14
- package/lib/util/nameClass.js +20 -9
- package/lib/util/negateValue.js +23 -8
- package/lib/util/normalizeConfig.js +116 -72
- package/lib/util/normalizeScreens.js +120 -11
- package/lib/util/parseAnimationValue.js +42 -40
- package/lib/util/parseBoxShadowValue.js +30 -23
- package/lib/util/parseDependency.js +38 -56
- package/lib/util/parseGlob.js +34 -0
- package/lib/util/parseObjectStyles.js +11 -8
- package/lib/util/pluginUtils.js +147 -50
- package/lib/util/prefixSelector.js +10 -8
- package/lib/util/removeAlphaVariables.js +29 -0
- package/lib/util/resolveConfig.js +97 -85
- package/lib/util/resolveConfigPath.js +11 -9
- package/lib/util/responsive.js +8 -5
- package/lib/util/splitAtTopLevelOnly.js +43 -0
- package/lib/util/tap.js +4 -1
- package/lib/util/toColorValue.js +5 -3
- package/lib/util/toPath.js +20 -4
- package/lib/util/transformThemeValue.js +37 -29
- package/lib/util/validateConfig.js +24 -0
- package/lib/util/validateFormalSyntax.js +24 -0
- package/lib/util/withAlphaVariable.js +23 -15
- package/nesting/index.js +2 -12
- package/oxide/README.md +1 -0
- package/oxide/package.json +18 -0
- package/oxide/packages/tailwindcss/dist/cli.js +2 -0
- package/oxide/packages/tailwindcss/dist/postcss-plugin.js +2 -0
- package/oxide/packages/tailwindcss/package.json +34 -0
- package/package.json +49 -42
- package/peers/index.js +11381 -7950
- package/plugin.d.ts +11 -0
- package/resolveConfig.d.ts +12 -0
- package/scripts/generate-types.js +105 -0
- package/scripts/release-channel.js +18 -0
- package/scripts/release-notes.js +21 -0
- package/scripts/type-utils.js +27 -0
- package/src/cli/build/deps.js +56 -0
- package/src/cli/build/index.js +49 -0
- package/src/cli/build/plugin.js +439 -0
- package/src/cli/build/utils.js +76 -0
- package/src/cli/build/watching.js +227 -0
- package/src/cli/help/index.js +70 -0
- package/src/cli/index.js +234 -0
- package/src/cli/init/index.js +50 -0
- package/src/cli/shared.js +6 -0
- package/src/cli-peer-dependencies.js +7 -1
- package/src/cli.js +4 -810
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +532 -217
- package/src/css/preflight.css +5 -5
- package/src/featureFlags.js +15 -9
- package/src/index.js +4 -27
- package/src/lib/cacheInvalidation.js +52 -0
- package/src/lib/collapseAdjacentRules.js +21 -2
- package/src/lib/content.js +212 -0
- package/src/lib/defaultExtractor.js +196 -33
- package/src/lib/evaluateTailwindFunctions.js +78 -7
- package/src/lib/expandApplyAtRules.js +482 -183
- package/src/lib/expandTailwindAtRules.js +106 -85
- package/src/lib/findAtConfigPath.js +48 -0
- package/src/lib/generateRules.js +418 -129
- package/src/lib/normalizeTailwindDirectives.js +1 -0
- package/src/lib/offsets.js +270 -0
- package/src/lib/partitionApplyAtRules.js +52 -0
- package/src/lib/regex.js +74 -0
- package/src/lib/resolveDefaultsAtRules.js +51 -30
- package/src/lib/setupContextUtils.js +556 -208
- package/src/lib/setupTrackingContext.js +11 -48
- package/src/lib/sharedState.js +5 -0
- package/src/plugin.js +47 -0
- package/src/postcss-plugins/nesting/README.md +42 -0
- package/src/postcss-plugins/nesting/index.js +13 -0
- package/src/postcss-plugins/nesting/plugin.js +80 -0
- package/src/processTailwindFeatures.js +8 -0
- package/src/util/buildMediaQuery.js +5 -3
- package/src/util/cloneNodes.js +19 -2
- package/src/util/color.js +25 -21
- package/src/util/dataTypes.js +29 -21
- package/src/util/formatVariantSelector.js +184 -61
- package/src/util/getAllConfigs.js +19 -0
- package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
- package/src/util/log.js +8 -8
- package/src/util/nameClass.js +4 -0
- package/src/util/negateValue.js +11 -3
- package/src/util/normalizeConfig.js +44 -6
- package/src/util/normalizeScreens.js +99 -4
- package/src/util/parseBoxShadowValue.js +4 -3
- package/src/util/parseDependency.js +37 -42
- package/src/util/parseGlob.js +24 -0
- package/src/util/pluginUtils.js +132 -10
- package/src/util/prefixSelector.js +7 -5
- package/src/util/removeAlphaVariables.js +24 -0
- package/src/util/resolveConfig.js +70 -32
- package/src/util/splitAtTopLevelOnly.js +45 -0
- package/src/util/toPath.js +1 -1
- package/src/util/transformThemeValue.js +13 -3
- package/src/util/validateConfig.js +13 -0
- package/src/util/validateFormalSyntax.js +34 -0
- package/src/util/withAlphaVariable.js +1 -1
- package/stubs/defaultConfig.stub.js +23 -20
- package/stubs/simpleConfig.stub.js +1 -0
- package/types/config.d.ts +362 -0
- package/types/generated/.gitkeep +0 -0
- package/types/generated/colors.d.ts +276 -0
- package/types/generated/corePluginList.d.ts +1 -0
- package/types/generated/default-theme.d.ts +342 -0
- package/types/index.d.ts +7 -0
- package/nesting/plugin.js +0 -41
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
1
2
|
import LRU from 'quick-lru'
|
|
2
3
|
import * as sharedState from './sharedState'
|
|
3
4
|
import { generateRules } from './generateRules'
|
|
4
|
-
import
|
|
5
|
+
import log from '../util/log'
|
|
5
6
|
import cloneNodes from '../util/cloneNodes'
|
|
6
7
|
import { defaultExtractor } from './defaultExtractor'
|
|
7
8
|
|
|
9
|
+
import oxide from '@tailwindcss/oxide'
|
|
10
|
+
|
|
8
11
|
let env = sharedState.env
|
|
9
12
|
|
|
10
13
|
const builtInExtractors = {
|
|
@@ -16,14 +19,14 @@ const builtInTransformers = {
|
|
|
16
19
|
svelte: (content) => content.replace(/(?:^|\s)class:/g, ' '),
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
function getExtractor(
|
|
20
|
-
let extractors = tailwindConfig.content.extract
|
|
22
|
+
function getExtractor(context, fileExtension) {
|
|
23
|
+
let extractors = context.tailwindConfig.content.extract
|
|
21
24
|
|
|
22
25
|
return (
|
|
23
26
|
extractors[fileExtension] ||
|
|
24
27
|
extractors.DEFAULT ||
|
|
25
28
|
builtInExtractors[fileExtension] ||
|
|
26
|
-
builtInExtractors.DEFAULT
|
|
29
|
+
builtInExtractors.DEFAULT(context)
|
|
27
30
|
)
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -73,8 +76,13 @@ function getClassCandidates(content, extractor, candidates, seen) {
|
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
78
|
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* @param {[import('./offsets.js').RuleOffset, import('postcss').Node][]} rules
|
|
82
|
+
* @param {*} context
|
|
83
|
+
*/
|
|
76
84
|
function buildStylesheet(rules, context) {
|
|
77
|
-
let sortedRules =
|
|
85
|
+
let sortedRules = context.offsets.sort(rules)
|
|
78
86
|
|
|
79
87
|
let returnValue = {
|
|
80
88
|
base: new Set(),
|
|
@@ -82,55 +90,15 @@ function buildStylesheet(rules, context) {
|
|
|
82
90
|
components: new Set(),
|
|
83
91
|
utilities: new Set(),
|
|
84
92
|
variants: new Set(),
|
|
85
|
-
|
|
86
|
-
// All the CSS that is not Tailwind related can be put in this bucket. This
|
|
87
|
-
// will make it easier to later use this information when we want to
|
|
88
|
-
// `@apply` for example. The main reason we do this here is because we
|
|
89
|
-
// still need to make sure the order is correct. Last but not least, we
|
|
90
|
-
// will make sure to always re-inject this section into the css, even if
|
|
91
|
-
// certain rules were not used. This means that it will look like a no-op
|
|
92
|
-
// from the user's perspective, but we gathered all the useful information
|
|
93
|
-
// we need.
|
|
94
|
-
user: new Set(),
|
|
95
93
|
}
|
|
96
94
|
|
|
97
95
|
for (let [sort, rule] of sortedRules) {
|
|
98
|
-
|
|
99
|
-
returnValue.variants.add(rule)
|
|
100
|
-
continue
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (sort & context.layerOrder.base) {
|
|
104
|
-
returnValue.base.add(rule)
|
|
105
|
-
continue
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (sort & context.layerOrder.defaults) {
|
|
109
|
-
returnValue.defaults.add(rule)
|
|
110
|
-
continue
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (sort & context.layerOrder.components) {
|
|
114
|
-
returnValue.components.add(rule)
|
|
115
|
-
continue
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (sort & context.layerOrder.utilities) {
|
|
119
|
-
returnValue.utilities.add(rule)
|
|
120
|
-
continue
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (sort & context.layerOrder.user) {
|
|
124
|
-
returnValue.user.add(rule)
|
|
125
|
-
continue
|
|
126
|
-
}
|
|
96
|
+
returnValue[sort.layer].add(rule)
|
|
127
97
|
}
|
|
128
98
|
|
|
129
99
|
return returnValue
|
|
130
100
|
}
|
|
131
101
|
|
|
132
|
-
export const DEFAULTS_LAYER = Symbol('defaults-layer')
|
|
133
|
-
|
|
134
102
|
export default function expandTailwindAtRules(context) {
|
|
135
103
|
return (root) => {
|
|
136
104
|
let layerNodes = {
|
|
@@ -140,8 +108,6 @@ export default function expandTailwindAtRules(context) {
|
|
|
140
108
|
variants: null,
|
|
141
109
|
}
|
|
142
110
|
|
|
143
|
-
// let hasApply = false
|
|
144
|
-
|
|
145
111
|
root.walkAtRules((rule) => {
|
|
146
112
|
// Make sure this file contains Tailwind directives. If not, we can save
|
|
147
113
|
// a lot of work and bail early. Also we don't have to register our touch
|
|
@@ -152,13 +118,6 @@ export default function expandTailwindAtRules(context) {
|
|
|
152
118
|
layerNodes[rule.params] = rule
|
|
153
119
|
}
|
|
154
120
|
}
|
|
155
|
-
|
|
156
|
-
// We also want to check for @apply because the user can
|
|
157
|
-
// apply classes in an isolated environment like CSS
|
|
158
|
-
// modules and we still need to inject defaults
|
|
159
|
-
// if (rule.name === 'apply') {
|
|
160
|
-
// hasApply = true
|
|
161
|
-
// }
|
|
162
121
|
})
|
|
163
122
|
|
|
164
123
|
if (Object.values(layerNodes).every((n) => n === null)) {
|
|
@@ -168,33 +127,62 @@ export default function expandTailwindAtRules(context) {
|
|
|
168
127
|
// ---
|
|
169
128
|
|
|
170
129
|
// Find potential rules in changed files
|
|
171
|
-
let candidates = new Set([
|
|
130
|
+
let candidates = new Set([...(context.candidates ?? []), sharedState.NOT_ON_DEMAND])
|
|
172
131
|
let seen = new Set()
|
|
173
132
|
|
|
174
133
|
env.DEBUG && console.time('Reading changed files')
|
|
175
134
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
let
|
|
179
|
-
|
|
135
|
+
if (env.OXIDE) {
|
|
136
|
+
// TODO: Pass through or implement `extractor`
|
|
137
|
+
for (let candidate of oxide.parseCandidateStringsFromFiles(
|
|
138
|
+
context.changedContent
|
|
139
|
+
// Object.assign({}, builtInTransformers, context.tailwindConfig.content.transform)
|
|
140
|
+
)) {
|
|
141
|
+
candidates.add(candidate)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// for (let { file, content, extension } of context.changedContent) {
|
|
145
|
+
// let transformer = getTransformer(context.tailwindConfig, extension)
|
|
146
|
+
// let extractor = getExtractor(context, extension)
|
|
147
|
+
// getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen)
|
|
148
|
+
// }
|
|
149
|
+
} else {
|
|
150
|
+
for (let { file, content, extension } of context.changedContent) {
|
|
151
|
+
let transformer = getTransformer(context.tailwindConfig, extension)
|
|
152
|
+
let extractor = getExtractor(context, extension)
|
|
153
|
+
content = file ? fs.readFileSync(file, 'utf8') : content
|
|
154
|
+
getClassCandidates(transformer(content), extractor, candidates, seen)
|
|
155
|
+
}
|
|
180
156
|
}
|
|
181
157
|
|
|
158
|
+
env.DEBUG && console.timeEnd('Reading changed files')
|
|
159
|
+
|
|
182
160
|
// ---
|
|
183
161
|
|
|
184
162
|
// Generate the actual CSS
|
|
185
163
|
let classCacheCount = context.classCache.size
|
|
186
164
|
|
|
187
165
|
env.DEBUG && console.time('Generate rules')
|
|
188
|
-
|
|
166
|
+
// TODO: Sorting is _probably_ slow, but right now it can guarantee the same order. Eventually
|
|
167
|
+
// we will be able to get rid of this.
|
|
168
|
+
env.DEBUG && console.time('Sorting candidates')
|
|
169
|
+
let sortedCandidates =
|
|
170
|
+
typeof process !== 'undefined' && process.env.JEST_WORKER_ID
|
|
171
|
+
? new Set(
|
|
172
|
+
[...candidates].sort((a, z) => {
|
|
173
|
+
if (a === z) return 0
|
|
174
|
+
if (a < z) return -1
|
|
175
|
+
return 1
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
: candidates
|
|
179
|
+
env.DEBUG && console.timeEnd('Sorting candidates')
|
|
180
|
+
generateRules(sortedCandidates, context)
|
|
189
181
|
env.DEBUG && console.timeEnd('Generate rules')
|
|
190
182
|
|
|
191
183
|
// We only ever add to the classCache, so if it didn't grow, there is nothing new.
|
|
192
184
|
env.DEBUG && console.time('Build stylesheet')
|
|
193
185
|
if (context.stylesheetCache === null || context.classCache.size !== classCacheCount) {
|
|
194
|
-
for (let rule of rules) {
|
|
195
|
-
context.ruleCache.add(rule)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
186
|
context.stylesheetCache = buildStylesheet([...context.ruleCache], context)
|
|
199
187
|
}
|
|
200
188
|
env.DEBUG && console.timeEnd('Build stylesheet')
|
|
@@ -212,39 +200,72 @@ export default function expandTailwindAtRules(context) {
|
|
|
212
200
|
// Replace any Tailwind directives with generated CSS
|
|
213
201
|
|
|
214
202
|
if (layerNodes.base) {
|
|
215
|
-
layerNodes.base.before(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// compiled in an isolated environment like CSS modules
|
|
221
|
-
if (context.tailwindConfig[DEFAULTS_LAYER] !== false) {
|
|
222
|
-
if (layerNodes.base) {
|
|
223
|
-
layerNodes.base.after(cloneNodes([...defaultNodes], root.source))
|
|
224
|
-
} else {
|
|
225
|
-
root.prepend(cloneNodes([...defaultNodes], root.source))
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (layerNodes.base) {
|
|
203
|
+
layerNodes.base.before(
|
|
204
|
+
cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source, {
|
|
205
|
+
layer: 'base',
|
|
206
|
+
})
|
|
207
|
+
)
|
|
230
208
|
layerNodes.base.remove()
|
|
231
209
|
}
|
|
232
210
|
|
|
233
211
|
if (layerNodes.components) {
|
|
234
|
-
layerNodes.components.before(
|
|
212
|
+
layerNodes.components.before(
|
|
213
|
+
cloneNodes([...componentNodes], layerNodes.components.source, {
|
|
214
|
+
layer: 'components',
|
|
215
|
+
})
|
|
216
|
+
)
|
|
235
217
|
layerNodes.components.remove()
|
|
236
218
|
}
|
|
237
219
|
|
|
238
220
|
if (layerNodes.utilities) {
|
|
239
|
-
layerNodes.utilities.before(
|
|
221
|
+
layerNodes.utilities.before(
|
|
222
|
+
cloneNodes([...utilityNodes], layerNodes.utilities.source, {
|
|
223
|
+
layer: 'utilities',
|
|
224
|
+
})
|
|
225
|
+
)
|
|
240
226
|
layerNodes.utilities.remove()
|
|
241
227
|
}
|
|
242
228
|
|
|
229
|
+
// We do post-filtering to not alter the emitted order of the variants
|
|
230
|
+
const variantNodes = Array.from(screenNodes).filter((node) => {
|
|
231
|
+
const parentLayer = node.raws.tailwind?.parentLayer
|
|
232
|
+
|
|
233
|
+
if (parentLayer === 'components') {
|
|
234
|
+
return layerNodes.components !== null
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (parentLayer === 'utilities') {
|
|
238
|
+
return layerNodes.utilities !== null
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return true
|
|
242
|
+
})
|
|
243
|
+
|
|
243
244
|
if (layerNodes.variants) {
|
|
244
|
-
layerNodes.variants.before(
|
|
245
|
+
layerNodes.variants.before(
|
|
246
|
+
cloneNodes(variantNodes, layerNodes.variants.source, {
|
|
247
|
+
layer: 'variants',
|
|
248
|
+
})
|
|
249
|
+
)
|
|
245
250
|
layerNodes.variants.remove()
|
|
246
|
-
} else {
|
|
247
|
-
root.append(
|
|
251
|
+
} else if (variantNodes.length > 0) {
|
|
252
|
+
root.append(
|
|
253
|
+
cloneNodes(variantNodes, root.source, {
|
|
254
|
+
layer: 'variants',
|
|
255
|
+
})
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// If we've got a utility layer and no utilities are generated there's likely something wrong
|
|
260
|
+
const hasUtilityVariants = variantNodes.some(
|
|
261
|
+
(node) => node.raws.tailwind?.parentLayer === 'utilities'
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if (layerNodes.utilities && utilityNodes.size === 0 && !hasUtilityVariants) {
|
|
265
|
+
log.warn('content-problems', [
|
|
266
|
+
'No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.',
|
|
267
|
+
'https://tailwindcss.com/docs/content-configuration',
|
|
268
|
+
])
|
|
248
269
|
}
|
|
249
270
|
|
|
250
271
|
// ---
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Find the @config at-rule in the given CSS AST and return the relative path to the config file
|
|
6
|
+
*
|
|
7
|
+
* @param {import('postcss').Root} root
|
|
8
|
+
* @param {import('postcss').Result} result
|
|
9
|
+
*/
|
|
10
|
+
export function findAtConfigPath(root, result) {
|
|
11
|
+
let configPath = null
|
|
12
|
+
let relativeTo = null
|
|
13
|
+
|
|
14
|
+
root.walkAtRules('config', (rule) => {
|
|
15
|
+
relativeTo = rule.source?.input.file ?? result.opts.from ?? null
|
|
16
|
+
|
|
17
|
+
if (relativeTo === null) {
|
|
18
|
+
throw rule.error(
|
|
19
|
+
'The `@config` directive cannot be used without setting `from` in your PostCSS config.'
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (configPath) {
|
|
24
|
+
throw rule.error('Only one `@config` directive is allowed per file.')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let matches = rule.params.match(/(['"])(.*?)\1/)
|
|
28
|
+
if (!matches) {
|
|
29
|
+
throw rule.error('A path is required when using the `@config` directive.')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let inputPath = matches[2]
|
|
33
|
+
if (path.isAbsolute(inputPath)) {
|
|
34
|
+
throw rule.error('The `@config` directive cannot be used with an absolute path.')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
configPath = path.resolve(path.dirname(relativeTo), inputPath)
|
|
38
|
+
if (!fs.existsSync(configPath)) {
|
|
39
|
+
throw rule.error(
|
|
40
|
+
`The config file at "${inputPath}" does not exist. Make sure the path is correct and the file exists.`
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rule.remove()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return configPath ? configPath : null
|
|
48
|
+
}
|