weapp-tailwindcss 4.12.0-next.0 → 5.0.0-next.1

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 (310) hide show
  1. package/bin/weapp-tailwindcss.js +21 -1
  2. package/dist/babel/index.d.ts +3 -0
  3. package/dist/bundlers/gulp/index.d.ts +7 -0
  4. package/dist/bundlers/shared/cache.d.ts +16 -0
  5. package/dist/bundlers/shared/css-cleanup.d.ts +4 -0
  6. package/dist/bundlers/shared/css-imports.d.ts +8 -0
  7. package/dist/bundlers/shared/generator-candidates.d.ts +5 -0
  8. package/dist/bundlers/shared/generator-css.d.ts +41 -0
  9. package/dist/bundlers/shared/module-graph.d.ts +5 -0
  10. package/dist/bundlers/shared/run-tasks.d.ts +2 -0
  11. package/dist/bundlers/vite/bundle-entries.d.ts +14 -0
  12. package/dist/bundlers/vite/bundle-state.d.ts +43 -0
  13. package/dist/bundlers/vite/css-finalizer.d.ts +19 -0
  14. package/dist/bundlers/vite/generate-bundle.d.ts +20 -0
  15. package/dist/bundlers/vite/incremental-runtime-class-set.d.ts +21 -0
  16. package/dist/bundlers/vite/index.d.ts +3 -0
  17. package/dist/bundlers/vite/js-precheck.d.ts +1 -0
  18. package/dist/bundlers/vite/query.d.ts +15 -0
  19. package/dist/bundlers/vite/resolve-app-type.d.ts +2 -0
  20. package/dist/bundlers/vite/rewrite-css-imports.d.ts +11 -0
  21. package/dist/bundlers/vite/runtime-affecting-signature.d.ts +2 -0
  22. package/dist/bundlers/vite/utils.d.ts +9 -0
  23. package/dist/bundlers/webpack/BaseUnifiedPlugin/shared.d.ts +20 -0
  24. package/dist/bundlers/webpack/BaseUnifiedPlugin/v4-assets.d.ts +14 -0
  25. package/dist/bundlers/webpack/BaseUnifiedPlugin/v4-loaders.d.ts +15 -0
  26. package/dist/bundlers/webpack/BaseUnifiedPlugin/v4.d.ts +9 -0
  27. package/dist/bundlers/webpack/BaseUnifiedPlugin/v5-assets.d.ts +17 -0
  28. package/dist/bundlers/webpack/BaseUnifiedPlugin/v5-loaders.d.ts +19 -0
  29. package/dist/bundlers/webpack/BaseUnifiedPlugin/v5.d.ts +9 -0
  30. package/dist/bundlers/webpack/index.d.ts +1 -0
  31. package/dist/bundlers/webpack/loaders/weapp-tw-css-import-rewrite-loader.d.ts +12 -0
  32. package/dist/bundlers/webpack/loaders/weapp-tw-runtime-classset-loader.d.ts +11 -0
  33. package/dist/bundlers/webpack/shared/css-imports.d.ts +6 -0
  34. package/dist/bundlers/webpack/shared/loader-anchors.d.ts +8 -0
  35. package/dist/cache/index.d.ts +38 -0
  36. package/dist/cache/md5.d.ts +1 -0
  37. package/dist/chunk-8l464Juk.js +28 -0
  38. package/dist/cli/config.d.ts +5 -0
  39. package/dist/cli/context.d.ts +16 -0
  40. package/dist/cli/doctor/constants.d.ts +7 -0
  41. package/dist/cli/doctor/types.d.ts +31 -0
  42. package/dist/cli/doctor.d.ts +4 -0
  43. package/dist/cli/helpers/options/format.d.ts +2 -0
  44. package/dist/cli/helpers/options/parse.d.ts +3 -0
  45. package/dist/cli/helpers/options/resolve.d.ts +1 -0
  46. package/dist/cli/helpers/options.d.ts +3 -0
  47. package/dist/cli/helpers/patch-cwd.d.ts +1 -0
  48. package/dist/cli/helpers.d.ts +5 -0
  49. package/dist/cli/mount-options/patch-status.d.ts +2 -0
  50. package/dist/cli/mount-options.d.ts +2 -0
  51. package/dist/cli/patch-options.d.ts +6 -0
  52. package/dist/cli/tokens.d.ts +4 -0
  53. package/dist/cli/types.d.ts +17 -0
  54. package/dist/cli/vscode-entry.d.ts +14 -0
  55. package/dist/cli/workspace/package-dirs.d.ts +3 -0
  56. package/dist/cli/workspace/patch-package.d.ts +3 -0
  57. package/dist/cli/workspace/patch-utils.d.ts +3 -0
  58. package/dist/cli/workspace/types.d.ts +11 -0
  59. package/dist/cli/workspace/workspace-globs.d.ts +2 -0
  60. package/dist/cli/workspace/workspace-io.d.ts +1 -0
  61. package/dist/cli/workspace/workspace-lock.d.ts +1 -0
  62. package/dist/cli/workspace.d.ts +2 -0
  63. package/dist/cli.d.ts +1 -2
  64. package/dist/cli.js +2517 -1544
  65. package/dist/cli.mjs +2493 -1524
  66. package/dist/constants-B-_T5UnW.mjs +44 -0
  67. package/dist/constants-p1dyh1x1.js +73 -0
  68. package/dist/constants.d.ts +13 -0
  69. package/dist/context/compiler-context-cache.d.ts +3 -0
  70. package/dist/context/custom-attributes.d.ts +2 -0
  71. package/dist/context/handlers.d.ts +6 -0
  72. package/dist/context/index.d.ts +7 -0
  73. package/dist/context/logger.d.ts +4 -0
  74. package/dist/context/tailwindcss/basedir.d.ts +1 -0
  75. package/dist/context/tailwindcss/rax.d.ts +2 -0
  76. package/dist/context/tailwindcss.d.ts +4 -0
  77. package/dist/context/workspace.d.ts +3 -0
  78. package/dist/core.d.ts +5 -21
  79. package/dist/core.js +138 -180
  80. package/dist/core.mjs +135 -180
  81. package/dist/css-imports-BbrbluP9.js +177 -0
  82. package/dist/css-imports-CSdPq_Sc.mjs +128 -0
  83. package/dist/css-macro/constants.d.ts +14 -0
  84. package/dist/css-macro/index.d.ts +15 -0
  85. package/dist/css-macro/postcss.d.ts +3 -7
  86. package/dist/css-macro/postcss.js +44 -58
  87. package/dist/css-macro/postcss.mjs +44 -56
  88. package/dist/css-macro.d.ts +1 -20
  89. package/dist/css-macro.js +37 -50
  90. package/dist/css-macro.mjs +33 -47
  91. package/dist/debug/index.d.ts +5 -0
  92. package/dist/defaults.d.ts +2 -11
  93. package/dist/defaults.js +132 -8
  94. package/dist/defaults.mjs +128 -7
  95. package/dist/escape.js +31 -54
  96. package/dist/escape.mjs +18 -25
  97. package/dist/experimental/index.d.ts +2 -0
  98. package/dist/experimental/oxc/ast-utils.d.ts +30 -0
  99. package/dist/experimental/oxc/index.d.ts +2 -0
  100. package/dist/experimental/oxc/module-specifiers.d.ts +2 -0
  101. package/dist/experimental/shared/cache.d.ts +3 -0
  102. package/dist/experimental/shared/transform.d.ts +3 -0
  103. package/dist/experimental/shared.d.ts +8 -0
  104. package/dist/experimental/swc/ast-utils.d.ts +30 -0
  105. package/dist/experimental/swc/index.d.ts +2 -0
  106. package/dist/experimental/swc/module-specifiers.d.ts +2 -0
  107. package/dist/generator/index.d.ts +11 -0
  108. package/dist/generator/options.d.ts +15 -0
  109. package/dist/generator/types.d.ts +19 -0
  110. package/dist/generator-CZ-JXw6T.js +492 -0
  111. package/dist/generator-Dwxgra97.mjs +399 -0
  112. package/dist/generator-css-CnYjiMrD.js +1084 -0
  113. package/dist/generator-css-DhPFjSzK.mjs +1057 -0
  114. package/dist/generator.d.ts +1 -0
  115. package/dist/generator.js +19 -0
  116. package/dist/generator.mjs +2 -0
  117. package/dist/gulp.d.ts +4 -24
  118. package/dist/gulp.js +271 -13
  119. package/dist/gulp.mjs +263 -13
  120. package/dist/index.d.ts +8 -15
  121. package/dist/index.js +12 -24
  122. package/dist/index.mjs +6 -24
  123. package/dist/js/JsTokenUpdater.d.ts +14 -0
  124. package/dist/js/ModuleGraph.d.ts +18 -0
  125. package/dist/js/NodePathWalker.d.ts +33 -0
  126. package/dist/js/babel/parse.d.ts +9 -0
  127. package/dist/js/babel/process.d.ts +4 -0
  128. package/dist/js/babel.d.ts +13 -0
  129. package/dist/js/class-context.d.ts +3 -0
  130. package/dist/js/evalTransforms.d.ts +7 -0
  131. package/dist/js/handlers.d.ts +5 -0
  132. package/dist/js/index.d.ts +4 -0
  133. package/dist/js/module-graph/ignored-exports.d.ts +18 -0
  134. package/dist/js/module-graph/types.d.ts +17 -0
  135. package/dist/js/node-path-walker/export-handlers.d.ts +12 -0
  136. package/dist/js/node-path-walker/import-tokens.d.ts +24 -0
  137. package/dist/js/precheck.d.ts +2 -0
  138. package/dist/js/sourceAnalysis.d.ts +17 -0
  139. package/dist/js/syntax.d.ts +10 -0
  140. package/dist/js/taggedTemplateIgnore.d.ts +13 -0
  141. package/dist/js/types.d.ts +11 -0
  142. package/dist/lightningcss/index.d.ts +8 -0
  143. package/dist/lightningcss/style-handler/options.d.ts +3 -0
  144. package/dist/lightningcss/style-handler/selector-transform.d.ts +10 -0
  145. package/dist/lightningcss/style-handler/selector-utils.d.ts +10 -0
  146. package/dist/lightningcss/style-handler.d.ts +17 -0
  147. package/dist/loader-anchors-DvwgIYdA.mjs +205 -0
  148. package/dist/loader-anchors-cprm4Klq.js +273 -0
  149. package/dist/logger/index.d.ts +2 -0
  150. package/dist/logger-BZ45DZJT.js +1003 -0
  151. package/dist/logger-BoVx1Dbt.mjs +935 -0
  152. package/dist/patcher-options-6gJN2EXy.js +115 -0
  153. package/dist/patcher-options-DQfR5xxT.mjs +92 -0
  154. package/dist/postcss-html-transform.d.ts +3 -3
  155. package/dist/postcss-html-transform.js +7 -10
  156. package/dist/postcss-html-transform.mjs +3 -6
  157. package/dist/postcss.d.ts +15 -0
  158. package/dist/postcss.js +278 -0
  159. package/dist/postcss.mjs +268 -0
  160. package/dist/presets/hbuilderx.d.ts +4 -0
  161. package/dist/presets/index.d.ts +3 -0
  162. package/dist/presets/shared.d.ts +10 -0
  163. package/dist/presets/taro.d.ts +4 -0
  164. package/dist/presets/uni-app-x.d.ts +16 -0
  165. package/dist/presets/uni-app.d.ts +4 -0
  166. package/dist/presets.d.ts +1 -76
  167. package/dist/presets.js +115 -163
  168. package/dist/presets.mjs +107 -163
  169. package/dist/recorder-B_XyZ576.mjs +2763 -0
  170. package/dist/recorder-rn_2v_nd.js +2878 -0
  171. package/dist/reset/index.d.ts +2 -0
  172. package/dist/reset.d.ts +1 -4
  173. package/dist/reset.js +19 -8
  174. package/dist/reset.mjs +2 -8
  175. package/dist/shared/classname-transform.d.ts +14 -0
  176. package/dist/shared/mpx.d.ts +7 -0
  177. package/dist/shared/tailwindcss-css-redirect.d.ts +1 -0
  178. package/dist/tailwindcss/index.d.ts +11 -0
  179. package/dist/tailwindcss/miniprogram.d.ts +1 -0
  180. package/dist/tailwindcss/patcher-options.d.ts +56 -0
  181. package/dist/tailwindcss/patcher-resolve.d.ts +4 -0
  182. package/dist/tailwindcss/patcher.d.ts +13 -0
  183. package/dist/tailwindcss/recorder.d.ts +13 -0
  184. package/dist/tailwindcss/remove-unsupported-css.d.ts +2 -0
  185. package/dist/tailwindcss/runtime/cache.d.ts +11 -0
  186. package/dist/tailwindcss/runtime-logs.d.ts +3 -0
  187. package/dist/tailwindcss/runtime.d.ts +29 -0
  188. package/dist/tailwindcss/targets/paths.d.ts +13 -0
  189. package/dist/tailwindcss/targets/record-io.d.ts +5 -0
  190. package/dist/tailwindcss/targets/recorder.d.ts +3 -0
  191. package/dist/tailwindcss/targets/types.d.ts +35 -0
  192. package/dist/tailwindcss/targets.d.ts +6 -0
  193. package/dist/tailwindcss/v3-engine/generator.d.ts +2 -0
  194. package/dist/tailwindcss/v3-engine/index.d.ts +4 -0
  195. package/dist/tailwindcss/v3-engine/miniprogram.d.ts +4 -0
  196. package/dist/tailwindcss/v3-engine/source.d.ts +5 -0
  197. package/dist/tailwindcss/v3-engine/types.d.ts +55 -0
  198. package/dist/tailwindcss/v4/config.d.ts +5 -0
  199. package/dist/tailwindcss/v4/css-entries.d.ts +7 -0
  200. package/dist/tailwindcss/v4/index.d.ts +2 -0
  201. package/dist/tailwindcss/v4/multi-patcher.d.ts +2 -0
  202. package/dist/tailwindcss/v4/patcher-options.d.ts +24 -0
  203. package/dist/tailwindcss/v4/patcher.d.ts +14 -0
  204. package/dist/tailwindcss/v4-engine/design-system.d.ts +1 -0
  205. package/dist/tailwindcss/v4-engine/generator.d.ts +2 -0
  206. package/dist/tailwindcss/v4-engine/index.d.ts +5 -0
  207. package/dist/tailwindcss/v4-engine/miniprogram.d.ts +4 -0
  208. package/dist/tailwindcss/v4-engine/source.d.ts +7 -0
  209. package/dist/tailwindcss/v4-engine/types.d.ts +17 -0
  210. package/dist/typedoc.export.d.ts +5 -0
  211. package/dist/types/base.d.ts +1 -0
  212. package/dist/types/disabled-options.d.ts +4 -0
  213. package/dist/types/index.d.ts +104 -0
  214. package/dist/types/shared.d.ts +7 -0
  215. package/dist/types/user-defined-options/general.d.ts +31 -0
  216. package/dist/types/user-defined-options/important.d.ts +37 -0
  217. package/dist/types/user-defined-options/index.d.ts +11 -0
  218. package/dist/types/user-defined-options/lifecycle.d.ts +6 -0
  219. package/dist/types/user-defined-options/matcher.d.ts +9 -0
  220. package/dist/types.d.ts +1 -150
  221. package/dist/types.js +0 -1
  222. package/dist/types.mjs +1 -1
  223. package/dist/uni-app-x/component-local-style.d.ts +19 -0
  224. package/dist/uni-app-x/index.d.ts +2 -0
  225. package/dist/uni-app-x/options.d.ts +12 -0
  226. package/dist/uni-app-x/style-isolation.d.ts +2 -0
  227. package/dist/uni-app-x/transform.d.ts +9 -0
  228. package/dist/uni-app-x/vite.d.ts +36 -0
  229. package/dist/utils/decode.d.ts +2 -0
  230. package/dist/utils/disabled.d.ts +6 -0
  231. package/dist/utils/hbuilderx.d.ts +5 -0
  232. package/dist/utils/index.d.ts +7 -0
  233. package/dist/utils/nameMatcher.d.ts +4 -0
  234. package/dist/utils/resolve-package.d.ts +1 -0
  235. package/dist/utils/uni-platform.d.ts +11 -0
  236. package/dist/utils-7DUGTFED.mjs +48 -0
  237. package/dist/utils-DmC9_In3.js +61 -0
  238. package/dist/vite-BHpAqldo.js +1952 -0
  239. package/dist/vite-C8JlHiyR.mjs +1940 -0
  240. package/dist/vite.d.ts +4 -17
  241. package/dist/vite.js +5 -14
  242. package/dist/vite.mjs +2 -14
  243. package/dist/weapp-tw-css-import-rewrite-loader.js +59 -87
  244. package/dist/weapp-tw-runtime-classset-loader.js +33 -47
  245. package/dist/webpack-CABjKGGQ.mjs +441 -0
  246. package/dist/webpack-DNIJ0ysE.js +456 -0
  247. package/dist/webpack.d.ts +4 -25
  248. package/dist/webpack.js +6 -17
  249. package/dist/webpack.mjs +2 -17
  250. package/dist/webpack4.d.ts +4 -26
  251. package/dist/webpack4.js +379 -481
  252. package/dist/webpack4.mjs +370 -482
  253. package/dist/wxml/Tokenizer.d.ts +15 -0
  254. package/dist/wxml/custom-attributes.d.ts +4 -0
  255. package/dist/wxml/index.d.ts +2 -0
  256. package/dist/wxml/shared.d.ts +2 -0
  257. package/dist/wxml/tokenizer/types.d.ts +18 -0
  258. package/dist/wxml/utils/codegen/legacy-rewriter.d.ts +2 -0
  259. package/dist/wxml/utils/codegen/legacy-visitor.d.ts +8 -0
  260. package/dist/wxml/utils/codegen.d.ts +2 -0
  261. package/dist/wxml/utils/custom-template.d.ts +3 -0
  262. package/dist/wxml/utils/fragment-helpers.d.ts +6 -0
  263. package/dist/wxml/utils/fragment-updater.d.ts +4 -0
  264. package/dist/wxml/utils/template-fragments.d.ts +3 -0
  265. package/dist/wxml/utils.d.ts +8 -0
  266. package/dist/wxml/whitespace.d.ts +2 -0
  267. package/generator-placeholder.css +1 -0
  268. package/package.json +28 -13
  269. package/scripts/postinstall.mjs +59 -0
  270. package/dist/chunk-2LH6PZH3.mjs +0 -51
  271. package/dist/chunk-4AFQP74Z.js +0 -24
  272. package/dist/chunk-5ONE75V7.js +0 -2381
  273. package/dist/chunk-76S2EME4.mjs +0 -34
  274. package/dist/chunk-A5PB4KZT.js +0 -138
  275. package/dist/chunk-AYJ4HLWZ.mjs +0 -1508
  276. package/dist/chunk-DYLQ6UOI.js +0 -71
  277. package/dist/chunk-F2CKKG6Q.mjs +0 -171
  278. package/dist/chunk-F5XJWJYO.mjs +0 -582
  279. package/dist/chunk-FMK6SFQQ.js +0 -276
  280. package/dist/chunk-GC7WXUOW.js +0 -3906
  281. package/dist/chunk-GD4SQMVF.mjs +0 -2378
  282. package/dist/chunk-GMKSBLNY.js +0 -175
  283. package/dist/chunk-HL3US2OT.mjs +0 -10
  284. package/dist/chunk-LVSUBDJC.js +0 -579
  285. package/dist/chunk-NIS74SI6.js +0 -1511
  286. package/dist/chunk-OF6MFURR.js +0 -34
  287. package/dist/chunk-ONLKZIRQ.js +0 -7
  288. package/dist/chunk-OOHJLO5M.mjs +0 -71
  289. package/dist/chunk-OYSABARD.js +0 -51
  290. package/dist/chunk-QNRJCEZN.mjs +0 -3906
  291. package/dist/chunk-UUJWDME4.mjs +0 -276
  292. package/dist/chunk-WSS26HZS.js +0 -292
  293. package/dist/chunk-XAKAD2CR.mjs +0 -138
  294. package/dist/chunk-ZR3KN3FG.mjs +0 -292
  295. package/dist/cli.d.mts +0 -2
  296. package/dist/core.d.mts +0 -26
  297. package/dist/css-macro/postcss.d.mts +0 -7
  298. package/dist/css-macro.d.mts +0 -18
  299. package/dist/defaults.d.mts +0 -11
  300. package/dist/gulp.d.mts +0 -24
  301. package/dist/index-BXrmQelt.d.mts +0 -672
  302. package/dist/index-BXrmQelt.d.ts +0 -672
  303. package/dist/index.d.mts +0 -15
  304. package/dist/postcss-html-transform.d.mts +0 -2
  305. package/dist/presets.d.mts +0 -76
  306. package/dist/reset.d.mts +0 -1
  307. package/dist/types.d.mts +0 -150
  308. package/dist/vite.d.mts +0 -17
  309. package/dist/webpack.d.mts +0 -25
  310. package/dist/webpack4.d.mts +0 -26
package/dist/cli.mjs CHANGED
@@ -1,1621 +1,2590 @@
1
- // src/cli.ts
2
- import process18 from "process";
1
+ import { createRequire } from "node:module";
2
+ import process from "node:process";
3
3
  import semver from "semver";
4
- import { createTailwindcssPatchCli } from "tailwindcss-patch";
5
-
6
- // src/cli/context.ts
7
- import path12 from "path";
8
- import process12 from "process";
9
-
10
- // src/context/index.ts
11
- import { rm } from "fs/promises";
12
- import { logger as logger11 } from "@weapp-tailwindcss/logger";
13
-
14
- // src/cache/index.ts
4
+ import { TailwindcssPatcher, createTailwindcssPatchCli, normalizeOptions } from "tailwindcss-patch";
5
+ import path from "node:path";
6
+ import { access, mkdir, rm, writeFile } from "node:fs/promises";
7
+ import { logger, logger as logger$1 } from "@weapp-tailwindcss/logger";
15
8
  import { LRUCache } from "lru-cache";
16
-
17
- // src/cache/md5.ts
18
- import { md5 } from "@weapp-tailwindcss/shared/node";
19
-
20
- // src/defaults.ts
21
- import { isAllowedClassName, MappingChars2String } from "@weapp-core/escape";
22
-
23
- // src/utils/index.ts
24
- import { defu, defuOverrideArray, groupBy, isMap, isRegexp, noop, regExpTest, removeExt } from "@weapp-tailwindcss/shared";
25
-
26
- // src/utils/hbuilderx.ts
27
- import path from "path";
28
- import process from "process";
29
-
30
- // src/utils/uni-platform.ts
31
- import process2 from "process";
32
-
33
- // src/debug/index.ts
9
+ import { md5 as md5Hash } from "@weapp-tailwindcss/shared/node";
10
+ import { MappingChars2String, escape } from "@weapp-core/escape";
11
+ import "@weapp-tailwindcss/shared";
34
12
  import _createDebug from "debug";
35
- var _debug = _createDebug("weapp-tw");
13
+ import { constants, existsSync, readFileSync } from "node:fs";
14
+ import "@weapp-tailwindcss/postcss";
15
+ import _babelTraverse from "@babel/traverse";
16
+ import { parse as parse$1 } from "@babel/parser";
17
+ import { escapeStringRegexp } from "@weapp-core/regex";
18
+ import MagicString from "magic-string";
19
+ import { jsStringEscape } from "@ast-core/escape";
20
+ import { splitCode } from "@weapp-tailwindcss/shared/extractors";
21
+ import "@babel/types";
22
+ import "htmlparser2";
23
+ import { getPackageInfoSync } from "local-pkg";
24
+ import fg from "fast-glob";
25
+ import { parse } from "yaml";
26
+ //#region src/debug/index.ts
27
+ const _debug = _createDebug("weapp-tw");
36
28
  function createDebug(prefix) {
37
- const debug3 = ((formatter, ...args) => {
38
- return _debug((prefix ?? "") + formatter, ...args);
39
- });
40
- Object.defineProperty(debug3, "enabled", {
41
- enumerable: false,
42
- configurable: false,
43
- get() {
44
- return _debug.enabled;
45
- }
46
- });
47
- return debug3;
48
- }
49
-
50
- // src/tailwindcss/runtime/cache.ts
51
- import { statSync } from "fs";
52
-
53
- // src/tailwindcss/runtime.ts
54
- var debug = createDebug("[tailwindcss:runtime] ");
55
-
56
- // src/tailwindcss/runtime-logs.ts
57
- import process3 from "process";
58
- import { logger, pc } from "@weapp-tailwindcss/logger";
59
- var runtimeLogDedupeHolder = globalThis;
60
- var runtimeLogDedupe = runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ ?? (runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ = /* @__PURE__ */ new Set());
29
+ const debug = ((formatter, ...args) => {
30
+ return _debug((prefix ?? "") + formatter, ...args);
31
+ });
32
+ Object.defineProperty(debug, "enabled", {
33
+ enumerable: false,
34
+ configurable: false,
35
+ get() {
36
+ return _debug.enabled;
37
+ }
38
+ });
39
+ return debug;
40
+ }
41
+ createDebug("[tailwindcss:runtime] ");
42
+ //#endregion
43
+ //#region src/tailwindcss/runtime-logs.ts
44
+ const runtimeLogDedupeHolder = globalThis;
45
+ const runtimeLogDedupe = runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ ?? (runtimeLogDedupeHolder.__WEAPP_TW_RUNTIME_LOG_DEDUPE__ = /* @__PURE__ */ new Set());
61
46
  function createRuntimeLogKey(category, baseDir, rootPath, version) {
62
- return JSON.stringify([
63
- category,
64
- baseDir ?? process3.cwd(),
65
- rootPath ?? "",
66
- version ?? ""
67
- ]);
47
+ return JSON.stringify([
48
+ category,
49
+ baseDir ?? process.cwd(),
50
+ rootPath ?? "",
51
+ version ?? ""
52
+ ]);
68
53
  }
69
54
  function markRuntimeLog(category, baseDir, rootPath, version) {
70
- const key = createRuntimeLogKey(category, baseDir, rootPath, version);
71
- if (runtimeLogDedupe.has(key)) {
72
- return false;
73
- }
74
- runtimeLogDedupe.add(key);
75
- return true;
55
+ const key = createRuntimeLogKey(category, baseDir, rootPath, version);
56
+ if (runtimeLogDedupe.has(key)) return false;
57
+ runtimeLogDedupe.add(key);
58
+ return true;
76
59
  }
77
60
  function logRuntimeTailwindcssTarget(baseDir, rootPath, version) {
78
- if (!markRuntimeLog("target", baseDir, rootPath, version)) {
79
- return;
80
- }
81
- const versionText = version ? ` (v${version})` : "";
82
- logger.info("%s \u4F7F\u7528 Tailwind CSS%s", "Weapp-tailwindcss", versionText);
83
- }
84
-
85
- // src/tailwindcss/targets.ts
86
- import process6 from "process";
87
- import { logger as logger3 } from "@weapp-tailwindcss/logger";
88
-
89
- // src/tailwindcss/targets/paths.ts
90
- import { existsSync as existsSync2 } from "fs";
91
- import path3 from "path";
92
-
93
- // src/context/workspace.ts
94
- import { existsSync, readdirSync, readFileSync } from "fs";
95
- import path2 from "path";
61
+ if (!markRuntimeLog("target", baseDir, rootPath, version)) return;
62
+ const versionText = version ? ` (v${version})` : "";
63
+ logger.info("%s 使用 Tailwind CSS%s", "Weapp-tailwindcss", versionText);
64
+ }
65
+ //#endregion
66
+ //#region src/context/workspace.ts
96
67
  function findWorkspaceRoot(startDir) {
97
- if (!startDir) {
98
- return void 0;
99
- }
100
- let current = path2.resolve(startDir);
101
- while (true) {
102
- const workspaceFile = path2.join(current, "pnpm-workspace.yaml");
103
- if (existsSync(workspaceFile)) {
104
- return current;
105
- }
106
- const parent = path2.dirname(current);
107
- if (parent === current) {
108
- return void 0;
109
- }
110
- current = parent;
111
- }
68
+ if (!startDir) return;
69
+ let current = path.resolve(startDir);
70
+ while (true) {
71
+ if (existsSync(path.join(current, "pnpm-workspace.yaml"))) return current;
72
+ const parent = path.dirname(current);
73
+ if (parent === current) return;
74
+ current = parent;
75
+ }
112
76
  }
113
77
  function findNearestPackageRoot(startDir) {
114
- if (!startDir) {
115
- return void 0;
116
- }
117
- let current = path2.resolve(startDir);
118
- while (true) {
119
- const pkgPath = path2.join(current, "package.json");
120
- if (existsSync(pkgPath)) {
121
- return current;
122
- }
123
- const parent = path2.dirname(current);
124
- if (parent === current) {
125
- return void 0;
126
- }
127
- current = parent;
128
- }
129
- }
130
-
131
- // src/tailwindcss/targets/paths.ts
132
- var PATCH_INFO_FILENAME = "tailwindcss-target.json";
133
- var PATCH_INFO_CACHE_RELATIVE_PATH = path3.join("node_modules", ".cache", "weapp-tailwindcss", PATCH_INFO_FILENAME);
134
- var PATCH_INFO_LEGACY_RELATIVE_PATH = path3.join(".tw-patch", PATCH_INFO_FILENAME);
78
+ if (!startDir) return;
79
+ let current = path.resolve(startDir);
80
+ while (true) {
81
+ if (existsSync(path.join(current, "package.json"))) return current;
82
+ const parent = path.dirname(current);
83
+ if (parent === current) return;
84
+ current = parent;
85
+ }
86
+ }
87
+ //#endregion
88
+ //#region src/tailwindcss/targets/paths.ts
89
+ const PATCH_INFO_FILENAME = "tailwindcss-target.json";
90
+ const PATCH_INFO_CACHE_RELATIVE_PATH = path.join("node_modules", ".cache", "weapp-tailwindcss", PATCH_INFO_FILENAME);
91
+ const PATCH_INFO_LEGACY_RELATIVE_PATH = path.join(".tw-patch", PATCH_INFO_FILENAME);
92
+ function toDisplayPath(value) {
93
+ return path.normalize(value).replace(/\\/g, "/");
94
+ }
135
95
  function formatRelativeToBase(targetPath, baseDir) {
136
- if (!baseDir) {
137
- return path3.normalize(targetPath);
138
- }
139
- const relative = path3.relative(baseDir, targetPath);
140
- if (!relative || relative === ".") {
141
- return ".";
142
- }
143
- if (relative.startsWith("..")) {
144
- return path3.normalize(targetPath);
145
- }
146
- return path3.join(".", relative);
96
+ if (!baseDir) return toDisplayPath(targetPath);
97
+ const relative = path.relative(baseDir, targetPath);
98
+ if (!relative || relative === ".") return ".";
99
+ if (relative.startsWith("..")) return toDisplayPath(targetPath);
100
+ return toDisplayPath(path.join(".", relative));
147
101
  }
148
102
  function resolveRecordLocation(baseDir) {
149
- const normalizedBase = path3.normalize(baseDir);
150
- const packageRoot = findNearestPackageRoot(normalizedBase) ?? normalizedBase;
151
- const packageJsonPath = path3.join(packageRoot, "package.json");
152
- const hasPackageJson = existsSync2(packageJsonPath);
153
- const recordKeySource = hasPackageJson ? packageJsonPath : normalizedBase;
154
- const recordKey = md5(path3.normalize(recordKeySource));
155
- const recordDir = path3.join(packageRoot, "node_modules", ".cache", "weapp-tailwindcss", recordKey);
156
- const recordPath = path3.join(recordDir, PATCH_INFO_FILENAME);
157
- return {
158
- normalizedBase,
159
- packageRoot,
160
- recordDir,
161
- recordKey,
162
- recordPath,
163
- packageJsonPath: hasPackageJson ? packageJsonPath : void 0
164
- };
103
+ const normalizedBase = path.normalize(baseDir);
104
+ const packageRoot = findNearestPackageRoot(normalizedBase) ?? normalizedBase;
105
+ const packageJsonPath = path.join(packageRoot, "package.json");
106
+ const hasPackageJson = existsSync(packageJsonPath);
107
+ const recordKeySource = hasPackageJson ? packageJsonPath : normalizedBase;
108
+ const recordKey = md5Hash(path.normalize(recordKeySource));
109
+ const recordDir = path.join(packageRoot, "node_modules", ".cache", "weapp-tailwindcss", recordKey);
110
+ return {
111
+ normalizedBase,
112
+ packageRoot,
113
+ recordDir,
114
+ recordKey,
115
+ recordPath: path.join(recordDir, PATCH_INFO_FILENAME),
116
+ packageJsonPath: hasPackageJson ? packageJsonPath : void 0
117
+ };
165
118
  }
166
119
  function getRecordFileCandidates(baseDir) {
167
- const { normalizedBase, packageRoot, recordPath } = resolveRecordLocation(baseDir);
168
- const candidates = /* @__PURE__ */ new Set([
169
- recordPath,
170
- path3.join(packageRoot, PATCH_INFO_CACHE_RELATIVE_PATH),
171
- path3.join(normalizedBase, PATCH_INFO_CACHE_RELATIVE_PATH),
172
- path3.join(normalizedBase, PATCH_INFO_LEGACY_RELATIVE_PATH)
173
- ]);
174
- return [...candidates];
175
- }
176
-
177
- // src/tailwindcss/targets/record-io.ts
178
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
179
- import { mkdir, writeFile } from "fs/promises";
180
- import path4 from "path";
181
- import process4 from "process";
182
- import { logger as logger2 } from "@weapp-tailwindcss/logger";
183
-
184
- // package.json
185
- var package_default = {
186
- name: "weapp-tailwindcss",
187
- version: "4.12.0-next.0",
188
- description: "\u628A tailwindcss \u539F\u5B50\u5316\u6837\u5F0F\u601D\u60F3\uFF0C\u5E26\u7ED9\u5C0F\u7A0B\u5E8F\u5F00\u53D1\u8005\u4EEC! bring tailwindcss to miniprogram developers!",
189
- author: "ice breaker <1324318532@qq.com>",
190
- license: "MIT",
191
- homepage: "https://tw.icebreaker.top",
192
- repository: {
193
- type: "git",
194
- url: "git+https://github.com/sonofmagic/weapp-tailwindcss.git",
195
- directory: "packages/weapp-tailwindcss"
196
- },
197
- bugs: {
198
- url: "https://github.com/sonofmagic/weapp-tailwindcss/issues"
199
- },
200
- keywords: [
201
- "tailwindcss",
202
- "weapp",
203
- "wechat",
204
- "mini",
205
- "miniprogram",
206
- "mini app",
207
- "weapp-tw",
208
- "weapp-tailwindcss",
209
- "taro",
210
- "uni-app",
211
- "remax",
212
- "rax",
213
- "mpx",
214
- "jit",
215
- "mp",
216
- "android",
217
- "ios",
218
- "\u5C0F\u7A0B\u5E8F",
219
- "vite",
220
- "postcss",
221
- "webpack",
222
- "webpack-plugin",
223
- "gulp",
224
- "gulp-plugin"
225
- ],
226
- exports: {
227
- ".": {
228
- style: "./index.css",
229
- types: "./dist/index.d.ts",
230
- import: "./dist/index.mjs",
231
- require: "./dist/index.js"
232
- },
233
- "./escape": {
234
- types: "./dist/escape.d.ts",
235
- import: "./dist/escape.mjs",
236
- require: "./dist/escape.js"
237
- },
238
- "./vite": {
239
- types: "./dist/vite.d.ts",
240
- import: "./dist/vite.mjs",
241
- require: "./dist/vite.js"
242
- },
243
- "./webpack": {
244
- types: "./dist/webpack.d.ts",
245
- import: "./dist/webpack.mjs",
246
- require: "./dist/webpack.js"
247
- },
248
- "./webpack4": {
249
- types: "./dist/webpack4.d.ts",
250
- import: "./dist/webpack4.mjs",
251
- require: "./dist/webpack4.js"
252
- },
253
- "./core": {
254
- types: "./dist/core.d.ts",
255
- import: "./dist/core.mjs",
256
- require: "./dist/core.js"
257
- },
258
- "./gulp": {
259
- types: "./dist/gulp.d.ts",
260
- import: "./dist/gulp.mjs",
261
- require: "./dist/gulp.js"
262
- },
263
- "./defaults": {
264
- types: "./dist/defaults.d.ts",
265
- import: "./dist/defaults.mjs",
266
- require: "./dist/defaults.js"
267
- },
268
- "./presets": {
269
- types: "./dist/presets.d.ts",
270
- import: "./dist/presets.mjs",
271
- require: "./dist/presets.js"
272
- },
273
- "./reset": {
274
- types: "./dist/reset.d.ts",
275
- import: "./dist/reset.mjs",
276
- require: "./dist/reset.js"
277
- },
278
- "./css-macro/postcss": {
279
- types: "./dist/css-macro/postcss.d.ts",
280
- import: "./dist/css-macro/postcss.mjs",
281
- require: "./dist/css-macro/postcss.js"
282
- },
283
- "./css-macro": {
284
- types: "./dist/css-macro.d.ts",
285
- import: "./dist/css-macro.mjs",
286
- require: "./dist/css-macro.js"
287
- },
288
- "./types": {
289
- types: "./dist/types.d.ts",
290
- import: "./dist/types.mjs",
291
- require: "./dist/types.js"
292
- },
293
- "./postcss-html-transform": {
294
- types: "./dist/postcss-html-transform.d.ts",
295
- import: "./dist/postcss-html-transform.mjs",
296
- require: "./dist/postcss-html-transform.js"
297
- },
298
- "./package.json": "./package.json",
299
- "./index.css": "./index.css",
300
- "./index": "./index.css",
301
- "./preflight.css": "./preflight.css",
302
- "./preflight": "./preflight.css",
303
- "./theme.css": "./theme.css",
304
- "./theme": "./theme.css",
305
- "./utilities.css": "./utilities.css",
306
- "./utilities": "./utilities.css",
307
- "./with-layer.css": "./with-layer.css",
308
- "./with-layer": "./with-layer.css",
309
- "./uni-app-x": "./uni-app-x.css",
310
- "./uni-app-x.css": "./uni-app-x.css",
311
- "./css": "./css/index.css",
312
- "./*": "./*"
313
- },
314
- main: "./dist/index.js",
315
- module: "./dist/index.mjs",
316
- types: "./dist/index.d.ts",
317
- style: "index.css",
318
- typesVersions: {
319
- "*": {
320
- "*": [
321
- "./dist/*",
322
- "./dist/index.d.ts"
323
- ]
324
- }
325
- },
326
- bin: {
327
- "weapp-tailwindcss-webpack-plugin": "bin/weapp-tailwindcss.js",
328
- "weapp-tailwindcss": "bin/weapp-tailwindcss.js",
329
- "weapp-tw": "bin/weapp-tailwindcss.js"
330
- },
331
- files: [
332
- "bin",
333
- "css",
334
- "dist",
335
- "index.css",
336
- "preflight.css",
337
- "theme.css",
338
- "uni-app-x.css",
339
- "utilities.css",
340
- "with-layer.css"
341
- ],
342
- engines: {
343
- node: "^18.17.0 || >=20.5.0"
344
- },
345
- scripts: {
346
- dev: "tsup --watch --sourcemap",
347
- build: "tsup && node scripts/ensure-escape-dts.mjs",
348
- "build:tsc": "cross-env NODE_ENV=development tsc --build tsconfig.json",
349
- "build:cli": "cd plugins/cli && pnpm run build",
350
- "build:css": "tsx scripts/build-css.ts",
351
- "build:weapp-theme": "tsx scripts/build-weapp-theme.ts",
352
- test: "npm run postinstall && vitest run",
353
- "test:dev": "vitest",
354
- "test:ui": "vitest --ui",
355
- bench: "vitest bench --config ./vitest.config.ts",
356
- "bench:vite-perf": "tsx scripts/vite-perf-bench.ts",
357
- "bench:vite-perf:summary": "tsx scripts/vite-perf-summary.ts",
358
- "bench:js-handlers": "tsx scripts/js-bench.ts",
359
- "bench:js-diff": "tsx scripts/js-bench-diff.ts",
360
- tsd: "tsd",
361
- clean: "tsx scripts/clean.ts",
362
- "get-decl": "tsx scripts/get-decl.ts",
363
- "ls:pack": "npm pack --dry-run",
364
- "cli:patch": "node bin/weapp-tailwindcss.js patch",
365
- colors: "tsx scripts/colors.ts",
366
- release: "tsx scripts/release.ts",
367
- lint: "eslint .",
368
- "lint:fix": "eslint ./src --fix",
369
- postinstall: "node bin/weapp-tailwindcss.js patch",
370
- "bench:vite-dev-hmr": "tsx scripts/vite-dev-hmr-bench.ts",
371
- "test:watch-hmr": "node --import tsx scripts/watch-hmr-regression/index.ts"
372
- },
373
- publishConfig: {
374
- access: "public",
375
- registry: "https://registry.npmjs.org"
376
- },
377
- dependencies: {
378
- "@ast-core/escape": "~1.0.1",
379
- "@babel/parser": "~7.29.2",
380
- "@babel/traverse": "~7.29.0",
381
- "@babel/types": "~7.29.0",
382
- "@tailwindcss-mangle/config": "^7.0.0",
383
- "@vue/compiler-dom": "catalog:vue3",
384
- "@vue/compiler-sfc": "catalog:vue3",
385
- "@weapp-core/escape": "~7.0.0",
386
- "@weapp-core/regex": "~1.0.1",
387
- "@weapp-tailwindcss/logger": "workspace:*",
388
- "@weapp-tailwindcss/postcss": "workspace:*",
389
- "@weapp-tailwindcss/reset": "workspace:*",
390
- "@weapp-tailwindcss/shared": "workspace:*",
391
- cac: "6.7.14",
392
- "comment-json": "^4.6.2",
393
- debug: "~4.4.3",
394
- "fast-glob": "^3.3.3",
395
- htmlparser2: "10.1.0",
396
- "loader-utils": "2.0.4",
397
- "local-pkg": "^1.1.2",
398
- "lru-cache": "10.4.3",
399
- "magic-string": "0.30.21",
400
- semver: "~7.7.4",
401
- "tailwindcss-patch": "catalog:tailwindcssPatch",
402
- "webpack-sources": "3.3.4",
403
- yaml: "^2.8.3"
404
- },
405
- devDependencies: {
406
- "fast-check": "^4.7.0"
407
- }
408
- };
409
-
410
- // src/constants.ts
411
- var WEAPP_TW_REQUIRED_NODE_VERSION = "18.17.0";
412
- var WEAPP_TW_VERSION = package_default.version;
413
-
414
- // src/tailwindcss/targets/record-io.ts
415
- var loggedInvalidPatchRecords = /* @__PURE__ */ new Set();
120
+ const { normalizedBase, packageRoot, recordPath } = resolveRecordLocation(baseDir);
121
+ return [...new Set([
122
+ recordPath,
123
+ path.join(packageRoot, PATCH_INFO_CACHE_RELATIVE_PATH),
124
+ path.join(normalizedBase, PATCH_INFO_CACHE_RELATIVE_PATH),
125
+ path.join(normalizedBase, PATCH_INFO_LEGACY_RELATIVE_PATH)
126
+ ])];
127
+ }
128
+ //#endregion
129
+ //#region package.json
130
+ var version = "5.0.0-next.1";
131
+ //#endregion
132
+ //#region src/constants.ts
133
+ const WEAPP_TW_REQUIRED_NODE_VERSION_RANGE = "^20.19.0 || >=22.12.0";
134
+ const WEAPP_TW_VERSION = version;
135
+ //#endregion
136
+ //#region src/tailwindcss/targets/record-io.ts
137
+ const loggedInvalidPatchRecords = /* @__PURE__ */ new Set();
416
138
  function warnInvalidPatchTargetRecord(baseDir, recordPath, reason) {
417
- const normalizedPath = path4.normalize(recordPath);
418
- if (loggedInvalidPatchRecords.has(normalizedPath)) {
419
- return;
420
- }
421
- loggedInvalidPatchRecords.add(normalizedPath);
422
- const fileDisplay = formatRelativeToBase(normalizedPath, baseDir);
423
- const baseDisplay = formatRelativeToBase(path4.normalize(baseDir), process4.cwd());
424
- const reasonMessage = reason ? `\uFF1A${reason}` : "";
425
- logger2.warn(
426
- `\u68C0\u6D4B\u5230\u635F\u574F\u7684 Tailwind CSS \u76EE\u6807\u8BB0\u5F55 ${fileDisplay}${reasonMessage}\u3002\u8BF7\u5728 ${baseDisplay} \u91CD\u65B0\u6267\u884C "weapp-tw patch --record-target" \u6216\u5220\u9664\u8BE5\u6587\u4EF6\u540E\u518D\u8FD0\u884C\u3002`
427
- );
139
+ const normalizedPath = path.normalize(recordPath);
140
+ if (loggedInvalidPatchRecords.has(normalizedPath)) return;
141
+ loggedInvalidPatchRecords.add(normalizedPath);
142
+ const fileDisplay = formatRelativeToBase(normalizedPath, baseDir);
143
+ const baseDisplay = formatRelativeToBase(path.normalize(baseDir), process.cwd());
144
+ const reasonMessage = reason ? `:${reason}` : "";
145
+ logger.warn(`检测到损坏的 Tailwind CSS 目标记录 ${fileDisplay}${reasonMessage}。请在 ${baseDisplay} 重新执行 "weapp-tw patch --record-target" 或删除该文件后再运行。`);
428
146
  }
429
147
  function readPatchTargetRecord(baseDir) {
430
- if (!baseDir) {
431
- return void 0;
432
- }
433
- const normalizedBase = path4.normalize(baseDir);
434
- for (const recordPath of getRecordFileCandidates(normalizedBase)) {
435
- if (!existsSync3(recordPath)) {
436
- continue;
437
- }
438
- try {
439
- const content = readFileSync2(recordPath, "utf8");
440
- const parsed = JSON.parse(content);
441
- if (!parsed || typeof parsed.tailwindPackagePath !== "string") {
442
- warnInvalidPatchTargetRecord(normalizedBase, recordPath, "\u7F3A\u5C11 tailwindPackagePath \u5B57\u6BB5");
443
- continue;
444
- }
445
- return {
446
- baseDir: normalizedBase,
447
- path: recordPath,
448
- record: parsed
449
- };
450
- } catch (error) {
451
- const reason = error instanceof Error ? error.message : String(error);
452
- warnInvalidPatchTargetRecord(normalizedBase, recordPath, reason);
453
- continue;
454
- }
455
- }
456
- return void 0;
148
+ if (!baseDir) return;
149
+ const normalizedBase = path.normalize(baseDir);
150
+ for (const recordPath of getRecordFileCandidates(normalizedBase)) {
151
+ if (!existsSync(recordPath)) continue;
152
+ try {
153
+ const content = readFileSync(recordPath, "utf8");
154
+ const parsed = JSON.parse(content);
155
+ if (!parsed || typeof parsed.tailwindPackagePath !== "string") {
156
+ warnInvalidPatchTargetRecord(normalizedBase, recordPath, "缺少 tailwindPackagePath 字段");
157
+ continue;
158
+ }
159
+ return {
160
+ baseDir: normalizedBase,
161
+ path: recordPath,
162
+ record: parsed
163
+ };
164
+ } catch (error) {
165
+ warnInvalidPatchTargetRecord(normalizedBase, recordPath, error instanceof Error ? error.message : String(error));
166
+ continue;
167
+ }
168
+ }
457
169
  }
458
170
  async function saveCliPatchTargetRecord(baseDir, patcher, options) {
459
- if (!baseDir || !patcher?.packageInfo?.rootPath) {
460
- return void 0;
461
- }
462
- const normalizedBase = path4.normalize(baseDir);
463
- const location = resolveRecordLocation(normalizedBase);
464
- const recordPath = options?.recordPath ? path4.normalize(options.recordPath) : location.recordPath;
465
- const record = {
466
- tailwindPackagePath: path4.normalize(patcher.packageInfo.rootPath),
467
- packageVersion: patcher.packageInfo.version,
468
- recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
469
- source: options?.source ?? "cli",
470
- tailwindcssBasedir: normalizedBase,
471
- cwd: options?.cwd ? path4.normalize(options.cwd) : normalizedBase,
472
- patchVersion: WEAPP_TW_VERSION,
473
- packageJsonPath: options?.packageJsonPath ?? location.packageJsonPath,
474
- recordKey: options?.recordKey ?? location.recordKey
475
- };
476
- try {
477
- await mkdir(path4.dirname(recordPath), { recursive: true });
478
- await writeFile(recordPath, `${JSON.stringify(record, null, 2)}
479
- `, "utf8");
480
- return recordPath;
481
- } catch (error) {
482
- const baseDisplay = formatRelativeToBase(normalizedBase, process4.cwd());
483
- logger2.warn(
484
- '\u81EA\u52A8\u66F4\u65B0 Tailwind CSS \u8865\u4E01\u8BB0\u5F55\u5931\u8D25\uFF0C\u8BF7\u5728 %s \u8FD0\u884C "weapp-tw patch --cwd %s"\u3002',
485
- baseDisplay,
486
- normalizedBase
487
- );
488
- logger2.debug("failed to persist patch target record %s: %O", recordPath, error);
489
- return void 0;
490
- }
491
- }
492
-
493
- // src/tailwindcss/targets/recorder.ts
494
- import path5 from "path";
495
- import process5 from "process";
171
+ if (!baseDir || !patcher?.packageInfo?.rootPath) return;
172
+ const normalizedBase = path.normalize(baseDir);
173
+ const location = resolveRecordLocation(normalizedBase);
174
+ const recordPath = options?.recordPath ? path.normalize(options.recordPath) : location.recordPath;
175
+ const record = {
176
+ tailwindPackagePath: path.normalize(patcher.packageInfo.rootPath),
177
+ packageVersion: patcher.packageInfo.version,
178
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
179
+ source: options?.source ?? "cli",
180
+ tailwindcssBasedir: normalizedBase,
181
+ cwd: options?.cwd ? path.normalize(options.cwd) : normalizedBase,
182
+ patchVersion: WEAPP_TW_VERSION,
183
+ packageJsonPath: options?.packageJsonPath ?? location.packageJsonPath,
184
+ recordKey: options?.recordKey ?? location.recordKey
185
+ };
186
+ try {
187
+ await mkdir(path.dirname(recordPath), { recursive: true });
188
+ await writeFile(recordPath, `${JSON.stringify(record, null, 2)}\n`, "utf8");
189
+ return recordPath;
190
+ } catch (error) {
191
+ const baseDisplay = formatRelativeToBase(normalizedBase, process.cwd());
192
+ logger.warn("自动更新 Tailwind CSS 补丁记录失败,请在 %s 运行 \"weapp-tw patch --cwd %s\"。", baseDisplay, normalizedBase);
193
+ logger.debug("failed to persist patch target record %s: %O", recordPath, error);
194
+ return;
195
+ }
196
+ }
197
+ //#endregion
198
+ //#region src/tailwindcss/targets/recorder.ts
496
199
  function findPatchTargetRecord(baseDir) {
497
- const visited = /* @__PURE__ */ new Set();
498
- const fallback = baseDir ?? process5.cwd();
499
- let current = path5.resolve(fallback);
500
- while (!visited.has(current)) {
501
- const record = readPatchTargetRecord(current);
502
- if (record) {
503
- return record;
504
- }
505
- const parent = path5.dirname(current);
506
- if (parent === current) {
507
- break;
508
- }
509
- visited.add(current);
510
- current = parent;
511
- }
512
- return void 0;
200
+ const visited = /* @__PURE__ */ new Set();
201
+ const fallback = baseDir ?? process.cwd();
202
+ let current = path.resolve(fallback);
203
+ while (!visited.has(current)) {
204
+ const record = readPatchTargetRecord(current);
205
+ if (record) return record;
206
+ const parent = path.dirname(current);
207
+ if (parent === current) break;
208
+ visited.add(current);
209
+ current = parent;
210
+ }
513
211
  }
514
212
  function createPatchTargetRecorder(baseDir, patcher, options) {
515
- if (!baseDir || !patcher?.packageInfo?.rootPath || options?.recordTarget === false) {
516
- return void 0;
517
- }
518
- const normalizedBase = path5.normalize(baseDir);
519
- const recorded = findPatchTargetRecord(normalizedBase);
520
- const location = resolveRecordLocation(normalizedBase);
521
- const expectedPath = path5.normalize(patcher.packageInfo.rootPath);
522
- let reason;
523
- if (!recorded) {
524
- reason = "missing";
525
- } else {
526
- const normalizedRecorded = path5.normalize(recorded.record.tailwindPackagePath);
527
- if (normalizedRecorded !== expectedPath) {
528
- reason = "mismatch";
529
- } else if (path5.normalize(recorded.path) !== path5.normalize(location.recordPath) || !recorded.record.recordKey || recorded.record.recordKey !== location.recordKey) {
530
- reason = "migrate";
531
- } else if (!recorded.record.patchVersion || recorded.record.patchVersion !== WEAPP_TW_VERSION) {
532
- reason = "stale";
533
- } else if (options?.cwd && recorded.record.cwd && path5.normalize(recorded.record.cwd) !== path5.normalize(options.cwd)) {
534
- reason = "metadata";
535
- } else if (!recorded.record.cwd && options?.cwd) {
536
- reason = "metadata";
537
- }
538
- }
539
- const shouldPersist = options?.alwaysRecord || !recorded || Boolean(reason);
540
- if (!shouldPersist) {
541
- return void 0;
542
- }
543
- let message;
544
- switch (reason) {
545
- case "mismatch":
546
- message = "\u68C0\u6D4B\u5230 Tailwind CSS \u76EE\u6807\u8BB0\u5F55\u4E0E\u5F53\u524D\u89E3\u6790\u7ED3\u679C\u4E0D\u4E00\u81F4\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u65B0 patch \u5E76\u5237\u65B0\u7F13\u5B58\u3002";
547
- break;
548
- case "migrate":
549
- case "stale":
550
- message = "\u6B63\u5728\u5237\u65B0\u5F53\u524D\u5B50\u5305\u7684 Tailwind CSS \u8865\u4E01\u8BB0\u5F55\uFF0C\u786E\u4FDD\u7F13\u5B58\u9694\u79BB\u3002";
551
- break;
552
- case "missing":
553
- message = "\u672A\u627E\u5230\u5F53\u524D\u5B50\u5305\u7684 Tailwind CSS \u76EE\u6807\u8BB0\u5F55\uFF0C\u6B63\u5728\u751F\u6210\u3002";
554
- break;
555
- default:
556
- break;
557
- }
558
- const onPatched = async () => saveCliPatchTargetRecord(normalizedBase, patcher, {
559
- cwd: options?.cwd ?? normalizedBase,
560
- source: options?.source ?? "cli",
561
- recordPath: location.recordPath,
562
- recordKey: location.recordKey,
563
- packageJsonPath: location.packageJsonPath
564
- });
565
- return {
566
- recordPath: location.recordPath,
567
- message,
568
- reason,
569
- onPatched
570
- };
571
- }
572
-
573
- // src/tailwindcss/targets.ts
213
+ if (!baseDir || !patcher?.packageInfo?.rootPath || options?.recordTarget === false) return;
214
+ const normalizedBase = path.normalize(baseDir);
215
+ const recorded = findPatchTargetRecord(normalizedBase);
216
+ const location = resolveRecordLocation(normalizedBase);
217
+ const expectedPath = path.normalize(patcher.packageInfo.rootPath);
218
+ let reason;
219
+ if (!recorded) reason = "missing";
220
+ else if (path.normalize(recorded.record.tailwindPackagePath) !== expectedPath) reason = "mismatch";
221
+ else if (path.normalize(recorded.path) !== path.normalize(location.recordPath) || !recorded.record.recordKey || recorded.record.recordKey !== location.recordKey) reason = "migrate";
222
+ else if (!recorded.record.patchVersion || recorded.record.patchVersion !== WEAPP_TW_VERSION) reason = "stale";
223
+ else if (options?.cwd && recorded.record.cwd && path.normalize(recorded.record.cwd) !== path.normalize(options.cwd)) reason = "metadata";
224
+ else if (!recorded.record.cwd && options?.cwd) reason = "metadata";
225
+ if (!(options?.alwaysRecord || !recorded || Boolean(reason))) return;
226
+ let message;
227
+ switch (reason) {
228
+ case "mismatch":
229
+ message = "检测到 Tailwind CSS 目标记录与当前解析结果不一致,正在自动重新 patch 并刷新缓存。";
230
+ break;
231
+ case "migrate":
232
+ case "stale":
233
+ message = "正在刷新当前子包的 Tailwind CSS 补丁记录,确保缓存隔离。";
234
+ break;
235
+ case "missing":
236
+ message = "未找到当前子包的 Tailwind CSS 目标记录,正在生成。";
237
+ break;
238
+ default: break;
239
+ }
240
+ const onPatched = async () => saveCliPatchTargetRecord(normalizedBase, patcher, {
241
+ cwd: options?.cwd ?? normalizedBase,
242
+ source: options?.source ?? "cli",
243
+ recordPath: location.recordPath,
244
+ recordKey: location.recordKey,
245
+ packageJsonPath: location.packageJsonPath
246
+ });
247
+ return {
248
+ recordPath: location.recordPath,
249
+ message,
250
+ reason,
251
+ onPatched
252
+ };
253
+ }
254
+ //#endregion
255
+ //#region src/tailwindcss/targets.ts
574
256
  function logTailwindcssTarget(kind, patcher, baseDir) {
575
- const packageInfo = patcher?.packageInfo;
576
- const label = kind === "cli" ? "weapp-tw patch" : "Weapp-tailwindcss";
577
- if (!packageInfo?.rootPath) {
578
- logger3.warn(
579
- "%s \u672A\u627E\u5230 Tailwind CSS \u4F9D\u8D56\uFF0C\u8BF7\u68C0\u67E5\u5728 %s \u662F\u5426\u5DF2\u5B89\u88C5 tailwindcss",
580
- label,
581
- baseDir ?? process6.cwd()
582
- );
583
- return;
584
- }
585
- const displayPath = formatRelativeToBase(packageInfo.rootPath, baseDir);
586
- const version = packageInfo.version ? ` (v${packageInfo.version})` : "";
587
- if (kind === "runtime") {
588
- logRuntimeTailwindcssTarget(baseDir, packageInfo.rootPath, packageInfo.version);
589
- return;
590
- }
591
- logger3.info("%s \u7ED1\u5B9A Tailwind CSS -> %s%s", label, displayPath, version);
592
- }
593
-
594
- // src/tailwindcss/v4/config.ts
595
- import { logger as logger4 } from "@weapp-tailwindcss/logger";
596
-
597
- // src/tailwindcss/v4/patcher.ts
598
- import { logger as logger6 } from "@weapp-tailwindcss/logger";
599
-
600
- // src/tailwindcss/patcher.ts
601
- import path7 from "path";
602
- import process8 from "process";
603
- import { logger as logger5 } from "@weapp-tailwindcss/logger";
604
- import { defuOverrideArray as defuOverrideArray2 } from "@weapp-tailwindcss/shared";
605
- import { TailwindcssPatcher } from "tailwindcss-patch";
606
-
607
- // src/tailwindcss/patcher-resolve.ts
608
- import { existsSync as existsSync4 } from "fs";
609
- import { createRequire } from "module";
610
- import path6 from "path";
611
- import process7 from "process";
612
- import { fileURLToPath } from "url";
613
-
614
- // src/tailwindcss/v4/css-entries.ts
615
- import path8 from "path";
616
-
617
- // src/context/compiler-context-cache.ts
618
- import { Buffer } from "buffer";
619
- import path9 from "path";
620
- import process9 from "process";
621
- import { logger as logger7 } from "@weapp-tailwindcss/logger";
622
- var globalCacheHolder = globalThis;
623
- var compilerContextCache = globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
624
-
625
- // src/context/handlers.ts
626
- import { createStyleHandler } from "@weapp-tailwindcss/postcss";
627
-
628
- // src/js/index.ts
629
- import { LRUCache as LRUCache3 } from "lru-cache";
630
-
631
- // src/babel/index.ts
632
- import _babelTraverse from "@babel/traverse";
633
- import { parse, parseExpression } from "@babel/parser";
257
+ const packageInfo = patcher?.packageInfo;
258
+ const label = kind === "cli" ? "weapp-tw patch" : "Weapp-tailwindcss";
259
+ if (!packageInfo?.rootPath) {
260
+ logger.warn("%s 未找到 Tailwind CSS 依赖,请检查在 %s 是否已安装 tailwindcss", label, baseDir ?? process.cwd());
261
+ return;
262
+ }
263
+ const displayPath = formatRelativeToBase(packageInfo.rootPath, baseDir);
264
+ const version = packageInfo.version ? ` (v${packageInfo.version})` : "";
265
+ if (kind === "runtime") {
266
+ logRuntimeTailwindcssTarget(baseDir, packageInfo.rootPath, packageInfo.version);
267
+ return;
268
+ }
269
+ logger.info("%s 绑定 Tailwind CSS -> %s%s", label, displayPath, version);
270
+ }
271
+ //#endregion
272
+ //#region src/context/compiler-context-cache.ts
273
+ const globalCacheHolder = globalThis;
274
+ globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
275
+ //#endregion
276
+ //#region src/babel/index.ts
634
277
  function _interopDefaultCompat(e) {
635
- return e && typeof e === "object" && "default" in e ? e.default : e;
278
+ return e && typeof e === "object" && "default" in e ? e.default : e;
636
279
  }
637
- var traverse = _interopDefaultCompat(_babelTraverse);
638
-
639
- // src/utils/nameMatcher.ts
640
- import { escapeStringRegexp } from "@weapp-core/regex";
641
-
642
- // src/js/babel/parse.ts
643
- import { LRUCache as LRUCache2 } from "lru-cache";
644
- var parseCache = new LRUCache2(
645
- {
646
- max: 1024
647
- }
648
- );
649
-
650
- // src/js/babel/process.ts
651
- import MagicString from "magic-string";
652
-
653
- // src/js/handlers.ts
654
- import { jsStringEscape } from "@ast-core/escape";
655
- import { splitCode } from "@weapp-tailwindcss/shared/extractors";
656
-
657
- // src/wxml/shared.ts
658
- import { escape, MappingChars2String as MappingChars2String2 } from "@weapp-core/escape";
659
-
660
- // src/js/handlers.ts
661
- var debug2 = createDebug("[js:handlers] ");
662
-
663
- // src/js/evalTransforms.ts
664
- import { jsStringEscape as jsStringEscape2 } from "@ast-core/escape";
665
-
666
- // src/wxml/utils/codegen/legacy-rewriter.ts
667
- import MagicString2 from "magic-string";
668
-
669
- // src/wxml/utils/codegen/legacy-visitor.ts
670
- import * as t from "@babel/types";
671
-
672
- // src/wxml/utils/codegen.ts
673
- var WRAP_EXPRESSION_HANDLER_OPTIONS = Object.freeze({
674
- wrapExpression: true
675
- });
676
-
677
- // src/wxml/utils/custom-template.ts
678
- import { Parser } from "htmlparser2";
679
- import MagicString4 from "magic-string";
680
-
681
- // src/wxml/utils/template-fragments.ts
682
- import MagicString3 from "magic-string";
683
-
684
- // src/wxml/whitespace.ts
685
- var WHITESPACE_CODES = /* @__PURE__ */ new Set([
686
- 9,
687
- // 制表符 \t
688
- 10,
689
- // 换行符 \n
690
- 11,
691
- // 垂直制表符 \v
692
- 12,
693
- // 换页符 \f
694
- 13,
695
- // 回车符 \r
696
- 32,
697
- // 空格
698
- 160,
699
- // 不间断空格 \u00A0
700
- 65279
701
- // 零宽无断行空格 \uFEFF
280
+ const traverse = _interopDefaultCompat(_babelTraverse);
281
+ //#endregion
282
+ //#region src/utils/nameMatcher.ts
283
+ const NEVER_MATCH_NAME$1 = () => false;
284
+ const GLOBAL_FLAG_REGEXP = /g/g;
285
+ function buildFuzzyMatcher(fuzzyStrings) {
286
+ if (fuzzyStrings.length === 0) return;
287
+ if (fuzzyStrings.length === 1) {
288
+ const [needle] = fuzzyStrings;
289
+ return (value) => value.includes(needle);
290
+ }
291
+ const unique = [...new Set(fuzzyStrings)];
292
+ const pattern = new RegExp(unique.map(escapeStringRegexp).join("|"));
293
+ return (value) => pattern.test(value);
294
+ }
295
+ function normaliseRegex(regex) {
296
+ const { source, flags } = regex;
297
+ if (!flags.includes("g")) return regex;
298
+ return new RegExp(source, flags.replace(GLOBAL_FLAG_REGEXP, ""));
299
+ }
300
+ function createNameMatcher(list, { exact = false } = {}) {
301
+ if (!list || list.length === 0) return NEVER_MATCH_NAME$1;
302
+ const exactStrings = exact ? /* @__PURE__ */ new Set() : void 0;
303
+ const fuzzyStrings = [];
304
+ const regexList = [];
305
+ for (const item of list) if (typeof item === "string") if (exact) exactStrings.add(item);
306
+ else fuzzyStrings.push(item);
307
+ else regexList.push(normaliseRegex(item));
308
+ if (exact) {
309
+ const exactStringCount = exactStrings?.size ?? 0;
310
+ if (exactStringCount === 1 && regexList.length === 0) {
311
+ const [needle] = exactStrings;
312
+ return (value) => value === needle;
313
+ }
314
+ if (regexList.length === 0) return (value) => exactStrings.has(value);
315
+ if (exactStringCount === 0 && regexList.length === 1) {
316
+ const [regex] = regexList;
317
+ return (value) => regex.test(value);
318
+ }
319
+ return (value) => {
320
+ if (exactStrings?.has(value)) return true;
321
+ return regexList.some((regex) => regex.test(value));
322
+ };
323
+ }
324
+ const fuzzyMatcher = exact ? void 0 : buildFuzzyMatcher(fuzzyStrings);
325
+ const hasRegex = regexList.length > 0;
326
+ if (fuzzyMatcher && !hasRegex) return fuzzyMatcher;
327
+ if (!fuzzyMatcher && regexList.length === 1) {
328
+ const [regex] = regexList;
329
+ return (value) => regex.test(value);
330
+ }
331
+ return (value) => {
332
+ if (fuzzyMatcher?.(value)) return true;
333
+ if (!hasRegex) return false;
334
+ return regexList.some((regex) => regex.test(value));
335
+ };
336
+ }
337
+ //#endregion
338
+ //#region src/js/babel/parse.ts
339
+ const parseCache = new LRUCache({ max: 1024 });
340
+ function genCacheKey(source, options) {
341
+ if (typeof options === "string") return source + options;
342
+ return source + JSON.stringify(options, (_, val) => typeof val === "function" ? val.toString() : val);
343
+ }
344
+ function babelParse(code, opts = {}) {
345
+ const { cache, cacheKey, ...rest } = opts;
346
+ const cacheKeyString = genCacheKey(code, cacheKey ?? rest);
347
+ let result;
348
+ if (cache) result = parseCache.get(cacheKeyString);
349
+ if (!result) {
350
+ const { cache: _cache, cacheKey: _cacheKey, ...parseOptions } = opts;
351
+ result = parse$1(code, parseOptions);
352
+ if (cache) parseCache.set(cacheKeyString, result);
353
+ }
354
+ return result;
355
+ }
356
+ //#endregion
357
+ //#region src/wxml/shared.ts
358
+ const NEWLINE_RE = /[\n\r]+/g;
359
+ function replaceWxml(original, options = {
360
+ keepEOL: false,
361
+ escapeMap: MappingChars2String
362
+ }) {
363
+ const { keepEOL, escapeMap, ignoreHead } = options;
364
+ let res = original;
365
+ if (!keepEOL) res = res.replaceAll(NEWLINE_RE, "");
366
+ res = escape(res, {
367
+ map: escapeMap,
368
+ ignoreHead
369
+ });
370
+ return res;
371
+ }
372
+ //#endregion
373
+ //#region src/shared/classname-transform.ts
374
+ const escapedCandidateCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
375
+ const defaultEscapedCandidateCache = /* @__PURE__ */ new Map();
376
+ let lastEscapedCandidateEscapeMap;
377
+ let lastEscapedCandidateCacheStore;
378
+ function isUrlLikeCandidate(candidate) {
379
+ return candidate.startsWith("//") || candidate.startsWith("http://") || candidate.startsWith("https://");
380
+ }
381
+ function isArbitraryValueCandidate(candidate) {
382
+ let hasOpenBracket = false;
383
+ let hasCloseBracket = false;
384
+ for (let i = 0; i < candidate.length; i++) {
385
+ const char = candidate[i];
386
+ if (char === "[") hasOpenBracket = true;
387
+ else if (char === "]") hasCloseBracket = true;
388
+ if (hasOpenBracket && hasCloseBracket) break;
389
+ }
390
+ if (!hasOpenBracket || !hasCloseBracket) return false;
391
+ if (isUrlLikeCandidate(candidate.trim())) return false;
392
+ return true;
393
+ }
394
+ function shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) {
395
+ if (jsArbitraryValueFallback === true) return true;
396
+ if (jsArbitraryValueFallback === false) return false;
397
+ return tailwindcssMajorVersion === 4 && (!classNameSet || classNameSet.size === 0);
398
+ }
399
+ function shouldEnableArbitraryValueFallback({ classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion }) {
400
+ return shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion);
401
+ }
402
+ const SKIP_RESULT = { decision: "skip" };
403
+ const DIRECT_RESULT = { decision: "direct" };
404
+ const FALLBACK_RESULT = { decision: "fallback" };
405
+ function getEscapedCandidateCacheStore(escapeMap) {
406
+ if (!escapeMap) return defaultEscapedCandidateCache;
407
+ if (escapeMap === lastEscapedCandidateEscapeMap && lastEscapedCandidateCacheStore) return lastEscapedCandidateCacheStore;
408
+ let store = escapedCandidateCacheByEscapeMap.get(escapeMap);
409
+ if (!store) {
410
+ store = /* @__PURE__ */ new Map();
411
+ escapedCandidateCacheByEscapeMap.set(escapeMap, store);
412
+ }
413
+ lastEscapedCandidateEscapeMap = escapeMap;
414
+ lastEscapedCandidateCacheStore = store;
415
+ return store;
416
+ }
417
+ function getEscapedCandidate(candidate, escapeMap, store = getEscapedCandidateCacheStore(escapeMap)) {
418
+ let cached = store.get(candidate);
419
+ if (cached === void 0) {
420
+ cached = replaceWxml(candidate, { escapeMap });
421
+ store.set(candidate, cached);
422
+ }
423
+ return cached;
424
+ }
425
+ /**
426
+ * JS 转译严格遵循 runtime class set:
427
+ * 1. 直接命中 classNameSet 原始值;
428
+ * 2. 兼容命中 classNameSet 中已转义值;
429
+ * 3. 仅在受控条件下允许 class 语义兜底。
430
+ *
431
+ * 返回结构化结果,附带已计算的 escapedValue 以避免下游重复 escape。
432
+ */
433
+ function resolveClassNameTransformWithResult(candidate, { alwaysEscape, classNameSet, escapeMap, jsArbitraryValueFallback, jsPreserveClass, tailwindcssMajorVersion, classContext }) {
434
+ if (alwaysEscape) return DIRECT_RESULT;
435
+ if (jsPreserveClass?.(candidate)) return SKIP_RESULT;
436
+ if (classNameSet?.has(candidate)) return DIRECT_RESULT;
437
+ if (classNameSet && classNameSet.size > 0) {
438
+ const escapedCandidate = getEscapedCandidate(candidate, escapeMap);
439
+ if (escapedCandidate !== candidate && classNameSet.has(escapedCandidate)) return {
440
+ decision: "escaped",
441
+ escapedValue: escapedCandidate
442
+ };
443
+ }
444
+ if (classContext && shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) && isArbitraryValueCandidate(candidate)) return FALLBACK_RESULT;
445
+ return SKIP_RESULT;
446
+ }
447
+ //#endregion
448
+ //#region src/utils/decode.ts
449
+ const unicodeEscapeRE = /\\u([\dA-Fa-f]{4})/g;
450
+ const unicodeEscapeTestRE = /\\u[\dA-Fa-f]{4}/;
451
+ function decodeUnicode(value) {
452
+ if (!unicodeEscapeTestRE.test(value)) return value;
453
+ return value.replace(unicodeEscapeRE, (_match, hex) => {
454
+ const codePoint = Number.parseInt(hex, 16);
455
+ return Number.isNaN(codePoint) ? _match : String.fromCharCode(codePoint);
456
+ });
457
+ }
458
+ function decodeUnicode2(input) {
459
+ if (!unicodeEscapeTestRE.test(input)) return input;
460
+ try {
461
+ return JSON.parse(`"${input}"`);
462
+ } catch (_error) {
463
+ return decodeUnicode(input);
464
+ }
465
+ }
466
+ //#endregion
467
+ //#region src/js/class-context.ts
468
+ const CLASS_LIKE_KEYWORDS = new Set([
469
+ "class",
470
+ "classname",
471
+ "hoverclass",
472
+ "virtualhostclass",
473
+ "rootclass"
474
+ ]);
475
+ const CLASS_HELPER_IDENTIFIERS = new Set([
476
+ "cn",
477
+ "clsx",
478
+ "classnames",
479
+ "twmerge",
480
+ "cva",
481
+ "tv",
482
+ "cx",
483
+ "r"
484
+ ]);
485
+ const DASH_CODE = 45;
486
+ const COLON_CODE = 58;
487
+ const UPPERCASE_A_CODE = 65;
488
+ const UPPERCASE_Z_CODE = 90;
489
+ const UNDERSCORE_CODE = 95;
490
+ const ASCII_MAX_CODE = 127;
491
+ const NORMALIZE_KEYWORD_REGEXP = /[-_:]/g;
492
+ function normalizeKeyword(name) {
493
+ const length = name.length;
494
+ let firstNormalizedIndex = -1;
495
+ for (let i = 0; i < length; i++) {
496
+ const code = name.charCodeAt(i);
497
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE || code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
498
+ firstNormalizedIndex = i;
499
+ break;
500
+ }
501
+ if (code > ASCII_MAX_CODE) return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
502
+ }
503
+ if (firstNormalizedIndex === -1) return name;
504
+ let normalized = name.slice(0, firstNormalizedIndex);
505
+ for (let i = firstNormalizedIndex; i < length; i++) {
506
+ const code = name.charCodeAt(i);
507
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE) continue;
508
+ if (code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
509
+ normalized += String.fromCharCode(code + 32);
510
+ continue;
511
+ }
512
+ if (code > ASCII_MAX_CODE) return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
513
+ normalized += name[i];
514
+ }
515
+ return normalized;
516
+ }
517
+ function readObjectKeyName(path) {
518
+ if (path.isIdentifier()) return path.node.name;
519
+ if (path.isStringLiteral()) return path.node.value;
520
+ if (path.isTemplateLiteral() && path.node.expressions.length === 0) return path.node.quasis[0]?.value.cooked ?? path.node.quasis[0]?.value.raw;
521
+ }
522
+ function isClassLikeObjectProperty(path, valuePath) {
523
+ if (!path.isObjectProperty()) return false;
524
+ if (path.get("value") !== valuePath) return false;
525
+ const keyName = readObjectKeyName(path.get("key"));
526
+ if (!keyName) return false;
527
+ return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(keyName));
528
+ }
529
+ function isClassLikeJsxAttribute(path) {
530
+ if (!path.isJSXAttribute()) return false;
531
+ const namePath = path.get("name");
532
+ if (!namePath.isJSXIdentifier()) return false;
533
+ return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(namePath.node.name));
534
+ }
535
+ function readCallHelperName(calleePath) {
536
+ if (calleePath.isIdentifier()) return calleePath.node.name;
537
+ if (calleePath.isMemberExpression()) {
538
+ const propertyPath = calleePath.get("property");
539
+ if (propertyPath.isIdentifier()) return propertyPath.node.name;
540
+ if (propertyPath.isStringLiteral()) return propertyPath.node.value;
541
+ }
542
+ }
543
+ function isClassLikeCallExpression(path, valuePath) {
544
+ if (!path.isCallExpression()) return false;
545
+ const helperName = readCallHelperName(path.get("callee"));
546
+ if (!helperName || !CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(helperName))) return false;
547
+ return path.get("arguments").some((argumentPath) => argumentPath.node === valuePath.node);
548
+ }
549
+ /**
550
+ * 判断字符串字面量是否处于 class 语义上下文。
551
+ * 仅用于受控兜底场景,避免将普通业务文本误判为 class。
552
+ */
553
+ function isClassContextLiteralPath(path) {
554
+ let current = path;
555
+ while (current.parentPath) {
556
+ const parent = current.parentPath;
557
+ if (isClassLikeObjectProperty(parent, current)) return true;
558
+ if (isClassLikeJsxAttribute(parent)) return true;
559
+ if (isClassLikeCallExpression(parent, current)) return true;
560
+ current = parent;
561
+ }
562
+ return false;
563
+ }
564
+ //#endregion
565
+ //#region src/js/handlers.ts
566
+ const debug = createDebug("[js:handlers] ");
567
+ const replacementCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
568
+ const defaultReplacementCache = /* @__PURE__ */ new Map();
569
+ const WEAPP_TW_IGNORE_MARKER = "weapp-tw";
570
+ const IGNORE_MARKER = "ignore";
571
+ function getReplacementCacheStore(escapeMap) {
572
+ if (!escapeMap) return defaultReplacementCache;
573
+ let store = replacementCacheByEscapeMap.get(escapeMap);
574
+ if (!store) {
575
+ store = /* @__PURE__ */ new Map();
576
+ replacementCacheByEscapeMap.set(escapeMap, store);
577
+ }
578
+ return store;
579
+ }
580
+ function getReplacement(candidate, escapeMap, store = getReplacementCacheStore(escapeMap)) {
581
+ let cached = store.get(candidate);
582
+ if (cached === void 0) {
583
+ cached = replaceWxml(candidate, { escapeMap });
584
+ store.set(candidate, cached);
585
+ }
586
+ return cached;
587
+ }
588
+ function hasIgnoreComment(node) {
589
+ const { leadingComments } = node;
590
+ if (!Array.isArray(leadingComments) || leadingComments.length === 0) return false;
591
+ for (const comment of leadingComments) {
592
+ const { value } = comment;
593
+ if (value.includes(WEAPP_TW_IGNORE_MARKER) && value.includes(IGNORE_MARKER)) return true;
594
+ }
595
+ return false;
596
+ }
597
+ function extractLiteralValue(path, { unescapeUnicode, arbitraryValues }) {
598
+ const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
599
+ const { node } = path;
600
+ let offset = 0;
601
+ let original;
602
+ if (node.type === "StringLiteral") {
603
+ offset = 1;
604
+ original = node.value;
605
+ } else if (node.type === "TemplateElement") original = node.value.raw;
606
+ else original = "";
607
+ let literal = original;
608
+ if (unescapeUnicode && original.includes("\\u")) literal = decodeUnicode2(original);
609
+ return {
610
+ allowDoubleQuotes,
611
+ literal,
612
+ offset,
613
+ original
614
+ };
615
+ }
616
+ function createCandidatePlanResolver(options, classContext) {
617
+ const { escapeMap } = options;
618
+ const replacementCache = getReplacementCacheStore(escapeMap);
619
+ const transformOptions = classContext ? {
620
+ ...options,
621
+ classContext
622
+ } : options;
623
+ let firstCandidate = "";
624
+ let firstPlan;
625
+ let cache;
626
+ const buildCandidatePlan = (candidate) => {
627
+ const result = resolveClassNameTransformWithResult(candidate, transformOptions);
628
+ if (result.decision === "skip") return { result };
629
+ let replacement;
630
+ if (result.decision === "escaped" && result.escapedValue) {
631
+ replacement = result.escapedValue;
632
+ replacementCache.set(candidate, replacement);
633
+ } else replacement = getReplacement(candidate, escapeMap, replacementCache);
634
+ return {
635
+ result,
636
+ replacement
637
+ };
638
+ };
639
+ return (candidate) => {
640
+ if (cache) {
641
+ const cached = cache.get(candidate);
642
+ if (cached) return cached;
643
+ } else if (firstPlan && candidate === firstCandidate) return firstPlan;
644
+ const plan = buildCandidatePlan(candidate);
645
+ if (!firstPlan) {
646
+ firstCandidate = candidate;
647
+ firstPlan = plan;
648
+ return plan;
649
+ }
650
+ if (!cache) {
651
+ cache = /* @__PURE__ */ new Map();
652
+ cache.set(firstCandidate, firstPlan);
653
+ }
654
+ cache.set(candidate, plan);
655
+ return plan;
656
+ };
657
+ }
658
+ function replaceHandleValue(path, options) {
659
+ const { needEscaped = false } = options;
660
+ const { classNameSet, alwaysEscape } = options;
661
+ const fallbackEnabled = shouldEnableArbitraryValueFallback(options);
662
+ if (!alwaysEscape && !fallbackEnabled && (!classNameSet || classNameSet.size === 0)) return;
663
+ if (hasIgnoreComment(path.node)) return;
664
+ const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path, options);
665
+ const candidates = splitCode(literal, allowDoubleQuotes);
666
+ if (candidates.length === 0) return;
667
+ const debugEnabled = debug.enabled;
668
+ const classContext = options.wrapExpression || isClassContextLiteralPath(path);
669
+ let transformed = literal;
670
+ let mutated = false;
671
+ let matchedCandidateCount = 0;
672
+ let escapedDecisionCount = 0;
673
+ let fallbackDecisionCount = 0;
674
+ let escapedSamples;
675
+ let skippedSamples;
676
+ const resolveCandidatePlan = createCandidatePlanResolver(options, classContext);
677
+ for (const candidate of candidates) {
678
+ const plan = resolveCandidatePlan(candidate);
679
+ if (plan.result.decision === "skip") {
680
+ if (debugEnabled) {
681
+ if (!skippedSamples) skippedSamples = [];
682
+ if (skippedSamples.length < 6) skippedSamples.push(candidate);
683
+ }
684
+ continue;
685
+ }
686
+ if (debugEnabled) {
687
+ matchedCandidateCount += 1;
688
+ if (plan.result.decision === "escaped") {
689
+ escapedDecisionCount += 1;
690
+ if (!escapedSamples) escapedSamples = [];
691
+ if (escapedSamples.length < 6) escapedSamples.push(candidate);
692
+ }
693
+ if (plan.result.decision === "fallback") fallbackDecisionCount += 1;
694
+ }
695
+ const replaced = transformed.replace(candidate, plan.replacement);
696
+ if (replaced !== transformed) {
697
+ transformed = replaced;
698
+ mutated = true;
699
+ }
700
+ }
701
+ const node = path.node;
702
+ if (!mutated || typeof node.start !== "number" || typeof node.end !== "number") return;
703
+ if (debugEnabled) debug("runtimeSet size=%d fallbackTriggered=%s candidates=%d matched=%d escapedHits=%d skipped=%d file=%s escapedSamples=%s skippedSamples=%s", classNameSet?.size ?? 0, fallbackDecisionCount > 0, candidates.length, matchedCandidateCount, escapedDecisionCount, skippedSamples?.length ?? 0, options.filename ?? "unknown", escapedSamples?.join(",") || "-", skippedSamples?.join(",") || "-");
704
+ const start = node.start + offset;
705
+ const end = node.end - offset;
706
+ if (start >= end || transformed === original) return;
707
+ return {
708
+ start,
709
+ end,
710
+ value: needEscaped ? jsStringEscape(transformed) : transformed,
711
+ path
712
+ };
713
+ }
714
+ //#endregion
715
+ //#region src/js/sourceAnalysis.ts
716
+ function hasReplacementEntries(replacements) {
717
+ for (const key in replacements) if (Object.hasOwn(replacements, key)) return true;
718
+ return false;
719
+ }
720
+ function createModuleSpecifierReplacementToken(path, replacement) {
721
+ const node = path.node;
722
+ if (node.value === replacement) return;
723
+ if (typeof node.start !== "number" || typeof node.end !== "number") return;
724
+ const start = node.start + 1;
725
+ const end = node.end - 1;
726
+ if (start >= end) return;
727
+ return {
728
+ start,
729
+ end,
730
+ value: replacement,
731
+ path
732
+ };
733
+ }
734
+ function collectModuleSpecifierReplacementTokens(analysis, replacements) {
735
+ if (!hasReplacementEntries(replacements)) return [];
736
+ if (analysis.importDeclarations.size === 0 && analysis.exportDeclarations.size === 0 && analysis.requireCallPaths.length === 0 && analysis.walker.imports.size === 0) return [];
737
+ const tokens = [];
738
+ const applyReplacement = (path) => {
739
+ const replacement = replacements[path.node.value];
740
+ if (!replacement) return;
741
+ const token = createModuleSpecifierReplacementToken(path, replacement);
742
+ if (token) tokens.push(token);
743
+ };
744
+ for (const importPath of analysis.importDeclarations) {
745
+ const source = importPath.get("source");
746
+ if (source.isStringLiteral()) applyReplacement(source);
747
+ }
748
+ for (const exportPath of analysis.exportDeclarations) if (exportPath.isExportNamedDeclaration() || exportPath.isExportAllDeclaration()) {
749
+ const source = exportPath.get("source");
750
+ if (source && !Array.isArray(source) && source.isStringLiteral()) applyReplacement(source);
751
+ }
752
+ for (const literalPath of analysis.requireCallPaths) applyReplacement(literalPath);
753
+ for (const token of analysis.walker.imports) {
754
+ const replacement = replacements[token.source];
755
+ if (replacement) token.source = replacement;
756
+ }
757
+ return tokens;
758
+ }
759
+ //#endregion
760
+ //#region src/js/babel/process.ts
761
+ const optionVariantsCache = /* @__PURE__ */ new WeakMap();
762
+ function getNeedEscapedOptions(options, needEscaped) {
763
+ if (options.needEscaped === needEscaped) return options;
764
+ let cached = optionVariantsCache.get(options);
765
+ if (!cached) {
766
+ cached = {};
767
+ optionVariantsCache.set(options, cached);
768
+ }
769
+ if (needEscaped) {
770
+ if (!cached.stringLiteralOptions) cached.stringLiteralOptions = {
771
+ ...options,
772
+ needEscaped: true
773
+ };
774
+ return cached.stringLiteralOptions;
775
+ }
776
+ if (!cached.templateLiteralOptions) cached.templateLiteralOptions = {
777
+ ...options,
778
+ needEscaped: false
779
+ };
780
+ return cached.templateLiteralOptions;
781
+ }
782
+ function processUpdatedSource(rawSource, options, analysis) {
783
+ const { targetPaths, jsTokenUpdater, ignoredPaths } = analysis;
784
+ if (targetPaths.length === 0 && !options.moduleSpecifierReplacements && jsTokenUpdater.length === 0) return new MagicString(rawSource);
785
+ const replacementTokens = [];
786
+ for (const path of targetPaths) {
787
+ if (ignoredPaths.has(path)) continue;
788
+ const token = replaceHandleValue(path, path.isStringLiteral() ? getNeedEscapedOptions(options, true) : getNeedEscapedOptions(options, false));
789
+ if (token) replacementTokens.push(token);
790
+ }
791
+ if (options.moduleSpecifierReplacements) replacementTokens.push(...collectModuleSpecifierReplacementTokens(analysis, options.moduleSpecifierReplacements));
792
+ if (jsTokenUpdater.length + replacementTokens.length === 0) return new MagicString(rawSource);
793
+ const ms = new MagicString(rawSource);
794
+ jsTokenUpdater.push(...replacementTokens).filter((token) => !ignoredPaths.has(token.path)).updateMagicString(ms);
795
+ return ms;
796
+ }
797
+ //#endregion
798
+ //#region src/js/evalTransforms.ts
799
+ const evalHandlerOptionsCache = /* @__PURE__ */ new WeakMap();
800
+ const EVAL_SCOPE_ERROR_REGEXP = /pass a scope and parentPath|traversing a Program\/File/i;
801
+ function isEvalPath(path) {
802
+ if (path.isCallExpression()) return path.get("callee").isIdentifier({ name: "eval" });
803
+ return false;
804
+ }
805
+ function createEvalReplacementToken(path, updated) {
806
+ const node = path.node;
807
+ let offset = 0;
808
+ let original;
809
+ if (path.isStringLiteral()) {
810
+ offset = 1;
811
+ original = path.node.value;
812
+ } else if (path.isTemplateElement()) original = path.node.value.raw;
813
+ else original = "";
814
+ if (typeof node.start !== "number" || typeof node.end !== "number") return;
815
+ const start = node.start + offset;
816
+ const end = node.end - offset;
817
+ if (start >= end) return;
818
+ if (original === updated) return;
819
+ return {
820
+ start,
821
+ end,
822
+ value: path.isStringLiteral() ? jsStringEscape(updated) : updated,
823
+ path
824
+ };
825
+ }
826
+ function handleEvalStringLiteral(path, handlerOptions, updater, handler) {
827
+ const { code } = handler(path.node.value, handlerOptions);
828
+ if (!code) return;
829
+ const token = createEvalReplacementToken(path, code);
830
+ if (token) updater.addToken(token);
831
+ }
832
+ function handleEvalTemplateElement(path, handlerOptions, updater, handler) {
833
+ const { code } = handler(path.node.value.raw, handlerOptions);
834
+ if (!code) return;
835
+ const token = createEvalReplacementToken(path, code);
836
+ if (token) updater.addToken(token);
837
+ }
838
+ function getEvalStringHandlerOptions(options) {
839
+ if (options.needEscaped === false && options.generateMap === false) return options;
840
+ let cached = evalHandlerOptionsCache.get(options);
841
+ if (!cached) {
842
+ cached = {};
843
+ evalHandlerOptionsCache.set(options, cached);
844
+ }
845
+ if (!cached.stringLiteralOptions) cached.stringLiteralOptions = {
846
+ ...options,
847
+ needEscaped: false,
848
+ generateMap: false
849
+ };
850
+ return cached.stringLiteralOptions;
851
+ }
852
+ function getEvalTemplateHandlerOptions(options) {
853
+ if (options.generateMap === false) return options;
854
+ let cached = evalHandlerOptionsCache.get(options);
855
+ if (!cached) {
856
+ cached = {};
857
+ evalHandlerOptionsCache.set(options, cached);
858
+ }
859
+ if (!cached.templateLiteralOptions) cached.templateLiteralOptions = {
860
+ ...options,
861
+ generateMap: false
862
+ };
863
+ return cached.templateLiteralOptions;
864
+ }
865
+ function walkEvalExpression(path, options, updater, handler) {
866
+ const stringHandlerOptions = getEvalStringHandlerOptions(options);
867
+ const templateHandlerOptions = getEvalTemplateHandlerOptions(options);
868
+ const maybeTraverse = path?.traverse;
869
+ if (typeof maybeTraverse === "function") try {
870
+ return maybeTraverse.call(path, {
871
+ StringLiteral(innerPath) {
872
+ handleEvalStringLiteral(innerPath, stringHandlerOptions, updater, handler);
873
+ },
874
+ TemplateElement(innerPath) {
875
+ handleEvalTemplateElement(innerPath, templateHandlerOptions, updater, handler);
876
+ }
877
+ });
878
+ } catch (error) {
879
+ const msg = error?.message ?? "";
880
+ if (!EVAL_SCOPE_ERROR_REGEXP.test(msg)) throw error;
881
+ }
882
+ const getArgs = path?.get?.("arguments");
883
+ if (Array.isArray(getArgs)) {
884
+ for (const arg of getArgs) {
885
+ if (arg?.isStringLiteral?.()) {
886
+ handleEvalStringLiteral(arg, stringHandlerOptions, updater, handler);
887
+ continue;
888
+ }
889
+ if (arg?.isTemplateLiteral?.()) for (const quasi of arg.get("quasis")) handleEvalTemplateElement(quasi, templateHandlerOptions, updater, handler);
890
+ }
891
+ return;
892
+ }
893
+ const nodeArgs = path?.node?.arguments;
894
+ if (Array.isArray(nodeArgs)) {
895
+ for (const n of nodeArgs) if (n?.type === "StringLiteral") handleEvalStringLiteral({
896
+ node: n,
897
+ isStringLiteral: () => true
898
+ }, stringHandlerOptions, updater, handler);
899
+ else if (n?.type === "TemplateLiteral" && Array.isArray(n.quasis)) for (const q of n.quasis) handleEvalTemplateElement({
900
+ node: q,
901
+ isStringLiteral: () => false,
902
+ isTemplateElement: () => true
903
+ }, templateHandlerOptions, updater, handler);
904
+ }
905
+ }
906
+ //#endregion
907
+ //#region src/js/JsTokenUpdater.ts
908
+ /**
909
+ * Lightweight helper that batches updates to {@link MagicString}.
910
+ * It keeps the transformation logic out of the traversal code and makes
911
+ * it easier to reason about the order in which tokens are written back.
912
+ */
913
+ var JsTokenUpdater = class {
914
+ constructor({ value } = {}) {
915
+ this.tokens = value ? [...value] : [];
916
+ }
917
+ addToken(token) {
918
+ if (token) this.tokens.push(token);
919
+ }
920
+ push(...args) {
921
+ this.tokens.push(...args);
922
+ return this;
923
+ }
924
+ /**
925
+ * 待写入的 token 数量。
926
+ */
927
+ get length() {
928
+ return this.tokens.length;
929
+ }
930
+ map(callbackfn) {
931
+ this.tokens = this.tokens.map(callbackfn);
932
+ return this;
933
+ }
934
+ filter(callbackfn) {
935
+ this.tokens = this.tokens.filter(callbackfn);
936
+ return this;
937
+ }
938
+ updateMagicString(ms) {
939
+ for (const { start, end, value } of this.tokens) ms.update(start, end, value);
940
+ return ms;
941
+ }
942
+ };
943
+ //#endregion
944
+ //#region src/js/module-graph/ignored-exports.ts
945
+ var IgnoredExportsTracker = class {
946
+ constructor(options) {
947
+ this.options = options;
948
+ this.ignoredExportNames = /* @__PURE__ */ new Map();
949
+ }
950
+ addIgnoredExport(filename, exportName) {
951
+ if (!exportName) return;
952
+ let pending = this.ignoredExportNames.get(filename);
953
+ if (!pending) {
954
+ pending = /* @__PURE__ */ new Set();
955
+ this.ignoredExportNames.set(filename, pending);
956
+ }
957
+ if (pending.has(exportName)) return;
958
+ pending.add(exportName);
959
+ const existing = this.options.modules.get(filename);
960
+ if (existing) this.applyIgnoredExportsToAnalysis(filename, existing.analysis);
961
+ }
962
+ registerIgnoredExportsFromTokens(resolved, tokens) {
963
+ for (const token of tokens) if (token.type === "ImportSpecifier") this.addIgnoredExport(resolved, token.imported);
964
+ else if (token.type === "ImportDefaultSpecifier") this.addIgnoredExport(resolved, "default");
965
+ }
966
+ applyIgnoredExportsToAnalysis(filename, analysis) {
967
+ const pending = this.ignoredExportNames.get(filename);
968
+ if (!pending || pending.size === 0) return;
969
+ const names = new Set(pending);
970
+ pending.clear();
971
+ const propagate = [];
972
+ for (const exportPath of analysis.exportDeclarations) {
973
+ if (names.size === 0) break;
974
+ if (exportPath.isExportDefaultDeclaration()) {
975
+ if (names.has("default")) {
976
+ analysis.walker.walkExportDefaultDeclaration(exportPath);
977
+ names.delete("default");
978
+ }
979
+ continue;
980
+ }
981
+ if (exportPath.isExportNamedDeclaration()) {
982
+ const source = exportPath.node.source?.value;
983
+ if (typeof source === "string") {
984
+ for (const spec of exportPath.get("specifiers")) {
985
+ if (!spec.isExportSpecifier()) continue;
986
+ const exported = spec.get("exported");
987
+ let exportedName;
988
+ if (exported.isIdentifier()) exportedName = exported.node.name;
989
+ else if (exported.isStringLiteral()) exportedName = exported.node.value;
990
+ if (!exportedName || !names.has(exportedName)) continue;
991
+ const local = spec.get("local");
992
+ if (local.isIdentifier()) {
993
+ propagate.push({
994
+ specifier: source,
995
+ exportName: local.node.name
996
+ });
997
+ names.delete(exportedName);
998
+ } else if (local.isStringLiteral()) {
999
+ propagate.push({
1000
+ specifier: source,
1001
+ exportName: local.node.value
1002
+ });
1003
+ names.delete(exportedName);
1004
+ }
1005
+ }
1006
+ continue;
1007
+ }
1008
+ const declaration = exportPath.get("declaration");
1009
+ if (declaration.isVariableDeclaration()) for (const decl of declaration.get("declarations")) {
1010
+ const id = decl.get("id");
1011
+ if (id.isIdentifier()) {
1012
+ const exportName = id.node.name;
1013
+ if (names.has(exportName)) {
1014
+ analysis.walker.walkVariableDeclarator(decl);
1015
+ names.delete(exportName);
1016
+ }
1017
+ }
1018
+ }
1019
+ for (const spec of exportPath.get("specifiers")) {
1020
+ if (!spec.isExportSpecifier()) continue;
1021
+ const exported = spec.get("exported");
1022
+ let exportedName;
1023
+ if (exported.isIdentifier()) exportedName = exported.node.name;
1024
+ else if (exported.isStringLiteral()) exportedName = exported.node.value;
1025
+ if (!exportedName || !names.has(exportedName)) continue;
1026
+ const local = spec.get("local");
1027
+ analysis.walker.walkNode(local);
1028
+ names.delete(exportedName);
1029
+ }
1030
+ continue;
1031
+ }
1032
+ if (exportPath.isExportAllDeclaration()) {
1033
+ const source = exportPath.node.source?.value;
1034
+ if (typeof source === "string") {
1035
+ for (const exportName of names) propagate.push({
1036
+ specifier: source,
1037
+ exportName
1038
+ });
1039
+ names.clear();
1040
+ }
1041
+ }
1042
+ }
1043
+ for (const { specifier, exportName } of propagate) {
1044
+ let resolved;
1045
+ try {
1046
+ resolved = this.options.resolve(specifier, filename);
1047
+ } catch {
1048
+ resolved = void 0;
1049
+ }
1050
+ if (!resolved) {
1051
+ pending.add(exportName);
1052
+ continue;
1053
+ }
1054
+ if (this.options.filter && !this.options.filter(resolved, specifier, filename)) {
1055
+ pending.add(exportName);
1056
+ continue;
1057
+ }
1058
+ this.addIgnoredExport(resolved, exportName);
1059
+ }
1060
+ for (const name of names) pending.add(name);
1061
+ }
1062
+ };
1063
+ //#endregion
1064
+ //#region src/js/ModuleGraph.ts
1065
+ var JsModuleGraph = class {
1066
+ constructor(entry, graphOptions) {
1067
+ this.modules = /* @__PURE__ */ new Map();
1068
+ this.queue = [];
1069
+ this.resolve = graphOptions.resolve;
1070
+ this.load = graphOptions.load;
1071
+ this.filter = graphOptions.filter;
1072
+ this.maxDepth = graphOptions.maxDepth ?? Number.POSITIVE_INFINITY;
1073
+ const { moduleGraph: _moduleGraph, filename: _ignoredFilename, ...rest } = entry.handlerOptions;
1074
+ this.baseOptions = {
1075
+ ...rest,
1076
+ filename: entry.filename
1077
+ };
1078
+ this.parserOptions = entry.handlerOptions.babelParserOptions;
1079
+ this.rootFilename = entry.filename;
1080
+ this.ignoredExports = new IgnoredExportsTracker({
1081
+ resolve: this.resolve,
1082
+ filter: this.filter,
1083
+ modules: this.modules
1084
+ });
1085
+ this.modules.set(entry.filename, {
1086
+ filename: entry.filename,
1087
+ source: entry.source,
1088
+ analysis: entry.analysis
1089
+ });
1090
+ this.queue.push({
1091
+ filename: entry.filename,
1092
+ depth: 0
1093
+ });
1094
+ }
1095
+ build() {
1096
+ this.collectDependencies();
1097
+ let linked;
1098
+ for (const [filename, state] of this.modules) {
1099
+ if (filename === this.rootFilename) continue;
1100
+ const childOptions = {
1101
+ ...this.baseOptions,
1102
+ filename
1103
+ };
1104
+ const code = processUpdatedSource(state.source, childOptions, state.analysis).toString();
1105
+ if (code !== state.source) {
1106
+ if (!linked) linked = {};
1107
+ linked[filename] = { code };
1108
+ }
1109
+ }
1110
+ return linked;
1111
+ }
1112
+ collectDependencies() {
1113
+ while (this.queue.length > 0) {
1114
+ const { filename, depth } = this.queue.shift();
1115
+ if (depth >= this.maxDepth) continue;
1116
+ const state = this.modules.get(filename);
1117
+ if (!state) continue;
1118
+ const dependencySpecifiers = /* @__PURE__ */ new Map();
1119
+ for (const token of state.analysis.walker.imports) {
1120
+ if (!dependencySpecifiers.has(token.source)) dependencySpecifiers.set(token.source, []);
1121
+ dependencySpecifiers.get(token.source).push(token);
1122
+ }
1123
+ for (const exportPath of state.analysis.exportDeclarations) if (exportPath.isExportAllDeclaration() || exportPath.isExportNamedDeclaration()) {
1124
+ const source = exportPath.node.source?.value;
1125
+ if (typeof source === "string" && !dependencySpecifiers.has(source)) dependencySpecifiers.set(source, []);
1126
+ }
1127
+ for (const [specifier, tokens] of dependencySpecifiers) {
1128
+ let resolved;
1129
+ try {
1130
+ resolved = this.resolve(specifier, filename);
1131
+ } catch {
1132
+ continue;
1133
+ }
1134
+ if (!resolved) continue;
1135
+ if (this.filter && !this.filter(resolved, specifier, filename)) continue;
1136
+ if (tokens.length > 0) this.ignoredExports.registerIgnoredExportsFromTokens(resolved, tokens);
1137
+ if (this.modules.has(resolved)) continue;
1138
+ let source;
1139
+ try {
1140
+ source = this.load(resolved);
1141
+ } catch {
1142
+ continue;
1143
+ }
1144
+ if (typeof source !== "string") continue;
1145
+ let analysis;
1146
+ try {
1147
+ analysis = analyzeSource(babelParse(source, {
1148
+ ...this.parserOptions,
1149
+ sourceFilename: resolved
1150
+ }), {
1151
+ ...this.baseOptions,
1152
+ filename: resolved
1153
+ });
1154
+ this.ignoredExports.applyIgnoredExportsToAnalysis(resolved, analysis);
1155
+ } catch {
1156
+ continue;
1157
+ }
1158
+ this.modules.set(resolved, {
1159
+ filename: resolved,
1160
+ source,
1161
+ analysis
1162
+ });
1163
+ this.queue.push({
1164
+ filename: resolved,
1165
+ depth: depth + 1
1166
+ });
1167
+ }
1168
+ }
1169
+ }
1170
+ };
1171
+ //#endregion
1172
+ //#region src/js/node-path-walker/export-handlers.ts
1173
+ function walkExportDeclaration(ctx, path) {
1174
+ if (path.isExportDeclaration()) {
1175
+ if (path.isExportNamedDeclaration()) walkExportNamedDeclaration(ctx, path);
1176
+ else if (path.isExportDefaultDeclaration()) walkExportDefaultDeclaration(ctx, path);
1177
+ else if (path.isExportAllDeclaration()) walkExportAllDeclaration(ctx, path);
1178
+ }
1179
+ }
1180
+ function walkExportNamedDeclaration(ctx, path) {
1181
+ const declaration = path.get("declaration");
1182
+ if (declaration.isVariableDeclaration()) for (const decl of declaration.get("declarations")) ctx.walkNode(decl);
1183
+ const specifiers = path.get("specifiers");
1184
+ for (const spec of specifiers) if (spec.isExportSpecifier()) {
1185
+ const local = spec.get("local");
1186
+ if (local.isIdentifier()) ctx.walkNode(local);
1187
+ }
1188
+ }
1189
+ function walkExportDefaultDeclaration(ctx, path) {
1190
+ const decl = path.get("declaration");
1191
+ if (decl.isIdentifier()) ctx.walkNode(decl);
1192
+ else ctx.walkNode(decl);
1193
+ }
1194
+ function walkExportAllDeclaration(ctx, path) {
1195
+ const source = path.get("source");
1196
+ if (source.isStringLiteral()) ctx.addImportToken({
1197
+ declaration: path,
1198
+ source: source.node.value,
1199
+ type: "ExportAllDeclaration"
1200
+ });
1201
+ }
1202
+ //#endregion
1203
+ //#region src/js/node-path-walker/import-tokens.ts
1204
+ function maybeAddImportToken(imports, arg) {
1205
+ if (!(arg.isImportSpecifier() && arg.node.importKind !== "type" || arg.isImportDefaultSpecifier())) return false;
1206
+ const importDeclaration = arg.parentPath;
1207
+ if (!importDeclaration.isImportDeclaration() || importDeclaration.node.importKind === "type") return false;
1208
+ if (arg.isImportSpecifier()) {
1209
+ const imported = arg.get("imported");
1210
+ if (imported.isIdentifier()) imports.add({
1211
+ declaration: importDeclaration,
1212
+ specifier: arg,
1213
+ imported: imported.node.name,
1214
+ local: arg.node.local.name,
1215
+ source: importDeclaration.node.source.value,
1216
+ type: "ImportSpecifier"
1217
+ });
1218
+ return true;
1219
+ }
1220
+ imports.add({
1221
+ declaration: importDeclaration,
1222
+ specifier: arg,
1223
+ local: arg.node.local.name,
1224
+ source: importDeclaration.node.source.value,
1225
+ type: "ImportDefaultSpecifier"
1226
+ });
1227
+ return true;
1228
+ }
1229
+ //#endregion
1230
+ //#region src/js/NodePathWalker.ts
1231
+ const EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS = [];
1232
+ const EMPTY_IMPORT_TOKENS = /* @__PURE__ */ new Set();
1233
+ function NOOP_STRING_PATH_CALLBACK() {}
1234
+ const NEVER_MATCH_NAME = () => false;
1235
+ /**
1236
+ * 遍历我们关注的调用表达式所关联的绑定,收集后续需要转换的字符串节点。
1237
+ */
1238
+ var NodePathWalker = class {
1239
+ constructor({ ignoreCallExpressionIdentifiers, callback } = {}) {
1240
+ this.hasIgnoredCallIdentifiers = Boolean(ignoreCallExpressionIdentifiers && ignoreCallExpressionIdentifiers.length > 0);
1241
+ this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS;
1242
+ this.callback = callback ?? NOOP_STRING_PATH_CALLBACK;
1243
+ this.isIgnoredCallIdentifier = this.hasIgnoredCallIdentifiers ? createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true }) : NEVER_MATCH_NAME;
1244
+ }
1245
+ get imports() {
1246
+ return this.importsStore ?? EMPTY_IMPORT_TOKENS;
1247
+ }
1248
+ getWritableImports() {
1249
+ if (!this.importsStore) this.importsStore = /* @__PURE__ */ new Set();
1250
+ return this.importsStore;
1251
+ }
1252
+ addImportToken(token) {
1253
+ this.getWritableImports().add(token);
1254
+ }
1255
+ getVisited() {
1256
+ if (!this.visitedStore) this.visitedStore = /* @__PURE__ */ new WeakSet();
1257
+ return this.visitedStore;
1258
+ }
1259
+ walkVariableDeclarator(path) {
1260
+ const init = path.get("init");
1261
+ this.walkNode(init);
1262
+ }
1263
+ walkTemplateLiteral(path) {
1264
+ for (const exp of path.get("expressions")) this.walkNode(exp);
1265
+ for (const quasis of path.get("quasis")) this.callback(quasis);
1266
+ }
1267
+ walkStringLiteral(path) {
1268
+ this.callback(path);
1269
+ }
1270
+ walkBinaryExpression(path) {
1271
+ const left = path.get("left");
1272
+ this.walkNode(left);
1273
+ const right = path.get("right");
1274
+ this.walkNode(right);
1275
+ }
1276
+ walkLogicalExpression(path) {
1277
+ const left = path.get("left");
1278
+ this.walkNode(left);
1279
+ const right = path.get("right");
1280
+ this.walkNode(right);
1281
+ }
1282
+ walkObjectExpression(path) {
1283
+ const props = path.get("properties");
1284
+ for (const prop of props) if (prop.isObjectProperty()) {
1285
+ const key = prop.get("key");
1286
+ this.walkNode(key);
1287
+ const value = prop.get("value");
1288
+ this.walkNode(value);
1289
+ }
1290
+ }
1291
+ walkArrayExpression(path) {
1292
+ const elements = path.get("elements");
1293
+ for (const element of elements) this.walkNode(element);
1294
+ }
1295
+ walkNode(arg) {
1296
+ const visited = this.getVisited();
1297
+ if (visited.has(arg)) return;
1298
+ visited.add(arg);
1299
+ if (arg.isIdentifier()) {
1300
+ const binding = arg?.scope?.getBinding?.(arg.node.name);
1301
+ if (binding) this.walkNode(binding.path);
1302
+ } else if (arg.isMemberExpression()) {
1303
+ const objectPath = arg.get("object");
1304
+ if (objectPath.isIdentifier()) {
1305
+ const binding = arg?.scope?.getBinding?.(objectPath.node.name);
1306
+ if (binding) {
1307
+ if (binding.path.isVariableDeclarator()) this.walkVariableDeclarator(binding.path);
1308
+ }
1309
+ }
1310
+ } else if (arg.isTemplateLiteral()) this.walkTemplateLiteral(arg);
1311
+ else if (arg.isStringLiteral()) this.walkStringLiteral(arg);
1312
+ else if (arg.isBinaryExpression()) this.walkBinaryExpression(arg);
1313
+ else if (arg.isLogicalExpression()) this.walkLogicalExpression(arg);
1314
+ else if (arg.isObjectExpression()) this.walkObjectExpression(arg);
1315
+ else if (arg.isArrayExpression()) this.walkArrayExpression(arg);
1316
+ else if (arg.isVariableDeclarator()) this.walkVariableDeclarator(arg);
1317
+ else if (maybeAddImportToken(this.getWritableImports(), arg)) {}
1318
+ }
1319
+ /**
1320
+ * Walk the arguments of a desired call expression so their bindings can be analysed.
1321
+ */
1322
+ walkCallExpression(path) {
1323
+ if (!this.hasIgnoredCallIdentifiers) return;
1324
+ const calleePath = path.get("callee");
1325
+ if (calleePath.isIdentifier() && this.isIgnoredCallIdentifier(calleePath.node.name)) for (const arg of path.get("arguments")) this.walkNode(arg);
1326
+ }
1327
+ walkExportDeclaration(path) {
1328
+ walkExportDeclaration(this, path);
1329
+ }
1330
+ walkExportNamedDeclaration(path) {
1331
+ walkExportNamedDeclaration(this, path);
1332
+ }
1333
+ walkExportDefaultDeclaration(path) {
1334
+ walkExportDefaultDeclaration(this, path);
1335
+ }
1336
+ walkExportAllDeclaration(path) {
1337
+ walkExportAllDeclaration(this, path);
1338
+ }
1339
+ };
1340
+ //#endregion
1341
+ //#region src/js/taggedTemplateIgnore.ts
1342
+ function createTaggedTemplateIgnore({ matcher, names }) {
1343
+ const bindingIgnoreCache = /* @__PURE__ */ new Map();
1344
+ const taggedTemplateIgnoreCache = /* @__PURE__ */ new WeakMap();
1345
+ const seenBindings = /* @__PURE__ */ new Set();
1346
+ let singleCanonicalIgnoreName;
1347
+ let canonicalIgnoreNames;
1348
+ for (const item of names ?? []) {
1349
+ if (typeof item !== "string") continue;
1350
+ if (singleCanonicalIgnoreName === void 0) {
1351
+ singleCanonicalIgnoreName = item;
1352
+ continue;
1353
+ }
1354
+ if (item === singleCanonicalIgnoreName) continue;
1355
+ if (!canonicalIgnoreNames) {
1356
+ canonicalIgnoreNames = new Set([singleCanonicalIgnoreName, item]);
1357
+ continue;
1358
+ }
1359
+ canonicalIgnoreNames.add(item);
1360
+ }
1361
+ const hasCanonicalIgnoreNames = singleCanonicalIgnoreName !== void 0;
1362
+ const matchesIgnoreName = (value) => {
1363
+ if (hasCanonicalIgnoreNames) {
1364
+ if (canonicalIgnoreNames) {
1365
+ if (canonicalIgnoreNames.has(value)) return true;
1366
+ } else if (value === singleCanonicalIgnoreName) return true;
1367
+ }
1368
+ return matcher(value);
1369
+ };
1370
+ const propertyMatches = (propertyPath) => {
1371
+ if (!propertyPath) return false;
1372
+ if (propertyPath.isIdentifier()) return matchesIgnoreName(propertyPath.node.name);
1373
+ if (propertyPath.isStringLiteral()) return matchesIgnoreName(propertyPath.node.value);
1374
+ return false;
1375
+ };
1376
+ const resolvesMemberExpressionToIgnore = (path, seen) => {
1377
+ if (propertyMatches(path.get("property"))) return true;
1378
+ const objectPath = path.get("object");
1379
+ if (objectPath.isIdentifier()) {
1380
+ const binding = (objectPath?.scope)?.getBinding?.(objectPath.node.name);
1381
+ if (binding) return resolvesToWeappTwIgnore(binding, seen);
1382
+ }
1383
+ return false;
1384
+ };
1385
+ const resolvesToWeappTwIgnore = (binding, seen) => {
1386
+ const cached = bindingIgnoreCache.get(binding);
1387
+ if (cached !== void 0) return cached;
1388
+ if (seen.has(binding)) return false;
1389
+ seen.add(binding);
1390
+ let result = false;
1391
+ const bindingPath = binding.path;
1392
+ if (bindingPath.isImportSpecifier()) {
1393
+ const imported = bindingPath.node.imported;
1394
+ if (imported.type === "Identifier" && matchesIgnoreName(imported.name)) result = true;
1395
+ else if (imported.type === "StringLiteral" && matchesIgnoreName(imported.value)) result = true;
1396
+ } else if (bindingPath.isVariableDeclarator()) {
1397
+ const init = bindingPath.get("init");
1398
+ if (init && init.node) {
1399
+ if (init.isIdentifier()) {
1400
+ const target = binding?.scope?.getBinding?.(init.node.name);
1401
+ if (target) result = resolvesToWeappTwIgnore(target, seen);
1402
+ } else if (init.isMemberExpression()) result = resolvesMemberExpressionToIgnore(init, seen);
1403
+ }
1404
+ }
1405
+ bindingIgnoreCache.set(binding, result);
1406
+ seen.delete(binding);
1407
+ return result;
1408
+ };
1409
+ const getEffectiveTagPath = (tagPath) => {
1410
+ let current = tagPath;
1411
+ while (true) {
1412
+ if (current.isParenthesizedExpression?.() || current.node.type === "ParenthesizedExpression") {
1413
+ current = current.get("expression");
1414
+ continue;
1415
+ }
1416
+ if (current.isTSAsExpression() || current.isTSTypeAssertion()) {
1417
+ current = current.get("expression");
1418
+ continue;
1419
+ }
1420
+ if (current.isTSNonNullExpression()) {
1421
+ current = current.get("expression");
1422
+ continue;
1423
+ }
1424
+ if (current.isTypeCastExpression?.()) {
1425
+ current = current.get("expression");
1426
+ continue;
1427
+ }
1428
+ if (current.isSequenceExpression()) {
1429
+ const last = current.get("expressions").at(-1);
1430
+ if (last) {
1431
+ current = last;
1432
+ continue;
1433
+ }
1434
+ }
1435
+ if (current.isCallExpression?.() || current.node.type === "CallExpression") {
1436
+ current = current.get("callee");
1437
+ continue;
1438
+ }
1439
+ break;
1440
+ }
1441
+ return current;
1442
+ };
1443
+ const evaluateTagPath = (tagPath, seen) => {
1444
+ if (tagPath.isCallExpression?.() || tagPath.node.type === "CallExpression") return evaluateTagPath(tagPath.get("callee"), seen);
1445
+ if (tagPath.isIdentifier()) {
1446
+ if (matchesIgnoreName(tagPath.node.name)) return true;
1447
+ const binding = tagPath?.scope?.getBinding?.(tagPath.node.name);
1448
+ if (binding) return resolvesToWeappTwIgnore(binding, seen);
1449
+ return false;
1450
+ }
1451
+ if (tagPath.isMemberExpression()) return resolvesMemberExpressionToIgnore(tagPath, seen);
1452
+ return false;
1453
+ };
1454
+ const computeIgnore = (tagPath) => {
1455
+ const cached = taggedTemplateIgnoreCache.get(tagPath.node);
1456
+ if (cached !== void 0) return cached;
1457
+ const effectiveTagPath = getEffectiveTagPath(tagPath);
1458
+ const effectiveCached = taggedTemplateIgnoreCache.get(effectiveTagPath.node);
1459
+ if (effectiveCached !== void 0) {
1460
+ taggedTemplateIgnoreCache.set(tagPath.node, effectiveCached);
1461
+ return effectiveCached;
1462
+ }
1463
+ seenBindings.clear();
1464
+ const result = evaluateTagPath(effectiveTagPath, seenBindings);
1465
+ taggedTemplateIgnoreCache.set(effectiveTagPath.node, result);
1466
+ taggedTemplateIgnoreCache.set(tagPath.node, result);
1467
+ return result;
1468
+ };
1469
+ return {
1470
+ shouldIgnore(tagPath) {
1471
+ return computeIgnore(tagPath);
1472
+ },
1473
+ getEffectiveTagPath
1474
+ };
1475
+ }
1476
+ //#endregion
1477
+ //#region src/js/babel.ts
1478
+ const EXPRESSION_WRAPPER_PREFIX = "(\n";
1479
+ const EXPRESSION_WRAPPER_SUFFIX = "\n)";
1480
+ const EMPTY_IGNORED_PATHS = /* @__PURE__ */ new WeakSet();
1481
+ const EMPTY_IMPORT_DECLARATIONS = /* @__PURE__ */ new Set();
1482
+ const EMPTY_EXPORT_DECLARATIONS = /* @__PURE__ */ new Set();
1483
+ const EMPTY_REQUIRE_CALL_PATHS = [];
1484
+ const ignoredTaggedTemplateMatcherCache = /* @__PURE__ */ new WeakMap();
1485
+ let defaultEvalHandler;
1486
+ function getIgnoredTaggedTemplateMatcher(options) {
1487
+ const cached = ignoredTaggedTemplateMatcherCache.get(options);
1488
+ if (cached) return cached;
1489
+ const created = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
1490
+ ignoredTaggedTemplateMatcherCache.set(options, created);
1491
+ return created;
1492
+ }
1493
+ function getDefaultEvalHandler() {
1494
+ if (!defaultEvalHandler) throw new Error("Default JS eval handler is not initialized.");
1495
+ return defaultEvalHandler;
1496
+ }
1497
+ function analyzeSource(ast, options, handler, collectModuleMetadata = true) {
1498
+ const jsTokenUpdater = new JsTokenUpdater();
1499
+ const needScope = Boolean(options.ignoreCallExpressionIdentifiers && options.ignoreCallExpressionIdentifiers.length > 0);
1500
+ const ignoredPaths = needScope ? /* @__PURE__ */ new WeakSet() : EMPTY_IGNORED_PATHS;
1501
+ const walker = needScope ? new NodePathWalker({
1502
+ ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
1503
+ callback(path) {
1504
+ ignoredPaths.add(path);
1505
+ }
1506
+ }) : new NodePathWalker();
1507
+ let taggedTemplateIgnore;
1508
+ const hasTaggedTemplateIgnoreIdentifiers = Boolean(options.ignoreTaggedTemplateExpressionIdentifiers && options.ignoreTaggedTemplateExpressionIdentifiers.length > 0);
1509
+ function getTaggedTemplateIgnore() {
1510
+ if (!taggedTemplateIgnore) taggedTemplateIgnore = createTaggedTemplateIgnore({
1511
+ matcher: getIgnoredTaggedTemplateMatcher(options),
1512
+ names: options.ignoreTaggedTemplateExpressionIdentifiers
1513
+ });
1514
+ return taggedTemplateIgnore;
1515
+ }
1516
+ const targetPaths = [];
1517
+ const importDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_IMPORT_DECLARATIONS;
1518
+ const exportDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_EXPORT_DECLARATIONS;
1519
+ const requireCallPaths = collectModuleMetadata ? [] : EMPTY_REQUIRE_CALL_PATHS;
1520
+ const evalHandler = handler ?? getDefaultEvalHandler();
1521
+ traverse(ast, {
1522
+ StringLiteral: { enter(p) {
1523
+ if (isEvalPath(p.parentPath)) return;
1524
+ targetPaths.push(p);
1525
+ } },
1526
+ TemplateElement: { enter: hasTaggedTemplateIgnoreIdentifiers ? (p) => {
1527
+ const pp = p.parentPath;
1528
+ if (pp.isTemplateLiteral()) {
1529
+ const ppp = pp.parentPath;
1530
+ if (isEvalPath(ppp)) return;
1531
+ if (ppp.isTaggedTemplateExpression()) {
1532
+ const tagPath = ppp.get("tag");
1533
+ if (getTaggedTemplateIgnore().shouldIgnore(tagPath)) return;
1534
+ }
1535
+ }
1536
+ targetPaths.push(p);
1537
+ } : (p) => {
1538
+ const pp = p.parentPath;
1539
+ if (pp.isTemplateLiteral()) {
1540
+ const ppp = pp.parentPath;
1541
+ if (isEvalPath(ppp)) return;
1542
+ }
1543
+ targetPaths.push(p);
1544
+ } },
1545
+ CallExpression: { enter: !collectModuleMetadata && !needScope ? (p) => {
1546
+ if (isEvalPath(p)) walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
1547
+ } : (p) => {
1548
+ if (isEvalPath(p)) {
1549
+ walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
1550
+ return;
1551
+ }
1552
+ const calleePath = p.get("callee");
1553
+ if (collectModuleMetadata && calleePath.isIdentifier({ name: "require" }) && !p?.scope?.hasBinding?.("require")) {
1554
+ const args = p.get("arguments");
1555
+ if (Array.isArray(args) && args.length > 0) {
1556
+ const first = args[0];
1557
+ if (first?.isStringLiteral()) requireCallPaths.push(first);
1558
+ }
1559
+ }
1560
+ if (needScope) walker.walkCallExpression(p);
1561
+ } },
1562
+ ...collectModuleMetadata ? {
1563
+ ImportDeclaration: { enter(p) {
1564
+ importDeclarations.add(p);
1565
+ } },
1566
+ ExportDeclaration: { enter(p) {
1567
+ exportDeclarations.add(p);
1568
+ } }
1569
+ } : {},
1570
+ noScope: !needScope
1571
+ });
1572
+ return {
1573
+ walker,
1574
+ jsTokenUpdater,
1575
+ ast,
1576
+ targetPaths,
1577
+ importDeclarations,
1578
+ exportDeclarations,
1579
+ requireCallPaths,
1580
+ ignoredPaths
1581
+ };
1582
+ }
1583
+ function jsHandler(rawSource, options) {
1584
+ const shouldWrapExpression = Boolean(options.wrapExpression);
1585
+ const source = shouldWrapExpression ? `${EXPRESSION_WRAPPER_PREFIX}${rawSource}${EXPRESSION_WRAPPER_SUFFIX}` : rawSource;
1586
+ let ast;
1587
+ try {
1588
+ ast = babelParse(source, options.babelParserOptions);
1589
+ } catch (error) {
1590
+ return {
1591
+ code: rawSource,
1592
+ error
1593
+ };
1594
+ }
1595
+ const needsModuleMetadata = Boolean(options.moduleSpecifierReplacements || options.moduleGraph && options.filename);
1596
+ const analysis = analyzeSource(ast, options, jsHandler, needsModuleMetadata);
1597
+ const ms = processUpdatedSource(source, options, analysis);
1598
+ if (shouldWrapExpression) {
1599
+ const start = 0;
1600
+ const end = source.length;
1601
+ const prefixLength = 2;
1602
+ const suffixLength = 2;
1603
+ ms.remove(start, start + prefixLength);
1604
+ ms.remove(end - suffixLength, end);
1605
+ }
1606
+ const result = { code: ms.toString() };
1607
+ if (options.generateMap) Object.defineProperty(result, "map", {
1608
+ configurable: true,
1609
+ enumerable: true,
1610
+ get() {
1611
+ return ms.generateMap();
1612
+ }
1613
+ });
1614
+ if (options.moduleGraph && options.filename) {
1615
+ const linked = new JsModuleGraph({
1616
+ filename: options.filename,
1617
+ source: rawSource,
1618
+ analysis,
1619
+ handlerOptions: options
1620
+ }, options.moduleGraph).build();
1621
+ if (linked) result.linked = linked;
1622
+ }
1623
+ return result;
1624
+ }
1625
+ defaultEvalHandler = jsHandler;
1626
+ Object.freeze({ wrapExpression: true });
1627
+ //#endregion
1628
+ //#region src/wxml/whitespace.ts
1629
+ const WHITESPACE_CODES = new Set([
1630
+ 9,
1631
+ 10,
1632
+ 11,
1633
+ 12,
1634
+ 13,
1635
+ 32,
1636
+ 160,
1637
+ 65279
702
1638
  ]);
703
1639
  function isWhitespace(char) {
704
- if (char.length === 0) {
705
- return false;
706
- }
707
- return WHITESPACE_CODES.has(char.charCodeAt(0));
1640
+ if (char.length === 0) return false;
1641
+ return WHITESPACE_CODES.has(char.charCodeAt(0));
708
1642
  }
709
-
710
- // src/wxml/Tokenizer.ts
1643
+ //#endregion
1644
+ //#region src/wxml/Tokenizer.ts
711
1645
  var Tokenizer = class {
712
- constructor() {
713
- this.reset();
714
- }
715
- processChar(char, index) {
716
- switch (this.state) {
717
- case 0 /* START */:
718
- if (isWhitespace(char)) {
719
- } else if (char === "{") {
720
- this.state = 2 /* OPEN_BRACE */;
721
- this.bufferStartIndex = index;
722
- this.buffer += char;
723
- this.expressionBuffer = char;
724
- this.expressionStartIndex = index;
725
- } else {
726
- this.state = 1 /* TEXT */;
727
- this.bufferStartIndex = index;
728
- this.buffer += char;
729
- }
730
- break;
731
- case 1 /* TEXT */:
732
- if (isWhitespace(char)) {
733
- this.tokens.push({ start: this.bufferStartIndex, end: index, value: this.buffer, expressions: this.expressions });
734
- this.buffer = "";
735
- this.expressions = [];
736
- this.state = 0 /* START */;
737
- } else if (char === "{") {
738
- this.buffer += char;
739
- this.expressionBuffer = char;
740
- this.expressionStartIndex = index;
741
- this.state = 2 /* OPEN_BRACE */;
742
- } else {
743
- this.buffer += char;
744
- }
745
- break;
746
- case 2 /* OPEN_BRACE */:
747
- if (char === "}") {
748
- this.buffer += char;
749
- this.expressionBuffer += char;
750
- this.state = 3 /* POTENTIAL_CLOSE */;
751
- } else {
752
- this.buffer += char;
753
- this.expressionBuffer += char;
754
- }
755
- break;
756
- case 3 /* POTENTIAL_CLOSE */:
757
- if (char === "}") {
758
- this.buffer += char;
759
- this.expressionBuffer += char;
760
- this.expressions.push({
761
- start: this.expressionStartIndex,
762
- end: index + 1,
763
- value: this.expressionBuffer
764
- });
765
- this.expressionBuffer = "";
766
- this.state = 4 /* BRACES_COMPLETE */;
767
- } else {
768
- this.buffer += char;
769
- this.expressionBuffer += char;
770
- this.state = 2 /* OPEN_BRACE */;
771
- }
772
- break;
773
- case 4 /* BRACES_COMPLETE */:
774
- if (isWhitespace(char)) {
775
- this.tokens.push({
776
- start: this.bufferStartIndex,
777
- end: index,
778
- value: this.buffer,
779
- expressions: this.expressions
780
- });
781
- this.buffer = "";
782
- this.expressions = [];
783
- this.state = 0 /* START */;
784
- } else if (char === "{") {
785
- this.expressionStartIndex = index;
786
- this.expressionBuffer = char;
787
- this.buffer += char;
788
- this.state = 2 /* OPEN_BRACE */;
789
- } else {
790
- this.buffer += char;
791
- this.state = 1 /* TEXT */;
792
- }
793
- break;
794
- default:
795
- throw new Error("Unexpected state");
796
- }
797
- }
798
- run(input) {
799
- this.reset();
800
- for (let i = 0; i < input.length; i++) {
801
- const char = input[i];
802
- this.processChar(char, i);
803
- }
804
- if (this.buffer.length > 0) {
805
- this.tokens.push({
806
- start: this.bufferStartIndex,
807
- end: input.length,
808
- value: this.buffer,
809
- expressions: this.expressions
810
- });
811
- }
812
- const tokens = this.tokens;
813
- this.reset();
814
- return tokens;
815
- }
816
- reset() {
817
- this.state = 0 /* START */;
818
- this.buffer = "";
819
- this.tokens = [];
820
- this.bufferStartIndex = 0;
821
- this.expressionBuffer = "";
822
- this.expressionStartIndex = 0;
823
- this.expressions = [];
824
- }
1646
+ constructor() {
1647
+ this.reset();
1648
+ }
1649
+ processChar(char, index) {
1650
+ switch (this.state) {
1651
+ case 0:
1652
+ if (isWhitespace(char)) {} else if (char === "{") {
1653
+ this.state = 2;
1654
+ this.bufferStartIndex = index;
1655
+ this.buffer += char;
1656
+ this.expressionBuffer = char;
1657
+ this.expressionStartIndex = index;
1658
+ } else {
1659
+ this.state = 1;
1660
+ this.bufferStartIndex = index;
1661
+ this.buffer += char;
1662
+ }
1663
+ break;
1664
+ case 1:
1665
+ if (isWhitespace(char)) {
1666
+ this.tokens.push({
1667
+ start: this.bufferStartIndex,
1668
+ end: index,
1669
+ value: this.buffer,
1670
+ expressions: this.expressions
1671
+ });
1672
+ this.buffer = "";
1673
+ this.expressions = [];
1674
+ this.state = 0;
1675
+ } else if (char === "{") {
1676
+ this.buffer += char;
1677
+ this.expressionBuffer = char;
1678
+ this.expressionStartIndex = index;
1679
+ this.state = 2;
1680
+ } else this.buffer += char;
1681
+ break;
1682
+ case 2:
1683
+ if (char === "}") {
1684
+ this.buffer += char;
1685
+ this.expressionBuffer += char;
1686
+ this.state = 3;
1687
+ } else {
1688
+ this.buffer += char;
1689
+ this.expressionBuffer += char;
1690
+ }
1691
+ break;
1692
+ case 3:
1693
+ if (char === "}") {
1694
+ this.buffer += char;
1695
+ this.expressionBuffer += char;
1696
+ this.expressions.push({
1697
+ start: this.expressionStartIndex,
1698
+ end: index + 1,
1699
+ value: this.expressionBuffer
1700
+ });
1701
+ this.expressionBuffer = "";
1702
+ this.state = 4;
1703
+ } else {
1704
+ this.buffer += char;
1705
+ this.expressionBuffer += char;
1706
+ this.state = 2;
1707
+ }
1708
+ break;
1709
+ case 4:
1710
+ if (isWhitespace(char)) {
1711
+ this.tokens.push({
1712
+ start: this.bufferStartIndex,
1713
+ end: index,
1714
+ value: this.buffer,
1715
+ expressions: this.expressions
1716
+ });
1717
+ this.buffer = "";
1718
+ this.expressions = [];
1719
+ this.state = 0;
1720
+ } else if (char === "{") {
1721
+ this.expressionStartIndex = index;
1722
+ this.expressionBuffer = char;
1723
+ this.buffer += char;
1724
+ this.state = 2;
1725
+ } else {
1726
+ this.buffer += char;
1727
+ this.state = 1;
1728
+ }
1729
+ break;
1730
+ default: throw new Error("Unexpected state");
1731
+ }
1732
+ }
1733
+ run(input) {
1734
+ this.reset();
1735
+ for (let i = 0; i < input.length; i++) {
1736
+ const char = input[i];
1737
+ this.processChar(char, i);
1738
+ }
1739
+ if (this.buffer.length > 0) this.tokens.push({
1740
+ start: this.bufferStartIndex,
1741
+ end: input.length,
1742
+ value: this.buffer,
1743
+ expressions: this.expressions
1744
+ });
1745
+ const tokens = this.tokens;
1746
+ this.reset();
1747
+ return tokens;
1748
+ }
1749
+ reset() {
1750
+ this.state = 0;
1751
+ this.buffer = "";
1752
+ this.tokens = [];
1753
+ this.bufferStartIndex = 0;
1754
+ this.expressionBuffer = "";
1755
+ this.expressionStartIndex = 0;
1756
+ this.expressions = [];
1757
+ }
825
1758
  };
826
-
827
- // src/wxml/utils/template-fragments.ts
828
- var sharedTokenizer = new Tokenizer();
829
-
830
- // src/context/logger.ts
831
- import { logger as logger8 } from "@weapp-tailwindcss/logger";
832
-
833
- // src/context/tailwindcss.ts
834
- import { logger as logger10 } from "@weapp-tailwindcss/logger";
835
-
836
- // src/context/tailwindcss/basedir.ts
837
- import { createRequire as createRequire2 } from "module";
838
- import path10 from "path";
839
- import process10 from "process";
840
- import { fileURLToPath as fileURLToPath2 } from "url";
841
- import { logger as logger9 } from "@weapp-tailwindcss/logger";
842
-
843
- // src/context/tailwindcss/rax.ts
844
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
845
- import path11 from "path";
846
- import process11 from "process";
847
-
848
- // src/context/index.ts
1759
+ new Tokenizer();
1760
+ //#endregion
1761
+ //#region src/context/index.ts
849
1762
  async function clearTailwindcssPatcherCache(patcher, options) {
850
- if (!patcher) {
851
- return;
852
- }
853
- const cacheOptions = patcher.options?.cache;
854
- if (cacheOptions == null || typeof cacheOptions === "object" && cacheOptions.enabled === false) {
855
- return;
856
- }
857
- if (typeof patcher.clearCache === "function") {
858
- try {
859
- await patcher.clearCache({ scope: "all" });
860
- } catch (error) {
861
- logger11.debug("failed to clear tailwindcss patcher cache via clearCache(): %O", error);
862
- }
863
- }
864
- if (!options?.removeDirectory) {
865
- return;
866
- }
867
- const cachePaths = /* @__PURE__ */ new Map();
868
- const normalizedCacheOptions = typeof cacheOptions === "object" ? cacheOptions : void 0;
869
- if (normalizedCacheOptions?.path) {
870
- cachePaths.set(normalizedCacheOptions.path, false);
871
- }
872
- const privateCachePath = patcher?.cacheStore?.options?.path;
873
- if (privateCachePath) {
874
- cachePaths.set(privateCachePath, false);
875
- }
876
- if (options?.removeDirectory && normalizedCacheOptions?.dir) {
877
- cachePaths.set(normalizedCacheOptions.dir, true);
878
- }
879
- if (!cachePaths.size) {
880
- return;
881
- }
882
- for (const [cachePath, recursive] of cachePaths.entries()) {
883
- try {
884
- await rm(cachePath, { force: true, recursive });
885
- } catch (error) {
886
- const err = error;
887
- if (err?.code === "ENOENT") {
888
- continue;
889
- }
890
- logger11.debug("failed to clear tailwindcss patcher cache: %s %O", cachePath, err);
891
- }
892
- }
893
- }
894
-
895
- // src/cli/context.ts
1763
+ if (!patcher) return;
1764
+ const cacheOptions = patcher.options?.cache;
1765
+ if (cacheOptions == null || typeof cacheOptions === "object" && cacheOptions.enabled === false) return;
1766
+ if (typeof patcher.clearCache === "function") try {
1767
+ await patcher.clearCache({ scope: "all" });
1768
+ } catch (error) {
1769
+ logger.debug("failed to clear tailwindcss patcher cache via clearCache(): %O", error);
1770
+ }
1771
+ if (!options?.removeDirectory) return;
1772
+ const cachePaths = /* @__PURE__ */ new Map();
1773
+ const normalizedCacheOptions = typeof cacheOptions === "object" ? cacheOptions : void 0;
1774
+ if (normalizedCacheOptions?.path) cachePaths.set(normalizedCacheOptions.path, false);
1775
+ const privateCachePath = patcher?.cacheStore?.options?.path;
1776
+ if (privateCachePath) cachePaths.set(privateCachePath, false);
1777
+ if (options?.removeDirectory && normalizedCacheOptions?.dir) cachePaths.set(normalizedCacheOptions.dir, true);
1778
+ if (!cachePaths.size) return;
1779
+ for (const [cachePath, recursive] of cachePaths.entries()) try {
1780
+ await rm(cachePath, {
1781
+ force: true,
1782
+ recursive
1783
+ });
1784
+ } catch (error) {
1785
+ const err = error;
1786
+ if (err?.code === "ENOENT") continue;
1787
+ logger.debug("failed to clear tailwindcss patcher cache: %s %O", cachePath, err);
1788
+ }
1789
+ }
1790
+ //#endregion
1791
+ //#region src/cli/context.ts
896
1792
  function formatOutputPath(target, baseDir) {
897
- const root = baseDir ?? process12.cwd();
898
- const relative = path12.relative(root, target);
899
- if (!relative) {
900
- return ".";
901
- }
902
- if (relative.startsWith("..")) {
903
- return path12.normalize(target);
904
- }
905
- return relative.startsWith(".") ? relative : `.${path12.sep}${relative}`;
906
- }
907
-
908
- // src/cli/helpers.ts
909
- import { mkdir as mkdir2 } from "fs/promises";
910
- import process15 from "process";
911
-
912
- // src/logger/index.ts
913
- import { logger as logger12 } from "@weapp-tailwindcss/logger";
914
-
915
- // src/cli/helpers/options/parse.ts
1793
+ const root = baseDir ?? process.cwd();
1794
+ const relative = path.relative(root, target);
1795
+ if (!relative) return ".";
1796
+ if (relative.startsWith("..")) return path.normalize(target);
1797
+ return relative.startsWith(".") ? relative : `.${path.sep}${relative}`;
1798
+ }
1799
+ //#endregion
1800
+ //#region src/cli/doctor/constants.ts
1801
+ const CONFIG_FILES = {
1802
+ tailwind: [
1803
+ "tailwind.config.js",
1804
+ "tailwind.config.cjs",
1805
+ "tailwind.config.mjs",
1806
+ "tailwind.config.ts"
1807
+ ],
1808
+ postcss: [
1809
+ "postcss.config.js",
1810
+ "postcss.config.cjs",
1811
+ "postcss.config.mjs",
1812
+ "postcss.config.ts"
1813
+ ],
1814
+ vite: [
1815
+ "vite.config.js",
1816
+ "vite.config.mjs",
1817
+ "vite.config.ts"
1818
+ ],
1819
+ webpack: [
1820
+ "webpack.config.js",
1821
+ "webpack.config.cjs",
1822
+ "webpack.config.ts"
1823
+ ]
1824
+ };
1825
+ const FRAMEWORK_DEPS = [
1826
+ ["@tarojs/taro", "Taro"],
1827
+ ["@dcloudio/uni-app", "uni-app"],
1828
+ ["@mpxjs/core", "MPX"],
1829
+ ["remax", "Remax"],
1830
+ ["rax", "Rax"]
1831
+ ];
1832
+ //#endregion
1833
+ //#region src/cli/doctor.ts
1834
+ function tryReadJson$1(file) {
1835
+ try {
1836
+ return JSON.parse(readFileSync(file, "utf8"));
1837
+ } catch {
1838
+ return;
1839
+ }
1840
+ }
1841
+ function findFirstExisting(cwd, files) {
1842
+ return files.find((file) => existsSync(path.join(cwd, file)));
1843
+ }
1844
+ function readProjectPackageJson(cwd) {
1845
+ return tryReadJson$1(path.join(cwd, "package.json"));
1846
+ }
1847
+ function readDependencyVersion(cwd, packageName) {
1848
+ try {
1849
+ return tryReadJson$1(createRequire(path.join(cwd, "package.json")).resolve(`${packageName}/package.json`))?.version;
1850
+ } catch {
1851
+ return;
1852
+ }
1853
+ }
1854
+ function collectDependencySpecs(pkg) {
1855
+ return {
1856
+ ...pkg?.dependencies ?? {},
1857
+ ...pkg?.devDependencies ?? {},
1858
+ ...pkg?.optionalDependencies ?? {},
1859
+ ...pkg?.peerDependencies ?? {}
1860
+ };
1861
+ }
1862
+ function detectPackageManager(cwd, pkg) {
1863
+ if (pkg?.packageManager) return pkg.packageManager;
1864
+ if (existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1865
+ if (existsSync(path.join(cwd, "package-lock.json"))) return "npm";
1866
+ if (existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
1867
+ }
1868
+ function detectFrameworks(deps) {
1869
+ return FRAMEWORK_DEPS.filter(([dependency]) => dependency in deps).map(([, label]) => label);
1870
+ }
1871
+ function addCheck(checks, check) {
1872
+ checks.push(check);
1873
+ }
1874
+ function summarizeChecks(checks) {
1875
+ return checks.reduce((summary, check) => {
1876
+ summary[check.status] += 1;
1877
+ return summary;
1878
+ }, {
1879
+ ok: 0,
1880
+ warn: 0,
1881
+ error: 0,
1882
+ info: 0
1883
+ });
1884
+ }
1885
+ function hasDependency(deps, packageName) {
1886
+ return packageName in deps;
1887
+ }
1888
+ function getMajorVersion(version) {
1889
+ if (!version) return;
1890
+ return semver.parse(version)?.major;
1891
+ }
1892
+ function getDependencyMajor(deps, packageName) {
1893
+ const spec = deps[packageName];
1894
+ return spec ? semver.minVersion(spec)?.major : void 0;
1895
+ }
1896
+ function createDoctorReport(options = {}) {
1897
+ const cwd = path.resolve(options.cwd ?? process.cwd());
1898
+ const nodeVersion = options.nodeVersion ?? process.versions.node;
1899
+ const pkg = readProjectPackageJson(cwd);
1900
+ const deps = collectDependencySpecs(pkg);
1901
+ const checks = [];
1902
+ const packageManager = detectPackageManager(cwd, pkg);
1903
+ const frameworks = detectFrameworks(deps);
1904
+ const tailwindcssVersion = readDependencyVersion(cwd, "tailwindcss");
1905
+ const weappTailwindcssVersion = readDependencyVersion(cwd, "weapp-tailwindcss");
1906
+ const tailwindMajor = getMajorVersion(tailwindcssVersion) ?? getDependencyMajor(deps, "tailwindcss");
1907
+ const tailwindConfig = findFirstExisting(cwd, CONFIG_FILES.tailwind);
1908
+ const postcssConfig = findFirstExisting(cwd, CONFIG_FILES.postcss);
1909
+ const viteConfig = findFirstExisting(cwd, CONFIG_FILES.vite);
1910
+ const webpackConfig = findFirstExisting(cwd, CONFIG_FILES.webpack);
1911
+ addCheck(checks, pkg ? {
1912
+ id: "package-json",
1913
+ title: "package.json",
1914
+ status: "ok",
1915
+ message: "已找到项目 package.json。"
1916
+ } : {
1917
+ id: "package-json",
1918
+ title: "package.json",
1919
+ status: "error",
1920
+ message: "当前目录没有 package.json。",
1921
+ suggestion: "请在项目根目录运行 doctor,或通过 --cwd 指向项目根目录。"
1922
+ });
1923
+ addCheck(checks, semver.satisfies(nodeVersion, "^20.19.0 || >=22.12.0") ? {
1924
+ id: "node-version",
1925
+ title: "Node.js",
1926
+ status: "ok",
1927
+ message: `当前 Node.js ${nodeVersion} 满足版本要求 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}。`
1928
+ } : {
1929
+ id: "node-version",
1930
+ title: "Node.js",
1931
+ status: "error",
1932
+ message: `当前 Node.js ${nodeVersion} 不满足版本要求 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}。`,
1933
+ suggestion: "请升级 Node.js 后再安装或构建 weapp-tailwindcss 项目。"
1934
+ });
1935
+ addCheck(checks, packageManager ? {
1936
+ id: "package-manager",
1937
+ title: "包管理器",
1938
+ status: packageManager.startsWith("pnpm") ? "ok" : "info",
1939
+ message: `检测到 ${packageManager}。`
1940
+ } : {
1941
+ id: "package-manager",
1942
+ title: "包管理器",
1943
+ status: "info",
1944
+ message: "未检测到 lockfile 或 packageManager 字段。"
1945
+ });
1946
+ addCheck(checks, hasDependency(deps, "weapp-tailwindcss") || Boolean(weappTailwindcssVersion) ? {
1947
+ id: "weapp-tailwindcss",
1948
+ title: "weapp-tailwindcss",
1949
+ status: "ok",
1950
+ message: `检测到 weapp-tailwindcss${weappTailwindcssVersion ? `@${weappTailwindcssVersion}` : ""}。`
1951
+ } : {
1952
+ id: "weapp-tailwindcss",
1953
+ title: "weapp-tailwindcss",
1954
+ status: "warn",
1955
+ message: "未在当前项目依赖中检测到 weapp-tailwindcss。",
1956
+ suggestion: "如果这是业务项目,请安装 weapp-tailwindcss 并确认命令运行在项目根目录。"
1957
+ });
1958
+ addCheck(checks, hasDependency(deps, "tailwindcss") || Boolean(tailwindcssVersion) ? {
1959
+ id: "tailwindcss",
1960
+ title: "Tailwind CSS",
1961
+ status: "ok",
1962
+ message: `检测到 tailwindcss${tailwindcssVersion ? `@${tailwindcssVersion}` : ""}。`
1963
+ } : {
1964
+ id: "tailwindcss",
1965
+ title: "Tailwind CSS",
1966
+ status: "error",
1967
+ message: "未检测到 tailwindcss。",
1968
+ suggestion: "请安装 tailwindcss,并确认依赖可以从当前项目解析。"
1969
+ });
1970
+ addCheck(checks, tailwindConfig ? {
1971
+ id: "tailwind-config",
1972
+ title: "Tailwind 配置",
1973
+ status: "ok",
1974
+ message: `检测到 ${tailwindConfig}。`
1975
+ } : {
1976
+ id: "tailwind-config",
1977
+ title: "Tailwind 配置",
1978
+ status: tailwindMajor === 4 ? "info" : "warn",
1979
+ message: "未检测到 tailwind.config.*。",
1980
+ suggestion: tailwindMajor === 4 ? "Tailwind CSS v4 可以采用 CSS-first 配置;如果使用 v3 或复杂 content/source,请补充配置文件。" : "请确认 Tailwind content/source 配置能够覆盖小程序页面、组件和脚本文件。"
1981
+ });
1982
+ addCheck(checks, postcssConfig ? {
1983
+ id: "postcss-config",
1984
+ title: "PostCSS 配置",
1985
+ status: "ok",
1986
+ message: `检测到 ${postcssConfig}。`
1987
+ } : {
1988
+ id: "postcss-config",
1989
+ title: "PostCSS 配置",
1990
+ status: viteConfig ? "info" : "warn",
1991
+ message: "未检测到 postcss.config.*。",
1992
+ suggestion: "如果通过 PostCSS 接入,请补充 postcss.config.*;如果通过 Vite/Taro 插件接入,可忽略此项。"
1993
+ });
1994
+ if (tailwindMajor === 4 && postcssConfig && !hasDependency(deps, "@tailwindcss/postcss")) addCheck(checks, {
1995
+ id: "tailwindcss-v4-postcss",
1996
+ title: "Tailwind v4 PostCSS",
1997
+ status: "warn",
1998
+ message: "Tailwind CSS v4 项目存在 PostCSS 配置,但未检测到 @tailwindcss/postcss。",
1999
+ suggestion: "如果 PostCSS 配置中仍直接使用 tailwindcss,请迁移到 @tailwindcss/postcss。"
2000
+ });
2001
+ addCheck(checks, frameworks.length > 0 ? {
2002
+ id: "framework",
2003
+ title: "框架识别",
2004
+ status: "ok",
2005
+ message: `检测到 ${frameworks.join(", ")}。`
2006
+ } : {
2007
+ id: "framework",
2008
+ title: "框架识别",
2009
+ status: "info",
2010
+ message: "未从依赖中识别出 Taro、uni-app、MPX、Remax 或 Rax。"
2011
+ });
2012
+ addCheck(checks, viteConfig || webpackConfig ? {
2013
+ id: "bundler-config",
2014
+ title: "构建器配置",
2015
+ status: "ok",
2016
+ message: `检测到 ${[viteConfig, webpackConfig].filter(Boolean).join(", ")}。`
2017
+ } : {
2018
+ id: "bundler-config",
2019
+ title: "构建器配置",
2020
+ status: "info",
2021
+ message: "未检测到 vite.config.* 或 webpack.config.*。"
2022
+ });
2023
+ return {
2024
+ cwd,
2025
+ nodeVersion,
2026
+ detected: {
2027
+ packageManager,
2028
+ frameworks,
2029
+ tailwindcssVersion,
2030
+ weappTailwindcssVersion
2031
+ },
2032
+ summary: summarizeChecks(checks),
2033
+ checks
2034
+ };
2035
+ }
2036
+ function hasDoctorFailure(report, strict = false) {
2037
+ return report.summary.error > 0 || strict && report.summary.warn > 0;
2038
+ }
2039
+ function formatDoctorReport(report) {
2040
+ const lines = [
2041
+ `weapp-tailwindcss doctor`,
2042
+ `cwd: ${report.cwd}`,
2043
+ `summary: ${report.summary.error} error, ${report.summary.warn} warn, ${report.summary.ok} ok, ${report.summary.info} info`,
2044
+ ""
2045
+ ];
2046
+ for (const check of report.checks) {
2047
+ lines.push(`[${check.status}] ${check.title}: ${check.message}`);
2048
+ if (check.suggestion) lines.push(` -> ${check.suggestion}`);
2049
+ }
2050
+ return lines.join("\n");
2051
+ }
2052
+ //#endregion
2053
+ //#region src/cli/helpers/options/parse.ts
916
2054
  function readStringOption(flag, value) {
917
- if (value == null) {
918
- return void 0;
919
- }
920
- if (typeof value !== "string") {
921
- throw new TypeError(`Option "--${flag}" expects a string value.`);
922
- }
923
- const trimmed = value.trim();
924
- if (trimmed.length === 0) {
925
- throw new TypeError(`Option "--${flag}" expects a non-empty value.`);
926
- }
927
- return trimmed;
2055
+ if (value == null) return;
2056
+ if (typeof value !== "string") throw new TypeError(`Option "--${flag}" expects a string value.`);
2057
+ const trimmed = value.trim();
2058
+ if (trimmed.length === 0) throw new TypeError(`Option "--${flag}" expects a non-empty value.`);
2059
+ return trimmed;
928
2060
  }
929
2061
  function readStringArrayOption(flag, value) {
930
- if (value == null) {
931
- return void 0;
932
- }
933
- if (Array.isArray(value)) {
934
- const normalized2 = value.filter((entry) => entry != null).map((entry) => {
935
- if (typeof entry !== "string") {
936
- throw new TypeError(`Option "--${flag}" expects string values.`);
937
- }
938
- const trimmed = entry.trim();
939
- if (!trimmed) {
940
- throw new TypeError(`Option "--${flag}" expects non-empty values.`);
941
- }
942
- return trimmed;
943
- });
944
- return normalized2.length > 0 ? normalized2 : void 0;
945
- }
946
- const normalized = readStringOption(flag, value);
947
- return normalized ? [normalized] : void 0;
2062
+ if (value == null) return;
2063
+ if (Array.isArray(value)) {
2064
+ const normalized = value.filter((entry) => entry != null).map((entry) => {
2065
+ if (typeof entry !== "string") throw new TypeError(`Option "--${flag}" expects string values.`);
2066
+ const trimmed = entry.trim();
2067
+ if (!trimmed) throw new TypeError(`Option "--${flag}" expects non-empty values.`);
2068
+ return trimmed;
2069
+ });
2070
+ return normalized.length > 0 ? normalized : void 0;
2071
+ }
2072
+ const normalized = readStringOption(flag, value);
2073
+ return normalized ? [normalized] : void 0;
948
2074
  }
949
2075
  function toBoolean(value, fallback) {
950
- if (typeof value === "boolean") {
951
- return value;
952
- }
953
- if (typeof value === "string") {
954
- if (value === "true") {
955
- return true;
956
- }
957
- if (value === "false") {
958
- return false;
959
- }
960
- }
961
- if (value == null) {
962
- return fallback;
963
- }
964
- return Boolean(value);
965
- }
966
-
967
- // src/cli/helpers/options/resolve.ts
968
- import path13 from "path";
969
- import process13 from "process";
2076
+ if (typeof value === "boolean") return value;
2077
+ if (typeof value === "string") {
2078
+ if (value === "true") return true;
2079
+ if (value === "false") return false;
2080
+ }
2081
+ if (value == null) return fallback;
2082
+ return Boolean(value);
2083
+ }
2084
+ //#endregion
2085
+ //#region src/cli/helpers/options/resolve.ts
970
2086
  function resolveCliCwd(value) {
971
- const raw = readStringOption("cwd", value);
972
- if (!raw) {
973
- return void 0;
974
- }
975
- return path13.isAbsolute(raw) ? path13.normalize(raw) : path13.resolve(process13.cwd(), raw);
976
- }
977
-
978
- // src/cli/helpers/patch-cwd.ts
979
- import path14 from "path";
980
- import process14 from "process";
981
-
982
- // src/tailwindcss/index.ts
983
- import { getPackageInfoSync } from "local-pkg";
2087
+ const raw = readStringOption("cwd", value);
2088
+ if (!raw) return;
2089
+ return path.isAbsolute(raw) ? path.normalize(raw) : path.resolve(process.cwd(), raw);
2090
+ }
2091
+ //#endregion
2092
+ //#region src/tailwindcss/index.ts
984
2093
  function getTailwindcssPackageInfo(options) {
985
- return getPackageInfoSync("tailwindcss", options);
2094
+ return getPackageInfoSync("tailwindcss", options);
986
2095
  }
987
-
988
- // src/cli/helpers/patch-cwd.ts
2096
+ //#endregion
2097
+ //#region src/cli/helpers/patch-cwd.ts
2098
+ /**
2099
+ * Resolve default working directory for `weapp-tw patch`.
2100
+ * Prefer explicit env overrides to avoid cross-package INIT_CWD pollution.
2101
+ */
989
2102
  function normalizeCandidatePath(baseDir, candidate) {
990
- if (!candidate) {
991
- return void 0;
992
- }
993
- return path14.isAbsolute(candidate) ? path14.normalize(candidate) : path14.resolve(baseDir, candidate);
2103
+ if (!candidate) return;
2104
+ return path.isAbsolute(candidate) ? path.normalize(candidate) : path.resolve(baseDir, candidate);
994
2105
  }
995
2106
  function detectTailwindWorkspace(paths) {
996
- for (const candidate of paths) {
997
- try {
998
- const info = getTailwindcssPackageInfo({ paths: [candidate] });
999
- if (info?.rootPath) {
1000
- return candidate;
1001
- }
1002
- } catch {
1003
- }
1004
- }
1005
- return void 0;
1006
- }
1007
- function resolvePatchDefaultCwd(currentCwd = process14.cwd()) {
1008
- const baseDir = path14.normalize(currentCwd);
1009
- const explicitCwd = normalizeCandidatePath(baseDir, process14.env.WEAPP_TW_PATCH_CWD);
1010
- if (explicitCwd) {
1011
- return explicitCwd;
1012
- }
1013
- const workspaceRoot = findWorkspaceRoot(baseDir);
1014
- const initCwd = normalizeCandidatePath(baseDir, process14.env.INIT_CWD);
1015
- const localPrefix = normalizeCandidatePath(baseDir, process14.env.npm_config_local_prefix);
1016
- const candidates = [
1017
- baseDir,
1018
- workspaceRoot,
1019
- initCwd,
1020
- localPrefix
1021
- ].filter(Boolean);
1022
- const detected = detectTailwindWorkspace([...new Set(candidates)]);
1023
- if (detected) {
1024
- return detected;
1025
- }
1026
- return initCwd ?? localPrefix ?? workspaceRoot ?? baseDir;
1027
- }
1028
-
1029
- // src/cli/helpers.ts
2107
+ for (const candidate of paths) try {
2108
+ if (getTailwindcssPackageInfo({ paths: [candidate] })?.rootPath) return candidate;
2109
+ } catch {}
2110
+ }
2111
+ function resolvePatchDefaultCwd(currentCwd = process.cwd()) {
2112
+ const baseDir = path.normalize(currentCwd);
2113
+ const explicitCwd = normalizeCandidatePath(baseDir, process.env.WEAPP_TW_PATCH_CWD);
2114
+ if (explicitCwd) return explicitCwd;
2115
+ const workspaceRoot = findWorkspaceRoot(baseDir);
2116
+ const initCwd = normalizeCandidatePath(baseDir, process.env.INIT_CWD);
2117
+ const localPrefix = normalizeCandidatePath(baseDir, process.env.npm_config_local_prefix);
2118
+ const candidates = [
2119
+ baseDir,
2120
+ workspaceRoot,
2121
+ initCwd,
2122
+ localPrefix
2123
+ ].filter(Boolean);
2124
+ const detected = detectTailwindWorkspace([...new Set(candidates)]);
2125
+ if (detected) return detected;
2126
+ return initCwd ?? localPrefix ?? workspaceRoot ?? baseDir;
2127
+ }
2128
+ //#endregion
2129
+ //#region src/cli/helpers.ts
1030
2130
  async function ensureDir(dir) {
1031
- await mkdir2(dir, { recursive: true });
2131
+ await mkdir(dir, { recursive: true });
1032
2132
  }
1033
- function handleCliError(error) {
1034
- if (error instanceof Error) {
1035
- logger12.error(error.message);
1036
- if (error.stack && process15.env.WEAPP_TW_DEBUG === "1") {
1037
- logger12.error(error.stack);
1038
- }
1039
- } else {
1040
- logger12.error(String(error));
1041
- }
2133
+ function handleCliError$1(error) {
2134
+ if (error instanceof Error) {
2135
+ logger$1.error(error.message);
2136
+ if (error.stack && process.env.WEAPP_TW_DEBUG === "1") logger$1.error(error.stack);
2137
+ } else logger$1.error(String(error));
1042
2138
  }
1043
2139
  function commandAction(handler) {
1044
- return async (...args) => {
1045
- try {
1046
- await handler(...args);
1047
- } catch (error) {
1048
- handleCliError(error);
1049
- process15.exitCode = 1;
1050
- }
1051
- };
1052
- }
1053
-
1054
- // src/cli/mount-options.ts
1055
- import process17 from "process";
1056
-
1057
- // src/cli/mount-options/patch-status.ts
2140
+ return async (...args) => {
2141
+ try {
2142
+ await handler(...args);
2143
+ } catch (error) {
2144
+ handleCliError$1(error);
2145
+ process.exitCode = 1;
2146
+ }
2147
+ };
2148
+ }
2149
+ //#endregion
2150
+ //#region src/cli/mount-options/patch-status.ts
1058
2151
  function formatStatusFilesHint(files) {
1059
- if (!files?.length) {
1060
- return "";
1061
- }
1062
- return ` (${files.join(", ")})`;
2152
+ if (!files?.length) return "";
2153
+ return ` (${files.join(", ")})`;
1063
2154
  }
1064
2155
  function logPatchStatusReport(report) {
1065
- const applied = report.entries.filter((entry) => entry.status === "applied");
1066
- const pending = report.entries.filter((entry) => entry.status === "not-applied");
1067
- const skipped = report.entries.filter(
1068
- (entry) => entry.status === "skipped" || entry.status === "unsupported"
1069
- );
1070
- const packageLabel = `${report.package.name ?? "tailwindcss"}@${report.package.version ?? "unknown"}`;
1071
- logger12.info(`Patch status for ${packageLabel} (v${report.majorVersion})`);
1072
- if (applied.length) {
1073
- logger12.success("Applied:");
1074
- applied.forEach((entry) => {
1075
- logger12.success(` - ${entry.name}${formatStatusFilesHint(entry.files)}`);
1076
- });
1077
- }
1078
- if (pending.length) {
1079
- logger12.warn("Needs attention:");
1080
- pending.forEach((entry) => {
1081
- const details = entry.reason ? ` - ${entry.reason}` : "";
1082
- logger12.warn(` - ${entry.name}${formatStatusFilesHint(entry.files)}${details}`);
1083
- });
1084
- } else {
1085
- logger12.success("All applicable patches are applied.");
1086
- }
1087
- if (skipped.length) {
1088
- logger12.info("Skipped:");
1089
- skipped.forEach((entry) => {
1090
- const details = entry.reason ? ` - ${entry.reason}` : "";
1091
- logger12.info(` - ${entry.name}${details}`);
1092
- });
1093
- }
1094
- }
1095
-
1096
- // src/cli/patch-options.ts
1097
- var DEFAULT_EXTEND_LENGTH_UNITS_FEATURE = {
1098
- enabled: true,
1099
- units: ["rpx"],
1100
- overwrite: true
2156
+ const applied = report.entries.filter((entry) => entry.status === "applied");
2157
+ const pending = report.entries.filter((entry) => entry.status === "not-applied");
2158
+ const skipped = report.entries.filter((entry) => entry.status === "skipped" || entry.status === "unsupported");
2159
+ const packageLabel = `${report.package.name ?? "tailwindcss"}@${report.package.version ?? "unknown"}`;
2160
+ logger$1.info(`Patch status for ${packageLabel} (v${report.majorVersion})`);
2161
+ if (applied.length) {
2162
+ logger$1.success("Applied:");
2163
+ applied.forEach((entry) => {
2164
+ logger$1.success(` - ${entry.name}${formatStatusFilesHint(entry.files)}`);
2165
+ });
2166
+ }
2167
+ if (pending.length) {
2168
+ logger$1.warn("Needs attention:");
2169
+ pending.forEach((entry) => {
2170
+ const details = entry.reason ? ` - ${entry.reason}` : "";
2171
+ logger$1.warn(` - ${entry.name}${formatStatusFilesHint(entry.files)}${details}`);
2172
+ });
2173
+ } else logger$1.success("All applicable patches are applied.");
2174
+ if (skipped.length) {
2175
+ logger$1.info("Skipped:");
2176
+ skipped.forEach((entry) => {
2177
+ const details = entry.reason ? ` - ${entry.reason}` : "";
2178
+ logger$1.info(` - ${entry.name}${details}`);
2179
+ });
2180
+ }
2181
+ }
2182
+ //#endregion
2183
+ //#region src/cli/patch-options.ts
2184
+ const DEFAULT_EXTEND_LENGTH_UNITS_FEATURE = {
2185
+ enabled: true,
2186
+ units: ["rpx"],
2187
+ overwrite: true
1101
2188
  };
1102
2189
  function withDefaultExtendLengthUnits(options) {
1103
- const normalized = options ?? {};
1104
- const extendLengthUnits = normalized.apply?.extendLengthUnits;
1105
- if (extendLengthUnits == null) {
1106
- return {
1107
- ...normalized,
1108
- apply: {
1109
- ...normalized.apply ?? {},
1110
- extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
1111
- }
1112
- };
1113
- }
1114
- return normalized;
2190
+ const normalized = options ?? {};
2191
+ if (normalized.apply?.extendLengthUnits == null) return {
2192
+ ...normalized,
2193
+ apply: {
2194
+ ...normalized.apply ?? {},
2195
+ extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
2196
+ }
2197
+ };
2198
+ return normalized;
1115
2199
  }
1116
2200
  function buildExtendLengthUnitsOverride(options) {
1117
- const extendLengthUnits = options?.apply?.extendLengthUnits;
1118
- if (extendLengthUnits == null) {
1119
- return {
1120
- apply: {
1121
- ...options?.apply ?? {},
1122
- extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
1123
- }
1124
- };
1125
- }
1126
- return void 0;
1127
- }
1128
-
1129
- // src/cli/workspace.ts
1130
- import path19 from "path";
1131
- import process16 from "process";
1132
-
1133
- // src/cli/workspace/package-dirs.ts
1134
- import { existsSync as existsSync8 } from "fs";
1135
- import path17 from "path";
1136
- import fg from "fast-glob";
1137
-
1138
- // src/cli/workspace/workspace-globs.ts
1139
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
1140
- import path15 from "path";
1141
- import { parse as parseYaml } from "yaml";
1142
-
1143
- // src/cli/workspace/workspace-io.ts
1144
- import { readFileSync as readFileSync4 } from "fs";
2201
+ if (options?.apply?.extendLengthUnits == null) return { apply: {
2202
+ ...options?.apply ?? {},
2203
+ extendLengthUnits: DEFAULT_EXTEND_LENGTH_UNITS_FEATURE
2204
+ } };
2205
+ }
2206
+ //#endregion
2207
+ //#region src/cli/workspace/workspace-io.ts
1145
2208
  function tryReadJson(file) {
1146
- try {
1147
- const content = readFileSync4(file, "utf8");
1148
- return JSON.parse(content);
1149
- } catch {
1150
- return void 0;
1151
- }
1152
- }
1153
-
1154
- // src/cli/workspace/workspace-globs.ts
2209
+ try {
2210
+ const content = readFileSync(file, "utf8");
2211
+ return JSON.parse(content);
2212
+ } catch {
2213
+ return;
2214
+ }
2215
+ }
2216
+ //#endregion
2217
+ //#region src/cli/workspace/workspace-globs.ts
1155
2218
  function parseWorkspaceGlobsFromPackageJson(workspaceRoot) {
1156
- const pkgJsonPath = path15.join(workspaceRoot, "package.json");
1157
- const pkg = tryReadJson(pkgJsonPath);
1158
- if (!pkg?.workspaces) {
1159
- return [];
1160
- }
1161
- if (Array.isArray(pkg.workspaces)) {
1162
- return pkg.workspaces.filter(Boolean);
1163
- }
1164
- if (Array.isArray(pkg.workspaces.packages)) {
1165
- return pkg.workspaces.packages.filter(Boolean);
1166
- }
1167
- return [];
2219
+ const pkg = tryReadJson(path.join(workspaceRoot, "package.json"));
2220
+ if (!pkg?.workspaces) return [];
2221
+ if (Array.isArray(pkg.workspaces)) return pkg.workspaces.filter(Boolean);
2222
+ if (Array.isArray(pkg.workspaces.packages)) return pkg.workspaces.packages.filter(Boolean);
2223
+ return [];
1168
2224
  }
1169
2225
  function parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot) {
1170
- const workspaceFile = path15.join(workspaceRoot, "pnpm-workspace.yaml");
1171
- if (!existsSync6(workspaceFile)) {
1172
- return [];
1173
- }
1174
- try {
1175
- const parsed = parseYaml(readFileSync5(workspaceFile, "utf8"));
1176
- return Array.isArray(parsed?.packages) ? parsed.packages.filter(Boolean) : [];
1177
- } catch {
1178
- return [];
1179
- }
1180
- }
1181
-
1182
- // src/cli/workspace/workspace-lock.ts
1183
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
1184
- import path16 from "path";
1185
- import { parse as parseYaml2 } from "yaml";
2226
+ const workspaceFile = path.join(workspaceRoot, "pnpm-workspace.yaml");
2227
+ if (!existsSync(workspaceFile)) return [];
2228
+ try {
2229
+ const parsed = parse(readFileSync(workspaceFile, "utf8"));
2230
+ return Array.isArray(parsed?.packages) ? parsed.packages.filter(Boolean) : [];
2231
+ } catch {
2232
+ return [];
2233
+ }
2234
+ }
2235
+ //#endregion
2236
+ //#region src/cli/workspace/workspace-lock.ts
1186
2237
  function parseImportersFromLock(workspaceRoot) {
1187
- const lockPath = path16.join(workspaceRoot, "pnpm-lock.yaml");
1188
- if (!existsSync7(lockPath)) {
1189
- return [];
1190
- }
1191
- try {
1192
- const parsed = parseYaml2(readFileSync6(lockPath, "utf8"));
1193
- const importers = parsed?.importers;
1194
- if (!importers) {
1195
- return [];
1196
- }
1197
- return Object.keys(importers).map((key) => {
1198
- if (!key || key === ".") {
1199
- return workspaceRoot;
1200
- }
1201
- return path16.join(workspaceRoot, key);
1202
- });
1203
- } catch {
1204
- return [];
1205
- }
1206
- }
1207
-
1208
- // src/cli/workspace/package-dirs.ts
1209
- var BACKSLASH_RE = /\\/g;
1210
- var TRAILING_SLASH_RE = /\/+$/;
2238
+ const lockPath = path.join(workspaceRoot, "pnpm-lock.yaml");
2239
+ if (!existsSync(lockPath)) return [];
2240
+ try {
2241
+ const importers = parse(readFileSync(lockPath, "utf8"))?.importers;
2242
+ if (!importers) return [];
2243
+ return Object.keys(importers).map((key) => {
2244
+ if (!key || key === ".") return workspaceRoot;
2245
+ return path.join(workspaceRoot, key);
2246
+ });
2247
+ } catch {
2248
+ return [];
2249
+ }
2250
+ }
2251
+ //#endregion
2252
+ //#region src/cli/workspace/package-dirs.ts
2253
+ const BACKSLASH_RE$1 = /\\/g;
2254
+ const TRAILING_SLASH_RE = /\/+$/;
1211
2255
  async function resolveWorkspacePackageDirs(workspaceRoot) {
1212
- const dirs = /* @__PURE__ */ new Set();
1213
- for (const importerDir of parseImportersFromLock(workspaceRoot)) {
1214
- dirs.add(path17.normalize(importerDir));
1215
- }
1216
- if (!dirs.size) {
1217
- let globs = parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot);
1218
- if (!globs.length) {
1219
- globs = parseWorkspaceGlobsFromPackageJson(workspaceRoot);
1220
- }
1221
- if (globs.length > 0) {
1222
- const patterns = globs.map((pattern) => {
1223
- const normalized = pattern.replace(BACKSLASH_RE, "/").replace(TRAILING_SLASH_RE, "");
1224
- return normalized.endsWith("package.json") ? normalized : `${normalized}/package.json`;
1225
- });
1226
- const packageJsonFiles = await fg(patterns, {
1227
- cwd: workspaceRoot,
1228
- absolute: true,
1229
- onlyFiles: true,
1230
- unique: true,
1231
- ignore: ["**/node_modules/**", "**/.git/**"]
1232
- });
1233
- for (const file of packageJsonFiles) {
1234
- dirs.add(path17.normalize(path17.dirname(file)));
1235
- }
1236
- }
1237
- }
1238
- const rootPkg = path17.join(workspaceRoot, "package.json");
1239
- if (existsSync8(rootPkg)) {
1240
- dirs.add(path17.normalize(workspaceRoot));
1241
- }
1242
- return [...dirs];
1243
- }
1244
-
1245
- // src/cli/workspace/patch-package.ts
1246
- import { normalizeOptions, TailwindcssPatcher as TailwindcssPatcher2 } from "tailwindcss-patch";
1247
-
1248
- // src/cli/workspace/patch-utils.ts
1249
- import path18 from "path";
2256
+ const dirs = /* @__PURE__ */ new Set();
2257
+ for (const importerDir of parseImportersFromLock(workspaceRoot)) dirs.add(path.normalize(importerDir));
2258
+ if (!dirs.size) {
2259
+ let globs = parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot);
2260
+ if (!globs.length) globs = parseWorkspaceGlobsFromPackageJson(workspaceRoot);
2261
+ if (globs.length > 0) {
2262
+ const packageJsonFiles = await fg(globs.map((pattern) => {
2263
+ const normalized = pattern.replace(BACKSLASH_RE$1, "/").replace(TRAILING_SLASH_RE, "");
2264
+ return normalized.endsWith("package.json") ? normalized : `${normalized}/package.json`;
2265
+ }), {
2266
+ cwd: workspaceRoot,
2267
+ absolute: true,
2268
+ onlyFiles: true,
2269
+ unique: true,
2270
+ ignore: ["**/node_modules/**", "**/.git/**"]
2271
+ });
2272
+ for (const file of packageJsonFiles) dirs.add(path.normalize(path.dirname(file)));
2273
+ }
2274
+ }
2275
+ if (existsSync(path.join(workspaceRoot, "package.json"))) dirs.add(path.normalize(workspaceRoot));
2276
+ return [...dirs];
2277
+ }
2278
+ //#endregion
2279
+ //#region src/cli/workspace/patch-utils.ts
1250
2280
  function formatDisplayName(workspaceRoot, dir, name) {
1251
- const relative = path18.relative(workspaceRoot, dir) || ".";
1252
- return name ? `${name} (${relative})` : relative;
2281
+ const relative = path.relative(workspaceRoot, dir) || ".";
2282
+ return name ? `${name} (${relative})` : relative;
1253
2283
  }
1254
2284
  function summarizeWorkspaceResults(results) {
1255
- const patched = results.filter((result) => result.status === "patched").length;
1256
- const skipped = results.filter((result) => result.status === "skipped").length;
1257
- const failed = results.filter((result) => result.status === "failed").length;
1258
- logger12.info("[workspace] \u6C47\u603B\uFF1A\u5DF2\u8865\u4E01 %d\uFF0C\u8DF3\u8FC7 %d\uFF0C\u5931\u8D25 %d", patched, skipped, failed);
2285
+ const patched = results.filter((result) => result.status === "patched").length;
2286
+ const skipped = results.filter((result) => result.status === "skipped").length;
2287
+ const failed = results.filter((result) => result.status === "failed").length;
2288
+ logger$1.info("[workspace] 汇总:已补丁 %d,跳过 %d,失败 %d", patched, skipped, failed);
1259
2289
  }
1260
-
1261
- // src/cli/workspace/patch-package.ts
2290
+ //#endregion
2291
+ //#region src/cli/workspace/patch-package.ts
1262
2292
  function createWorkspacePatcher(cwd) {
1263
- const normalized = normalizeOptions(
1264
- withDefaultExtendLengthUnits({
1265
- projectRoot: cwd
1266
- })
1267
- );
1268
- return new TailwindcssPatcher2(normalized);
2293
+ return new TailwindcssPatcher(normalizeOptions(withDefaultExtendLengthUnits({ projectRoot: cwd })));
1269
2294
  }
1270
2295
  async function patchWorkspacePackage(workspaceRoot, dir, pkgName, options) {
1271
- const displayName = formatDisplayName(workspaceRoot, dir, pkgName);
1272
- const tailwindInfo = getTailwindcssPackageInfo({ paths: [dir] });
1273
- if (!tailwindInfo?.rootPath) {
1274
- logger12.info("[workspace] \u8DF3\u8FC7 %s\uFF08tailwindcss \u672A\u5B89\u88C5\uFF09\u3002", displayName);
1275
- return {
1276
- dir,
1277
- name: pkgName,
1278
- status: "skipped",
1279
- message: "tailwindcss \u672A\u5B89\u88C5\uFF0C\u5DF2\u8DF3\u8FC7\u3002"
1280
- };
1281
- }
1282
- try {
1283
- const patcher = createWorkspacePatcher(dir);
1284
- if (options.clearCache) {
1285
- await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
1286
- }
1287
- const recorder = createPatchTargetRecorder(dir, patcher, {
1288
- source: "cli",
1289
- cwd: dir,
1290
- recordTarget: options.recordTarget !== false,
1291
- alwaysRecord: true
1292
- });
1293
- if (recorder?.message) {
1294
- logger12.info("[workspace] %s %s", displayName, recorder.message);
1295
- }
1296
- logTailwindcssTarget("cli", patcher, dir);
1297
- await patcher.patch();
1298
- if (recorder?.onPatched) {
1299
- await recorder.onPatched();
1300
- }
1301
- logger12.success("[workspace] \u5DF2\u8865\u4E01 %s", displayName);
1302
- return {
1303
- dir,
1304
- name: pkgName,
1305
- status: "patched",
1306
- message: "\u5DF2\u5B8C\u6210 patch\u3002"
1307
- };
1308
- } catch (error) {
1309
- const reason = error instanceof Error ? error.message : String(error);
1310
- const suggestion = `\u8BF7\u5728 ${dir} \u8FD0\u884C "weapp-tw patch --cwd ${dir}".`;
1311
- const message = `${reason}\uFF0C${suggestion}`;
1312
- logger12.error("[workspace] \u8865\u4E01\u5931\u8D25 %s\uFF1A%s", displayName, message);
1313
- return {
1314
- dir,
1315
- name: pkgName,
1316
- status: "failed",
1317
- message
1318
- };
1319
- }
1320
- }
1321
-
1322
- // src/cli/workspace.ts
2296
+ const displayName = formatDisplayName(workspaceRoot, dir, pkgName);
2297
+ if (!getTailwindcssPackageInfo({ paths: [dir] })?.rootPath) {
2298
+ logger$1.info("[workspace] 跳过 %s(tailwindcss 未安装)。", displayName);
2299
+ return {
2300
+ dir,
2301
+ name: pkgName,
2302
+ status: "skipped",
2303
+ message: "tailwindcss 未安装,已跳过。"
2304
+ };
2305
+ }
2306
+ try {
2307
+ const patcher = createWorkspacePatcher(dir);
2308
+ if (options.clearCache) await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
2309
+ const recorder = createPatchTargetRecorder(dir, patcher, {
2310
+ source: "cli",
2311
+ cwd: dir,
2312
+ recordTarget: options.recordTarget !== false,
2313
+ alwaysRecord: true
2314
+ });
2315
+ if (recorder?.message) logger$1.info("[workspace] %s %s", displayName, recorder.message);
2316
+ logTailwindcssTarget("cli", patcher, dir);
2317
+ await patcher.patch();
2318
+ if (recorder?.onPatched) await recorder.onPatched();
2319
+ logger$1.success("[workspace] 已补丁 %s", displayName);
2320
+ return {
2321
+ dir,
2322
+ name: pkgName,
2323
+ status: "patched",
2324
+ message: "已完成 patch。"
2325
+ };
2326
+ } catch (error) {
2327
+ const message = `${error instanceof Error ? error.message : String(error)},${`请在 ${dir} 运行 "weapp-tw patch --cwd ${dir}".`}`;
2328
+ logger$1.error("[workspace] 补丁失败 %s:%s", displayName, message);
2329
+ return {
2330
+ dir,
2331
+ name: pkgName,
2332
+ status: "failed",
2333
+ message
2334
+ };
2335
+ }
2336
+ }
2337
+ //#endregion
2338
+ //#region src/cli/workspace.ts
1323
2339
  async function patchWorkspace(options) {
1324
- const cwd = options.cwd ?? process16.cwd();
1325
- const workspaceRoot = findWorkspaceRoot(cwd) ?? cwd;
1326
- const packageDirs = await resolveWorkspacePackageDirs(workspaceRoot);
1327
- if (packageDirs.length === 0) {
1328
- logger12.warn("\u672A\u5728 %s \u68C0\u6D4B\u5230 workspace \u5305\uFF0C\u5DF2\u8DF3\u8FC7\u6279\u91CF patch\u3002", workspaceRoot);
1329
- return;
1330
- }
1331
- const results = [];
1332
- for (const dir of packageDirs) {
1333
- const pkgJsonPath = path19.join(dir, "package.json");
1334
- const pkgJson = tryReadJson(pkgJsonPath);
1335
- results.push(await patchWorkspacePackage(workspaceRoot, dir, pkgJson?.name, options));
1336
- }
1337
- summarizeWorkspaceResults(results);
1338
- }
1339
-
1340
- // src/cli/mount-options.ts
1341
- function handleCliError2(error) {
1342
- if (error instanceof Error) {
1343
- logger12.error(error.message);
1344
- if (error.stack && process17.env.WEAPP_TW_DEBUG === "1") {
1345
- logger12.error(error.stack);
1346
- }
1347
- } else {
1348
- logger12.error(String(error));
1349
- }
2340
+ const cwd = options.cwd ?? process.cwd();
2341
+ const workspaceRoot = findWorkspaceRoot(cwd) ?? cwd;
2342
+ const packageDirs = await resolveWorkspacePackageDirs(workspaceRoot);
2343
+ if (packageDirs.length === 0) {
2344
+ logger$1.warn("未在 %s 检测到 workspace 包,已跳过批量 patch", workspaceRoot);
2345
+ return;
2346
+ }
2347
+ const results = [];
2348
+ for (const dir of packageDirs) {
2349
+ const pkgJson = tryReadJson(path.join(dir, "package.json"));
2350
+ results.push(await patchWorkspacePackage(workspaceRoot, dir, pkgJson?.name, options));
2351
+ }
2352
+ summarizeWorkspaceResults(results);
2353
+ }
2354
+ //#endregion
2355
+ //#region src/cli/mount-options.ts
2356
+ function handleCliError(error) {
2357
+ if (error instanceof Error) {
2358
+ logger$1.error(error.message);
2359
+ if (error.stack && process.env.WEAPP_TW_DEBUG === "1") logger$1.error(error.stack);
2360
+ } else logger$1.error(String(error));
1350
2361
  }
1351
2362
  function withCommandErrorHandling(handler) {
1352
- return (async (ctx, next) => {
1353
- try {
1354
- return await handler(ctx, next);
1355
- } catch (error) {
1356
- handleCliError2(error);
1357
- process17.exitCode = 1;
1358
- return void 0;
1359
- }
1360
- });
2363
+ return (async (ctx, next) => {
2364
+ try {
2365
+ return await handler(ctx, next);
2366
+ } catch (error) {
2367
+ handleCliError(error);
2368
+ process.exitCode = 1;
2369
+ return;
2370
+ }
2371
+ });
1361
2372
  }
1362
2373
  async function createPatcherWithDefaultExtendLengthUnits(ctx) {
1363
- const patchOptions = await ctx.loadPatchOptions();
1364
- const extendLengthUnitsOverride = buildExtendLengthUnitsOverride(patchOptions);
1365
- if (extendLengthUnitsOverride) {
1366
- return ctx.createPatcher(extendLengthUnitsOverride);
1367
- }
1368
- return ctx.createPatcher();
1369
- }
1370
- var mountOptions = {
1371
- commandOptions: {
1372
- install: {
1373
- name: "patch",
1374
- aliases: ["install"],
1375
- appendDefaultOptions: false,
1376
- optionDefs: [
1377
- {
1378
- flags: "--cwd <dir>",
1379
- description: "Working directory",
1380
- config: { default: resolvePatchDefaultCwd() }
1381
- },
1382
- {
1383
- flags: "--record-target",
1384
- description: 'Write tailwindcss target metadata (node_modules/.cache/weapp-tailwindcss/tailwindcss-target.json). Pass "--record-target false" to skip.',
1385
- config: { default: true }
1386
- },
1387
- {
1388
- flags: "--clear-cache",
1389
- description: "Clear tailwindcss-patch cache before patch (opt-in)"
1390
- },
1391
- {
1392
- flags: "--workspace",
1393
- description: "Scan pnpm workspace packages and patch each Tailwind CSS dependency"
1394
- }
1395
- ]
1396
- },
1397
- status: {
1398
- appendDefaultOptions: false,
1399
- optionDefs: [
1400
- {
1401
- flags: "--cwd <dir>",
1402
- description: "Working directory",
1403
- config: { default: resolvePatchDefaultCwd() }
1404
- },
1405
- {
1406
- flags: "--json",
1407
- description: "Print a JSON report of patch status"
1408
- }
1409
- ]
1410
- }
1411
- },
1412
- commandHandlers: {
1413
- install: withCommandErrorHandling(async (ctx) => {
1414
- const shouldClearCache = toBoolean(ctx.args.clearCache, false);
1415
- const shouldRecordTarget = toBoolean(ctx.args.recordTarget, true);
1416
- const runWorkspace = toBoolean(ctx.args.workspace, false);
1417
- if (runWorkspace) {
1418
- await patchWorkspace({
1419
- cwd: ctx.cwd,
1420
- clearCache: shouldClearCache,
1421
- recordTarget: shouldRecordTarget
1422
- });
1423
- return;
1424
- }
1425
- const patcher = await createPatcherWithDefaultExtendLengthUnits(ctx);
1426
- if (shouldClearCache) {
1427
- await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
1428
- }
1429
- const recorder = createPatchTargetRecorder(ctx.cwd, patcher, {
1430
- source: "cli",
1431
- cwd: ctx.cwd,
1432
- recordTarget: shouldRecordTarget,
1433
- alwaysRecord: true
1434
- });
1435
- if (recorder?.message) {
1436
- logger12.info(recorder.message);
1437
- }
1438
- logTailwindcssTarget("cli", patcher, ctx.cwd);
1439
- await patcher.patch();
1440
- if (recorder?.onPatched) {
1441
- const recordPath = await recorder.onPatched();
1442
- if (recordPath) {
1443
- logger12.info(`\u8BB0\u5F55 weapp-tw patch \u76EE\u6807 -> ${formatOutputPath(recordPath, ctx.cwd)}`);
1444
- }
1445
- }
1446
- logger12.success("Tailwind CSS \u8FD0\u884C\u65F6\u8865\u4E01\u5DF2\u5B8C\u6210\u3002");
1447
- }),
1448
- extract: withCommandErrorHandling(async (_ctx, next) => next()),
1449
- tokens: withCommandErrorHandling(async (_ctx, next) => next()),
1450
- init: withCommandErrorHandling(async (_ctx, next) => next()),
1451
- status: withCommandErrorHandling(async (ctx) => {
1452
- const patcher = await createPatcherWithDefaultExtendLengthUnits(ctx);
1453
- const report = await patcher.getPatchStatus();
1454
- if (ctx.args.json) {
1455
- logger12.log(JSON.stringify(report, null, 2));
1456
- return report;
1457
- }
1458
- logPatchStatusReport(report);
1459
- return report;
1460
- })
1461
- }
2374
+ const extendLengthUnitsOverride = buildExtendLengthUnitsOverride(await ctx.loadPatchOptions());
2375
+ if (extendLengthUnitsOverride) return ctx.createPatcher(extendLengthUnitsOverride);
2376
+ return ctx.createPatcher();
2377
+ }
2378
+ const mountOptions = {
2379
+ commandOptions: {
2380
+ install: {
2381
+ name: "patch",
2382
+ aliases: ["install"],
2383
+ appendDefaultOptions: false,
2384
+ optionDefs: [
2385
+ {
2386
+ flags: "--cwd <dir>",
2387
+ description: "Working directory",
2388
+ config: { default: resolvePatchDefaultCwd() }
2389
+ },
2390
+ {
2391
+ flags: "--record-target",
2392
+ description: "Write tailwindcss target metadata (node_modules/.cache/weapp-tailwindcss/tailwindcss-target.json). Pass \"--record-target false\" to skip.",
2393
+ config: { default: true }
2394
+ },
2395
+ {
2396
+ flags: "--clear-cache",
2397
+ description: "Clear tailwindcss-patch cache before patch (opt-in)"
2398
+ },
2399
+ {
2400
+ flags: "--workspace",
2401
+ description: "Scan pnpm workspace packages and patch each Tailwind CSS dependency"
2402
+ }
2403
+ ]
2404
+ },
2405
+ status: {
2406
+ appendDefaultOptions: false,
2407
+ optionDefs: [{
2408
+ flags: "--cwd <dir>",
2409
+ description: "Working directory",
2410
+ config: { default: resolvePatchDefaultCwd() }
2411
+ }, {
2412
+ flags: "--json",
2413
+ description: "Print a JSON report of patch status"
2414
+ }]
2415
+ }
2416
+ },
2417
+ commandHandlers: {
2418
+ install: withCommandErrorHandling(async (ctx) => {
2419
+ const shouldClearCache = toBoolean(ctx.args.clearCache, false);
2420
+ const shouldRecordTarget = toBoolean(ctx.args.recordTarget, true);
2421
+ if (toBoolean(ctx.args.workspace, false)) {
2422
+ await patchWorkspace({
2423
+ cwd: ctx.cwd,
2424
+ clearCache: shouldClearCache,
2425
+ recordTarget: shouldRecordTarget
2426
+ });
2427
+ return;
2428
+ }
2429
+ const patcher = await createPatcherWithDefaultExtendLengthUnits(ctx);
2430
+ if (shouldClearCache) await clearTailwindcssPatcherCache(patcher, { removeDirectory: true });
2431
+ const recorder = createPatchTargetRecorder(ctx.cwd, patcher, {
2432
+ source: "cli",
2433
+ cwd: ctx.cwd,
2434
+ recordTarget: shouldRecordTarget,
2435
+ alwaysRecord: true
2436
+ });
2437
+ if (recorder?.message) logger$1.info(recorder.message);
2438
+ logTailwindcssTarget("cli", patcher, ctx.cwd);
2439
+ await patcher.patch();
2440
+ if (recorder?.onPatched) {
2441
+ const recordPath = await recorder.onPatched();
2442
+ if (recordPath) logger$1.info(`记录 weapp-tw patch 目标 -> ${formatOutputPath(recordPath, ctx.cwd)}`);
2443
+ }
2444
+ logger$1.success("Tailwind CSS 运行时补丁已完成。");
2445
+ }),
2446
+ extract: withCommandErrorHandling(async (_ctx, next) => next()),
2447
+ tokens: withCommandErrorHandling(async (_ctx, next) => next()),
2448
+ init: withCommandErrorHandling(async (_ctx, next) => next()),
2449
+ status: withCommandErrorHandling(async (ctx) => {
2450
+ const report = await (await createPatcherWithDefaultExtendLengthUnits(ctx)).getPatchStatus();
2451
+ if (ctx.args.json) {
2452
+ logger$1.log(JSON.stringify(report, null, 2));
2453
+ return report;
2454
+ }
2455
+ logPatchStatusReport(report);
2456
+ return report;
2457
+ })
2458
+ }
1462
2459
  };
1463
-
1464
- // src/cli/vscode-entry.ts
1465
- import { constants } from "fs";
1466
- import { access, writeFile as writeFile2 } from "fs/promises";
1467
- import path20 from "path";
1468
- var DEFAULT_VSCODE_ENTRY_OUTPUT = ".vscode/weapp-tailwindcss.intellisense.css";
1469
- var DEFAULT_VSCODE_SOURCES = [
1470
- 'not "./dist"',
1471
- 'not "./unpackage"',
1472
- "./src/**/*.{wxml,axml,swan,qml,ttml,ux,uts}",
1473
- "./src/**/*.{js,jsx,ts,tsx}",
1474
- "./src/**/*.{vue,svelte,html,md,mdx}"
2460
+ //#endregion
2461
+ //#region src/cli/vscode-entry.ts
2462
+ const DEFAULT_VSCODE_ENTRY_OUTPUT = ".vscode/weapp-tailwindcss.intellisense.css";
2463
+ const DEFAULT_VSCODE_SOURCES = [
2464
+ "not \"./dist\"",
2465
+ "not \"./unpackage\"",
2466
+ "./src/**/*.{wxml,axml,swan,qml,ttml,ux,uts}",
2467
+ "./src/**/*.{js,jsx,ts,tsx,mjs,cjs,wxs,sjs}",
2468
+ "./src/**/*.{vue,svelte,mpx,html,md,mdx}"
1475
2469
  ];
1476
- var SINGLE_QUOTE = "'";
1477
- var DOUBLE_QUOTE = '"';
1478
- var BACKSLASH_RE2 = /\\/g;
2470
+ const SINGLE_QUOTE = "'";
2471
+ const DOUBLE_QUOTE = "\"";
2472
+ const BACKSLASH_RE = /\\/g;
1479
2473
  function toPosixPath(filepath) {
1480
- return filepath.replace(BACKSLASH_RE2, "/");
2474
+ return filepath.replace(BACKSLASH_RE, "/");
1481
2475
  }
1482
2476
  async function assertFileExists(filepath) {
1483
- try {
1484
- await access(filepath, constants.F_OK);
1485
- } catch (error) {
1486
- const err = error;
1487
- if (err?.code === "ENOENT") {
1488
- throw new Error(`CSS entry file not found: ${filepath}`);
1489
- }
1490
- throw err;
1491
- }
2477
+ try {
2478
+ await access(filepath, constants.F_OK);
2479
+ } catch (error) {
2480
+ const err = error;
2481
+ if (err?.code === "ENOENT") throw new Error(`CSS entry file not found: ${filepath}`);
2482
+ throw err;
2483
+ }
1492
2484
  }
1493
2485
  async function assertCanWrite(filepath, force) {
1494
- try {
1495
- await access(filepath, constants.F_OK);
1496
- if (!force) {
1497
- throw new Error(
1498
- `VS Code helper already exists at ${filepath}. Re-run with --force to overwrite it.`
1499
- );
1500
- }
1501
- } catch (error) {
1502
- const err = error;
1503
- if (err?.code === "ENOENT") {
1504
- return;
1505
- }
1506
- throw err;
1507
- }
2486
+ try {
2487
+ await access(filepath, constants.F_OK);
2488
+ if (!force) throw new Error(`VS Code helper already exists at ${filepath}. Re-run with --force to overwrite it.`);
2489
+ } catch (error) {
2490
+ const err = error;
2491
+ if (err?.code === "ENOENT") return;
2492
+ throw err;
2493
+ }
1508
2494
  }
1509
2495
  function toCssLiteral(value) {
1510
- const normalized = toPosixPath(value);
1511
- return JSON.stringify(normalized);
2496
+ const normalized = toPosixPath(value);
2497
+ return JSON.stringify(normalized);
1512
2498
  }
1513
2499
  function formatSource(pattern) {
1514
- const trimmed = pattern.trim();
1515
- if (!trimmed) {
1516
- return null;
1517
- }
1518
- if (trimmed.startsWith("@source ")) {
1519
- return trimmed.endsWith(";") ? trimmed : `${trimmed};`;
1520
- }
1521
- let body = trimmed;
1522
- let keyword = "";
1523
- if (body.startsWith("not ")) {
1524
- keyword = "not ";
1525
- body = body.slice(4).trim();
1526
- } else if (body.startsWith("!")) {
1527
- keyword = "not ";
1528
- body = body.slice(1).trim();
1529
- }
1530
- if (!body) {
1531
- throw new Error("Invalid @source pattern: empty body.");
1532
- }
1533
- if (!body.startsWith(SINGLE_QUOTE) && !body.startsWith(DOUBLE_QUOTE)) {
1534
- body = toCssLiteral(body);
1535
- }
1536
- return `@source ${keyword}${body};`;
2500
+ const trimmed = pattern.trim();
2501
+ if (!trimmed) return null;
2502
+ if (trimmed.startsWith("@source ")) return trimmed.endsWith(";") ? trimmed : `${trimmed};`;
2503
+ let body = trimmed;
2504
+ let keyword = "";
2505
+ if (body.startsWith("not ")) {
2506
+ keyword = "not ";
2507
+ body = body.slice(4).trim();
2508
+ } else if (body.startsWith("!")) {
2509
+ keyword = "not ";
2510
+ body = body.slice(1).trim();
2511
+ }
2512
+ if (!body) throw new Error("Invalid @source pattern: empty body.");
2513
+ if (!body.startsWith(SINGLE_QUOTE) && !body.startsWith(DOUBLE_QUOTE)) body = toCssLiteral(body);
2514
+ return `@source ${keyword}${body};`;
1537
2515
  }
1538
2516
  function resolveOutputPath(baseDir, output) {
1539
- const target = output ?? DEFAULT_VSCODE_ENTRY_OUTPUT;
1540
- return path20.isAbsolute(target) ? path20.normalize(target) : path20.resolve(baseDir, target);
2517
+ const target = output ?? ".vscode/weapp-tailwindcss.intellisense.css";
2518
+ return path.isAbsolute(target) ? path.normalize(target) : path.resolve(baseDir, target);
1541
2519
  }
1542
2520
  function resolveCssEntry(baseDir, entry) {
1543
- return path20.isAbsolute(entry) ? path20.normalize(entry) : path20.resolve(baseDir, entry);
2521
+ return path.isAbsolute(entry) ? path.normalize(entry) : path.resolve(baseDir, entry);
1544
2522
  }
1545
2523
  function toRelativeImport(fromFile, targetFile) {
1546
- const fromDir = path20.dirname(fromFile);
1547
- let relative = path20.relative(fromDir, targetFile);
1548
- if (!relative) {
1549
- relative = path20.basename(targetFile);
1550
- }
1551
- if (!relative.startsWith(".")) {
1552
- relative = `./${relative}`;
1553
- }
1554
- return toPosixPath(relative);
2524
+ const fromDir = path.dirname(fromFile);
2525
+ let relative = path.relative(fromDir, targetFile);
2526
+ if (!relative) relative = path.basename(targetFile);
2527
+ if (!relative.startsWith(".")) relative = `./${relative}`;
2528
+ return toPosixPath(relative);
1555
2529
  }
1556
2530
  async function generateVscodeIntellisenseEntry(options) {
1557
- const baseDir = options.baseDir;
1558
- const cssEntryPath = resolveCssEntry(baseDir, options.cssEntry);
1559
- await assertFileExists(cssEntryPath);
1560
- const outputPath = resolveOutputPath(baseDir, options.output);
1561
- await ensureDir(path20.dirname(outputPath));
1562
- await assertCanWrite(outputPath, options.force);
1563
- const sources = options.sources && options.sources.length > 0 ? options.sources : DEFAULT_VSCODE_SOURCES;
1564
- const formattedSources = sources.map(formatSource).filter((statement) => Boolean(statement));
1565
- const cssImport = toRelativeImport(outputPath, cssEntryPath);
1566
- const separator = formattedSources.length > 0 ? [""] : [];
1567
- const content = [
1568
- "/*",
1569
- " * Auto-generated by weapp-tailwindcss.",
1570
- " * This file exists solely to activate Tailwind CSS IntelliSense in VS Code.",
1571
- " * Do not import it in your actual mini-program bundles.",
1572
- " */",
1573
- "@import 'tailwindcss';",
1574
- "",
1575
- ...formattedSources,
1576
- ...separator,
1577
- `@import '${cssImport}';`,
1578
- ""
1579
- ].filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join("\n");
1580
- await writeFile2(outputPath, `${content}
1581
- `, "utf8");
1582
- return { outputPath, cssEntryPath };
1583
- }
1584
-
1585
- // src/cli.ts
1586
- process18.title = "node (weapp-tailwindcss)";
1587
- if (semver.lt(process18.versions.node, WEAPP_TW_REQUIRED_NODE_VERSION)) {
1588
- logger12.warn(
1589
- `You are using Node.js ${process18.versions.node}. For weapp-tailwindcss, Node.js version >= v${WEAPP_TW_REQUIRED_NODE_VERSION} is required.`
1590
- );
1591
- }
1592
- var cli = createTailwindcssPatchCli({
1593
- name: "weapp-tailwindcss",
1594
- mountOptions
2531
+ const baseDir = options.baseDir;
2532
+ const cssEntryPath = resolveCssEntry(baseDir, options.cssEntry);
2533
+ await assertFileExists(cssEntryPath);
2534
+ const outputPath = resolveOutputPath(baseDir, options.output);
2535
+ await ensureDir(path.dirname(outputPath));
2536
+ await assertCanWrite(outputPath, options.force);
2537
+ const formattedSources = (options.sources && options.sources.length > 0 ? options.sources : DEFAULT_VSCODE_SOURCES).map(formatSource).filter((statement) => Boolean(statement));
2538
+ const cssImport = toRelativeImport(outputPath, cssEntryPath);
2539
+ const separator = formattedSources.length > 0 ? [""] : [];
2540
+ await writeFile(outputPath, `${[
2541
+ "/*",
2542
+ " * Auto-generated by weapp-tailwindcss.",
2543
+ " * This file exists solely to activate Tailwind CSS IntelliSense in VS Code.",
2544
+ " * Do not import it in your actual mini-program bundles.",
2545
+ " */",
2546
+ "@import 'tailwindcss';",
2547
+ "",
2548
+ ...formattedSources,
2549
+ ...separator,
2550
+ `@import '${cssImport}';`,
2551
+ ""
2552
+ ].filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join("\n")}\n`, "utf8");
2553
+ return {
2554
+ outputPath,
2555
+ cssEntryPath
2556
+ };
2557
+ }
2558
+ //#endregion
2559
+ //#region src/cli.ts
2560
+ process.title = "node (weapp-tailwindcss)";
2561
+ if (!semver.satisfies(process.versions.node, "^20.19.0 || >=22.12.0")) logger$1.warn(`You are using Node.js ${process.versions.node}. For weapp-tailwindcss, Node.js version ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE} is required.`);
2562
+ const cli = createTailwindcssPatchCli({
2563
+ name: "weapp-tailwindcss",
2564
+ mountOptions
1595
2565
  });
1596
- cli.command("vscode-entry", "Generate a VS Code helper CSS for Tailwind IntelliSense").option("--cwd <dir>", "Working directory").option("--css <file>", "Path to the CSS file that imports weapp-tailwindcss (required)").option("--output <file>", `Helper output path. Defaults to ${DEFAULT_VSCODE_ENTRY_OUTPUT}`).option("--source <pattern>", "Additional @source glob (can be repeated)").option("--force", "Overwrite the helper file when it already exists").action(
1597
- commandAction(async (options) => {
1598
- const resolvedCwd = resolveCliCwd(options.cwd);
1599
- const baseDir = resolvedCwd ?? process18.cwd();
1600
- const cssEntry = readStringOption("css", options.css);
1601
- if (!cssEntry) {
1602
- throw new Error('Option "--css" is required.');
1603
- }
1604
- const output = readStringOption("output", options.output);
1605
- const sources = readStringArrayOption("source", options.source);
1606
- const force = toBoolean(options.force, false);
1607
- const result = await generateVscodeIntellisenseEntry({
1608
- baseDir,
1609
- cssEntry,
1610
- output,
1611
- sources,
1612
- force
1613
- });
1614
- logger12.success(
1615
- `VS Code helper generated -> ${formatOutputPath(result.outputPath, resolvedCwd)}`
1616
- );
1617
- })
1618
- );
2566
+ cli.command("vscode-entry", "Generate a VS Code helper CSS for Tailwind IntelliSense").option("--cwd <dir>", "Working directory").option("--css <file>", "Path to the CSS file that imports weapp-tailwindcss (required)").option("--output <file>", `Helper output path. Defaults to ${DEFAULT_VSCODE_ENTRY_OUTPUT}`).option("--source <pattern>", "Additional @source glob (can be repeated)").option("--force", "Overwrite the helper file when it already exists").action(commandAction(async (options) => {
2567
+ const resolvedCwd = resolveCliCwd(options.cwd);
2568
+ const baseDir = resolvedCwd ?? process.cwd();
2569
+ const cssEntry = readStringOption("css", options.css);
2570
+ if (!cssEntry) throw new Error("Option \"--css\" is required.");
2571
+ const result = await generateVscodeIntellisenseEntry({
2572
+ baseDir,
2573
+ cssEntry,
2574
+ output: readStringOption("output", options.output),
2575
+ sources: readStringArrayOption("source", options.source),
2576
+ force: toBoolean(options.force, false)
2577
+ });
2578
+ logger$1.success(`VS Code helper generated -> ${formatOutputPath(result.outputPath, resolvedCwd)}`);
2579
+ }));
2580
+ cli.command("doctor", "Check project setup for weapp-tailwindcss").option("--cwd <dir>", "Working directory").option("--json", "Print a JSON report").option("--strict", "Exit with code 1 when warnings are found").action(commandAction(async (options) => {
2581
+ const report = createDoctorReport({ cwd: resolveCliCwd(options.cwd) });
2582
+ if (toBoolean(options.json, false)) logger$1.log(JSON.stringify(report, null, 2));
2583
+ else logger$1.log(formatDoctorReport(report));
2584
+ if (hasDoctorFailure(report, toBoolean(options.strict, false))) process.exitCode = 1;
2585
+ }));
1619
2586
  cli.help();
1620
- cli.version(process18.env.npm_package_version ?? "0.0.0");
2587
+ cli.version(process.env.npm_package_version ?? "0.0.0");
1621
2588
  cli.parse();
2589
+ //#endregion
2590
+ export {};