weapp-tailwindcss 4.12.0-next.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/bin/weapp-tailwindcss.js +21 -1
  2. package/dist/{chunk-GMKSBLNY.js → chunk-24AGZQVR.js} +15 -7
  3. package/dist/{chunk-F2CKKG6Q.mjs → chunk-3VQKDHGP.mjs} +12 -4
  4. package/dist/{chunk-F5XJWJYO.mjs → chunk-57SOQCAU.mjs} +5 -5
  5. package/dist/{chunk-GD4SQMVF.mjs → chunk-5ZYHNDEK.mjs} +98 -37
  6. package/dist/{chunk-FMK6SFQQ.js → chunk-DUHYLR2R.js} +7 -7
  7. package/dist/{chunk-OYSABARD.js → chunk-E7I5TW5K.js} +3 -2
  8. package/dist/{chunk-WSS26HZS.js → chunk-FS2NOOEB.js} +5 -5
  9. package/dist/{chunk-GC7WXUOW.js → chunk-HVNGIKLS.js} +55 -31
  10. package/dist/{chunk-LVSUBDJC.js → chunk-JZQBZHN5.js} +39 -39
  11. package/dist/{chunk-QNRJCEZN.mjs → chunk-KGTVD4EP.mjs} +66 -42
  12. package/dist/{chunk-HL3US2OT.mjs → chunk-NNOQDMUP.mjs} +1 -1
  13. package/dist/{chunk-5ONE75V7.js → chunk-OFB2KBRP.js} +175 -114
  14. package/dist/{chunk-AYJ4HLWZ.mjs → chunk-PCDYXXSK.mjs} +11 -4
  15. package/dist/{chunk-ONLKZIRQ.js → chunk-RKISS72P.js} +1 -1
  16. package/dist/{chunk-ZR3KN3FG.mjs → chunk-RRQZL7FQ.mjs} +2 -2
  17. package/dist/{chunk-UUJWDME4.mjs → chunk-XZP3MREK.mjs} +1 -1
  18. package/dist/{chunk-NIS74SI6.js → chunk-ZAA5ZG3D.js} +60 -53
  19. package/dist/{chunk-2LH6PZH3.mjs → chunk-ZCH4YINE.mjs} +3 -2
  20. package/dist/cli.js +2241 -169
  21. package/dist/cli.mjs +2246 -174
  22. package/dist/core.js +9 -9
  23. package/dist/core.mjs +3 -3
  24. package/dist/css-macro/postcss.js +4 -4
  25. package/dist/css-macro/postcss.mjs +2 -2
  26. package/dist/css-macro.js +5 -5
  27. package/dist/css-macro.mjs +2 -2
  28. package/dist/defaults.js +1 -1
  29. package/dist/defaults.mjs +1 -1
  30. package/dist/gulp.js +5 -5
  31. package/dist/gulp.mjs +4 -4
  32. package/dist/index.js +9 -9
  33. package/dist/index.mjs +8 -8
  34. package/dist/postcss-html-transform.js +1 -1
  35. package/dist/postcss-html-transform.mjs +1 -1
  36. package/dist/presets.js +6 -6
  37. package/dist/presets.mjs +2 -2
  38. package/dist/reset.js +1 -1
  39. package/dist/reset.mjs +1 -1
  40. package/dist/types.js +1 -1
  41. package/dist/types.mjs +1 -1
  42. package/dist/vite.js +6 -6
  43. package/dist/vite.mjs +5 -5
  44. package/dist/weapp-tw-css-import-rewrite-loader.js +10 -5
  45. package/dist/weapp-tw-runtime-classset-loader.js +9 -4
  46. package/dist/webpack.js +7 -7
  47. package/dist/webpack.mjs +6 -6
  48. package/dist/webpack4.js +59 -55
  49. package/dist/webpack4.mjs +28 -24
  50. package/package.json +11 -10
  51. package/scripts/postinstall.mjs +59 -0
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/cli.ts
2
- import process18 from "process";
3
- import semver from "semver";
2
+ import process19 from "process";
3
+ import semver2 from "semver";
4
4
  import { createTailwindcssPatchCli } from "tailwindcss-patch";
5
5
 
6
6
  // src/cli/context.ts
@@ -132,18 +132,21 @@ function findNearestPackageRoot(startDir) {
132
132
  var PATCH_INFO_FILENAME = "tailwindcss-target.json";
133
133
  var PATCH_INFO_CACHE_RELATIVE_PATH = path3.join("node_modules", ".cache", "weapp-tailwindcss", PATCH_INFO_FILENAME);
134
134
  var PATCH_INFO_LEGACY_RELATIVE_PATH = path3.join(".tw-patch", PATCH_INFO_FILENAME);
135
+ function toDisplayPath(value) {
136
+ return path3.normalize(value).replace(/\\/g, "/");
137
+ }
135
138
  function formatRelativeToBase(targetPath, baseDir) {
136
139
  if (!baseDir) {
137
- return path3.normalize(targetPath);
140
+ return toDisplayPath(targetPath);
138
141
  }
139
142
  const relative = path3.relative(baseDir, targetPath);
140
143
  if (!relative || relative === ".") {
141
144
  return ".";
142
145
  }
143
146
  if (relative.startsWith("..")) {
144
- return path3.normalize(targetPath);
147
+ return toDisplayPath(targetPath);
145
148
  }
146
- return path3.join(".", relative);
149
+ return toDisplayPath(path3.join(".", relative));
147
150
  }
148
151
  function resolveRecordLocation(baseDir) {
149
152
  const normalizedBase = path3.normalize(baseDir);
@@ -184,7 +187,7 @@ import { logger as logger2 } from "@weapp-tailwindcss/logger";
184
187
  // package.json
185
188
  var package_default = {
186
189
  name: "weapp-tailwindcss",
187
- version: "4.12.0-next.0",
190
+ version: "4.12.0",
188
191
  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
192
  author: "ice breaker <1324318532@qq.com>",
190
193
  license: "MIT",
@@ -334,13 +337,14 @@ var package_default = {
334
337
  "dist",
335
338
  "index.css",
336
339
  "preflight.css",
340
+ "scripts/postinstall.mjs",
337
341
  "theme.css",
338
342
  "uni-app-x.css",
339
343
  "utilities.css",
340
344
  "with-layer.css"
341
345
  ],
342
346
  engines: {
343
- node: "^18.17.0 || >=20.5.0"
347
+ node: "^20.19.0 || >=22.12.0"
344
348
  },
345
349
  scripts: {
346
350
  dev: "tsup --watch --sourcemap",
@@ -349,7 +353,7 @@ var package_default = {
349
353
  "build:cli": "cd plugins/cli && pnpm run build",
350
354
  "build:css": "tsx scripts/build-css.ts",
351
355
  "build:weapp-theme": "tsx scripts/build-weapp-theme.ts",
352
- test: "npm run postinstall && vitest run",
356
+ test: "pnpm run cli:patch && vitest run",
353
357
  "test:dev": "vitest",
354
358
  "test:ui": "vitest --ui",
355
359
  bench: "vitest bench --config ./vitest.config.ts",
@@ -366,7 +370,7 @@ var package_default = {
366
370
  release: "tsx scripts/release.ts",
367
371
  lint: "eslint .",
368
372
  "lint:fix": "eslint ./src --fix",
369
- postinstall: "node bin/weapp-tailwindcss.js patch",
373
+ postinstall: "node scripts/postinstall.mjs",
370
374
  "bench:vite-dev-hmr": "tsx scripts/vite-dev-hmr-bench.ts",
371
375
  "test:watch-hmr": "node --import tsx scripts/watch-hmr-regression/index.ts"
372
376
  },
@@ -376,10 +380,10 @@ var package_default = {
376
380
  },
377
381
  dependencies: {
378
382
  "@ast-core/escape": "~1.0.1",
379
- "@babel/parser": "~7.29.2",
383
+ "@babel/parser": "~7.29.3",
380
384
  "@babel/traverse": "~7.29.0",
381
385
  "@babel/types": "~7.29.0",
382
- "@tailwindcss-mangle/config": "^7.0.0",
386
+ "@tailwindcss-mangle/config": "^7.0.1",
383
387
  "@vue/compiler-dom": "catalog:vue3",
384
388
  "@vue/compiler-sfc": "catalog:vue3",
385
389
  "@weapp-core/escape": "~7.0.0",
@@ -400,7 +404,7 @@ var package_default = {
400
404
  semver: "~7.7.4",
401
405
  "tailwindcss-patch": "catalog:tailwindcssPatch",
402
406
  "webpack-sources": "3.3.4",
403
- yaml: "^2.8.3"
407
+ yaml: "^2.8.4"
404
408
  },
405
409
  devDependencies: {
406
410
  "fast-check": "^4.7.0"
@@ -408,7 +412,7 @@ var package_default = {
408
412
  };
409
413
 
410
414
  // src/constants.ts
411
- var WEAPP_TW_REQUIRED_NODE_VERSION = "18.17.0";
415
+ var WEAPP_TW_REQUIRED_NODE_VERSION_RANGE = "^20.19.0 || >=22.12.0";
412
416
  var WEAPP_TW_VERSION = package_default.version;
413
417
 
414
418
  // src/tailwindcss/targets/record-io.ts
@@ -554,114 +558,1904 @@ function createPatchTargetRecorder(baseDir, patcher, options) {
554
558
  break;
555
559
  default:
556
560
  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
- });
561
+ }
562
+ const onPatched = async () => saveCliPatchTargetRecord(normalizedBase, patcher, {
563
+ cwd: options?.cwd ?? normalizedBase,
564
+ source: options?.source ?? "cli",
565
+ recordPath: location.recordPath,
566
+ recordKey: location.recordKey,
567
+ packageJsonPath: location.packageJsonPath
568
+ });
569
+ return {
570
+ recordPath: location.recordPath,
571
+ message,
572
+ reason,
573
+ onPatched
574
+ };
575
+ }
576
+
577
+ // src/tailwindcss/targets.ts
578
+ function logTailwindcssTarget(kind, patcher, baseDir) {
579
+ const packageInfo = patcher?.packageInfo;
580
+ const label = kind === "cli" ? "weapp-tw patch" : "Weapp-tailwindcss";
581
+ if (!packageInfo?.rootPath) {
582
+ logger3.warn(
583
+ "%s \u672A\u627E\u5230 Tailwind CSS \u4F9D\u8D56\uFF0C\u8BF7\u68C0\u67E5\u5728 %s \u662F\u5426\u5DF2\u5B89\u88C5 tailwindcss",
584
+ label,
585
+ baseDir ?? process6.cwd()
586
+ );
587
+ return;
588
+ }
589
+ const displayPath = formatRelativeToBase(packageInfo.rootPath, baseDir);
590
+ const version = packageInfo.version ? ` (v${packageInfo.version})` : "";
591
+ if (kind === "runtime") {
592
+ logRuntimeTailwindcssTarget(baseDir, packageInfo.rootPath, packageInfo.version);
593
+ return;
594
+ }
595
+ logger3.info("%s \u7ED1\u5B9A Tailwind CSS -> %s%s", label, displayPath, version);
596
+ }
597
+
598
+ // src/tailwindcss/v4/config.ts
599
+ import { logger as logger4 } from "@weapp-tailwindcss/logger";
600
+
601
+ // src/tailwindcss/v4/patcher.ts
602
+ import { logger as logger6 } from "@weapp-tailwindcss/logger";
603
+
604
+ // src/tailwindcss/patcher.ts
605
+ import path7 from "path";
606
+ import process8 from "process";
607
+ import { logger as logger5 } from "@weapp-tailwindcss/logger";
608
+ import { defuOverrideArray as defuOverrideArray2 } from "@weapp-tailwindcss/shared";
609
+ import { TailwindcssPatcher } from "tailwindcss-patch";
610
+
611
+ // src/tailwindcss/patcher-resolve.ts
612
+ import { existsSync as existsSync4 } from "fs";
613
+ import { createRequire } from "module";
614
+ import path6 from "path";
615
+ import process7 from "process";
616
+ import { fileURLToPath } from "url";
617
+
618
+ // src/tailwindcss/v4/css-entries.ts
619
+ import path8 from "path";
620
+
621
+ // src/context/compiler-context-cache.ts
622
+ import { Buffer } from "buffer";
623
+ import path9 from "path";
624
+ import process9 from "process";
625
+ import { logger as logger7 } from "@weapp-tailwindcss/logger";
626
+ var globalCacheHolder = globalThis;
627
+ var compilerContextCache = globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
628
+
629
+ // src/context/handlers.ts
630
+ import { createStyleHandler } from "@weapp-tailwindcss/postcss";
631
+
632
+ // src/js/index.ts
633
+ import { LRUCache as LRUCache3 } from "lru-cache";
634
+
635
+ // src/babel/index.ts
636
+ import _babelTraverse from "@babel/traverse";
637
+ import { parse, parseExpression } from "@babel/parser";
638
+ function _interopDefaultCompat(e) {
639
+ return e && typeof e === "object" && "default" in e ? e.default : e;
640
+ }
641
+ var traverse = _interopDefaultCompat(_babelTraverse);
642
+
643
+ // src/utils/nameMatcher.ts
644
+ import { escapeStringRegexp } from "@weapp-core/regex";
645
+ var NEVER_MATCH_NAME = () => false;
646
+ var GLOBAL_FLAG_REGEXP = /g/g;
647
+ function buildFuzzyMatcher(fuzzyStrings) {
648
+ if (fuzzyStrings.length === 0) {
649
+ return void 0;
650
+ }
651
+ if (fuzzyStrings.length === 1) {
652
+ const [needle] = fuzzyStrings;
653
+ return (value) => value.includes(needle);
654
+ }
655
+ const unique = [...new Set(fuzzyStrings)];
656
+ const pattern = new RegExp(unique.map(escapeStringRegexp).join("|"));
657
+ return (value) => pattern.test(value);
658
+ }
659
+ function normaliseRegex(regex) {
660
+ const { source, flags } = regex;
661
+ if (!flags.includes("g")) {
662
+ return regex;
663
+ }
664
+ return new RegExp(source, flags.replace(GLOBAL_FLAG_REGEXP, ""));
665
+ }
666
+ function createNameMatcher(list, { exact = false } = {}) {
667
+ if (!list || list.length === 0) {
668
+ return NEVER_MATCH_NAME;
669
+ }
670
+ const exactStrings = exact ? /* @__PURE__ */ new Set() : void 0;
671
+ const fuzzyStrings = [];
672
+ const regexList = [];
673
+ for (const item of list) {
674
+ if (typeof item === "string") {
675
+ if (exact) {
676
+ exactStrings.add(item);
677
+ } else {
678
+ fuzzyStrings.push(item);
679
+ }
680
+ } else {
681
+ regexList.push(normaliseRegex(item));
682
+ }
683
+ }
684
+ if (exact) {
685
+ const exactStringCount = exactStrings?.size ?? 0;
686
+ if (exactStringCount === 1 && regexList.length === 0) {
687
+ const [needle] = exactStrings;
688
+ return (value) => value === needle;
689
+ }
690
+ if (regexList.length === 0) {
691
+ return (value) => exactStrings.has(value);
692
+ }
693
+ if (exactStringCount === 0 && regexList.length === 1) {
694
+ const [regex] = regexList;
695
+ return (value) => regex.test(value);
696
+ }
697
+ return (value) => {
698
+ if (exactStrings?.has(value)) {
699
+ return true;
700
+ }
701
+ return regexList.some((regex) => regex.test(value));
702
+ };
703
+ }
704
+ const fuzzyMatcher = exact ? void 0 : buildFuzzyMatcher(fuzzyStrings);
705
+ const hasRegex = regexList.length > 0;
706
+ if (fuzzyMatcher && !hasRegex) {
707
+ return fuzzyMatcher;
708
+ }
709
+ if (!fuzzyMatcher && regexList.length === 1) {
710
+ const [regex] = regexList;
711
+ return (value) => regex.test(value);
712
+ }
713
+ return (value) => {
714
+ if (fuzzyMatcher?.(value)) {
715
+ return true;
716
+ }
717
+ if (!hasRegex) {
718
+ return false;
719
+ }
720
+ return regexList.some((regex) => regex.test(value));
721
+ };
722
+ }
723
+
724
+ // src/js/babel/parse.ts
725
+ import { LRUCache as LRUCache2 } from "lru-cache";
726
+ var parseCache = new LRUCache2(
727
+ {
728
+ max: 1024
729
+ }
730
+ );
731
+ function genCacheKey(source, options) {
732
+ if (typeof options === "string") {
733
+ return source + options;
734
+ }
735
+ return source + JSON.stringify(options, (_, val) => typeof val === "function" ? val.toString() : val);
736
+ }
737
+ function babelParse(code, opts = {}) {
738
+ const { cache, cacheKey, ...rest } = opts;
739
+ const cacheKeyString = genCacheKey(code, cacheKey ?? rest);
740
+ let result;
741
+ if (cache) {
742
+ result = parseCache.get(cacheKeyString);
743
+ }
744
+ if (!result) {
745
+ const { cache: _cache, cacheKey: _cacheKey, ...parseOptions } = opts;
746
+ result = parse(code, parseOptions);
747
+ if (cache) {
748
+ parseCache.set(cacheKeyString, result);
749
+ }
750
+ }
751
+ return result;
752
+ }
753
+
754
+ // src/js/babel/process.ts
755
+ import MagicString from "magic-string";
756
+
757
+ // src/js/handlers.ts
758
+ import { jsStringEscape } from "@ast-core/escape";
759
+ import { splitCode } from "@weapp-tailwindcss/shared/extractors";
760
+
761
+ // src/wxml/shared.ts
762
+ import { escape, MappingChars2String as MappingChars2String2 } from "@weapp-core/escape";
763
+ var NEWLINE_RE = /[\n\r]+/g;
764
+ function replaceWxml(original, options = {
765
+ keepEOL: false,
766
+ escapeMap: MappingChars2String2
767
+ }) {
768
+ const { keepEOL, escapeMap, ignoreHead } = options;
769
+ let res = original;
770
+ if (!keepEOL) {
771
+ res = res.replaceAll(NEWLINE_RE, "");
772
+ }
773
+ res = escape(res, {
774
+ map: escapeMap,
775
+ ignoreHead
776
+ });
777
+ return res;
778
+ }
779
+
780
+ // src/shared/classname-transform.ts
781
+ var escapedCandidateCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
782
+ var defaultEscapedCandidateCache = /* @__PURE__ */ new Map();
783
+ var lastEscapedCandidateEscapeMap;
784
+ var lastEscapedCandidateCacheStore;
785
+ function isUrlLikeCandidate(candidate) {
786
+ return candidate.startsWith("//") || candidate.startsWith("http://") || candidate.startsWith("https://");
787
+ }
788
+ function isArbitraryValueCandidate(candidate) {
789
+ let hasOpenBracket = false;
790
+ let hasCloseBracket = false;
791
+ for (let i = 0; i < candidate.length; i++) {
792
+ const char = candidate[i];
793
+ if (char === "[") {
794
+ hasOpenBracket = true;
795
+ } else if (char === "]") {
796
+ hasCloseBracket = true;
797
+ }
798
+ if (hasOpenBracket && hasCloseBracket) {
799
+ break;
800
+ }
801
+ }
802
+ if (!hasOpenBracket || !hasCloseBracket) {
803
+ return false;
804
+ }
805
+ const normalized = candidate.trim();
806
+ if (isUrlLikeCandidate(normalized)) {
807
+ return false;
808
+ }
809
+ return true;
810
+ }
811
+ function shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) {
812
+ if (jsArbitraryValueFallback === true) {
813
+ return true;
814
+ }
815
+ if (jsArbitraryValueFallback === false) {
816
+ return false;
817
+ }
818
+ return tailwindcssMajorVersion === 4 && (!classNameSet || classNameSet.size === 0);
819
+ }
820
+ function shouldEnableArbitraryValueFallback({
821
+ classNameSet,
822
+ jsArbitraryValueFallback,
823
+ tailwindcssMajorVersion
824
+ }) {
825
+ return shouldEnableArbitraryValueFallbackByInputs(
826
+ classNameSet,
827
+ jsArbitraryValueFallback,
828
+ tailwindcssMajorVersion
829
+ );
830
+ }
831
+ var SKIP_RESULT = { decision: "skip" };
832
+ var DIRECT_RESULT = { decision: "direct" };
833
+ var FALLBACK_RESULT = { decision: "fallback" };
834
+ function getEscapedCandidateCacheStore(escapeMap) {
835
+ if (!escapeMap) {
836
+ return defaultEscapedCandidateCache;
837
+ }
838
+ if (escapeMap === lastEscapedCandidateEscapeMap && lastEscapedCandidateCacheStore) {
839
+ return lastEscapedCandidateCacheStore;
840
+ }
841
+ let store = escapedCandidateCacheByEscapeMap.get(escapeMap);
842
+ if (!store) {
843
+ store = /* @__PURE__ */ new Map();
844
+ escapedCandidateCacheByEscapeMap.set(escapeMap, store);
845
+ }
846
+ lastEscapedCandidateEscapeMap = escapeMap;
847
+ lastEscapedCandidateCacheStore = store;
848
+ return store;
849
+ }
850
+ function getEscapedCandidate(candidate, escapeMap, store = getEscapedCandidateCacheStore(escapeMap)) {
851
+ let cached = store.get(candidate);
852
+ if (cached === void 0) {
853
+ cached = replaceWxml(candidate, { escapeMap });
854
+ store.set(candidate, cached);
855
+ }
856
+ return cached;
857
+ }
858
+ function resolveClassNameTransformWithResult(candidate, {
859
+ alwaysEscape,
860
+ classNameSet,
861
+ escapeMap,
862
+ jsArbitraryValueFallback,
863
+ jsPreserveClass,
864
+ tailwindcssMajorVersion,
865
+ classContext
866
+ }) {
867
+ if (alwaysEscape) {
868
+ return DIRECT_RESULT;
869
+ }
870
+ if (jsPreserveClass?.(candidate)) {
871
+ return SKIP_RESULT;
872
+ }
873
+ if (classNameSet?.has(candidate)) {
874
+ return DIRECT_RESULT;
875
+ }
876
+ if (classNameSet && classNameSet.size > 0) {
877
+ const escapedCandidate = getEscapedCandidate(candidate, escapeMap);
878
+ if (escapedCandidate !== candidate && classNameSet.has(escapedCandidate)) {
879
+ return { decision: "escaped", escapedValue: escapedCandidate };
880
+ }
881
+ }
882
+ if (classContext && shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) && isArbitraryValueCandidate(candidate)) {
883
+ return FALLBACK_RESULT;
884
+ }
885
+ return SKIP_RESULT;
886
+ }
887
+
888
+ // src/utils/decode.ts
889
+ var unicodeEscapeRE = /\\u([\dA-Fa-f]{4})/g;
890
+ var unicodeEscapeTestRE = /\\u[\dA-Fa-f]{4}/;
891
+ function decodeUnicode(value) {
892
+ if (!unicodeEscapeTestRE.test(value)) {
893
+ return value;
894
+ }
895
+ return value.replace(unicodeEscapeRE, (_match, hex) => {
896
+ const codePoint = Number.parseInt(hex, 16);
897
+ return Number.isNaN(codePoint) ? _match : String.fromCharCode(codePoint);
898
+ });
899
+ }
900
+ function decodeUnicode2(input) {
901
+ if (!unicodeEscapeTestRE.test(input)) {
902
+ return input;
903
+ }
904
+ try {
905
+ return JSON.parse(`"${input}"`);
906
+ } catch (_error) {
907
+ return decodeUnicode(input);
908
+ }
909
+ }
910
+
911
+ // src/js/class-context.ts
912
+ var CLASS_LIKE_KEYWORDS = /* @__PURE__ */ new Set([
913
+ "class",
914
+ "classname",
915
+ "hoverclass",
916
+ "virtualhostclass",
917
+ "rootclass"
918
+ ]);
919
+ var CLASS_HELPER_IDENTIFIERS = /* @__PURE__ */ new Set([
920
+ "cn",
921
+ "clsx",
922
+ "classnames",
923
+ "twmerge",
924
+ "cva",
925
+ "tv",
926
+ "cx",
927
+ "r"
928
+ ]);
929
+ var DASH_CODE = 45;
930
+ var COLON_CODE = 58;
931
+ var UPPERCASE_A_CODE = 65;
932
+ var UPPERCASE_Z_CODE = 90;
933
+ var UNDERSCORE_CODE = 95;
934
+ var ASCII_MAX_CODE = 127;
935
+ var NORMALIZE_KEYWORD_REGEXP = /[-_:]/g;
936
+ function normalizeKeyword(name) {
937
+ const length = name.length;
938
+ let firstNormalizedIndex = -1;
939
+ for (let i = 0; i < length; i++) {
940
+ const code = name.charCodeAt(i);
941
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE || code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
942
+ firstNormalizedIndex = i;
943
+ break;
944
+ }
945
+ if (code > ASCII_MAX_CODE) {
946
+ return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
947
+ }
948
+ }
949
+ if (firstNormalizedIndex === -1) {
950
+ return name;
951
+ }
952
+ let normalized = name.slice(0, firstNormalizedIndex);
953
+ for (let i = firstNormalizedIndex; i < length; i++) {
954
+ const code = name.charCodeAt(i);
955
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE) {
956
+ continue;
957
+ }
958
+ if (code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
959
+ normalized += String.fromCharCode(code + 32);
960
+ continue;
961
+ }
962
+ if (code > ASCII_MAX_CODE) {
963
+ return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
964
+ }
965
+ normalized += name[i];
966
+ }
967
+ return normalized;
968
+ }
969
+ function readObjectKeyName(path22) {
970
+ if (path22.isIdentifier()) {
971
+ return path22.node.name;
972
+ }
973
+ if (path22.isStringLiteral()) {
974
+ return path22.node.value;
975
+ }
976
+ if (path22.isTemplateLiteral() && path22.node.expressions.length === 0) {
977
+ return path22.node.quasis[0]?.value.cooked ?? path22.node.quasis[0]?.value.raw;
978
+ }
979
+ return void 0;
980
+ }
981
+ function isClassLikeObjectProperty(path22, valuePath) {
982
+ if (!path22.isObjectProperty()) {
983
+ return false;
984
+ }
985
+ if (path22.get("value") !== valuePath) {
986
+ return false;
987
+ }
988
+ const keyName = readObjectKeyName(path22.get("key"));
989
+ if (!keyName) {
990
+ return false;
991
+ }
992
+ return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(keyName));
993
+ }
994
+ function isClassLikeJsxAttribute(path22) {
995
+ if (!path22.isJSXAttribute()) {
996
+ return false;
997
+ }
998
+ const namePath = path22.get("name");
999
+ if (!namePath.isJSXIdentifier()) {
1000
+ return false;
1001
+ }
1002
+ return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(namePath.node.name));
1003
+ }
1004
+ function readCallHelperName(calleePath) {
1005
+ if (calleePath.isIdentifier()) {
1006
+ return calleePath.node.name;
1007
+ }
1008
+ if (calleePath.isMemberExpression()) {
1009
+ const propertyPath = calleePath.get("property");
1010
+ if (propertyPath.isIdentifier()) {
1011
+ return propertyPath.node.name;
1012
+ }
1013
+ if (propertyPath.isStringLiteral()) {
1014
+ return propertyPath.node.value;
1015
+ }
1016
+ }
1017
+ return void 0;
1018
+ }
1019
+ function isClassLikeCallExpression(path22, valuePath) {
1020
+ if (!path22.isCallExpression()) {
1021
+ return false;
1022
+ }
1023
+ const helperName = readCallHelperName(path22.get("callee"));
1024
+ if (!helperName || !CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(helperName))) {
1025
+ return false;
1026
+ }
1027
+ return path22.get("arguments").some((argumentPath) => argumentPath.node === valuePath.node);
1028
+ }
1029
+ function isClassContextLiteralPath(path22) {
1030
+ let current = path22;
1031
+ while (current.parentPath) {
1032
+ const parent = current.parentPath;
1033
+ if (isClassLikeObjectProperty(parent, current)) {
1034
+ return true;
1035
+ }
1036
+ if (isClassLikeJsxAttribute(parent)) {
1037
+ return true;
1038
+ }
1039
+ if (isClassLikeCallExpression(parent, current)) {
1040
+ return true;
1041
+ }
1042
+ current = parent;
1043
+ }
1044
+ return false;
1045
+ }
1046
+
1047
+ // src/js/handlers.ts
1048
+ var debug2 = createDebug("[js:handlers] ");
1049
+ var replacementCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
1050
+ var defaultReplacementCache = /* @__PURE__ */ new Map();
1051
+ var WEAPP_TW_IGNORE_MARKER = "weapp-tw";
1052
+ var IGNORE_MARKER = "ignore";
1053
+ function getReplacementCacheStore(escapeMap) {
1054
+ if (!escapeMap) {
1055
+ return defaultReplacementCache;
1056
+ }
1057
+ let store = replacementCacheByEscapeMap.get(escapeMap);
1058
+ if (!store) {
1059
+ store = /* @__PURE__ */ new Map();
1060
+ replacementCacheByEscapeMap.set(escapeMap, store);
1061
+ }
1062
+ return store;
1063
+ }
1064
+ function getReplacement(candidate, escapeMap, store = getReplacementCacheStore(escapeMap)) {
1065
+ let cached = store.get(candidate);
1066
+ if (cached === void 0) {
1067
+ cached = replaceWxml(candidate, { escapeMap });
1068
+ store.set(candidate, cached);
1069
+ }
1070
+ return cached;
1071
+ }
1072
+ function hasIgnoreComment(node) {
1073
+ const { leadingComments } = node;
1074
+ if (!Array.isArray(leadingComments) || leadingComments.length === 0) {
1075
+ return false;
1076
+ }
1077
+ for (const comment of leadingComments) {
1078
+ const { value } = comment;
1079
+ if (value.includes(WEAPP_TW_IGNORE_MARKER) && value.includes(IGNORE_MARKER)) {
1080
+ return true;
1081
+ }
1082
+ }
1083
+ return false;
1084
+ }
1085
+ function extractLiteralValue(path22, { unescapeUnicode, arbitraryValues }) {
1086
+ const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
1087
+ const { node } = path22;
1088
+ let offset = 0;
1089
+ let original;
1090
+ if (node.type === "StringLiteral") {
1091
+ offset = 1;
1092
+ original = node.value;
1093
+ } else if (node.type === "TemplateElement") {
1094
+ original = node.value.raw;
1095
+ } else {
1096
+ original = "";
1097
+ }
1098
+ let literal = original;
1099
+ if (unescapeUnicode && original.includes("\\u")) {
1100
+ literal = decodeUnicode2(original);
1101
+ }
1102
+ return {
1103
+ allowDoubleQuotes,
1104
+ literal,
1105
+ offset,
1106
+ original
1107
+ };
1108
+ }
1109
+ function createCandidatePlanResolver(options, classContext) {
1110
+ const { escapeMap } = options;
1111
+ const replacementCache = getReplacementCacheStore(escapeMap);
1112
+ const transformOptions = classContext ? {
1113
+ ...options,
1114
+ classContext
1115
+ } : options;
1116
+ let firstCandidate = "";
1117
+ let firstPlan;
1118
+ let cache;
1119
+ const buildCandidatePlan = (candidate) => {
1120
+ const result = resolveClassNameTransformWithResult(candidate, transformOptions);
1121
+ if (result.decision === "skip") {
1122
+ return { result };
1123
+ }
1124
+ let replacement;
1125
+ if (result.decision === "escaped" && result.escapedValue) {
1126
+ replacement = result.escapedValue;
1127
+ replacementCache.set(candidate, replacement);
1128
+ } else {
1129
+ replacement = getReplacement(candidate, escapeMap, replacementCache);
1130
+ }
1131
+ return {
1132
+ result,
1133
+ replacement
1134
+ };
1135
+ };
1136
+ return (candidate) => {
1137
+ if (cache) {
1138
+ const cached = cache.get(candidate);
1139
+ if (cached) {
1140
+ return cached;
1141
+ }
1142
+ } else if (firstPlan && candidate === firstCandidate) {
1143
+ return firstPlan;
1144
+ }
1145
+ const plan = buildCandidatePlan(candidate);
1146
+ if (!firstPlan) {
1147
+ firstCandidate = candidate;
1148
+ firstPlan = plan;
1149
+ return plan;
1150
+ }
1151
+ if (!cache) {
1152
+ cache = /* @__PURE__ */ new Map();
1153
+ cache.set(firstCandidate, firstPlan);
1154
+ }
1155
+ cache.set(candidate, plan);
1156
+ return plan;
1157
+ };
1158
+ }
1159
+ function replaceHandleValue(path22, options) {
1160
+ const { needEscaped = false } = options;
1161
+ const { classNameSet, alwaysEscape } = options;
1162
+ const fallbackEnabled = shouldEnableArbitraryValueFallback(options);
1163
+ if (!alwaysEscape && !fallbackEnabled && (!classNameSet || classNameSet.size === 0)) {
1164
+ return void 0;
1165
+ }
1166
+ if (hasIgnoreComment(path22.node)) {
1167
+ return void 0;
1168
+ }
1169
+ const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path22, options);
1170
+ const candidates = splitCode(literal, allowDoubleQuotes);
1171
+ if (candidates.length === 0) {
1172
+ return void 0;
1173
+ }
1174
+ const debugEnabled = debug2.enabled;
1175
+ const classContext = options.wrapExpression || isClassContextLiteralPath(path22);
1176
+ let transformed = literal;
1177
+ let mutated = false;
1178
+ let matchedCandidateCount = 0;
1179
+ let escapedDecisionCount = 0;
1180
+ let fallbackDecisionCount = 0;
1181
+ let escapedSamples;
1182
+ let skippedSamples;
1183
+ const resolveCandidatePlan = createCandidatePlanResolver(options, classContext);
1184
+ for (const candidate of candidates) {
1185
+ const plan = resolveCandidatePlan(candidate);
1186
+ if (plan.result.decision === "skip") {
1187
+ if (debugEnabled) {
1188
+ if (!skippedSamples) {
1189
+ skippedSamples = [];
1190
+ }
1191
+ if (skippedSamples.length < 6) {
1192
+ skippedSamples.push(candidate);
1193
+ }
1194
+ }
1195
+ continue;
1196
+ }
1197
+ if (debugEnabled) {
1198
+ matchedCandidateCount += 1;
1199
+ if (plan.result.decision === "escaped") {
1200
+ escapedDecisionCount += 1;
1201
+ if (!escapedSamples) {
1202
+ escapedSamples = [];
1203
+ }
1204
+ if (escapedSamples.length < 6) {
1205
+ escapedSamples.push(candidate);
1206
+ }
1207
+ }
1208
+ if (plan.result.decision === "fallback") {
1209
+ fallbackDecisionCount += 1;
1210
+ }
1211
+ }
1212
+ const replaced = transformed.replace(candidate, plan.replacement);
1213
+ if (replaced !== transformed) {
1214
+ transformed = replaced;
1215
+ mutated = true;
1216
+ }
1217
+ }
1218
+ const node = path22.node;
1219
+ if (!mutated || typeof node.start !== "number" || typeof node.end !== "number") {
1220
+ return void 0;
1221
+ }
1222
+ if (debugEnabled) {
1223
+ debug2(
1224
+ "runtimeSet size=%d fallbackTriggered=%s candidates=%d matched=%d escapedHits=%d skipped=%d file=%s escapedSamples=%s skippedSamples=%s",
1225
+ classNameSet?.size ?? 0,
1226
+ fallbackDecisionCount > 0,
1227
+ candidates.length,
1228
+ matchedCandidateCount,
1229
+ escapedDecisionCount,
1230
+ skippedSamples?.length ?? 0,
1231
+ options.filename ?? "unknown",
1232
+ escapedSamples?.join(",") || "-",
1233
+ skippedSamples?.join(",") || "-"
1234
+ );
1235
+ }
1236
+ const start = node.start + offset;
1237
+ const end = node.end - offset;
1238
+ if (start >= end || transformed === original) {
1239
+ return void 0;
1240
+ }
1241
+ const value = needEscaped ? jsStringEscape(transformed) : transformed;
1242
+ return {
1243
+ start,
1244
+ end,
1245
+ value,
1246
+ path: path22
1247
+ };
1248
+ }
1249
+
1250
+ // src/js/sourceAnalysis.ts
1251
+ function hasReplacementEntries(replacements) {
1252
+ for (const key in replacements) {
1253
+ if (Object.hasOwn(replacements, key)) {
1254
+ return true;
1255
+ }
1256
+ }
1257
+ return false;
1258
+ }
1259
+ function createModuleSpecifierReplacementToken(path22, replacement) {
1260
+ const node = path22.node;
1261
+ if (node.value === replacement) {
1262
+ return void 0;
1263
+ }
1264
+ if (typeof node.start !== "number" || typeof node.end !== "number") {
1265
+ return void 0;
1266
+ }
1267
+ const start = node.start + 1;
1268
+ const end = node.end - 1;
1269
+ if (start >= end) {
1270
+ return void 0;
1271
+ }
1272
+ return {
1273
+ start,
1274
+ end,
1275
+ value: replacement,
1276
+ path: path22
1277
+ };
1278
+ }
1279
+ function collectModuleSpecifierReplacementTokens(analysis, replacements) {
1280
+ if (!hasReplacementEntries(replacements)) {
1281
+ return [];
1282
+ }
1283
+ if (analysis.importDeclarations.size === 0 && analysis.exportDeclarations.size === 0 && analysis.requireCallPaths.length === 0 && analysis.walker.imports.size === 0) {
1284
+ return [];
1285
+ }
1286
+ const tokens = [];
1287
+ const applyReplacement = (path22) => {
1288
+ const replacement = replacements[path22.node.value];
1289
+ if (!replacement) {
1290
+ return;
1291
+ }
1292
+ const token = createModuleSpecifierReplacementToken(path22, replacement);
1293
+ if (token) {
1294
+ tokens.push(token);
1295
+ }
1296
+ };
1297
+ for (const importPath of analysis.importDeclarations) {
1298
+ const source = importPath.get("source");
1299
+ if (source.isStringLiteral()) {
1300
+ applyReplacement(source);
1301
+ }
1302
+ }
1303
+ for (const exportPath of analysis.exportDeclarations) {
1304
+ if (exportPath.isExportNamedDeclaration() || exportPath.isExportAllDeclaration()) {
1305
+ const source = exportPath.get("source");
1306
+ if (source && !Array.isArray(source) && source.isStringLiteral()) {
1307
+ applyReplacement(source);
1308
+ }
1309
+ }
1310
+ }
1311
+ for (const literalPath of analysis.requireCallPaths) {
1312
+ applyReplacement(literalPath);
1313
+ }
1314
+ for (const token of analysis.walker.imports) {
1315
+ const replacement = replacements[token.source];
1316
+ if (replacement) {
1317
+ token.source = replacement;
1318
+ }
1319
+ }
1320
+ return tokens;
1321
+ }
1322
+
1323
+ // src/js/babel/process.ts
1324
+ var optionVariantsCache = /* @__PURE__ */ new WeakMap();
1325
+ function getNeedEscapedOptions(options, needEscaped) {
1326
+ if (options.needEscaped === needEscaped) {
1327
+ return options;
1328
+ }
1329
+ let cached = optionVariantsCache.get(options);
1330
+ if (!cached) {
1331
+ cached = {};
1332
+ optionVariantsCache.set(options, cached);
1333
+ }
1334
+ if (needEscaped) {
1335
+ if (!cached.stringLiteralOptions) {
1336
+ cached.stringLiteralOptions = {
1337
+ ...options,
1338
+ needEscaped: true
1339
+ };
1340
+ }
1341
+ return cached.stringLiteralOptions;
1342
+ }
1343
+ if (!cached.templateLiteralOptions) {
1344
+ cached.templateLiteralOptions = {
1345
+ ...options,
1346
+ needEscaped: false
1347
+ };
1348
+ }
1349
+ return cached.templateLiteralOptions;
1350
+ }
1351
+ function processUpdatedSource(rawSource, options, analysis) {
1352
+ const { targetPaths, jsTokenUpdater, ignoredPaths } = analysis;
1353
+ if (targetPaths.length === 0 && !options.moduleSpecifierReplacements && jsTokenUpdater.length === 0) {
1354
+ return new MagicString(rawSource);
1355
+ }
1356
+ const replacementTokens = [];
1357
+ for (const path22 of targetPaths) {
1358
+ if (ignoredPaths.has(path22)) {
1359
+ continue;
1360
+ }
1361
+ const token = replaceHandleValue(
1362
+ path22,
1363
+ path22.isStringLiteral() ? getNeedEscapedOptions(options, true) : getNeedEscapedOptions(options, false)
1364
+ );
1365
+ if (token) {
1366
+ replacementTokens.push(token);
1367
+ }
1368
+ }
1369
+ if (options.moduleSpecifierReplacements) {
1370
+ replacementTokens.push(
1371
+ ...collectModuleSpecifierReplacementTokens(analysis, options.moduleSpecifierReplacements)
1372
+ );
1373
+ }
1374
+ if (jsTokenUpdater.length + replacementTokens.length === 0) {
1375
+ return new MagicString(rawSource);
1376
+ }
1377
+ const ms = new MagicString(rawSource);
1378
+ jsTokenUpdater.push(...replacementTokens).filter((token) => !ignoredPaths.has(token.path)).updateMagicString(ms);
1379
+ return ms;
1380
+ }
1381
+
1382
+ // src/js/evalTransforms.ts
1383
+ import { jsStringEscape as jsStringEscape2 } from "@ast-core/escape";
1384
+ var evalHandlerOptionsCache = /* @__PURE__ */ new WeakMap();
1385
+ var EVAL_SCOPE_ERROR_REGEXP = /pass a scope and parentPath|traversing a Program\/File/i;
1386
+ function isEvalPath(path22) {
1387
+ if (path22.isCallExpression()) {
1388
+ const calleePath = path22.get("callee");
1389
+ return calleePath.isIdentifier({ name: "eval" });
1390
+ }
1391
+ return false;
1392
+ }
1393
+ function createEvalReplacementToken(path22, updated) {
1394
+ const node = path22.node;
1395
+ let offset = 0;
1396
+ let original;
1397
+ if (path22.isStringLiteral()) {
1398
+ offset = 1;
1399
+ original = path22.node.value;
1400
+ } else if (path22.isTemplateElement()) {
1401
+ original = path22.node.value.raw;
1402
+ } else {
1403
+ original = "";
1404
+ }
1405
+ if (typeof node.start !== "number" || typeof node.end !== "number") {
1406
+ return void 0;
1407
+ }
1408
+ const start = node.start + offset;
1409
+ const end = node.end - offset;
1410
+ if (start >= end) {
1411
+ return void 0;
1412
+ }
1413
+ if (original === updated) {
1414
+ return void 0;
1415
+ }
1416
+ const value = path22.isStringLiteral() ? jsStringEscape2(updated) : updated;
1417
+ return {
1418
+ start,
1419
+ end,
1420
+ value,
1421
+ path: path22
1422
+ };
1423
+ }
1424
+ function handleEvalStringLiteral(path22, handlerOptions, updater, handler) {
1425
+ const { code } = handler(path22.node.value, handlerOptions);
1426
+ if (!code) {
1427
+ return;
1428
+ }
1429
+ const token = createEvalReplacementToken(path22, code);
1430
+ if (token) {
1431
+ updater.addToken(token);
1432
+ }
1433
+ }
1434
+ function handleEvalTemplateElement(path22, handlerOptions, updater, handler) {
1435
+ const { code } = handler(path22.node.value.raw, handlerOptions);
1436
+ if (!code) {
1437
+ return;
1438
+ }
1439
+ const token = createEvalReplacementToken(path22, code);
1440
+ if (token) {
1441
+ updater.addToken(token);
1442
+ }
1443
+ }
1444
+ function getEvalStringHandlerOptions(options) {
1445
+ if (options.needEscaped === false && options.generateMap === false) {
1446
+ return options;
1447
+ }
1448
+ let cached = evalHandlerOptionsCache.get(options);
1449
+ if (!cached) {
1450
+ cached = {};
1451
+ evalHandlerOptionsCache.set(options, cached);
1452
+ }
1453
+ if (!cached.stringLiteralOptions) {
1454
+ cached.stringLiteralOptions = {
1455
+ ...options,
1456
+ needEscaped: false,
1457
+ generateMap: false
1458
+ };
1459
+ }
1460
+ return cached.stringLiteralOptions;
1461
+ }
1462
+ function getEvalTemplateHandlerOptions(options) {
1463
+ if (options.generateMap === false) {
1464
+ return options;
1465
+ }
1466
+ let cached = evalHandlerOptionsCache.get(options);
1467
+ if (!cached) {
1468
+ cached = {};
1469
+ evalHandlerOptionsCache.set(options, cached);
1470
+ }
1471
+ if (!cached.templateLiteralOptions) {
1472
+ cached.templateLiteralOptions = {
1473
+ ...options,
1474
+ generateMap: false
1475
+ };
1476
+ }
1477
+ return cached.templateLiteralOptions;
1478
+ }
1479
+ function walkEvalExpression(path22, options, updater, handler) {
1480
+ const stringHandlerOptions = getEvalStringHandlerOptions(options);
1481
+ const templateHandlerOptions = getEvalTemplateHandlerOptions(options);
1482
+ const maybeTraverse = path22?.traverse;
1483
+ if (typeof maybeTraverse === "function") {
1484
+ try {
1485
+ return maybeTraverse.call(path22, {
1486
+ StringLiteral(innerPath) {
1487
+ handleEvalStringLiteral(innerPath, stringHandlerOptions, updater, handler);
1488
+ },
1489
+ TemplateElement(innerPath) {
1490
+ handleEvalTemplateElement(innerPath, templateHandlerOptions, updater, handler);
1491
+ }
1492
+ });
1493
+ } catch (error) {
1494
+ const msg = error?.message ?? "";
1495
+ const scopeError = EVAL_SCOPE_ERROR_REGEXP.test(msg);
1496
+ if (!scopeError) {
1497
+ throw error;
1498
+ }
1499
+ }
1500
+ }
1501
+ const getArgs = path22?.get?.("arguments");
1502
+ if (Array.isArray(getArgs)) {
1503
+ for (const arg of getArgs) {
1504
+ if (arg?.isStringLiteral?.()) {
1505
+ handleEvalStringLiteral(arg, stringHandlerOptions, updater, handler);
1506
+ continue;
1507
+ }
1508
+ if (arg?.isTemplateLiteral?.()) {
1509
+ for (const quasi of arg.get("quasis")) {
1510
+ handleEvalTemplateElement(quasi, templateHandlerOptions, updater, handler);
1511
+ }
1512
+ }
1513
+ }
1514
+ return;
1515
+ }
1516
+ const nodeArgs = path22?.node?.arguments;
1517
+ if (Array.isArray(nodeArgs)) {
1518
+ for (const n of nodeArgs) {
1519
+ if (n?.type === "StringLiteral") {
1520
+ const stub = {
1521
+ node: n,
1522
+ isStringLiteral: () => true
1523
+ };
1524
+ handleEvalStringLiteral(stub, stringHandlerOptions, updater, handler);
1525
+ } else if (n?.type === "TemplateLiteral" && Array.isArray(n.quasis)) {
1526
+ for (const q of n.quasis) {
1527
+ const stub = {
1528
+ node: q,
1529
+ isStringLiteral: () => false,
1530
+ isTemplateElement: () => true
1531
+ };
1532
+ handleEvalTemplateElement(stub, templateHandlerOptions, updater, handler);
1533
+ }
1534
+ }
1535
+ }
1536
+ }
1537
+ }
1538
+
1539
+ // src/js/JsTokenUpdater.ts
1540
+ var JsTokenUpdater = class {
1541
+ constructor({ value } = {}) {
1542
+ this.tokens = value ? [...value] : [];
1543
+ }
1544
+ addToken(token) {
1545
+ if (token) {
1546
+ this.tokens.push(token);
1547
+ }
1548
+ }
1549
+ push(...args) {
1550
+ this.tokens.push(...args);
1551
+ return this;
1552
+ }
1553
+ /**
1554
+ * 待写入的 token 数量。
1555
+ */
1556
+ get length() {
1557
+ return this.tokens.length;
1558
+ }
1559
+ map(callbackfn) {
1560
+ this.tokens = this.tokens.map(callbackfn);
1561
+ return this;
1562
+ }
1563
+ filter(callbackfn) {
1564
+ this.tokens = this.tokens.filter(callbackfn);
1565
+ return this;
1566
+ }
1567
+ updateMagicString(ms) {
1568
+ for (const { start, end, value } of this.tokens) {
1569
+ ms.update(start, end, value);
1570
+ }
1571
+ return ms;
1572
+ }
1573
+ };
1574
+
1575
+ // src/js/module-graph/ignored-exports.ts
1576
+ var IgnoredExportsTracker = class {
1577
+ constructor(options) {
1578
+ this.options = options;
1579
+ this.ignoredExportNames = /* @__PURE__ */ new Map();
1580
+ }
1581
+ addIgnoredExport(filename, exportName) {
1582
+ if (!exportName) {
1583
+ return;
1584
+ }
1585
+ let pending = this.ignoredExportNames.get(filename);
1586
+ if (!pending) {
1587
+ pending = /* @__PURE__ */ new Set();
1588
+ this.ignoredExportNames.set(filename, pending);
1589
+ }
1590
+ if (pending.has(exportName)) {
1591
+ return;
1592
+ }
1593
+ pending.add(exportName);
1594
+ const existing = this.options.modules.get(filename);
1595
+ if (existing) {
1596
+ this.applyIgnoredExportsToAnalysis(filename, existing.analysis);
1597
+ }
1598
+ }
1599
+ registerIgnoredExportsFromTokens(resolved, tokens) {
1600
+ for (const token of tokens) {
1601
+ if (token.type === "ImportSpecifier") {
1602
+ this.addIgnoredExport(resolved, token.imported);
1603
+ } else if (token.type === "ImportDefaultSpecifier") {
1604
+ this.addIgnoredExport(resolved, "default");
1605
+ }
1606
+ }
1607
+ }
1608
+ applyIgnoredExportsToAnalysis(filename, analysis) {
1609
+ const pending = this.ignoredExportNames.get(filename);
1610
+ if (!pending || pending.size === 0) {
1611
+ return;
1612
+ }
1613
+ const names = new Set(pending);
1614
+ pending.clear();
1615
+ const propagate = [];
1616
+ for (const exportPath of analysis.exportDeclarations) {
1617
+ if (names.size === 0) {
1618
+ break;
1619
+ }
1620
+ if (exportPath.isExportDefaultDeclaration()) {
1621
+ if (names.has("default")) {
1622
+ analysis.walker.walkExportDefaultDeclaration(exportPath);
1623
+ names.delete("default");
1624
+ }
1625
+ continue;
1626
+ }
1627
+ if (exportPath.isExportNamedDeclaration()) {
1628
+ const source = exportPath.node.source?.value;
1629
+ if (typeof source === "string") {
1630
+ for (const spec of exportPath.get("specifiers")) {
1631
+ if (!spec.isExportSpecifier()) {
1632
+ continue;
1633
+ }
1634
+ const exported = spec.get("exported");
1635
+ let exportedName;
1636
+ if (exported.isIdentifier()) {
1637
+ exportedName = exported.node.name;
1638
+ } else if (exported.isStringLiteral()) {
1639
+ exportedName = exported.node.value;
1640
+ }
1641
+ if (!exportedName || !names.has(exportedName)) {
1642
+ continue;
1643
+ }
1644
+ const local = spec.get("local");
1645
+ if (local.isIdentifier()) {
1646
+ propagate.push({
1647
+ specifier: source,
1648
+ exportName: local.node.name
1649
+ });
1650
+ names.delete(exportedName);
1651
+ } else if (local.isStringLiteral()) {
1652
+ propagate.push({
1653
+ specifier: source,
1654
+ exportName: local.node.value
1655
+ });
1656
+ names.delete(exportedName);
1657
+ }
1658
+ }
1659
+ continue;
1660
+ }
1661
+ const declaration = exportPath.get("declaration");
1662
+ if (declaration.isVariableDeclaration()) {
1663
+ for (const decl of declaration.get("declarations")) {
1664
+ const id = decl.get("id");
1665
+ if (id.isIdentifier()) {
1666
+ const exportName = id.node.name;
1667
+ if (names.has(exportName)) {
1668
+ analysis.walker.walkVariableDeclarator(decl);
1669
+ names.delete(exportName);
1670
+ }
1671
+ }
1672
+ }
1673
+ }
1674
+ for (const spec of exportPath.get("specifiers")) {
1675
+ if (!spec.isExportSpecifier()) {
1676
+ continue;
1677
+ }
1678
+ const exported = spec.get("exported");
1679
+ let exportedName;
1680
+ if (exported.isIdentifier()) {
1681
+ exportedName = exported.node.name;
1682
+ } else if (exported.isStringLiteral()) {
1683
+ exportedName = exported.node.value;
1684
+ }
1685
+ if (!exportedName || !names.has(exportedName)) {
1686
+ continue;
1687
+ }
1688
+ const local = spec.get("local");
1689
+ analysis.walker.walkNode(local);
1690
+ names.delete(exportedName);
1691
+ }
1692
+ continue;
1693
+ }
1694
+ if (exportPath.isExportAllDeclaration()) {
1695
+ const source = exportPath.node.source?.value;
1696
+ if (typeof source === "string") {
1697
+ for (const exportName of names) {
1698
+ propagate.push({
1699
+ specifier: source,
1700
+ exportName
1701
+ });
1702
+ }
1703
+ names.clear();
1704
+ }
1705
+ }
1706
+ }
1707
+ for (const { specifier, exportName } of propagate) {
1708
+ let resolved;
1709
+ try {
1710
+ resolved = this.options.resolve(specifier, filename);
1711
+ } catch {
1712
+ resolved = void 0;
1713
+ }
1714
+ if (!resolved) {
1715
+ pending.add(exportName);
1716
+ continue;
1717
+ }
1718
+ if (this.options.filter && !this.options.filter(resolved, specifier, filename)) {
1719
+ pending.add(exportName);
1720
+ continue;
1721
+ }
1722
+ this.addIgnoredExport(resolved, exportName);
1723
+ }
1724
+ for (const name of names) {
1725
+ pending.add(name);
1726
+ }
1727
+ }
1728
+ };
1729
+
1730
+ // src/js/ModuleGraph.ts
1731
+ var JsModuleGraph = class {
1732
+ constructor(entry, graphOptions) {
1733
+ this.modules = /* @__PURE__ */ new Map();
1734
+ this.queue = [];
1735
+ this.resolve = graphOptions.resolve;
1736
+ this.load = graphOptions.load;
1737
+ this.filter = graphOptions.filter;
1738
+ this.maxDepth = graphOptions.maxDepth ?? Number.POSITIVE_INFINITY;
1739
+ const { moduleGraph: _moduleGraph, filename: _ignoredFilename, ...rest } = entry.handlerOptions;
1740
+ this.baseOptions = {
1741
+ ...rest,
1742
+ filename: entry.filename
1743
+ };
1744
+ this.parserOptions = entry.handlerOptions.babelParserOptions;
1745
+ this.rootFilename = entry.filename;
1746
+ this.ignoredExports = new IgnoredExportsTracker({
1747
+ resolve: this.resolve,
1748
+ filter: this.filter,
1749
+ modules: this.modules
1750
+ });
1751
+ this.modules.set(entry.filename, {
1752
+ filename: entry.filename,
1753
+ source: entry.source,
1754
+ analysis: entry.analysis
1755
+ });
1756
+ this.queue.push({ filename: entry.filename, depth: 0 });
1757
+ }
1758
+ build() {
1759
+ this.collectDependencies();
1760
+ let linked;
1761
+ for (const [filename, state] of this.modules) {
1762
+ if (filename === this.rootFilename) {
1763
+ continue;
1764
+ }
1765
+ const childOptions = {
1766
+ ...this.baseOptions,
1767
+ filename
1768
+ };
1769
+ const ms = processUpdatedSource(state.source, childOptions, state.analysis);
1770
+ const code = ms.toString();
1771
+ if (code !== state.source) {
1772
+ if (!linked) {
1773
+ linked = {};
1774
+ }
1775
+ linked[filename] = { code };
1776
+ }
1777
+ }
1778
+ return linked;
1779
+ }
1780
+ collectDependencies() {
1781
+ while (this.queue.length > 0) {
1782
+ const { filename, depth } = this.queue.shift();
1783
+ if (depth >= this.maxDepth) {
1784
+ continue;
1785
+ }
1786
+ const state = this.modules.get(filename);
1787
+ if (!state) {
1788
+ continue;
1789
+ }
1790
+ const dependencySpecifiers = /* @__PURE__ */ new Map();
1791
+ for (const token of state.analysis.walker.imports) {
1792
+ if (!dependencySpecifiers.has(token.source)) {
1793
+ dependencySpecifiers.set(token.source, []);
1794
+ }
1795
+ dependencySpecifiers.get(token.source).push(token);
1796
+ }
1797
+ for (const exportPath of state.analysis.exportDeclarations) {
1798
+ if (exportPath.isExportAllDeclaration() || exportPath.isExportNamedDeclaration()) {
1799
+ const source = exportPath.node.source?.value;
1800
+ if (typeof source === "string" && !dependencySpecifiers.has(source)) {
1801
+ dependencySpecifiers.set(source, []);
1802
+ }
1803
+ }
1804
+ }
1805
+ for (const [specifier, tokens] of dependencySpecifiers) {
1806
+ let resolved;
1807
+ try {
1808
+ resolved = this.resolve(specifier, filename);
1809
+ } catch {
1810
+ continue;
1811
+ }
1812
+ if (!resolved) {
1813
+ continue;
1814
+ }
1815
+ if (this.filter && !this.filter(resolved, specifier, filename)) {
1816
+ continue;
1817
+ }
1818
+ if (tokens.length > 0) {
1819
+ this.ignoredExports.registerIgnoredExportsFromTokens(resolved, tokens);
1820
+ }
1821
+ if (this.modules.has(resolved)) {
1822
+ continue;
1823
+ }
1824
+ let source;
1825
+ try {
1826
+ source = this.load(resolved);
1827
+ } catch {
1828
+ continue;
1829
+ }
1830
+ if (typeof source !== "string") {
1831
+ continue;
1832
+ }
1833
+ let analysis;
1834
+ try {
1835
+ const ast = babelParse(source, {
1836
+ ...this.parserOptions,
1837
+ sourceFilename: resolved
1838
+ });
1839
+ analysis = analyzeSource(ast, {
1840
+ ...this.baseOptions,
1841
+ filename: resolved
1842
+ });
1843
+ this.ignoredExports.applyIgnoredExportsToAnalysis(resolved, analysis);
1844
+ } catch {
1845
+ continue;
1846
+ }
1847
+ this.modules.set(resolved, {
1848
+ filename: resolved,
1849
+ source,
1850
+ analysis
1851
+ });
1852
+ this.queue.push({ filename: resolved, depth: depth + 1 });
1853
+ }
1854
+ }
1855
+ }
1856
+ };
1857
+
1858
+ // src/js/node-path-walker/export-handlers.ts
1859
+ function walkExportDeclaration(ctx, path22) {
1860
+ if (path22.isExportDeclaration()) {
1861
+ if (path22.isExportNamedDeclaration()) {
1862
+ walkExportNamedDeclaration(ctx, path22);
1863
+ } else if (path22.isExportDefaultDeclaration()) {
1864
+ walkExportDefaultDeclaration(ctx, path22);
1865
+ } else if (path22.isExportAllDeclaration()) {
1866
+ walkExportAllDeclaration(ctx, path22);
1867
+ }
1868
+ }
1869
+ }
1870
+ function walkExportNamedDeclaration(ctx, path22) {
1871
+ const declaration = path22.get("declaration");
1872
+ if (declaration.isVariableDeclaration()) {
1873
+ for (const decl of declaration.get("declarations")) {
1874
+ ctx.walkNode(decl);
1875
+ }
1876
+ }
1877
+ const specifiers = path22.get("specifiers");
1878
+ for (const spec of specifiers) {
1879
+ if (spec.isExportSpecifier()) {
1880
+ const local = spec.get("local");
1881
+ if (local.isIdentifier()) {
1882
+ ctx.walkNode(local);
1883
+ }
1884
+ }
1885
+ }
1886
+ }
1887
+ function walkExportDefaultDeclaration(ctx, path22) {
1888
+ const decl = path22.get("declaration");
1889
+ if (decl.isIdentifier()) {
1890
+ ctx.walkNode(decl);
1891
+ } else {
1892
+ ctx.walkNode(decl);
1893
+ }
1894
+ }
1895
+ function walkExportAllDeclaration(ctx, path22) {
1896
+ const source = path22.get("source");
1897
+ if (source.isStringLiteral()) {
1898
+ ctx.addImportToken(
1899
+ {
1900
+ declaration: path22,
1901
+ source: source.node.value,
1902
+ type: "ExportAllDeclaration"
1903
+ }
1904
+ );
1905
+ }
1906
+ }
1907
+
1908
+ // src/js/node-path-walker/import-tokens.ts
1909
+ function maybeAddImportToken(imports, arg) {
1910
+ if (!(arg.isImportSpecifier() && arg.node.importKind !== "type" || arg.isImportDefaultSpecifier())) {
1911
+ return false;
1912
+ }
1913
+ const importDeclaration = arg.parentPath;
1914
+ if (!importDeclaration.isImportDeclaration() || importDeclaration.node.importKind === "type") {
1915
+ return false;
1916
+ }
1917
+ if (arg.isImportSpecifier()) {
1918
+ const imported = arg.get("imported");
1919
+ if (imported.isIdentifier()) {
1920
+ imports.add(
1921
+ {
1922
+ declaration: importDeclaration,
1923
+ specifier: arg,
1924
+ imported: imported.node.name,
1925
+ local: arg.node.local.name,
1926
+ source: importDeclaration.node.source.value,
1927
+ type: "ImportSpecifier"
1928
+ }
1929
+ );
1930
+ }
1931
+ return true;
1932
+ }
1933
+ imports.add(
1934
+ {
1935
+ declaration: importDeclaration,
1936
+ specifier: arg,
1937
+ local: arg.node.local.name,
1938
+ source: importDeclaration.node.source.value,
1939
+ type: "ImportDefaultSpecifier"
1940
+ }
1941
+ );
1942
+ return true;
1943
+ }
1944
+
1945
+ // src/js/NodePathWalker.ts
1946
+ var EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS = [];
1947
+ var EMPTY_IMPORT_TOKENS = /* @__PURE__ */ new Set();
1948
+ function NOOP_STRING_PATH_CALLBACK() {
1949
+ }
1950
+ var NEVER_MATCH_NAME2 = () => false;
1951
+ var NodePathWalker = class {
1952
+ constructor({ ignoreCallExpressionIdentifiers, callback } = {}) {
1953
+ this.hasIgnoredCallIdentifiers = Boolean(ignoreCallExpressionIdentifiers && ignoreCallExpressionIdentifiers.length > 0);
1954
+ this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS;
1955
+ this.callback = callback ?? NOOP_STRING_PATH_CALLBACK;
1956
+ this.isIgnoredCallIdentifier = this.hasIgnoredCallIdentifiers ? createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true }) : NEVER_MATCH_NAME2;
1957
+ }
1958
+ get imports() {
1959
+ return this.importsStore ?? EMPTY_IMPORT_TOKENS;
1960
+ }
1961
+ getWritableImports() {
1962
+ if (!this.importsStore) {
1963
+ this.importsStore = /* @__PURE__ */ new Set();
1964
+ }
1965
+ return this.importsStore;
1966
+ }
1967
+ addImportToken(token) {
1968
+ this.getWritableImports().add(token);
1969
+ }
1970
+ getVisited() {
1971
+ if (!this.visitedStore) {
1972
+ this.visitedStore = /* @__PURE__ */ new WeakSet();
1973
+ }
1974
+ return this.visitedStore;
1975
+ }
1976
+ walkVariableDeclarator(path22) {
1977
+ const init = path22.get("init");
1978
+ this.walkNode(init);
1979
+ }
1980
+ walkTemplateLiteral(path22) {
1981
+ for (const exp of path22.get("expressions")) {
1982
+ this.walkNode(exp);
1983
+ }
1984
+ for (const quasis of path22.get("quasis")) {
1985
+ this.callback(quasis);
1986
+ }
1987
+ }
1988
+ walkStringLiteral(path22) {
1989
+ this.callback(path22);
1990
+ }
1991
+ walkBinaryExpression(path22) {
1992
+ const left = path22.get("left");
1993
+ this.walkNode(left);
1994
+ const right = path22.get("right");
1995
+ this.walkNode(right);
1996
+ }
1997
+ walkLogicalExpression(path22) {
1998
+ const left = path22.get("left");
1999
+ this.walkNode(left);
2000
+ const right = path22.get("right");
2001
+ this.walkNode(right);
2002
+ }
2003
+ walkObjectExpression(path22) {
2004
+ const props = path22.get("properties");
2005
+ for (const prop of props) {
2006
+ if (prop.isObjectProperty()) {
2007
+ const key = prop.get("key");
2008
+ this.walkNode(key);
2009
+ const value = prop.get("value");
2010
+ this.walkNode(value);
2011
+ }
2012
+ }
2013
+ }
2014
+ walkArrayExpression(path22) {
2015
+ const elements = path22.get("elements");
2016
+ for (const element of elements) {
2017
+ this.walkNode(element);
2018
+ }
2019
+ }
2020
+ walkNode(arg) {
2021
+ const visited = this.getVisited();
2022
+ if (visited.has(arg)) {
2023
+ return;
2024
+ }
2025
+ visited.add(arg);
2026
+ if (arg.isIdentifier()) {
2027
+ const binding = arg?.scope?.getBinding?.(arg.node.name);
2028
+ if (binding) {
2029
+ this.walkNode(binding.path);
2030
+ }
2031
+ } else if (arg.isMemberExpression()) {
2032
+ const objectPath = arg.get("object");
2033
+ if (objectPath.isIdentifier()) {
2034
+ const binding = arg?.scope?.getBinding?.(objectPath.node.name);
2035
+ if (binding) {
2036
+ if (binding.path.isVariableDeclarator()) {
2037
+ this.walkVariableDeclarator(binding.path);
2038
+ }
2039
+ }
2040
+ }
2041
+ } else if (arg.isTemplateLiteral()) {
2042
+ this.walkTemplateLiteral(arg);
2043
+ } else if (arg.isStringLiteral()) {
2044
+ this.walkStringLiteral(arg);
2045
+ } else if (arg.isBinaryExpression()) {
2046
+ this.walkBinaryExpression(arg);
2047
+ } else if (arg.isLogicalExpression()) {
2048
+ this.walkLogicalExpression(arg);
2049
+ } else if (arg.isObjectExpression()) {
2050
+ this.walkObjectExpression(arg);
2051
+ } else if (arg.isArrayExpression()) {
2052
+ this.walkArrayExpression(arg);
2053
+ } else if (arg.isVariableDeclarator()) {
2054
+ this.walkVariableDeclarator(arg);
2055
+ } else if (maybeAddImportToken(this.getWritableImports(), arg)) {
2056
+ }
2057
+ }
2058
+ /**
2059
+ * Walk the arguments of a desired call expression so their bindings can be analysed.
2060
+ */
2061
+ walkCallExpression(path22) {
2062
+ if (!this.hasIgnoredCallIdentifiers) {
2063
+ return;
2064
+ }
2065
+ const calleePath = path22.get("callee");
2066
+ if (calleePath.isIdentifier() && this.isIgnoredCallIdentifier(calleePath.node.name)) {
2067
+ for (const arg of path22.get("arguments")) {
2068
+ this.walkNode(arg);
2069
+ }
2070
+ }
2071
+ }
2072
+ walkExportDeclaration(path22) {
2073
+ walkExportDeclaration(this, path22);
2074
+ }
2075
+ walkExportNamedDeclaration(path22) {
2076
+ walkExportNamedDeclaration(this, path22);
2077
+ }
2078
+ walkExportDefaultDeclaration(path22) {
2079
+ walkExportDefaultDeclaration(this, path22);
2080
+ }
2081
+ walkExportAllDeclaration(path22) {
2082
+ walkExportAllDeclaration(this, path22);
2083
+ }
2084
+ };
2085
+
2086
+ // src/js/taggedTemplateIgnore.ts
2087
+ function createTaggedTemplateIgnore({ matcher, names }) {
2088
+ const bindingIgnoreCache = /* @__PURE__ */ new Map();
2089
+ const taggedTemplateIgnoreCache = /* @__PURE__ */ new WeakMap();
2090
+ const seenBindings = /* @__PURE__ */ new Set();
2091
+ let singleCanonicalIgnoreName;
2092
+ let canonicalIgnoreNames;
2093
+ for (const item of names ?? []) {
2094
+ if (typeof item !== "string") {
2095
+ continue;
2096
+ }
2097
+ if (singleCanonicalIgnoreName === void 0) {
2098
+ singleCanonicalIgnoreName = item;
2099
+ continue;
2100
+ }
2101
+ if (item === singleCanonicalIgnoreName) {
2102
+ continue;
2103
+ }
2104
+ if (!canonicalIgnoreNames) {
2105
+ canonicalIgnoreNames = /* @__PURE__ */ new Set([singleCanonicalIgnoreName, item]);
2106
+ continue;
2107
+ }
2108
+ canonicalIgnoreNames.add(item);
2109
+ }
2110
+ const hasCanonicalIgnoreNames = singleCanonicalIgnoreName !== void 0;
2111
+ const matchesIgnoreName = (value) => {
2112
+ if (hasCanonicalIgnoreNames) {
2113
+ if (canonicalIgnoreNames) {
2114
+ if (canonicalIgnoreNames.has(value)) {
2115
+ return true;
2116
+ }
2117
+ } else if (value === singleCanonicalIgnoreName) {
2118
+ return true;
2119
+ }
2120
+ }
2121
+ return matcher(value);
2122
+ };
2123
+ const propertyMatches = (propertyPath) => {
2124
+ if (!propertyPath) {
2125
+ return false;
2126
+ }
2127
+ if (propertyPath.isIdentifier()) {
2128
+ return matchesIgnoreName(propertyPath.node.name);
2129
+ }
2130
+ if (propertyPath.isStringLiteral()) {
2131
+ return matchesIgnoreName(propertyPath.node.value);
2132
+ }
2133
+ return false;
2134
+ };
2135
+ const resolvesMemberExpressionToIgnore = (path22, seen) => {
2136
+ const propertyPath = path22.get("property");
2137
+ if (propertyMatches(propertyPath)) {
2138
+ return true;
2139
+ }
2140
+ const objectPath = path22.get("object");
2141
+ if (objectPath.isIdentifier()) {
2142
+ const scope = objectPath?.scope;
2143
+ const binding = scope?.getBinding?.(objectPath.node.name);
2144
+ if (binding) {
2145
+ return resolvesToWeappTwIgnore(binding, seen);
2146
+ }
2147
+ }
2148
+ return false;
2149
+ };
2150
+ const resolvesToWeappTwIgnore = (binding, seen) => {
2151
+ const cached = bindingIgnoreCache.get(binding);
2152
+ if (cached !== void 0) {
2153
+ return cached;
2154
+ }
2155
+ if (seen.has(binding)) {
2156
+ return false;
2157
+ }
2158
+ seen.add(binding);
2159
+ let result = false;
2160
+ const bindingPath = binding.path;
2161
+ if (bindingPath.isImportSpecifier()) {
2162
+ const imported = bindingPath.node.imported;
2163
+ if (imported.type === "Identifier" && matchesIgnoreName(imported.name)) {
2164
+ result = true;
2165
+ } else if (imported.type === "StringLiteral" && matchesIgnoreName(imported.value)) {
2166
+ result = true;
2167
+ }
2168
+ } else if (bindingPath.isVariableDeclarator()) {
2169
+ const init = bindingPath.get("init");
2170
+ if (init && init.node) {
2171
+ if (init.isIdentifier()) {
2172
+ const target = binding?.scope?.getBinding?.(init.node.name);
2173
+ if (target) {
2174
+ result = resolvesToWeappTwIgnore(target, seen);
2175
+ }
2176
+ } else if (init.isMemberExpression()) {
2177
+ result = resolvesMemberExpressionToIgnore(init, seen);
2178
+ }
2179
+ }
2180
+ }
2181
+ bindingIgnoreCache.set(binding, result);
2182
+ seen.delete(binding);
2183
+ return result;
2184
+ };
2185
+ const getEffectiveTagPath = (tagPath) => {
2186
+ let current = tagPath;
2187
+ while (true) {
2188
+ if (current.isParenthesizedExpression?.() || current.node.type === "ParenthesizedExpression") {
2189
+ current = current.get("expression");
2190
+ continue;
2191
+ }
2192
+ if (current.isTSAsExpression() || current.isTSTypeAssertion()) {
2193
+ current = current.get("expression");
2194
+ continue;
2195
+ }
2196
+ if (current.isTSNonNullExpression()) {
2197
+ current = current.get("expression");
2198
+ continue;
2199
+ }
2200
+ if (current.isTypeCastExpression?.()) {
2201
+ current = current.get("expression");
2202
+ continue;
2203
+ }
2204
+ if (current.isSequenceExpression()) {
2205
+ const expressions = current.get("expressions");
2206
+ const last = expressions.at(-1);
2207
+ if (last) {
2208
+ current = last;
2209
+ continue;
2210
+ }
2211
+ }
2212
+ if (current.isCallExpression?.() || current.node.type === "CallExpression") {
2213
+ const callee = current.get("callee");
2214
+ current = callee;
2215
+ continue;
2216
+ }
2217
+ break;
2218
+ }
2219
+ return current;
2220
+ };
2221
+ const evaluateTagPath = (tagPath, seen) => {
2222
+ if (tagPath.isCallExpression?.() || tagPath.node.type === "CallExpression") {
2223
+ const calleePath = tagPath.get("callee");
2224
+ return evaluateTagPath(calleePath, seen);
2225
+ }
2226
+ if (tagPath.isIdentifier()) {
2227
+ if (matchesIgnoreName(tagPath.node.name)) {
2228
+ return true;
2229
+ }
2230
+ const binding = tagPath?.scope?.getBinding?.(tagPath.node.name);
2231
+ if (binding) {
2232
+ return resolvesToWeappTwIgnore(binding, seen);
2233
+ }
2234
+ return false;
2235
+ }
2236
+ if (tagPath.isMemberExpression()) {
2237
+ return resolvesMemberExpressionToIgnore(tagPath, seen);
2238
+ }
2239
+ return false;
2240
+ };
2241
+ const computeIgnore = (tagPath) => {
2242
+ const cached = taggedTemplateIgnoreCache.get(tagPath.node);
2243
+ if (cached !== void 0) {
2244
+ return cached;
2245
+ }
2246
+ const effectiveTagPath = getEffectiveTagPath(tagPath);
2247
+ const effectiveCached = taggedTemplateIgnoreCache.get(effectiveTagPath.node);
2248
+ if (effectiveCached !== void 0) {
2249
+ taggedTemplateIgnoreCache.set(tagPath.node, effectiveCached);
2250
+ return effectiveCached;
2251
+ }
2252
+ seenBindings.clear();
2253
+ const result = evaluateTagPath(effectiveTagPath, seenBindings);
2254
+ taggedTemplateIgnoreCache.set(effectiveTagPath.node, result);
2255
+ taggedTemplateIgnoreCache.set(tagPath.node, result);
2256
+ return result;
2257
+ };
565
2258
  return {
566
- recordPath: location.recordPath,
567
- message,
568
- reason,
569
- onPatched
2259
+ shouldIgnore(tagPath) {
2260
+ return computeIgnore(tagPath);
2261
+ },
2262
+ getEffectiveTagPath
570
2263
  };
571
2264
  }
572
2265
 
573
- // src/tailwindcss/targets.ts
574
- 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;
2266
+ // src/js/babel.ts
2267
+ var EXPRESSION_WRAPPER_PREFIX = "(\n";
2268
+ var EXPRESSION_WRAPPER_SUFFIX = "\n)";
2269
+ var EMPTY_IGNORED_PATHS = /* @__PURE__ */ new WeakSet();
2270
+ var EMPTY_IMPORT_DECLARATIONS = /* @__PURE__ */ new Set();
2271
+ var EMPTY_EXPORT_DECLARATIONS = /* @__PURE__ */ new Set();
2272
+ var EMPTY_REQUIRE_CALL_PATHS = [];
2273
+ var ignoredTaggedTemplateMatcherCache = /* @__PURE__ */ new WeakMap();
2274
+ var defaultEvalHandler;
2275
+ function getIgnoredTaggedTemplateMatcher(options) {
2276
+ const cached = ignoredTaggedTemplateMatcherCache.get(options);
2277
+ if (cached) {
2278
+ return cached;
2279
+ }
2280
+ const created = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
2281
+ ignoredTaggedTemplateMatcherCache.set(options, created);
2282
+ return created;
2283
+ }
2284
+ function getDefaultEvalHandler() {
2285
+ if (!defaultEvalHandler) {
2286
+ throw new Error("Default JS eval handler is not initialized.");
590
2287
  }
591
- logger3.info("%s \u7ED1\u5B9A Tailwind CSS -> %s%s", label, displayPath, version);
2288
+ return defaultEvalHandler;
592
2289
  }
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";
634
- function _interopDefaultCompat(e) {
635
- return e && typeof e === "object" && "default" in e ? e.default : e;
2290
+ function analyzeSource(ast, options, handler, collectModuleMetadata = true) {
2291
+ const jsTokenUpdater = new JsTokenUpdater();
2292
+ const needScope = Boolean(options.ignoreCallExpressionIdentifiers && options.ignoreCallExpressionIdentifiers.length > 0);
2293
+ const ignoredPaths = needScope ? /* @__PURE__ */ new WeakSet() : EMPTY_IGNORED_PATHS;
2294
+ const walker = needScope ? new NodePathWalker({
2295
+ ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
2296
+ callback(path22) {
2297
+ ignoredPaths.add(path22);
2298
+ }
2299
+ }) : new NodePathWalker();
2300
+ let taggedTemplateIgnore;
2301
+ const hasTaggedTemplateIgnoreIdentifiers = Boolean(
2302
+ options.ignoreTaggedTemplateExpressionIdentifiers && options.ignoreTaggedTemplateExpressionIdentifiers.length > 0
2303
+ );
2304
+ function getTaggedTemplateIgnore() {
2305
+ if (!taggedTemplateIgnore) {
2306
+ taggedTemplateIgnore = createTaggedTemplateIgnore({
2307
+ matcher: getIgnoredTaggedTemplateMatcher(options),
2308
+ names: options.ignoreTaggedTemplateExpressionIdentifiers
2309
+ });
2310
+ }
2311
+ return taggedTemplateIgnore;
2312
+ }
2313
+ const targetPaths = [];
2314
+ const importDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_IMPORT_DECLARATIONS;
2315
+ const exportDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_EXPORT_DECLARATIONS;
2316
+ const requireCallPaths = collectModuleMetadata ? [] : EMPTY_REQUIRE_CALL_PATHS;
2317
+ const evalHandler = handler ?? getDefaultEvalHandler();
2318
+ const templateElementEnter = hasTaggedTemplateIgnoreIdentifiers ? (p) => {
2319
+ const pp = p.parentPath;
2320
+ if (pp.isTemplateLiteral()) {
2321
+ const ppp = pp.parentPath;
2322
+ if (isEvalPath(ppp)) {
2323
+ return;
2324
+ }
2325
+ if (ppp.isTaggedTemplateExpression()) {
2326
+ const tagPath = ppp.get("tag");
2327
+ if (getTaggedTemplateIgnore().shouldIgnore(tagPath)) {
2328
+ return;
2329
+ }
2330
+ }
2331
+ }
2332
+ targetPaths.push(p);
2333
+ } : (p) => {
2334
+ const pp = p.parentPath;
2335
+ if (pp.isTemplateLiteral()) {
2336
+ const ppp = pp.parentPath;
2337
+ if (isEvalPath(ppp)) {
2338
+ return;
2339
+ }
2340
+ }
2341
+ targetPaths.push(p);
2342
+ };
2343
+ const callExpressionEnter = !collectModuleMetadata && !needScope ? (p) => {
2344
+ if (isEvalPath(p)) {
2345
+ walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
2346
+ }
2347
+ } : (p) => {
2348
+ if (isEvalPath(p)) {
2349
+ walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
2350
+ return;
2351
+ }
2352
+ const calleePath = p.get("callee");
2353
+ if (collectModuleMetadata && calleePath.isIdentifier({ name: "require" }) && !p?.scope?.hasBinding?.("require")) {
2354
+ const args = p.get("arguments");
2355
+ if (Array.isArray(args) && args.length > 0) {
2356
+ const first = args[0];
2357
+ if (first?.isStringLiteral()) {
2358
+ requireCallPaths.push(first);
2359
+ }
2360
+ }
2361
+ }
2362
+ if (needScope) {
2363
+ walker.walkCallExpression(p);
2364
+ }
2365
+ };
2366
+ const traverseOptions = {
2367
+ StringLiteral: {
2368
+ enter(p) {
2369
+ if (isEvalPath(p.parentPath)) {
2370
+ return;
2371
+ }
2372
+ targetPaths.push(p);
2373
+ }
2374
+ },
2375
+ TemplateElement: {
2376
+ enter: templateElementEnter
2377
+ },
2378
+ CallExpression: {
2379
+ enter: callExpressionEnter
2380
+ },
2381
+ ...collectModuleMetadata ? {
2382
+ ImportDeclaration: {
2383
+ enter(p) {
2384
+ importDeclarations.add(p);
2385
+ }
2386
+ },
2387
+ ExportDeclaration: {
2388
+ enter(p) {
2389
+ exportDeclarations.add(p);
2390
+ }
2391
+ }
2392
+ } : {}
2393
+ };
2394
+ traverse(ast, { ...traverseOptions, noScope: !needScope });
2395
+ return {
2396
+ walker,
2397
+ jsTokenUpdater,
2398
+ ast,
2399
+ targetPaths,
2400
+ importDeclarations,
2401
+ exportDeclarations,
2402
+ requireCallPaths,
2403
+ ignoredPaths
2404
+ };
636
2405
  }
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
2406
+ function jsHandler(rawSource, options) {
2407
+ const shouldWrapExpression = Boolean(options.wrapExpression);
2408
+ const source = shouldWrapExpression ? `${EXPRESSION_WRAPPER_PREFIX}${rawSource}${EXPRESSION_WRAPPER_SUFFIX}` : rawSource;
2409
+ let ast;
2410
+ try {
2411
+ ast = babelParse(source, options.babelParserOptions);
2412
+ } catch (error) {
2413
+ return {
2414
+ code: rawSource,
2415
+ error
2416
+ };
647
2417
  }
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";
2418
+ const needsModuleMetadata = Boolean(options.moduleSpecifierReplacements || options.moduleGraph && options.filename);
2419
+ const analysis = analyzeSource(ast, options, jsHandler, needsModuleMetadata);
2420
+ const ms = processUpdatedSource(source, options, analysis);
2421
+ if (shouldWrapExpression) {
2422
+ const start = 0;
2423
+ const end = source.length;
2424
+ const prefixLength = EXPRESSION_WRAPPER_PREFIX.length;
2425
+ const suffixLength = EXPRESSION_WRAPPER_SUFFIX.length;
2426
+ ms.remove(start, start + prefixLength);
2427
+ ms.remove(end - suffixLength, end);
2428
+ }
2429
+ const result = {
2430
+ code: ms.toString()
2431
+ };
2432
+ if (options.generateMap) {
2433
+ Object.defineProperty(result, "map", {
2434
+ configurable: true,
2435
+ enumerable: true,
2436
+ get() {
2437
+ return ms.generateMap();
2438
+ }
2439
+ });
2440
+ }
2441
+ if (options.moduleGraph && options.filename) {
2442
+ const graph = new JsModuleGraph(
2443
+ {
2444
+ filename: options.filename,
2445
+ source: rawSource,
2446
+ analysis,
2447
+ handlerOptions: options
2448
+ },
2449
+ options.moduleGraph
2450
+ );
2451
+ const linked = graph.build();
2452
+ if (linked) {
2453
+ result.linked = linked;
2454
+ }
2455
+ }
2456
+ return result;
2457
+ }
2458
+ defaultEvalHandler = jsHandler;
665
2459
 
666
2460
  // src/wxml/utils/codegen/legacy-rewriter.ts
667
2461
  import MagicString2 from "magic-string";
@@ -905,9 +2699,273 @@ function formatOutputPath(target, baseDir) {
905
2699
  return relative.startsWith(".") ? relative : `.${path12.sep}${relative}`;
906
2700
  }
907
2701
 
2702
+ // src/cli/doctor.ts
2703
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
2704
+ import { createRequire as createRequire3 } from "module";
2705
+ import path13 from "path";
2706
+ import process13 from "process";
2707
+ import semver from "semver";
2708
+
2709
+ // src/cli/doctor/constants.ts
2710
+ var CONFIG_FILES = {
2711
+ tailwind: [
2712
+ "tailwind.config.js",
2713
+ "tailwind.config.cjs",
2714
+ "tailwind.config.mjs",
2715
+ "tailwind.config.ts"
2716
+ ],
2717
+ postcss: [
2718
+ "postcss.config.js",
2719
+ "postcss.config.cjs",
2720
+ "postcss.config.mjs",
2721
+ "postcss.config.ts"
2722
+ ],
2723
+ vite: ["vite.config.js", "vite.config.mjs", "vite.config.ts"],
2724
+ webpack: ["webpack.config.js", "webpack.config.cjs", "webpack.config.ts"]
2725
+ };
2726
+ var FRAMEWORK_DEPS = [
2727
+ ["@tarojs/taro", "Taro"],
2728
+ ["@dcloudio/uni-app", "uni-app"],
2729
+ ["@mpxjs/core", "MPX"],
2730
+ ["remax", "Remax"],
2731
+ ["rax", "Rax"]
2732
+ ];
2733
+
2734
+ // src/cli/doctor.ts
2735
+ function tryReadJson(file) {
2736
+ try {
2737
+ return JSON.parse(readFileSync4(file, "utf8"));
2738
+ } catch {
2739
+ return void 0;
2740
+ }
2741
+ }
2742
+ function findFirstExisting(cwd, files) {
2743
+ return files.find((file) => existsSync6(path13.join(cwd, file)));
2744
+ }
2745
+ function readProjectPackageJson(cwd) {
2746
+ return tryReadJson(path13.join(cwd, "package.json"));
2747
+ }
2748
+ function readDependencyVersion(cwd, packageName) {
2749
+ try {
2750
+ const requireFromCwd = createRequire3(path13.join(cwd, "package.json"));
2751
+ const packageJsonPath = requireFromCwd.resolve(`${packageName}/package.json`);
2752
+ return tryReadJson(packageJsonPath)?.version;
2753
+ } catch {
2754
+ return void 0;
2755
+ }
2756
+ }
2757
+ function collectDependencySpecs(pkg) {
2758
+ return {
2759
+ ...pkg?.dependencies ?? {},
2760
+ ...pkg?.devDependencies ?? {},
2761
+ ...pkg?.optionalDependencies ?? {},
2762
+ ...pkg?.peerDependencies ?? {}
2763
+ };
2764
+ }
2765
+ function detectPackageManager(cwd, pkg) {
2766
+ if (pkg?.packageManager) {
2767
+ return pkg.packageManager;
2768
+ }
2769
+ if (existsSync6(path13.join(cwd, "pnpm-lock.yaml"))) {
2770
+ return "pnpm";
2771
+ }
2772
+ if (existsSync6(path13.join(cwd, "package-lock.json"))) {
2773
+ return "npm";
2774
+ }
2775
+ if (existsSync6(path13.join(cwd, "yarn.lock"))) {
2776
+ return "yarn";
2777
+ }
2778
+ return void 0;
2779
+ }
2780
+ function detectFrameworks(deps) {
2781
+ return FRAMEWORK_DEPS.filter(([dependency]) => dependency in deps).map(([, label]) => label);
2782
+ }
2783
+ function addCheck(checks, check) {
2784
+ checks.push(check);
2785
+ }
2786
+ function summarizeChecks(checks) {
2787
+ return checks.reduce((summary, check) => {
2788
+ summary[check.status] += 1;
2789
+ return summary;
2790
+ }, { ok: 0, warn: 0, error: 0, info: 0 });
2791
+ }
2792
+ function hasDependency(deps, packageName) {
2793
+ return packageName in deps;
2794
+ }
2795
+ function getMajorVersion(version) {
2796
+ if (!version) {
2797
+ return void 0;
2798
+ }
2799
+ return semver.parse(version)?.major;
2800
+ }
2801
+ function getDependencyMajor(deps, packageName) {
2802
+ const spec = deps[packageName];
2803
+ return spec ? semver.minVersion(spec)?.major : void 0;
2804
+ }
2805
+ function createDoctorReport(options = {}) {
2806
+ const cwd = path13.resolve(options.cwd ?? process13.cwd());
2807
+ const nodeVersion = options.nodeVersion ?? process13.versions.node;
2808
+ const pkg = readProjectPackageJson(cwd);
2809
+ const deps = collectDependencySpecs(pkg);
2810
+ const checks = [];
2811
+ const packageManager = detectPackageManager(cwd, pkg);
2812
+ const frameworks = detectFrameworks(deps);
2813
+ const tailwindcssVersion = readDependencyVersion(cwd, "tailwindcss");
2814
+ const weappTailwindcssVersion = readDependencyVersion(cwd, "weapp-tailwindcss");
2815
+ const tailwindMajor = getMajorVersion(tailwindcssVersion) ?? getDependencyMajor(deps, "tailwindcss");
2816
+ const tailwindConfig = findFirstExisting(cwd, CONFIG_FILES.tailwind);
2817
+ const postcssConfig = findFirstExisting(cwd, CONFIG_FILES.postcss);
2818
+ const viteConfig = findFirstExisting(cwd, CONFIG_FILES.vite);
2819
+ const webpackConfig = findFirstExisting(cwd, CONFIG_FILES.webpack);
2820
+ addCheck(checks, pkg ? {
2821
+ id: "package-json",
2822
+ title: "package.json",
2823
+ status: "ok",
2824
+ message: "\u5DF2\u627E\u5230\u9879\u76EE package.json\u3002"
2825
+ } : {
2826
+ id: "package-json",
2827
+ title: "package.json",
2828
+ status: "error",
2829
+ message: "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709 package.json\u3002",
2830
+ suggestion: "\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u8FD0\u884C doctor\uFF0C\u6216\u901A\u8FC7 --cwd \u6307\u5411\u9879\u76EE\u6839\u76EE\u5F55\u3002"
2831
+ });
2832
+ addCheck(checks, semver.satisfies(nodeVersion, WEAPP_TW_REQUIRED_NODE_VERSION_RANGE) ? {
2833
+ id: "node-version",
2834
+ title: "Node.js",
2835
+ status: "ok",
2836
+ message: `\u5F53\u524D Node.js ${nodeVersion} \u6EE1\u8DB3\u7248\u672C\u8981\u6C42 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}\u3002`
2837
+ } : {
2838
+ id: "node-version",
2839
+ title: "Node.js",
2840
+ status: "error",
2841
+ message: `\u5F53\u524D Node.js ${nodeVersion} \u4E0D\u6EE1\u8DB3\u7248\u672C\u8981\u6C42 ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE}\u3002`,
2842
+ suggestion: "\u8BF7\u5347\u7EA7 Node.js \u540E\u518D\u5B89\u88C5\u6216\u6784\u5EFA weapp-tailwindcss \u9879\u76EE\u3002"
2843
+ });
2844
+ addCheck(checks, packageManager ? {
2845
+ id: "package-manager",
2846
+ title: "\u5305\u7BA1\u7406\u5668",
2847
+ status: packageManager.startsWith("pnpm") ? "ok" : "info",
2848
+ message: `\u68C0\u6D4B\u5230 ${packageManager}\u3002`
2849
+ } : {
2850
+ id: "package-manager",
2851
+ title: "\u5305\u7BA1\u7406\u5668",
2852
+ status: "info",
2853
+ message: "\u672A\u68C0\u6D4B\u5230 lockfile \u6216 packageManager \u5B57\u6BB5\u3002"
2854
+ });
2855
+ addCheck(checks, hasDependency(deps, "weapp-tailwindcss") || Boolean(weappTailwindcssVersion) ? {
2856
+ id: "weapp-tailwindcss",
2857
+ title: "weapp-tailwindcss",
2858
+ status: "ok",
2859
+ message: `\u68C0\u6D4B\u5230 weapp-tailwindcss${weappTailwindcssVersion ? `@${weappTailwindcssVersion}` : ""}\u3002`
2860
+ } : {
2861
+ id: "weapp-tailwindcss",
2862
+ title: "weapp-tailwindcss",
2863
+ status: "warn",
2864
+ message: "\u672A\u5728\u5F53\u524D\u9879\u76EE\u4F9D\u8D56\u4E2D\u68C0\u6D4B\u5230 weapp-tailwindcss\u3002",
2865
+ suggestion: "\u5982\u679C\u8FD9\u662F\u4E1A\u52A1\u9879\u76EE\uFF0C\u8BF7\u5B89\u88C5 weapp-tailwindcss \u5E76\u786E\u8BA4\u547D\u4EE4\u8FD0\u884C\u5728\u9879\u76EE\u6839\u76EE\u5F55\u3002"
2866
+ });
2867
+ addCheck(checks, hasDependency(deps, "tailwindcss") || Boolean(tailwindcssVersion) ? {
2868
+ id: "tailwindcss",
2869
+ title: "Tailwind CSS",
2870
+ status: "ok",
2871
+ message: `\u68C0\u6D4B\u5230 tailwindcss${tailwindcssVersion ? `@${tailwindcssVersion}` : ""}\u3002`
2872
+ } : {
2873
+ id: "tailwindcss",
2874
+ title: "Tailwind CSS",
2875
+ status: "error",
2876
+ message: "\u672A\u68C0\u6D4B\u5230 tailwindcss\u3002",
2877
+ suggestion: "\u8BF7\u5B89\u88C5 tailwindcss\uFF0C\u5E76\u786E\u8BA4\u4F9D\u8D56\u53EF\u4EE5\u4ECE\u5F53\u524D\u9879\u76EE\u89E3\u6790\u3002"
2878
+ });
2879
+ addCheck(checks, tailwindConfig ? {
2880
+ id: "tailwind-config",
2881
+ title: "Tailwind \u914D\u7F6E",
2882
+ status: "ok",
2883
+ message: `\u68C0\u6D4B\u5230 ${tailwindConfig}\u3002`
2884
+ } : {
2885
+ id: "tailwind-config",
2886
+ title: "Tailwind \u914D\u7F6E",
2887
+ status: tailwindMajor === 4 ? "info" : "warn",
2888
+ message: "\u672A\u68C0\u6D4B\u5230 tailwind.config.*\u3002",
2889
+ suggestion: tailwindMajor === 4 ? "Tailwind CSS v4 \u53EF\u4EE5\u91C7\u7528 CSS-first \u914D\u7F6E\uFF1B\u5982\u679C\u4F7F\u7528 v3 \u6216\u590D\u6742 content/source\uFF0C\u8BF7\u8865\u5145\u914D\u7F6E\u6587\u4EF6\u3002" : "\u8BF7\u786E\u8BA4 Tailwind content/source \u914D\u7F6E\u80FD\u591F\u8986\u76D6\u5C0F\u7A0B\u5E8F\u9875\u9762\u3001\u7EC4\u4EF6\u548C\u811A\u672C\u6587\u4EF6\u3002"
2890
+ });
2891
+ addCheck(checks, postcssConfig ? {
2892
+ id: "postcss-config",
2893
+ title: "PostCSS \u914D\u7F6E",
2894
+ status: "ok",
2895
+ message: `\u68C0\u6D4B\u5230 ${postcssConfig}\u3002`
2896
+ } : {
2897
+ id: "postcss-config",
2898
+ title: "PostCSS \u914D\u7F6E",
2899
+ status: viteConfig ? "info" : "warn",
2900
+ message: "\u672A\u68C0\u6D4B\u5230 postcss.config.*\u3002",
2901
+ suggestion: "\u5982\u679C\u901A\u8FC7 PostCSS \u63A5\u5165\uFF0C\u8BF7\u8865\u5145 postcss.config.*\uFF1B\u5982\u679C\u901A\u8FC7 Vite/Taro \u63D2\u4EF6\u63A5\u5165\uFF0C\u53EF\u5FFD\u7565\u6B64\u9879\u3002"
2902
+ });
2903
+ if (tailwindMajor === 4 && postcssConfig && !hasDependency(deps, "@tailwindcss/postcss")) {
2904
+ addCheck(checks, {
2905
+ id: "tailwindcss-v4-postcss",
2906
+ title: "Tailwind v4 PostCSS",
2907
+ status: "warn",
2908
+ message: "Tailwind CSS v4 \u9879\u76EE\u5B58\u5728 PostCSS \u914D\u7F6E\uFF0C\u4F46\u672A\u68C0\u6D4B\u5230 @tailwindcss/postcss\u3002",
2909
+ suggestion: "\u5982\u679C PostCSS \u914D\u7F6E\u4E2D\u4ECD\u76F4\u63A5\u4F7F\u7528 tailwindcss\uFF0C\u8BF7\u8FC1\u79FB\u5230 @tailwindcss/postcss\u3002"
2910
+ });
2911
+ }
2912
+ addCheck(checks, frameworks.length > 0 ? {
2913
+ id: "framework",
2914
+ title: "\u6846\u67B6\u8BC6\u522B",
2915
+ status: "ok",
2916
+ message: `\u68C0\u6D4B\u5230 ${frameworks.join(", ")}\u3002`
2917
+ } : {
2918
+ id: "framework",
2919
+ title: "\u6846\u67B6\u8BC6\u522B",
2920
+ status: "info",
2921
+ message: "\u672A\u4ECE\u4F9D\u8D56\u4E2D\u8BC6\u522B\u51FA Taro\u3001uni-app\u3001MPX\u3001Remax \u6216 Rax\u3002"
2922
+ });
2923
+ addCheck(checks, viteConfig || webpackConfig ? {
2924
+ id: "bundler-config",
2925
+ title: "\u6784\u5EFA\u5668\u914D\u7F6E",
2926
+ status: "ok",
2927
+ message: `\u68C0\u6D4B\u5230 ${[viteConfig, webpackConfig].filter(Boolean).join(", ")}\u3002`
2928
+ } : {
2929
+ id: "bundler-config",
2930
+ title: "\u6784\u5EFA\u5668\u914D\u7F6E",
2931
+ status: "info",
2932
+ message: "\u672A\u68C0\u6D4B\u5230 vite.config.* \u6216 webpack.config.*\u3002"
2933
+ });
2934
+ return {
2935
+ cwd,
2936
+ nodeVersion,
2937
+ detected: {
2938
+ packageManager,
2939
+ frameworks,
2940
+ tailwindcssVersion,
2941
+ weappTailwindcssVersion
2942
+ },
2943
+ summary: summarizeChecks(checks),
2944
+ checks
2945
+ };
2946
+ }
2947
+ function hasDoctorFailure(report, strict = false) {
2948
+ return report.summary.error > 0 || strict && report.summary.warn > 0;
2949
+ }
2950
+ function formatDoctorReport(report) {
2951
+ const lines = [
2952
+ `weapp-tailwindcss doctor`,
2953
+ `cwd: ${report.cwd}`,
2954
+ `summary: ${report.summary.error} error, ${report.summary.warn} warn, ${report.summary.ok} ok, ${report.summary.info} info`,
2955
+ ""
2956
+ ];
2957
+ for (const check of report.checks) {
2958
+ lines.push(`[${check.status}] ${check.title}: ${check.message}`);
2959
+ if (check.suggestion) {
2960
+ lines.push(` -> ${check.suggestion}`);
2961
+ }
2962
+ }
2963
+ return lines.join("\n");
2964
+ }
2965
+
908
2966
  // src/cli/helpers.ts
909
2967
  import { mkdir as mkdir2 } from "fs/promises";
910
- import process15 from "process";
2968
+ import process16 from "process";
911
2969
 
912
2970
  // src/logger/index.ts
913
2971
  import { logger as logger12 } from "@weapp-tailwindcss/logger";
@@ -965,19 +3023,19 @@ function toBoolean(value, fallback) {
965
3023
  }
966
3024
 
967
3025
  // src/cli/helpers/options/resolve.ts
968
- import path13 from "path";
969
- import process13 from "process";
3026
+ import path14 from "path";
3027
+ import process14 from "process";
970
3028
  function resolveCliCwd(value) {
971
3029
  const raw = readStringOption("cwd", value);
972
3030
  if (!raw) {
973
3031
  return void 0;
974
3032
  }
975
- return path13.isAbsolute(raw) ? path13.normalize(raw) : path13.resolve(process13.cwd(), raw);
3033
+ return path14.isAbsolute(raw) ? path14.normalize(raw) : path14.resolve(process14.cwd(), raw);
976
3034
  }
977
3035
 
978
3036
  // src/cli/helpers/patch-cwd.ts
979
- import path14 from "path";
980
- import process14 from "process";
3037
+ import path15 from "path";
3038
+ import process15 from "process";
981
3039
 
982
3040
  // src/tailwindcss/index.ts
983
3041
  import { getPackageInfoSync } from "local-pkg";
@@ -990,7 +3048,7 @@ function normalizeCandidatePath(baseDir, candidate) {
990
3048
  if (!candidate) {
991
3049
  return void 0;
992
3050
  }
993
- return path14.isAbsolute(candidate) ? path14.normalize(candidate) : path14.resolve(baseDir, candidate);
3051
+ return path15.isAbsolute(candidate) ? path15.normalize(candidate) : path15.resolve(baseDir, candidate);
994
3052
  }
995
3053
  function detectTailwindWorkspace(paths) {
996
3054
  for (const candidate of paths) {
@@ -1004,15 +3062,15 @@ function detectTailwindWorkspace(paths) {
1004
3062
  }
1005
3063
  return void 0;
1006
3064
  }
1007
- function resolvePatchDefaultCwd(currentCwd = process14.cwd()) {
1008
- const baseDir = path14.normalize(currentCwd);
1009
- const explicitCwd = normalizeCandidatePath(baseDir, process14.env.WEAPP_TW_PATCH_CWD);
3065
+ function resolvePatchDefaultCwd(currentCwd = process15.cwd()) {
3066
+ const baseDir = path15.normalize(currentCwd);
3067
+ const explicitCwd = normalizeCandidatePath(baseDir, process15.env.WEAPP_TW_PATCH_CWD);
1010
3068
  if (explicitCwd) {
1011
3069
  return explicitCwd;
1012
3070
  }
1013
3071
  const workspaceRoot = findWorkspaceRoot(baseDir);
1014
- const initCwd = normalizeCandidatePath(baseDir, process14.env.INIT_CWD);
1015
- const localPrefix = normalizeCandidatePath(baseDir, process14.env.npm_config_local_prefix);
3072
+ const initCwd = normalizeCandidatePath(baseDir, process15.env.INIT_CWD);
3073
+ const localPrefix = normalizeCandidatePath(baseDir, process15.env.npm_config_local_prefix);
1016
3074
  const candidates = [
1017
3075
  baseDir,
1018
3076
  workspaceRoot,
@@ -1033,7 +3091,7 @@ async function ensureDir(dir) {
1033
3091
  function handleCliError(error) {
1034
3092
  if (error instanceof Error) {
1035
3093
  logger12.error(error.message);
1036
- if (error.stack && process15.env.WEAPP_TW_DEBUG === "1") {
3094
+ if (error.stack && process16.env.WEAPP_TW_DEBUG === "1") {
1037
3095
  logger12.error(error.stack);
1038
3096
  }
1039
3097
  } else {
@@ -1046,13 +3104,13 @@ function commandAction(handler) {
1046
3104
  await handler(...args);
1047
3105
  } catch (error) {
1048
3106
  handleCliError(error);
1049
- process15.exitCode = 1;
3107
+ process16.exitCode = 1;
1050
3108
  }
1051
3109
  };
1052
3110
  }
1053
3111
 
1054
3112
  // src/cli/mount-options.ts
1055
- import process17 from "process";
3113
+ import process18 from "process";
1056
3114
 
1057
3115
  // src/cli/mount-options/patch-status.ts
1058
3116
  function formatStatusFilesHint(files) {
@@ -1127,24 +3185,24 @@ function buildExtendLengthUnitsOverride(options) {
1127
3185
  }
1128
3186
 
1129
3187
  // src/cli/workspace.ts
1130
- import path19 from "path";
1131
- import process16 from "process";
3188
+ import path20 from "path";
3189
+ import process17 from "process";
1132
3190
 
1133
3191
  // src/cli/workspace/package-dirs.ts
1134
- import { existsSync as existsSync8 } from "fs";
1135
- import path17 from "path";
3192
+ import { existsSync as existsSync9 } from "fs";
3193
+ import path18 from "path";
1136
3194
  import fg from "fast-glob";
1137
3195
 
1138
3196
  // src/cli/workspace/workspace-globs.ts
1139
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
1140
- import path15 from "path";
3197
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
3198
+ import path16 from "path";
1141
3199
  import { parse as parseYaml } from "yaml";
1142
3200
 
1143
3201
  // src/cli/workspace/workspace-io.ts
1144
- import { readFileSync as readFileSync4 } from "fs";
1145
- function tryReadJson(file) {
3202
+ import { readFileSync as readFileSync5 } from "fs";
3203
+ function tryReadJson2(file) {
1146
3204
  try {
1147
- const content = readFileSync4(file, "utf8");
3205
+ const content = readFileSync5(file, "utf8");
1148
3206
  return JSON.parse(content);
1149
3207
  } catch {
1150
3208
  return void 0;
@@ -1153,8 +3211,8 @@ function tryReadJson(file) {
1153
3211
 
1154
3212
  // src/cli/workspace/workspace-globs.ts
1155
3213
  function parseWorkspaceGlobsFromPackageJson(workspaceRoot) {
1156
- const pkgJsonPath = path15.join(workspaceRoot, "package.json");
1157
- const pkg = tryReadJson(pkgJsonPath);
3214
+ const pkgJsonPath = path16.join(workspaceRoot, "package.json");
3215
+ const pkg = tryReadJson2(pkgJsonPath);
1158
3216
  if (!pkg?.workspaces) {
1159
3217
  return [];
1160
3218
  }
@@ -1167,12 +3225,12 @@ function parseWorkspaceGlobsFromPackageJson(workspaceRoot) {
1167
3225
  return [];
1168
3226
  }
1169
3227
  function parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot) {
1170
- const workspaceFile = path15.join(workspaceRoot, "pnpm-workspace.yaml");
1171
- if (!existsSync6(workspaceFile)) {
3228
+ const workspaceFile = path16.join(workspaceRoot, "pnpm-workspace.yaml");
3229
+ if (!existsSync7(workspaceFile)) {
1172
3230
  return [];
1173
3231
  }
1174
3232
  try {
1175
- const parsed = parseYaml(readFileSync5(workspaceFile, "utf8"));
3233
+ const parsed = parseYaml(readFileSync6(workspaceFile, "utf8"));
1176
3234
  return Array.isArray(parsed?.packages) ? parsed.packages.filter(Boolean) : [];
1177
3235
  } catch {
1178
3236
  return [];
@@ -1180,16 +3238,16 @@ function parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot) {
1180
3238
  }
1181
3239
 
1182
3240
  // src/cli/workspace/workspace-lock.ts
1183
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
1184
- import path16 from "path";
3241
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
3242
+ import path17 from "path";
1185
3243
  import { parse as parseYaml2 } from "yaml";
1186
3244
  function parseImportersFromLock(workspaceRoot) {
1187
- const lockPath = path16.join(workspaceRoot, "pnpm-lock.yaml");
1188
- if (!existsSync7(lockPath)) {
3245
+ const lockPath = path17.join(workspaceRoot, "pnpm-lock.yaml");
3246
+ if (!existsSync8(lockPath)) {
1189
3247
  return [];
1190
3248
  }
1191
3249
  try {
1192
- const parsed = parseYaml2(readFileSync6(lockPath, "utf8"));
3250
+ const parsed = parseYaml2(readFileSync7(lockPath, "utf8"));
1193
3251
  const importers = parsed?.importers;
1194
3252
  if (!importers) {
1195
3253
  return [];
@@ -1198,7 +3256,7 @@ function parseImportersFromLock(workspaceRoot) {
1198
3256
  if (!key || key === ".") {
1199
3257
  return workspaceRoot;
1200
3258
  }
1201
- return path16.join(workspaceRoot, key);
3259
+ return path17.join(workspaceRoot, key);
1202
3260
  });
1203
3261
  } catch {
1204
3262
  return [];
@@ -1211,7 +3269,7 @@ var TRAILING_SLASH_RE = /\/+$/;
1211
3269
  async function resolveWorkspacePackageDirs(workspaceRoot) {
1212
3270
  const dirs = /* @__PURE__ */ new Set();
1213
3271
  for (const importerDir of parseImportersFromLock(workspaceRoot)) {
1214
- dirs.add(path17.normalize(importerDir));
3272
+ dirs.add(path18.normalize(importerDir));
1215
3273
  }
1216
3274
  if (!dirs.size) {
1217
3275
  let globs = parseWorkspaceGlobsFromWorkspaceFile(workspaceRoot);
@@ -1231,13 +3289,13 @@ async function resolveWorkspacePackageDirs(workspaceRoot) {
1231
3289
  ignore: ["**/node_modules/**", "**/.git/**"]
1232
3290
  });
1233
3291
  for (const file of packageJsonFiles) {
1234
- dirs.add(path17.normalize(path17.dirname(file)));
3292
+ dirs.add(path18.normalize(path18.dirname(file)));
1235
3293
  }
1236
3294
  }
1237
3295
  }
1238
- const rootPkg = path17.join(workspaceRoot, "package.json");
1239
- if (existsSync8(rootPkg)) {
1240
- dirs.add(path17.normalize(workspaceRoot));
3296
+ const rootPkg = path18.join(workspaceRoot, "package.json");
3297
+ if (existsSync9(rootPkg)) {
3298
+ dirs.add(path18.normalize(workspaceRoot));
1241
3299
  }
1242
3300
  return [...dirs];
1243
3301
  }
@@ -1246,9 +3304,9 @@ async function resolveWorkspacePackageDirs(workspaceRoot) {
1246
3304
  import { normalizeOptions, TailwindcssPatcher as TailwindcssPatcher2 } from "tailwindcss-patch";
1247
3305
 
1248
3306
  // src/cli/workspace/patch-utils.ts
1249
- import path18 from "path";
3307
+ import path19 from "path";
1250
3308
  function formatDisplayName(workspaceRoot, dir, name) {
1251
- const relative = path18.relative(workspaceRoot, dir) || ".";
3309
+ const relative = path19.relative(workspaceRoot, dir) || ".";
1252
3310
  return name ? `${name} (${relative})` : relative;
1253
3311
  }
1254
3312
  function summarizeWorkspaceResults(results) {
@@ -1321,7 +3379,7 @@ async function patchWorkspacePackage(workspaceRoot, dir, pkgName, options) {
1321
3379
 
1322
3380
  // src/cli/workspace.ts
1323
3381
  async function patchWorkspace(options) {
1324
- const cwd = options.cwd ?? process16.cwd();
3382
+ const cwd = options.cwd ?? process17.cwd();
1325
3383
  const workspaceRoot = findWorkspaceRoot(cwd) ?? cwd;
1326
3384
  const packageDirs = await resolveWorkspacePackageDirs(workspaceRoot);
1327
3385
  if (packageDirs.length === 0) {
@@ -1330,8 +3388,8 @@ async function patchWorkspace(options) {
1330
3388
  }
1331
3389
  const results = [];
1332
3390
  for (const dir of packageDirs) {
1333
- const pkgJsonPath = path19.join(dir, "package.json");
1334
- const pkgJson = tryReadJson(pkgJsonPath);
3391
+ const pkgJsonPath = path20.join(dir, "package.json");
3392
+ const pkgJson = tryReadJson2(pkgJsonPath);
1335
3393
  results.push(await patchWorkspacePackage(workspaceRoot, dir, pkgJson?.name, options));
1336
3394
  }
1337
3395
  summarizeWorkspaceResults(results);
@@ -1341,7 +3399,7 @@ async function patchWorkspace(options) {
1341
3399
  function handleCliError2(error) {
1342
3400
  if (error instanceof Error) {
1343
3401
  logger12.error(error.message);
1344
- if (error.stack && process17.env.WEAPP_TW_DEBUG === "1") {
3402
+ if (error.stack && process18.env.WEAPP_TW_DEBUG === "1") {
1345
3403
  logger12.error(error.stack);
1346
3404
  }
1347
3405
  } else {
@@ -1354,7 +3412,7 @@ function withCommandErrorHandling(handler) {
1354
3412
  return await handler(ctx, next);
1355
3413
  } catch (error) {
1356
3414
  handleCliError2(error);
1357
- process17.exitCode = 1;
3415
+ process18.exitCode = 1;
1358
3416
  return void 0;
1359
3417
  }
1360
3418
  });
@@ -1464,14 +3522,14 @@ var mountOptions = {
1464
3522
  // src/cli/vscode-entry.ts
1465
3523
  import { constants } from "fs";
1466
3524
  import { access, writeFile as writeFile2 } from "fs/promises";
1467
- import path20 from "path";
3525
+ import path21 from "path";
1468
3526
  var DEFAULT_VSCODE_ENTRY_OUTPUT = ".vscode/weapp-tailwindcss.intellisense.css";
1469
3527
  var DEFAULT_VSCODE_SOURCES = [
1470
3528
  'not "./dist"',
1471
3529
  'not "./unpackage"',
1472
3530
  "./src/**/*.{wxml,axml,swan,qml,ttml,ux,uts}",
1473
- "./src/**/*.{js,jsx,ts,tsx}",
1474
- "./src/**/*.{vue,svelte,html,md,mdx}"
3531
+ "./src/**/*.{js,jsx,ts,tsx,mjs,cjs,wxs,sjs}",
3532
+ "./src/**/*.{vue,svelte,mpx,html,md,mdx}"
1475
3533
  ];
1476
3534
  var SINGLE_QUOTE = "'";
1477
3535
  var DOUBLE_QUOTE = '"';
@@ -1537,16 +3595,16 @@ function formatSource(pattern) {
1537
3595
  }
1538
3596
  function resolveOutputPath(baseDir, output) {
1539
3597
  const target = output ?? DEFAULT_VSCODE_ENTRY_OUTPUT;
1540
- return path20.isAbsolute(target) ? path20.normalize(target) : path20.resolve(baseDir, target);
3598
+ return path21.isAbsolute(target) ? path21.normalize(target) : path21.resolve(baseDir, target);
1541
3599
  }
1542
3600
  function resolveCssEntry(baseDir, entry) {
1543
- return path20.isAbsolute(entry) ? path20.normalize(entry) : path20.resolve(baseDir, entry);
3601
+ return path21.isAbsolute(entry) ? path21.normalize(entry) : path21.resolve(baseDir, entry);
1544
3602
  }
1545
3603
  function toRelativeImport(fromFile, targetFile) {
1546
- const fromDir = path20.dirname(fromFile);
1547
- let relative = path20.relative(fromDir, targetFile);
3604
+ const fromDir = path21.dirname(fromFile);
3605
+ let relative = path21.relative(fromDir, targetFile);
1548
3606
  if (!relative) {
1549
- relative = path20.basename(targetFile);
3607
+ relative = path21.basename(targetFile);
1550
3608
  }
1551
3609
  if (!relative.startsWith(".")) {
1552
3610
  relative = `./${relative}`;
@@ -1558,7 +3616,7 @@ async function generateVscodeIntellisenseEntry(options) {
1558
3616
  const cssEntryPath = resolveCssEntry(baseDir, options.cssEntry);
1559
3617
  await assertFileExists(cssEntryPath);
1560
3618
  const outputPath = resolveOutputPath(baseDir, options.output);
1561
- await ensureDir(path20.dirname(outputPath));
3619
+ await ensureDir(path21.dirname(outputPath));
1562
3620
  await assertCanWrite(outputPath, options.force);
1563
3621
  const sources = options.sources && options.sources.length > 0 ? options.sources : DEFAULT_VSCODE_SOURCES;
1564
3622
  const formattedSources = sources.map(formatSource).filter((statement) => Boolean(statement));
@@ -1583,10 +3641,10 @@ async function generateVscodeIntellisenseEntry(options) {
1583
3641
  }
1584
3642
 
1585
3643
  // src/cli.ts
1586
- process18.title = "node (weapp-tailwindcss)";
1587
- if (semver.lt(process18.versions.node, WEAPP_TW_REQUIRED_NODE_VERSION)) {
3644
+ process19.title = "node (weapp-tailwindcss)";
3645
+ if (!semver2.satisfies(process19.versions.node, WEAPP_TW_REQUIRED_NODE_VERSION_RANGE)) {
1588
3646
  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.`
3647
+ `You are using Node.js ${process19.versions.node}. For weapp-tailwindcss, Node.js version ${WEAPP_TW_REQUIRED_NODE_VERSION_RANGE} is required.`
1590
3648
  );
1591
3649
  }
1592
3650
  var cli = createTailwindcssPatchCli({
@@ -1596,7 +3654,7 @@ var cli = createTailwindcssPatchCli({
1596
3654
  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
3655
  commandAction(async (options) => {
1598
3656
  const resolvedCwd = resolveCliCwd(options.cwd);
1599
- const baseDir = resolvedCwd ?? process18.cwd();
3657
+ const baseDir = resolvedCwd ?? process19.cwd();
1600
3658
  const cssEntry = readStringOption("css", options.css);
1601
3659
  if (!cssEntry) {
1602
3660
  throw new Error('Option "--css" is required.');
@@ -1616,6 +3674,20 @@ cli.command("vscode-entry", "Generate a VS Code helper CSS for Tailwind IntelliS
1616
3674
  );
1617
3675
  })
1618
3676
  );
3677
+ 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(
3678
+ commandAction(async (options) => {
3679
+ const resolvedCwd = resolveCliCwd(options.cwd);
3680
+ const report = createDoctorReport({ cwd: resolvedCwd });
3681
+ if (toBoolean(options.json, false)) {
3682
+ logger12.log(JSON.stringify(report, null, 2));
3683
+ } else {
3684
+ logger12.log(formatDoctorReport(report));
3685
+ }
3686
+ if (hasDoctorFailure(report, toBoolean(options.strict, false))) {
3687
+ process19.exitCode = 1;
3688
+ }
3689
+ })
3690
+ );
1619
3691
  cli.help();
1620
- cli.version(process18.env.npm_package_version ?? "0.0.0");
3692
+ cli.version(process19.env.npm_package_version ?? "0.0.0");
1621
3693
  cli.parse();