weapp-tailwindcss 4.12.0-alpha.1 → 4.12.0-alpha.2

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