tailwindcss-patch 9.0.0-alpha.1 → 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.
Files changed (70) hide show
  1. package/README.md +20 -0
  2. package/dist/{chunk-Z6OMJZTU.js → chunk-TOAZIPHJ.js} +29 -11
  3. package/dist/{chunk-SWLOK2S6.mjs → chunk-VDWTCQ74.mjs} +29 -11
  4. package/dist/cli.js +4 -4
  5. package/dist/cli.mjs +1 -1
  6. package/dist/index.d.mts +43 -35
  7. package/dist/index.d.ts +43 -35
  8. package/dist/index.js +2 -2
  9. package/dist/index.mjs +1 -1
  10. package/package.json +8 -3
  11. package/src/api/tailwindcss-patcher.ts +424 -0
  12. package/src/babel/index.ts +12 -0
  13. package/src/cache/context.ts +212 -0
  14. package/src/cache/store.ts +1440 -0
  15. package/src/cache/types.ts +71 -0
  16. package/src/cli.ts +20 -0
  17. package/src/commands/basic-handlers.ts +145 -0
  18. package/src/commands/cli.ts +56 -0
  19. package/src/commands/command-context.ts +77 -0
  20. package/src/commands/command-definitions.ts +102 -0
  21. package/src/commands/command-metadata.ts +68 -0
  22. package/src/commands/command-registrar.ts +39 -0
  23. package/src/commands/command-runtime.ts +33 -0
  24. package/src/commands/default-handler-map.ts +25 -0
  25. package/src/commands/migrate-config.ts +104 -0
  26. package/src/commands/migrate-handler.ts +67 -0
  27. package/src/commands/migration-aggregation.ts +100 -0
  28. package/src/commands/migration-args.ts +85 -0
  29. package/src/commands/migration-file-executor.ts +189 -0
  30. package/src/commands/migration-output.ts +115 -0
  31. package/src/commands/migration-report-loader.ts +26 -0
  32. package/src/commands/migration-report.ts +21 -0
  33. package/src/commands/migration-source.ts +318 -0
  34. package/src/commands/migration-target-files.ts +161 -0
  35. package/src/commands/migration-target-resolver.ts +34 -0
  36. package/src/commands/migration-types.ts +65 -0
  37. package/src/commands/restore-handler.ts +24 -0
  38. package/src/commands/status-handler.ts +17 -0
  39. package/src/commands/status-output.ts +60 -0
  40. package/src/commands/token-output.ts +30 -0
  41. package/src/commands/types.ts +137 -0
  42. package/src/commands/validate-handler.ts +42 -0
  43. package/src/commands/validate.ts +83 -0
  44. package/src/config/index.ts +25 -0
  45. package/src/config/workspace.ts +87 -0
  46. package/src/constants.ts +4 -0
  47. package/src/extraction/candidate-extractor.ts +354 -0
  48. package/src/index.ts +57 -0
  49. package/src/install/class-collector.ts +1 -0
  50. package/src/install/context-registry.ts +1 -0
  51. package/src/install/index.ts +5 -0
  52. package/src/install/patch-runner.ts +1 -0
  53. package/src/install/process-tailwindcss.ts +1 -0
  54. package/src/install/status.ts +1 -0
  55. package/src/logger.ts +5 -0
  56. package/src/options/legacy.ts +93 -0
  57. package/src/options/normalize.ts +262 -0
  58. package/src/options/types.ts +217 -0
  59. package/src/patching/operations/export-context/index.ts +110 -0
  60. package/src/patching/operations/export-context/postcss-v2.ts +235 -0
  61. package/src/patching/operations/export-context/postcss-v3.ts +249 -0
  62. package/src/patching/operations/extend-length-units.ts +197 -0
  63. package/src/patching/patch-runner.ts +46 -0
  64. package/src/patching/status.ts +262 -0
  65. package/src/runtime/class-collector.ts +105 -0
  66. package/src/runtime/collector.ts +148 -0
  67. package/src/runtime/context-registry.ts +65 -0
  68. package/src/runtime/process-tailwindcss.ts +115 -0
  69. package/src/types.ts +159 -0
  70. package/src/utils.ts +52 -0
@@ -0,0 +1,115 @@
1
+ import { createRequire } from 'node:module'
2
+ import fs from 'fs-extra'
3
+ import path from 'pathe'
4
+ import postcss from 'postcss'
5
+ import { loadConfig } from 'tailwindcss-config'
6
+
7
+ const require = createRequire(import.meta.url)
8
+
9
+ export interface TailwindBuildOptions {
10
+ cwd: string
11
+ config?: string
12
+ majorVersion: 2 | 3 | 4
13
+ postcssPlugin?: string
14
+ }
15
+
16
+ function resolveModuleEntry(id: string) {
17
+ return path.isAbsolute(id) ? id : require.resolve(id)
18
+ }
19
+
20
+ function resolvePackageRootFromEntry(entry: string) {
21
+ let current = path.dirname(entry)
22
+ while (current && current !== path.dirname(current)) {
23
+ const packageJsonPath = path.join(current, 'package.json')
24
+ if (fs.pathExistsSync(packageJsonPath)) {
25
+ return current
26
+ }
27
+ current = path.dirname(current)
28
+ }
29
+ return undefined
30
+ }
31
+
32
+ function clearTailwindV3RuntimeState(pluginName: string) {
33
+ try {
34
+ const entry = resolveModuleEntry(pluginName)
35
+ const root = resolvePackageRootFromEntry(entry)
36
+ if (!root) {
37
+ return
38
+ }
39
+
40
+ const sharedStatePath = path.join(root, 'lib/lib/sharedState.js')
41
+ if (!fs.pathExistsSync(sharedStatePath)) {
42
+ return
43
+ }
44
+
45
+ const sharedState = require.cache[sharedStatePath]?.exports as
46
+ | {
47
+ contextMap?: Map<unknown, unknown>
48
+ configContextMap?: Map<unknown, unknown>
49
+ contextSourcesMap?: Map<unknown, unknown>
50
+ sourceHashMap?: Map<unknown, unknown>
51
+ }
52
+ | undefined
53
+ sharedState?.contextMap?.clear()
54
+ sharedState?.configContextMap?.clear()
55
+ sharedState?.contextSourcesMap?.clear()
56
+ sharedState?.sourceHashMap?.clear()
57
+
58
+ for (const candidate of ['lib/plugin.js', 'lib/index.js']) {
59
+ const runtimeEntry = path.join(root, candidate)
60
+ if (!fs.pathExistsSync(runtimeEntry)) {
61
+ continue
62
+ }
63
+
64
+ const runtimeModule = require.cache[runtimeEntry]?.exports as
65
+ | {
66
+ contextRef?: { value?: unknown[] }
67
+ }
68
+ | undefined
69
+ runtimeModule?.contextRef?.value?.splice(0, runtimeModule.contextRef.value.length)
70
+ break
71
+ }
72
+ }
73
+ catch {
74
+ // best-effort cleanup for Tailwind v3 runtime state
75
+ }
76
+ }
77
+
78
+ async function resolveConfigPath(options: TailwindBuildOptions) {
79
+ if (options.config && path.isAbsolute(options.config)) {
80
+ return options.config
81
+ }
82
+
83
+ const result = await loadConfig({ cwd: options.cwd })
84
+ if (!result) {
85
+ throw new Error(`Unable to locate Tailwind CSS config from ${options.cwd}`)
86
+ }
87
+ return result.filepath
88
+ }
89
+
90
+ export async function runTailwindBuild(options: TailwindBuildOptions) {
91
+ const configPath = await resolveConfigPath(options)
92
+ const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? '@tailwindcss/postcss' : 'tailwindcss')
93
+
94
+ if (options.majorVersion === 3) {
95
+ clearTailwindV3RuntimeState(pluginName)
96
+ }
97
+
98
+ if (options.majorVersion === 4) {
99
+ return postcss([
100
+ require(pluginName)({
101
+ config: configPath,
102
+ }),
103
+ ]).process('@import \'tailwindcss\';', {
104
+ from: undefined,
105
+ })
106
+ }
107
+
108
+ return postcss([
109
+ require(pluginName)({
110
+ config: configPath,
111
+ }),
112
+ ]).process('@tailwind base;@tailwind components;@tailwind utilities;', {
113
+ from: undefined,
114
+ })
115
+ }
package/src/types.ts ADDED
@@ -0,0 +1,159 @@
1
+ import type { SourceEntry } from '@tailwindcss/oxide'
2
+ import type { Node, Rule } from 'postcss'
3
+ import type { Config } from 'tailwindcss'
4
+ import type {
5
+ ApplyOptions,
6
+ CacheOptions,
7
+ CacheStrategy,
8
+ ExposeContextOptions,
9
+ ExtendLengthUnitsOptions,
10
+ ExtractOptions,
11
+ NormalizedTailwindCssPatchOptions,
12
+ TailwindCssOptions,
13
+ TailwindCssPatchOptions,
14
+ TailwindV2Options,
15
+ TailwindV3Options,
16
+ TailwindV4Options,
17
+ } from './options/types'
18
+
19
+ type TailwindcssClassCacheEntry = Rule | {
20
+ layer: string
21
+ options: Record<string, any>
22
+ sort: Record<string, any>
23
+ }
24
+
25
+ export type TailwindcssClassCache = Map<string, TailwindcssClassCacheEntry[]>
26
+
27
+ export interface TailwindcssRuntimeContext {
28
+ applyClassCache: Map<any, any>
29
+ candidateRuleCache: Map<
30
+ string,
31
+ Set<
32
+ [
33
+ {
34
+ arbitrary: any
35
+ index: any
36
+ layer: string
37
+ options: any[]
38
+ parallelIndex: any
39
+ parentLayer: string
40
+ variants: any
41
+ },
42
+ Node,
43
+ ]
44
+ >
45
+ >
46
+ candidateRuleMap: Map<string | string, [object, Node][]>
47
+ changedContent: any[]
48
+ classCache: TailwindcssClassCache
49
+ disposables: any[]
50
+ getClassList: (...args: any[]) => any
51
+ getClassOrder: (...args: any[]) => any
52
+ getVariants: (...args: any[]) => any
53
+ markInvalidUtilityCandidate: (...args: any[]) => any
54
+ markInvalidUtilityNode: (...args: any[]) => any
55
+ notClassCache: Set<string>
56
+ offsets: {
57
+ layerPositions: object
58
+ offsets: object
59
+ reservedVariantBits: any
60
+ variantOffsets: Map<string, any>
61
+ }
62
+ postCssNodeCache: Map<object, [Node]>
63
+ ruleCache: Set<[object, Node]>
64
+ stylesheetCache: Record<string, Set<any>>
65
+ tailwindConfig: Config
66
+ userConfigPath: string | null
67
+ variantMap: Map<string, [[object, (...args: any[]) => unknown]]>
68
+ variantOptions: Map<string, object>
69
+ }
70
+
71
+ export interface ExtractResult {
72
+ classList: string[]
73
+ classSet: Set<string>
74
+ filename?: string
75
+ }
76
+
77
+ export interface TailwindTokenLocation {
78
+ rawCandidate: string
79
+ file: string
80
+ relativeFile: string
81
+ extension: string
82
+ start: number
83
+ end: number
84
+ length: number
85
+ line: number
86
+ column: number
87
+ lineText: string
88
+ }
89
+
90
+ export type TailwindTokenFileKey = 'relative' | 'absolute'
91
+
92
+ export interface TailwindTokenReport {
93
+ entries: TailwindTokenLocation[]
94
+ filesScanned: number
95
+ sources: SourceEntry[]
96
+ skippedFiles: {
97
+ file: string
98
+ reason: string
99
+ }[]
100
+ }
101
+
102
+ export type TailwindTokenByFileMap = Record<string, TailwindTokenLocation[]>
103
+
104
+ export interface TailwindPatchRuntime {
105
+ options: NormalizedTailwindCssPatchOptions
106
+ majorVersion: 2 | 3 | 4
107
+ }
108
+
109
+ export type {
110
+ ApplyOptions,
111
+ CacheOptions,
112
+ CacheStrategy,
113
+ ExposeContextOptions,
114
+ ExtendLengthUnitsOptions,
115
+ ExtractOptions,
116
+ NormalizedTailwindCssPatchOptions,
117
+ TailwindCssOptions,
118
+ TailwindCssPatchOptions,
119
+ TailwindV2Options,
120
+ TailwindV3Options,
121
+ TailwindV4Options,
122
+ }
123
+
124
+ export interface ILengthUnitsPatchOptions {
125
+ units: string[]
126
+ lengthUnitsFilePath?: string
127
+ variableName?: string
128
+ overwrite?: boolean
129
+ destPath?: string
130
+ }
131
+
132
+ export type PatchCheckStatus = 'applied' | 'not-applied' | 'skipped' | 'unsupported'
133
+
134
+ export type PatchName = 'exposeContext' | 'extendLengthUnits'
135
+
136
+ export interface PatchStatusEntry {
137
+ name: PatchName
138
+ status: PatchCheckStatus
139
+ reason?: string
140
+ files: string[]
141
+ }
142
+
143
+ export interface PatchStatusReport {
144
+ package: {
145
+ name?: string
146
+ version?: string
147
+ root: string
148
+ }
149
+ majorVersion: 2 | 3 | 4
150
+ entries: PatchStatusEntry[]
151
+ }
152
+
153
+ export type {
154
+ CacheClearOptions,
155
+ CacheClearResult,
156
+ CacheClearScope,
157
+ CacheContextMetadata,
158
+ CacheReadMeta,
159
+ } from './cache/types'
package/src/utils.ts ADDED
@@ -0,0 +1,52 @@
1
+ export function isObject(val: any) {
2
+ return val !== null && typeof val === 'object' && Array.isArray(val) === false
3
+ };
4
+
5
+ export interface StringChange {
6
+ start: number
7
+ end: number
8
+ replacement: string
9
+ }
10
+
11
+ /**
12
+ * Apply the changes to the string such that a change in the length
13
+ * of the string does not break the indexes of the subsequent changes.
14
+ */
15
+ export function spliceChangesIntoString(str: string, changes: StringChange[]) {
16
+ // If there are no changes, return the original string
17
+ const firstChange = changes[0]
18
+ if (!firstChange) {
19
+ return str
20
+ }
21
+
22
+ // Sort all changes in order to make it easier to apply them
23
+ changes.sort((a, b) => {
24
+ return a.end - b.end || a.start - b.start
25
+ })
26
+
27
+ // Append original string between each chunk, and then the chunk itself
28
+ // This is sort of a String Builder pattern, thus creating less memory pressure
29
+ let result = ''
30
+
31
+ let previous = firstChange
32
+
33
+ result += str.slice(0, previous.start)
34
+ result += previous.replacement
35
+
36
+ for (let i = 1; i < changes.length; ++i) {
37
+ const change = changes[i]
38
+ if (!change) {
39
+ continue
40
+ }
41
+
42
+ result += str.slice(previous.end, change.start)
43
+ result += change.replacement
44
+
45
+ previous = change
46
+ }
47
+
48
+ // Add leftover string from last chunk to end
49
+ result += str.slice(previous.end)
50
+
51
+ return result
52
+ }