tailwindcss-patch 9.3.6 → 9.4.0
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/dist/cli.js +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/commands/cli-runtime.d.mts +1 -1
- package/dist/commands/cli-runtime.d.ts +1 -1
- package/dist/commands/cli-runtime.js +1 -1
- package/dist/commands/cli-runtime.mjs +1 -1
- package/dist/{index.bundle-BF-qTWsU.js → index.bundle-CGaLDIgy.js} +2 -13
- package/dist/{index.bundle-BR8XOc2F.mjs → index.bundle-D6yHhQ-W.mjs} +2 -13
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{validate-DoeOD2Su.d.mts → validate-CDegYLlg.d.mts} +5 -4
- package/dist/{validate-BF0OladD.mjs → validate-Ci0W2Fuu.mjs} +93 -82
- package/dist/{validate-CLTQnfBI.js → validate-D9fDrE9I.js} +98 -81
- package/dist/{validate-eCzgDdk_.d.ts → validate-DFiRmBtJ.d.ts} +5 -4
- package/package.json +2 -1
- package/src/extraction/candidate-extractor.ts +10 -99
- package/src/extraction/split-candidate-tokens.ts +98 -0
- package/src/index.ts +26 -0
- package/src/v4/engine.ts +2 -10
- package/src/v4/index.ts +22 -0
- package/src/v4/node-adapter.ts +2 -4
- package/src/v4/source-scan.ts +432 -0
- package/src/v4/types.ts +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss-patch",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
4
4
|
"description": "patch tailwindcss for exposing context and extract classes",
|
|
5
5
|
"author": "ice breaker <1324318532@qq.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"consola": "^3.4.2",
|
|
72
72
|
"fs-extra": "^11.3.5",
|
|
73
73
|
"local-pkg": "^1.2.1",
|
|
74
|
+
"micromatch": "^4.0.8",
|
|
74
75
|
"pathe": "^2.0.3",
|
|
75
76
|
"postcss": "^8.5.15",
|
|
76
77
|
"semver": "^7.8.1",
|
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
} from '../v4/bare-arbitrary-values'
|
|
15
15
|
import { extractTailwindV4InlineSourceCandidates, resolveValidTailwindV4Candidates } from '../v4/candidates'
|
|
16
16
|
import { compileTailwindV4Source, getTailwindV4DesignSystemCacheKey, loadTailwindV4DesignSystem } from '../v4/node-adapter'
|
|
17
|
+
import {
|
|
18
|
+
createTailwindV4CompiledSourceEntries,
|
|
19
|
+
normalizeTailwindV4ScannerSources,
|
|
20
|
+
} from '../v4/source-scan'
|
|
17
21
|
|
|
18
22
|
let oxideImportPromise: ReturnType<typeof importOxide> | undefined
|
|
19
23
|
const designSystemCandidateCache = new Map<string, Map<string, boolean>>()
|
|
@@ -507,99 +511,12 @@ export interface ResolveProjectSourceFilesOptions {
|
|
|
507
511
|
filter?: (file: string) => boolean
|
|
508
512
|
}
|
|
509
513
|
|
|
510
|
-
function expandBracePattern(pattern: string) {
|
|
511
|
-
const index = pattern.indexOf('{')
|
|
512
|
-
if (index === -1) {
|
|
513
|
-
return [pattern]
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const rest = pattern.slice(index)
|
|
517
|
-
let depth = 0
|
|
518
|
-
let endIndex = -1
|
|
519
|
-
for (let i = 0; i < rest.length; i++) {
|
|
520
|
-
const char = rest[i]
|
|
521
|
-
if (char === '\\') {
|
|
522
|
-
i += 1
|
|
523
|
-
continue
|
|
524
|
-
}
|
|
525
|
-
if (char === '{') {
|
|
526
|
-
depth += 1
|
|
527
|
-
continue
|
|
528
|
-
}
|
|
529
|
-
if (char === '}') {
|
|
530
|
-
depth -= 1
|
|
531
|
-
if (depth === 0) {
|
|
532
|
-
endIndex = i
|
|
533
|
-
break
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (endIndex === -1) {
|
|
538
|
-
return [pattern]
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
const prefix = pattern.slice(0, index)
|
|
542
|
-
const inner = rest.slice(1, endIndex)
|
|
543
|
-
const suffix = rest.slice(endIndex + 1)
|
|
544
|
-
const parts: string[] = []
|
|
545
|
-
const stack: string[] = []
|
|
546
|
-
let lastPos = 0
|
|
547
|
-
for (let i = 0; i < inner.length; i++) {
|
|
548
|
-
const char = inner[i]
|
|
549
|
-
if (char === '\\') {
|
|
550
|
-
i += 1
|
|
551
|
-
continue
|
|
552
|
-
}
|
|
553
|
-
if (char === '{') {
|
|
554
|
-
stack.push('}')
|
|
555
|
-
continue
|
|
556
|
-
}
|
|
557
|
-
if (char === '}' && stack[stack.length - 1] === '}') {
|
|
558
|
-
stack.pop()
|
|
559
|
-
continue
|
|
560
|
-
}
|
|
561
|
-
if (char === ',' && stack.length === 0) {
|
|
562
|
-
parts.push(inner.slice(lastPos, i))
|
|
563
|
-
lastPos = i + 1
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
parts.push(inner.slice(lastPos))
|
|
567
|
-
|
|
568
|
-
return parts.flatMap(part =>
|
|
569
|
-
expandBracePattern(`${prefix}${part}${suffix}`))
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function normalizeScannerSources(
|
|
573
|
-
sources: SourceEntry[] | undefined,
|
|
574
|
-
cwd: string,
|
|
575
|
-
ignoredSources: SourceEntry[] = [],
|
|
576
|
-
) {
|
|
577
|
-
const baseSources = sources?.length
|
|
578
|
-
? sources
|
|
579
|
-
: [
|
|
580
|
-
{
|
|
581
|
-
base: cwd,
|
|
582
|
-
pattern: '**/*',
|
|
583
|
-
negated: false,
|
|
584
|
-
},
|
|
585
|
-
]
|
|
586
|
-
|
|
587
|
-
return [...baseSources, ...ignoredSources].flatMap((source) => {
|
|
588
|
-
const base = source.base ?? cwd
|
|
589
|
-
return expandBracePattern(source.pattern).map(pattern => ({
|
|
590
|
-
base,
|
|
591
|
-
pattern,
|
|
592
|
-
negated: source.negated,
|
|
593
|
-
}))
|
|
594
|
-
})
|
|
595
|
-
}
|
|
596
|
-
|
|
597
514
|
async function resolveScannerSources(options?: ResolveProjectSourceFilesOptions) {
|
|
598
515
|
const cwd = options?.cwd ? path.resolve(options.cwd) : process.cwd()
|
|
599
516
|
if (options?.sources?.length || options?.css === undefined) {
|
|
600
517
|
return {
|
|
601
518
|
cwd,
|
|
602
|
-
sources:
|
|
519
|
+
sources: normalizeTailwindV4ScannerSources(options?.sources, cwd, options?.ignoredSources),
|
|
603
520
|
}
|
|
604
521
|
}
|
|
605
522
|
|
|
@@ -611,19 +528,13 @@ async function resolveScannerSources(options?: ResolveProjectSourceFilesOptions)
|
|
|
611
528
|
css: options.css,
|
|
612
529
|
dependencies: [],
|
|
613
530
|
})
|
|
614
|
-
const rootSources = (() => {
|
|
615
|
-
if (compiled.root === 'none') {
|
|
616
|
-
return []
|
|
617
|
-
}
|
|
618
|
-
if (compiled.root === null) {
|
|
619
|
-
return [{ base, pattern: '**/*', negated: false }]
|
|
620
|
-
}
|
|
621
|
-
return [{ ...compiled.root, negated: false }]
|
|
622
|
-
})()
|
|
623
|
-
|
|
624
531
|
return {
|
|
625
532
|
cwd,
|
|
626
|
-
sources:
|
|
533
|
+
sources: normalizeTailwindV4ScannerSources(
|
|
534
|
+
createTailwindV4CompiledSourceEntries(compiled.root, compiled.sources, base),
|
|
535
|
+
cwd,
|
|
536
|
+
options.ignoredSources,
|
|
537
|
+
),
|
|
627
538
|
}
|
|
628
539
|
}
|
|
629
540
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// 参考链接:https://github.com/tailwindlabs/tailwindcss/blob/master/src/lib/regex.js
|
|
2
|
+
// eslint-disable-next-line regexp/no-obscure-range
|
|
3
|
+
export const validateCandidateTokenRE = /[\w\u00A0-\uFFFF%-?]/
|
|
4
|
+
|
|
5
|
+
export function isValidCandidateToken(token = ''): token is string {
|
|
6
|
+
return validateCandidateTokenRE.test(token)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const SPLIT_CACHE_LIMIT = 8192
|
|
10
|
+
const ESCAPED_WHITESPACE_RE = /\\[nrt]/g
|
|
11
|
+
const splitCache = new Map<string, string[]>()
|
|
12
|
+
|
|
13
|
+
function isSplitter(char: string, bracketDepth: number) {
|
|
14
|
+
return bracketDepth === 0 && (char === '"' || /\s/.test(char))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function hasClosingQuotedArbitraryValue(code: string, start: number, quote: string) {
|
|
18
|
+
for (let index = start; index < code.length; index++) {
|
|
19
|
+
if (code[index] === '\\') {
|
|
20
|
+
index++
|
|
21
|
+
continue
|
|
22
|
+
}
|
|
23
|
+
if (code[index] === quote) {
|
|
24
|
+
return code.includes(']', index + 1)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function splitBracketAware(code: string) {
|
|
32
|
+
const result: string[] = []
|
|
33
|
+
let bracketDepth = 0
|
|
34
|
+
let bracketQuote: string | undefined
|
|
35
|
+
let start = 0
|
|
36
|
+
|
|
37
|
+
for (let index = 0; index < code.length; index++) {
|
|
38
|
+
const char = code[index]
|
|
39
|
+
if (bracketDepth > 0 && char === '\\') {
|
|
40
|
+
index++
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (bracketDepth > 0 && (char === '"' || char === '\'')) {
|
|
45
|
+
if (bracketQuote === char) {
|
|
46
|
+
bracketQuote = undefined
|
|
47
|
+
}
|
|
48
|
+
else if (bracketQuote === undefined && hasClosingQuotedArbitraryValue(code, index + 1, char)) {
|
|
49
|
+
bracketQuote = char
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (bracketQuote === undefined) {
|
|
54
|
+
if (char === '[' && code.includes(']', index + 1)) {
|
|
55
|
+
bracketDepth++
|
|
56
|
+
}
|
|
57
|
+
else if (char === ']' && bracketDepth > 0) {
|
|
58
|
+
bracketDepth--
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!isSplitter(char, bracketDepth)) {
|
|
63
|
+
continue
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const candidate = code.slice(start, index)
|
|
67
|
+
if (isValidCandidateToken(candidate)) {
|
|
68
|
+
result.push(candidate)
|
|
69
|
+
}
|
|
70
|
+
start = index + 1
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const candidate = code.slice(start)
|
|
74
|
+
if (isValidCandidateToken(candidate)) {
|
|
75
|
+
result.push(candidate)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return result
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function splitCandidateTokens(code: string) {
|
|
82
|
+
const cached = splitCache.get(code)
|
|
83
|
+
if (cached) {
|
|
84
|
+
return cached
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 把压缩产物中的转义空白字符(\n \r \t)先还原成空格,避免被粘连到类名上。
|
|
88
|
+
const normalized = code.includes('\\') ? code.replace(ESCAPED_WHITESPACE_RE, ' ') : code
|
|
89
|
+
const result = splitBracketAware(normalized)
|
|
90
|
+
|
|
91
|
+
// 防止缓存无限增长。
|
|
92
|
+
if (splitCache.size >= SPLIT_CACHE_LIMIT) {
|
|
93
|
+
splitCache.clear()
|
|
94
|
+
}
|
|
95
|
+
splitCache.set(code, result)
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -46,6 +46,11 @@ export {
|
|
|
46
46
|
resolveProjectSourceFiles,
|
|
47
47
|
type ExtractSourceCandidate,
|
|
48
48
|
} from './extraction/candidate-extractor'
|
|
49
|
+
export {
|
|
50
|
+
isValidCandidateToken,
|
|
51
|
+
splitCandidateTokens,
|
|
52
|
+
validateCandidateTokenRE,
|
|
53
|
+
} from './extraction/split-candidate-tokens'
|
|
49
54
|
export {
|
|
50
55
|
collectClassesFromContexts,
|
|
51
56
|
collectClassesFromTailwindV4,
|
|
@@ -56,14 +61,34 @@ export {
|
|
|
56
61
|
export { default as logger } from './logger'
|
|
57
62
|
export * from './types'
|
|
58
63
|
export {
|
|
64
|
+
createTailwindV4CompiledSourceEntries,
|
|
59
65
|
createTailwindV4Engine,
|
|
66
|
+
createTailwindV4DefaultIgnoreSources,
|
|
67
|
+
createTailwindV4RootSources,
|
|
68
|
+
createTailwindV4SourceEntryMatcher,
|
|
69
|
+
createTailwindV4SourceExclusionMatcher,
|
|
70
|
+
expandTailwindV4SourceEntries,
|
|
71
|
+
expandTailwindV4SourceEntryBraces,
|
|
72
|
+
isFileExcludedByTailwindV4SourceEntries,
|
|
73
|
+
isFileMatchedByTailwindV4SourceEntries,
|
|
60
74
|
loadTailwindV4DesignSystem,
|
|
75
|
+
mergeTailwindV4SourceEntries,
|
|
76
|
+
normalizeTailwindV4ScannerSources,
|
|
77
|
+
normalizeTailwindV4SourceEntries,
|
|
78
|
+
resolveSourceScanPath,
|
|
61
79
|
resolveTailwindV4Source,
|
|
80
|
+
resolveTailwindV4SourceBaseCandidates,
|
|
81
|
+
resolveTailwindV4SourceEntry,
|
|
62
82
|
resolveTailwindV4SourceFromPatchOptions,
|
|
63
83
|
resolveValidTailwindV4Candidates,
|
|
84
|
+
TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
|
|
85
|
+
TAILWIND_V4_IGNORED_CONTENT_DIRS,
|
|
86
|
+
TAILWIND_V4_IGNORED_EXTENSIONS,
|
|
87
|
+
TAILWIND_V4_IGNORED_FILES,
|
|
64
88
|
} from './v4'
|
|
65
89
|
export type {
|
|
66
90
|
TailwindV4CandidateSource,
|
|
91
|
+
TailwindV4CompiledSourceRoot,
|
|
67
92
|
TailwindV4CssSource,
|
|
68
93
|
TailwindV4DesignSystem,
|
|
69
94
|
TailwindV4Engine,
|
|
@@ -71,6 +96,7 @@ export type {
|
|
|
71
96
|
TailwindV4GenerateResult,
|
|
72
97
|
TailwindV4ResolvedSource,
|
|
73
98
|
TailwindV4SourceOptions,
|
|
99
|
+
TailwindV4SourcePattern,
|
|
74
100
|
} from './v4'
|
|
75
101
|
|
|
76
102
|
export function defineConfig<T extends TailwindcssMangleConfig>(config: T): T {
|
package/src/v4/engine.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
resolveValidTailwindV4Candidates,
|
|
14
14
|
} from './candidates'
|
|
15
15
|
import { compileTailwindV4Source, loadTailwindV4DesignSystem } from './node-adapter'
|
|
16
|
+
import { createTailwindV4CompiledSourceEntries } from './source-scan'
|
|
16
17
|
|
|
17
18
|
function resolveScanSources(
|
|
18
19
|
options: TailwindV4GenerateOptions | undefined,
|
|
@@ -24,16 +25,7 @@ function resolveScanSources(
|
|
|
24
25
|
return options.scanSources
|
|
25
26
|
}
|
|
26
27
|
if (options?.scanSources === true) {
|
|
27
|
-
|
|
28
|
-
if (compiledRoot === 'none') {
|
|
29
|
-
return []
|
|
30
|
-
}
|
|
31
|
-
if (compiledRoot === null) {
|
|
32
|
-
return [{ base: source.base, pattern: '**/*', negated: false }]
|
|
33
|
-
}
|
|
34
|
-
return [{ ...compiledRoot, negated: false }]
|
|
35
|
-
})()
|
|
36
|
-
return [...rootSources, ...compiledSources]
|
|
28
|
+
return createTailwindV4CompiledSourceEntries(compiledRoot, compiledSources, source.base)
|
|
37
29
|
}
|
|
38
30
|
return []
|
|
39
31
|
}
|
package/src/v4/index.ts
CHANGED
|
@@ -8,6 +8,27 @@ export {
|
|
|
8
8
|
loadTailwindV4DesignSystem,
|
|
9
9
|
loadTailwindV4NodeModule,
|
|
10
10
|
} from './node-adapter'
|
|
11
|
+
export {
|
|
12
|
+
createTailwindV4CompiledSourceEntries,
|
|
13
|
+
createTailwindV4DefaultIgnoreSources,
|
|
14
|
+
createTailwindV4RootSources,
|
|
15
|
+
createTailwindV4SourceEntryMatcher,
|
|
16
|
+
createTailwindV4SourceExclusionMatcher,
|
|
17
|
+
expandTailwindV4SourceEntries,
|
|
18
|
+
expandTailwindV4SourceEntryBraces,
|
|
19
|
+
isFileExcludedByTailwindV4SourceEntries,
|
|
20
|
+
isFileMatchedByTailwindV4SourceEntries,
|
|
21
|
+
mergeTailwindV4SourceEntries,
|
|
22
|
+
normalizeTailwindV4ScannerSources,
|
|
23
|
+
normalizeTailwindV4SourceEntries,
|
|
24
|
+
resolveSourceScanPath,
|
|
25
|
+
resolveTailwindV4SourceBaseCandidates,
|
|
26
|
+
resolveTailwindV4SourceEntry,
|
|
27
|
+
TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
|
|
28
|
+
TAILWIND_V4_IGNORED_CONTENT_DIRS,
|
|
29
|
+
TAILWIND_V4_IGNORED_EXTENSIONS,
|
|
30
|
+
TAILWIND_V4_IGNORED_FILES,
|
|
31
|
+
} from './source-scan'
|
|
11
32
|
export {
|
|
12
33
|
resolveTailwindV4Source,
|
|
13
34
|
resolveTailwindV4SourceFromPatchOptions,
|
|
@@ -15,6 +36,7 @@ export {
|
|
|
15
36
|
} from './source'
|
|
16
37
|
export type {
|
|
17
38
|
TailwindV4CandidateSource,
|
|
39
|
+
TailwindV4CompiledSourceRoot,
|
|
18
40
|
TailwindV4CssSource,
|
|
19
41
|
TailwindV4DesignSystem,
|
|
20
42
|
TailwindV4Engine,
|
package/src/v4/node-adapter.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
TailwindV4DesignSystem,
|
|
3
3
|
TailwindV4ResolvedSource,
|
|
4
|
+
TailwindV4CompiledSourceRoot,
|
|
4
5
|
TailwindV4SourcePattern,
|
|
5
6
|
} from './types'
|
|
6
7
|
import { createRequire } from 'node:module'
|
|
@@ -9,10 +10,7 @@ import path from 'pathe'
|
|
|
9
10
|
|
|
10
11
|
interface TailwindV4CompiledSource {
|
|
11
12
|
sources: TailwindV4SourcePattern[]
|
|
12
|
-
root:
|
|
13
|
-
base: string
|
|
14
|
-
pattern: string
|
|
15
|
-
}
|
|
13
|
+
root: TailwindV4CompiledSourceRoot
|
|
16
14
|
build: (candidates: string[]) => string
|
|
17
15
|
}
|
|
18
16
|
|