cabloy 5.1.59 → 5.1.61
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/.claude/hooks/contract-loop-gate.ts +296 -0
- package/.claude/settings.json +16 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +103 -14
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +126 -12
- package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +148 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +49 -13
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +11 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
- package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +274 -0
- package/.claude/skills/cabloy-resource-field-update/evals/evals.json +53 -0
- package/.claude/skills/cabloy-resource-field-update/references/custom-renderer-demo-checklist.md +102 -0
- package/.claude/skills/cabloy-resource-field-update/references/field-update-decision-tree.md +120 -0
- package/.claude/skills/cabloy-resource-field-update/references/follow-up-checklist.md +80 -0
- package/.claude/skills/cabloy-resource-field-update/references/verification-checklist.md +97 -0
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
- package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
- package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
- package/.github/workflows/docs-pages.yml +2 -0
- package/.github/workflows/vona-cov-pg.yml +2 -0
- package/.github/workflows/vona-test-crud.yml +4 -2
- package/.github/workflows/vona-test-mysql.yml +2 -0
- package/.github/workflows/vona-test-pg.yml +2 -0
- package/.github/workflows/vona-test-sqlite3.yml +2 -0
- package/.github/workflows/vona-tsc.yml +2 -0
- package/.github/workflows/zova-ui.yml +2 -0
- package/.gitignore +0 -4
- package/CHANGELOG.md +52 -0
- package/CLAUDE.md +12 -0
- package/README.md +15 -0
- package/cabloy-docs/.vitepress/config.mjs +89 -0
- package/cabloy-docs/ai/class-placement-rule.md +2 -0
- package/cabloy-docs/ai/cli-to-skill-map.md +14 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +14 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +27 -9
- package/cabloy-docs/ai/introduction.md +1 -0
- package/cabloy-docs/ai/playbook-backend-module.md +6 -0
- package/cabloy-docs/ai/playbook-module-removal.md +164 -0
- package/cabloy-docs/ai/skills.md +11 -0
- package/cabloy-docs/backend/bean-scene-authoring.md +350 -0
- package/cabloy-docs/backend/cli.md +26 -1
- package/cabloy-docs/backend/dto-guide.md +6 -0
- package/cabloy-docs/backend/entity-guide.md +18 -0
- package/cabloy-docs/backend/foundation.md +28 -3
- package/cabloy-docs/backend/introduction.md +10 -0
- package/cabloy-docs/backend/serialization-guide.md +10 -0
- package/cabloy-docs/backend/service-guide.md +2 -0
- package/cabloy-docs/backend/status-guide.md +271 -0
- package/cabloy-docs/backend/websocket-call-flow.md +435 -0
- package/cabloy-docs/backend/websocket-guide.md +455 -0
- package/cabloy-docs/backend/websocket-protocol-guide.md +381 -0
- package/cabloy-docs/backend/websocket-usage-guide.md +356 -0
- package/cabloy-docs/frontend/api-guide.md +2 -0
- package/cabloy-docs/frontend/bean-scene-authoring.md +374 -0
- package/cabloy-docs/frontend/behavior-guide.md +449 -0
- package/cabloy-docs/frontend/cli.md +24 -0
- package/cabloy-docs/frontend/command-scene-authoring.md +495 -0
- package/cabloy-docs/frontend/design-principles.md +6 -0
- package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
- package/cabloy-docs/frontend/form-guide.md +795 -0
- package/cabloy-docs/frontend/foundation.md +29 -0
- package/cabloy-docs/frontend/introduction.md +17 -1
- package/cabloy-docs/frontend/ioc-and-beans.md +16 -9
- package/cabloy-docs/frontend/mock-guide.md +1 -0
- package/cabloy-docs/frontend/model-architecture.md +252 -39
- package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
- package/cabloy-docs/frontend/model-resource-cookbook.md +505 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +382 -0
- package/cabloy-docs/frontend/model-resource-usage-guide.md +318 -0
- package/cabloy-docs/frontend/model-state-guide.md +366 -13
- package/cabloy-docs/frontend/openapi-sdk-guide.md +5 -2
- package/cabloy-docs/frontend/page-guide.md +6 -0
- package/cabloy-docs/frontend/quickstart.md +4 -0
- package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
- package/cabloy-docs/frontend/router-tabs-admin-web-comparison.md +206 -0
- package/cabloy-docs/frontend/router-tabs-introduction.md +106 -0
- package/cabloy-docs/frontend/router-tabs-mechanism.md +469 -0
- package/cabloy-docs/frontend/router-tabs-overview.md +227 -0
- package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +343 -0
- package/cabloy-docs/frontend/server-data.md +2 -0
- package/cabloy-docs/frontend/ssr-architecture-overview.md +211 -0
- package/cabloy-docs/frontend/ssr-build-deploy-guide.md +308 -0
- package/cabloy-docs/frontend/ssr-review-checklist.md +184 -0
- package/cabloy-docs/frontend/ssr-troubleshooting-guide.md +301 -0
- package/cabloy-docs/frontend/zova-form-source-reading-map.md +295 -0
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +556 -0
- package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +327 -0
- package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
- package/cabloy-docs/fullstack/contract-loop-playbook.md +350 -0
- package/cabloy-docs/fullstack/framework-performance.md +3 -3
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +44 -1
- package/cabloy-docs/fullstack/introduction.md +40 -0
- package/cabloy-docs/fullstack/openapi-to-sdk.md +19 -9
- package/cabloy-docs/fullstack/quickstart.md +7 -1
- package/cabloy-docs/fullstack/tutorial-1-first-module.md +111 -0
- package/cabloy-docs/fullstack/tutorial-2-first-crud.md +122 -0
- package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +131 -0
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +144 -0
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +146 -0
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +170 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +192 -0
- package/cabloy-docs/index.md +4 -3
- package/cabloy-docs/reference/bean-scene-boilerplates.md +75 -0
- package/cabloy-docs/reference/cli-reference.md +2 -0
- package/package.json +7 -2
- package/scripts/initTestData.ts +25 -0
- package/scripts/upgrade.ts +17 -2
- package/vona/packages-cli/cabloy-cli/package.json +2 -2
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +4 -0
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +226 -1091
- package/vona/pnpm-workspace.yaml +0 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/assets/static/img/vona.svg +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/package.original.json +1 -1
- package/zova/packages-cli/cli/package.json +3 -3
- package/zova/packages-cli/cli-set-front/cli/templates/init/icon/boilerplate/icons/default/zova.svg +1 -1
- package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
- package/zova/packages-cli/cli-set-front/package.json +3 -3
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +4 -0
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
- package/zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts +5 -1
- package/zova/packages-utils/zova-vite/package.json +2 -2
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +282 -1311
- package/zova/pnpm-workspace.yaml +0 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/cabloy.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/vona.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/zova.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/src/.metadata/icons/groups/social.svg +3 -3
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +9 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +66 -16
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +60 -18
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableCell/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +4 -4
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
# Command Scene Authoring
|
|
2
|
+
|
|
3
|
+
This guide explains how the built-in Zova `command` scene works and how to read or author command beans accurately.
|
|
4
|
+
|
|
5
|
+
Use this page when you need to answer questions such as:
|
|
6
|
+
|
|
7
|
+
- what is a Zova command bean
|
|
8
|
+
- when should logic live in a command bean
|
|
9
|
+
- how does `$performCommand(...)` resolve and execute a command
|
|
10
|
+
- which built-in command boilerplates already exist
|
|
11
|
+
- which source files should I read first to understand command behavior
|
|
12
|
+
|
|
13
|
+
This page is about the **existing** `command` scene. If you need to create a brand-new frontend bean scene instead, use [Frontend Bean Scene Authoring](/frontend/bean-scene-authoring).
|
|
14
|
+
|
|
15
|
+
## What the command scene is
|
|
16
|
+
|
|
17
|
+
In Zova, `command` is a frontend bean scene for **named command beans** that can be invoked through an onion name.
|
|
18
|
+
|
|
19
|
+
A command bean is useful when you want:
|
|
20
|
+
|
|
21
|
+
- a reusable action with a stable command name
|
|
22
|
+
- scene-aware logic that depends on `renderContext`
|
|
23
|
+
- behavior that can be triggered indirectly rather than by calling one concrete class directly
|
|
24
|
+
- a typed command contract that can be extended through generated metadata
|
|
25
|
+
|
|
26
|
+
A good mental model is:
|
|
27
|
+
|
|
28
|
+
- the **command scene** defines the runtime contract
|
|
29
|
+
- each **command bean** implements one named action
|
|
30
|
+
- the framework resolves the command bean from the onion name and then calls its `execute(...)` method
|
|
31
|
+
|
|
32
|
+
This is a Zova bean-scene-based action mechanism, not a generic Vue helper pattern.
|
|
33
|
+
|
|
34
|
+
## When a command bean fits well
|
|
35
|
+
|
|
36
|
+
A command bean is a good fit when the action needs one or more of these properties:
|
|
37
|
+
|
|
38
|
+
- a stable command identity such as `basic-commands:create`
|
|
39
|
+
- access to host-driven context such as `app`, `ctx`, `$host`, or scene-specific render information
|
|
40
|
+
- a reusable action surface shared across modules or UI authoring paths
|
|
41
|
+
- an action that should stay thin and composable instead of being buried directly inside one page or component controller
|
|
42
|
+
|
|
43
|
+
Typical examples from the current source tree include:
|
|
44
|
+
|
|
45
|
+
- page-level resource creation commands
|
|
46
|
+
- table-row commands that need `resource` and `id`
|
|
47
|
+
- form-field commands that update field state from an event
|
|
48
|
+
- small sync commands such as debug or logging helpers
|
|
49
|
+
|
|
50
|
+
If the behavior is only private page logic with no command identity and no reuse pressure, it may belong in the page or component controller instead.
|
|
51
|
+
|
|
52
|
+
## Public authoring surface
|
|
53
|
+
|
|
54
|
+
The public authoring surface is intentionally small.
|
|
55
|
+
|
|
56
|
+
### `@Command()`
|
|
57
|
+
|
|
58
|
+
The scene decorator is defined in:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/lib/command.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Representative source:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
export function Command<T extends IDecoratorCommandOptions>(
|
|
68
|
+
options?: PowerPartial<T>,
|
|
69
|
+
): ClassDecorator {
|
|
70
|
+
return createBeanDecorator('command', 'sys', true, options);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That confirms three important facts:
|
|
75
|
+
|
|
76
|
+
- the scene name is `command`
|
|
77
|
+
- command beans use the `sys` container scope
|
|
78
|
+
- the decorator supports options
|
|
79
|
+
|
|
80
|
+
So a command bean is a Zova system-scoped bean scene with onion options, not a one-off helper class.
|
|
81
|
+
|
|
82
|
+
### `ICommandExecute`
|
|
83
|
+
|
|
84
|
+
The main runtime contract is defined in:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/types/command.ts
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Representative shape:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
export interface ICommandExecute {
|
|
94
|
+
execute(
|
|
95
|
+
options: IDecoratorCommandOptions,
|
|
96
|
+
renderContext: IJsxRenderContextBase,
|
|
97
|
+
next: NextCommandExecute,
|
|
98
|
+
): any | Promise<any>;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
In practice, a command bean usually:
|
|
103
|
+
|
|
104
|
+
1. receives typed options
|
|
105
|
+
2. reads `renderContext` when scene-specific behavior matters
|
|
106
|
+
3. performs the action
|
|
107
|
+
4. returns `next(...)` to continue the command pipeline or pass the result forward
|
|
108
|
+
|
|
109
|
+
### Minimal command bean pattern
|
|
110
|
+
|
|
111
|
+
The default command boilerplate currently generates this shape:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import type { IJsxRenderContextBase } from 'zova-module-a-openapi';
|
|
115
|
+
|
|
116
|
+
import { BeanBase } from 'zova';
|
|
117
|
+
import { Command, type ICommandExecute, type ICommandOptionsBase, type NextCommandExecute } from 'zova-module-a-command';
|
|
118
|
+
|
|
119
|
+
export type TypeCommandExampleResult = unknown;
|
|
120
|
+
|
|
121
|
+
export interface ICommandOptionsExample extends ICommandOptionsBase<TypeCommandExampleResult> {}
|
|
122
|
+
|
|
123
|
+
@Command<ICommandOptionsExample>()
|
|
124
|
+
export class CommandExample extends BeanBase implements ICommandExecute {
|
|
125
|
+
execute(_options: ICommandOptionsExample, _renderContext: IJsxRenderContextBase, next: NextCommandExecute) {
|
|
126
|
+
return next();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
That is the thinnest useful command-bean shape.
|
|
132
|
+
|
|
133
|
+
## Runtime invocation path
|
|
134
|
+
|
|
135
|
+
The runtime path is easiest to understand in this order:
|
|
136
|
+
|
|
137
|
+
1. `command.ts`
|
|
138
|
+
2. `monkey.ts`
|
|
139
|
+
3. `performCommand.ts`
|
|
140
|
+
4. downstream command beans and generated metadata
|
|
141
|
+
|
|
142
|
+
### `$performCommand(...)` is injected by monkey wiring
|
|
143
|
+
|
|
144
|
+
Read:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/monkey.ts
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`Monkey` injects `$performCommand(...)` onto bean instances during `beanInit(...)`.
|
|
151
|
+
|
|
152
|
+
A key source-confirmed detail is that the injected method synthesizes a default render context from the host bean:
|
|
153
|
+
|
|
154
|
+
- `app`
|
|
155
|
+
- `ctx`
|
|
156
|
+
- `$host`
|
|
157
|
+
|
|
158
|
+
That means command execution naturally carries the invoking bean context even when the caller only passes partial render information.
|
|
159
|
+
|
|
160
|
+
### A practical `$performCommand(...)` call shape
|
|
161
|
+
|
|
162
|
+
Because `$performCommand(...)` is injected onto bean instances, the most natural calling style is from another bean such as a page or component controller.
|
|
163
|
+
|
|
164
|
+
A representative call shape looks like this:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
await this.$performCommand('basic-commands:create', {
|
|
168
|
+
resource: 'demo-student:student',
|
|
169
|
+
replace: false,
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
A row-oriented example looks like this:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await this.$performCommand('basic-commands:delete', {
|
|
177
|
+
resource: 'demo-student:student',
|
|
178
|
+
id: row.id,
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The important point is not the exact calling location. The important point is that the caller invokes a **command onion name**, passes typed options, and lets the command scene resolve the real bean instance and execution path.
|
|
183
|
+
|
|
184
|
+
When scene-sensitive behavior matters, the caller can also pass explicit `renderContext` or a custom `next(...)` handler. If not, the injected helper already supplies the host-driven defaults.
|
|
185
|
+
|
|
186
|
+
### Onion name resolves to the command bean
|
|
187
|
+
|
|
188
|
+
Read:
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/lib/performCommand.ts
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The core dispatch path is:
|
|
195
|
+
|
|
196
|
+
1. resolve `beanFullName` from `commandName` with `beanFullNameFromOnionName(commandName, 'command')`
|
|
197
|
+
2. try synchronous lookup first with `sys.bean._getBeanSyncOnly(...)`
|
|
198
|
+
3. if not available, fall back to async lookup with `sys.bean._getBean(...)`
|
|
199
|
+
4. merge decorator/onion options and call-time options through `deepExtend(...)`
|
|
200
|
+
5. execute the command bean through `beanInstance.execute(props, renderContext, next)`
|
|
201
|
+
|
|
202
|
+
This shows that command invocation is not a string-to-function shortcut. It is a bean-container resolution flow with command-specific typing and option merging.
|
|
203
|
+
|
|
204
|
+
### Why `next(...)` matters
|
|
205
|
+
|
|
206
|
+
`performCommand.ts` also shows that a missing `next` gets a default identity-style function.
|
|
207
|
+
|
|
208
|
+
So `next(...)` is part of the stable command contract even for simple commands:
|
|
209
|
+
|
|
210
|
+
- simple commands can just call `next()`
|
|
211
|
+
- commands that produce a value can pass that value to `next(res)`
|
|
212
|
+
- callers can supply a custom `next` to wrap or transform the result
|
|
213
|
+
|
|
214
|
+
## Built-in helper base classes
|
|
215
|
+
|
|
216
|
+
The command scene includes two helper bases for common render-context patterns.
|
|
217
|
+
|
|
218
|
+
### `BeanCommandBulkBase`
|
|
219
|
+
|
|
220
|
+
Read:
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/lib/beanCommandBulkBase.ts
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
This base resolves `resource` from:
|
|
227
|
+
|
|
228
|
+
- explicit `options.resource`
|
|
229
|
+
- or page-scene `$celScope.resource`
|
|
230
|
+
|
|
231
|
+
If neither exists, it throws.
|
|
232
|
+
|
|
233
|
+
This makes it the right base when the command is bulk-like or page-resource-oriented and only needs a resource identity.
|
|
234
|
+
|
|
235
|
+
The `commandBulk` boilerplate reflects this shape.
|
|
236
|
+
|
|
237
|
+
### `BeanCommandRowBase`
|
|
238
|
+
|
|
239
|
+
Read:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/lib/beanCommandRowBase.ts
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
This base resolves:
|
|
246
|
+
|
|
247
|
+
- `resource`
|
|
248
|
+
- `id`
|
|
249
|
+
|
|
250
|
+
from either explicit options or `tableCell` render context.
|
|
251
|
+
|
|
252
|
+
If either value is missing, it throws.
|
|
253
|
+
|
|
254
|
+
This makes it the right base when the command is row-oriented and needs the current table row identity.
|
|
255
|
+
|
|
256
|
+
The `commandRow` boilerplate reflects this shape.
|
|
257
|
+
|
|
258
|
+
## Typing and metadata registration
|
|
259
|
+
|
|
260
|
+
The command scene becomes truly useful because the typing surface and generated metadata cooperate.
|
|
261
|
+
|
|
262
|
+
### Core typing surface
|
|
263
|
+
|
|
264
|
+
Read:
|
|
265
|
+
|
|
266
|
+
```text
|
|
267
|
+
zova/src/suite-vendor/a-zova/modules/a-command/src/types/command.ts
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Important pieces:
|
|
271
|
+
|
|
272
|
+
- `ICommandRecord`
|
|
273
|
+
- the extensible registry of command names to command option types
|
|
274
|
+
- `SymbolCommandResult`
|
|
275
|
+
- the result-type carrier used in the command option contract
|
|
276
|
+
- `IDecoratorCommandOptions`
|
|
277
|
+
- the base decorator options shape
|
|
278
|
+
- `ICommandOptionsBase`, `ICommandBulkOptionsBase`, `ICommandRowOptionsBase`
|
|
279
|
+
- shared option contracts for common command patterns
|
|
280
|
+
- `TypeCommandOptions<K>`
|
|
281
|
+
- typed command reference shape
|
|
282
|
+
- `ICommandExecute`
|
|
283
|
+
- runtime execution contract
|
|
284
|
+
|
|
285
|
+
The same file also declaration-merges the command scene into Zova surfaces such as:
|
|
286
|
+
|
|
287
|
+
- `SysOnion`
|
|
288
|
+
- `ConfigOnions`
|
|
289
|
+
- `IBeanSceneRecord`
|
|
290
|
+
|
|
291
|
+
That confirms `command` is a first-class Zova bean scene.
|
|
292
|
+
|
|
293
|
+
### Generated metadata proves the real command names
|
|
294
|
+
|
|
295
|
+
A representative generated metadata file is:
|
|
296
|
+
|
|
297
|
+
```text
|
|
298
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/.metadata/index.ts
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
From current source, this file augments `zova-module-a-command` by extending `ICommandRecord` with names such as:
|
|
302
|
+
|
|
303
|
+
- `basic-commands:create`
|
|
304
|
+
- `basic-commands:delete`
|
|
305
|
+
- `basic-commands:setValue`
|
|
306
|
+
|
|
307
|
+
It also records the related bean full names such as:
|
|
308
|
+
|
|
309
|
+
- `basic-commands.command.create`
|
|
310
|
+
- `basic-commands.command.delete`
|
|
311
|
+
- `basic-commands.command.setValue`
|
|
312
|
+
|
|
313
|
+
This is why the command scene should be read through both the source bean and the generated metadata surface.
|
|
314
|
+
|
|
315
|
+
## CLI scaffolding and boilerplate variants
|
|
316
|
+
|
|
317
|
+
The command scene is also defined by module metadata in:
|
|
318
|
+
|
|
319
|
+
```text
|
|
320
|
+
zova/src/suite-vendor/a-zova/modules/a-command/package.json
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The `zovaModule.onions.command` metadata confirms:
|
|
324
|
+
|
|
325
|
+
- `beanGeneral: true`
|
|
326
|
+
- `optionsGlobalInterfaceName: IDecoratorCommandOptions`
|
|
327
|
+
- default `boilerplate`
|
|
328
|
+
- `boilerplateCommandBulk`
|
|
329
|
+
- `boilerplateCommandRow`
|
|
330
|
+
|
|
331
|
+
The CLI command shape is currently exposed by:
|
|
332
|
+
|
|
333
|
+
```text
|
|
334
|
+
zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
CLI help usage:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npm run zova :create:bean sceneName beanName -- [--module=] [--boilerplate=]
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Default command boilerplate
|
|
344
|
+
|
|
345
|
+
Use the default template when the command bean does not need `BeanCommandBulkBase` or `BeanCommandRowBase`:
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
npm run zova :create:bean command test -- --module=demo-student
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### `commandBulk` boilerplate
|
|
352
|
+
|
|
353
|
+
Use the bulk variant when the command should resolve `resource` through `BeanCommandBulkBase`:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npm run zova :create:bean command test -- --module=demo-student --boilerplate=commandBulk
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### `commandRow` boilerplate
|
|
360
|
+
|
|
361
|
+
Use the row variant when the command should resolve `resource` and `id` through `BeanCommandRowBase`:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
npm run zova :create:bean command test -- --module=demo-student --boilerplate=commandRow
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
For the cross-scene lookup table, also see [Bean Scene Boilerplate Variants](/reference/bean-scene-boilerplates).
|
|
368
|
+
|
|
369
|
+
## Representative built-in examples
|
|
370
|
+
|
|
371
|
+
Use the following examples when you need to understand how the command scene is used in real modules.
|
|
372
|
+
|
|
373
|
+
### `basic-commands:create`
|
|
374
|
+
|
|
375
|
+
Read:
|
|
376
|
+
|
|
377
|
+
```text
|
|
378
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.create.tsx
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Why it matters:
|
|
382
|
+
|
|
383
|
+
- extends `BeanCommandBulkBase`
|
|
384
|
+
- derives `resource` from options or page context
|
|
385
|
+
- routes through the host router to the resource-create page
|
|
386
|
+
|
|
387
|
+
This is the clearest bulk-command specimen.
|
|
388
|
+
|
|
389
|
+
### `basic-commands:delete`
|
|
390
|
+
|
|
391
|
+
Read:
|
|
392
|
+
|
|
393
|
+
```text
|
|
394
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.delete.tsx
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Why it matters:
|
|
398
|
+
|
|
399
|
+
- extends `BeanCommandRowBase`
|
|
400
|
+
- derives `resource` and `id`
|
|
401
|
+
- resolves a resource model bean and performs a mutation
|
|
402
|
+
|
|
403
|
+
This is the clearest row-command specimen.
|
|
404
|
+
|
|
405
|
+
### `basic-commands:setValue`
|
|
406
|
+
|
|
407
|
+
Read:
|
|
408
|
+
|
|
409
|
+
```text
|
|
410
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.setValue.tsx
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Why it matters:
|
|
414
|
+
|
|
415
|
+
- extends plain `BeanBase`, not a bulk/row helper base
|
|
416
|
+
- checks `renderContext.$scene === 'formField'`
|
|
417
|
+
- uses field-scene data and event data to update form state
|
|
418
|
+
|
|
419
|
+
This is the clearest example that command beans can be scene-sensitive without fitting the resource-row patterns.
|
|
420
|
+
|
|
421
|
+
### `basic-commandssync:log`
|
|
422
|
+
|
|
423
|
+
Read:
|
|
424
|
+
|
|
425
|
+
```text
|
|
426
|
+
zova/src/suite/cabloy-basic/modules/basic-commandssync/src/bean/command.log.tsx
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Why it matters:
|
|
430
|
+
|
|
431
|
+
- small synchronous command
|
|
432
|
+
- also uses `@Preload()`
|
|
433
|
+
- demonstrates that command beans can stay very small when the command contract is the important part
|
|
434
|
+
|
|
435
|
+
## A practical source-reading order
|
|
436
|
+
|
|
437
|
+
When you need to understand Zova Command quickly, use this order:
|
|
438
|
+
|
|
439
|
+
1. this guide
|
|
440
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-command/src/lib/command.ts`
|
|
441
|
+
3. `zova/src/suite-vendor/a-zova/modules/a-command/src/monkey.ts`
|
|
442
|
+
4. `zova/src/suite-vendor/a-zova/modules/a-command/src/lib/performCommand.ts`
|
|
443
|
+
5. `zova/src/suite-vendor/a-zova/modules/a-command/src/types/command.ts`
|
|
444
|
+
6. one representative downstream metadata file such as `basic-commands/src/.metadata/index.ts`
|
|
445
|
+
7. one or more concrete command beans such as `command.create.tsx`, `command.delete.tsx`, `command.setValue.tsx`, or `command.log.tsx`
|
|
446
|
+
|
|
447
|
+
That path moves from public scene surface to runtime wiring to real consumer code without flattening the architecture into generic Vue terminology too early.
|
|
448
|
+
|
|
449
|
+
## Design guidance
|
|
450
|
+
|
|
451
|
+
When authoring command beans, prefer these rules:
|
|
452
|
+
|
|
453
|
+
- keep the command bean focused on one named action
|
|
454
|
+
- use `BeanCommandBulkBase` or `BeanCommandRowBase` only when the render-context pattern matches
|
|
455
|
+
- prefer explicit command identity over hidden page-local behavior when the action is meant to be reused
|
|
456
|
+
- keep business logic thin when it naturally belongs in a model, service, or other bean
|
|
457
|
+
- treat `renderContext` as part of the command contract, not as an afterthought
|
|
458
|
+
|
|
459
|
+
A command bean should usually coordinate an action cleanly, not become a dumping ground for unrelated page behavior.
|
|
460
|
+
|
|
461
|
+
## Relationship to other guides
|
|
462
|
+
|
|
463
|
+
Read this together with:
|
|
464
|
+
|
|
465
|
+
- [Frontend CLI](/frontend/cli)
|
|
466
|
+
- [IoC and Beans](/frontend/ioc-and-beans)
|
|
467
|
+
- [Frontend Bean Scene Authoring](/frontend/bean-scene-authoring)
|
|
468
|
+
- [Zova Source Reading Map](/frontend/zova-source-reading-map)
|
|
469
|
+
|
|
470
|
+
Use this page to understand the built-in command scene itself. Use the bean-scene authoring page when you need to design a new scene contract, not when you only need to author command beans inside the existing `command` scene.
|
|
471
|
+
|
|
472
|
+
## Verification checklist
|
|
473
|
+
|
|
474
|
+
When documenting or reviewing command-scene behavior, verify in this order:
|
|
475
|
+
|
|
476
|
+
1. confirm the CLI help still matches the documented command shape:
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
npm run zova :create:bean --help
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
2. confirm these source files still match the explanation:
|
|
483
|
+
- `a-command/src/lib/command.ts`
|
|
484
|
+
- `a-command/src/monkey.ts`
|
|
485
|
+
- `a-command/src/lib/performCommand.ts`
|
|
486
|
+
- `a-command/src/lib/beanCommandBulkBase.ts`
|
|
487
|
+
- `a-command/src/lib/beanCommandRowBase.ts`
|
|
488
|
+
- `a-command/src/types/command.ts`
|
|
489
|
+
3. inspect a generated downstream `.metadata/index.ts` file to confirm current command names and bean full names
|
|
490
|
+
4. confirm the example command beans still demonstrate the described scene patterns
|
|
491
|
+
5. run the docs build for repo-level docs verification:
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
npm run docs:build
|
|
495
|
+
```
|
|
@@ -49,6 +49,12 @@ That is especially valuable for:
|
|
|
49
49
|
|
|
50
50
|
These design principles should influence how code is extended in Zova. For the deeper structural model behind these principles, see [IoC and Beans](/frontend/ioc-and-beans), [Modules and Suites](/frontend/modules-and-suites), and [Module Scope](/frontend/module-scope).
|
|
51
51
|
|
|
52
|
+
If you are approaching Zova from a Vue-first background, also read:
|
|
53
|
+
|
|
54
|
+
- [Reading Zova for Vue Developers](/frontend/reading-zova-for-vue-developers)
|
|
55
|
+
- [Zova Reactivity Under the Hood](/frontend/zova-reactivity-under-the-hood)
|
|
56
|
+
- [Zova Source Reading Map](/frontend/zova-source-reading-map)
|
|
57
|
+
|
|
52
58
|
- do not rewrite Zova code toward generic Vue habits automatically
|
|
53
59
|
- do not assume `ref.value`-style patterns are the desired end state
|
|
54
60
|
- prefer existing model, IOC, and AOP conventions when extending code
|