openyida 2026.9.7-beta.0 → 2026.9.7

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.
@@ -24,13 +24,12 @@
24
24
  * 3) 第三方依赖以 `window.<别名>` 形式引用(antd→window.antd、react→window.React …),
25
25
  * 这些 UMD 依赖由画布运行时依据 importedModules 白名单按需注入。
26
26
  *
27
- * 因此本地编译 = Babel 把 JSX/TS 转成 JS → 把 import 改写成 window 别名引用、
28
- * 把 export default 改写成画布入口 `YidaComp` → UglifyJS 压缩 → 正则抽出依赖包名。
27
+ * 因此本地编译 = Babel 把 JSX/TS 转成 ES5 → 把 import 改写成 window 别名引用、
28
+ * 把 export default 改写成画布入口 `YidaComp` → 正则抽出依赖包名。
29
29
  */
30
30
 
31
31
  const Babel = require('@babel/standalone');
32
32
  const globals = require('globals');
33
- const UglifyJS = require('uglify-js');
34
33
  const {
35
34
  assertNoEmojiInArtifactName,
36
35
  assertNoEmojiInText,
@@ -878,36 +877,6 @@ function assertCanvasRuntimeParseable(runtimeCode, options = {}) {
878
877
  }
879
878
  }
880
879
 
881
- /**
882
- * 压缩画布运行态代码,并显式保留装配器读取的 YidaComp 入口名。
883
- */
884
- function minifyCanvasRuntime(runtimeCode, options = {}) {
885
- let result;
886
- try {
887
- result = UglifyJS.minify(runtimeCode, {
888
- compress: true,
889
- mangle: {
890
- reserved: ['YidaComp'],
891
- },
892
- });
893
- } catch (error) {
894
- result = { error };
895
- }
896
- if (!result || result.error || typeof result.code !== 'string' || !result.code) {
897
- const detail = result && result.error && result.error.message
898
- ? result.error.message
899
- : '压缩结果为空';
900
- throw new CliError(`Code Canvas runtimeCode 压缩失败: ${detail}`, {
901
- code: 'OPENYIDA_CANVAS_MINIFY_FAILED',
902
- details: {
903
- stage: 'canvas_minify',
904
- sourcePath: options.sourcePath || '',
905
- },
906
- });
907
- }
908
- return result.code;
909
- }
910
-
911
880
  /**
912
881
  * 本地编译 Code Canvas 源码。
913
882
  * @param {string} source 原始 React/JSX/TSX 源码
@@ -1015,12 +984,11 @@ function compileCanvasLocal(source, options = {}) {
1015
984
  configFile: false,
1016
985
  });
1017
986
 
1018
- const unminifiedRuntimeCode = stage2.code || '';
1019
- assertNoEmojiInText(unminifiedRuntimeCode, {
987
+ const runtimeCode = stage2.code || '';
988
+ assertNoEmojiInText(runtimeCode, {
1020
989
  artifact: options.sourcePath ? options.sourcePath + ' runtime' : 'Code Canvas runtime',
1021
990
  code: 'OPENYIDA_CANVAS_SOURCE_EMOJI_FORBIDDEN',
1022
991
  });
1023
- const runtimeCode = minifyCanvasRuntime(unminifiedRuntimeCode, options);
1024
992
  assertCanvasRuntimeParseable(runtimeCode, options);
1025
993
  assertDependencyManifestConsistent(runtimeCode, importedModules, options);
1026
994
  return {
@@ -1088,7 +1056,6 @@ module.exports = {
1088
1056
  resolveWindowAlias,
1089
1057
  shouldAllowUnsupportedBareImports,
1090
1058
  assertCanvasRuntimeParseable,
1091
- minifyCanvasRuntime,
1092
1059
  findBareDependencyGlobalIssues,
1093
1060
  findSelfReferentialDependencyBindingIssues,
1094
1061
  findDependencyManifestIssues,
@@ -23,30 +23,10 @@ function fingerprint(value) {
23
23
  return crypto.createHash('sha256').update(normalized).digest('hex');
24
24
  }
25
25
 
26
- function rawFingerprint(value) {
27
- if (typeof value !== 'string' || !value) {
28
- return '';
29
- }
30
- return crypto.createHash('sha256').update(value, 'utf8').digest('hex');
31
- }
32
-
33
- function positiveSize(value) {
34
- const size = Number(value);
35
- return Number.isFinite(size) && size > 0 ? size : 0;
36
- }
37
-
38
- function sha256(value) {
39
- const digest = String(value || '').toLowerCase();
40
- return /^[a-f0-9]{64}$/.test(digest) ? digest : '';
41
- }
42
-
43
26
  function createEmptyDisplayInfo() {
44
27
  return {
45
28
  hasYidaCodeCanvas: false,
46
- hasCodeBundle: false,
47
29
  hasNativeJsx: false,
48
- codeBundleCount: 0,
49
- bundleIds: [],
50
30
  runtimeCodeBytes: 0,
51
31
  sourceCodeBytes: 0,
52
32
  compiledCodeBytes: 0,
@@ -54,8 +34,6 @@ function createEmptyDisplayInfo() {
54
34
  componentCount: 0,
55
35
  canvasRuntimeCode: '',
56
36
  canvasSourceCode: '',
57
- canvasRuntimeSha256: '',
58
- canvasSourceSha256: '',
59
37
  nativeCompiledCode: '',
60
38
  nativeSourceCode: '',
61
39
  };
@@ -101,37 +79,12 @@ function traverseDisplayNodes(node, info) {
101
79
 
102
80
  if (node.componentName === 'YidaCodeCanvas') {
103
81
  const props = node.props || {};
104
- const codeBundle = props.codeBundle && typeof props.codeBundle === 'object'
105
- ? props.codeBundle
106
- : null;
107
82
  info.hasYidaCodeCanvas = true;
108
83
  info.componentCount++;
109
- if (typeof props.runtimeCode === 'string' && props.runtimeCode) {
110
- info.canvasRuntimeCode = props.runtimeCode;
111
- }
112
- if (typeof props.code === 'string' && props.code) {
113
- info.canvasSourceCode = props.code;
114
- }
84
+ info.canvasRuntimeCode = props.runtimeCode || '';
85
+ info.canvasSourceCode = props.code || '';
115
86
  info.runtimeCodeBytes += codeBytes(props.runtimeCode);
116
87
  info.sourceCodeBytes += codeBytes(props.code);
117
- if (codeBundle) {
118
- const bundleId = String(codeBundle.bundleId || '');
119
- const runtime = codeBundle.runtime && typeof codeBundle.runtime === 'object'
120
- ? codeBundle.runtime
121
- : {};
122
- const source = codeBundle.source && typeof codeBundle.source === 'object'
123
- ? codeBundle.source
124
- : {};
125
- info.hasCodeBundle = true;
126
- info.codeBundleCount++;
127
- if (bundleId && !info.bundleIds.includes(bundleId)) {
128
- info.bundleIds.push(bundleId);
129
- }
130
- info.runtimeCodeBytes += positiveSize(runtime.size);
131
- info.sourceCodeBytes += positiveSize(source.size);
132
- info.canvasRuntimeSha256 = sha256(runtime.sha256) || info.canvasRuntimeSha256;
133
- info.canvasSourceSha256 = sha256(source.sha256) || info.canvasSourceSha256;
134
- }
135
88
  addImportedModules(info.importedModules, props.importedModules);
136
89
  } else if (node.componentName === 'Jsx') {
137
90
  info.hasNativeJsx = true;
@@ -180,9 +133,7 @@ function hasExpectedDisplayComponent(info, publishMode) {
180
133
  return false;
181
134
  }
182
135
  if (publishMode === 'canvas') {
183
- return info.hasYidaCodeCanvas && (
184
- info.runtimeCodeBytes > 0 || !!info.canvasRuntimeSha256
185
- );
136
+ return info.hasYidaCodeCanvas && info.runtimeCodeBytes > 0;
186
137
  }
187
138
  return info.hasNativeJsx && info.compiledCodeBytes > 0;
188
139
  }
@@ -193,10 +144,7 @@ function summarizeDisplayPublishInfo(info) {
193
144
  }
194
145
  return {
195
146
  hasYidaCodeCanvas: info.hasYidaCodeCanvas,
196
- hasCodeBundle: info.hasCodeBundle,
197
147
  hasNativeJsx: info.hasNativeJsx,
198
- codeBundleCount: info.codeBundleCount,
199
- bundleIds: info.bundleIds.slice(),
200
148
  runtimeCodeBytes: info.runtimeCodeBytes,
201
149
  sourceCodeBytes: info.sourceCodeBytes,
202
150
  compiledCodeBytes: info.compiledCodeBytes,
@@ -211,13 +159,8 @@ function verifyPublishedContentMatch(readbackSchema, expectedSchemaContent, publ
211
159
  const displayComponentPresent = hasExpectedDisplayComponent(readbackInfo, publishMode);
212
160
  const readbackArtifact = getPublishArtifact(readbackInfo, publishMode);
213
161
  const expectedArtifact = getPublishArtifact(expectedInfo, publishMode);
214
- const codeBundleReadback = publishMode === 'canvas' && readbackInfo && readbackInfo.hasCodeBundle;
215
- const readbackFingerprint = codeBundleReadback
216
- ? readbackInfo.canvasRuntimeSha256
217
- : fingerprint(readbackArtifact);
218
- const expectedFingerprint = codeBundleReadback
219
- ? rawFingerprint(expectedArtifact)
220
- : fingerprint(expectedArtifact);
162
+ const readbackFingerprint = fingerprint(readbackArtifact);
163
+ const expectedFingerprint = fingerprint(expectedArtifact);
221
164
 
222
165
  return {
223
166
  readbackInfo,
@@ -237,7 +180,6 @@ function verifyPublishedContentMatch(readbackSchema, expectedSchemaContent, publ
237
180
  module.exports = {
238
181
  extractDisplayPublishInfo,
239
182
  fingerprint,
240
- rawFingerprint,
241
183
  hasExpectedDisplayComponent,
242
184
  parseSchemaContent,
243
185
  summarizeDisplayPublishInfo,
@@ -9,7 +9,6 @@
9
9
 
10
10
  'use strict';
11
11
 
12
- const crypto = require('crypto');
13
12
  const fs = require('fs');
14
13
  const path = require('path');
15
14
  const {
@@ -17,7 +16,6 @@ const {
17
16
  triggerLogin,
18
17
  resolveBaseUrl,
19
18
  httpGet,
20
- httpGetCodeBundleText,
21
19
  requestWithAutoLogin,
22
20
  } = require('../core/utils');
23
21
  const { t } = require('../core/i18n');
@@ -229,122 +227,6 @@ function resolveSchemaContent(schemaResult) {
229
227
  return parseJsonObject(content);
230
228
  }
231
229
 
232
- function validateCodeBundleDescriptor(codeBundle) {
233
- const bundleId = String(codeBundle && codeBundle.bundleId || '');
234
- const source = codeBundle && codeBundle.source;
235
- const runtime = codeBundle && codeBundle.runtime;
236
- const validSha256 = value => /^[a-f0-9]{64}$/.test(String(value || ''));
237
- const validSize = value => Number.isFinite(Number(value)) && Number(value) > 0
238
- && Number(value) <= 5 * 1024 * 1024;
239
- if (!validSha256(bundleId)
240
- || !source || !runtime
241
- || !validSha256(source.sha256) || !validSize(source.size)
242
- || !validSha256(runtime.sha256) || !validSize(runtime.size)
243
- || Number(source.size) + Number(runtime.size) > 5 * 1024 * 1024) {
244
- throw new Error('YidaCodeCanvas codeBundle 描述不合法');
245
- }
246
- return { bundleId, source, runtime };
247
- }
248
-
249
- function collectCodeBundleCanvases(content) {
250
- const canvases = [];
251
- function traverse(node) {
252
- if (Array.isArray(node)) {
253
- node.forEach(traverse);
254
- return;
255
- }
256
- if (!node || typeof node !== 'object') {
257
- return;
258
- }
259
- if (node.componentName === 'YidaCodeCanvas' && node.id && node.props
260
- && node.props.codeBundle && typeof node.props.codeBundle === 'object') {
261
- canvases.push({ props: node.props, descriptor: validateCodeBundleDescriptor(node.props.codeBundle) });
262
- }
263
- Object.values(node).forEach(traverse);
264
- }
265
- traverse(content);
266
- return canvases;
267
- }
268
-
269
- async function downloadCodeBundleArtifact(appType, formUuid, bundleId, artifact, descriptor, authRef) {
270
- let responseMetadata = null;
271
- const expectedContentTypes = artifact === 'source'
272
- ? ['text/plain']
273
- : ['application/javascript', 'text/javascript', 'application/x-javascript'];
274
- const value = await requestWithAutoLogin((auth) => httpGetCodeBundleText(
275
- auth.baseUrl,
276
- `/alibaba/web/${appType}/query/codeBundle/download.json`,
277
- { formUuid, bundleId, artifact },
278
- {
279
- silentStatus: true,
280
- maxBytes: 5 * 1024 * 1024,
281
- expectedContentTypes,
282
- onResponseMetadata: metadata => {
283
- responseMetadata = metadata;
284
- },
285
- }
286
- ), authRef);
287
- if (typeof value !== 'string') {
288
- const message = value && (value.errorMsg || value.message);
289
- throw new Error(message || `下载 CodeBundle ${artifact} 失败`);
290
- }
291
- const size = Buffer.byteLength(value, 'utf8');
292
- const digest = crypto.createHash('sha256').update(value, 'utf8').digest('hex');
293
- if (size !== Number(descriptor.size) || digest !== descriptor.sha256) {
294
- const context = responseMetadata && responseMetadata.context
295
- ? responseMetadata.context
296
- : `baseUrl=${authRef && authRef.baseUrl || 'unknown'}`;
297
- const error = new Error(t('common.code_bundle_integrity_failed', artifact, context));
298
- error.code = 'CODE_BUNDLE_INTEGRITY_MISMATCH';
299
- error.details = {
300
- artifact,
301
- expectedSize: Number(descriptor.size),
302
- actualSize: size,
303
- expectedSha256: descriptor.sha256,
304
- actualSha256: digest,
305
- ...(responseMetadata || {}),
306
- };
307
- throw error;
308
- }
309
- return value;
310
- }
311
-
312
- async function resolveCodeBundleSchema(schemaResult, appType, formUuid, authRef) {
313
- const content = resolveSchemaContent(schemaResult);
314
- if (!content) {
315
- return schemaResult;
316
- }
317
- const canvases = collectCodeBundleCanvases(content);
318
- if (canvases.length === 0) {
319
- return schemaResult;
320
- }
321
-
322
- const downloaded = new Map();
323
- for (const canvas of canvases) {
324
- const { bundleId, source, runtime } = canvas.descriptor;
325
- let code = downloaded.get(bundleId);
326
- if (!code) {
327
- const [sourceCode, runtimeCode] = await Promise.all([
328
- downloadCodeBundleArtifact(appType, formUuid, bundleId, 'source', source, authRef),
329
- downloadCodeBundleArtifact(appType, formUuid, bundleId, 'runtime', runtime, authRef),
330
- ]);
331
- code = { sourceCode, runtimeCode };
332
- downloaded.set(bundleId, code);
333
- }
334
- canvas.props.code = code.sourceCode;
335
- canvas.props.runtimeCode = code.runtimeCode;
336
- delete canvas.props.codeBundle;
337
- }
338
-
339
- if (schemaResult && Object.prototype.hasOwnProperty.call(schemaResult, 'content')) {
340
- schemaResult.content = typeof schemaResult.content === 'string'
341
- ? JSON.stringify(content)
342
- : content;
343
- return schemaResult;
344
- }
345
- return content;
346
- }
347
-
348
230
  function addImportedModules(target, value) {
349
231
  let modules = value;
350
232
  if (typeof modules === 'string') {
@@ -387,10 +269,7 @@ function extractDisplayPageSummary(schemaResult) {
387
269
 
388
270
  const displayPage = {
389
271
  hasYidaCodeCanvas: false,
390
- hasCodeBundle: false,
391
272
  hasNativeJsx: false,
392
- codeBundleCount: 0,
393
- bundleIds: [],
394
273
  runtimeCodeBytes: 0,
395
274
  sourceCodeBytes: 0,
396
275
  compiledCodeBytes: 0,
@@ -412,29 +291,10 @@ function extractDisplayPageSummary(schemaResult) {
412
291
 
413
292
  if (node.componentName === 'YidaCodeCanvas' && isComponentInstance(node)) {
414
293
  const props = node.props || {};
415
- const codeBundle = props.codeBundle && typeof props.codeBundle === 'object'
416
- ? props.codeBundle
417
- : null;
418
294
  displayPage.hasYidaCodeCanvas = true;
419
295
  displayPage.componentCount++;
420
296
  displayPage.runtimeCodeBytes += codeBytes(props.runtimeCode);
421
297
  displayPage.sourceCodeBytes += codeBytes(props.code);
422
- if (codeBundle) {
423
- const source = codeBundle.source && typeof codeBundle.source === 'object'
424
- ? codeBundle.source
425
- : {};
426
- const runtime = codeBundle.runtime && typeof codeBundle.runtime === 'object'
427
- ? codeBundle.runtime
428
- : {};
429
- const bundleId = String(codeBundle.bundleId || '');
430
- displayPage.hasCodeBundle = true;
431
- displayPage.codeBundleCount++;
432
- displayPage.sourceCodeBytes += Number(source.size) || 0;
433
- displayPage.runtimeCodeBytes += Number(runtime.size) || 0;
434
- if (bundleId && !displayPage.bundleIds.includes(bundleId)) {
435
- displayPage.bundleIds.push(bundleId);
436
- }
437
- }
438
298
  addImportedModules(displayPage.importedModules, props.importedModules);
439
299
  } else if (node.componentName === 'Jsx' && isComponentInstance(node)) {
440
300
  displayPage.hasNativeJsx = true;
@@ -721,15 +581,12 @@ async function mapLimit(items, limit, iterator) {
721
581
  return results;
722
582
  }
723
583
 
724
- async function fetchSchemaRecord(appType, form, authRef, retries, options = {}) {
584
+ async function fetchSchemaRecord(appType, form, authRef, retries) {
725
585
  let lastError = null;
726
586
  for (let attempt = 0; attempt <= retries; attempt++) {
727
587
  try {
728
588
  const result = await fetchSchema(appType, form.formUuid, authRef);
729
589
  if (isSuccessfulSchemaResult(result)) {
730
- const resolvedResult = options.resolveCodeBundles
731
- ? await resolveCodeBundleSchema(result, appType, form.formUuid, authRef)
732
- : result;
733
590
  const record = {
734
591
  formUuid: form.formUuid,
735
592
  formName: form.formName,
@@ -737,10 +594,10 @@ async function fetchSchemaRecord(appType, form, authRef, retries, options = {})
737
594
  pathName: form.pathName,
738
595
  success: true,
739
596
  attempts: attempt + 1,
740
- fieldSummary: extractFieldSummary(resolvedResult),
741
- schema: resolvedResult,
597
+ fieldSummary: extractFieldSummary(result),
598
+ schema: result,
742
599
  };
743
- const displayPage = extractDisplayPageSummary(resolvedResult);
600
+ const displayPage = extractDisplayPageSummary(result);
744
601
  if (displayPage) {
745
602
  record.displayPage = displayPage;
746
603
  }
@@ -837,10 +694,6 @@ async function runSingle(parsed, authRef) {
837
694
  throwCommandError(errorMsg);
838
695
  }
839
696
 
840
- if (!parsed.field && !parsed.compact && !parsed.summaryJson) {
841
- result = await resolveCodeBundleSchema(result, parsed.appType, parsed.formUuid, authRef);
842
- }
843
-
844
697
  // 保留既有 --field 返回结构;新 contract 仅由 --compact / --resolve-fields 触发。
845
698
  if (parsed.field) {
846
699
  const allFieldNodes = collectFieldNodes(result);
@@ -929,9 +782,7 @@ async function runBatch(parsed, authRef) {
929
782
  info(` 批量获取 ${forms.length} 个表单 Schema,并发 ${parsed.concurrency},重试 ${parsed.retries}`);
930
783
 
931
784
  const records = await mapLimit(forms, parsed.concurrency, async (form) => {
932
- const record = await fetchSchemaRecord(parsed.appType, form, authRef, parsed.retries, {
933
- resolveCodeBundles: !parsed.summaryJson,
934
- });
785
+ const record = await fetchSchemaRecord(parsed.appType, form, authRef, parsed.retries);
935
786
  if (record.success && parsed.analysisJson) {
936
787
  record.semanticAnalysis = buildSemanticAnalysis(
937
788
  parsed.appType,
@@ -997,9 +848,5 @@ module.exports = {
997
848
  fetchSchemaRecord,
998
849
  collectFieldNodes,
999
850
  findFieldNode,
1000
- validateCodeBundleDescriptor,
1001
- collectCodeBundleCanvases,
1002
- downloadCodeBundleArtifact,
1003
- resolveCodeBundleSchema,
1004
851
  run,
1005
852
  };
@@ -10,9 +10,9 @@
10
10
  *
11
11
  * 流程:
12
12
  * 1. 读取源文件,通过内置 babel-transform 编译 + UglifyJS 压缩
13
- * 2. 用代码动态构建 Schema;Canvas 页面拆出 source/runtime 后统一保存
13
+ * 2. 用代码动态构建 Schema,将 source/compiled 填入 actions.module
14
14
  * 3. 读取 token session,在写前确认登录态
15
- * 4. Canvas 调统一保存接口;普通 JSX 页面仍调用原 saveFormSchema
15
+ * 4. 通过 HTTP POST 调用 saveFormSchema,token 失效时尝试 token refresh
16
16
  */
17
17
 
18
18
  const fs = require('fs');
@@ -21,7 +21,6 @@ const querystring = require('querystring');
21
21
  const {
22
22
  findProjectRoot,
23
23
  httpPost,
24
- httpPostMultipart,
25
24
  httpGet,
26
25
  requestWithAutoLogin,
27
26
  } = require('../core/utils');
@@ -60,8 +59,6 @@ const {
60
59
  const SCHEMA_VERSION = 'V5';
61
60
  const DOMAIN_CODE = 'tEXDRG';
62
61
  const PREFIX = '_view';
63
- const MAX_CODE_BUNDLE_BYTES = 5 * 1024 * 1024;
64
- const MAX_CANVAS_SCHEMA_SKELETON_BYTES = 1024 * 1024;
65
62
 
66
63
  // ── 参数解析 ─────────────────────────────────────────
67
64
 
@@ -288,61 +285,6 @@ function buildCanvasSchemaContent(sourceCode, runtimeCode, importedModules, form
288
285
  return buildCanvasPageSchemaContent(sourceCode, runtimeCode, importedModules, formUuid);
289
286
  }
290
287
 
291
- function buildCanvasSavePayload(schemaContent, sourceCode, runtimeCode) {
292
- if (typeof sourceCode !== 'string' || sourceCode.length === 0
293
- || typeof runtimeCode !== 'string' || runtimeCode.length === 0) {
294
- throw new Error('Canvas source/runtime 不能为空');
295
- }
296
- const totalCodeBytes = Buffer.byteLength(sourceCode, 'utf8')
297
- + Buffer.byteLength(runtimeCode, 'utf8');
298
- if (totalCodeBytes > MAX_CODE_BUNDLE_BYTES) {
299
- throw new Error('Canvas source/runtime 总大小不能超过 5 MiB');
300
- }
301
-
302
- let schema;
303
- try {
304
- schema = JSON.parse(schemaContent);
305
- } catch {
306
- throw new Error('Canvas Schema 不是有效 JSON');
307
- }
308
-
309
- const canvases = [];
310
- function traverse(node) {
311
- if (Array.isArray(node)) {
312
- node.forEach(traverse);
313
- return;
314
- }
315
- if (!node || typeof node !== 'object') {
316
- return;
317
- }
318
- if (node.componentName === 'YidaCodeCanvas' && node.id) {
319
- canvases.push(node);
320
- }
321
- Object.values(node).forEach(traverse);
322
- }
323
- traverse(schema);
324
- if (canvases.length !== 1) {
325
- throw new Error('Canvas Schema 必须且只能包含一个 YidaCodeCanvas 节点');
326
- }
327
-
328
- const canvas = canvases[0];
329
- canvas.props = canvas.props && typeof canvas.props === 'object' ? canvas.props : {};
330
- delete canvas.props.code;
331
- delete canvas.props.runtimeCode;
332
- delete canvas.props.codeBundle;
333
-
334
- const skeletonContent = JSON.stringify(schema);
335
- if (Buffer.byteLength(skeletonContent, 'utf8') > MAX_CANVAS_SCHEMA_SKELETON_BYTES) {
336
- throw new Error('Canvas Schema 骨架不能超过 1 MiB');
337
- }
338
- return {
339
- canvasNodeId: canvas.id,
340
- content: skeletonContent,
341
- sourceCode,
342
- runtimeCode,
343
- };
344
- }
345
-
346
288
 
347
289
  // ── 4. 发送 saveFormSchema 请求 ──────────────────────
348
290
 
@@ -372,40 +314,6 @@ function sendSaveRequestWithAuth(authRef, schemaContent, appType, formUuid, serv
372
314
  return httpPost(authRef.baseUrl, saveSchemaPath, postData, { silentStatus: true });
373
315
  }
374
316
 
375
- function sendCanvasSaveRequestWithAuth(authRef, payload, appType, formUuid, serverRevision) {
376
- if (
377
- !authRef ||
378
- typeof authRef.baseUrl !== 'string' ||
379
- authRef.baseUrl.length === 0 ||
380
- !isTokenAuthRef(authRef)
381
- ) {
382
- const authError = new Error('Publish Canvas write authentication is not ready.');
383
- authError.code = 'PUBLISH_SCHEMA_WRITE_PRECHECK_FAILED';
384
- return Promise.reject(authError);
385
- }
386
- const gmtModified = requireSchemaServerRevision({ gmtModified: serverRevision });
387
- const savePath = `/alibaba/web/${appType}/query/codeBundle/save.json?_stamp=${Date.now()}`;
388
- return httpPostMultipart(authRef.baseUrl, savePath, {
389
- _csrf_token: authRef.csrfToken,
390
- formUuid,
391
- gmtModified,
392
- canvasNodeId: payload.canvasNodeId,
393
- content: payload.content,
394
- importSchema: true,
395
- }, {
396
- source: {
397
- content: payload.sourceCode,
398
- fileName: 'source.jsx',
399
- contentType: 'text/plain; charset=UTF-8',
400
- },
401
- runtime: {
402
- content: payload.runtimeCode,
403
- fileName: 'runtime.js',
404
- contentType: 'application/javascript; charset=UTF-8',
405
- },
406
- }, { silentStatus: true });
407
- }
408
-
409
317
  function walkFiles(dir, results, limit) {
410
318
  if (!fs.existsSync(dir) || results.length >= limit) {
411
319
  return;
@@ -716,8 +624,6 @@ async function runMain(argv) {
716
624
  baseUrl = authRef.baseUrl;
717
625
 
718
626
  let schemaContent;
719
- let expectedSchemaContent;
720
- let canvasSavePayload;
721
627
  let serverRevision;
722
628
  if (isCanvas) {
723
629
  try {
@@ -727,18 +633,7 @@ async function runMain(argv) {
727
633
  process.exit(1);
728
634
  }
729
635
  // canvasResult 已在登录前本地编译完成,这里只需据其装配 Schema content。
730
- expectedSchemaContent = buildCanvasSchemaContent(
731
- sourceCode,
732
- canvasResult.runtimeCode,
733
- canvasResult.importedModules,
734
- formUuid
735
- );
736
- canvasSavePayload = buildCanvasSavePayload(
737
- expectedSchemaContent,
738
- sourceCode,
739
- canvasResult.runtimeCode
740
- );
741
- schemaContent = canvasSavePayload.content;
636
+ schemaContent = buildCanvasSchemaContent(sourceCode, canvasResult.runtimeCode, canvasResult.importedModules, formUuid);
742
637
  } else {
743
638
  let existingDataSource = null;
744
639
  try {
@@ -751,7 +646,6 @@ async function runMain(argv) {
751
646
  }
752
647
  baseUrl = authRef.baseUrl;
753
648
  schemaContent = buildSchemaContent(sourceCode, compiledCode, formUuid, { existingDataSource });
754
- expectedSchemaContent = schemaContent;
755
649
  }
756
650
  success(t('publish.schema_built'));
757
651
 
@@ -762,15 +656,7 @@ async function runMain(argv) {
762
656
  label('Source:', sourcePath);
763
657
  label('Compiled:', compiledPath);
764
658
  step(3, t('publish.step_publish'));
765
- const response = isCanvas
766
- ? await sendCanvasSaveRequestWithAuth(
767
- authRef,
768
- canvasSavePayload,
769
- appType,
770
- formUuid,
771
- serverRevision
772
- )
773
- : await sendSaveRequestWithAuth(authRef, schemaContent, appType, formUuid, serverRevision);
659
+ const response = await sendSaveRequestWithAuth(authRef, schemaContent, appType, formUuid, serverRevision);
774
660
 
775
661
  if (!response || !response.success) {
776
662
  const errorMsg = response ? response.errorMsg || t('common.unknown_error') : t('common.request_failed');
@@ -784,9 +670,6 @@ async function runMain(argv) {
784
670
  const content = response.content || {};
785
671
  const savedFormUuid = content.formUuid || formUuid;
786
672
  const version = content.version || 0;
787
- const storageMode = isCanvas ? content.storageMode || null : undefined;
788
- const bundleId = isCanvas ? content.bundleId || null : undefined;
789
- const fallbackReason = isCanvas ? content.fallbackReason || null : undefined;
790
673
  success(t('publish.schema_published'));
791
674
  label('Form UUID:', savedFormUuid);
792
675
  label('Version:', String(version));
@@ -805,7 +688,7 @@ async function runMain(argv) {
805
688
  appType,
806
689
  savedFormUuid,
807
690
  authRef,
808
- expectedSchemaContent,
691
+ schemaContent,
809
692
  isCanvas ? 'canvas' : 'native'
810
693
  );
811
694
  } catch (healthCheckError) {
@@ -871,9 +754,6 @@ async function runMain(argv) {
871
754
  version,
872
755
  url: pageUrl,
873
756
  publishMode,
874
- storageMode,
875
- bundleId,
876
- fallbackReason,
877
757
  publishReadbackVerified: !!(healthCheckResult && healthCheckResult.ok === true),
878
758
  runtimeSmokeVerified: false,
879
759
  runtimeSmokeStatus: 'not_checked',
@@ -914,7 +794,5 @@ if (require.main === module) {
914
794
  module.exports.countCustomPageDataSources = countCustomPageDataSources;
915
795
  module.exports.buildSchemaContent = buildSchemaContent;
916
796
  module.exports.buildCanvasSchemaContent = buildCanvasSchemaContent;
917
- module.exports.buildCanvasSavePayload = buildCanvasSavePayload;
918
797
  module.exports.sendSaveRequestWithAuth = sendSaveRequestWithAuth;
919
- module.exports.sendCanvasSaveRequestWithAuth = sendCanvasSaveRequestWithAuth;
920
798
  }
@@ -294,6 +294,8 @@ function buildUpdateAppPostData(params, currentApp = {}, authRef) {
294
294
 
295
295
  const currentThemeColor = pickAppField(currentApp, 'themeColor', 'THEME_COLOR');
296
296
  const currentCustomThemeStyle = pickAppField(currentApp, 'customThemeStyle', 'CUSTOM_THEME_STYLE');
297
+ const addWaterMark = pickAppField(currentApp, 'addWaterMark', 'ADDWATERMARK');
298
+ const sentryMode = pickAppField(currentApp, 'sentryMode', 'SENTRY_MODE');
297
299
  if (params.colour === 'custom' && !params.themeColor && !currentThemeColor) {
298
300
  throw new Error(t('update_app.custom_theme_color_required'));
299
301
  }
@@ -342,10 +344,14 @@ function buildUpdateAppPostData(params, currentApp = {}, authRef) {
342
344
  navigation: currentApp.navigation || (currentApp.config && currentApp.config.NAVIGATION) || 'TODO,DONE,SUBMIT',
343
345
  pageHeader: currentApp.pageHeader || '',
344
346
  pageFooter: currentApp.pageFooter || '',
345
- addWaterMark: currentApp.addWaterMark || (currentApp.config && currentApp.config.ADDWATERMARK) || 'y',
346
- sentryMode: currentApp.sentryMode || (currentApp.config && currentApp.config.SENTRY_MODE) || 'y',
347
347
  };
348
348
 
349
+ if (addWaterMark !== undefined && addWaterMark !== null) {
350
+ postDataObj.addWaterMark = addWaterMark;
351
+ }
352
+ if (sentryMode !== undefined && sentryMode !== null) {
353
+ postDataObj.sentryMode = sentryMode;
354
+ }
349
355
  if (params.hideAppNav !== null && params.hideAppNav !== undefined) {
350
356
  postDataObj.hideAppNav = params.hideAppNav;
351
357
  } else {
@@ -902,15 +902,6 @@ Examples:
902
902
  response_body: ' Response body: {0}',
903
903
  response_detail: ' Response detail: {0}',
904
904
  response_not_json: 'response is not JSON',
905
- code_bundle_download_failed: 'CodeBundle download failed: {0} ({1})',
906
- code_bundle_forbidden: 'permission verification or OSS access was denied',
907
- code_bundle_not_found: 'the file does not exist or has been removed',
908
- code_bundle_http_error: 'HTTP {0}',
909
- code_bundle_html_response: 'received an HTML error page; the environment or route may be incorrect',
910
- code_bundle_json_response: 'the service returned a JSON error response: {0}',
911
- code_bundle_unexpected_content_type: 'unexpected response Content-Type: {0}',
912
- code_bundle_invalid_utf8: 'the response is not valid UTF-8 text',
913
- code_bundle_integrity_failed: 'CodeBundle {0} integrity verification failed ({1})',
914
905
  login_expired: ' Login session expired: {0}',
915
906
  csrf_expired: ' CSRF token expired: {0}',
916
907
  csrf_refreshed: ' csrf_token refreshed',
@@ -873,15 +873,6 @@ openyida - 宜搭命令行工具
873
873
  response_body: ' 响应内容: {0}',
874
874
  response_detail: ' 响应详情: {0}',
875
875
  response_not_json: '响应非 JSON',
876
- code_bundle_download_failed: 'CodeBundle 下载失败:{0}({1})',
877
- code_bundle_forbidden: '权限校验或 OSS 访问被拒绝',
878
- code_bundle_not_found: '文件不存在或已被清理',
879
- code_bundle_http_error: 'HTTP {0}',
880
- code_bundle_html_response: '返回了 HTML 错误页,可能是环境或路由错误',
881
- code_bundle_json_response: '服务端返回 JSON 错误响应:{0}',
882
- code_bundle_unexpected_content_type: '响应 Content-Type 不符合预期:{0}',
883
- code_bundle_invalid_utf8: '响应内容不是有效 UTF-8 文本',
884
- code_bundle_integrity_failed: 'CodeBundle {0} 完整性校验失败({1})',
885
876
  login_expired: ' 检测到登录过期: {0}',
886
877
  csrf_expired: ' 检测到 csrf_token 过期: {0}',
887
878
  csrf_refreshed: ' csrf_token 已刷新',
package/lib/core/utils.js CHANGED
@@ -1080,362 +1080,6 @@ function createNonJsonResponseResult(statusCode, data) {
1080
1080
  };
1081
1081
  }
1082
1082
 
1083
- function buildRequestUrl(baseUrl, requestPath, queryParams) {
1084
- const normalizedBaseUrl = String(baseUrl || '').replace(/\/+$/, '') + '/';
1085
- const requestUrl = new URL(requestPath, normalizedBaseUrl);
1086
- if (queryParams) {
1087
- Object.entries(queryParams).forEach(([key, value]) => {
1088
- if (value !== undefined && value !== null) {
1089
- requestUrl.searchParams.set(key, String(value));
1090
- }
1091
- });
1092
- }
1093
- return requestUrl;
1094
- }
1095
-
1096
- async function fetchWithTimeout(requestUrl, requestOptions, timeout) {
1097
- const controller = new AbortController();
1098
- const timer = setTimeout(() => controller.abort(), timeout || 30000);
1099
- try {
1100
- return await fetch(requestUrl, {
1101
- ...requestOptions,
1102
- signal: controller.signal,
1103
- });
1104
- } catch (error) {
1105
- if (error && error.name === 'AbortError') {
1106
- throw new Error(t('common.request_timeout'));
1107
- }
1108
- throw error;
1109
- } finally {
1110
- clearTimeout(timer);
1111
- }
1112
- }
1113
-
1114
- async function parseJsonFetchResponse(response, options = {}) {
1115
- const data = await response.text();
1116
- if (!options.silentStatus) {
1117
- warn(t('common.http_status', response.status));
1118
- }
1119
- if (isHttpRedirectStatus(response.status) || isHttpAuthStatus(response.status)) {
1120
- return {
1121
- __needLogin: true,
1122
- __httpStatus: response.status,
1123
- __location: response.headers.get('location') || '',
1124
- };
1125
- }
1126
- try {
1127
- const parsed = JSON.parse(data);
1128
- if (isLoginExpired(parsed)) {
1129
- return { __needLogin: true };
1130
- }
1131
- if (isCsrfTokenExpired(parsed)) {
1132
- return { __csrfExpired: true };
1133
- }
1134
- return parsed;
1135
- } catch {
1136
- if (!options.silentStatus) {
1137
- warn(t('common.http_response', data.substring(0, 500)));
1138
- }
1139
- return createNonJsonResponseResult(response.status, data);
1140
- }
1141
- }
1142
-
1143
- function appendMultipartFile(form, fieldName, file) {
1144
- if (!file || file.content === undefined || file.content === null) {
1145
- throw new TypeError(`multipart file ${fieldName} is required`);
1146
- }
1147
- const content = Buffer.isBuffer(file.content)
1148
- ? file.content
1149
- : Buffer.from(String(file.content), 'utf8');
1150
- form.append(
1151
- fieldName,
1152
- new Blob([content], { type: file.contentType || 'application/octet-stream' }),
1153
- file.fileName || fieldName
1154
- );
1155
- }
1156
-
1157
- /**
1158
- * 发送 multipart/form-data POST。Content-Type boundary 由 Node.js FormData 生成。
1159
- */
1160
- async function httpPostMultipart(baseUrl, requestPath, fields, files, optionsOrLegacyCookies, maybeOptions) {
1161
- if (typeof fetch !== 'function' || typeof FormData !== 'function' || typeof Blob !== 'function') {
1162
- throw new Error('当前 Node.js 环境缺少 fetch/FormData/Blob,请使用 Node.js 18+');
1163
- }
1164
- const optionsOverride = resolveRequestOptions(optionsOrLegacyCookies, maybeOptions);
1165
- const authHeaders = await resolveRequestAuthHeaders(optionsOverride);
1166
- const form = new FormData();
1167
- Object.entries(fields || {}).forEach(([key, value]) => {
1168
- if (value !== undefined && value !== null) {
1169
- form.append(key, String(value));
1170
- }
1171
- });
1172
- Object.entries(files || {}).forEach(([key, file]) => appendMultipartFile(form, key, file));
1173
-
1174
- const requestUrl = buildRequestUrl(baseUrl, requestPath);
1175
- const response = await fetchWithTimeout(requestUrl, {
1176
- method: 'POST',
1177
- redirect: 'manual',
1178
- headers: {
1179
- Accept: 'application/json, text/plain, */*',
1180
- Origin: requestUrl.origin,
1181
- Referer: optionsOverride.referer || requestUrl.origin + '/',
1182
- 'x-requested-with': 'XMLHttpRequest',
1183
- ...authHeaders,
1184
- },
1185
- body: form,
1186
- }, optionsOverride.timeout);
1187
- return parseJsonFetchResponse(response, optionsOverride);
1188
- }
1189
-
1190
- async function readFetchResponseBuffer(response, maxBytes, timeout) {
1191
- const limit = Number(maxBytes);
1192
- const timeoutMs = Number(timeout) || 30000;
1193
- const contentLength = Number(response.headers.get('content-length') || 0);
1194
- if (Number.isFinite(limit) && limit > 0 && contentLength > limit) {
1195
- const error = new Error(`响应内容超过允许大小 ${limit} bytes`);
1196
- error.code = 'HTTP_RESPONSE_TOO_LARGE';
1197
- throw error;
1198
- }
1199
-
1200
- if (!response.body || typeof response.body.getReader !== 'function') {
1201
- let timer;
1202
- const arrayBuffer = await Promise.race([
1203
- response.arrayBuffer(),
1204
- new Promise((resolve, reject) => {
1205
- void resolve;
1206
- timer = setTimeout(() => reject(new Error(t('common.request_timeout'))), timeoutMs);
1207
- }),
1208
- ]).finally(() => clearTimeout(timer));
1209
- const buffer = Buffer.from(arrayBuffer);
1210
- if (Number.isFinite(limit) && limit > 0 && buffer.length > limit) {
1211
- const error = new Error(`响应内容超过允许大小 ${limit} bytes`);
1212
- error.code = 'HTTP_RESPONSE_TOO_LARGE';
1213
- throw error;
1214
- }
1215
- return buffer;
1216
- }
1217
-
1218
- const chunks = [];
1219
- let size = 0;
1220
- const reader = response.body.getReader();
1221
- let timedOut = false;
1222
- const timer = setTimeout(() => {
1223
- timedOut = true;
1224
- void reader.cancel();
1225
- }, timeoutMs);
1226
- try {
1227
- for (;;) {
1228
- const { done, value } = await reader.read();
1229
- if (done) {
1230
- break;
1231
- }
1232
- const chunk = Buffer.from(value);
1233
- size += chunk.length;
1234
- if (Number.isFinite(limit) && limit > 0 && size > limit) {
1235
- await reader.cancel();
1236
- const error = new Error(`响应内容超过允许大小 ${limit} bytes`);
1237
- error.code = 'HTTP_RESPONSE_TOO_LARGE';
1238
- throw error;
1239
- }
1240
- chunks.push(chunk);
1241
- }
1242
- if (timedOut) {
1243
- throw new Error(t('common.request_timeout'));
1244
- }
1245
- } finally {
1246
- clearTimeout(timer);
1247
- reader.releaseLock();
1248
- }
1249
- return Buffer.concat(chunks, size);
1250
- }
1251
-
1252
- function normalizeResponseContentType(value) {
1253
- return String(value || '').split(';')[0].trim().toLowerCase();
1254
- }
1255
-
1256
- function responseRequestId(response) {
1257
- return response.headers.get('x-request-id') || '';
1258
- }
1259
-
1260
- function buildCodeBundleResponseMetadata(requestUrl, response) {
1261
- const metadata = {
1262
- baseUrl: requestUrl.origin,
1263
- finalHost: requestUrl.host,
1264
- status: response.status,
1265
- contentType: normalizeResponseContentType(response.headers.get('content-type')),
1266
- eagleeyeTraceId: response.headers.get('eagleeye-traceid') || '',
1267
- requestId: responseRequestId(response),
1268
- };
1269
- metadata.context = [
1270
- `baseUrl=${metadata.baseUrl}`,
1271
- `finalHost=${metadata.finalHost}`,
1272
- `status=${metadata.status}`,
1273
- `contentType=${metadata.contentType || 'missing'}`,
1274
- metadata.eagleeyeTraceId ? `eagleeyeTraceId=${metadata.eagleeyeTraceId}` : '',
1275
- metadata.requestId ? `requestId=${metadata.requestId}` : '',
1276
- ].filter(Boolean).join(', ');
1277
- return metadata;
1278
- }
1279
-
1280
- function createCodeBundleDownloadError(code, reason, metadata, responsePreview) {
1281
- const suffix = responsePreview ? `; response=${responsePreview}` : '';
1282
- const error = new Error(t('common.code_bundle_download_failed', reason, metadata.context) + suffix);
1283
- error.code = code;
1284
- error.details = {
1285
- ...metadata,
1286
- responsePreview: responsePreview || undefined,
1287
- };
1288
- return error;
1289
- }
1290
-
1291
- function compactResponsePreview(buffer) {
1292
- return buffer.toString('utf8').replace(/\s+/g, ' ').trim().substring(0, 500);
1293
- }
1294
-
1295
- async function readErrorResponsePreview(response, timeout) {
1296
- try {
1297
- return compactResponsePreview(await readFetchResponseBuffer(response, 4096, timeout));
1298
- } catch {
1299
- return '';
1300
- }
1301
- }
1302
-
1303
- function looksLikeHtml(buffer) {
1304
- const prefix = buffer.toString('utf8', 0, Math.min(buffer.length, 256)).trimStart().toLowerCase();
1305
- return prefix.startsWith('<!doctype html')
1306
- || prefix.startsWith('<html')
1307
- || prefix.startsWith('<head')
1308
- || prefix.startsWith('<body');
1309
- }
1310
-
1311
- function expectedContentTypeMatches(actualContentType, expectedContentTypes) {
1312
- if (!Array.isArray(expectedContentTypes) || expectedContentTypes.length === 0) {
1313
- return true;
1314
- }
1315
- return expectedContentTypes.some(value => normalizeResponseContentType(value) === actualContentType);
1316
- }
1317
-
1318
- function jsonResponseReason(preview) {
1319
- if (!preview) {
1320
- return t('common.code_bundle_json_response', t('common.unknown_error'));
1321
- }
1322
- try {
1323
- const payload = JSON.parse(preview);
1324
- const message = payload && (payload.errorMsg || payload.message || payload.throwable || payload.errorCode);
1325
- return t('common.code_bundle_json_response', message || t('common.unknown_error'));
1326
- } catch {
1327
- return t('common.code_bundle_json_response', t('common.unknown_error'));
1328
- }
1329
- }
1330
-
1331
- /**
1332
- * 从宜搭首方接口直接获取 CodeBundle 文本。
1333
- */
1334
- async function httpGetCodeBundleText(baseUrl, requestPath, queryParams, optionsOrLegacyCookies, maybeOptions) {
1335
- if (typeof fetch !== 'function') {
1336
- throw new Error('当前 Node.js 环境缺少 fetch,请使用 Node.js 18+');
1337
- }
1338
- const optionsOverride = resolveRequestOptions(optionsOrLegacyCookies, maybeOptions);
1339
- const authHeaders = await resolveRequestAuthHeaders(optionsOverride);
1340
- const requestUrl = buildRequestUrl(baseUrl, requestPath, queryParams);
1341
- const maxBytes = Number(optionsOverride.maxBytes) || 5 * 1024 * 1024;
1342
- const response = await fetchWithTimeout(requestUrl, {
1343
- method: 'GET',
1344
- redirect: 'manual',
1345
- headers: {
1346
- Accept: 'text/plain, application/javascript, */*',
1347
- Origin: requestUrl.origin,
1348
- Referer: requestUrl.origin + '/',
1349
- 'x-requested-with': 'XMLHttpRequest',
1350
- ...authHeaders,
1351
- },
1352
- }, optionsOverride.timeout);
1353
- const metadata = buildCodeBundleResponseMetadata(requestUrl, response);
1354
-
1355
- if (response.status === 401) {
1356
- return { __needLogin: true, __httpStatus: response.status };
1357
- }
1358
- if (response.status < 200 || response.status >= 300) {
1359
- const preview = await readErrorResponsePreview(response, optionsOverride.timeout);
1360
- if (response.status === 403) {
1361
- throw createCodeBundleDownloadError(
1362
- 'CODE_BUNDLE_DOWNLOAD_FORBIDDEN',
1363
- t('common.code_bundle_forbidden'),
1364
- metadata,
1365
- preview
1366
- );
1367
- }
1368
- if (response.status === 404) {
1369
- throw createCodeBundleDownloadError(
1370
- 'CODE_BUNDLE_DOWNLOAD_NOT_FOUND',
1371
- t('common.code_bundle_not_found'),
1372
- metadata,
1373
- preview
1374
- );
1375
- }
1376
- throw createCodeBundleDownloadError(
1377
- 'CODE_BUNDLE_DOWNLOAD_HTTP_ERROR',
1378
- t('common.code_bundle_http_error', response.status),
1379
- metadata,
1380
- preview
1381
- );
1382
- }
1383
-
1384
- const contentType = metadata.contentType;
1385
- const htmlResponse = contentType === 'text/html' || contentType === 'application/xhtml+xml';
1386
- const jsonResponse = contentType === 'application/json' || contentType.endsWith('+json');
1387
- if (htmlResponse || jsonResponse
1388
- || !expectedContentTypeMatches(contentType, optionsOverride.expectedContentTypes)) {
1389
- const preview = await readErrorResponsePreview(response, optionsOverride.timeout);
1390
- if (htmlResponse) {
1391
- throw createCodeBundleDownloadError(
1392
- 'CODE_BUNDLE_DOWNLOAD_HTML_RESPONSE',
1393
- t('common.code_bundle_html_response'),
1394
- metadata,
1395
- preview
1396
- );
1397
- }
1398
- if (jsonResponse) {
1399
- throw createCodeBundleDownloadError(
1400
- 'CODE_BUNDLE_DOWNLOAD_JSON_RESPONSE',
1401
- jsonResponseReason(preview),
1402
- metadata,
1403
- preview
1404
- );
1405
- }
1406
- throw createCodeBundleDownloadError(
1407
- 'CODE_BUNDLE_DOWNLOAD_UNEXPECTED_CONTENT_TYPE',
1408
- t('common.code_bundle_unexpected_content_type', contentType || 'missing'),
1409
- metadata,
1410
- preview
1411
- );
1412
- }
1413
-
1414
- const buffer = await readFetchResponseBuffer(response, maxBytes, optionsOverride.timeout);
1415
- if (looksLikeHtml(buffer)) {
1416
- throw createCodeBundleDownloadError(
1417
- 'CODE_BUNDLE_DOWNLOAD_HTML_RESPONSE',
1418
- t('common.code_bundle_html_response'),
1419
- metadata,
1420
- compactResponsePreview(buffer)
1421
- );
1422
- }
1423
- let value;
1424
- try {
1425
- value = new TextDecoder('utf-8', { fatal: true }).decode(buffer);
1426
- } catch {
1427
- throw createCodeBundleDownloadError(
1428
- 'CODE_BUNDLE_DOWNLOAD_INVALID_UTF8',
1429
- t('common.code_bundle_invalid_utf8'),
1430
- metadata
1431
- );
1432
- }
1433
- if (typeof optionsOverride.onResponseMetadata === 'function') {
1434
- optionsOverride.onResponseMetadata(metadata);
1435
- }
1436
- return value;
1437
- }
1438
-
1439
1083
  /**
1440
1084
  * 发送 HTTP POST 请求(application/x-www-form-urlencoded)
1441
1085
  * @param {string} baseUrl
@@ -1860,10 +1504,8 @@ module.exports = {
1860
1504
  isLoginExpired,
1861
1505
  isCsrfTokenExpired,
1862
1506
  httpPost,
1863
- httpPostMultipart,
1864
1507
  httpPostJson,
1865
1508
  httpGet,
1866
- httpGetCodeBundleText,
1867
1509
  requestWithAutoLogin,
1868
1510
  requestNonIdempotentWithAuthPreflight,
1869
1511
  getNpmExecutable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.9.7-beta.0",
3
+ "version": "2026.9.7",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",