tailwindcss-patch 9.4.1 → 9.4.3
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 +69 -0
- package/dist/{cli-CBVPia5Z.js → cli-BztQHMRp.js} +63 -64
- package/dist/{cli-CgBdW1U5.mjs → cli-D0jXMGXf.mjs} +1 -1
- package/dist/cli.js +5 -6
- 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 +6 -6
- package/dist/commands/cli-runtime.mjs +2 -2
- package/dist/{dist-B1VBpHtd.js → dist-DDcbvOwe.js} +2 -2
- package/dist/index.d.mts +105 -5
- package/dist/index.d.ts +105 -5
- package/dist/index.js +325 -62
- package/dist/index.mjs +253 -4
- package/dist/{migrate-config-DqknZpUe.mjs → validate-Bug_WYcU.mjs} +193 -93
- package/dist/{validate-CaJv2g5K.d.ts → validate-BuqRodYI.d.ts} +65 -16
- package/dist/{migrate-config-Dn9OTXpO.js → validate-DbuKewV-.js} +257 -100
- package/dist/{validate-Dr7IkGU8.d.mts → validate-oAkURzUC.d.mts} +65 -15
- package/package.json +9 -9
- package/src/extraction/candidate-extractor.ts +76 -12
- package/src/public-api.ts +54 -13
- package/src/style-candidates.ts +35 -0
- package/src/style-generator.ts +80 -0
- package/src/v3/index.ts +11 -0
- package/src/v3/style-generator.ts +384 -0
- package/src/v4/bare-arbitrary-values.ts +127 -2
- package/src/v4/engine.ts +5 -2
- package/src/v4/index.ts +20 -4
- package/src/v4/node-adapter.ts +1 -1
- package/src/v4/source-scan.ts +1 -1
- package/src/v4/style-generator.ts +44 -0
- package/src/v4/types.ts +23 -0
- package/dist/chunk-8l464Juk.js +0 -28
- /package/dist/{dist-BjUV1yEM.mjs → dist-CxmNpfyy.mjs} +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PackageInfo, PackageResolvingOptions } from "local-pkg";
|
|
2
|
-
import * as _$consola from "consola";
|
|
3
2
|
import { Node, Rule } from "postcss";
|
|
4
3
|
import { CAC, Command } from "cac";
|
|
5
4
|
import { SourceEntry } from "@tailwindcss/oxide";
|
|
@@ -158,6 +157,44 @@ interface PatchStatusReport {
|
|
|
158
157
|
entries: PatchStatusEntry[];
|
|
159
158
|
}
|
|
160
159
|
//#endregion
|
|
160
|
+
//#region src/v4/bare-arbitrary-values.d.ts
|
|
161
|
+
interface BareArbitraryValueOptions {
|
|
162
|
+
/**
|
|
163
|
+
* 允许作为无方括号任意值的单位列表。
|
|
164
|
+
*/
|
|
165
|
+
units?: string[];
|
|
166
|
+
}
|
|
167
|
+
interface BareArbitraryValueResolveResult {
|
|
168
|
+
candidate: string;
|
|
169
|
+
canonicalCandidate: string;
|
|
170
|
+
}
|
|
171
|
+
interface BareArbitraryValueSourceCandidate {
|
|
172
|
+
rawCandidate: string;
|
|
173
|
+
start: number;
|
|
174
|
+
end: number;
|
|
175
|
+
}
|
|
176
|
+
declare function isBareArbitraryValuesEnabled(options: boolean | BareArbitraryValueOptions | undefined): boolean;
|
|
177
|
+
declare function resolveBareArbitraryValueCandidate(candidate: string, options?: boolean | BareArbitraryValueOptions): BareArbitraryValueResolveResult | undefined;
|
|
178
|
+
declare function extractBareArbitraryValueSourceCandidatesWithPositions(content: string, options?: boolean | BareArbitraryValueOptions): BareArbitraryValueSourceCandidate[];
|
|
179
|
+
declare function extractBareArbitraryValueSourceCandidates(content: string, options?: boolean | BareArbitraryValueOptions): string[];
|
|
180
|
+
declare function escapeCssClassName(value: string): string;
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/style-candidates.d.ts
|
|
183
|
+
interface TailwindStyleSource {
|
|
184
|
+
content: string;
|
|
185
|
+
extension?: string;
|
|
186
|
+
file?: string;
|
|
187
|
+
}
|
|
188
|
+
interface TailwindStyleCandidateOptions {
|
|
189
|
+
candidates?: Iterable<string>;
|
|
190
|
+
sources?: TailwindStyleSource[];
|
|
191
|
+
/**
|
|
192
|
+
* Enables UnoCSS-style bare arbitrary values such as `p-10%` and `p-2.5px`.
|
|
193
|
+
*/
|
|
194
|
+
bareArbitraryValues?: boolean | BareArbitraryValueOptions;
|
|
195
|
+
}
|
|
196
|
+
declare function collectTailwindStyleCandidates(options?: TailwindStyleCandidateOptions): Promise<Set<string>>;
|
|
197
|
+
//#endregion
|
|
161
198
|
//#region src/v4/types.d.ts
|
|
162
199
|
interface TailwindV4SourceOptions {
|
|
163
200
|
projectRoot?: string;
|
|
@@ -186,6 +223,7 @@ interface TailwindV4CandidateSource {
|
|
|
186
223
|
content: string;
|
|
187
224
|
extension?: string;
|
|
188
225
|
}
|
|
226
|
+
interface TailwindV4StyleSource extends TailwindStyleSource {}
|
|
189
227
|
interface TailwindV4GenerateOptions {
|
|
190
228
|
candidates?: Iterable<string>;
|
|
191
229
|
sources?: TailwindV4CandidateSource[];
|
|
@@ -220,6 +258,23 @@ interface TailwindV4GenerateResult {
|
|
|
220
258
|
sources: TailwindV4SourcePattern[];
|
|
221
259
|
root: TailwindV4CompiledSourceRoot;
|
|
222
260
|
}
|
|
261
|
+
interface TailwindV4StyleGenerateOptions extends TailwindV4SourceOptions {
|
|
262
|
+
source?: TailwindV4ResolvedSource;
|
|
263
|
+
candidates?: Iterable<string>;
|
|
264
|
+
sources?: TailwindV4StyleSource[];
|
|
265
|
+
/**
|
|
266
|
+
* Enables UnoCSS-style bare arbitrary values such as `p-10%` and `p-2.5px`.
|
|
267
|
+
*/
|
|
268
|
+
bareArbitraryValues?: TailwindV4GenerateOptions['bareArbitraryValues'];
|
|
269
|
+
/**
|
|
270
|
+
* Scans the compiled Tailwind CSS v4 source entries in addition to in-memory sources.
|
|
271
|
+
*/
|
|
272
|
+
scanSources?: TailwindV4GenerateOptions['scanSources'];
|
|
273
|
+
}
|
|
274
|
+
interface TailwindV4StyleGenerateResult extends TailwindV4GenerateResult {
|
|
275
|
+
tokens: Set<string>;
|
|
276
|
+
source: TailwindV4ResolvedSource;
|
|
277
|
+
}
|
|
223
278
|
interface TailwindV4DesignSystem {
|
|
224
279
|
parseCandidate: (candidate: string) => unknown[];
|
|
225
280
|
candidatesToCss: (candidates: string[]) => Array<string | null | undefined>;
|
|
@@ -496,14 +551,6 @@ type TailwindcssConfigResult = Awaited<ReturnType<TailwindcssConfigModule['getCo
|
|
|
496
551
|
//#region src/runtime/collector.d.ts
|
|
497
552
|
type TailwindMajorVersion = 2 | 3 | 4;
|
|
498
553
|
//#endregion
|
|
499
|
-
//#region src/v4/bare-arbitrary-values.d.ts
|
|
500
|
-
interface BareArbitraryValueOptions {
|
|
501
|
-
/**
|
|
502
|
-
* 允许作为无方括号任意值的单位列表。
|
|
503
|
-
*/
|
|
504
|
-
units?: string[];
|
|
505
|
-
}
|
|
506
|
-
//#endregion
|
|
507
554
|
//#region src/extraction/candidate-extractor.d.ts
|
|
508
555
|
interface ExtractValidCandidatesOption {
|
|
509
556
|
sources?: SourceEntry[];
|
|
@@ -513,15 +560,18 @@ interface ExtractValidCandidatesOption {
|
|
|
513
560
|
cwd?: string;
|
|
514
561
|
bareArbitraryValues?: boolean | BareArbitraryValueOptions;
|
|
515
562
|
}
|
|
563
|
+
interface ExtractCandidateOptions {
|
|
564
|
+
bareArbitraryValues?: boolean | BareArbitraryValueOptions;
|
|
565
|
+
}
|
|
516
566
|
interface ExtractSourceCandidate {
|
|
517
567
|
rawCandidate: string;
|
|
518
568
|
start: number;
|
|
519
569
|
end: number;
|
|
520
570
|
}
|
|
521
|
-
declare function extractRawCandidatesWithPositions(content: string, extension?: string): Promise<ExtractSourceCandidate[]>;
|
|
522
|
-
declare function extractSourceCandidatesWithPositions(content: string, extension?: string): Promise<ExtractSourceCandidate[]>;
|
|
523
|
-
declare function extractSourceCandidates(content: string, extension?: string): Promise<string[]>;
|
|
524
|
-
declare function extractRawCandidates(sources?: SourceEntry[]): Promise<string[]>;
|
|
571
|
+
declare function extractRawCandidatesWithPositions(content: string, extension?: string, options?: ExtractCandidateOptions): Promise<ExtractSourceCandidate[]>;
|
|
572
|
+
declare function extractSourceCandidatesWithPositions(content: string, extension?: string, options?: ExtractCandidateOptions): Promise<ExtractSourceCandidate[]>;
|
|
573
|
+
declare function extractSourceCandidates(content: string, extension?: string, options?: ExtractCandidateOptions): Promise<string[]>;
|
|
574
|
+
declare function extractRawCandidates(sources?: SourceEntry[], options?: ExtractCandidateOptions): Promise<string[]>;
|
|
525
575
|
declare function extractValidCandidates(options?: ExtractValidCandidatesOption): Promise<string[]>;
|
|
526
576
|
interface ExtractProjectCandidatesOptions {
|
|
527
577
|
cwd?: string;
|
|
@@ -586,7 +636,7 @@ declare class TailwindcssPatcher {
|
|
|
586
636
|
}
|
|
587
637
|
//#endregion
|
|
588
638
|
//#region src/logger.d.ts
|
|
589
|
-
declare const logger:
|
|
639
|
+
declare const logger: import("consola").ConsolaInstance;
|
|
590
640
|
//#endregion
|
|
591
641
|
//#region src/commands/migration-report.d.ts
|
|
592
642
|
declare const MIGRATION_REPORT_KIND = "tw-patch-migrate-report";
|
|
@@ -790,4 +840,4 @@ declare class ValidateCommandError extends Error {
|
|
|
790
840
|
constructor(summary: ValidateFailureSummary, options?: ErrorOptions);
|
|
791
841
|
}
|
|
792
842
|
//#endregion
|
|
793
|
-
export {
|
|
843
|
+
export { TailwindV4Engine as $, extractSourceCandidates as A, CacheClearOptions as At, ExtendLengthUnitsOptions as B, MIGRATION_REPORT_SCHEMA_VERSION as C, TailwindPatchRuntime as Ct, extractProjectCandidatesWithPositions as D, TailwindTokenReport as Dt, ExtractSourceCandidate as E, TailwindTokenLocation as Et, normalizeOptions as F, CacheIndexFileV2 as Ft, TailwindCssPatchOptions as G, NormalizedCacheOptions as H, ApplyOptions as I, CacheReadMeta as It, TailwindV4Options as J, TailwindV2Options as K, CacheOptions as L, CacheReadResult as Lt, extractValidCandidates as M, CacheClearScope as Mt, groupTokensByFile as N, CacheContextDescriptor as Nt, extractRawCandidates as O, TailwindcssClassCache as Ot, resolveProjectSourceFiles as P, CacheContextMetadata as Pt, TailwindV4DesignSystem as Q, CacheStrategy as R, MIGRATION_REPORT_KIND as S, PatchStatusReport as St, TailwindcssPatcher as T, TailwindTokenFileKey as Tt, NormalizedTailwindCssPatchOptions as U, ExtractOptions as V, TailwindCssOptions as W, TailwindV4CompiledSourceRoot as X, TailwindV4CandidateSource as Y, TailwindV4CssSource as Z, ConfigFileMigrationEntry as _, ExtractResult as _t, ValidateFailureSummary as a, TailwindV4StyleGenerateOptions as at, RestoreConfigFilesOptions as b, PatchName as bt, TailwindcssPatchCliMountOptions as c, TailwindStyleCandidateOptions as ct, TailwindcssPatchCommandContext as d, BareArbitraryValueOptions as dt, TailwindV4GenerateOptions as et, TailwindcssPatchCommandHandler as f, escapeCssClassName as ft, tailwindcssPatchCommands as g, resolveBareArbitraryValueCandidate as gt, TailwindcssPatchCommandOptions as h, isBareArbitraryValuesEnabled as ht, ValidateFailureReason as i, TailwindV4SourcePattern as it, extractSourceCandidatesWithPositions as j, CacheClearResult as jt, extractRawCandidatesWithPositions as k, TailwindcssRuntimeContext as kt, TailwindcssPatchCliOptions as l, TailwindStyleSource as lt, TailwindcssPatchCommandOptionDefinition as m, extractBareArbitraryValueSourceCandidatesWithPositions as mt, VALIDATE_FAILURE_REASONS as n, TailwindV4ResolvedSource as nt, ValidateJsonFailurePayload as o, TailwindV4StyleGenerateResult as ot, TailwindcssPatchCommandHandlerMap as p, extractBareArbitraryValueSourceCandidates as pt, TailwindV3Options as q, ValidateCommandError as r, TailwindV4SourceOptions as rt, ValidateJsonSuccessPayload as s, TailwindV4StyleSource as st, VALIDATE_EXIT_CODES as t, TailwindV4GenerateResult as tt, TailwindcssPatchCommand as u, collectTailwindStyleCandidates as ut, ConfigFileMigrationReport as v, ILengthUnitsPatchOptions as vt, logger as w, TailwindTokenByFileMap as wt, RestoreConfigFilesResult as x, PatchStatusEntry as xt, MigrateConfigFilesOptions as y, PatchCheckStatus as yt, ExposeContextOptions as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss-patch",
|
|
3
|
-
"version": "9.4.
|
|
3
|
+
"version": "9.4.3",
|
|
4
4
|
"description": "patch tailwindcss for exposing context and extract classes",
|
|
5
5
|
"author": "ice breaker <1324318532@qq.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@babel/generator": "^7.29.
|
|
65
|
-
"@babel/parser": "^7.29.
|
|
66
|
-
"@babel/traverse": "^7.29.
|
|
67
|
-
"@babel/types": "^7.29.
|
|
64
|
+
"@babel/generator": "^7.29.7",
|
|
65
|
+
"@babel/parser": "^7.29.7",
|
|
66
|
+
"@babel/traverse": "^7.29.7",
|
|
67
|
+
"@babel/types": "^7.29.7",
|
|
68
68
|
"@tailwindcss/node": "^4.3.0",
|
|
69
69
|
"@tailwindcss/oxide": "^4.3.0",
|
|
70
70
|
"cac": "6.7.14",
|
|
@@ -74,16 +74,16 @@
|
|
|
74
74
|
"micromatch": "^4.0.8",
|
|
75
75
|
"pathe": "^2.0.3",
|
|
76
76
|
"postcss": "^8.5.15",
|
|
77
|
-
"semver": "^7.8.
|
|
78
|
-
"tailwindcss-config": "^
|
|
77
|
+
"semver": "^7.8.4",
|
|
78
|
+
"tailwindcss-config": "^2.0.0",
|
|
79
79
|
"@tailwindcss-mangle/config": "7.0.2"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@tailwindcss/postcss": "^4.3.0",
|
|
83
83
|
"@tailwindcss/vite": "^4.3.0",
|
|
84
|
-
"tailwindcss": "^4.
|
|
84
|
+
"tailwindcss": "^4.3.0",
|
|
85
85
|
"tailwindcss-3": "npm:tailwindcss@^3.4.19",
|
|
86
|
-
"tailwindcss-4": "npm:tailwindcss@^4.
|
|
86
|
+
"tailwindcss-4": "npm:tailwindcss@^4.3.0"
|
|
87
87
|
},
|
|
88
88
|
"scripts": {
|
|
89
89
|
"dev": "tsdown --watch --sourcemap",
|
|
@@ -5,11 +5,12 @@ import type {
|
|
|
5
5
|
TailwindTokenLocation,
|
|
6
6
|
TailwindTokenReport,
|
|
7
7
|
} from '../types'
|
|
8
|
+
import type { BareArbitraryValueOptions } from '../v4/bare-arbitrary-values'
|
|
8
9
|
import { promises as fs } from 'node:fs'
|
|
9
10
|
import process from 'node:process'
|
|
10
11
|
import path from 'pathe'
|
|
11
12
|
import {
|
|
12
|
-
|
|
13
|
+
extractBareArbitraryValueSourceCandidatesWithPositions,
|
|
13
14
|
resolveBareArbitraryValueCandidate,
|
|
14
15
|
} from '../v4/bare-arbitrary-values'
|
|
15
16
|
import { extractTailwindV4InlineSourceCandidates, resolveValidTailwindV4Candidates } from '../v4/candidates'
|
|
@@ -59,6 +60,10 @@ export interface ExtractValidCandidatesOption {
|
|
|
59
60
|
bareArbitraryValues?: boolean | BareArbitraryValueOptions
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
export interface ExtractCandidateOptions {
|
|
64
|
+
bareArbitraryValues?: boolean | BareArbitraryValueOptions
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
export interface ExtractSourceCandidate {
|
|
63
68
|
rawCandidate: string
|
|
64
69
|
start: number
|
|
@@ -75,7 +80,7 @@ const HTML_ATTRIBUTE_NAME_CANDIDATE_RE = /^(?:class|className|hover-class|hoverC
|
|
|
75
80
|
const CSS_DIRECTIVE_CANDIDATE_RE = /^@(?:apply|tailwind|source|config|plugin|theme|utility|custom-variant|variant)$/
|
|
76
81
|
const CSS_APPLY_IMPORTANT = '!important'
|
|
77
82
|
const CSS_APPLY_RE = /@apply\s+([^;{}]+)/g
|
|
78
|
-
const JS_LIKE_SOURCE_EXTENSION_RE = /^
|
|
83
|
+
const JS_LIKE_SOURCE_EXTENSION_RE = /^[cm]?[jt]sx?$/
|
|
79
84
|
const MIXED_TEMPLATE_SOURCE_EXTENSION_RE = /^(?:vue|uvue|nvue|svelte|mpx)$/
|
|
80
85
|
const CSS_LIKE_SOURCE_EXTENSION_RE = /^(?:css|wxss|acss|jxss|ttss|qss|tyss|scss|sass|less|styl|stylus)$/
|
|
81
86
|
const SFC_SCRIPT_BLOCK_RE = /<script\b[^>]*>([\s\S]*?)<\/script>/gi
|
|
@@ -102,7 +107,7 @@ function isInsideHtmlTagText(content: string, candidate: ExtractSourceCandidate)
|
|
|
102
107
|
return false
|
|
103
108
|
}
|
|
104
109
|
const nextOpen = content.indexOf('<', candidate.end)
|
|
105
|
-
return nextOpen !== -1 && (nextOpen < content.indexOf('>', candidate.end) || content.
|
|
110
|
+
return nextOpen !== -1 && (nextOpen < content.indexOf('>', candidate.end) || !content.includes('>', candidate.end))
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
function isCssDirectiveCandidate(candidate: string) {
|
|
@@ -223,7 +228,36 @@ function createLocalCandidate(candidate: ExtractSourceCandidateWithContext): Ext
|
|
|
223
228
|
}
|
|
224
229
|
}
|
|
225
230
|
|
|
226
|
-
|
|
231
|
+
function dedupeCandidatesWithPositions(candidates: ExtractSourceCandidate[]) {
|
|
232
|
+
const seen = new Set<string>()
|
|
233
|
+
return candidates.filter((candidate) => {
|
|
234
|
+
const key = `${candidate.start}:${candidate.end}:${candidate.rawCandidate}`
|
|
235
|
+
if (seen.has(key)) {
|
|
236
|
+
return false
|
|
237
|
+
}
|
|
238
|
+
seen.add(key)
|
|
239
|
+
return true
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function createBareArbitraryValueCandidateContexts(
|
|
244
|
+
content: string,
|
|
245
|
+
extension: string,
|
|
246
|
+
offset: number,
|
|
247
|
+
options?: ExtractCandidateOptions,
|
|
248
|
+
): ExtractSourceCandidateWithContext[] {
|
|
249
|
+
return extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues)
|
|
250
|
+
.map(candidate => ({
|
|
251
|
+
content,
|
|
252
|
+
extension,
|
|
253
|
+
localStart: candidate.start,
|
|
254
|
+
rawCandidate: candidate.rawCandidate,
|
|
255
|
+
start: candidate.start + offset,
|
|
256
|
+
end: candidate.end + offset,
|
|
257
|
+
}))
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function extractCssApplyCandidates(content: string, extension: string, options?: ExtractCandidateOptions) {
|
|
227
261
|
const candidates: ExtractSourceCandidateWithContext[] = []
|
|
228
262
|
CSS_APPLY_RE.lastIndex = 0
|
|
229
263
|
let match = CSS_APPLY_RE.exec(content)
|
|
@@ -239,12 +273,13 @@ async function extractCssApplyCandidates(content: string, extension: string) {
|
|
|
239
273
|
start: candidate.start + applyParamsStart,
|
|
240
274
|
end: candidate.end + applyParamsStart,
|
|
241
275
|
})))
|
|
276
|
+
candidates.push(...createBareArbitraryValueCandidateContexts(applyParams, 'html', applyParamsStart, options))
|
|
242
277
|
match = CSS_APPLY_RE.exec(content)
|
|
243
278
|
}
|
|
244
279
|
return candidates
|
|
245
280
|
}
|
|
246
281
|
|
|
247
|
-
async function extractMixedSourceScriptCandidates(content: string) {
|
|
282
|
+
async function extractMixedSourceScriptCandidates(content: string, options?: ExtractCandidateOptions) {
|
|
248
283
|
const candidates: ExtractSourceCandidateWithContext[] = []
|
|
249
284
|
SFC_SCRIPT_BLOCK_RE.lastIndex = 0
|
|
250
285
|
let match = SFC_SCRIPT_BLOCK_RE.exec(content)
|
|
@@ -260,6 +295,7 @@ async function extractMixedSourceScriptCandidates(content: string) {
|
|
|
260
295
|
start: candidate.start + scriptStart,
|
|
261
296
|
end: candidate.end + scriptStart,
|
|
262
297
|
})))
|
|
298
|
+
candidates.push(...createBareArbitraryValueCandidateContexts(scriptContent, 'js', scriptStart, options))
|
|
263
299
|
match = SFC_SCRIPT_BLOCK_RE.exec(content)
|
|
264
300
|
}
|
|
265
301
|
return candidates
|
|
@@ -278,26 +314,30 @@ function createCandidateCacheKey(
|
|
|
278
314
|
export async function extractRawCandidatesWithPositions(
|
|
279
315
|
content: string,
|
|
280
316
|
extension: string = 'html',
|
|
317
|
+
options?: ExtractCandidateOptions,
|
|
281
318
|
): Promise<ExtractSourceCandidate[]> {
|
|
282
319
|
const { Scanner } = await getOxideModule()
|
|
283
320
|
const scanner = new Scanner({})
|
|
284
321
|
const result = scanner.getCandidatesWithPositions({ content, extension })
|
|
285
322
|
|
|
286
|
-
|
|
323
|
+
const candidates = result.map(({ candidate, position }) => ({
|
|
287
324
|
rawCandidate: candidate,
|
|
288
325
|
start: position,
|
|
289
326
|
end: position + candidate.length,
|
|
290
327
|
}))
|
|
328
|
+
candidates.push(...extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues))
|
|
329
|
+
return dedupeCandidatesWithPositions(candidates)
|
|
291
330
|
}
|
|
292
331
|
|
|
293
332
|
export async function extractSourceCandidatesWithPositions(
|
|
294
333
|
content: string,
|
|
295
334
|
extension: string = 'html',
|
|
335
|
+
options?: ExtractCandidateOptions,
|
|
296
336
|
): Promise<ExtractSourceCandidate[]> {
|
|
297
337
|
const normalizedExtension = extension.replace(/^\./, '')
|
|
298
338
|
const candidates: ExtractSourceCandidateWithContext[] = CSS_LIKE_SOURCE_EXTENSION_RE.test(normalizedExtension)
|
|
299
|
-
? await extractCssApplyCandidates(content, normalizedExtension)
|
|
300
|
-
: (await extractRawCandidatesWithPositions(content, normalizedExtension))
|
|
339
|
+
? await extractCssApplyCandidates(content, normalizedExtension, options)
|
|
340
|
+
: (await extractRawCandidatesWithPositions(content, normalizedExtension, options))
|
|
301
341
|
.map(candidate => ({
|
|
302
342
|
...candidate,
|
|
303
343
|
content,
|
|
@@ -305,7 +345,7 @@ export async function extractSourceCandidatesWithPositions(
|
|
|
305
345
|
localStart: candidate.start,
|
|
306
346
|
}))
|
|
307
347
|
if (MIXED_TEMPLATE_SOURCE_EXTENSION_RE.test(normalizedExtension)) {
|
|
308
|
-
candidates.push(...await extractMixedSourceScriptCandidates(content))
|
|
348
|
+
candidates.push(...await extractMixedSourceScriptCandidates(content, options))
|
|
309
349
|
}
|
|
310
350
|
const seen = new Set<string>()
|
|
311
351
|
return candidates.filter((candidate) => {
|
|
@@ -324,18 +364,37 @@ export async function extractSourceCandidatesWithPositions(
|
|
|
324
364
|
export async function extractSourceCandidates(
|
|
325
365
|
content: string,
|
|
326
366
|
extension: string = 'html',
|
|
367
|
+
options?: ExtractCandidateOptions,
|
|
327
368
|
): Promise<string[]> {
|
|
328
|
-
const candidates = await extractSourceCandidatesWithPositions(content, extension)
|
|
369
|
+
const candidates = await extractSourceCandidatesWithPositions(content, extension, options)
|
|
329
370
|
return [...new Set(candidates.map(candidate => candidate.rawCandidate))]
|
|
330
371
|
}
|
|
331
372
|
|
|
332
373
|
export async function extractRawCandidates(
|
|
333
374
|
sources?: SourceEntry[],
|
|
375
|
+
options?: ExtractCandidateOptions,
|
|
334
376
|
): Promise<string[]> {
|
|
335
377
|
const { Scanner } = await getOxideModule()
|
|
336
378
|
const scanner = new Scanner(sources === undefined ? {} : { sources })
|
|
337
379
|
|
|
338
|
-
|
|
380
|
+
const candidates = new Set(scanner.scan())
|
|
381
|
+
if (options?.bareArbitraryValues !== undefined && options.bareArbitraryValues !== false) {
|
|
382
|
+
await Promise.all((scanner.files ?? []).map(async (file) => {
|
|
383
|
+
try {
|
|
384
|
+
const content = await fs.readFile(file, 'utf8')
|
|
385
|
+
const extension = toExtension(file)
|
|
386
|
+
for (const candidate of extractBareArbitraryValueSourceCandidatesWithPositions(content, options.bareArbitraryValues)) {
|
|
387
|
+
if (shouldKeepSourceCandidate(content, extension, candidate)) {
|
|
388
|
+
candidates.add(candidate.rawCandidate)
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// 文件可能在扫描和读取之间被移除,保持与 Tailwind 原扫描结果一致。
|
|
394
|
+
}
|
|
395
|
+
}))
|
|
396
|
+
}
|
|
397
|
+
return [...candidates]
|
|
339
398
|
}
|
|
340
399
|
|
|
341
400
|
export async function extractValidCandidates(options?: ExtractValidCandidatesOption) {
|
|
@@ -370,7 +429,12 @@ export async function extractValidCandidates(options?: ExtractValidCandidatesOpt
|
|
|
370
429
|
const candidateCache = designSystemCandidateCache.get(candidateCacheKey) ?? new Map<string, boolean>()
|
|
371
430
|
designSystemCandidateCache.set(candidateCacheKey, candidateCache)
|
|
372
431
|
|
|
373
|
-
const candidates = await extractRawCandidates(
|
|
432
|
+
const candidates = await extractRawCandidates(
|
|
433
|
+
sources,
|
|
434
|
+
providedOptions.bareArbitraryValues === undefined
|
|
435
|
+
? undefined
|
|
436
|
+
: { bareArbitraryValues: providedOptions.bareArbitraryValues },
|
|
437
|
+
)
|
|
374
438
|
const inlineSources = extractTailwindV4InlineSourceCandidates(css)
|
|
375
439
|
for (const candidate of inlineSources.included) {
|
|
376
440
|
candidates.push(candidate)
|
package/src/public-api.ts
CHANGED
|
@@ -2,6 +2,17 @@ import type { TailwindcssMangleConfig } from '@tailwindcss-mangle/config'
|
|
|
2
2
|
|
|
3
3
|
export { TailwindcssPatcher } from './api/tailwindcss-patcher'
|
|
4
4
|
export { CacheStore } from './cache/store'
|
|
5
|
+
export {
|
|
6
|
+
type ConfigFileMigrationEntry,
|
|
7
|
+
type ConfigFileMigrationReport,
|
|
8
|
+
migrateConfigFiles,
|
|
9
|
+
type MigrateConfigFilesOptions,
|
|
10
|
+
MIGRATION_REPORT_KIND,
|
|
11
|
+
MIGRATION_REPORT_SCHEMA_VERSION,
|
|
12
|
+
restoreConfigFiles,
|
|
13
|
+
type RestoreConfigFilesOptions,
|
|
14
|
+
type RestoreConfigFilesResult,
|
|
15
|
+
} from './commands/migrate-config'
|
|
5
16
|
export {
|
|
6
17
|
type TailwindcssPatchCliMountOptions,
|
|
7
18
|
type TailwindcssPatchCliOptions,
|
|
@@ -22,29 +33,18 @@ export {
|
|
|
22
33
|
type ValidateJsonFailurePayload,
|
|
23
34
|
type ValidateJsonSuccessPayload,
|
|
24
35
|
} from './commands/validate'
|
|
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
36
|
export { normalizeOptions } from './config'
|
|
37
37
|
export type { TailwindCssPatchOptions } from './config'
|
|
38
38
|
export {
|
|
39
39
|
extractProjectCandidatesWithPositions,
|
|
40
40
|
extractRawCandidates,
|
|
41
41
|
extractRawCandidatesWithPositions,
|
|
42
|
+
type ExtractSourceCandidate,
|
|
42
43
|
extractSourceCandidates,
|
|
43
44
|
extractSourceCandidatesWithPositions,
|
|
44
45
|
extractValidCandidates,
|
|
45
46
|
groupTokensByFile,
|
|
46
47
|
resolveProjectSourceFiles,
|
|
47
|
-
type ExtractSourceCandidate,
|
|
48
48
|
} from './extraction/candidate-extractor'
|
|
49
49
|
export {
|
|
50
50
|
isValidCandidateToken,
|
|
@@ -59,22 +59,60 @@ export {
|
|
|
59
59
|
runTailwindBuild,
|
|
60
60
|
} from './install'
|
|
61
61
|
export { default as logger } from './logger'
|
|
62
|
+
export {
|
|
63
|
+
collectTailwindStyleCandidates,
|
|
64
|
+
} from './style-candidates'
|
|
65
|
+
export type {
|
|
66
|
+
TailwindStyleCandidateOptions,
|
|
67
|
+
TailwindStyleSource,
|
|
68
|
+
} from './style-candidates'
|
|
69
|
+
export {
|
|
70
|
+
generateCustomStyle,
|
|
71
|
+
generateTailwindStyle,
|
|
72
|
+
} from './style-generator'
|
|
73
|
+
export type {
|
|
74
|
+
CustomTailwindStyleGenerateContext,
|
|
75
|
+
CustomTailwindStyleGenerateOptions,
|
|
76
|
+
CustomTailwindStyleGenerateResult,
|
|
77
|
+
TailwindStyleGenerateOptions,
|
|
78
|
+
TailwindStyleGenerateResult,
|
|
79
|
+
} from './style-generator'
|
|
62
80
|
export * from './types'
|
|
63
81
|
export {
|
|
82
|
+
generateTailwindV3RawStyle,
|
|
83
|
+
generateTailwindV3Style,
|
|
84
|
+
} from './v3'
|
|
85
|
+
export type {
|
|
86
|
+
TailwindV3RawStyleGenerateOptions,
|
|
87
|
+
TailwindV3RawStyleGenerateResult,
|
|
88
|
+
TailwindV3StyleGenerateOptions,
|
|
89
|
+
TailwindV3StyleGenerateResult,
|
|
90
|
+
TailwindV3StyleLayer,
|
|
91
|
+
} from './v3'
|
|
92
|
+
export {
|
|
93
|
+
canonicalizeBareArbitraryValueCandidates,
|
|
94
|
+
collectTailwindV4StyleCandidates,
|
|
64
95
|
createTailwindV4CompiledSourceEntries,
|
|
65
|
-
createTailwindV4Engine,
|
|
66
96
|
createTailwindV4DefaultIgnoreSources,
|
|
97
|
+
createTailwindV4Engine,
|
|
67
98
|
createTailwindV4RootSources,
|
|
68
99
|
createTailwindV4SourceEntryMatcher,
|
|
69
100
|
createTailwindV4SourceExclusionMatcher,
|
|
101
|
+
escapeCssClassName,
|
|
70
102
|
expandTailwindV4SourceEntries,
|
|
71
103
|
expandTailwindV4SourceEntryBraces,
|
|
104
|
+
extractBareArbitraryValueSourceCandidates,
|
|
105
|
+
extractBareArbitraryValueSourceCandidatesWithPositions,
|
|
106
|
+
generateTailwindV4Style,
|
|
107
|
+
isBareArbitraryValuesEnabled,
|
|
72
108
|
isFileExcludedByTailwindV4SourceEntries,
|
|
73
109
|
isFileMatchedByTailwindV4SourceEntries,
|
|
74
110
|
loadTailwindV4DesignSystem,
|
|
75
111
|
mergeTailwindV4SourceEntries,
|
|
76
112
|
normalizeTailwindV4ScannerSources,
|
|
77
113
|
normalizeTailwindV4SourceEntries,
|
|
114
|
+
replaceBareArbitraryValueSelectors,
|
|
115
|
+
resolveBareArbitraryValueCandidate,
|
|
78
116
|
resolveSourceScanPath,
|
|
79
117
|
resolveTailwindV4Source,
|
|
80
118
|
resolveTailwindV4SourceBaseCandidates,
|
|
@@ -97,6 +135,9 @@ export type {
|
|
|
97
135
|
TailwindV4ResolvedSource,
|
|
98
136
|
TailwindV4SourceOptions,
|
|
99
137
|
TailwindV4SourcePattern,
|
|
138
|
+
TailwindV4StyleGenerateOptions,
|
|
139
|
+
TailwindV4StyleGenerateResult,
|
|
140
|
+
TailwindV4StyleSource,
|
|
100
141
|
} from './v4'
|
|
101
142
|
|
|
102
143
|
export function defineConfig<T extends TailwindcssMangleConfig>(config: T): T {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BareArbitraryValueOptions } from './v4/bare-arbitrary-values'
|
|
2
|
+
import { extractSourceCandidates } from './extraction/candidate-extractor'
|
|
3
|
+
|
|
4
|
+
export interface TailwindStyleSource {
|
|
5
|
+
content: string
|
|
6
|
+
extension?: string
|
|
7
|
+
file?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TailwindStyleCandidateOptions {
|
|
11
|
+
candidates?: Iterable<string>
|
|
12
|
+
sources?: TailwindStyleSource[]
|
|
13
|
+
/**
|
|
14
|
+
* Enables UnoCSS-style bare arbitrary values such as `p-10%` and `p-2.5px`.
|
|
15
|
+
*/
|
|
16
|
+
bareArbitraryValues?: boolean | BareArbitraryValueOptions
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function collectTailwindStyleCandidates(
|
|
20
|
+
options: TailwindStyleCandidateOptions = {},
|
|
21
|
+
): Promise<Set<string>> {
|
|
22
|
+
const candidates = new Set<string>()
|
|
23
|
+
for (const candidate of options.candidates ?? []) {
|
|
24
|
+
candidates.add(candidate)
|
|
25
|
+
}
|
|
26
|
+
for (const source of options.sources ?? []) {
|
|
27
|
+
const sourceCandidates = await extractSourceCandidates(source.content, source.extension, {
|
|
28
|
+
bareArbitraryValues: options.bareArbitraryValues,
|
|
29
|
+
})
|
|
30
|
+
for (const candidate of sourceCandidates) {
|
|
31
|
+
candidates.add(candidate)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return candidates
|
|
35
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TailwindStyleCandidateOptions,
|
|
3
|
+
TailwindStyleSource,
|
|
4
|
+
} from './style-candidates'
|
|
5
|
+
import type {
|
|
6
|
+
TailwindV3StyleGenerateOptions,
|
|
7
|
+
TailwindV3StyleGenerateResult,
|
|
8
|
+
} from './v3'
|
|
9
|
+
import type {
|
|
10
|
+
TailwindV4StyleGenerateOptions,
|
|
11
|
+
TailwindV4StyleGenerateResult,
|
|
12
|
+
} from './v4'
|
|
13
|
+
import { collectTailwindStyleCandidates } from './style-candidates'
|
|
14
|
+
import { generateTailwindV3Style } from './v3'
|
|
15
|
+
import { generateTailwindV4Style } from './v4'
|
|
16
|
+
|
|
17
|
+
export interface CustomTailwindStyleGenerateContext {
|
|
18
|
+
tokens: Set<string>
|
|
19
|
+
classSet: Set<string>
|
|
20
|
+
sources: TailwindStyleSource[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CustomTailwindStyleGenerateOptions extends TailwindStyleCandidateOptions {
|
|
24
|
+
generate: (context: CustomTailwindStyleGenerateContext) => string | Promise<string>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface CustomTailwindStyleGenerateResult {
|
|
28
|
+
version: 'custom'
|
|
29
|
+
css: string
|
|
30
|
+
tokens: Set<string>
|
|
31
|
+
classSet: Set<string>
|
|
32
|
+
sources: TailwindStyleSource[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type TailwindStyleGenerateOptions
|
|
36
|
+
= | ({ version: 3 } & TailwindV3StyleGenerateOptions)
|
|
37
|
+
| ({ version: 4 } & TailwindV4StyleGenerateOptions)
|
|
38
|
+
| ({ version: 'custom' } & CustomTailwindStyleGenerateOptions)
|
|
39
|
+
|
|
40
|
+
export type TailwindStyleGenerateResult
|
|
41
|
+
= | TailwindV3StyleGenerateResult
|
|
42
|
+
| (TailwindV4StyleGenerateResult & { version: 4 })
|
|
43
|
+
| CustomTailwindStyleGenerateResult
|
|
44
|
+
|
|
45
|
+
export async function generateCustomStyle(
|
|
46
|
+
options: CustomTailwindStyleGenerateOptions,
|
|
47
|
+
): Promise<CustomTailwindStyleGenerateResult> {
|
|
48
|
+
const tokens = await collectTailwindStyleCandidates(options)
|
|
49
|
+
const classSet = new Set(tokens)
|
|
50
|
+
const sources = options.sources ?? []
|
|
51
|
+
const css = await options.generate({
|
|
52
|
+
tokens,
|
|
53
|
+
classSet,
|
|
54
|
+
sources,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
version: 'custom',
|
|
59
|
+
css,
|
|
60
|
+
tokens,
|
|
61
|
+
classSet,
|
|
62
|
+
sources,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function generateTailwindStyle(
|
|
67
|
+
options: TailwindStyleGenerateOptions,
|
|
68
|
+
): Promise<TailwindStyleGenerateResult> {
|
|
69
|
+
if (options.version === 3) {
|
|
70
|
+
return generateTailwindV3Style(options)
|
|
71
|
+
}
|
|
72
|
+
if (options.version === 4) {
|
|
73
|
+
const result = await generateTailwindV4Style(options)
|
|
74
|
+
return {
|
|
75
|
+
...result,
|
|
76
|
+
version: 4,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return generateCustomStyle(options)
|
|
80
|
+
}
|
package/src/v3/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
generateTailwindV3RawStyle,
|
|
3
|
+
generateTailwindV3Style,
|
|
4
|
+
} from './style-generator'
|
|
5
|
+
export type {
|
|
6
|
+
TailwindV3RawStyleGenerateOptions,
|
|
7
|
+
TailwindV3RawStyleGenerateResult,
|
|
8
|
+
TailwindV3StyleGenerateOptions,
|
|
9
|
+
TailwindV3StyleGenerateResult,
|
|
10
|
+
TailwindV3StyleLayer,
|
|
11
|
+
} from './style-generator'
|