@qmuse/qmuse-cli 1.0.3-dev.2 → 1.0.3-dev.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.
@@ -1,7 +1,9 @@
1
1
  import { openAsBlob } from 'node:fs';
2
2
  import { apiCall, authHeaders, buildUrl, requestSourceHeaders, } from '../client.js';
3
+ import { assertImportArchiveSize } from './limits.js';
3
4
  export async function uploadImportArchive(input, cfg) {
4
5
  const archive = await openAsBlob(input.filePath, { type: 'application/zip' });
6
+ assertImportArchiveSize(archive.size);
5
7
  const headers = authHeaders(cfg);
6
8
  headers['Content-Type'] = 'application/zip';
7
9
  headers['Content-Length'] = String(archive.size);
@@ -18,15 +20,37 @@ export async function uploadImportArchive(input, cfg) {
18
20
  catch (error) {
19
21
  throw new Error(`上传源码失败:${error instanceof Error ? error.message : String(error)}`);
20
22
  }
21
- let result;
23
+ const contentType = response.headers.get('content-type')?.split(';')[0].trim();
24
+ const traceId = response.headers.get('x-trace-id') ?? response.headers.get('trace-id');
25
+ const details = [
26
+ `HTTP ${response.status}`,
27
+ `源码包 ${(archive.size / 1024 / 1024).toFixed(2)} MiB(${archive.size} 字节)`,
28
+ contentType && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/iu.test(contentType)
29
+ ? `响应类型 ${contentType}` : undefined,
30
+ traceId && /^[a-z0-9_-]{1,128}$/iu.test(traceId) ? `traceId=${traceId}` : undefined,
31
+ ].filter(Boolean).join(',');
32
+ if (response.status === 413) {
33
+ await response.body?.cancel().catch(() => undefined);
34
+ throw new Error(`上传源码失败:源码包超过上传入口大小限制(${details})。请将不参与运行的生成产物加入 .gitignore 后重试;如需上传完整源码包,请联系平台核对上传限制。`);
35
+ }
36
+ let payload;
22
37
  try {
23
- result = await response.json();
38
+ payload = await response.json();
24
39
  }
25
40
  catch {
26
- throw new Error('上传源码失败:服务端响应格式错误');
41
+ throw new Error(`上传源码失败:无法读取有效的 JSON 响应(${details}),请检查服务或网关响应后重试`);
42
+ }
43
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
44
+ throw new Error(`上传源码失败:服务端响应结构错误(${details})`);
45
+ }
46
+ const result = payload;
47
+ if (!response.ok || result.success !== true) {
48
+ const reason = typeof result.errorMessage === 'string' ? result.errorMessage
49
+ : typeof result.errorCode === 'string' ? result.errorCode : '服务端拒绝上传';
50
+ throw new Error(`上传源码失败:${reason}(${details})`);
27
51
  }
28
- if (!response.ok || result.success !== true || !result.data?.sourceToken) {
29
- throw new Error(`上传源码失败:${result.errorMessage ?? result.errorCode ?? `HTTP ${response.status}`}`);
52
+ if (typeof result.data?.sourceToken !== 'string' || !result.data.sourceToken.trim()) {
53
+ throw new Error(`上传源码失败:服务端响应缺少有效上传凭证(${details})`);
30
54
  }
31
55
  return result.data.sourceToken;
32
56
  }
@@ -4,7 +4,7 @@ import { tmpdir } from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { ZipFile } from 'yazl';
6
6
  import { createSourceManifest, SOURCE_MANIFEST_PATH } from './source-manifest.js';
7
- const MAX_ARCHIVE_BYTES = 500 * 1024 * 1024;
7
+ import { assertImportArchiveSize } from './limits.js';
8
8
  const STABLE_ZIP_MTIME = new Date('1980-01-01T00:00:00.000Z');
9
9
  export async function createImportArchive(preflight) {
10
10
  const temporaryDirectory = await mkdtemp(path.join(tmpdir(), 'qmuse-import-'));
@@ -36,8 +36,7 @@ export async function createImportArchive(preflight) {
36
36
  const sizeBytes = (await stat(filePath)).size;
37
37
  if (sizeBytes <= 0)
38
38
  throw new Error('生成的源码压缩包为空');
39
- if (sizeBytes > MAX_ARCHIVE_BYTES)
40
- throw new Error('源码压缩包超过 500MB');
39
+ assertImportArchiveSize(sizeBytes);
41
40
  return {
42
41
  filePath,
43
42
  fileName,
@@ -0,0 +1,6 @@
1
+ export const MAX_IMPORT_ARCHIVE_BYTES = 10 * 1024 * 1024;
2
+ export function assertImportArchiveSize(sizeBytes) {
3
+ if (sizeBytes > MAX_IMPORT_ARCHIVE_BYTES) {
4
+ throw new Error(`源码压缩包超过 10 MiB 上传上限:当前 ${(sizeBytes / 1024 / 1024).toFixed(2)} MiB(${sizeBytes} 字节)。请将不参与运行的生成产物加入 .gitignore 后重试`);
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qmuse/qmuse-cli",
3
- "version": "1.0.3-dev.2",
3
+ "version": "1.0.3-dev.3",
4
4
  "description": "将本地 React 项目安全导入 QMuse 的命令行客户端",
5
5
  "type": "module",
6
6
  "bin": {