openyida 2026.7.17 → 2026.7.18
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 +23 -8
- package/bin/yida.js +12 -0
- package/lib/app/canvas-compile.js +8 -1
- package/lib/app/create-app.js +94 -26
- package/lib/app/create-form/args.js +263 -0
- package/lib/app/create-form/commands.js +27 -0
- package/lib/app/create-form/definition-reader.js +230 -0
- package/lib/app/create-form/field-normalizers.js +429 -0
- package/lib/app/create-form/rule-builder.js +9 -0
- package/lib/app/create-form/schema-builder.js +12 -0
- package/lib/app/create-form/schema-patch.js +36 -0
- package/lib/app/create-form/validation-builder.js +9 -0
- package/lib/app/create-form.js +662 -997
- package/lib/app/form-navigation.js +2 -13
- package/lib/app/generate-page.js +463 -12
- package/lib/app/get-form-config.js +148 -0
- package/lib/app/nav-group.js +2 -13
- package/lib/app/page-ir.js +1097 -28
- package/lib/app/page-linter.js +57 -0
- package/lib/app/publish.js +3 -3
- package/lib/app/theme-presets.js +44 -0
- package/lib/app/update-app.js +126 -35
- package/lib/app/update-form-config.js +116 -29
- package/lib/asset/ai-image.js +126 -0
- package/lib/asset/asset-cmd.js +217 -0
- package/lib/asset/asset-resolve.js +307 -0
- package/lib/asset/asset-status.js +87 -0
- package/lib/asset/url-verify.js +217 -0
- package/lib/auth/token-auth.js +15 -5
- package/lib/basic-info/basic-info.js +8 -30
- package/lib/bridge/bridge.js +3 -3
- package/lib/core/agent-capabilities.js +2 -0
- package/lib/core/check-data.js +1 -1
- package/lib/core/command-manifest.js +23 -4
- package/lib/core/command-router.js +30 -0
- package/lib/core/copy.js +37 -8
- package/lib/core/env.js +0 -12
- package/lib/core/i18n.js +11 -7
- package/lib/core/locales/ar.js +24 -7
- package/lib/core/locales/de.js +24 -7
- package/lib/core/locales/en.js +46 -12
- package/lib/core/locales/es.js +24 -7
- package/lib/core/locales/fr.js +24 -7
- package/lib/core/locales/hi.js +24 -7
- package/lib/core/locales/ja.js +26 -9
- package/lib/core/locales/ko.js +24 -7
- package/lib/core/locales/pt.js +24 -7
- package/lib/core/locales/vi.js +24 -7
- package/lib/core/locales/zh-HK.js +26 -9
- package/lib/core/locales/zh.js +46 -12
- package/lib/core/safe-json.js +183 -0
- package/lib/core/sample.js +15 -0
- package/lib/core/task-center.js +1 -1
- package/lib/core/yida-client.js +41 -0
- package/lib/core/yida-i18n.js +46 -0
- package/lib/corp-efficiency/corp-efficiency.js +13 -25
- package/lib/mcp/server.js +1 -11
- package/lib/process/ai-form-setting.js +2 -14
- package/lib/samples/yida-canvas-custom-page/business-list.canvas.jsx +625 -0
- package/lib/samples/yida-canvas-custom-page/dashboard-overview.canvas.jsx +571 -0
- package/lib/samples/yida-canvas-custom-page/dashboard-starter.canvas.jsx +386 -0
- package/lib/samples/yida-canvas-custom-page/data-management.canvas.jsx +1116 -0
- package/lib/samples/yida-canvas-custom-page/data-screen.canvas.jsx +1034 -0
- package/lib/samples/yida-canvas-custom-page/detail-profile.canvas.jsx +421 -0
- package/lib/samples/yida-canvas-custom-page/native-components-smoke.canvas.jsx +773 -0
- package/lib/samples/yida-canvas-custom-page/official-homepage.canvas.jsx +936 -0
- package/lib/samples/yida-canvas-custom-page/portal-native-components.canvas.jsx +1259 -0
- package/lib/samples/yida-canvas-custom-page/portal-shell-home.canvas.jsx +471 -0
- package/lib/samples/yida-canvas-custom-page/product-homepage.canvas.jsx +777 -0
- package/lib/samples/yida-canvas-custom-page/split-pane-detail.canvas.jsx +353 -0
- package/lib/samples/yida-canvas-custom-page/todo-mvc.canvas.jsx +614 -0
- package/lib/samples/yida-canvas-custom-page/workbench-home.canvas.jsx +662 -0
- package/lib/samples/yida-chart/china-map.js +46 -18
- package/lib/samples/yida-chart/dashboard-bindform.js +54 -25
- package/lib/samples/yida-chart/line-trend.js +51 -22
- package/lib/samples/yida-chart/multi-bar-compare.js +114 -43
- package/lib/samples/yida-chart/radar-chart.js +45 -17
- package/lib/samples/yida-chart/scatter-bindform.js +35 -6
- package/lib/samples/yida-chart/stacked-area.js +34 -6
- package/lib/samples/yida-custom-page/business-list.oyd.jsx +443 -0
- package/lib/samples/yida-custom-page/custom-page-template.js +432 -109
- package/lib/samples/yida-custom-page/dashboard-overview.oyd.jsx +327 -0
- package/lib/samples/yida-custom-page/data-management.oyd.jsx +263 -0
- package/lib/samples/yida-custom-page/data-screen.oyd.jsx +348 -0
- package/lib/samples/yida-custom-page/design-tokens.js +53 -11
- package/lib/samples/yida-custom-page/detail-profile.oyd.jsx +241 -0
- package/lib/samples/yida-custom-page/official-homepage.oyd.jsx +218 -0
- package/lib/samples/yida-custom-page/portal-shell-home.oyd.jsx +263 -0
- package/lib/samples/yida-custom-page/product-homepage.jsx +361 -119
- package/lib/samples/yida-custom-page/split-pane-detail.oyd.jsx +244 -0
- package/lib/samples/yida-custom-page/todo-mvc.oyd.jsx +328 -52
- package/lib/samples/yida-custom-page/workbench-home.oyd.jsx +707 -0
- package/lib/samples/yida-density/density-switch-page.js +236 -77
- package/lib/samples/yida-table-form/table-form-batch-submit.js +395 -61
- package/package.json +8 -2
- package/project/prd/demo-birthday-game.md +9 -0
- package/scripts/check-syntax.js +48 -1
- package/scripts/generate-command-docs.js +70 -29
- package/scripts/i18n-baseline.json +50 -0
- package/scripts/postinstall.js +17 -29
- package/scripts/validate-ci.sh +10 -6
- package/scripts/validate-command-manifest.js +11 -6
- package/scripts/validate-i18n.js +176 -0
- package/scripts/validate-package-size.js +23 -6
- package/scripts/validate-skills.js +34 -0
- package/yida-skills/SKILL.md +62 -72
- package/yida-skills/references/development-rules.md +3 -3
- package/yida-skills/references/task-retrospective.md +134 -0
- package/yida-skills/skills/yida-app/SKILL.md +143 -7
- package/yida-skills/skills/yida-app-uiux/SKILL.md +95 -0
- package/yida-skills/skills/yida-business-rule/SKILL.md +1 -11
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +156 -72
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-authoring-examples.md +2 -2
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-design-system.md +137 -11
- package/yida-skills/skills/yida-canvas-custom-page/references/component-library-guide.md +70 -0
- package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +272 -25
- package/yida-skills/skills/yida-canvas-custom-page/references/employeefield-verification.md +1 -1
- package/yida-skills/skills/yida-canvas-custom-page/references/native-components-bridge.md +237 -0
- package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +136 -0
- package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +174 -0
- package/yida-skills/skills/yida-canvas-upgrade/SKILL.md +3 -5
- package/yida-skills/skills/yida-canvas-upgrade/references/migration-examples.md +1 -1
- package/yida-skills/skills/yida-chart/SKILL.md +16 -10
- package/yida-skills/skills/yida-create-app/SKILL.md +20 -4
- package/yida-skills/skills/yida-create-form-page/SKILL.md +119 -308
- package/yida-skills/skills/yida-create-form-page/references/advanced-form-modes.md +178 -0
- package/yida-skills/skills/yida-create-form-page/references/field-definition-guide.md +130 -0
- package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +100 -0
- package/yida-skills/skills/yida-create-page/SKILL.md +4 -2
- package/yida-skills/skills/yida-custom-page/SKILL.md +13 -11
- package/yida-skills/skills/yida-custom-page/references/coding-guide.md +36 -6
- package/yida-skills/skills/yida-custom-page/references/component-jsx-guide.md +93 -17
- package/yida-skills/skills/yida-custom-page/references/design-system.md +13 -2
- package/yida-skills/skills/yida-dashboard/SKILL.md +2 -17
- package/yida-skills/skills/yida-data-source-connectors/SKILL.md +4 -12
- package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +0 -26
- package/yida-skills/skills/yida-formula/SKILL.md +5 -26
- package/yida-skills/skills/yida-formula-evaluate/SKILL.md +0 -8
- package/yida-skills/skills/yida-get-schema/SKILL.md +0 -10
- package/yida-skills/skills/yida-integration/SKILL.md +0 -11
- package/yida-skills/skills/yida-nav-shell/SKILL.md +7 -18
- package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +4 -4
- package/yida-skills/skills/yida-page-uiux/SKILL.md +76 -15
- package/yida-skills/skills/yida-page-uiux/references/app/blueprint.md +21 -0
- package/yida-skills/skills/yida-page-uiux/references/app/navigation-patterns.md +32 -0
- package/yida-skills/skills/yida-page-uiux/references/app/role-journey.md +31 -0
- package/yida-skills/skills/yida-page-uiux/references/asset-workflow.md +112 -0
- package/yida-skills/skills/yida-page-uiux/references/dashboard/app-blueprint.md +19 -0
- package/yida-skills/skills/yida-page-uiux/references/dashboard/chart-contracts.md +17 -0
- package/yida-skills/skills/yida-page-uiux/references/dashboard/component-contracts.md +19 -0
- package/yida-skills/skills/yida-page-uiux/references/dashboard/layout-patterns.md +32 -0
- package/yida-skills/skills/yida-page-uiux/references/dashboard/theme-recipes.md +23 -0
- package/yida-skills/skills/yida-page-uiux/references/detail/object-narrative.md +19 -0
- package/yida-skills/skills/yida-page-uiux/references/detail/section-patterns.md +16 -0
- package/yida-skills/skills/yida-page-uiux/references/detail/timeline-and-related.md +18 -0
- package/yida-skills/skills/yida-page-uiux/references/landing/assets-workflow.md +26 -0
- package/yida-skills/skills/yida-page-uiux/references/landing/industry-playbooks.md +26 -0
- package/yida-skills/skills/yida-page-uiux/references/landing/realistic-brand-homepage.md +82 -0
- package/yida-skills/skills/yida-page-uiux/references/landing/research-levels.md +11 -0
- package/yida-skills/skills/yida-page-uiux/references/landing/section-patterns.md +17 -0
- package/yida-skills/skills/yida-page-uiux/references/list/drawer-detail.md +19 -0
- package/yida-skills/skills/yida-page-uiux/references/list/empty-loading-error.md +18 -0
- package/yida-skills/skills/yida-page-uiux/references/list/filter-patterns.md +16 -0
- package/yida-skills/skills/yida-page-uiux/references/list/table-patterns.md +14 -0
- package/yida-skills/skills/yida-page-uiux/references/scenes/landing.md +13 -2
- package/yida-skills/skills/yida-page-uiux/references/scenes/screen.md +36 -0
- package/yida-skills/skills/yida-page-uiux/references/visual-decision-engine.md +2 -2
- package/yida-skills/skills/yida-page-uiux/references/workbench/entry-patterns.md +19 -0
- package/yida-skills/skills/yida-page-uiux/references/workbench/portal-layouts.md +20 -0
- package/yida-skills/skills/yida-page-uiux/references/workbench/task-feed.md +21 -0
- package/yida-skills/skills/yida-page-uiux/workflow/output-decision-block.md +68 -4
- package/yida-skills/skills/yida-page-uiux/workflow/step-0-nav-shape.md +3 -3
- package/yida-skills/skills/yida-page-uiux/workflow/step-1-page-type.md +17 -0
- package/yida-skills/skills/yida-page-uiux/workflow/step-3-scene-routing.md +27 -7
- package/yida-skills/skills/yida-page-uiux/workflow/step-4-visual-decision.md +12 -0
- package/yida-skills/skills/yida-page-uiux/workflow/step-5-icon-and-assets.md +2 -2
- package/yida-skills/skills/yida-page-uiux/workflow/step-6-deai-selfcheck.md +4 -1
- package/yida-skills/skills/yida-process-rule/SKILL.md +4 -23
- package/yida-skills/skills/yida-publish-page/SKILL.md +13 -32
- package/yida-skills/skills/yida-report/SKILL.md +15 -2
- package/yida-skills/skills/yida-table-form/SKILL.md +0 -16
- package/yida-skills/skills/yida-theme/SKILL.md +238 -0
- package/yida-skills/skills-index.json +690 -145
- package/scripts/e2e-real/cleanup.js +0 -67
- package/scripts/e2e-real/fixtures/form-fields.json +0 -18
- package/scripts/e2e-real/full-runner.js +0 -1558
- package/scripts/e2e-real/runner.js +0 -262
- package/scripts/e2e-real/skill-coverage.js +0 -120
- package/scripts/eval/VERIFY.md +0 -169
- package/scripts/eval/agent.js +0 -148
- package/scripts/eval/config.js +0 -276
- package/scripts/eval/dashboard/index.html +0 -389
- package/scripts/eval/dashboard/server.js +0 -344
- package/scripts/eval/eval.config.json +0 -8
- package/scripts/eval/generate.js +0 -362
- package/scripts/eval/guardrail.js +0 -130
- package/scripts/eval/manifest.js +0 -117
- package/scripts/eval/report.js +0 -262
- package/scripts/eval/routing.js +0 -217
- package/scripts/eval/runner.js +0 -318
- package/scripts/eval/scenarios/generation/generation-core.json +0 -32
- package/scripts/eval/scenarios/routing-core.json +0 -101
- package/scripts/eval/score.js +0 -205
- package/scripts/eval/screenshot.js +0 -151
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ OpenYida connects AI coding agents with Yida's low-code platform, so developers
|
|
|
18
18
|
|
|
19
19
|
**Documentation:** [English](https://openyida.ai/docs/en) · [简体中文](https://openyida.ai/docs) · [繁體中文](https://openyida.ai/docs/zh-Hant/) · [日本語](https://openyida.ai/docs/ja/) · [한국어](https://openyida.ai/docs/ko/) · [Français](https://openyida.ai/docs/fr/) · [Deutsch](https://openyida.ai/docs/de/) · [Español](https://openyida.ai/docs/es/) · [Português](https://openyida.ai/docs/pt/) · [Tiếng Việt](https://openyida.ai/docs/vi/) · [हिन्दी](https://openyida.ai/docs/hi/) · [العربية](https://openyida.ai/docs/ar/)
|
|
20
20
|
|
|
21
|
+
[English README](./README.md) · [简体中文 README](./README_zhCN.md)
|
|
22
|
+
|
|
21
23
|
</div>
|
|
22
24
|
|
|
23
25
|
---
|
|
@@ -175,19 +177,28 @@ openyida get-schema APP_XXX FORM_XXX
|
|
|
175
177
|
openyida get-schema APP_XXX --all --output-dir .cache/schemas
|
|
176
178
|
```
|
|
177
179
|
|
|
180
|
+
Form definitions support 19 business field types plus verified `@ali/vc-deep-yida` presentation/layout components. Prefer `Divider` for section titles and `ColumnContainer` (mapped to `ColumnsLayout` + `Column`) for multi-column layout; use `GroupContainer` / `PageSection` only when an actual grouping container is needed.
|
|
181
|
+
|
|
178
182
|
### Custom Page Development
|
|
179
183
|
|
|
180
184
|
```bash
|
|
181
185
|
openyida create-page APP_XXX "Dashboard" --mode dashboard
|
|
182
|
-
openyida generate-page product-homepage --spec .cache/openyida/page-specs/home.json --output pages/src/home.
|
|
183
|
-
openyida generate-page
|
|
184
|
-
openyida
|
|
185
|
-
openyida
|
|
186
|
-
openyida
|
|
186
|
+
openyida generate-page product-homepage --scene workbench --theme-profile yida-app-theme --theme-scope page --spec .cache/openyida/page-specs/home.json --output pages/src/home.canvas.jsx --compile
|
|
187
|
+
openyida generate-page official-homepage --theme-profile yida-app-theme --spec .cache/openyida/page-specs/official-home.json --resolve-assets --upload-assets --output pages/src/official-home.canvas.jsx --compile
|
|
188
|
+
openyida generate-page data-screen --theme-profile yida-app-theme --output pages/src/data-screen.canvas.jsx --compile
|
|
189
|
+
openyida generate-page split-pane-detail --theme-profile yida-app-theme --output pages/src/split-pane-detail.canvas.jsx --compile
|
|
190
|
+
openyida generate-page portal-shell-home --theme-profile yida-app-theme --output pages/src/portal-shell-home.canvas.jsx --compile
|
|
191
|
+
openyida sample yida-canvas-custom-page dashboard-starter --output pages/src/dashboard-starter.canvas.jsx
|
|
192
|
+
openyida sample yida-canvas-custom-page native-components-smoke --output pages/src/native-components-smoke.canvas.jsx
|
|
193
|
+
openyida sample yida-canvas-custom-page portal-native-components --output pages/src/portal-native-components.canvas.jsx
|
|
194
|
+
openyida generate-page todo-mvc --output pages/src/todo-mvc.canvas.jsx --compile
|
|
195
|
+
openyida publish pages/src/home.canvas.jsx APP_XXX FORM_XXX
|
|
187
196
|
```
|
|
188
197
|
|
|
189
|
-
`generate-page` turns a structured spec into a Page IR, renders a curated
|
|
190
|
-
Built-in templates currently include `
|
|
198
|
+
`generate-page` turns a structured spec into a Page IR, renders a curated template, writes a `.openyida-page.json` manifest, and optionally compiles the result. Code Canvas is the default output (`.canvas.jsx`); pass `--native` or output `.oyd.jsx` only when the page must use the 普通自定义页面 JSX/Jsx 组件链路. Pass `--scene workbench|dashboard|list|detail|landing|screen` and `--theme-profile <name-or-json>` / `--visual-profile <name-or-json>` to preserve the visual direction decision in both source comments and the manifest. The user-facing default theme profile is `yida-app-theme`, which follows Yida application theme styling, compact business density, and layered 12/8/6/4 radii. `--theme-scope page` only injects theme variables into the generated page root; `--theme-scope app` additionally calls `window.__YIDA__.updateShellConfig({ themeConfig })` so the application shell can adopt the same theme. Landing pages should declare `spec.assets.heroImage` / `productImages`; use `--resolve-assets` to verify public image URLs and `--upload-assets` to mirror local or verified external images to CDN when CDN is configured. Use `--offline-assets` only for draft/offline gating. The manifest makes follow-up AI edits safer because agents can update known blocks and visual constraints instead of rewriting a large JSX file by hand.
|
|
199
|
+
Built-in templates currently include `official-homepage` for brand/law-firm/product official sites, `data-screen` for immersive monitoring screens, `dashboard-overview` for business dashboards, `workbench-home` for task/entry workbenches, `business-list` for list management pages, `detail-profile` for single-object detail pages, `split-pane-detail` for left-list/right-detail processing consoles, `portal-shell-home` for in-page portal shells, `native-components-smoke` for runtime probing existing Yida host components without changing `vc-deep-yida`, `portal-native-components` for runtime-bridged portal, member, department, and upload components, `product-homepage` for legacy workbench-style pages, and `todo-mvc` for a full interaction smoke page covering events, custom state, list rendering, editing, filtering, and localStorage persistence.
|
|
200
|
+
|
|
201
|
+
For member, department, attachment, and image upload components, choose the page chain first. Code Canvas pages should start with `native-components-smoke` or `portal-native-components` and follow `yida-canvas-custom-page/references/native-components-bridge.md` for feature detection, fallback, and value normalization. 普通自定义页面 JSX/Jsx pages should use `.oyd.jsx`, read `yida-custom-page/references/component-jsx-guide.md`, and read `attachment-upload-guide.md` when upload fields are involved.
|
|
191
202
|
|
|
192
203
|
### Workflow, Data, and Permissions
|
|
193
204
|
|
|
@@ -270,7 +281,7 @@ npm run eval:routing
|
|
|
270
281
|
# sub-skill, adds guardrail assertions, screenshots the published page, and writes a
|
|
271
282
|
# human scoring template. Runs deterministic CLI commands (no agent) so it serves as
|
|
272
283
|
# a control that proves the build→publish→screenshot→score plumbing itself works.
|
|
273
|
-
# Requires OPENYIDA_E2E=1 and a valid
|
|
284
|
+
# Requires OPENYIDA_E2E=1 and a valid token session.
|
|
274
285
|
OPENYIDA_E2E=1 npm run eval:e2e -- --skill yida-dashboard --screenshot
|
|
275
286
|
|
|
276
287
|
# Same, plus automatic screenshot scoring via the local multimodal `claude -p`.
|
|
@@ -375,6 +386,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
375
386
|
| `openyida compile <src>` | Compile custom page locally |
|
|
376
387
|
| `openyida publish <src> <appType> <formUuid> [--health-check] [--force] [--canvas] [--open\|--no-open]` | Compile and publish custom page |
|
|
377
388
|
| `openyida update-form-config <appType> ...` | Update form configuration |
|
|
389
|
+
| `openyida get-form-config <appType> <formUuid> [--json]` | Query form configuration |
|
|
378
390
|
|
|
379
391
|
### Data & Permissions
|
|
380
392
|
|
|
@@ -464,6 +476,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
464
476
|
| `openyida batch <file>\|--commands "cmd1 ; cmd2" [--stop-on-error] [--json]` | Run OpenYida commands in batch |
|
|
465
477
|
| `openyida flash-to-prd --file <path> --name "<project>"` | Convert flash notes or meeting notes to a PRD prompt |
|
|
466
478
|
| `openyida ai <text\|image> [options]` | Call Yida AI text and image recognition APIs |
|
|
479
|
+
| `openyida asset <status\|verify-url\|resolve\|generate> [options]` | Detect asset capability / verify image URLs / resolve materials |
|
|
467
480
|
| `openyida cdn-config [options]` | Configure CDN / OSS upload |
|
|
468
481
|
| `openyida cdn-upload <image-path>` | Upload image to CDN |
|
|
469
482
|
| `openyida cdn-refresh [options]` | Refresh CDN cache |
|
|
@@ -472,6 +485,8 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
|
|
|
472
485
|
|
|
473
486
|
### CLI Notes
|
|
474
487
|
|
|
488
|
+
`openyida asset resolve --hero <path-or-url> --product <path-or-url> --require-hero --upload-assets --json` is the preferred preflight for homepage visuals. It verifies public image URLs, uploads local images when CDN is configured, mirrors verified external images to CDN when `--upload-assets` is passed, and returns `materialStatus: final|draft|none` so agents do not claim an unfinished visual page is final.
|
|
489
|
+
|
|
475
490
|
#### Environment and Localization
|
|
476
491
|
|
|
477
492
|
Environment selectors such as `--env intl`, `--intl`, `--overseas`, `--global`, and `--yidaapps` can be used on login-required commands to choose the target Yida environment for that run. The `intl` preset uses `https://www.yidaapps.com` as the built-in Global YiDA entrypoint (not the bare `https://yidaapps.com` domain) and DingTalk International OAuth at `https://login.dingtalk.io`; business API requests still use the authenticated environment `baseUrl`, so customer custom subdomains are supported.
|
package/bin/yida.js
CHANGED
|
@@ -707,6 +707,12 @@ async function main() {
|
|
|
707
707
|
break;
|
|
708
708
|
}
|
|
709
709
|
|
|
710
|
+
case 'get-form-config': {
|
|
711
|
+
const { run: runGetFormConfig } = require('../lib/app/get-form-config');
|
|
712
|
+
await runGetFormConfig(args);
|
|
713
|
+
break;
|
|
714
|
+
}
|
|
715
|
+
|
|
710
716
|
case 'update-app': {
|
|
711
717
|
if (args.length < 2) {
|
|
712
718
|
throwCliUsage(t('cli.update_app_usage'), t('cli.update_app_example'));
|
|
@@ -867,6 +873,12 @@ async function main() {
|
|
|
867
873
|
break;
|
|
868
874
|
}
|
|
869
875
|
|
|
876
|
+
case 'asset': {
|
|
877
|
+
const { run: runAsset } = require('../lib/asset/asset-cmd');
|
|
878
|
+
await runAsset(args);
|
|
879
|
+
break;
|
|
880
|
+
}
|
|
881
|
+
|
|
870
882
|
case 'connector': {
|
|
871
883
|
const subCommand = args[0];
|
|
872
884
|
const subArgs = args.slice(1);
|
|
@@ -59,6 +59,12 @@ const IMPORT_SIDE_EFFECT_PATTERN = /import\s+['"]([^'"]+)['"]/g;
|
|
|
59
59
|
const REQUIRE_PATTERN = /require\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
60
60
|
const DYNAMIC_IMPORT_PATTERN = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
61
61
|
|
|
62
|
+
function stripJsComments(code) {
|
|
63
|
+
return String(code || '')
|
|
64
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
65
|
+
.replace(/(^|[^:])\/\/.*$/gm, '$1');
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
/**
|
|
63
69
|
* 从源码里正则抽取裸包名(过滤相对/绝对路径),去重排序。
|
|
64
70
|
* 对齐 dingtalk-ai-app 的 _extract_imported_modules 行为。
|
|
@@ -67,11 +73,12 @@ const DYNAMIC_IMPORT_PATTERN = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
|
67
73
|
*/
|
|
68
74
|
function extractImportedModules(code) {
|
|
69
75
|
const modules = new Set();
|
|
76
|
+
const source = stripJsComments(code);
|
|
70
77
|
const patterns = [IMPORT_PATTERN, IMPORT_SIDE_EFFECT_PATTERN, REQUIRE_PATTERN, DYNAMIC_IMPORT_PATTERN];
|
|
71
78
|
for (const pattern of patterns) {
|
|
72
79
|
pattern.lastIndex = 0;
|
|
73
80
|
let match;
|
|
74
|
-
while ((match = pattern.exec(
|
|
81
|
+
while ((match = pattern.exec(source)) !== null) {
|
|
75
82
|
const name = match[1];
|
|
76
83
|
if (name && !name.startsWith('.') && !name.startsWith('/')) {
|
|
77
84
|
modules.add(name);
|
package/lib/app/create-app.js
CHANGED
|
@@ -17,15 +17,59 @@ const { createAuthRef } = require('../core/yida-client');
|
|
|
17
17
|
const { t } = require('../core/i18n');
|
|
18
18
|
const { buildYidaI18n, normalizeYidaLocale, resolveContentLocale } = require('../core/yida-i18n');
|
|
19
19
|
const { parseOpenOption, withBrowserHandoff } = require('../core/browser-handoff');
|
|
20
|
+
const { assertPresetThemeKey } = require('./theme-presets');
|
|
20
21
|
|
|
21
22
|
const DEFAULT_APP_OPTIONS = {
|
|
22
23
|
icon: 'xian-yingyong',
|
|
23
24
|
iconColor: '#0089FF',
|
|
24
25
|
colour: 'deepBlue',
|
|
25
|
-
navTheme: 'dark',
|
|
26
|
-
layoutDirection: 'slide',
|
|
27
26
|
};
|
|
28
27
|
|
|
28
|
+
const INDUSTRY_APP_DEFAULTS = [
|
|
29
|
+
{
|
|
30
|
+
name: 'legal',
|
|
31
|
+
pattern: /(律所|律师|法律|法务|合规|仲裁|知识产权|诉讼|legal|law\s*firm|lawyer)/i,
|
|
32
|
+
options: {
|
|
33
|
+
icon: 'xian-falv',
|
|
34
|
+
iconColor: '#5C72FF',
|
|
35
|
+
colour: 'greyBlue',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'tea-ecology',
|
|
40
|
+
pattern: /(茶叶|茶园|茶业|茶庄|茶文化|农业|生态|环保|有机|健康|tea|agri|eco|green)/i,
|
|
41
|
+
options: {
|
|
42
|
+
icon: 'xian-diqiu',
|
|
43
|
+
iconColor: '#00B853',
|
|
44
|
+
colour: 'teal',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'command-screen',
|
|
49
|
+
pattern: /(数据大屏|大屏|实时监控|监测预警|预警系统|态势|指挥舱|水质|物联网|iot|screen|monitoring|command\s*center)/i,
|
|
50
|
+
options: {
|
|
51
|
+
icon: 'xian-baogao',
|
|
52
|
+
iconColor: '#14A9FF',
|
|
53
|
+
colour: 'greyBlue',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'professional-service',
|
|
58
|
+
pattern: /(咨询|审计|会计|投顾|专业服务|企业服务|consulting|audit|advisory)/i,
|
|
59
|
+
options: {
|
|
60
|
+
icon: 'xian-qiye',
|
|
61
|
+
iconColor: '#5C72FF',
|
|
62
|
+
colour: 'royalBlue',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
function inferAppDefaults(appName, description) {
|
|
68
|
+
const text = `${appName || ''} ${description || ''}`;
|
|
69
|
+
const matched = INDUSTRY_APP_DEFAULTS.find((item) => item.pattern.test(text));
|
|
70
|
+
return matched ? { industry: matched.name, ...matched.options } : { industry: 'default', ...DEFAULT_APP_OPTIONS };
|
|
71
|
+
}
|
|
72
|
+
|
|
29
73
|
// ── prd 文档更新 ──────────────────────────────────────
|
|
30
74
|
|
|
31
75
|
function findPrdFile() {
|
|
@@ -177,11 +221,15 @@ function parseCreateAppArgs(args) {
|
|
|
177
221
|
|
|
178
222
|
params.appName = params.appName || positional[0] || null;
|
|
179
223
|
params.description = params.description || positional[1] || params.appName;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
params.
|
|
183
|
-
params.
|
|
184
|
-
params.
|
|
224
|
+
|
|
225
|
+
const inferredDefaults = inferAppDefaults(params.appName, params.description);
|
|
226
|
+
params.icon = params.icon || positional[2] || inferredDefaults.icon;
|
|
227
|
+
params.iconColor = params.iconColor || positional[3] || inferredDefaults.iconColor;
|
|
228
|
+
params.colour = params.colour || positional[4] || inferredDefaults.colour;
|
|
229
|
+
assertPresetThemeKey(params.colour);
|
|
230
|
+
params.navTheme = params.navTheme || positional[5] || null;
|
|
231
|
+
params.layoutDirection = params.layoutDirection || positional[6] || null;
|
|
232
|
+
params.industry = inferredDefaults.industry;
|
|
185
233
|
|
|
186
234
|
return params;
|
|
187
235
|
}
|
|
@@ -196,6 +244,40 @@ function printUsage() {
|
|
|
196
244
|
process.stderr.write(` ${c.dim}${t('create_app.colors_list')}${c.reset}\n`);
|
|
197
245
|
}
|
|
198
246
|
|
|
247
|
+
function buildCreateAppPayload(params, auth, contentLocale, openExclusive, openPhysicColumn) {
|
|
248
|
+
const {
|
|
249
|
+
appName,
|
|
250
|
+
description,
|
|
251
|
+
icon,
|
|
252
|
+
iconColor,
|
|
253
|
+
colour,
|
|
254
|
+
navTheme,
|
|
255
|
+
layoutDirection,
|
|
256
|
+
} = params;
|
|
257
|
+
const iconValue = `${icon}%%${iconColor}`;
|
|
258
|
+
const payload = {
|
|
259
|
+
_csrf_token: auth.csrfToken,
|
|
260
|
+
appName: JSON.stringify(buildYidaI18n(appName, { en_US: appName, ja_JP: appName })),
|
|
261
|
+
description: JSON.stringify(buildYidaI18n(description, { en_US: description, ja_JP: description })),
|
|
262
|
+
icon: iconValue,
|
|
263
|
+
iconUrl: iconValue,
|
|
264
|
+
colour,
|
|
265
|
+
defaultLanguage: contentLocale,
|
|
266
|
+
openExclusive,
|
|
267
|
+
openPhysicColumn,
|
|
268
|
+
openIsolationDatabase: 'n',
|
|
269
|
+
openExclusiveUnit: 'n',
|
|
270
|
+
group: 'ALL',
|
|
271
|
+
};
|
|
272
|
+
if (navTheme) {
|
|
273
|
+
payload.navTheme = navTheme;
|
|
274
|
+
}
|
|
275
|
+
if (layoutDirection) {
|
|
276
|
+
payload.layoutDirection = layoutDirection;
|
|
277
|
+
}
|
|
278
|
+
return payload;
|
|
279
|
+
}
|
|
280
|
+
|
|
199
281
|
async function run(args) {
|
|
200
282
|
const openOption = parseOpenOption(args);
|
|
201
283
|
args = openOption.args;
|
|
@@ -220,13 +302,13 @@ async function run(args) {
|
|
|
220
302
|
|
|
221
303
|
const { appName, description, icon, iconColor, colour, navTheme, layoutDirection } = params;
|
|
222
304
|
|
|
223
|
-
const { c, banner, step, label,
|
|
305
|
+
const { c, banner, step, label, success: chalkSuccess, result: chalkResult } = require('../core/chalk');
|
|
224
306
|
|
|
225
307
|
banner(t('create_app.title'));
|
|
226
308
|
label('Name', appName);
|
|
227
309
|
label('Desc', description);
|
|
228
310
|
label('Icon', `${icon} ${c.dim}(${iconColor})${c.reset}`);
|
|
229
|
-
label('Theme', `${colour} / ${navTheme} / ${layoutDirection}`);
|
|
311
|
+
label('Theme', `${colour} / ${navTheme || 'default'} / ${layoutDirection || 'default'}`);
|
|
230
312
|
|
|
231
313
|
// Step 1: 读取登录态
|
|
232
314
|
step(1, t('common.step_login', 1));
|
|
@@ -257,23 +339,9 @@ async function run(args) {
|
|
|
257
339
|
// 查询失败时使用默认值,不影响主流程
|
|
258
340
|
}
|
|
259
341
|
|
|
260
|
-
const iconValue = `${icon}%%${iconColor}`;
|
|
261
342
|
const response = await requestWithAutoLogin((auth) => {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
description: JSON.stringify(buildYidaI18n(description, { en_US: description, ja_JP: description })),
|
|
265
|
-
icon: iconValue,
|
|
266
|
-
iconUrl: iconValue,
|
|
267
|
-
colour,
|
|
268
|
-
navTheme,
|
|
269
|
-
layoutDirection,
|
|
270
|
-
defaultLanguage: contentLocale,
|
|
271
|
-
openExclusive: openExclusive,
|
|
272
|
-
openPhysicColumn: openPhysicColumn,
|
|
273
|
-
openIsolationDatabase: 'n',
|
|
274
|
-
openExclusiveUnit: 'n',
|
|
275
|
-
group: 'ALL',
|
|
276
|
-
});
|
|
343
|
+
const payload = buildCreateAppPayload(params, auth, contentLocale, openExclusive, openPhysicColumn);
|
|
344
|
+
const postData = querystring.stringify(payload);
|
|
277
345
|
return httpPost(auth.baseUrl, '/query/app/registerApp.json', postData);
|
|
278
346
|
}, authRef);
|
|
279
347
|
|
|
@@ -306,4 +374,4 @@ async function run(args) {
|
|
|
306
374
|
}
|
|
307
375
|
}
|
|
308
376
|
|
|
309
|
-
module.exports = { run, parseCreateAppArgs };
|
|
377
|
+
module.exports = { run, parseCreateAppArgs, inferAppDefaults, buildCreateAppPayload };
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function parseMaybeJsonValue(value) {
|
|
4
|
+
if (typeof value !== 'string') {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
const trimmed = value.trim();
|
|
8
|
+
if (!trimmed) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (
|
|
12
|
+
(trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
13
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']'))
|
|
14
|
+
) {
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(trimmed);
|
|
17
|
+
} catch {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseInlineValidationOptions(tokens) {
|
|
25
|
+
if (!Array.isArray(tokens) || tokens.length === 0) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const rule = {};
|
|
30
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
31
|
+
const token = tokens[index];
|
|
32
|
+
if (!token || !token.startsWith('--')) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const key = token.slice(2).replace(/-/g, '_');
|
|
36
|
+
const next = tokens[index + 1];
|
|
37
|
+
if (next && !next.startsWith('--')) {
|
|
38
|
+
rule[key] = parseMaybeJsonValue(next);
|
|
39
|
+
index++;
|
|
40
|
+
} else {
|
|
41
|
+
rule[key] = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!rule.field && !rule.field_id && !rule.label && !rule.target && !rule.type) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (rule.field_id && !rule.fieldId) {
|
|
50
|
+
rule.fieldId = rule.field_id;
|
|
51
|
+
}
|
|
52
|
+
if (rule.domain_whitelist && !rule.domainWhitelist) {
|
|
53
|
+
rule.domainWhitelist = String(rule.domain_whitelist).split(',').map(function (item) {
|
|
54
|
+
return item.trim();
|
|
55
|
+
}).filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
if (rule.compare_to && !rule.compareTo) {
|
|
58
|
+
rule.compareTo = rule.compare_to;
|
|
59
|
+
}
|
|
60
|
+
if (rule.other_field && !rule.otherField) {
|
|
61
|
+
rule.otherField = rule.other_field;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return rule;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createParseArgs(dependencies) {
|
|
68
|
+
const {
|
|
69
|
+
parseOpenOption,
|
|
70
|
+
normalizeYidaLocale,
|
|
71
|
+
usage,
|
|
72
|
+
hint,
|
|
73
|
+
error,
|
|
74
|
+
t,
|
|
75
|
+
throwCreateFormError,
|
|
76
|
+
} = dependencies;
|
|
77
|
+
|
|
78
|
+
return function parseArgs(inputArgs) {
|
|
79
|
+
const openOption = parseOpenOption(inputArgs || process.argv.slice(2));
|
|
80
|
+
const rawArgs = openOption.args;
|
|
81
|
+
|
|
82
|
+
const options = {
|
|
83
|
+
layout: 'single',
|
|
84
|
+
theme: 'default',
|
|
85
|
+
labelAlign: 'top',
|
|
86
|
+
contentLocale: null,
|
|
87
|
+
browserOpenMode: openOption.mode,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const args = [...rawArgs];
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < args.length; i++) {
|
|
93
|
+
if (args[i] === '--layout' && i + 1 < args.length) {
|
|
94
|
+
options.layout = args[i + 1];
|
|
95
|
+
args.splice(i, 2);
|
|
96
|
+
i--;
|
|
97
|
+
} else if (args[i] === '--theme' && i + 1 < args.length) {
|
|
98
|
+
options.theme = args[i + 1];
|
|
99
|
+
args.splice(i, 2);
|
|
100
|
+
i--;
|
|
101
|
+
} else if (args[i] === '--label-align' && i + 1 < args.length) {
|
|
102
|
+
options.labelAlign = args[i + 1];
|
|
103
|
+
args.splice(i, 2);
|
|
104
|
+
i--;
|
|
105
|
+
} else if ((args[i] === '--locale' || args[i] === '--content-locale' || args[i] === '--lang') && i + 1 < args.length) {
|
|
106
|
+
options.contentLocale = args[i + 1];
|
|
107
|
+
if (!normalizeYidaLocale(options.contentLocale)) {
|
|
108
|
+
error(`Unsupported locale: ${options.contentLocale}`);
|
|
109
|
+
throwCreateFormError(`Unsupported locale: ${options.contentLocale}`, 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
110
|
+
}
|
|
111
|
+
process.env.OPENYIDA_CONTENT_LOCALE = normalizeYidaLocale(options.contentLocale);
|
|
112
|
+
args.splice(i, 2);
|
|
113
|
+
i--;
|
|
114
|
+
} else if (args[i] === '--force') {
|
|
115
|
+
options.force = true;
|
|
116
|
+
args.splice(i, 1);
|
|
117
|
+
i--;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const mode = args[0];
|
|
122
|
+
|
|
123
|
+
if (mode === 'create') {
|
|
124
|
+
if (args.length < 4) {
|
|
125
|
+
usage(t('create_form.usage_create'), t('create_form.example_create'));
|
|
126
|
+
throwCreateFormError(t('create_form.usage_create'), 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
mode: 'create',
|
|
130
|
+
appType: args[1],
|
|
131
|
+
formTitle: args[2],
|
|
132
|
+
fieldsJsonOrFile: args[3],
|
|
133
|
+
...options
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (mode === 'update') {
|
|
138
|
+
if (args.length < 4) {
|
|
139
|
+
usage(t('create_form.usage_update'), t('create_form.example_update'));
|
|
140
|
+
throwCreateFormError(t('create_form.usage_update'), 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
mode: 'update',
|
|
144
|
+
appType: args[1],
|
|
145
|
+
formUuid: args[2],
|
|
146
|
+
changesJsonOrFile: args[3],
|
|
147
|
+
...options
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (mode === 'patch') {
|
|
152
|
+
if (args.length < 4) {
|
|
153
|
+
usage(
|
|
154
|
+
'openyida create-form patch <appType> <formUuid> <patchJsonOrFile>',
|
|
155
|
+
'openyida create-form patch APP_XXX FORM-XXX .cache/openyida/forms/form-patch.json'
|
|
156
|
+
);
|
|
157
|
+
throwCreateFormError('openyida create-form patch <appType> <formUuid> <patchJsonOrFile>', 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
mode: 'patch',
|
|
161
|
+
appType: args[1],
|
|
162
|
+
formUuid: args[2],
|
|
163
|
+
patchJsonOrFile: args[3],
|
|
164
|
+
...options
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (mode === 'rule' || mode === 'rules') {
|
|
169
|
+
if (args.length < 4) {
|
|
170
|
+
usage(
|
|
171
|
+
'openyida create-form rule <appType> <formUuid> <rulesJsonOrFile>',
|
|
172
|
+
'openyida create-form rule APP_XXX FORM-XXX .cache/openyida/forms/form-rules.json'
|
|
173
|
+
);
|
|
174
|
+
throwCreateFormError('openyida create-form rule <appType> <formUuid> <rulesJsonOrFile>', 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
mode: 'rule',
|
|
178
|
+
appType: args[1],
|
|
179
|
+
formUuid: args[2],
|
|
180
|
+
rulesJsonOrFile: args[3],
|
|
181
|
+
...options
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (mode === 'validation' || mode === 'validate' || mode === 'validations') {
|
|
186
|
+
const inlineRule = parseInlineValidationOptions(args.slice(3));
|
|
187
|
+
if (args.length < 4 && !inlineRule) {
|
|
188
|
+
usage(
|
|
189
|
+
'openyida create-form validation <appType> <formUuid> <validationsJsonOrFile>',
|
|
190
|
+
'openyida create-form validation APP_XXX FORM-XXX .cache/openyida/forms/form-validations.json'
|
|
191
|
+
);
|
|
192
|
+
hint('openyida add-validation APP_XXX FORM-XXX --field "手机号" --type phone --message "请输入正确的手机号"');
|
|
193
|
+
throwCreateFormError('openyida create-form validation <appType> <formUuid> <validationsJsonOrFile>', 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
mode: 'validation',
|
|
197
|
+
appType: args[1],
|
|
198
|
+
formUuid: args[2],
|
|
199
|
+
validationJsonOrFile: inlineRule ? '' : args[3],
|
|
200
|
+
inlineValidationRule: inlineRule,
|
|
201
|
+
...options
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (mode === 'bind-datasource' || mode === 'datasource' || mode === 'data-source') {
|
|
206
|
+
if (args.length < 5) {
|
|
207
|
+
usage(
|
|
208
|
+
'openyida create-form bind-datasource <appType> <formUuid> <fieldLabelOrId> <dataSourceJsonOrFile>',
|
|
209
|
+
'openyida create-form bind-datasource APP_XXX FORM-XXX "客户" .cache/openyida/forms/customer-datasource.json'
|
|
210
|
+
);
|
|
211
|
+
throwCreateFormError('openyida create-form bind-datasource <appType> <formUuid> <fieldLabelOrId> <dataSourceJsonOrFile>', 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
mode: 'bind-datasource',
|
|
215
|
+
appType: args[1],
|
|
216
|
+
formUuid: args[2],
|
|
217
|
+
fieldLabel: args[3],
|
|
218
|
+
dataSourceJsonOrFile: args[4],
|
|
219
|
+
...options
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (mode === 'add-option') {
|
|
224
|
+
if (args.length < 5) {
|
|
225
|
+
usage(
|
|
226
|
+
'openyida create-form add-option <appType> <formUuid> <fieldLabel> <option1> [option2] ...',
|
|
227
|
+
'openyida create-form add-option APP_XXX FORM-XXX "优先级" "P0" "P1"'
|
|
228
|
+
);
|
|
229
|
+
throwCreateFormError('openyida create-form add-option <appType> <formUuid> <fieldLabel> <option1> [option2] ...', 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
mode: 'add-option',
|
|
233
|
+
appType: args[1],
|
|
234
|
+
formUuid: args[2],
|
|
235
|
+
fieldLabel: args[3],
|
|
236
|
+
newOptions: args.slice(4).filter(function (arg) { return !arg.startsWith('--'); }),
|
|
237
|
+
...options
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (args.length >= 3 && mode !== 'create' && mode !== 'update' && mode !== 'patch' && mode !== 'rule' && mode !== 'rules' && mode !== 'validation' && mode !== 'validate' && mode !== 'validations' && mode !== 'bind-datasource' && mode !== 'datasource' && mode !== 'data-source') {
|
|
242
|
+
return {
|
|
243
|
+
mode: 'create',
|
|
244
|
+
appType: args[0],
|
|
245
|
+
formTitle: args[1],
|
|
246
|
+
fieldsJsonOrFile: args[2],
|
|
247
|
+
...options
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
usage(t('create_form.usage_create_short'));
|
|
252
|
+
hint(t('create_form.usage_update_short'));
|
|
253
|
+
hint(t('create_form.example_create'));
|
|
254
|
+
hint(t('create_form.example_update'));
|
|
255
|
+
throwCreateFormError(t('create_form.usage_create_short'), 'CREATE_FORM_INVALID_ARGUMENTS');
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
module.exports = {
|
|
260
|
+
createParseArgs,
|
|
261
|
+
parseInlineValidationOptions,
|
|
262
|
+
parseMaybeJsonValue,
|
|
263
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function dispatchCreateFormCommand(parsedArgs, authContext, handlers) {
|
|
4
|
+
const args = [parsedArgs, authContext];
|
|
5
|
+
|
|
6
|
+
switch (parsedArgs.mode) {
|
|
7
|
+
case 'update':
|
|
8
|
+
return handlers.update(...args);
|
|
9
|
+
case 'patch':
|
|
10
|
+
return handlers.patch(...args);
|
|
11
|
+
case 'rule':
|
|
12
|
+
return handlers.rule(...args);
|
|
13
|
+
case 'validation':
|
|
14
|
+
return handlers.validation(...args);
|
|
15
|
+
case 'bind-datasource':
|
|
16
|
+
return handlers.bindDataSource(...args);
|
|
17
|
+
case 'add-option':
|
|
18
|
+
return handlers.addOption(...args);
|
|
19
|
+
case 'create':
|
|
20
|
+
default:
|
|
21
|
+
return handlers.create(...args);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
dispatchCreateFormCommand,
|
|
27
|
+
};
|