openyida 2026.9.2-beta.1 → 2026.9.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/README.md +7 -6
- package/lib/app/display-page-readback.js +5 -63
- package/lib/app/get-schema.js +5 -158
- package/lib/app/nav-group.js +221 -53
- package/lib/app/page-template-guard.js +64 -0
- package/lib/app/publish.js +21 -139
- package/lib/app/services/canvas-page-schema-builder.js +1 -1
- package/lib/asset/ai-image.js +8 -9
- package/lib/asset/asset-cmd.js +3 -49
- package/lib/asset/asset-resolve.js +8 -10
- package/lib/asset/asset-status.js +7 -7
- package/lib/core/agent-capabilities.js +38 -1
- package/lib/core/cli-error.js +6 -1
- package/lib/core/command-manifest.js +36 -9
- package/lib/core/locales/en.js +4 -10
- package/lib/core/locales/zh.js +6 -12
- package/lib/core/query-data.js +126 -8
- package/lib/core/sample.js +51 -10
- package/lib/core/utils.js +0 -409
- package/lib/samples/openyida-scaffold/canvas-form-drawer.canvas.jsx +7 -7
- package/package.json +1 -1
- package/scripts/postinstall.js +5 -5
- package/yida-skills/SKILL.md +13 -13
- package/yida-skills/references/task-retrospective.md +4 -4
- package/yida-skills/skills/yida-app/SKILL.md +9 -8
- package/yida-skills/skills/yida-app/references/common-issues.md +1 -1
- package/yida-skills/skills/yida-app/workflow/step-2-design.md +42 -15
- package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +8 -1
- package/yida-skills/skills/yida-app/workflow/step-4-forms-processes.md +13 -15
- package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +4 -2
- package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +26 -11
- package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +22 -11
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +8 -8
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +1 -1
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +16 -16
- package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +1 -1
- package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +1 -1
- package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +6 -7
- package/yida-skills/skills/yida-canvas-table-form/SKILL.md +2 -2
- package/yida-skills/skills/yida-create-app/SKILL.md +13 -7
- package/yida-skills/skills/yida-create-form-page/SKILL.md +10 -16
- package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +1 -4
- package/yida-skills/skills/yida-custom-page/SKILL.md +5 -5
- package/yida-skills/skills/yida-custom-page/references/coding-guide.md +2 -6
- package/yida-skills/skills/yida-custom-page/references/design-system.md +4 -4
- package/yida-skills/skills/yida-data-management/SKILL.md +6 -4
- package/yida-skills/skills/yida-data-management/references/data-format-guide.md +13 -5
- package/yida-skills/skills/yida-design/SKILL.md +36 -39
- package/yida-skills/skills/yida-design/references/asset-workflow.md +32 -85
- package/yida-skills/skills/yida-design/references/page-quality-gates.md +3 -3
- package/yida-skills/skills/yida-design/references/style-design-selection.md +4 -4
- package/yida-skills/skills/yida-design/references/theme/app-custom-theme-template.css +15 -24
- package/yida-skills/skills/yida-design/references/theme/theme-token-presets.md +8 -8
- package/yida-skills/skills/yida-design/references/visual-decision-engine.md +1 -1
- package/yida-skills/skills/yida-design/references/visual-scaffold-recipes.md +2 -2
- package/yida-skills/skills/yida-design/sub_skill/page-design/SKILL.md +12 -13
- package/yida-skills/skills/yida-design/workflow/output-design.md +40 -26
- package/yida-skills/skills/yida-design/workflow/output-prd.md +8 -8
- package/yida-skills/skills/yida-design/workflow/step-1-read-brief.md +14 -0
- package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +23 -17
- package/yida-skills/skills/yida-design/workflow/step-4-wireframe-interaction.md +3 -3
- package/yida-skills/skills/yida-design/workflow/step-5-visual-states.md +5 -5
- package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +22 -55
- package/yida-skills/skills/yida-nav-group/SKILL.md +3 -1
- package/yida-skills/skills/yida-page-config/SKILL.md +3 -1
- package/yida-skills/skills/yida-prd/SKILL.md +48 -0
- package/yida-skills/skills/yida-prd/references/app/blueprint.md +73 -0
- package/yida-skills/skills/yida-prd/references/app/navigation-patterns.md +43 -0
- package/yida-skills/skills/yida-prd/references/app/role-journey.md +30 -0
- package/yida-skills/skills/yida-prd/workflow/output-prd.md +188 -0
- package/yida-skills/skills/yida-prd/workflow/step-1-read-brief.md +15 -0
- package/yida-skills/skills/{yida-design/workflow/step-3-information-architecture.md → yida-prd/workflow/step-2-information-architecture.md} +2 -2
- package/yida-skills/skills/yida-publish-page/SKILL.md +1 -1
- package/yida-skills/skills/yida-requirement-analysis/SKILL.md +49 -0
- package/yida-skills/skills-index.json +36 -35
- package/yida-skills/skills/yida-design/workflow/step-1-positioning.md +0 -58
- package/yida-skills/skills/yida-form-detail/SKILL.md +0 -68
package/README.md
CHANGED
|
@@ -153,7 +153,7 @@ openyida/
|
|
|
153
153
|
│ ├── core/ # Environment detection, i18n, diagnostics, data commands
|
|
154
154
|
│ ├── process/ # Process form creation, configuration, preview
|
|
155
155
|
│ ├── report/ # Yida report and chart generation
|
|
156
|
-
│ └── samples/ #
|
|
156
|
+
│ └── samples/ # Reusable code templates emitted by openyida sample
|
|
157
157
|
├── project/ # Default workspace template for generated Yida projects
|
|
158
158
|
├── yida-skills/ # Source skill docs and Yida API references
|
|
159
159
|
└── scripts/ # CI, packaging, and installation helpers
|
|
@@ -167,13 +167,14 @@ For a user-facing list of supported features and matching CLI commands, see [Ope
|
|
|
167
167
|
|
|
168
168
|
```bash
|
|
169
169
|
openyida create-app "CRM"
|
|
170
|
-
openyida
|
|
170
|
+
openyida sample yida-design app-theme --output .cache/openyida/crm/app-theme.css
|
|
171
|
+
openyida create-app --name "CRM" --desc "Customer management" --theme-file .cache/openyida/crm/app-theme.css --nav-theme light --logo-source appIcon --layout l_shape
|
|
171
172
|
openyida app-list --size 20
|
|
172
173
|
openyida corp-efficiency
|
|
173
174
|
openyida create-form create APP_XXX "Customer" .cache/openyida/forms/customer-fields.json
|
|
174
175
|
openyida create-form update APP_XXX FORM_XXX .cache/openyida/forms/customer-changes.json
|
|
175
|
-
openyida sample openyida-
|
|
176
|
-
openyida sample openyida-
|
|
176
|
+
openyida sample openyida-page-template form-fields --output .cache/openyida/forms/customer-fields.json
|
|
177
|
+
openyida sample openyida-page-template canvas-form-drawer --output project/pages/src/customer-entry.canvas.jsx --var APP_TYPE=APP_XXX --var FORM_UUID=FORM_XXX
|
|
177
178
|
openyida get-schema APP_XXX FORM_XXX
|
|
178
179
|
openyida get-schema APP_XXX FORM_XXX --compact --resolve-fields "Customer Name,Status"
|
|
179
180
|
openyida get-schema APP_XXX --all --output-dir .cache/schemas
|
|
@@ -519,7 +520,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
519
520
|
| `openyida batch <file>\|--commands "cmd1 ; cmd2" [--stop-on-error] [--json]` | Run OpenYida commands in batch |
|
|
520
521
|
| `openyida flash-to-prd --file <path> --name "<project>"` | Convert flash notes or meeting notes to a PRD prompt |
|
|
521
522
|
| `openyida ai <text\|image> [options]` | Call Yida AI text and image recognition APIs |
|
|
522
|
-
| `openyida asset <status\|
|
|
523
|
+
| `openyida asset <status\|resolve\|generate> [options]` | Detect asset capability / resolve materials |
|
|
523
524
|
| `openyida cdn-config [options]` | Configure CDN / OSS upload |
|
|
524
525
|
| `openyida cdn-upload <image-path>` | Upload image to CDN |
|
|
525
526
|
| `openyida cdn-refresh [options]` | Refresh CDN cache |
|
|
@@ -550,7 +551,7 @@ The runner rejects public generic echo services such as httpbin and example.com.
|
|
|
550
551
|
|
|
551
552
|
The opt-in `node scripts/e2e-real/connector/action-update-runner.js` regression uses the owner-confirmed login-free `www.aliwork.com` fixture and a single owned NONE-auth connector containing a target action plus one preservation sentinel. Enable it with `OPENYIDA_E2E=1 OPENYIDA_E2E_CONNECTOR_ACTION_UPDATE=1`. It verifies isolated `currentPage`, `pageSize`, `userLanguage`, `searchFieldJson`, and dynamic `_stamp` edits, restores each field and the final baseline, and persists only response structure, data count, and SHA-256. It never stores response row values or auth/profile/corp identifiers, never retries unknown writes, and intentionally leaves the owned connector as a `cleanup_blocked` residual because no proven delete API exists.
|
|
552
553
|
|
|
553
|
-
`openyida asset resolve --hero <path-or-url> --product <path-or-url> --require-hero --upload-assets --json` is the preferred preflight for homepage visuals. It
|
|
554
|
+
`openyida asset resolve --hero <path-or-url> --product <path-or-url> --require-hero --upload-assets --json` is the preferred preflight for homepage visuals. It handles local files and external image references in one flow, uploads or mirrors them when CDN is configured, and returns `materialStatus: final|draft|none` so agents do not claim an unfinished visual page is final.
|
|
554
555
|
|
|
555
556
|
#### Environment and Localization
|
|
556
557
|
|
|
@@ -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
|
-
|
|
110
|
-
|
|
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
|
|
215
|
-
const
|
|
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,
|
package/lib/app/get-schema.js
CHANGED
|
@@ -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
|
-
httpGetRedirectText,
|
|
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) => httpGetRedirectText(
|
|
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
|
|
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(
|
|
741
|
-
schema:
|
|
597
|
+
fieldSummary: extractFieldSummary(result),
|
|
598
|
+
schema: result,
|
|
742
599
|
};
|
|
743
|
-
const displayPage = extractDisplayPageSummary(
|
|
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
|
};
|