weapp-vite 7.5.0 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +14 -6
  2. package/THIRD_PARTY_NOTICES.md +60 -0
  3. package/bin/bootstrap.js +9 -4
  4. package/bin/bootstrap.test.ts +82 -1
  5. package/bin/nodeVersionWarning.js +17 -0
  6. package/bin/nodeVersionWarning.test.ts +30 -0
  7. package/dist/action-BD56SQh4.mjs +254 -0
  8. package/dist/action-CPtgEl6p.mjs +94 -0
  9. package/dist/action-le0bNff_.mjs +1102 -0
  10. package/dist/action-ytG5oFAw.mjs +138 -0
  11. package/dist/action-zmJrU8PC.mjs +245 -0
  12. package/dist/{analyze-ZJUvEdaY.mjs → analyze-DCZo-sJd.mjs} +4 -71
  13. package/dist/artifacts-TrTX9_jj.mjs +104 -0
  14. package/dist/assets-XyhpYtGl.mjs +630 -0
  15. package/dist/auto-import-components/resolvers.d.mts +1 -1
  16. package/dist/auto-import-components/resolvers.mjs +1 -1
  17. package/dist/auto-import-presets/wevu-router.d.mts +1 -1
  18. package/dist/auto-import-presets/wevu-router.mjs +1 -1
  19. package/dist/auto-import-presets/wevu.d.mts +1 -1
  20. package/dist/auto-import-presets/wevu.mjs +1 -1
  21. package/dist/auto-import-presets.d.mts +2 -2
  22. package/dist/auto-import-presets.mjs +2 -2
  23. package/dist/auto-routes.d.mts +1 -3
  24. package/dist/auto-routes.mjs +3 -4
  25. package/dist/{budget-BD7VqLCl.d.mts → budget-DTPngJU0.d.mts} +1 -10
  26. package/dist/budget-_Mu-4GKn.mjs +63 -0
  27. package/dist/builtProject-B145uOt5.mjs +534 -0
  28. package/dist/{package-7swhyLmf.mjs → classifier-CNTJOYQL.mjs} +5 -9
  29. package/dist/cli-acceptance.mjs +3 -4
  30. package/dist/cli.mjs +142 -4569
  31. package/dist/{config-DRGcCi3h.mjs → config-59ZWhCIf.mjs} +1 -2
  32. package/dist/{config-V0L-IAJf.d.mts → config-BNx2BODw.d.mts} +145 -150
  33. package/dist/config.d.mts +2 -2
  34. package/dist/config.mjs +3 -3
  35. package/dist/{constants-DEZdcsMn.mjs → constants-BOe8mgqL.mjs} +2 -4
  36. package/dist/{createCompilerContextInstance-DJH_P_nZ.mjs → createCompilerContextInstance-BXSdH2E8.mjs} +19930 -14019
  37. package/dist/{createContext-BqYzHhY9.mjs → createContext-W0TeXxbo.mjs} +7 -5
  38. package/dist/dashboard/analyze.d.mts +1 -7
  39. package/dist/dashboard/analyze.mjs +3 -1
  40. package/dist/dashboard/vite.d.mts +2 -4
  41. package/dist/dashboard/vite.mjs +1 -2
  42. package/dist/dashboard.d.mts +2 -2
  43. package/dist/dashboard.mjs +1733 -1
  44. package/dist/dashboardTransport-C9290QgS.mjs +15 -0
  45. package/dist/{dashboardViteBridge-Dy3nAD4m.mjs → dashboardViteBridge-B7QgQo94.mjs} +11 -11
  46. package/dist/{dev-fR5GiJRO.mjs → dev-D1QSExwk.mjs} +6 -3
  47. package/dist/devProvider-Bcvz5nu4.mjs +4966 -0
  48. package/dist/docs/README.md +14 -6
  49. package/dist/docs/ai-workflows.md +2 -0
  50. package/dist/docs/mcp.md +11 -1
  51. package/dist/docs/troubleshooting.md +16 -0
  52. package/dist/docs/vue-sfc.md +25 -2
  53. package/dist/docs/weapp-config.md +29 -0
  54. package/dist/docs/wevu-authoring.md +2 -0
  55. package/dist/doctor-worker.mjs +5 -5
  56. package/dist/doctor.d.mts +2 -8
  57. package/dist/doctor.mjs +24 -31
  58. package/dist/engine-Mnnm_ALP.mjs +53 -0
  59. package/dist/file-5eEfbK60.mjs +1 -0
  60. package/dist/{file-sC3jD7Fh.mjs → file-D8mp5GmB.mjs} +50 -26
  61. package/dist/{files-BqxFIPRp.mjs → files-Cy9jURJu.mjs} +1 -2
  62. package/dist/forwardConsole-D2Q0RIqc.mjs +509 -0
  63. package/dist/getInstance-BXNVH7sU.mjs +1 -0
  64. package/dist/{getInstance-DiGSzBNI.mjs → getInstance-DfNlbr-X.mjs} +2 -3
  65. package/dist/history-dKxzoHmN.mjs +774 -0
  66. package/dist/i18n.d.mts +1 -3
  67. package/dist/i18n.mjs +1 -2
  68. package/dist/{index-C9HjUX5c.d.mts → index-DIZJRrvK.d.mts} +1 -24
  69. package/dist/{index-CaXAtb9e.d.mts → index-SnaW3cvA.d.mts} +0 -12
  70. package/dist/index.d.mts +3 -7
  71. package/dist/index.mjs +6 -6
  72. package/dist/{json-BL8Dhhk6.mjs → json-Cvon2mw5.mjs} +1 -2
  73. package/dist/json.d.mts +1 -1
  74. package/dist/json.mjs +1 -1
  75. package/dist/lib-CJyMBzoe.mjs +140 -0
  76. package/dist/{lifecycle-BROTlwSL.mjs → lifecycle-CUo8PMQc.mjs} +123 -33
  77. package/dist/{loadConfig-C3BQhz7F.mjs → loadConfig-CKIdfW4o.mjs} +2 -3
  78. package/dist/loadConfig-D4WGJcYp.mjs +1 -0
  79. package/dist/logBuildAppFinish-DOBoof6S.mjs +54 -0
  80. package/dist/mcp-D88QvQgG.mjs +84 -0
  81. package/dist/{mcp-Cj8Maqo6.mjs → mcp-ovJgl1N9.mjs} +2 -4
  82. package/dist/mcp.d.mts +1 -3
  83. package/dist/mcp.mjs +1 -1
  84. package/dist/mcpClient-C8JzVZ46.mjs +283 -0
  85. package/dist/{processCleanup-B6KA30Zc.mjs → metadata-HlDKtlsu.mjs} +2 -21
  86. package/dist/nodeEnv-zq1EymWj.mjs +6 -0
  87. package/dist/openIde-QoYKhuuM.mjs +643 -0
  88. package/dist/options-Cz8vZ-0w.mjs +33 -0
  89. package/dist/{chunkStrategy-DRA5WpB-.mjs → package-DR62fAzP.mjs} +32 -31
  90. package/dist/path-E1OjBJAl.mjs +43 -0
  91. package/dist/{platform-CnkySBKz.mjs → platform-BiMpsZIb.mjs} +1 -2
  92. package/dist/{pluginHost--CaeyWpA.mjs → pluginHost-vn8Vty1J.mjs} +1 -2
  93. package/dist/processCleanup-DzB64WI8.mjs +18 -0
  94. package/dist/{protocol-vg8HGJ4n.mjs → protocol-HiSJRrSO.mjs} +43 -41
  95. package/dist/reader-wzPH_W8A.mjs +92 -0
  96. package/dist/realpathScope-DwlLaCk3.mjs +22 -0
  97. package/dist/report-PJVyo-UZ.mjs +105 -0
  98. package/dist/{path-doV773b7.mjs → resolvedId-DaxPh_yV.mjs} +5 -50
  99. package/dist/{resolvers-Dod-euqX.mjs → resolvers-CKYqmRD_.mjs} +10 -20
  100. package/dist/resolvers.d.mts +1 -1
  101. package/dist/resolvers.mjs +1 -1
  102. package/dist/{routes-C7fCmf92.d.mts → routes-DvAFX29h.d.mts} +0 -2
  103. package/dist/{runtime-Ee2HY6gR.d.mts → runtime-BL4RjBRa.d.mts} +1 -9
  104. package/dist/runtime-CKtMVERT.mjs +42 -0
  105. package/dist/{runtime-D6VCNhNY.mjs → runtime-DDUCb7pP.mjs} +4 -8
  106. package/dist/runtime.d.mts +1 -1
  107. package/dist/runtime.mjs +1 -1
  108. package/dist/schematics-DikfOjMD.mjs +90 -0
  109. package/dist/{session-PskhD-nZ.mjs → session-COrQJYif.mjs} +81 -21
  110. package/dist/test.d.mts +1 -3
  111. package/dist/test.mjs +54 -30
  112. package/dist/types-BK2EQ3Jm.d.mts +37 -0
  113. package/dist/{types-CgZn5X6j.d.mts → types-e2BMP9NU.d.mts} +1 -4
  114. package/dist/types.d.mts +4 -4
  115. package/dist/{upload-D4msblBf.mjs → upload-Chal5b3w.mjs} +118 -24
  116. package/dist/upload-worker.mjs +3 -5
  117. package/dist/{utils-CJSCgEj6.mjs → utils-CTGSZp4j.mjs} +72 -146
  118. package/dist/vite.d.mts +2 -4
  119. package/dist/vite.mjs +55 -21
  120. package/dist/volar.mjs +1 -2
  121. package/dist/{wevu-BQWUU7br.mjs → wevu-BaihCXO9.mjs} +1 -2
  122. package/dist/wevu-DTtSOyxB.d.mts +3 -0
  123. package/dist/{wevu-router-Dg1LnBlg.mjs → wevu-router-BIoxDbnu.mjs} +1 -2
  124. package/dist/wevu-router-CdWurGQ4.d.mts +3 -0
  125. package/dist/wxs-7V7MPzeW.mjs +1 -0
  126. package/dist/wxs-BdHHXltv.mjs +110 -0
  127. package/package.json +62 -53
  128. package/dist/dashboard-DvqF3Key.mjs +0 -1842
  129. package/dist/devProvider-BGBkw28J.mjs +0 -1050
  130. package/dist/file-DRb4eWqw.mjs +0 -1
  131. package/dist/getInstance-SiE6WZRh.mjs +0 -1
  132. package/dist/loadConfig-VGtBF4qm.mjs +0 -1
  133. package/dist/mcp-D3Yh24Cj.mjs +0 -529
  134. package/dist/wevu-C4KEC5kO.d.mts +0 -5
  135. package/dist/wevu-router-Cg2sIkIE.d.mts +0 -5
@@ -1,6 +1,6 @@
1
- import { O as getRouteRuntimeGlobalKeys } from "./createCompilerContextInstance-DJH_P_nZ.mjs";
2
- import { t as getCompilerContext } from "./getInstance-DiGSzBNI.mjs";
3
- //#region src/auto-routes.ts
1
+ import { V as getRouteRuntimeGlobalKeys } from "./createCompilerContextInstance-BXSdH2E8.mjs";
2
+ import { t as getCompilerContext } from "./getInstance-DfNlbr-X.mjs";
3
+ // src/auto-routes.ts
4
4
  const ROUTE_RUNTIME_OVERRIDE_KEY = Symbol.for("weapp-vite.route-runtime");
5
5
  function createGetter(resolver) {
6
6
  return {
@@ -59,5 +59,4 @@ const miniProgramRouter = {
59
59
  }
60
60
  };
61
61
  const wxRouter = miniProgramRouter;
62
- //#endregion
63
62
  export { routes as default, routes, entries, miniProgramRouter, pages, subPackages, wxRouter };
@@ -1,6 +1,4 @@
1
- import { C as GlassEaselAnalyzeResult } from "./config-V0L-IAJf.mjs";
2
- import { RolldownOutput } from "rolldown";
3
- //#region src/analyze/components/types.d.ts
1
+ import { n as GlassEaselAnalyzeResult } from "./types-BK2EQ3Jm.mjs";
4
2
  type AnalyzeComponentSuggestionKind = 'move-to-subpackage' | 'split-or-async' | 'shared-subpackage-or-placeholder';
5
3
  interface AnalyzeComponentSuggestion {
6
4
  kind: AnalyzeComponentSuggestionKind;
@@ -23,8 +21,6 @@ interface AnalyzeComponentUsage {
23
21
  pages: AnalyzeComponentPageUsage[];
24
22
  suggestions: AnalyzeComponentSuggestion[];
25
23
  }
26
- //#endregion
27
- //#region src/analyze/subpackages/artifacts/types.d.ts
28
24
  interface AnalyzeModuleOwner {
29
25
  name: string;
30
26
  version?: string;
@@ -66,8 +62,6 @@ interface AnalyzeArtifactAnalysis {
66
62
  unknownFiles: string[];
67
63
  };
68
64
  }
69
- //#endregion
70
- //#region src/analyze/subpackages/types.d.ts
71
65
  type PackageType = 'main' | 'subPackage' | 'independent' | 'virtual';
72
66
  type ModuleSourceType = 'src' | 'plugin' | 'node_modules' | 'workspace';
73
67
  type BuildOrigin = 'main' | 'independent';
@@ -153,8 +147,6 @@ interface AnalyzeSubpackagesResult {
153
147
  components?: AnalyzeComponentUsage[];
154
148
  glassEasel: GlassEaselAnalyzeResult;
155
149
  }
156
- //#endregion
157
- //#region src/analyze/subpackages/budget.d.ts
158
150
  interface AnalyzeBudgetCheckItem {
159
151
  id: string;
160
152
  label: string;
@@ -174,5 +166,4 @@ interface AnalyzeBudgetCheckInput {
174
166
  };
175
167
  }
176
168
  declare function createAnalyzeBudgetCheck(result: AnalyzeBudgetCheckInput): AnalyzeBudgetCheckItem[];
177
- //#endregion
178
169
  export { AnalyzeSubpackagesResult as a, AnalyzeBudgetConfig as i, AnalyzeBudgetCheckItem as n, ModuleSourceType as o, createAnalyzeBudgetCheck as r, AnalyzeBudgetCheckInput as t };
@@ -0,0 +1,63 @@
1
+ // src/analyze/subpackages/artifacts/category.ts
2
+ function isRuntimeCategory(category) {
3
+ return category === "runtime" || category === "reactivity" || category === "host" || category === "helper";
4
+ }
5
+ // src/analyze/subpackages/budget.ts
6
+ const defaultBudgets = {
7
+ totalBytes: 20971520,
8
+ mainBytes: 2097152,
9
+ subPackageBytes: 2097152,
10
+ independentBytes: 2097152,
11
+ warningRatio: .85,
12
+ source: "default"
13
+ };
14
+ function createAnalyzeBudgetCheck(result) {
15
+ const budgets = result.metadata?.budgets ?? defaultBudgets;
16
+ const createItem = (options, unknown = false) => {
17
+ const ratio = options.limitBytes > 0 ? options.currentBytes / options.limitBytes : options.currentBytes > 0 ? 1 : 0;
18
+ return {
19
+ ...options,
20
+ ratio,
21
+ status: unknown ? "unknown" : ratio >= 1 ? "exceeded" : ratio >= budgets.warningRatio ? "warning" : "ok"
22
+ };
23
+ };
24
+ const files = result.packages.flatMap((pkg) => pkg.files);
25
+ const unique = new Map(files.map((file) => [file.file, file]));
26
+ const sizeUnknown = (items) => items.some((file) => typeof file.size !== "number" || !Number.isFinite(file.size) || file.size < 0);
27
+ const items = [createItem({
28
+ id: "__total__",
29
+ label: "总包",
30
+ scope: "total",
31
+ currentBytes: [...unique.values()].reduce((sum, file) => sum + (file.size ?? 0), 0),
32
+ limitBytes: budgets.totalBytes,
33
+ measurement: "file-bytes",
34
+ files: [...unique.keys()].sort()
35
+ }, sizeUnknown(files))];
36
+ for (const pkg of result.packages) {
37
+ const limitBytes = budgets.packageBytes?.[pkg.id] ?? (pkg.type === "main" ? budgets.mainBytes : pkg.type === "subPackage" ? budgets.subPackageBytes : pkg.type === "independent" ? budgets.independentBytes : void 0);
38
+ if (limitBytes === void 0) continue;
39
+ items.push(createItem({
40
+ id: pkg.id,
41
+ label: pkg.label,
42
+ scope: pkg.type,
43
+ currentBytes: pkg.files.reduce((sum, file) => sum + (file.size ?? 0), 0),
44
+ limitBytes,
45
+ measurement: "file-bytes",
46
+ files: pkg.files.map((file) => file.file).sort()
47
+ }, sizeUnknown(pkg.files)));
48
+ }
49
+ if (budgets.runtimeBytes !== void 0) {
50
+ const artifacts = result.artifacts;
51
+ items.push(createItem({
52
+ id: "__runtime__",
53
+ label: "Runtime(含混合 chunk 的文件上界)",
54
+ scope: "runtime",
55
+ currentBytes: artifacts?.runtime.upperBoundBytes ?? 0,
56
+ limitBytes: budgets.runtimeBytes,
57
+ measurement: artifacts ? "upper-bound" : "unavailable",
58
+ files: artifacts?.files.filter((file) => artifacts.runtime.unknownFiles.includes(file.file) || file.modules.some((module) => isRuntimeCategory(module.category))).map((file) => file.file) ?? files.filter((file) => file.type === "chunk" || /\.[cm]?js$/i.test(file.file)).map((file) => file.file)
59
+ }, !artifacts || artifacts.runtime.unknownFiles.length > 0));
60
+ }
61
+ return items.sort((a, b) => b.ratio - a.ratio || a.label.localeCompare(b.label));
62
+ }
63
+ export { isRuntimeCategory as n, createAnalyzeBudgetCheck as t };
@@ -0,0 +1,534 @@
1
+ import { a as resolveWeappViteHostMeta } from "./pluginHost-vn8Vty1J.mjs";
2
+ import { l as getProjectPlatformOptions } from "./platform-BiMpsZIb.mjs";
3
+ import { r as logger_default } from "./logger-DGn5iEVN.mjs";
4
+ import { r as printUploadProgress } from "./report-PJVyo-UZ.mjs";
5
+ import { a as terminateUploadProcess, i as terminateUploadDescendants, n as resolveUploadPlatforms, o as describeUploadProcessTreeError, r as redactUploadSecrets, t as prepareUpload } from "./upload-Chal5b3w.mjs";
6
+ import process from "node:process";
7
+ import { fileURLToPath } from "node:url";
8
+ import path from "node:path";
9
+ import { access, readFile, realpath, rm, stat, writeFile } from "node:fs/promises";
10
+ import { randomUUID } from "node:crypto";
11
+ import { fork } from "node:child_process";
12
+ import semverInc from "semver/functions/inc.js";
13
+ import { x } from "tinyexec";
14
+ // src/cli/upload/autoMetadata.ts
15
+ /** 只读取命令根目录的清单,不向父目录查找或修改文件。 */
16
+ async function readPackageVersion(packagePath) {
17
+ let manifest;
18
+ try {
19
+ manifest = JSON.parse(await readFile(packagePath, "utf8"));
20
+ } catch (cause) {
21
+ throw new Error("--bump 无法读取命令根目录的 package.json。", { cause });
22
+ }
23
+ if (manifest === null || typeof manifest !== "object" || !("version" in manifest) || typeof manifest.version !== "string") throw new Error("--bump 要求命令根目录 package.json 的 version 为有效的 SemVer 字符串。");
24
+ return manifest.version;
25
+ }
26
+ /** 在首次编译配置求值前准备一次元数据;预演不写文件,实际版本由 npm 同步。 */
27
+ function validateAutoUploadMetadata(options, action) {
28
+ const { bump, gitDesc } = options;
29
+ if (action === "preview" && (bump !== void 0 || gitDesc !== void 0)) throw new Error("--bump 和 --git-desc 仅支持 upload 或 build --upload,不支持 preview。");
30
+ if (bump !== void 0 && options.uv !== void 0) throw new Error("--bump 不能与 --uv 同时使用。");
31
+ if (gitDesc && options.desc !== void 0) throw new Error("--git-desc 不能与 --desc 同时使用。");
32
+ if (bump !== void 0 && ![
33
+ "patch",
34
+ "minor",
35
+ "major"
36
+ ].includes(bump)) throw new Error("--bump 仅支持 patch、minor 或 major。");
37
+ }
38
+ async function captureMetadataSnapshot(root) {
39
+ const snapshots = [];
40
+ for (const name of [
41
+ "package.json",
42
+ "package-lock.json",
43
+ "npm-shrinkwrap.json"
44
+ ]) {
45
+ const filePath = path.join(root, name);
46
+ try {
47
+ snapshots.push({
48
+ path: filePath,
49
+ content: await readFile(filePath, "utf8")
50
+ });
51
+ } catch (error) {
52
+ if (error.code !== "ENOENT") throw error;
53
+ snapshots.push({ path: filePath });
54
+ }
55
+ }
56
+ return snapshots;
57
+ }
58
+ async function restoreMetadataSnapshot(snapshots) {
59
+ for (const snapshot of snapshots) if (snapshot.content === void 0) await rm(snapshot.path, { force: true });
60
+ else await writeFile(snapshot.path, snapshot.content);
61
+ }
62
+ async function prepareAutoUploadMetadata(cwd, options, action) {
63
+ validateAutoUploadMetadata(options, action);
64
+ const { bump, gitDesc } = options;
65
+ if (bump === void 0 && !gitDesc) return options;
66
+ if (bump !== void 0 && options.uv !== void 0) throw new Error("--bump 不能与 --uv 同时使用。");
67
+ if (gitDesc && options.desc !== void 0) throw new Error("--git-desc 不能与 --desc 同时使用。");
68
+ if (bump !== void 0 && bump !== "patch" && bump !== "minor" && bump !== "major") throw new Error("--bump 仅支持 patch、minor 或 major。");
69
+ const root = path.resolve(cwd);
70
+ const packagePath = path.join(root, "package.json");
71
+ let currentVersion;
72
+ let nextVersion;
73
+ if (bump !== void 0) {
74
+ currentVersion = await readPackageVersion(packagePath);
75
+ nextVersion = semverInc(currentVersion, bump) ?? void 0;
76
+ if (!nextVersion) throw new Error("--bump 要求命令根目录 package.json 的 version 为有效的 SemVer 字符串。");
77
+ }
78
+ let desc;
79
+ if (gitDesc) {
80
+ try {
81
+ desc = (await x("git", [
82
+ "log",
83
+ "-1",
84
+ "--format=%s"
85
+ ], {
86
+ nodePath: false,
87
+ throwOnError: true,
88
+ nodeOptions: { cwd: root }
89
+ })).stdout.trim();
90
+ } catch (cause) {
91
+ throw new Error("--git-desc 无法读取最新 Git 提交主题,请确认 Git 可用且仓库已有提交。", { cause });
92
+ }
93
+ if (!desc) throw new Error("--git-desc 要求最新 Git 提交主题非空。");
94
+ }
95
+ if (nextVersion) {
96
+ if (options.dryRun) logger_default.info(`[upload] dry-run:计划版本 ${currentVersion} → ${nextVersion},未修改 package.json 或锁文件。`);
97
+ else {
98
+ try {
99
+ await x("npm", [
100
+ "version",
101
+ nextVersion,
102
+ "--no-git-tag-version",
103
+ "--ignore-scripts",
104
+ "--workspaces=false",
105
+ "--prefix",
106
+ root
107
+ ], {
108
+ nodePath: false,
109
+ throwOnError: true,
110
+ nodeOptions: { cwd: root }
111
+ });
112
+ } catch (cause) {
113
+ throw new Error("--bump 执行 npm version 失败,请检查本地版本与锁文件后重试。", { cause });
114
+ }
115
+ if (await readPackageVersion(packagePath) !== nextVersion) throw new Error("--bump 执行 npm version 后,命令根目录的 package.json 版本未按预期更新。");
116
+ logger_default.info(`[upload] 版本已更新:${currentVersion} → ${nextVersion}。后续构建或上传失败不会回退;重试同一版本时请移除 --bump。`);
117
+ }
118
+ }
119
+ if (gitDesc) logger_default.info("[upload] 使用最新 Git 提交主题作为上传说明。");
120
+ const metadata = { ...options };
121
+ if (nextVersion !== void 0) metadata.uv = nextVersion;
122
+ if (desc !== void 0) metadata.desc = desc;
123
+ return metadata;
124
+ }
125
+ /** 配置尚未确认可上传时,保留 npm version 所有可能修改文件的回滚点。 */
126
+ async function prepareAutoUploadMetadataWithRollback(cwd, options, action) {
127
+ validateAutoUploadMetadata(options, action);
128
+ const snapshots = options.bump !== void 0 && !options.dryRun ? await captureMetadataSnapshot(path.resolve(cwd)) : [];
129
+ return {
130
+ options: await prepareAutoUploadMetadata(cwd, options, action),
131
+ rollback: () => restoreMetadataSnapshot(snapshots)
132
+ };
133
+ }
134
+ // src/cli/upload/env.ts
135
+ /** 凭据不经过 Vite 的 env 调试日志;文件优先级和进程环境覆盖规则保持一致。 */
136
+ async function loadUploadEnv(cwd, mode, root, envDir) {
137
+ if (envDir === false) return { ...process.env };
138
+ if (mode === "local") throw new Error("local 不能作为 mode,因为它与 .env.local 文件后缀冲突。");
139
+ const directory = path.resolve(cwd, root ?? ".", envDir ?? ".");
140
+ const parsed = {};
141
+ let parse;
142
+ for (const file of [
143
+ ".env",
144
+ ".env.local",
145
+ `.env.${mode}`,
146
+ `.env.${mode}.local`
147
+ ]) {
148
+ const content = await readFile(path.join(directory, file), "utf8").catch((error) => {
149
+ if (error.code === "ENOENT") return "";
150
+ throw error;
151
+ });
152
+ if (!content) continue;
153
+ parse ??= (await import("dotenv")).parse;
154
+ for (const [key, value] of Object.entries(parse(content))) {
155
+ delete parsed[key];
156
+ parsed[key] = value;
157
+ }
158
+ }
159
+ const processEnv = { ...parsed };
160
+ for (const [key, value] of Object.entries(process.env)) if (value !== void 0) {
161
+ processEnv[key] = value;
162
+ delete parsed[key];
163
+ }
164
+ if (Object.keys(parsed).length) {
165
+ const { expand } = await import("dotenv-expand");
166
+ expand({
167
+ parsed,
168
+ processEnv
169
+ });
170
+ }
171
+ return {
172
+ ...parsed,
173
+ ...process.env
174
+ };
175
+ }
176
+ // src/cli/upload/executionError.ts
177
+ /** 仅描述本地执行结果,不代表远端上传已取消。 */
178
+ var UploadExecutionError = class extends Error {
179
+ /** timeout 为本地超时,interrupted 为本地中断,failed 为工具或传输失败。 */
180
+ reason;
181
+ /** not-started 表示尚未允许 SDK 执行;unknown 表示远端结果需要人工核实。 */
182
+ remoteOutcome;
183
+ constructor(message, reason, remoteOutcome) {
184
+ super(message);
185
+ this.name = "UploadExecutionError";
186
+ this.reason = reason;
187
+ this.remoteOutcome = remoteOutcome;
188
+ }
189
+ };
190
+ // src/cli/upload/result.ts
191
+ /** 只接受可展示的预览结果,文件必须由本次任务生成,不能沿用旧二维码。 */
192
+ async function validatePreviewResult(value, context) {
193
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("预览工具未返回二维码或预览链接。");
194
+ const input = value;
195
+ const result = {};
196
+ for (const key of ["qrCodeUrl", "previewUrl"]) {
197
+ if (input[key] === void 0) continue;
198
+ if (typeof input[key] !== "string" || !input[key].trim()) throw new Error("预览工具返回了无效链接。");
199
+ let url;
200
+ try {
201
+ url = new URL(input[key]);
202
+ } catch {
203
+ throw new Error("预览工具返回了无效链接。");
204
+ }
205
+ if (url.username || url.password || key === "qrCodeUrl" && url.protocol !== "http:" && url.protocol !== "https:" || [
206
+ "javascript:",
207
+ "data:",
208
+ "file:"
209
+ ].includes(url.protocol)) throw new Error("预览工具返回了不支持的链接类型。");
210
+ result[key] = input[key];
211
+ }
212
+ if (input.qrCodeFile !== void 0) {
213
+ if (typeof input.qrCodeFile !== "string" || !context.qrCodePath || path.resolve(input.qrCodeFile) !== path.resolve(context.qrCodePath)) throw new Error("预览工具返回的二维码文件不是本次任务的输出路径。");
214
+ const file = await stat(input.qrCodeFile);
215
+ if (!file.isFile() || file.size === 0) throw new Error("预览二维码文件不存在或为空。");
216
+ result.qrCodeFile = input.qrCodeFile;
217
+ }
218
+ if (!result.qrCodeUrl && !result.previewUrl && !result.qrCodeFile) throw new Error("预览工具未返回二维码或预览链接。");
219
+ return result;
220
+ }
221
+ // src/cli/upload/process.ts
222
+ function readProgress(value, secrets) {
223
+ if (!value || typeof value !== "object" || !("type" in value) || ![
224
+ "progress",
225
+ "log",
226
+ "task-created",
227
+ "version-created"
228
+ ].includes(String(value.type))) return;
229
+ const event = { type: value.type };
230
+ if ("message" in value && typeof value.message === "string") event.message = redactUploadSecrets(value.message, secrets);
231
+ if ("percent" in value && typeof value.percent === "number" && Number.isFinite(value.percent) && value.percent >= 0 && value.percent <= 100) event.percent = value.percent;
232
+ return event;
233
+ }
234
+ /** 强制终止可能截断日志尾部;同时隐藏已知凭据的不完整前缀,保留普通诊断。 */
235
+ function redactDiagnostic(message, secrets) {
236
+ const output = message.trimEnd();
237
+ let end = output.length;
238
+ for (const value of secrets) {
239
+ const secret = value.trimEnd();
240
+ if (!secret) continue;
241
+ let start = output.indexOf(secret[0], Math.max(0, output.length - secret.length));
242
+ while (start !== -1) {
243
+ let offset = 0;
244
+ while (start + offset < output.length && output[start + offset] === secret[offset]) offset++;
245
+ if (start + offset === output.length) {
246
+ end = Math.min(end, start);
247
+ break;
248
+ }
249
+ start = output.indexOf(secret[0], start + 1);
250
+ }
251
+ }
252
+ return redactUploadSecrets(end < output.length ? `${output.slice(0, end)}[REDACTED]` : output, secrets);
253
+ }
254
+ /** 隔离官方 SDK;完成确认与正常退出必须同时成立,取消仅作用于本地进程。 */
255
+ async function executeUpload(platform, context, secrets, action = "upload", options = {}) {
256
+ const label = `${platform} ${action === "preview" ? "预览" : "上传"}`;
257
+ if (options.signal?.aborted) throw new UploadExecutionError(`${label}已中断(SDK 尚未开始)。`, "interrupted", "not-started");
258
+ const { result, output } = await new Promise((resolve, reject) => {
259
+ const spawnedAt = Date.now();
260
+ let child;
261
+ try {
262
+ child = fork(fileURLToPath(new URL("./upload-worker.mjs", import.meta.url)), [], {
263
+ cwd: context.cwd,
264
+ env: context.env,
265
+ execArgv: [],
266
+ stdio: [
267
+ "pipe",
268
+ "pipe",
269
+ "pipe",
270
+ "ipc"
271
+ ],
272
+ detached: process.platform !== "win32",
273
+ windowsHide: true
274
+ });
275
+ } catch (error) {
276
+ reject(new UploadExecutionError(redactUploadSecrets(`${label}无法启动:${String(error)}`, secrets), "failed", "not-started"));
277
+ return;
278
+ }
279
+ let completed = false;
280
+ let started = false;
281
+ let settled = false;
282
+ let result = {};
283
+ const captured = {
284
+ stdout: "",
285
+ stderr: ""
286
+ };
287
+ let capturedSize = 0;
288
+ let failure;
289
+ let timer;
290
+ let closeTimer;
291
+ const terminate = (descendants = true) => {
292
+ if (!child.pid) return;
293
+ const exited = child.exitCode !== null || child.signalCode !== null;
294
+ try {
295
+ if (descendants && !exited && process.platform !== "win32") terminateUploadDescendants(child.pid);
296
+ } catch (error) {
297
+ failure ??= {
298
+ reason: "failed",
299
+ detail: "无法清理本地子进程"
300
+ };
301
+ failure.detail += `;${describeUploadProcessTreeError(error)}`;
302
+ }
303
+ try {
304
+ terminateUploadProcess(child.pid, {
305
+ processGroup: true,
306
+ exited,
307
+ lifetime: {
308
+ start: spawnedAt,
309
+ end: Date.now()
310
+ }
311
+ });
312
+ } catch (error) {
313
+ failure ??= {
314
+ reason: "failed",
315
+ detail: "无法终止本地 worker"
316
+ };
317
+ failure.detail += `;${describeUploadProcessTreeError(error)}`;
318
+ if (!exited) child.kill("SIGKILL");
319
+ }
320
+ };
321
+ const stop = (reason, detail) => {
322
+ if (settled || failure) return;
323
+ failure = {
324
+ reason,
325
+ detail
326
+ };
327
+ clearTimeout(timer);
328
+ terminate();
329
+ };
330
+ const cancel = () => stop("interrupted", "本地执行已中断");
331
+ const onParentExit = () => terminate();
332
+ const collect = (stream, chunk) => {
333
+ if (failure) return;
334
+ const remaining = 4194304 - capturedSize;
335
+ if (chunk.length > remaining) {
336
+ captured.stdout = "";
337
+ captured.stderr = "";
338
+ stop("failed", "日志超限,已省略日志以保护凭据");
339
+ return;
340
+ }
341
+ captured[stream] += chunk;
342
+ capturedSize += chunk.length;
343
+ };
344
+ const onStdout = (chunk) => collect("stdout", chunk);
345
+ const onStderr = (chunk) => collect("stderr", chunk);
346
+ const onError = (error) => stop("failed", error.message);
347
+ const onDisconnect = () => {
348
+ if (!completed) stop("failed", "IPC 连接中断,未收到完成确认");
349
+ };
350
+ const onMessage = (message) => {
351
+ if (settled || failure || !message || typeof message !== "object" || !("action" in message) || message.action !== action || !("type" in message)) return;
352
+ if (message.type === "started" && !started) {
353
+ started = true;
354
+ child.send({
355
+ type: "run",
356
+ action
357
+ }, (error) => {
358
+ if (error) onError(error);
359
+ });
360
+ } else if (message.type === "progress" && "event" in message) {
361
+ const event = readProgress(message.event, secrets);
362
+ if (event) try {
363
+ options.onProgress?.(event);
364
+ } catch (error) {
365
+ stop("failed", `进度处理失败:${String(error)}`);
366
+ }
367
+ } else if (message.type === "completed" && started) {
368
+ completed = true;
369
+ result = "result" in message && message.result && typeof message.result === "object" ? message.result : {};
370
+ }
371
+ };
372
+ const onExit = () => {
373
+ clearTimeout(timer);
374
+ terminate(false);
375
+ closeTimer = setTimeout(() => {
376
+ failure ??= {
377
+ reason: "failed",
378
+ detail: "worker 已退出"
379
+ };
380
+ failure.detail += ";日志管道未关闭,本地子进程清理未确认";
381
+ captured.stdout = "";
382
+ captured.stderr = "";
383
+ child.stdin?.destroy();
384
+ child.stdout?.destroy();
385
+ child.stderr?.destroy();
386
+ }, 1e3);
387
+ };
388
+ const cleanup = () => {
389
+ clearTimeout(timer);
390
+ clearTimeout(closeTimer);
391
+ options.signal?.removeEventListener("abort", cancel);
392
+ process.off("SIGINT", cancel);
393
+ process.off("SIGTERM", cancel);
394
+ process.off("exit", onParentExit);
395
+ child.off("message", onMessage);
396
+ child.off("error", onError);
397
+ child.off("disconnect", onDisconnect);
398
+ child.off("exit", onExit);
399
+ child.stdout?.off("data", onStdout);
400
+ child.stderr?.off("data", onStderr);
401
+ child.stdin?.off("error", onError);
402
+ };
403
+ child.once("close", (code, signal) => {
404
+ settled = true;
405
+ cleanup();
406
+ const output = [redactDiagnostic(captured.stdout, secrets), redactDiagnostic(captured.stderr, secrets)].filter(Boolean).join("\n").trim();
407
+ if (failure || code !== 0 || !completed) {
408
+ const detail = failure?.detail ?? `${signal ?? code ?? "unknown"},${completed ? "进程异常结束" : "未收到完成确认"}`;
409
+ reject(new UploadExecutionError(redactUploadSecrets(`${label}失败(${detail})。${started ? "远端结果未知,请核实平台状态;未自动重试。" : "SDK 尚未开始。"}${output ? `\n${output}` : ""}`, secrets), failure?.reason ?? "failed", started ? "unknown" : "not-started"));
410
+ return;
411
+ }
412
+ resolve({
413
+ result,
414
+ output
415
+ });
416
+ });
417
+ child.on("error", onError);
418
+ child.on("disconnect", onDisconnect);
419
+ child.on("message", onMessage);
420
+ child.once("exit", onExit);
421
+ child.stdout?.setEncoding("utf8").on("data", onStdout);
422
+ child.stderr?.setEncoding("utf8").on("data", onStderr);
423
+ child.stdin?.on("error", onError);
424
+ process.once("exit", onParentExit);
425
+ if (options.signal) options.signal.addEventListener("abort", cancel, { once: true });
426
+ else {
427
+ process.once("SIGINT", cancel);
428
+ process.once("SIGTERM", cancel);
429
+ }
430
+ if (options.timeoutMs !== void 0) timer = setTimeout(stop, options.timeoutMs, "timeout", `本地执行超时(${options.timeoutMs}ms)`);
431
+ if (options.signal?.aborted) cancel();
432
+ else try {
433
+ child.stdin?.end(JSON.stringify({
434
+ platform,
435
+ context,
436
+ action
437
+ }));
438
+ } catch (error) {
439
+ stop("failed", String(error));
440
+ }
441
+ });
442
+ if (output) logger_default.info(output);
443
+ return action === "preview" ? validatePreviewResult(result, context) : result;
444
+ }
445
+ // src/cli/upload/project.ts
446
+ /** 确保官方工具读取的目录正是本次构建输出,拒绝误传旧目录或同名配置。 */
447
+ async function validateUploadProject(options) {
448
+ const { projectConfigFileName } = getProjectPlatformOptions(options.platform);
449
+ if (options.sourceConfigPath && path.basename(options.sourceConfigPath) !== projectConfigFileName) throw new Error(`上传工具只读取 ${projectConfigFileName},请使用此标准文件名,避免读取其他项目配置。`);
450
+ const configPath = path.join(options.projectPath, projectConfigFileName);
451
+ const config = JSON.parse(await readFile(configPath, "utf8"));
452
+ if (!config || typeof config !== "object" || Array.isArray(config)) throw new TypeError(`${projectConfigFileName} 必须是 JSON 对象。`);
453
+ const rootKey = options.platform === "swan" ? "smartProgramRoot" : "miniprogramRoot";
454
+ const root = config[rootKey];
455
+ if (typeof root !== "string" || !root.trim()) throw new Error(`${projectConfigFileName} 缺少代码目录 ${rootKey}。`);
456
+ const sdkRoot = path.resolve(options.projectPath, root);
457
+ const [actualRoot, outputRoot] = await Promise.all([realpath(sdkRoot), realpath(options.outDir)]);
458
+ if (actualRoot !== outputRoot) throw new Error(`${projectConfigFileName} 的代码目录与本次构建输出不一致,已阻止上传旧产物。请检查项目配置根目录与 build.outDir。`);
459
+ await access(path.join(outputRoot, "app.json"));
460
+ }
461
+ // src/cli/upload/builtProject.ts
462
+ /** 仅由显式上传或预览入口读取参数,不执行构建或调用平台工具。 */
463
+ async function createUploadTarget(config, options, action) {
464
+ if (config.weappLibConfig?.enabled || config.pluginOnly) throw new Error(`${action} 仅支持完整小程序项目,不支持组件库或独立插件构建。`);
465
+ const platform = resolveUploadPlatforms(config.platform)[0];
466
+ const uploadConfig = action === "upload" ? config.weappViteConfig.upload : void 0;
467
+ const version = (options.uv ?? uploadConfig?.version ?? config.packageJson.version)?.trim() ?? "";
468
+ if (action === "upload" && !version) throw new Error("请通过 --uv、weapp.upload.version 或项目 package.json 的 version 指定上传版本。");
469
+ const desc = (options.desc ?? uploadConfig?.desc)?.trim() || `${config.packageJson.name ?? platform}${version ? `@${version}` : ""}`;
470
+ const env = options.dryRun ? {} : await loadUploadEnv(config.cwd, config.mode, config.inlineConfig.root, config.inlineConfig.envDir);
471
+ const { projectConfigFileName } = getProjectPlatformOptions(config.platform);
472
+ const generatedProjectConfig = config.multiPlatform.projectConfigs !== void 0;
473
+ const projectPath = generatedProjectConfig ? config.outDir : config.multiPlatform.enabled ? path.dirname(config.outDir) : path.dirname(config.projectConfigPath ?? path.join(config.cwd, projectConfigFileName));
474
+ const appid = config.projectConfig.appid ?? config.projectConfig.appId;
475
+ const target = {
476
+ platform,
477
+ sourceConfigPath: config.projectConfigPath,
478
+ context: {
479
+ cwd: config.cwd,
480
+ projectPath,
481
+ appid: typeof appid === "string" ? appid : void 0,
482
+ version,
483
+ desc,
484
+ qrCodePath: action === "preview" && !options.dryRun ? path.join(config.cwd, ".weapp-vite", "preview", `${platform}-${randomUUID()}.png`) : void 0,
485
+ env: {
486
+ ...process.env,
487
+ ...env
488
+ }
489
+ }
490
+ };
491
+ (config.inlineConfig.plugins ??= []).push({
492
+ name: "weapp-vite:upload-output",
493
+ apply: (viteConfig) => resolveWeappViteHostMeta(viteConfig)?.runtime === "miniprogram",
494
+ writeBundle(output, bundle) {
495
+ if (output.dir && Object.hasOwn(bundle, "app.json")) {
496
+ target.outDir = path.resolve(output.dir);
497
+ if (generatedProjectConfig) target.context.projectPath = target.outDir;
498
+ }
499
+ }
500
+ });
501
+ return target;
502
+ }
503
+ /** 只消费本次构建的产物;产物校验通过前不会准备凭据或调用平台工具。 */
504
+ async function executeUploadTarget(target, options, action, execution = {}) {
505
+ const { platform, context } = target;
506
+ if (!target.outDir) throw new Error("本次构建未写出 app.json,已阻止上传或预览旧产物。");
507
+ await validateUploadProject({
508
+ platform,
509
+ projectPath: context.projectPath,
510
+ outDir: target.outDir,
511
+ sourceConfigPath: target.sourceConfigPath
512
+ });
513
+ if (options.dryRun) {
514
+ logger_default.success(`[${action}:${platform}] dry-run:构建完成,未校验凭据或调用平台工具。项目:${path.relative(context.cwd, context.projectPath) || "."}`);
515
+ return;
516
+ }
517
+ const upload = await prepareUpload(platform, context, action);
518
+ execution.onUpload?.();
519
+ const result = await executeUpload(platform, context, upload.secrets, action, {
520
+ ...execution,
521
+ onProgress: execution.onProgress ?? ((event) => printUploadProgress(platform, event))
522
+ });
523
+ if (action === "preview") {
524
+ if (!result) throw new Error("预览工具未返回二维码或预览链接。");
525
+ for (const [label, value] of [
526
+ ["二维码图片", result.qrCodeUrl],
527
+ ["预览链接", result.previewUrl],
528
+ ["二维码文件", result.qrCodeFile && path.relative(context.cwd, result.qrCodeFile)]
529
+ ]) if (value) logger_default.info(`[preview:${platform}] ${label}:${redactUploadSecrets(value, upload.secrets)}`);
530
+ logger_default.success(`[preview:${platform}] 预览已生成(未上传开发版本、未提审、未正式发布)。`);
531
+ } else logger_default.success(`[upload:${platform}] ${context.version} 上传完成(未提审、未正式发布)。`);
532
+ return result;
533
+ }
534
+ export { prepareAutoUploadMetadataWithRollback as a, prepareAutoUploadMetadata as i, executeUploadTarget as n, validateAutoUploadMetadata as o, UploadExecutionError as r, createUploadTarget as t };
@@ -1,8 +1,8 @@
1
- import { t as isPathInside } from "./path-doV773b7.mjs";
2
- import "./utils-CJSCgEj6.mjs";
3
- import { i as SHARED_CHUNK_VIRTUAL_PREFIX } from "./chunkStrategy-DRA5WpB-.mjs";
1
+ import { t as isPathInside } from "./path-E1OjBJAl.mjs";
2
+ import "./utils-CTGSZp4j.mjs";
3
+ import { o as SHARED_CHUNK_VIRTUAL_PREFIX } from "./package-DR62fAzP.mjs";
4
4
  import { posix } from "pathe";
5
- //#region src/analyze/subpackages/classifier.ts
5
+ // src/analyze/subpackages/classifier.ts
6
6
  const VIRTUAL_MODULE_INDICATOR = "\0";
7
7
  const VIRTUAL_PREFIX = `${SHARED_CHUNK_VIRTUAL_PREFIX}/`;
8
8
  function classifyModuleSourceKind(options) {
@@ -84,8 +84,4 @@ function resolveAssetSource(fileName, ctx) {
84
84
  sourceType: "plugin"
85
85
  };
86
86
  }
87
- //#endregion
88
- //#region package.json
89
- var version = "7.5.0";
90
- //#endregion
91
- export { resolveModuleSourceType as a, resolveAssetSource as i, classifyPackage as n, normalizeModuleId as r, version as t };
87
+ export { resolveModuleSourceType as i, normalizeModuleId as n, resolveAssetSource as r, classifyPackage as t };