@heybox/hb-sdk 0.9.0-alpha.1 → 0.9.0-alpha.3
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.
- package/CHANGELOG.md +13 -0
- package/README.md +6 -1
- package/dist/cli-chunks/{build-BSeiFi0q.cjs → build-C4d4WXYT.cjs} +5 -5
- package/dist/cli-chunks/{context-D_L2-Hla.cjs → context-mt_ERryB.cjs} +2 -2
- package/dist/cli-chunks/{create-Dzeodh_-.cjs → create-LfZ8OhT6.cjs} +1 -1
- package/dist/cli-chunks/{dev-DQ7k_fu6.cjs → dev-lgUgVorS.cjs} +209 -10
- package/dist/cli-chunks/{doctor-FIcFZiJ0.cjs → doctor-BSJnY0Bu.cjs} +1 -1
- package/dist/cli-chunks/{index-d1cUUoR9.cjs → index-BtqxUixL.cjs} +15 -15
- package/dist/cli-chunks/{index-CakUTosC.cjs → index-DVALw2rx.cjs} +2 -2
- package/dist/cli-chunks/{index.esm-CerEC339.cjs → index.esm-Deim9BX8.cjs} +7 -7
- package/dist/cli-chunks/{login-lZKDg_9k.cjs → login-TIFXGbKv.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-BM7D-pf6.cjs → project-vite-DSBP8NLj.cjs} +1 -1
- package/dist/cli-chunks/{remote-9-tyxq6l.cjs → remote-DyGb3YBA.cjs} +83 -17
- package/dist/cli-chunks/{runtime-gate-BfAGMrE2.cjs → runtime-gate-CWUZK4aE.cjs} +1 -1
- package/dist/cli-chunks/{runtime-permission-env-B-GwDDT7.cjs → runtime-permission-env-DdWYFrFT.cjs} +39 -6
- package/dist/cli-chunks/{session-mMVA3395.cjs → session-CWCq-oeW.cjs} +1 -1
- package/dist/cli-chunks/{skill-BhUlKvyY.cjs → skill-DQzR5fMS.cjs} +2 -2
- package/dist/cli-chunks/{version-hsUgRL0I.cjs → version-4zRtvcVD.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/browser-dev-host/assets/{browser-dev-host-BLgy6aQ6.js → browser-dev-host-BEJTrPTS.js} +1 -1
- package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-D32fpjYQ.js → desktop-app-launch-Dod9L2SF.js} +1 -1
- package/dist/devtools/browser-dev-host/assets/{index-DMuA2oZx.js → index-xtE6gn7j.js} +3 -3
- package/dist/devtools/browser-dev-host/index.html +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/miniapp-publish.cjs.js +38 -5
- package/dist/miniapp-publish.esm.js +38 -5
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.esm.js +1 -1
- package/docs/runtime-host-migration.md +3 -1
- package/package.json +5 -5
- package/skill/skill.json +4 -4
- package/types/miniapp-publish/index.d.ts +13 -3
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var runtimePermissionEnv = require('./runtime-permission-env-
|
|
4
|
-
var context = require('./context-
|
|
3
|
+
var runtimePermissionEnv = require('./runtime-permission-env-DdWYFrFT.cjs');
|
|
4
|
+
var context = require('./context-mt_ERryB.cjs');
|
|
5
5
|
var promises = require('node:readline/promises');
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var session = require('./session-
|
|
6
|
+
var index = require('./index-BtqxUixL.cjs');
|
|
7
|
+
var session = require('./session-CWCq-oeW.cjs');
|
|
8
8
|
var childProcess = require('node:child_process');
|
|
9
9
|
var fs = require('node:fs');
|
|
10
10
|
var fs$1 = require('node:fs/promises');
|
|
11
11
|
var path = require('node:path');
|
|
12
12
|
var node_crypto = require('node:crypto');
|
|
13
13
|
require('node:zlib');
|
|
14
|
-
var runtimeGate = require('./runtime-gate-
|
|
15
|
-
require('./version-
|
|
14
|
+
var runtimeGate = require('./runtime-gate-CWUZK4aE.cjs');
|
|
15
|
+
require('./version-4zRtvcVD.cjs');
|
|
16
16
|
require('node:async_hooks');
|
|
17
17
|
require('sharp');
|
|
18
18
|
require('node:module');
|
|
@@ -68,6 +68,14 @@ async function postHeyboxApi(pathWithQuery, body, session$1, runtime) {
|
|
|
68
68
|
|
|
69
69
|
const CREATE_USER_MINIPROGRAM_UPLOAD_SESSION_API_PATH = '/mall/developer/user_miniprogram/version/upload_session/create';
|
|
70
70
|
const RECORD_USER_MINIPROGRAM_UPLOAD_RESULT_API_PATH = '/mall/developer/user_miniprogram/version/upload_session/record';
|
|
71
|
+
const COMPANION_FINALIZATION_TIMEOUT_MS = 30 * 60_000;
|
|
72
|
+
async function authorizeCompanionUpload(options, runtime = {}) {
|
|
73
|
+
const result = await postUserMiniprogramVersionForm('/mall/developer/user_miniprogram/version/upload_session/companion_authorization', options, { version: options.version, session_id: options.sessionId, relative_paths: options.relativePaths.join(','), artifact_protocol_version: '2' }, runtime);
|
|
74
|
+
if (!result.bucket || !result.region || !Array.isArray(result.keys) || !result.tmp_secret_id || !result.tmp_secret_key || !result.session_token || !(result.expired_time > result.start_time)) {
|
|
75
|
+
throw new Error('Companion 上传凭证响应不完整');
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
71
79
|
async function precheckUserMiniprogramVersion(options, runtime = {}) {
|
|
72
80
|
return postUserMiniprogramVersionForm(runtimePermissionEnv.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, options, {
|
|
73
81
|
// 构建前轻预检不携带独立资料;权威准入读取构建 Manifest。
|
|
@@ -78,11 +86,12 @@ async function precheckUserMiniprogramVersion(options, runtime = {}) {
|
|
|
78
86
|
}, runtime);
|
|
79
87
|
}
|
|
80
88
|
async function submitUserMiniprogramAudit(options, runtime = {}) {
|
|
81
|
-
return postUserMiniprogramVersionForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, options, { session_id: options.sessionId, preflight_token: options.preflightToken }, runtime);
|
|
89
|
+
return postUserMiniprogramVersionForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, options, { session_id: options.sessionId, preflight_token: options.preflightToken, artifact_protocol_version: '2' }, runtime);
|
|
82
90
|
}
|
|
83
91
|
async function createUserMiniprogramUploadSession(options, runtime = {}) {
|
|
84
92
|
return postUserMiniprogramVersionForm(CREATE_USER_MINIPROGRAM_UPLOAD_SESSION_API_PATH, options, {
|
|
85
93
|
version: options.version,
|
|
94
|
+
artifact_protocol_version: '2',
|
|
86
95
|
artifact_signature: options.artifactSignature,
|
|
87
96
|
files: JSON.stringify(options.files),
|
|
88
97
|
manifest: JSON.stringify(options.manifest),
|
|
@@ -91,11 +100,27 @@ async function createUserMiniprogramUploadSession(options, runtime = {}) {
|
|
|
91
100
|
}, runtime);
|
|
92
101
|
}
|
|
93
102
|
async function recordUserMiniprogramUploadResult(options, runtime = {}) {
|
|
94
|
-
|
|
103
|
+
const fields = {
|
|
95
104
|
version: options.version,
|
|
105
|
+
artifact_protocol_version: '2',
|
|
96
106
|
session_id: options.sessionId,
|
|
97
107
|
files: JSON.stringify(options.files),
|
|
98
|
-
}
|
|
108
|
+
};
|
|
109
|
+
const deadline = Date.now() + COMPANION_FINALIZATION_TIMEOUT_MS;
|
|
110
|
+
for (;;) {
|
|
111
|
+
const result = await postUserMiniprogramVersionForm(RECORD_USER_MINIPROGRAM_UPLOAD_RESULT_API_PATH, options, fields, runtime);
|
|
112
|
+
if (result.artifact_protocol_version !== 2 || !Array.isArray(result.companion_files)) {
|
|
113
|
+
throw new Error('服务端未返回产物协议 v2 Finalize 状态');
|
|
114
|
+
}
|
|
115
|
+
const failed = result.companion_files.find((file) => file.state === 'failed');
|
|
116
|
+
if (failed)
|
|
117
|
+
throw new Error(failed.error || `Companion 归档验证失败:${failed.relative_path}`);
|
|
118
|
+
if (result.complete)
|
|
119
|
+
return;
|
|
120
|
+
if (Date.now() >= deadline)
|
|
121
|
+
throw new Error('Companion 归档验证超时,请稍后重试');
|
|
122
|
+
await new Promise((resolve) => setTimeout(resolve, Math.max(250, Math.min(result.retry_after_ms || 1000, 5000))));
|
|
123
|
+
}
|
|
99
124
|
}
|
|
100
125
|
async function postUserMiniprogramVersionForm(path, options, fields, runtime) {
|
|
101
126
|
const fetchImpl = runtime.fetchImpl ?? fetch;
|
|
@@ -134,17 +159,21 @@ async function runUpload(options, runtime = {}) {
|
|
|
134
159
|
createCosClient = ({ uploadToken }) => createDefaultCosClient(uploadToken, COS);
|
|
135
160
|
}
|
|
136
161
|
const orderedFiles = runtimePermissionEnv.prepareMiniappArtifactFiles(options.files);
|
|
137
|
-
const batches = chunkUploadFiles(orderedFiles, runtimePermissionEnv.MINIAPP_UPLOAD_BATCH_SIZE);
|
|
162
|
+
const batches = [false, true].flatMap(companion => chunkUploadFiles(orderedFiles.filter(file => file.relativePath.startsWith('companions/') === companion), runtimePermissionEnv.MINIAPP_UPLOAD_BATCH_SIZE));
|
|
138
163
|
await logger.task(`正在上传 ${orderedFiles.length} 个文件`, async (taskContext) => {
|
|
139
164
|
logger.debug(`上传并发数: ${concurrency}`);
|
|
140
165
|
logger.debug(`上传批次数: ${batches.length}`);
|
|
141
166
|
let completed = 0;
|
|
142
167
|
for (let batchIndex = 0; batchIndex < batches.length; batchIndex += 1) {
|
|
143
168
|
const batch = batches[batchIndex];
|
|
169
|
+
const companion = batch[0].relativePath.startsWith('companions/');
|
|
170
|
+
const grant = companion ? await (runtime.authorizeCompanionUpload ?? authorizeCompanionUpload)({
|
|
171
|
+
session: options.session, miniProgramId: options.miniProgramId, version: options.version, sessionId: options.uploadSessionId, relativePaths: batch.map(file => file.relativePath),
|
|
172
|
+
}, { baseUrl: runtime.baseUrl, fetchImpl }) : undefined;
|
|
144
173
|
logger.debug(`正在处理上传批次 ${batchIndex + 1}/${batches.length},文件数: ${batch.length}`);
|
|
145
174
|
logger.debug('正在获取 CDN 上传信息');
|
|
146
175
|
const fileInfos = createUploadFileInfos(batch);
|
|
147
|
-
const uploadInfo = await getCDNUploadInfo$1({
|
|
176
|
+
const uploadInfo = grant ?? await getCDNUploadInfo$1({
|
|
148
177
|
session: options.session,
|
|
149
178
|
scope: runtimePermissionEnv.MINIAPP_UPLOAD_SCOPE,
|
|
150
179
|
fileInfos,
|
|
@@ -157,7 +186,10 @@ async function runUpload(options, runtime = {}) {
|
|
|
157
186
|
logger.debug('正在获取本批 CDN 上传凭证');
|
|
158
187
|
let uploadToken;
|
|
159
188
|
try {
|
|
160
|
-
uploadToken =
|
|
189
|
+
uploadToken = grant ? {
|
|
190
|
+
credentials: { tmpSecretId: grant.tmp_secret_id, tmpSecretKey: grant.tmp_secret_key, sessionToken: grant.session_token },
|
|
191
|
+
startTime: grant.start_time, expiredTime: grant.expired_time,
|
|
192
|
+
} : await getCDNUploadToken$1({
|
|
161
193
|
session: options.session,
|
|
162
194
|
bucket: uploadInfo.bucket,
|
|
163
195
|
keys: indexedFiles.map(item => item.key),
|
|
@@ -186,6 +218,11 @@ async function runUpload(options, runtime = {}) {
|
|
|
186
218
|
Body: createReadStream(uploadTask.file.absolutePath),
|
|
187
219
|
ContentLength: uploadTask.file.size,
|
|
188
220
|
ContentType: uploadTask.file.mimeType,
|
|
221
|
+
...(companion ? { Headers: { 'x-cos-forbid-overwrite': 'true' } } : {}),
|
|
222
|
+
}).catch(error => {
|
|
223
|
+
if (companion && isExistingCompanionObject(error))
|
|
224
|
+
return;
|
|
225
|
+
throw error;
|
|
189
226
|
});
|
|
190
227
|
successfulKeys.push(uploadTask.key);
|
|
191
228
|
completed += 1;
|
|
@@ -203,7 +240,8 @@ async function runUpload(options, runtime = {}) {
|
|
|
203
240
|
await Promise.all(workers);
|
|
204
241
|
if (successfulKeys.length > 0) {
|
|
205
242
|
logger.debug('正在确认 CDN 上传结果');
|
|
206
|
-
|
|
243
|
+
if (!companion)
|
|
244
|
+
await postCDNUploadCallback$1({ session: options.session, keys: successfulKeys, isFinished: true }, { baseUrl: runtime.baseUrl, fetchImpl });
|
|
207
245
|
await recordUserMiniprogramUploadResult$1({
|
|
208
246
|
session: options.session,
|
|
209
247
|
miniProgramId: options.miniProgramId,
|
|
@@ -227,6 +265,12 @@ function chunkUploadFiles(files, batchSize) {
|
|
|
227
265
|
}
|
|
228
266
|
return batches;
|
|
229
267
|
}
|
|
268
|
+
function isExistingCompanionObject(error) {
|
|
269
|
+
if (!error || typeof error !== 'object')
|
|
270
|
+
return false;
|
|
271
|
+
const value = error;
|
|
272
|
+
return Number(value.statusCode) === 409 && value.code === 'ObjectAlreadyExists';
|
|
273
|
+
}
|
|
230
274
|
function createUploadFileInfos(files) {
|
|
231
275
|
return files.map((file) => ({
|
|
232
276
|
name: file.relativePath.split('/').pop() ?? file.relativePath,
|
|
@@ -264,7 +308,7 @@ function createDefaultCosClient(uploadToken, COS) {
|
|
|
264
308
|
return new Promise((resolve, reject) => {
|
|
265
309
|
cos.putObject(params, (err, result) => {
|
|
266
310
|
if (err) {
|
|
267
|
-
reject(err
|
|
311
|
+
reject(err);
|
|
268
312
|
return;
|
|
269
313
|
}
|
|
270
314
|
resolve(result);
|
|
@@ -274,7 +318,7 @@ function createDefaultCosClient(uploadToken, COS) {
|
|
|
274
318
|
};
|
|
275
319
|
}
|
|
276
320
|
async function loadCosConstructor() {
|
|
277
|
-
const cosModule = await Promise.resolve().then(function () { return require('./index-
|
|
321
|
+
const cosModule = await Promise.resolve().then(function () { return require('./index-DVALw2rx.cjs'); }).then(function (n) { return n.index; });
|
|
278
322
|
return cosModule.default;
|
|
279
323
|
}
|
|
280
324
|
function formatSize(bytes) {
|
|
@@ -519,6 +563,9 @@ const MIME_BY_EXT = {
|
|
|
519
563
|
'.woff': 'font/woff',
|
|
520
564
|
'.woff2': 'font/woff2',
|
|
521
565
|
};
|
|
566
|
+
function formatDeployBytes(bytes) {
|
|
567
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MiB`;
|
|
568
|
+
}
|
|
522
569
|
async function runDeployCommand(options, runtime = {}) {
|
|
523
570
|
const logger = runtime.logger ?? index.createCliLogger();
|
|
524
571
|
const cwd = runtime.cwd ?? process.cwd();
|
|
@@ -691,24 +738,43 @@ async function runDeployCommand(options, runtime = {}) {
|
|
|
691
738
|
}
|
|
692
739
|
if (!result.preflight_token)
|
|
693
740
|
throw new Error('服务端未返回 preflight_token,请先升级服务端');
|
|
741
|
+
if (result.artifact_protocol_version !== 2) {
|
|
742
|
+
throw new Error('创建上传会话失败:服务端不支持产物协议 v2,请升级服务端后重试');
|
|
743
|
+
}
|
|
694
744
|
if (result.file_receipt_version !== 1) {
|
|
695
745
|
throw new Error('创建上传会话失败:服务端不支持文件完整性 receipt v1,请升级服务端后重试');
|
|
696
746
|
}
|
|
697
|
-
|
|
747
|
+
if (!Array.isArray(result.files) || !Array.isArray(result.uploaded_keys) || !Array.isArray(result.reused_companion_files)) {
|
|
748
|
+
throw new Error('创建上传会话失败:服务端返回的产物协议 v2 文件清单不完整');
|
|
749
|
+
}
|
|
750
|
+
const resolved = runtimePermissionEnv.resolveMiniappUploadSessionFiles(artifactReceipt.files, result.files, result.uploaded_keys, result.reused_companion_files);
|
|
698
751
|
return {
|
|
699
752
|
preflightToken: result.preflight_token,
|
|
700
753
|
sessionId: result.session_id.trim(),
|
|
701
754
|
files: resolved.files,
|
|
702
755
|
missingFiles: resolved.missingFiles,
|
|
756
|
+
reusedCompanionFiles: resolved.reusedCompanionFiles,
|
|
703
757
|
};
|
|
704
758
|
}, { successText: '上传会话已就绪' });
|
|
705
759
|
uploadSessionId = createdUploadSession.sessionId;
|
|
706
760
|
preflightToken = createdUploadSession.preflightToken;
|
|
707
761
|
const uploadedCount = createdUploadSession.files.length - createdUploadSession.missingFiles.length;
|
|
708
762
|
if (uploadedCount > 0) {
|
|
709
|
-
logger.debug(
|
|
763
|
+
logger.debug(`会话内已上传文件: ${uploadedCount}/${createdUploadSession.files.length}`);
|
|
710
764
|
}
|
|
765
|
+
const reusedBytes = createdUploadSession.reusedCompanionFiles.reduce((sum, file) => sum + file.size, 0);
|
|
766
|
+
const uploadBytes = createdUploadSession.missingFiles.reduce((sum, { file }) => sum + file.size, 0);
|
|
767
|
+
logger.info(`Companion Blob 复用: ${createdUploadSession.reusedCompanionFiles.length} 个,免上传 ${formatDeployBytes(reusedBytes)};实际待上传 ${formatDeployBytes(uploadBytes)}`);
|
|
711
768
|
try {
|
|
769
|
+
const missingKeys = new Set(createdUploadSession.missingFiles.map(item => item.key));
|
|
770
|
+
const uploadedCompanions = createdUploadSession.files.filter(item => item.file.relativePath.startsWith('companions/') && !missingKeys.has(item.key));
|
|
771
|
+
for (let index = 0; index < uploadedCompanions.length; index += runtimePermissionEnv.MINIAPP_UPLOAD_BATCH_SIZE) {
|
|
772
|
+
await (runtime.recordUserMiniprogramUploadResult ?? recordUserMiniprogramUploadResult)({
|
|
773
|
+
session: session$1, miniProgramId, version, sessionId: uploadSessionId,
|
|
774
|
+
files: uploadedCompanions.slice(index, index + runtimePermissionEnv.MINIAPP_UPLOAD_BATCH_SIZE)
|
|
775
|
+
.map(({ file }) => ({ path: file.relativePath, size: file.size, sha256: file.sha256 })),
|
|
776
|
+
}, { baseUrl: apiBaseUrl, fetchImpl: runtime.fetchImpl });
|
|
777
|
+
}
|
|
712
778
|
if (createdUploadSession.missingFiles.length > 0) {
|
|
713
779
|
await assertDeployUploadFilesStillMatchSignature({
|
|
714
780
|
computeMiniappArtifactReceipt: runtime.computeMiniappArtifactReceipt ?? computeMiniappArtifactReceipt,
|
package/dist/cli-chunks/{runtime-permission-env-B-GwDDT7.cjs → runtime-permission-env-DdWYFrFT.cjs}
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('node:fs');
|
|
4
4
|
var path = require('node:path');
|
|
5
|
-
var version = require('./version-
|
|
5
|
+
var version = require('./version-4zRtvcVD.cjs');
|
|
6
6
|
require('node:crypto');
|
|
7
7
|
var node_async_hooks = require('node:async_hooks');
|
|
8
8
|
|
|
@@ -3608,6 +3608,7 @@ function validateGeneratedCompanions(value) {
|
|
|
3608
3608
|
return undefined;
|
|
3609
3609
|
if (!isRecord$2(value) || Object.keys(value).length === 0)
|
|
3610
3610
|
throw new Error('manifest.companions 必须是非空对象');
|
|
3611
|
+
let descriptorCount = 0;
|
|
3611
3612
|
for (const [alias, definition] of Object.entries(value)) {
|
|
3612
3613
|
if (!/^[a-z][a-z0-9-]{0,31}$/.test(alias) ||
|
|
3613
3614
|
!isRecord$2(definition) ||
|
|
@@ -3621,6 +3622,9 @@ function validateGeneratedCompanions(value) {
|
|
|
3621
3622
|
Object.keys(definition.targets).length === 0)
|
|
3622
3623
|
throw new Error(`manifest.companions.${alias} 不合法`);
|
|
3623
3624
|
for (const [target, artifact] of Object.entries(definition.targets)) {
|
|
3625
|
+
descriptorCount += 1;
|
|
3626
|
+
if (descriptorCount > 64)
|
|
3627
|
+
throw new Error('manifest.companions 最多允许 64 个 target 描述符');
|
|
3624
3628
|
if (isRecord$2(artifact) && artifact.elevation === 'required') {
|
|
3625
3629
|
throw new Error(`manifest.companions.${alias}.targets.${target}.elevation V1 仅支持 none,暂不支持管理员权限启动`);
|
|
3626
3630
|
}
|
|
@@ -12469,8 +12473,9 @@ function createMiniappArtifactFileHeader(file) {
|
|
|
12469
12473
|
* 校验服务端 session 文件映射,并计算仍需上传的文件。
|
|
12470
12474
|
*
|
|
12471
12475
|
* @param localFiles - 本地构建产物 receipt;除 `relativePath` 和 `size` 外,每项必须包含 64 位小写十六进制 `sha256`。
|
|
12472
|
-
* @param serverFiles -
|
|
12476
|
+
* @param serverFiles - 服务端签发的会话文件映射;与复用的 Companion 合起来必须覆盖本地产物。
|
|
12473
12477
|
* @param uploadedKeys - 服务端已确认上传成功的 key;每个值都必须属于当前会话,重复值会被去重。
|
|
12478
|
+
* @param reusedCompanionFiles - 已验证 Blob 引用;仅允许当前产物中的 Companion 文件。
|
|
12474
12479
|
* @returns
|
|
12475
12480
|
* 包含三个字段的对象:`files` 是按路径 UTF-8 字节序排列的全部 `{ file, key }` 映射,
|
|
12476
12481
|
* `missingFiles` 是其中尚未确认上传的映射,`uploadedKeys` 是去重后的已上传 key。
|
|
@@ -12486,15 +12491,38 @@ function createMiniappArtifactFileHeader(file) {
|
|
|
12486
12491
|
* sha256: 'a'.repeat(64),
|
|
12487
12492
|
* }],
|
|
12488
12493
|
* [],
|
|
12494
|
+
* [],
|
|
12489
12495
|
* );
|
|
12490
12496
|
*
|
|
12491
12497
|
* console.log(resolved.missingFiles.length); // 1
|
|
12492
12498
|
* ```
|
|
12493
12499
|
*/
|
|
12494
|
-
function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys) {
|
|
12500
|
+
function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys, reusedCompanionFiles) {
|
|
12495
12501
|
const preparedFiles = prepareMiniappArtifactFiles(localFiles);
|
|
12496
|
-
if (serverFiles.length !== preparedFiles.length) {
|
|
12497
|
-
throw new Error(`上传会话文件数量异常:期望 ${preparedFiles.length},实际 ${serverFiles.length}`);
|
|
12502
|
+
if (serverFiles.length + reusedCompanionFiles.length !== preparedFiles.length) {
|
|
12503
|
+
throw new Error(`上传会话文件数量异常:期望 ${preparedFiles.length},实际 ${serverFiles.length + reusedCompanionFiles.length}`);
|
|
12504
|
+
}
|
|
12505
|
+
const localByPath = new Map(preparedFiles.map((file) => [file.relativePath, file]));
|
|
12506
|
+
const reused = new Map();
|
|
12507
|
+
for (const reference of reusedCompanionFiles) {
|
|
12508
|
+
const relativePath = normalizeMiniappArtifactRelativePath(reference.relative_path);
|
|
12509
|
+
const local = localByPath.get(relativePath);
|
|
12510
|
+
if (!relativePath.startsWith('companions/') || !local) {
|
|
12511
|
+
throw new Error(`上传会话返回了不属于当前 Companion 产物的 Blob 引用:${relativePath}`);
|
|
12512
|
+
}
|
|
12513
|
+
if (reused.has(relativePath)) {
|
|
12514
|
+
throw new Error(`上传会话返回重复 Blob 引用:${relativePath}`);
|
|
12515
|
+
}
|
|
12516
|
+
if (!Number.isSafeInteger(reference.size) || reference.size < 0 || reference.size !== local.size) {
|
|
12517
|
+
throw new Error(`上传会话 Blob 文件大小与本地构建不一致:${relativePath}`);
|
|
12518
|
+
}
|
|
12519
|
+
if (!('sha256' in local) || !/^[a-f0-9]{64}$/.test(reference.sha256) || reference.sha256 !== local.sha256) {
|
|
12520
|
+
throw new Error(`上传会话 Blob 文件 SHA-256 与本地构建不一致:${relativePath}`);
|
|
12521
|
+
}
|
|
12522
|
+
if (typeof reference.blob_id !== 'string' || !reference.blob_id.trim()) {
|
|
12523
|
+
throw new Error(`上传会话 Blob 引用 ID 无效:${relativePath}`);
|
|
12524
|
+
}
|
|
12525
|
+
reused.set(relativePath, reference);
|
|
12498
12526
|
}
|
|
12499
12527
|
const mappings = new Map();
|
|
12500
12528
|
const serverSizes = new Map();
|
|
@@ -12505,6 +12533,9 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
12505
12533
|
if (mappings.has(relativePath)) {
|
|
12506
12534
|
throw new Error(`上传会话返回重复文件路径:${relativePath}`);
|
|
12507
12535
|
}
|
|
12536
|
+
if (reused.has(relativePath)) {
|
|
12537
|
+
throw new Error(`上传会话同时返回文件 key 和 Blob 引用:${relativePath}`);
|
|
12538
|
+
}
|
|
12508
12539
|
const key = String(serverFile.key || '');
|
|
12509
12540
|
if (!key) {
|
|
12510
12541
|
throw new Error(`上传会话未返回文件 key:${relativePath}`);
|
|
@@ -12525,7 +12556,8 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
12525
12556
|
serverHashes.set(relativePath, sha256);
|
|
12526
12557
|
knownKeys.add(key);
|
|
12527
12558
|
}
|
|
12528
|
-
const
|
|
12559
|
+
const sessionFiles = preparedFiles.filter((file) => !reused.has(file.relativePath));
|
|
12560
|
+
const files = sessionFiles.map((file) => {
|
|
12529
12561
|
const key = mappings.get(file.relativePath);
|
|
12530
12562
|
if (!key) {
|
|
12531
12563
|
throw new Error(`上传会话缺少文件映射:${file.relativePath}`);
|
|
@@ -12550,6 +12582,7 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
|
|
|
12550
12582
|
files,
|
|
12551
12583
|
missingFiles: files.filter((file) => !completed.has(file.key)),
|
|
12552
12584
|
uploadedKeys: [...completed],
|
|
12585
|
+
reusedCompanionFiles: [...reused.values()],
|
|
12553
12586
|
};
|
|
12554
12587
|
}
|
|
12555
12588
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var version = require('./version-
|
|
3
|
+
var version = require('./version-4zRtvcVD.cjs');
|
|
4
4
|
var fs = require('node:fs/promises');
|
|
5
5
|
var path = require('node:path');
|
|
6
6
|
var childProcess = require('node:child_process');
|
|
7
|
-
var index = require('./index-
|
|
7
|
+
var index = require('./index-BtqxUixL.cjs');
|
|
8
8
|
require('node:module');
|
|
9
9
|
require('node:fs');
|
|
10
10
|
require('path');
|