tailwindcss-patch 8.7.4-alpha.0 → 9.0.0-alpha.2
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/README.md +65 -5
- package/dist/{chunk-ZXW4S356.js → chunk-TOAZIPHJ.js} +295 -285
- package/dist/{chunk-6ZDYMYHE.mjs → chunk-VDWTCQ74.mjs} +259 -249
- package/dist/cli.js +4 -4
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +46 -134
- package/dist/index.d.ts +46 -134
- package/dist/index.js +5 -3
- package/dist/index.mjs +4 -2
- package/package.json +8 -3
- package/src/api/tailwindcss-patcher.ts +424 -0
- package/src/babel/index.ts +12 -0
- package/src/cache/context.ts +212 -0
- package/src/cache/store.ts +1440 -0
- package/src/cache/types.ts +71 -0
- package/src/cli.ts +20 -0
- package/src/commands/basic-handlers.ts +145 -0
- package/src/commands/cli.ts +56 -0
- package/src/commands/command-context.ts +77 -0
- package/src/commands/command-definitions.ts +102 -0
- package/src/commands/command-metadata.ts +68 -0
- package/src/commands/command-registrar.ts +39 -0
- package/src/commands/command-runtime.ts +33 -0
- package/src/commands/default-handler-map.ts +25 -0
- package/src/commands/migrate-config.ts +104 -0
- package/src/commands/migrate-handler.ts +67 -0
- package/src/commands/migration-aggregation.ts +100 -0
- package/src/commands/migration-args.ts +85 -0
- package/src/commands/migration-file-executor.ts +189 -0
- package/src/commands/migration-output.ts +115 -0
- package/src/commands/migration-report-loader.ts +26 -0
- package/src/commands/migration-report.ts +21 -0
- package/src/commands/migration-source.ts +318 -0
- package/src/commands/migration-target-files.ts +161 -0
- package/src/commands/migration-target-resolver.ts +34 -0
- package/src/commands/migration-types.ts +65 -0
- package/src/commands/restore-handler.ts +24 -0
- package/src/commands/status-handler.ts +17 -0
- package/src/commands/status-output.ts +60 -0
- package/src/commands/token-output.ts +30 -0
- package/src/commands/types.ts +137 -0
- package/src/commands/validate-handler.ts +42 -0
- package/src/commands/validate.ts +83 -0
- package/src/config/index.ts +25 -0
- package/src/config/workspace.ts +87 -0
- package/src/constants.ts +4 -0
- package/src/extraction/candidate-extractor.ts +354 -0
- package/src/index.ts +57 -0
- package/src/install/class-collector.ts +1 -0
- package/src/install/context-registry.ts +1 -0
- package/src/install/index.ts +5 -0
- package/src/install/patch-runner.ts +1 -0
- package/src/install/process-tailwindcss.ts +1 -0
- package/src/install/status.ts +1 -0
- package/src/logger.ts +5 -0
- package/src/options/legacy.ts +93 -0
- package/src/options/normalize.ts +262 -0
- package/src/options/types.ts +217 -0
- package/src/patching/operations/export-context/index.ts +110 -0
- package/src/patching/operations/export-context/postcss-v2.ts +235 -0
- package/src/patching/operations/export-context/postcss-v3.ts +249 -0
- package/src/patching/operations/extend-length-units.ts +197 -0
- package/src/patching/patch-runner.ts +46 -0
- package/src/patching/status.ts +262 -0
- package/src/runtime/class-collector.ts +105 -0
- package/src/runtime/collector.ts +148 -0
- package/src/runtime/context-registry.ts +65 -0
- package/src/runtime/process-tailwindcss.ts +115 -0
- package/src/types.ts +159 -0
- package/src/utils.ts +52 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { SourceEntry } from '@tailwindcss/oxide'
|
|
2
|
+
import type {
|
|
3
|
+
TailwindTokenByFileMap,
|
|
4
|
+
TailwindTokenFileKey,
|
|
5
|
+
TailwindTokenLocation,
|
|
6
|
+
TailwindTokenReport,
|
|
7
|
+
} from '../types'
|
|
8
|
+
import { promises as fs } from 'node:fs'
|
|
9
|
+
import process from 'node:process'
|
|
10
|
+
import path from 'pathe'
|
|
11
|
+
|
|
12
|
+
let nodeImportPromise: ReturnType<typeof importNode> | undefined
|
|
13
|
+
let oxideImportPromise: ReturnType<typeof importOxide> | undefined
|
|
14
|
+
const designSystemPromiseCache = new Map<string, Promise<any>>()
|
|
15
|
+
const designSystemCandidateCache = new Map<string, Map<string, boolean>>()
|
|
16
|
+
|
|
17
|
+
async function importNode() {
|
|
18
|
+
return import('@tailwindcss/node')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function importOxide() {
|
|
22
|
+
return import('@tailwindcss/oxide')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getNodeModule() {
|
|
26
|
+
nodeImportPromise ??= importNode()
|
|
27
|
+
return nodeImportPromise
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getOxideModule() {
|
|
31
|
+
oxideImportPromise ??= importOxide()
|
|
32
|
+
return oxideImportPromise
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createDesignSystemCacheKey(css: string, bases: string[]) {
|
|
36
|
+
return JSON.stringify({
|
|
37
|
+
css,
|
|
38
|
+
bases: Array.from(new Set(bases.filter(Boolean))),
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function loadDesignSystem(css: string, bases: string[]) {
|
|
43
|
+
const uniqueBases = Array.from(new Set(bases.filter(Boolean)))
|
|
44
|
+
if (uniqueBases.length === 0) {
|
|
45
|
+
throw new Error('No base directories provided for Tailwind CSS design system.')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cacheKey = createDesignSystemCacheKey(css, uniqueBases)
|
|
49
|
+
const cached = designSystemPromiseCache.get(cacheKey)
|
|
50
|
+
if (cached) {
|
|
51
|
+
return cached
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const promise = (async () => {
|
|
55
|
+
const { __unstable__loadDesignSystem } = await getNodeModule()
|
|
56
|
+
let lastError: unknown
|
|
57
|
+
|
|
58
|
+
for (const base of uniqueBases) {
|
|
59
|
+
try {
|
|
60
|
+
return await __unstable__loadDesignSystem(css, { base })
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
lastError = error
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (lastError instanceof Error) {
|
|
68
|
+
throw lastError
|
|
69
|
+
}
|
|
70
|
+
throw new Error('Failed to load Tailwind CSS design system.')
|
|
71
|
+
})()
|
|
72
|
+
|
|
73
|
+
designSystemPromiseCache.set(cacheKey, promise)
|
|
74
|
+
promise.catch(() => {
|
|
75
|
+
if (designSystemPromiseCache.get(cacheKey) === promise) {
|
|
76
|
+
designSystemPromiseCache.delete(cacheKey)
|
|
77
|
+
designSystemCandidateCache.delete(cacheKey)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
return promise
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ExtractValidCandidatesOption {
|
|
84
|
+
sources?: SourceEntry[]
|
|
85
|
+
base?: string
|
|
86
|
+
baseFallbacks?: string[]
|
|
87
|
+
css?: string
|
|
88
|
+
cwd?: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function extractRawCandidatesWithPositions(
|
|
92
|
+
content: string,
|
|
93
|
+
extension: string = 'html',
|
|
94
|
+
): Promise<{ rawCandidate: string, start: number, end: number }[]> {
|
|
95
|
+
const { Scanner } = await getOxideModule()
|
|
96
|
+
const scanner = new Scanner({})
|
|
97
|
+
const result = scanner.getCandidatesWithPositions({ content, extension })
|
|
98
|
+
|
|
99
|
+
return result.map(({ candidate, position }) => ({
|
|
100
|
+
rawCandidate: candidate,
|
|
101
|
+
start: position,
|
|
102
|
+
end: position + candidate.length,
|
|
103
|
+
}))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function extractRawCandidates(
|
|
107
|
+
sources?: SourceEntry[],
|
|
108
|
+
): Promise<string[]> {
|
|
109
|
+
const { Scanner } = await getOxideModule()
|
|
110
|
+
const scanner = new Scanner(sources === undefined ? {} : { sources })
|
|
111
|
+
|
|
112
|
+
return scanner.scan()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function extractValidCandidates(options?: ExtractValidCandidatesOption) {
|
|
116
|
+
const providedOptions = options ?? {}
|
|
117
|
+
const defaultCwd = providedOptions.cwd ?? process.cwd()
|
|
118
|
+
|
|
119
|
+
const base = providedOptions.base ?? defaultCwd
|
|
120
|
+
const baseFallbacks = providedOptions.baseFallbacks ?? []
|
|
121
|
+
const css = providedOptions.css ?? '@import "tailwindcss";'
|
|
122
|
+
const sources = (providedOptions.sources ?? [
|
|
123
|
+
{
|
|
124
|
+
base: defaultCwd,
|
|
125
|
+
pattern: '**/*',
|
|
126
|
+
negated: false,
|
|
127
|
+
},
|
|
128
|
+
]).map(source => ({
|
|
129
|
+
base: source.base ?? defaultCwd,
|
|
130
|
+
pattern: source.pattern,
|
|
131
|
+
negated: source.negated,
|
|
132
|
+
}))
|
|
133
|
+
|
|
134
|
+
const designSystemKey = createDesignSystemCacheKey(css, [base, ...baseFallbacks])
|
|
135
|
+
const designSystem = await loadDesignSystem(css, [base, ...baseFallbacks])
|
|
136
|
+
const candidateCache = designSystemCandidateCache.get(designSystemKey) ?? new Map<string, boolean>()
|
|
137
|
+
designSystemCandidateCache.set(designSystemKey, candidateCache)
|
|
138
|
+
|
|
139
|
+
const candidates = await extractRawCandidates(sources)
|
|
140
|
+
const validCandidates: string[] = []
|
|
141
|
+
const uncachedCandidates: string[] = []
|
|
142
|
+
|
|
143
|
+
for (const rawCandidate of candidates) {
|
|
144
|
+
const cached = candidateCache.get(rawCandidate)
|
|
145
|
+
if (cached === true) {
|
|
146
|
+
validCandidates.push(rawCandidate)
|
|
147
|
+
continue
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (cached === false) {
|
|
151
|
+
continue
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (designSystem.parseCandidate(rawCandidate).length > 0) {
|
|
155
|
+
uncachedCandidates.push(rawCandidate)
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
candidateCache.set(rawCandidate, false)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (uncachedCandidates.length === 0) {
|
|
163
|
+
return validCandidates
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const cssByCandidate = designSystem.candidatesToCss(uncachedCandidates)
|
|
167
|
+
|
|
168
|
+
for (let index = 0; index < uncachedCandidates.length; index++) {
|
|
169
|
+
const candidate = uncachedCandidates[index]
|
|
170
|
+
if (candidate === undefined) {
|
|
171
|
+
continue
|
|
172
|
+
}
|
|
173
|
+
const candidateCss = cssByCandidate[index]
|
|
174
|
+
const isValid = typeof candidateCss === 'string' && candidateCss.trim().length > 0
|
|
175
|
+
candidateCache.set(candidate, isValid)
|
|
176
|
+
if (!isValid) {
|
|
177
|
+
continue
|
|
178
|
+
}
|
|
179
|
+
validCandidates.push(candidate)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return validCandidates
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function normalizeSources(sources: SourceEntry[] | undefined, cwd: string) {
|
|
186
|
+
const baseSources = sources?.length
|
|
187
|
+
? sources
|
|
188
|
+
: [
|
|
189
|
+
{
|
|
190
|
+
base: cwd,
|
|
191
|
+
pattern: '**/*',
|
|
192
|
+
negated: false,
|
|
193
|
+
},
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
return baseSources.map(source => ({
|
|
197
|
+
base: source.base ?? cwd,
|
|
198
|
+
pattern: source.pattern,
|
|
199
|
+
negated: source.negated,
|
|
200
|
+
}))
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function buildLineOffsets(content: string) {
|
|
204
|
+
const offsets: number[] = [0]
|
|
205
|
+
for (let i = 0; i < content.length; i++) {
|
|
206
|
+
if (content[i] === '\n') {
|
|
207
|
+
offsets.push(i + 1)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Push a sentinel to simplify bounds checks during binary search.
|
|
211
|
+
if (offsets[offsets.length - 1] !== content.length) {
|
|
212
|
+
offsets.push(content.length)
|
|
213
|
+
}
|
|
214
|
+
return offsets
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function resolveLineMeta(content: string, offsets: number[], index: number) {
|
|
218
|
+
let low = 0
|
|
219
|
+
let high = offsets.length - 1
|
|
220
|
+
while (low <= high) {
|
|
221
|
+
const mid = Math.floor((low + high) / 2)
|
|
222
|
+
const start = offsets[mid]
|
|
223
|
+
if (start === undefined) {
|
|
224
|
+
break
|
|
225
|
+
}
|
|
226
|
+
const nextStart = offsets[mid + 1] ?? content.length
|
|
227
|
+
|
|
228
|
+
if (index < start) {
|
|
229
|
+
high = mid - 1
|
|
230
|
+
continue
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (index >= nextStart) {
|
|
234
|
+
low = mid + 1
|
|
235
|
+
continue
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const line = mid + 1
|
|
239
|
+
const column = index - start + 1
|
|
240
|
+
const lineEnd = content.indexOf('\n', start)
|
|
241
|
+
const lineText = content.slice(start, lineEnd === -1 ? content.length : lineEnd)
|
|
242
|
+
|
|
243
|
+
return { line, column, lineText }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const lastStart = offsets[offsets.length - 2] ?? 0
|
|
247
|
+
return {
|
|
248
|
+
line: offsets.length - 1,
|
|
249
|
+
column: index - lastStart + 1,
|
|
250
|
+
lineText: content.slice(lastStart),
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function toExtension(filename: string) {
|
|
255
|
+
const ext = path.extname(filename).replace(/^\./, '')
|
|
256
|
+
return ext || 'txt'
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function toRelativeFile(cwd: string, filename: string) {
|
|
260
|
+
const relative = path.relative(cwd, filename)
|
|
261
|
+
return relative === '' ? path.basename(filename) : relative
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface ExtractProjectCandidatesOptions {
|
|
265
|
+
cwd?: string
|
|
266
|
+
sources?: SourceEntry[]
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export async function extractProjectCandidatesWithPositions(
|
|
270
|
+
options?: ExtractProjectCandidatesOptions,
|
|
271
|
+
): Promise<TailwindTokenReport> {
|
|
272
|
+
const cwd = options?.cwd ? path.resolve(options.cwd) : process.cwd()
|
|
273
|
+
const normalizedSources = normalizeSources(options?.sources, cwd)
|
|
274
|
+
const { Scanner } = await getOxideModule()
|
|
275
|
+
const scanner = new Scanner({
|
|
276
|
+
sources: normalizedSources,
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
const files = scanner.files ?? []
|
|
280
|
+
const entries: TailwindTokenLocation[] = []
|
|
281
|
+
const skipped: TailwindTokenReport['skippedFiles'] = []
|
|
282
|
+
|
|
283
|
+
for (const file of files) {
|
|
284
|
+
let content: string
|
|
285
|
+
try {
|
|
286
|
+
content = await fs.readFile(file, 'utf8')
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
skipped.push({
|
|
290
|
+
file,
|
|
291
|
+
reason: error instanceof Error ? error.message : 'Unknown error',
|
|
292
|
+
})
|
|
293
|
+
continue
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const extension = toExtension(file)
|
|
297
|
+
const matches = scanner.getCandidatesWithPositions({
|
|
298
|
+
file,
|
|
299
|
+
content,
|
|
300
|
+
extension,
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
if (!matches.length) {
|
|
304
|
+
continue
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const offsets = buildLineOffsets(content)
|
|
308
|
+
const relativeFile = toRelativeFile(cwd, file)
|
|
309
|
+
|
|
310
|
+
for (const match of matches) {
|
|
311
|
+
const info = resolveLineMeta(content, offsets, match.position)
|
|
312
|
+
entries.push({
|
|
313
|
+
rawCandidate: match.candidate,
|
|
314
|
+
file,
|
|
315
|
+
relativeFile,
|
|
316
|
+
extension,
|
|
317
|
+
start: match.position,
|
|
318
|
+
end: match.position + match.candidate.length,
|
|
319
|
+
length: match.candidate.length,
|
|
320
|
+
line: info.line,
|
|
321
|
+
column: info.column,
|
|
322
|
+
lineText: info.lineText,
|
|
323
|
+
})
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
entries,
|
|
329
|
+
filesScanned: files.length,
|
|
330
|
+
skippedFiles: skipped,
|
|
331
|
+
sources: normalizedSources,
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export function groupTokensByFile(
|
|
336
|
+
report: TailwindTokenReport,
|
|
337
|
+
options?: { key?: TailwindTokenFileKey, stripAbsolutePaths?: boolean },
|
|
338
|
+
): TailwindTokenByFileMap {
|
|
339
|
+
const key = options?.key ?? 'relative'
|
|
340
|
+
const stripAbsolute = options?.stripAbsolutePaths ?? key !== 'absolute'
|
|
341
|
+
|
|
342
|
+
return report.entries.reduce<TailwindTokenByFileMap>((acc, entry) => {
|
|
343
|
+
const bucketKey = key === 'absolute' ? entry.file : entry.relativeFile
|
|
344
|
+
const bucket = acc[bucketKey] ?? (acc[bucketKey] = [])
|
|
345
|
+
const value = stripAbsolute
|
|
346
|
+
? {
|
|
347
|
+
...entry,
|
|
348
|
+
file: entry.relativeFile,
|
|
349
|
+
}
|
|
350
|
+
: entry
|
|
351
|
+
bucket.push(value)
|
|
352
|
+
return acc
|
|
353
|
+
}, {})
|
|
354
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { TailwindcssMangleConfig } from '@tailwindcss-mangle/config'
|
|
2
|
+
|
|
3
|
+
export { TailwindcssPatcher } from './api/tailwindcss-patcher'
|
|
4
|
+
export { CacheStore } from './cache/store'
|
|
5
|
+
export {
|
|
6
|
+
createTailwindcssPatchCli,
|
|
7
|
+
mountTailwindcssPatchCommands,
|
|
8
|
+
type TailwindcssPatchCliMountOptions,
|
|
9
|
+
type TailwindcssPatchCliOptions,
|
|
10
|
+
type TailwindcssPatchCommand,
|
|
11
|
+
type TailwindcssPatchCommandContext,
|
|
12
|
+
type TailwindcssPatchCommandHandler,
|
|
13
|
+
type TailwindcssPatchCommandHandlerMap,
|
|
14
|
+
type TailwindcssPatchCommandOptionDefinition,
|
|
15
|
+
type TailwindcssPatchCommandOptions,
|
|
16
|
+
tailwindcssPatchCommands,
|
|
17
|
+
VALIDATE_EXIT_CODES,
|
|
18
|
+
VALIDATE_FAILURE_REASONS,
|
|
19
|
+
ValidateCommandError,
|
|
20
|
+
type ValidateFailureReason,
|
|
21
|
+
type ValidateFailureSummary,
|
|
22
|
+
type ValidateJsonFailurePayload,
|
|
23
|
+
type ValidateJsonSuccessPayload,
|
|
24
|
+
} from './commands/cli'
|
|
25
|
+
export {
|
|
26
|
+
type ConfigFileMigrationEntry,
|
|
27
|
+
type ConfigFileMigrationReport,
|
|
28
|
+
migrateConfigFiles,
|
|
29
|
+
type MigrateConfigFilesOptions,
|
|
30
|
+
MIGRATION_REPORT_KIND,
|
|
31
|
+
MIGRATION_REPORT_SCHEMA_VERSION,
|
|
32
|
+
restoreConfigFiles,
|
|
33
|
+
type RestoreConfigFilesOptions,
|
|
34
|
+
type RestoreConfigFilesResult,
|
|
35
|
+
} from './commands/migrate-config'
|
|
36
|
+
export { normalizeOptions } from './config'
|
|
37
|
+
export type { TailwindCssPatchOptions } from './config'
|
|
38
|
+
export {
|
|
39
|
+
extractProjectCandidatesWithPositions,
|
|
40
|
+
extractRawCandidates,
|
|
41
|
+
extractRawCandidatesWithPositions,
|
|
42
|
+
extractValidCandidates,
|
|
43
|
+
groupTokensByFile,
|
|
44
|
+
} from './extraction/candidate-extractor'
|
|
45
|
+
export {
|
|
46
|
+
collectClassesFromContexts,
|
|
47
|
+
collectClassesFromTailwindV4,
|
|
48
|
+
getPatchStatusReport,
|
|
49
|
+
loadRuntimeContexts,
|
|
50
|
+
runTailwindBuild,
|
|
51
|
+
} from './install'
|
|
52
|
+
export { default as logger } from './logger'
|
|
53
|
+
export * from './types'
|
|
54
|
+
|
|
55
|
+
export function defineConfig<T extends TailwindcssMangleConfig>(config: T): T {
|
|
56
|
+
return config
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { collectClassesFromContexts, collectClassesFromTailwindV4 } from '../runtime/class-collector'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { loadRuntimeContexts } from '../runtime/context-registry'
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { collectClassesFromContexts, collectClassesFromTailwindV4 } from './class-collector'
|
|
2
|
+
export { loadRuntimeContexts } from './context-registry'
|
|
3
|
+
export { applyTailwindPatches } from './patch-runner'
|
|
4
|
+
export { runTailwindBuild } from './process-tailwindcss'
|
|
5
|
+
export { getPatchStatusReport } from './status'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { applyTailwindPatches } from '../patching/patch-runner'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { runTailwindBuild } from '../runtime/process-tailwindcss'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getPatchStatusReport } from '../patching/status'
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { RegistryOptions } from '@tailwindcss-mangle/config'
|
|
2
|
+
import type { TailwindCssPatchOptions } from './types'
|
|
3
|
+
|
|
4
|
+
const deprecatedRegistryMapping = {
|
|
5
|
+
output: 'extract',
|
|
6
|
+
tailwind: 'tailwindcss',
|
|
7
|
+
} as const
|
|
8
|
+
|
|
9
|
+
type DeprecatedRegistryKey = keyof typeof deprecatedRegistryMapping
|
|
10
|
+
|
|
11
|
+
const deprecatedTailwindMapping = {
|
|
12
|
+
package: 'packageName',
|
|
13
|
+
legacy: 'v2',
|
|
14
|
+
classic: 'v3',
|
|
15
|
+
next: 'v4',
|
|
16
|
+
} as const
|
|
17
|
+
|
|
18
|
+
type DeprecatedTailwindKey = keyof typeof deprecatedTailwindMapping
|
|
19
|
+
|
|
20
|
+
function assertNoDeprecatedRegistryOptions(registry: RegistryOptions) {
|
|
21
|
+
const usedRegistryKeys = (Object.keys(deprecatedRegistryMapping) as DeprecatedRegistryKey[])
|
|
22
|
+
.filter(key => Object.prototype.hasOwnProperty.call(registry, key))
|
|
23
|
+
|
|
24
|
+
if (usedRegistryKeys.length > 0) {
|
|
25
|
+
const mapping = usedRegistryKeys.map(key => `${key} -> ${deprecatedRegistryMapping[key]}`).join(', ')
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Legacy registry fields are no longer supported: ${usedRegistryKeys.join(', ')}. Use the modern fields instead: ${mapping}.`,
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const tailwind = registry.tailwindcss
|
|
32
|
+
if (!tailwind) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const usedTailwindKeys = (Object.keys(deprecatedTailwindMapping) as DeprecatedTailwindKey[])
|
|
37
|
+
.filter(key => Object.prototype.hasOwnProperty.call(tailwind, key))
|
|
38
|
+
|
|
39
|
+
if (usedTailwindKeys.length > 0) {
|
|
40
|
+
const mapping = usedTailwindKeys.map(key => `${key} -> tailwindcss.${deprecatedTailwindMapping[key]}`).join(', ')
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Legacy "registry.tailwindcss" fields are no longer supported: ${usedTailwindKeys.join(', ')}. Use the modern fields instead: ${mapping}.`,
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function fromUnifiedConfig(registry?: RegistryOptions): TailwindCssPatchOptions {
|
|
48
|
+
if (!registry) {
|
|
49
|
+
return {}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
assertNoDeprecatedRegistryOptions(registry)
|
|
53
|
+
|
|
54
|
+
const extract = registry.extract
|
|
55
|
+
? {
|
|
56
|
+
...(registry.extract.write === undefined ? {} : { write: registry.extract.write }),
|
|
57
|
+
...(registry.extract.file === undefined ? {} : { file: registry.extract.file }),
|
|
58
|
+
...(registry.extract.format === undefined ? {} : { format: registry.extract.format }),
|
|
59
|
+
...(registry.extract.pretty === undefined ? {} : { pretty: registry.extract.pretty }),
|
|
60
|
+
...(registry.extract.removeUniversalSelector === undefined ? {} : { removeUniversalSelector: registry.extract.removeUniversalSelector }),
|
|
61
|
+
}
|
|
62
|
+
: undefined
|
|
63
|
+
|
|
64
|
+
const tailwindcss = registry.tailwindcss
|
|
65
|
+
? {
|
|
66
|
+
...(registry.tailwindcss.version === undefined ? {} : { version: registry.tailwindcss.version }),
|
|
67
|
+
...(registry.tailwindcss.packageName === undefined ? {} : { packageName: registry.tailwindcss.packageName }),
|
|
68
|
+
...(registry.tailwindcss.resolve === undefined ? {} : { resolve: registry.tailwindcss.resolve }),
|
|
69
|
+
...(registry.tailwindcss.config === undefined ? {} : { config: registry.tailwindcss.config }),
|
|
70
|
+
...(registry.tailwindcss.cwd === undefined ? {} : { cwd: registry.tailwindcss.cwd }),
|
|
71
|
+
...(registry.tailwindcss.v2 === undefined ? {} : { v2: registry.tailwindcss.v2 }),
|
|
72
|
+
...(registry.tailwindcss.v3 === undefined ? {} : { v3: registry.tailwindcss.v3 }),
|
|
73
|
+
...(registry.tailwindcss.v4 === undefined ? {} : { v4: registry.tailwindcss.v4 }),
|
|
74
|
+
}
|
|
75
|
+
: undefined
|
|
76
|
+
|
|
77
|
+
const apply = registry.apply
|
|
78
|
+
? {
|
|
79
|
+
...(registry.apply.overwrite === undefined ? {} : { overwrite: registry.apply.overwrite }),
|
|
80
|
+
...(registry.apply.exposeContext === undefined ? {} : { exposeContext: registry.apply.exposeContext }),
|
|
81
|
+
...(registry.apply.extendLengthUnits === undefined ? {} : { extendLengthUnits: registry.apply.extendLengthUnits }),
|
|
82
|
+
}
|
|
83
|
+
: undefined
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
...(registry.projectRoot === undefined ? {} : { projectRoot: registry.projectRoot }),
|
|
87
|
+
...(apply === undefined ? {} : { apply }),
|
|
88
|
+
...(registry.cache === undefined ? {} : { cache: registry.cache }),
|
|
89
|
+
...(registry.filter === undefined ? {} : { filter: registry.filter }),
|
|
90
|
+
...(extract === undefined ? {} : { extract }),
|
|
91
|
+
...(tailwindcss === undefined ? {} : { tailwindcss }),
|
|
92
|
+
}
|
|
93
|
+
}
|