weapp-vite 7.5.0 → 7.6.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 (93) hide show
  1. package/README.md +8 -2
  2. package/THIRD_PARTY_NOTICES.md +60 -0
  3. package/dist/action-B3YZMA-h.mjs +255 -0
  4. package/dist/action-BELcDNNv.mjs +139 -0
  5. package/dist/action-BOk3vGI7.mjs +1110 -0
  6. package/dist/action-DlC6JYpt.mjs +95 -0
  7. package/dist/action-zEDY7oh_.mjs +247 -0
  8. package/dist/{analyze-ZJUvEdaY.mjs → analyze-DN79YOAH.mjs} +1 -65
  9. package/dist/artifacts-BOyC9Fy-.mjs +106 -0
  10. package/dist/assets-C5_YYXNk.mjs +637 -0
  11. package/dist/auto-routes.mjs +2 -2
  12. package/dist/{budget-BD7VqLCl.d.mts → budget-CTLOHwgI.d.mts} +1 -2
  13. package/dist/budget-EOeEycc_.mjs +65 -0
  14. package/dist/builtProject-C29udgXY.mjs +541 -0
  15. package/dist/{chunkStrategy-DRA5WpB-.mjs → chunkStrategy-DY_LZIIe.mjs} +15 -3
  16. package/dist/{package-7swhyLmf.mjs → classifier-DBJY__kg.mjs} +4 -7
  17. package/dist/cli-acceptance.mjs +1 -1
  18. package/dist/cli.mjs +110 -4506
  19. package/dist/{config-V0L-IAJf.d.mts → config-Bf6DWhyb.d.mts} +136 -49
  20. package/dist/config.d.mts +2 -2
  21. package/dist/{createCompilerContextInstance-DJH_P_nZ.mjs → createCompilerContextInstance-aYwi8wQt.mjs} +15235 -9523
  22. package/dist/{createContext-BqYzHhY9.mjs → createContext-tApLtII-.mjs} +6 -3
  23. package/dist/dashboard/analyze.d.mts +1 -1
  24. package/dist/dashboard/analyze.mjs +3 -1
  25. package/dist/dashboard/vite.d.mts +1 -1
  26. package/dist/dashboard.d.mts +2 -2
  27. package/dist/dashboard.mjs +1749 -1
  28. package/dist/dashboardTransport-C_Y6jMp-.mjs +16 -0
  29. package/dist/{dashboardViteBridge-Dy3nAD4m.mjs → dashboardViteBridge-DCGR43aM.mjs} +8 -5
  30. package/dist/{dev-fR5GiJRO.mjs → dev-C2fgr_Xd.mjs} +5 -1
  31. package/dist/devProvider-D-hTfsEO.mjs +3027 -0
  32. package/dist/docs/README.md +8 -2
  33. package/dist/docs/mcp.md +10 -0
  34. package/dist/docs/troubleshooting.md +8 -0
  35. package/dist/docs/vue-sfc.md +25 -2
  36. package/dist/doctor-worker.mjs +3 -2
  37. package/dist/doctor.d.mts +2 -2
  38. package/dist/doctor.mjs +15 -13
  39. package/dist/engine-C66J0HLz.mjs +54 -0
  40. package/dist/{file-sC3jD7Fh.mjs → file-CcIOmqhC.mjs} +47 -19
  41. package/dist/file-DtcteQ4G.mjs +1 -0
  42. package/dist/forwardConsole-B0Reo8Lf.mjs +511 -0
  43. package/dist/getInstance-BAIaU2y9.mjs +1 -0
  44. package/dist/{getInstance-DiGSzBNI.mjs → getInstance-Dt9IQDKr.mjs} +1 -1
  45. package/dist/history-BIiRCzbq.mjs +784 -0
  46. package/dist/i18n.d.mts +1 -1
  47. package/dist/{index-C9HjUX5c.d.mts → index-D5rgBzYZ.d.mts} +1 -2
  48. package/dist/index.d.mts +3 -3
  49. package/dist/index.mjs +2 -2
  50. package/dist/json.d.mts +1 -1
  51. package/dist/lib-DjccSI1B.mjs +143 -0
  52. package/dist/{lifecycle-BROTlwSL.mjs → lifecycle-C36WSbQS.mjs} +120 -27
  53. package/dist/{loadConfig-C3BQhz7F.mjs → loadConfig-BWIsDXR4.mjs} +1 -1
  54. package/dist/loadConfig-D-BpBgsk.mjs +1 -0
  55. package/dist/logBuildAppFinish-ChjwATMv.mjs +57 -0
  56. package/dist/mcp-CYgX9HpO.mjs +86 -0
  57. package/dist/mcp.d.mts +1 -1
  58. package/dist/mcpClient-DVLvFLZv.mjs +287 -0
  59. package/dist/{processCleanup-B6KA30Zc.mjs → metadata-hwF7QRcS.mjs} +1 -19
  60. package/dist/nodeEnv-BmH8UZPR.mjs +7 -0
  61. package/dist/openIde-CroqOgk5.mjs +648 -0
  62. package/dist/options-jqFwfD1G.mjs +34 -0
  63. package/dist/package-Cmakyy3J.mjs +4 -0
  64. package/dist/path-CYYIQGS7.mjs +44 -0
  65. package/dist/processCleanup-BQn2kTcK.mjs +19 -0
  66. package/dist/{protocol-vg8HGJ4n.mjs → protocol-Cg6Jdlvb.mjs} +42 -39
  67. package/dist/reader-sh_POQ9-.mjs +93 -0
  68. package/dist/realpathScope-Tf9mz-fh.mjs +23 -0
  69. package/dist/report-hyonPGbZ.mjs +107 -0
  70. package/dist/{path-doV773b7.mjs → resolvedId-CiDl7SC1.mjs} +3 -46
  71. package/dist/runtime-CLUhQsdA.mjs +43 -0
  72. package/dist/{runtime-Ee2HY6gR.d.mts → runtime-DpVf714f.d.mts} +1 -1
  73. package/dist/runtime.d.mts +1 -1
  74. package/dist/schematics-kO26eQRT.mjs +91 -0
  75. package/dist/{session-PskhD-nZ.mjs → session-D3zsdzIy.mjs} +71 -9
  76. package/dist/test.mjs +10 -8
  77. package/dist/{types-CgZn5X6j.d.mts → types-D-kfuyVa.d.mts} +1 -2
  78. package/dist/types-D0FFexRF.d.mts +39 -0
  79. package/dist/types.d.mts +2 -2
  80. package/dist/{upload-D4msblBf.mjs → upload-DozK8UdN.mjs} +109 -5
  81. package/dist/upload-worker.mjs +1 -1
  82. package/dist/{utils-CJSCgEj6.mjs → utils-Dy51PYAC.mjs} +56 -116
  83. package/dist/vite.d.mts +1 -1
  84. package/dist/vite.mjs +51 -12
  85. package/dist/wxs-BT8btflA.mjs +112 -0
  86. package/dist/wxs-Z4VQDeJ_.mjs +1 -0
  87. package/package.json +52 -46
  88. package/dist/dashboard-DvqF3Key.mjs +0 -1842
  89. package/dist/devProvider-BGBkw28J.mjs +0 -1050
  90. package/dist/file-DRb4eWqw.mjs +0 -1
  91. package/dist/getInstance-SiE6WZRh.mjs +0 -1
  92. package/dist/loadConfig-VGtBF4qm.mjs +0 -1
  93. package/dist/mcp-D3Yh24Cj.mjs +0 -529
@@ -0,0 +1,65 @@
1
+ //#region src/analyze/subpackages/artifacts/category.ts
2
+ function isRuntimeCategory(category) {
3
+ return category === "runtime" || category === "reactivity" || category === "host" || category === "helper";
4
+ }
5
+ //#endregion
6
+ //#region src/analyze/subpackages/budget.ts
7
+ const defaultBudgets = {
8
+ totalBytes: 20971520,
9
+ mainBytes: 2097152,
10
+ subPackageBytes: 2097152,
11
+ independentBytes: 2097152,
12
+ warningRatio: .85,
13
+ source: "default"
14
+ };
15
+ function createAnalyzeBudgetCheck(result) {
16
+ const budgets = result.metadata?.budgets ?? defaultBudgets;
17
+ const createItem = (options, unknown = false) => {
18
+ const ratio = options.limitBytes > 0 ? options.currentBytes / options.limitBytes : options.currentBytes > 0 ? 1 : 0;
19
+ return {
20
+ ...options,
21
+ ratio,
22
+ status: unknown ? "unknown" : ratio >= 1 ? "exceeded" : ratio >= budgets.warningRatio ? "warning" : "ok"
23
+ };
24
+ };
25
+ const files = result.packages.flatMap((pkg) => pkg.files);
26
+ const unique = new Map(files.map((file) => [file.file, file]));
27
+ const sizeUnknown = (items) => items.some((file) => typeof file.size !== "number" || !Number.isFinite(file.size) || file.size < 0);
28
+ const items = [createItem({
29
+ id: "__total__",
30
+ label: "总包",
31
+ scope: "total",
32
+ currentBytes: [...unique.values()].reduce((sum, file) => sum + (file.size ?? 0), 0),
33
+ limitBytes: budgets.totalBytes,
34
+ measurement: "file-bytes",
35
+ files: [...unique.keys()].sort()
36
+ }, sizeUnknown(files))];
37
+ for (const pkg of result.packages) {
38
+ const limitBytes = budgets.packageBytes?.[pkg.id] ?? (pkg.type === "main" ? budgets.mainBytes : pkg.type === "subPackage" ? budgets.subPackageBytes : pkg.type === "independent" ? budgets.independentBytes : void 0);
39
+ if (limitBytes === void 0) continue;
40
+ items.push(createItem({
41
+ id: pkg.id,
42
+ label: pkg.label,
43
+ scope: pkg.type,
44
+ currentBytes: pkg.files.reduce((sum, file) => sum + (file.size ?? 0), 0),
45
+ limitBytes,
46
+ measurement: "file-bytes",
47
+ files: pkg.files.map((file) => file.file).sort()
48
+ }, sizeUnknown(pkg.files)));
49
+ }
50
+ if (budgets.runtimeBytes !== void 0) {
51
+ const artifacts = result.artifacts;
52
+ items.push(createItem({
53
+ id: "__runtime__",
54
+ label: "Runtime(含混合 chunk 的文件上界)",
55
+ scope: "runtime",
56
+ currentBytes: artifacts?.runtime.upperBoundBytes ?? 0,
57
+ limitBytes: budgets.runtimeBytes,
58
+ measurement: artifacts ? "upper-bound" : "unavailable",
59
+ 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)
60
+ }, !artifacts || artifacts.runtime.unknownFiles.length > 0));
61
+ }
62
+ return items.sort((a, b) => b.ratio - a.ratio || a.label.localeCompare(b.label));
63
+ }
64
+ //#endregion
65
+ export { isRuntimeCategory as n, createAnalyzeBudgetCheck as t };
@@ -0,0 +1,541 @@
1
+ import { a as resolveWeappViteHostMeta } from "./pluginHost--CaeyWpA.mjs";
2
+ import { l as getProjectPlatformOptions } from "./platform-CnkySBKz.mjs";
3
+ import { r as logger_default } from "./logger-DGn5iEVN.mjs";
4
+ import { r as printUploadProgress } from "./report-hyonPGbZ.mjs";
5
+ import { a as terminateUploadProcess, i as terminateUploadDescendants, n as resolveUploadPlatforms, o as describeUploadProcessTreeError, r as redactUploadSecrets, t as prepareUpload } from "./upload-DozK8UdN.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
+ //#region 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
+ //#endregion
135
+ //#region src/cli/upload/env.ts
136
+ /** 凭据不经过 Vite 的 env 调试日志;文件优先级和进程环境覆盖规则保持一致。 */
137
+ async function loadUploadEnv(cwd, mode, root, envDir) {
138
+ if (envDir === false) return { ...process.env };
139
+ if (mode === "local") throw new Error("local 不能作为 mode,因为它与 .env.local 文件后缀冲突。");
140
+ const directory = path.resolve(cwd, root ?? ".", envDir ?? ".");
141
+ const parsed = {};
142
+ let parse;
143
+ for (const file of [
144
+ ".env",
145
+ ".env.local",
146
+ `.env.${mode}`,
147
+ `.env.${mode}.local`
148
+ ]) {
149
+ const content = await readFile(path.join(directory, file), "utf8").catch((error) => {
150
+ if (error.code === "ENOENT") return "";
151
+ throw error;
152
+ });
153
+ if (!content) continue;
154
+ parse ??= (await import("dotenv")).parse;
155
+ for (const [key, value] of Object.entries(parse(content))) {
156
+ delete parsed[key];
157
+ parsed[key] = value;
158
+ }
159
+ }
160
+ const processEnv = { ...parsed };
161
+ for (const [key, value] of Object.entries(process.env)) if (value !== void 0) {
162
+ processEnv[key] = value;
163
+ delete parsed[key];
164
+ }
165
+ if (Object.keys(parsed).length) {
166
+ const { expand } = await import("dotenv-expand");
167
+ expand({
168
+ parsed,
169
+ processEnv
170
+ });
171
+ }
172
+ return {
173
+ ...parsed,
174
+ ...process.env
175
+ };
176
+ }
177
+ //#endregion
178
+ //#region src/cli/upload/executionError.ts
179
+ /** 仅描述本地执行结果,不代表远端上传已取消。 */
180
+ var UploadExecutionError = class extends Error {
181
+ /** timeout 为本地超时,interrupted 为本地中断,failed 为工具或传输失败。 */
182
+ reason;
183
+ /** not-started 表示尚未允许 SDK 执行;unknown 表示远端结果需要人工核实。 */
184
+ remoteOutcome;
185
+ constructor(message, reason, remoteOutcome) {
186
+ super(message);
187
+ this.name = "UploadExecutionError";
188
+ this.reason = reason;
189
+ this.remoteOutcome = remoteOutcome;
190
+ }
191
+ };
192
+ //#endregion
193
+ //#region src/cli/upload/result.ts
194
+ /** 只接受可展示的预览结果,文件必须由本次任务生成,不能沿用旧二维码。 */
195
+ async function validatePreviewResult(value, context) {
196
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("预览工具未返回二维码或预览链接。");
197
+ const input = value;
198
+ const result = {};
199
+ for (const key of ["qrCodeUrl", "previewUrl"]) {
200
+ if (input[key] === void 0) continue;
201
+ if (typeof input[key] !== "string" || !input[key].trim()) throw new Error("预览工具返回了无效链接。");
202
+ let url;
203
+ try {
204
+ url = new URL(input[key]);
205
+ } catch {
206
+ throw new Error("预览工具返回了无效链接。");
207
+ }
208
+ if (url.username || url.password || key === "qrCodeUrl" && url.protocol !== "http:" && url.protocol !== "https:" || [
209
+ "javascript:",
210
+ "data:",
211
+ "file:"
212
+ ].includes(url.protocol)) throw new Error("预览工具返回了不支持的链接类型。");
213
+ result[key] = input[key];
214
+ }
215
+ if (input.qrCodeFile !== void 0) {
216
+ if (typeof input.qrCodeFile !== "string" || !context.qrCodePath || path.resolve(input.qrCodeFile) !== path.resolve(context.qrCodePath)) throw new Error("预览工具返回的二维码文件不是本次任务的输出路径。");
217
+ const file = await stat(input.qrCodeFile);
218
+ if (!file.isFile() || file.size === 0) throw new Error("预览二维码文件不存在或为空。");
219
+ result.qrCodeFile = input.qrCodeFile;
220
+ }
221
+ if (!result.qrCodeUrl && !result.previewUrl && !result.qrCodeFile) throw new Error("预览工具未返回二维码或预览链接。");
222
+ return result;
223
+ }
224
+ //#endregion
225
+ //#region src/cli/upload/process.ts
226
+ function readProgress(value, secrets) {
227
+ if (!value || typeof value !== "object" || !("type" in value) || ![
228
+ "progress",
229
+ "log",
230
+ "task-created",
231
+ "version-created"
232
+ ].includes(String(value.type))) return;
233
+ const event = { type: value.type };
234
+ if ("message" in value && typeof value.message === "string") event.message = redactUploadSecrets(value.message, secrets);
235
+ if ("percent" in value && typeof value.percent === "number" && Number.isFinite(value.percent) && value.percent >= 0 && value.percent <= 100) event.percent = value.percent;
236
+ return event;
237
+ }
238
+ /** 强制终止可能截断日志尾部;同时隐藏已知凭据的不完整前缀,保留普通诊断。 */
239
+ function redactDiagnostic(message, secrets) {
240
+ const output = message.trimEnd();
241
+ let end = output.length;
242
+ for (const value of secrets) {
243
+ const secret = value.trimEnd();
244
+ if (!secret) continue;
245
+ let start = output.indexOf(secret[0], Math.max(0, output.length - secret.length));
246
+ while (start !== -1) {
247
+ let offset = 0;
248
+ while (start + offset < output.length && output[start + offset] === secret[offset]) offset++;
249
+ if (start + offset === output.length) {
250
+ end = Math.min(end, start);
251
+ break;
252
+ }
253
+ start = output.indexOf(secret[0], start + 1);
254
+ }
255
+ }
256
+ return redactUploadSecrets(end < output.length ? `${output.slice(0, end)}[REDACTED]` : output, secrets);
257
+ }
258
+ /** 隔离官方 SDK;完成确认与正常退出必须同时成立,取消仅作用于本地进程。 */
259
+ async function executeUpload(platform, context, secrets, action = "upload", options = {}) {
260
+ const label = `${platform} ${action === "preview" ? "预览" : "上传"}`;
261
+ if (options.signal?.aborted) throw new UploadExecutionError(`${label}已中断(SDK 尚未开始)。`, "interrupted", "not-started");
262
+ const { result, output } = await new Promise((resolve, reject) => {
263
+ const spawnedAt = Date.now();
264
+ let child;
265
+ try {
266
+ child = fork(fileURLToPath(new URL("./upload-worker.mjs", import.meta.url)), [], {
267
+ cwd: context.cwd,
268
+ env: context.env,
269
+ execArgv: [],
270
+ stdio: [
271
+ "pipe",
272
+ "pipe",
273
+ "pipe",
274
+ "ipc"
275
+ ],
276
+ detached: process.platform !== "win32",
277
+ windowsHide: true
278
+ });
279
+ } catch (error) {
280
+ reject(new UploadExecutionError(redactUploadSecrets(`${label}无法启动:${String(error)}`, secrets), "failed", "not-started"));
281
+ return;
282
+ }
283
+ let completed = false;
284
+ let started = false;
285
+ let settled = false;
286
+ let result = {};
287
+ const captured = {
288
+ stdout: "",
289
+ stderr: ""
290
+ };
291
+ let capturedSize = 0;
292
+ let failure;
293
+ let timer;
294
+ let closeTimer;
295
+ const terminate = (descendants = true) => {
296
+ if (!child.pid) return;
297
+ const exited = child.exitCode !== null || child.signalCode !== null;
298
+ try {
299
+ if (descendants && !exited && process.platform !== "win32") terminateUploadDescendants(child.pid);
300
+ } catch (error) {
301
+ failure ??= {
302
+ reason: "failed",
303
+ detail: "无法清理本地子进程"
304
+ };
305
+ failure.detail += `;${describeUploadProcessTreeError(error)}`;
306
+ }
307
+ try {
308
+ terminateUploadProcess(child.pid, {
309
+ processGroup: true,
310
+ exited,
311
+ lifetime: {
312
+ start: spawnedAt,
313
+ end: Date.now()
314
+ }
315
+ });
316
+ } catch (error) {
317
+ failure ??= {
318
+ reason: "failed",
319
+ detail: "无法终止本地 worker"
320
+ };
321
+ failure.detail += `;${describeUploadProcessTreeError(error)}`;
322
+ if (!exited) child.kill("SIGKILL");
323
+ }
324
+ };
325
+ const stop = (reason, detail) => {
326
+ if (settled || failure) return;
327
+ failure = {
328
+ reason,
329
+ detail
330
+ };
331
+ clearTimeout(timer);
332
+ terminate();
333
+ };
334
+ const cancel = () => stop("interrupted", "本地执行已中断");
335
+ const onParentExit = () => terminate();
336
+ const collect = (stream, chunk) => {
337
+ if (failure) return;
338
+ const remaining = 4194304 - capturedSize;
339
+ if (chunk.length > remaining) {
340
+ captured.stdout = "";
341
+ captured.stderr = "";
342
+ stop("failed", "日志超限,已省略日志以保护凭据");
343
+ return;
344
+ }
345
+ captured[stream] += chunk;
346
+ capturedSize += chunk.length;
347
+ };
348
+ const onStdout = (chunk) => collect("stdout", chunk);
349
+ const onStderr = (chunk) => collect("stderr", chunk);
350
+ const onError = (error) => stop("failed", error.message);
351
+ const onDisconnect = () => {
352
+ if (!completed) stop("failed", "IPC 连接中断,未收到完成确认");
353
+ };
354
+ const onMessage = (message) => {
355
+ if (settled || failure || !message || typeof message !== "object" || !("action" in message) || message.action !== action || !("type" in message)) return;
356
+ if (message.type === "started" && !started) {
357
+ started = true;
358
+ child.send({
359
+ type: "run",
360
+ action
361
+ }, (error) => {
362
+ if (error) onError(error);
363
+ });
364
+ } else if (message.type === "progress" && "event" in message) {
365
+ const event = readProgress(message.event, secrets);
366
+ if (event) try {
367
+ options.onProgress?.(event);
368
+ } catch (error) {
369
+ stop("failed", `进度处理失败:${String(error)}`);
370
+ }
371
+ } else if (message.type === "completed" && started) {
372
+ completed = true;
373
+ result = "result" in message && message.result && typeof message.result === "object" ? message.result : {};
374
+ }
375
+ };
376
+ const onExit = () => {
377
+ clearTimeout(timer);
378
+ terminate(false);
379
+ closeTimer = setTimeout(() => {
380
+ failure ??= {
381
+ reason: "failed",
382
+ detail: "worker 已退出"
383
+ };
384
+ failure.detail += ";日志管道未关闭,本地子进程清理未确认";
385
+ captured.stdout = "";
386
+ captured.stderr = "";
387
+ child.stdin?.destroy();
388
+ child.stdout?.destroy();
389
+ child.stderr?.destroy();
390
+ }, 1e3);
391
+ };
392
+ const cleanup = () => {
393
+ clearTimeout(timer);
394
+ clearTimeout(closeTimer);
395
+ options.signal?.removeEventListener("abort", cancel);
396
+ process.off("SIGINT", cancel);
397
+ process.off("SIGTERM", cancel);
398
+ process.off("exit", onParentExit);
399
+ child.off("message", onMessage);
400
+ child.off("error", onError);
401
+ child.off("disconnect", onDisconnect);
402
+ child.off("exit", onExit);
403
+ child.stdout?.off("data", onStdout);
404
+ child.stderr?.off("data", onStderr);
405
+ child.stdin?.off("error", onError);
406
+ };
407
+ child.once("close", (code, signal) => {
408
+ settled = true;
409
+ cleanup();
410
+ const output = [redactDiagnostic(captured.stdout, secrets), redactDiagnostic(captured.stderr, secrets)].filter(Boolean).join("\n").trim();
411
+ if (failure || code !== 0 || !completed) {
412
+ const detail = failure?.detail ?? `${signal ?? code ?? "unknown"},${completed ? "进程异常结束" : "未收到完成确认"}`;
413
+ reject(new UploadExecutionError(redactUploadSecrets(`${label}失败(${detail})。${started ? "远端结果未知,请核实平台状态;未自动重试。" : "SDK 尚未开始。"}${output ? `\n${output}` : ""}`, secrets), failure?.reason ?? "failed", started ? "unknown" : "not-started"));
414
+ return;
415
+ }
416
+ resolve({
417
+ result,
418
+ output
419
+ });
420
+ });
421
+ child.on("error", onError);
422
+ child.on("disconnect", onDisconnect);
423
+ child.on("message", onMessage);
424
+ child.once("exit", onExit);
425
+ child.stdout?.setEncoding("utf8").on("data", onStdout);
426
+ child.stderr?.setEncoding("utf8").on("data", onStderr);
427
+ child.stdin?.on("error", onError);
428
+ process.once("exit", onParentExit);
429
+ if (options.signal) options.signal.addEventListener("abort", cancel, { once: true });
430
+ else {
431
+ process.once("SIGINT", cancel);
432
+ process.once("SIGTERM", cancel);
433
+ }
434
+ if (options.timeoutMs !== void 0) timer = setTimeout(stop, options.timeoutMs, "timeout", `本地执行超时(${options.timeoutMs}ms)`);
435
+ if (options.signal?.aborted) cancel();
436
+ else try {
437
+ child.stdin?.end(JSON.stringify({
438
+ platform,
439
+ context,
440
+ action
441
+ }));
442
+ } catch (error) {
443
+ stop("failed", String(error));
444
+ }
445
+ });
446
+ if (output) logger_default.info(output);
447
+ return action === "preview" ? validatePreviewResult(result, context) : result;
448
+ }
449
+ //#endregion
450
+ //#region src/cli/upload/project.ts
451
+ /** 确保官方工具读取的目录正是本次构建输出,拒绝误传旧目录或同名配置。 */
452
+ async function validateUploadProject(options) {
453
+ const { projectConfigFileName } = getProjectPlatformOptions(options.platform);
454
+ if (options.sourceConfigPath && path.basename(options.sourceConfigPath) !== projectConfigFileName) throw new Error(`上传工具只读取 ${projectConfigFileName},请使用此标准文件名,避免读取其他项目配置。`);
455
+ const configPath = path.join(options.projectPath, projectConfigFileName);
456
+ const config = JSON.parse(await readFile(configPath, "utf8"));
457
+ if (!config || typeof config !== "object" || Array.isArray(config)) throw new TypeError(`${projectConfigFileName} 必须是 JSON 对象。`);
458
+ const rootKey = options.platform === "swan" ? "smartProgramRoot" : "miniprogramRoot";
459
+ const root = config[rootKey];
460
+ if (typeof root !== "string" || !root.trim()) throw new Error(`${projectConfigFileName} 缺少代码目录 ${rootKey}。`);
461
+ const sdkRoot = path.resolve(options.projectPath, root);
462
+ const [actualRoot, outputRoot] = await Promise.all([realpath(sdkRoot), realpath(options.outDir)]);
463
+ if (actualRoot !== outputRoot) throw new Error(`${projectConfigFileName} 的代码目录与本次构建输出不一致,已阻止上传旧产物。请检查项目配置根目录与 build.outDir。`);
464
+ await access(path.join(outputRoot, "app.json"));
465
+ }
466
+ //#endregion
467
+ //#region src/cli/upload/builtProject.ts
468
+ /** 仅由显式上传或预览入口读取参数,不执行构建或调用平台工具。 */
469
+ async function createUploadTarget(config, options, action) {
470
+ if (config.weappLibConfig?.enabled || config.pluginOnly) throw new Error(`${action} 仅支持完整小程序项目,不支持组件库或独立插件构建。`);
471
+ const platform = resolveUploadPlatforms(config.platform)[0];
472
+ const uploadConfig = action === "upload" ? config.weappViteConfig.upload : void 0;
473
+ const version = (options.uv ?? uploadConfig?.version ?? config.packageJson.version)?.trim() ?? "";
474
+ if (action === "upload" && !version) throw new Error("请通过 --uv、weapp.upload.version 或项目 package.json 的 version 指定上传版本。");
475
+ const desc = (options.desc ?? uploadConfig?.desc)?.trim() || `${config.packageJson.name ?? platform}${version ? `@${version}` : ""}`;
476
+ const env = options.dryRun ? {} : await loadUploadEnv(config.cwd, config.mode, config.inlineConfig.root, config.inlineConfig.envDir);
477
+ const { projectConfigFileName } = getProjectPlatformOptions(config.platform);
478
+ const generatedProjectConfig = config.multiPlatform.projectConfigs !== void 0;
479
+ const projectPath = generatedProjectConfig ? config.outDir : config.multiPlatform.enabled ? path.dirname(config.outDir) : path.dirname(config.projectConfigPath ?? path.join(config.cwd, projectConfigFileName));
480
+ const appid = config.projectConfig.appid ?? config.projectConfig.appId;
481
+ const target = {
482
+ platform,
483
+ sourceConfigPath: config.projectConfigPath,
484
+ context: {
485
+ cwd: config.cwd,
486
+ projectPath,
487
+ appid: typeof appid === "string" ? appid : void 0,
488
+ version,
489
+ desc,
490
+ qrCodePath: action === "preview" && !options.dryRun ? path.join(config.cwd, ".weapp-vite", "preview", `${platform}-${randomUUID()}.png`) : void 0,
491
+ env: {
492
+ ...process.env,
493
+ ...env
494
+ }
495
+ }
496
+ };
497
+ (config.inlineConfig.plugins ??= []).push({
498
+ name: "weapp-vite:upload-output",
499
+ apply: (viteConfig) => resolveWeappViteHostMeta(viteConfig)?.runtime === "miniprogram",
500
+ writeBundle(output, bundle) {
501
+ if (output.dir && Object.hasOwn(bundle, "app.json")) {
502
+ target.outDir = path.resolve(output.dir);
503
+ if (generatedProjectConfig) target.context.projectPath = target.outDir;
504
+ }
505
+ }
506
+ });
507
+ return target;
508
+ }
509
+ /** 只消费本次构建的产物;产物校验通过前不会准备凭据或调用平台工具。 */
510
+ async function executeUploadTarget(target, options, action, execution = {}) {
511
+ const { platform, context } = target;
512
+ if (!target.outDir) throw new Error("本次构建未写出 app.json,已阻止上传或预览旧产物。");
513
+ await validateUploadProject({
514
+ platform,
515
+ projectPath: context.projectPath,
516
+ outDir: target.outDir,
517
+ sourceConfigPath: target.sourceConfigPath
518
+ });
519
+ if (options.dryRun) {
520
+ logger_default.success(`[${action}:${platform}] dry-run:构建完成,未校验凭据或调用平台工具。项目:${path.relative(context.cwd, context.projectPath) || "."}`);
521
+ return;
522
+ }
523
+ const upload = await prepareUpload(platform, context, action);
524
+ execution.onUpload?.();
525
+ const result = await executeUpload(platform, context, upload.secrets, action, {
526
+ ...execution,
527
+ onProgress: execution.onProgress ?? ((event) => printUploadProgress(platform, event))
528
+ });
529
+ if (action === "preview") {
530
+ if (!result) throw new Error("预览工具未返回二维码或预览链接。");
531
+ for (const [label, value] of [
532
+ ["二维码图片", result.qrCodeUrl],
533
+ ["预览链接", result.previewUrl],
534
+ ["二维码文件", result.qrCodeFile && path.relative(context.cwd, result.qrCodeFile)]
535
+ ]) if (value) logger_default.info(`[preview:${platform}] ${label}:${redactUploadSecrets(value, upload.secrets)}`);
536
+ logger_default.success(`[preview:${platform}] 预览已生成(未上传开发版本、未提审、未正式发布)。`);
537
+ } else logger_default.success(`[upload:${platform}] ${context.version} 上传完成(未提审、未正式发布)。`);
538
+ return result;
539
+ }
540
+ //#endregion
541
+ export { prepareAutoUploadMetadataWithRollback as a, prepareAutoUploadMetadata as i, executeUploadTarget as n, validateAutoUploadMetadata as o, UploadExecutionError as r, createUploadTarget as t };
@@ -1,5 +1,5 @@
1
- import { a as parseSidecarModuleId, i as parseLogicalEntryId, o as parseSidecarSourceRequest } from "./protocol-vg8HGJ4n.mjs";
2
- import { r as normalizeRelativePath } from "./path-doV773b7.mjs";
1
+ import { a as parseSidecarModuleId, i as parseLogicalEntryId, s as parseSidecarSourceRequest } from "./protocol-Cg6Jdlvb.mjs";
2
+ import { r as normalizeRelativePath } from "./path-CYYIQGS7.mjs";
3
3
  import { posix } from "pathe";
4
4
  import { removeExtensionDeep } from "@weapp-core/shared";
5
5
  import { Buffer } from "node:buffer";
@@ -143,6 +143,18 @@ function applyMagicStringChunkRewrite(chunk, magicString, options) {
143
143
  return true;
144
144
  }
145
145
  /**
146
+ * 原子地提交一次 chunk 改写;映射组合失败时保留原始 chunk。
147
+ */
148
+ function applyAtomicMagicStringChunkRewrite(chunk, magicString, options) {
149
+ const staged = { ...chunk };
150
+ const changed = applyMagicStringChunkRewrite(staged, magicString, options);
151
+ Object.assign(chunk, {
152
+ code: staged.code,
153
+ map: staged.map
154
+ });
155
+ return changed;
156
+ }
157
+ /**
146
158
  * 在 chunk 当前代码上执行一次可追踪编辑。
147
159
  */
148
160
  function editOutputChunkCode(chunk, edit, options) {
@@ -1433,4 +1445,4 @@ function resolveSharedChunkName(options) {
1433
1445
  return "common";
1434
1446
  }
1435
1447
  //#endregion
1436
- export { syncOutputChunkSourceMapAssets as _, SUB_PACKAGE_SHARED_DIR as a, normalizeEncodedSourceMapLike as b, resolveSubPackagePrefix as c, applyOutputChunkTransform as d, editOutputChunkCode as f, resolveOutputChunkTransformCode as g, replaceOutputChunkCodeRanges as h, SHARED_CHUNK_VIRTUAL_PREFIX as i, appendOutputChunkCode as l, replaceOutputChunkCode as m, applySharedChunkStrategy as n, applyRuntimeChunkLocalization as o, prependOutputChunkCode as p, DEFAULT_SHARED_CHUNK_STRATEGY as r, assertModuleScopedToRoot as s, resolveSharedChunkName as t, applyMagicStringChunkRewrite as u, composeSourceMaps as v, resetTakeImportRegistry as x, labelSourceMapInput as y };
1448
+ export { resetTakeImportRegistry as S, resolveOutputChunkTransformCode as _, SUB_PACKAGE_SHARED_DIR as a, labelSourceMapInput as b, resolveSubPackagePrefix as c, applyMagicStringChunkRewrite as d, applyOutputChunkTransform as f, replaceOutputChunkCodeRanges as g, replaceOutputChunkCode as h, SHARED_CHUNK_VIRTUAL_PREFIX as i, appendOutputChunkCode as l, prependOutputChunkCode as m, applySharedChunkStrategy as n, applyRuntimeChunkLocalization as o, editOutputChunkCode as p, DEFAULT_SHARED_CHUNK_STRATEGY as r, assertModuleScopedToRoot as s, resolveSharedChunkName as t, applyAtomicMagicStringChunkRewrite as u, syncOutputChunkSourceMapAssets as v, normalizeEncodedSourceMapLike as x, composeSourceMaps as y };
@@ -1,6 +1,6 @@
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-CYYIQGS7.mjs";
2
+ import "./utils-Dy51PYAC.mjs";
3
+ import { i as SHARED_CHUNK_VIRTUAL_PREFIX } from "./chunkStrategy-DY_LZIIe.mjs";
4
4
  import { posix } from "pathe";
5
5
  //#region src/analyze/subpackages/classifier.ts
6
6
  const VIRTUAL_MODULE_INDICATOR = "\0";
@@ -85,7 +85,4 @@ function resolveAssetSource(fileName, ctx) {
85
85
  };
86
86
  }
87
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 };
88
+ export { resolveModuleSourceType as i, normalizeModuleId as n, resolveAssetSource as r, classifyPackage as t };
@@ -1,5 +1,5 @@
1
1
  import { t as VERSION } from "./constants-DEZdcsMn.mjs";
2
- import { l as registerAcceptCommand, t as registerMcpCommand } from "./mcp-D3Yh24Cj.mjs";
2
+ import { n as registerAcceptCommand, t as registerMcpCommand } from "./mcp-CYgX9HpO.mjs";
3
3
  import process from "node:process";
4
4
  import { cac } from "cac";
5
5
  //#region src/cli-acceptance.ts