cxtms 1.9.13
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 +384 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4784 -0
- package/dist/cli.js.map +1 -0
- package/dist/extractUtils.d.ts +11 -0
- package/dist/extractUtils.d.ts.map +1 -0
- package/dist/extractUtils.js +19 -0
- package/dist/extractUtils.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/schemaLoader.d.ts +17 -0
- package/dist/utils/schemaLoader.d.ts.map +1 -0
- package/dist/utils/schemaLoader.js +134 -0
- package/dist/utils/schemaLoader.js.map +1 -0
- package/dist/validator.d.ts +72 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +432 -0
- package/dist/validator.js.map +1 -0
- package/dist/workflowValidator.d.ts +103 -0
- package/dist/workflowValidator.d.ts.map +1 -0
- package/dist/workflowValidator.js +753 -0
- package/dist/workflowValidator.js.map +1 -0
- package/package.json +51 -0
- package/schemas/actions/all.json +27 -0
- package/schemas/actions/clipboard.json +46 -0
- package/schemas/actions/confirm.json +21 -0
- package/schemas/actions/consoleLog.json +16 -0
- package/schemas/actions/dialog.json +25 -0
- package/schemas/actions/fileDownload.json +16 -0
- package/schemas/actions/forEach.json +31 -0
- package/schemas/actions/if.json +12 -0
- package/schemas/actions/mutation.json +25 -0
- package/schemas/actions/navigate.json +18 -0
- package/schemas/actions/navigateBack.json +22 -0
- package/schemas/actions/navigateBackOrClose.json +21 -0
- package/schemas/actions/notification.json +19 -0
- package/schemas/actions/openBarcodeScanner.json +104 -0
- package/schemas/actions/query.json +32 -0
- package/schemas/actions/refresh.json +13 -0
- package/schemas/actions/resetDirtyState.json +22 -0
- package/schemas/actions/setFields.json +21 -0
- package/schemas/actions/setStore.json +13 -0
- package/schemas/actions/validateForm.json +15 -0
- package/schemas/actions/workflow.json +24 -0
- package/schemas/components/README.md +147 -0
- package/schemas/components/appComponent.json +58 -0
- package/schemas/components/barcodeScanner.json +69 -0
- package/schemas/components/button.json +123 -0
- package/schemas/components/calendar.json +489 -0
- package/schemas/components/card.json +176 -0
- package/schemas/components/collection.json +54 -0
- package/schemas/components/dataGrid.json +119 -0
- package/schemas/components/datasource.json +151 -0
- package/schemas/components/dropdown.json +57 -0
- package/schemas/components/field-collection.json +618 -0
- package/schemas/components/field.json +265 -0
- package/schemas/components/form.json +234 -0
- package/schemas/components/index.json +71 -0
- package/schemas/components/layout.json +69 -0
- package/schemas/components/module.json +167 -0
- package/schemas/components/navDropdown.json +36 -0
- package/schemas/components/navbar.json +78 -0
- package/schemas/components/navbarItem.json +28 -0
- package/schemas/components/navbarLink.json +36 -0
- package/schemas/components/row.json +31 -0
- package/schemas/components/slot.json +30 -0
- package/schemas/components/tab.json +34 -0
- package/schemas/components/tabs.json +35 -0
- package/schemas/components/timeline.json +172 -0
- package/schemas/components/timelineGrid.json +328 -0
- package/schemas/fields/README.md +66 -0
- package/schemas/fields/attachment.json +156 -0
- package/schemas/fields/autocomplete-googleplaces.json +130 -0
- package/schemas/fields/checkbox.json +82 -0
- package/schemas/fields/date.json +88 -0
- package/schemas/fields/datetime.json +75 -0
- package/schemas/fields/email.json +75 -0
- package/schemas/fields/index.json +53 -0
- package/schemas/fields/number.json +91 -0
- package/schemas/fields/password.json +70 -0
- package/schemas/fields/radio.json +94 -0
- package/schemas/fields/rangedatetime.json +56 -0
- package/schemas/fields/select-async.json +334 -0
- package/schemas/fields/select.json +115 -0
- package/schemas/fields/tel.json +79 -0
- package/schemas/fields/text.json +86 -0
- package/schemas/fields/textarea.json +95 -0
- package/schemas/fields/time.json +91 -0
- package/schemas/fields/url.json +74 -0
- package/schemas/schema.graphql +12248 -0
- package/schemas/schemas.json +610 -0
- package/schemas/workflows/activity.json +96 -0
- package/schemas/workflows/common/condition.json +48 -0
- package/schemas/workflows/common/expression.json +76 -0
- package/schemas/workflows/common/mapping.json +173 -0
- package/schemas/workflows/common/step.json +38 -0
- package/schemas/workflows/flow/aggregation.json +44 -0
- package/schemas/workflows/flow/entity.json +129 -0
- package/schemas/workflows/flow/state.json +105 -0
- package/schemas/workflows/flow/transition.json +143 -0
- package/schemas/workflows/input.json +122 -0
- package/schemas/workflows/output.json +61 -0
- package/schemas/workflows/schedule.json +26 -0
- package/schemas/workflows/tasks/accounting-transaction.json +95 -0
- package/schemas/workflows/tasks/action-event.json +65 -0
- package/schemas/workflows/tasks/all.json +152 -0
- package/schemas/workflows/tasks/appmodule.json +56 -0
- package/schemas/workflows/tasks/attachment.json +97 -0
- package/schemas/workflows/tasks/authentication.json +86 -0
- package/schemas/workflows/tasks/caching.json +68 -0
- package/schemas/workflows/tasks/charge.json +92 -0
- package/schemas/workflows/tasks/commodity.json +92 -0
- package/schemas/workflows/tasks/contact-address.json +72 -0
- package/schemas/workflows/tasks/contact-payment-method.json +72 -0
- package/schemas/workflows/tasks/contact.json +82 -0
- package/schemas/workflows/tasks/csv.json +81 -0
- package/schemas/workflows/tasks/document-render.json +105 -0
- package/schemas/workflows/tasks/document-send.json +84 -0
- package/schemas/workflows/tasks/edi.json +157 -0
- package/schemas/workflows/tasks/email-send.json +110 -0
- package/schemas/workflows/tasks/error.json +72 -0
- package/schemas/workflows/tasks/export.json +90 -0
- package/schemas/workflows/tasks/filetransfer.json +102 -0
- package/schemas/workflows/tasks/flow-transition.json +68 -0
- package/schemas/workflows/tasks/foreach.json +69 -0
- package/schemas/workflows/tasks/generic.json +47 -0
- package/schemas/workflows/tasks/graphql.json +78 -0
- package/schemas/workflows/tasks/httpRequest.json +161 -0
- package/schemas/workflows/tasks/import.json +64 -0
- package/schemas/workflows/tasks/inventory.json +67 -0
- package/schemas/workflows/tasks/job.json +88 -0
- package/schemas/workflows/tasks/log.json +73 -0
- package/schemas/workflows/tasks/map.json +58 -0
- package/schemas/workflows/tasks/movement.json +54 -0
- package/schemas/workflows/tasks/note.json +59 -0
- package/schemas/workflows/tasks/number.json +65 -0
- package/schemas/workflows/tasks/order-tracking-event.json +109 -0
- package/schemas/workflows/tasks/order.json +139 -0
- package/schemas/workflows/tasks/payment.json +85 -0
- package/schemas/workflows/tasks/pdf-document.json +60 -0
- package/schemas/workflows/tasks/postal-codes.json +92 -0
- package/schemas/workflows/tasks/resolve-timezone.json +65 -0
- package/schemas/workflows/tasks/setVariable.json +76 -0
- package/schemas/workflows/tasks/switch.json +75 -0
- package/schemas/workflows/tasks/template.json +73 -0
- package/schemas/workflows/tasks/tracking-event.json +137 -0
- package/schemas/workflows/tasks/transmission.json +185 -0
- package/schemas/workflows/tasks/unzip-file.json +68 -0
- package/schemas/workflows/tasks/user.json +70 -0
- package/schemas/workflows/tasks/validation.json +99 -0
- package/schemas/workflows/tasks/while.json +53 -0
- package/schemas/workflows/tasks/workflow-execute.json +82 -0
- package/schemas/workflows/trigger.json +90 -0
- package/schemas/workflows/variable.json +46 -0
- package/schemas/workflows/workflow.json +335 -0
- package/scripts/postinstall.js +291 -0
- package/scripts/setup-vscode.js +80 -0
- package/skills/cxtms-developer/SKILL.md +118 -0
- package/skills/cxtms-developer/ref-cli-auth.md +120 -0
- package/skills/cxtms-developer/ref-entity-accounting.md +180 -0
- package/skills/cxtms-developer/ref-entity-commodity.md +239 -0
- package/skills/cxtms-developer/ref-entity-contact.md +163 -0
- package/skills/cxtms-developer/ref-entity-geography.md +154 -0
- package/skills/cxtms-developer/ref-entity-job.md +77 -0
- package/skills/cxtms-developer/ref-entity-notification.md +85 -0
- package/skills/cxtms-developer/ref-entity-order-sub.md +160 -0
- package/skills/cxtms-developer/ref-entity-order.md +183 -0
- package/skills/cxtms-developer/ref-entity-organization.md +41 -0
- package/skills/cxtms-developer/ref-entity-rate.md +182 -0
- package/skills/cxtms-developer/ref-entity-shared.md +176 -0
- package/skills/cxtms-developer/ref-entity-warehouse.md +115 -0
- package/skills/cxtms-developer/ref-graphql-query.md +309 -0
- package/skills/cxtms-module-builder/SKILL.md +477 -0
- package/skills/cxtms-module-builder/ref-components-data.md +293 -0
- package/skills/cxtms-module-builder/ref-components-display.md +411 -0
- package/skills/cxtms-module-builder/ref-components-forms.md +369 -0
- package/skills/cxtms-module-builder/ref-components-interactive.md +317 -0
- package/skills/cxtms-module-builder/ref-components-layout.md +390 -0
- package/skills/cxtms-module-builder/ref-components-specialized.md +477 -0
- package/skills/cxtms-workflow-builder/SKILL.md +438 -0
- package/skills/cxtms-workflow-builder/ref-accounting.md +66 -0
- package/skills/cxtms-workflow-builder/ref-communication.md +169 -0
- package/skills/cxtms-workflow-builder/ref-entity.md +342 -0
- package/skills/cxtms-workflow-builder/ref-expressions-ncalc.md +128 -0
- package/skills/cxtms-workflow-builder/ref-expressions-template.md +161 -0
- package/skills/cxtms-workflow-builder/ref-filetransfer.md +80 -0
- package/skills/cxtms-workflow-builder/ref-flow.md +210 -0
- package/skills/cxtms-workflow-builder/ref-other.md +157 -0
- package/skills/cxtms-workflow-builder/ref-query.md +105 -0
- package/skills/cxtms-workflow-builder/ref-utilities.md +417 -0
- package/templates/module-configuration.yaml +44 -0
- package/templates/module-form.yaml +152 -0
- package/templates/module-grid.yaml +229 -0
- package/templates/module-select.yaml +139 -0
- package/templates/module.yaml +84 -0
- package/templates/workflow-api-tracking.yaml +189 -0
- package/templates/workflow-basic.yaml +76 -0
- package/templates/workflow-document.yaml +155 -0
- package/templates/workflow-entity-trigger.yaml +90 -0
- package/templates/workflow-ftp-edi.yaml +158 -0
- package/templates/workflow-ftp-tracking.yaml +161 -0
- package/templates/workflow-mcp-tool.yaml +112 -0
- package/templates/workflow-public-api.yaml +135 -0
- package/templates/workflow-scheduled-execute.yaml +75 -0
- package/templates/workflow-scheduled.yaml +125 -0
- package/templates/workflow-utility.yaml +96 -0
- package/templates/workflow-webhook.yaml +128 -0
- package/templates/workflow.yaml +140 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cxtms-module-builder
|
|
3
|
+
description: >
|
|
4
|
+
Works with CXTMS app module YAML files — creates, modifies, fixes, validates, and deploys UI screens, forms, grids, and routes.
|
|
5
|
+
Use when the user asks to create, modify, or fix a module YAML file, references *-module.yaml files, or asks about UI components/forms/grids/routes in a CX project.
|
|
6
|
+
Not for workflow YAML files, TypeScript code, or non-YAML tasks.
|
|
7
|
+
argument-hint: <description of what to build>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are a CargoXplorer module YAML builder. You generate schema-valid YAML for CX app modules — UI screens, forms, data grids, routes, and components. All output must conform to the JSON schemas in `.cx-schema/`.
|
|
11
|
+
|
|
12
|
+
**IMPORTANT — use `cxtms` for all module operations:**
|
|
13
|
+
- **Scaffold**: `npx cxtms create module <name> --template <template>` — generates a schema-valid YAML file. ALWAYS run this first, then read the generated file, then customize. Do NOT write YAML from scratch or copy templates manually.
|
|
14
|
+
- **Scaffold with fields**: `npx cxtms create module <name> --template <template> --options '<json>'`
|
|
15
|
+
- **Validate**: `npx cxtms <file.yaml>` — run after every change
|
|
16
|
+
- **Schema lookup**: `npx cxtms schema <component>` — e.g., `cxtms schema form`, `cxtms schema dataGrid`
|
|
17
|
+
- **Examples**: `npx cxtms example <component>` — show example YAML
|
|
18
|
+
- **List schemas**: `npx cxtms list`
|
|
19
|
+
- **Extract**: `npx cxtms extract <source> <component> --to <target>` — move components between modules
|
|
20
|
+
- **Feature folder**: `npx cxtms create module <name> --template <template> --feature <feature-name>`
|
|
21
|
+
- **Deploy to server**: `npx cxtms appmodule deploy <file.yaml> --org <id>` — creates or updates module on the CX server
|
|
22
|
+
- **Undeploy from server**: `npx cxtms appmodule undeploy <appModuleId> --org <id>` — removes a module by UUID
|
|
23
|
+
- **Publish all**: `npx cxtms publish [--feature <name>] --org <id>` — deploy all modules and workflows to the server
|
|
24
|
+
|
|
25
|
+
## Generation Workflow
|
|
26
|
+
|
|
27
|
+
### Step 1: Scaffold via CLI — MANDATORY
|
|
28
|
+
|
|
29
|
+
**You MUST run `cxtms create module` to generate the initial file.** Do not skip this step. Do not write YAML from scratch. Do not read template files and copy them manually. The CLI generates correct UUIDs, file paths, and structure.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx cxtms create module <name> --template <template>
|
|
33
|
+
npx cxtms create module <name> --template <template> --options '<json>'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Template | Use Case |
|
|
37
|
+
|----------|----------|
|
|
38
|
+
| `default` | Generic module with form |
|
|
39
|
+
| `form` | Entity create/edit form |
|
|
40
|
+
| `configuration` | Settings/config screen |
|
|
41
|
+
| `grid` | List/table view |
|
|
42
|
+
| `select` | Reusable async select |
|
|
43
|
+
|
|
44
|
+
### Step 2: Read the generated file
|
|
45
|
+
|
|
46
|
+
### Step 3: Customize for the use case
|
|
47
|
+
|
|
48
|
+
**All templates** — update module name, component names, entity fields, permissions, GraphQL queries/mutations.
|
|
49
|
+
|
|
50
|
+
**`form`** — update form fields, validationSchema, query/mutation field lists. Add tabs for grouped fields. Customize toolbar buttons. Update dirtyGuard messages.
|
|
51
|
+
|
|
52
|
+
**`configuration`** — update form fields, initialValues.append defaults, validationSchema rules, query/mutation field lists. Add tabs for grouped settings.
|
|
53
|
+
|
|
54
|
+
**`grid`** — update view columns, filters, entity fields. Add/remove views. Customize dotsMenu actions. Configure toolbar with export/import actions.
|
|
55
|
+
|
|
56
|
+
**`select`** — update `valueFieldName`, `itemLabelTemplate`, `itemValueTemplate`. Customize GraphQL query fields and variables. Set `navigateActionPermission`. Configure `dropDownToolbar` create button dialog.
|
|
57
|
+
|
|
58
|
+
### Step 4: Validate
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx cxtms <generated-file.yaml>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## --options Flag
|
|
67
|
+
|
|
68
|
+
Customize generated modules at scaffold time with `--options`. Accepts inline JSON or a file path.
|
|
69
|
+
|
|
70
|
+
### Field Array Format (all templates)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx cxtms create module "Tariff" --template grid --options '[
|
|
74
|
+
{"name": "code", "type": "text", "label": "Tariff Code", "required": true},
|
|
75
|
+
{"name": "rate", "type": "number", "label": "Rate %"},
|
|
76
|
+
{"name": "effectiveDate", "type": "date"},
|
|
77
|
+
{"name": "isActive", "type": "checkbox", "label": "Active"}
|
|
78
|
+
]'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Object Format (with entityName)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx cxtms create module "Country" --template select --options '{
|
|
85
|
+
"entityName": "Country",
|
|
86
|
+
"fields": [
|
|
87
|
+
{"name": "countryCode", "type": "text", "label": "Country Code"},
|
|
88
|
+
{"name": "countryName", "type": "text", "label": "Country Name"}
|
|
89
|
+
]
|
|
90
|
+
}'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Field Properties
|
|
94
|
+
|
|
95
|
+
| Property | Type | Description |
|
|
96
|
+
|----------|------|-------------|
|
|
97
|
+
| `name` | string | **Required.** Field name (camelCase) |
|
|
98
|
+
| `type` | string | **Required.** text, number, checkbox, date, select, select-async, textarea, email |
|
|
99
|
+
| `label` | string | Display label (auto-generated from name if omitted) |
|
|
100
|
+
| `required` | boolean | Add to validationSchema as required |
|
|
101
|
+
| `default` | any | Default value (form/configuration template: added to initialValues.append) |
|
|
102
|
+
|
|
103
|
+
### What --options Customizes Per Template
|
|
104
|
+
|
|
105
|
+
| Template | Fields | Entity | Queries |
|
|
106
|
+
|----------|--------|--------|---------|
|
|
107
|
+
| `form` | Form children, validationSchema, initialValues.append | Entity field definitions | GraphQL query field lists (preserves `id`) |
|
|
108
|
+
| `configuration` | Form children, validationSchema, initialValues.append | Entity field definitions | GraphQL query field lists |
|
|
109
|
+
| `grid` | View columns (with showAs by type), entity fields | Entity name + rootEntityName | — |
|
|
110
|
+
| `select` | Entity fields, itemLabelTemplate | Entity name | GraphQL query field lists |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Extract Command
|
|
115
|
+
|
|
116
|
+
Move or copy a component (and its routes) from one module into another. Useful for splitting large modules or sharing components.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cxtms extract <source-file> <component-name> --to <target-file>
|
|
120
|
+
cxtms extract <source-file> <component-name> --to <target-file> --copy
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Flags
|
|
124
|
+
- `--to <file>` — target module file (required)
|
|
125
|
+
- `--copy` — copy instead of move (source keeps the component, target gets a higher-priority copy)
|
|
126
|
+
|
|
127
|
+
### What Gets Moved/Copied
|
|
128
|
+
- The component matching the exact `name` field
|
|
129
|
+
- Any routes whose `component` field matches the component name
|
|
130
|
+
- Permissions and entities are **NOT** moved
|
|
131
|
+
|
|
132
|
+
### Examples
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Move a component to a new file (creates module scaffold automatically)
|
|
136
|
+
npx cxtms extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml
|
|
137
|
+
|
|
138
|
+
# Copy a component (source unchanged, target gets higher priority)
|
|
139
|
+
npx cxtms extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml --copy
|
|
140
|
+
|
|
141
|
+
# Extract to an existing module
|
|
142
|
+
npx cxtms extract modules/main.yaml Dashboard --to modules/dashboard.yaml
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### New Target Scaffold
|
|
146
|
+
When the target file doesn't exist, a new module is created with:
|
|
147
|
+
- `module` name derived from filename (PascalCase)
|
|
148
|
+
- Fresh `appModuleId` (UUID)
|
|
149
|
+
- `application` copied from source
|
|
150
|
+
- Empty `entities` and `permissions` arrays
|
|
151
|
+
|
|
152
|
+
### Workflow
|
|
153
|
+
1. Run `extract` to move the component
|
|
154
|
+
2. Manually move any related permissions/entities if needed
|
|
155
|
+
3. Validate both files: `npx cxtms <source>` and `npx cxtms <target>`
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## On-Demand References
|
|
160
|
+
|
|
161
|
+
**Read these files only when needed for the current task.** Do not load all references upfront.
|
|
162
|
+
|
|
163
|
+
### Entity Field Reference (cxtms-developer)
|
|
164
|
+
|
|
165
|
+
!cat skills/cxtms-developer/SKILL.md
|
|
166
|
+
|
|
167
|
+
### Component Directory
|
|
168
|
+
|
|
169
|
+
Read the relevant category ref file when building specific component types:
|
|
170
|
+
|
|
171
|
+
| Category | Components | File |
|
|
172
|
+
|----------|-----------|------|
|
|
173
|
+
| **Layout & Structure** | `layout`, `row`, `col`, `header`, `tabs`, `toolbar`, `card`, `line`, `slot` | `skills/cxtms-module-builder/ref-components-layout.md` |
|
|
174
|
+
| **Forms & Input** | `form`, `field`, `field-collection`, `barcodeScanner` | `skills/cxtms-module-builder/ref-components-forms.md` |
|
|
175
|
+
| **Data Display** | `dataGrid`, `text`, `markup`, `badge`, `icon`, `image`, `photo`, `summary`, `diff`, `viewer`, `embed` | `skills/cxtms-module-builder/ref-components-display.md` |
|
|
176
|
+
| **Interactive & Nav** | `button`, `dropdown`, `menuButton`, `link`, `redirect`, `navbar`, `navbarItem`, `navbarLink`, `navDropdown` | `skills/cxtms-module-builder/ref-components-interactive.md` |
|
|
177
|
+
| **Data & Collections** | `collection`, `list`, `listItem`, `datasource`, `script` | `skills/cxtms-module-builder/ref-components-data.md` |
|
|
178
|
+
| **Specialized** | `calendar`, `notes`, `dashboard`, `dashboard-widget`, `widget`, `timeline`, `timeline-grid`, `oauth2` | `skills/cxtms-module-builder/ref-components-specialized.md` |
|
|
179
|
+
|
|
180
|
+
### Templates
|
|
181
|
+
|
|
182
|
+
Read the relevant template after scaffolding to understand the generated structure:
|
|
183
|
+
|
|
184
|
+
| Template | File |
|
|
185
|
+
|----------|------|
|
|
186
|
+
| default | `templates/module.yaml` |
|
|
187
|
+
| form | `templates/module-form.yaml` |
|
|
188
|
+
| configuration | `templates/module-configuration.yaml` |
|
|
189
|
+
| grid | `templates/module-grid.yaml` |
|
|
190
|
+
| select | `templates/module-select.yaml` |
|
|
191
|
+
|
|
192
|
+
### JSON Schemas
|
|
193
|
+
|
|
194
|
+
Read schema files from `.cx-schema/` only when debugging validation errors:
|
|
195
|
+
- `schemas.json` — main schema definitions
|
|
196
|
+
- `components/<type>.json` — component schemas (layout, form, dataGrid, field, button, tabs, card, calendar, collection, appComponent, slot, module)
|
|
197
|
+
- `fields/<type>.json` — field schemas (text, select, select-async)
|
|
198
|
+
- `actions/<type>.json` — action schemas (navigate, mutation, dialog, all)
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
# Module YAML Reference
|
|
203
|
+
|
|
204
|
+
## Top-Level Structure
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
module:
|
|
208
|
+
name: "<ModuleName>" # PascalCase identifier
|
|
209
|
+
appModuleId: "<uuid>" # Generate a new UUID v4
|
|
210
|
+
displayName:
|
|
211
|
+
en-US: "Human Readable Name"
|
|
212
|
+
description:
|
|
213
|
+
en-US: "Module description"
|
|
214
|
+
application: "CargoXplorer" # Required
|
|
215
|
+
filePath: "modules/<name>-module.yaml" # File path in repo
|
|
216
|
+
|
|
217
|
+
entities:
|
|
218
|
+
- name: <EntityName>
|
|
219
|
+
entityKind: Order | Contact | OrderEntity | AccountingTransaction | Calendar | CalendarEvent | Other
|
|
220
|
+
extension: false # true if extending existing entity
|
|
221
|
+
displayName: { en-US: "..." }
|
|
222
|
+
fields:
|
|
223
|
+
- name: fieldName
|
|
224
|
+
fieldType: text | number | date | boolean | ...
|
|
225
|
+
displayName: { en-US: "..." }
|
|
226
|
+
isCustomField: false
|
|
227
|
+
props:
|
|
228
|
+
allowOrderBy: true
|
|
229
|
+
allowFilter: true
|
|
230
|
+
filter: # Optional filter selector
|
|
231
|
+
component: "Contacts/Select"
|
|
232
|
+
props:
|
|
233
|
+
filter: "contactType: Customer"
|
|
234
|
+
options: { baseName: "contactId" }
|
|
235
|
+
|
|
236
|
+
permissions:
|
|
237
|
+
- name: "ModuleName/Read" # PascalCase with slashes
|
|
238
|
+
displayName: { en-US: "..." }
|
|
239
|
+
roles: ["Admin", "Manager"]
|
|
240
|
+
|
|
241
|
+
configurations: # Optional: org-level config definitions
|
|
242
|
+
- configName: "apps.myFeature" # Unique config key
|
|
243
|
+
displayName: { en-US: "My Feature Settings" }
|
|
244
|
+
description: { en-US: "Configure my feature" }
|
|
245
|
+
component: "ModuleName/ConfigComponent" # Component that renders the config UI
|
|
246
|
+
defaultValue: # Optional default values
|
|
247
|
+
enabled: true
|
|
248
|
+
limit: 100
|
|
249
|
+
|
|
250
|
+
routes:
|
|
251
|
+
- name: "routeName"
|
|
252
|
+
path: "/module-path" # Supports :params
|
|
253
|
+
component: ComponentName # References component name
|
|
254
|
+
platforms: [web, mobile] # Optional, defaults to both
|
|
255
|
+
props:
|
|
256
|
+
title: { en-US: "..." }
|
|
257
|
+
icon: "icon-name"
|
|
258
|
+
permission: "permission-name"
|
|
259
|
+
|
|
260
|
+
components:
|
|
261
|
+
- name: "ModuleName/ComponentName" # Pattern: Module/Component
|
|
262
|
+
displayName: { en-US: "..." }
|
|
263
|
+
permissions: "permission-name" # String or array
|
|
264
|
+
layout:
|
|
265
|
+
component: layout # Root must be a component
|
|
266
|
+
# ... component tree
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Action Types
|
|
270
|
+
|
|
271
|
+
Actions are used in event handlers (onClick, onSubmit, etc.) as arrays:
|
|
272
|
+
|
|
273
|
+
```yaml
|
|
274
|
+
onClick:
|
|
275
|
+
- navigate: "~/path/{{ id }}" # Navigate to route
|
|
276
|
+
- navigateBack: { fallback: "/home" } # Go back in history
|
|
277
|
+
- navigateBackOrClose: { fallback: "/home" } # Go back or close dialog
|
|
278
|
+
- refresh: "componentName" # Refresh a component
|
|
279
|
+
- notification: { message: { en-US: "Saved!" }, type: success } # success|error|warning|info
|
|
280
|
+
- confirm: { title: { en-US: "Delete?" }, message: { en-US: "Are you sure?" } }
|
|
281
|
+
- mutation:
|
|
282
|
+
command: "mutation M($input: MInput!) { m(input: $input) { result } }"
|
|
283
|
+
variables: { input: "{{ form }}" }
|
|
284
|
+
onSuccess: [...]
|
|
285
|
+
onError: [...]
|
|
286
|
+
- query:
|
|
287
|
+
command: "query Q($id: ID!) { entity(id: $id) { id name } }"
|
|
288
|
+
variables: { id: "{{ entityId }}" }
|
|
289
|
+
onSuccess: [...]
|
|
290
|
+
onError: [...]
|
|
291
|
+
- setFields: { "fieldName": "{{ value }}" } # Set form field values
|
|
292
|
+
- setStore: { "key": "{{ value }}" } # Set store values
|
|
293
|
+
- validateForm: {} # Trigger form validation
|
|
294
|
+
- dialog:
|
|
295
|
+
name: "dialogName"
|
|
296
|
+
props: { title: { en-US: "Title" } }
|
|
297
|
+
component: { component: "Module/Component" }
|
|
298
|
+
onClose: [...]
|
|
299
|
+
- workflow:
|
|
300
|
+
workflowId: "<uuid>"
|
|
301
|
+
inputs: { key: "value" }
|
|
302
|
+
onSuccess: [...]
|
|
303
|
+
onError: [...]
|
|
304
|
+
- fileDownload: { url: "...", fileName: "..." }
|
|
305
|
+
- forEach:
|
|
306
|
+
items: "{{ selectedItems }}"
|
|
307
|
+
item: "currentItem"
|
|
308
|
+
actions: [...]
|
|
309
|
+
- if: "{{ condition }}"
|
|
310
|
+
then: [...]
|
|
311
|
+
else: [...]
|
|
312
|
+
- consoleLog: { message: "debug info" }
|
|
313
|
+
- openBarcodeScanner: { onScan: [...] }
|
|
314
|
+
- resetDirtyState: {}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Common Patterns
|
|
318
|
+
|
|
319
|
+
### Localized strings
|
|
320
|
+
```yaml
|
|
321
|
+
displayName:
|
|
322
|
+
en-US: "English text"
|
|
323
|
+
es-ES: "Spanish text"
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Template expressions
|
|
327
|
+
```yaml
|
|
328
|
+
value: "{{ fieldName }}" # Simple variable
|
|
329
|
+
value: "{{ format date L }}" # Format helper
|
|
330
|
+
value: "{{ number quantity }}" # Type cast
|
|
331
|
+
value: "{{ eval items.length > 0 }}" # JavaScript expression
|
|
332
|
+
isHidden: "{{ eval !canEdit }}" # Conditional visibility
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Permissions
|
|
336
|
+
```yaml
|
|
337
|
+
permission: "ModuleName/Read" # Single string (PascalCase/Action)
|
|
338
|
+
permissions: # Array
|
|
339
|
+
- "ModuleName/Read"
|
|
340
|
+
- "ModuleName/Update"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Async Select Component Pattern
|
|
344
|
+
|
|
345
|
+
Reusable select components (e.g., `Countries/Select`, `Ports/Select`) follow this structure:
|
|
346
|
+
|
|
347
|
+
```yaml
|
|
348
|
+
- name: Entity/Select
|
|
349
|
+
displayName: { en-US: "Select Entity" }
|
|
350
|
+
platforms: [web, mobile]
|
|
351
|
+
layout:
|
|
352
|
+
component: field
|
|
353
|
+
name: entityId # Value binding field name
|
|
354
|
+
props:
|
|
355
|
+
type: select-async
|
|
356
|
+
label: { en-US: "Entity" }
|
|
357
|
+
options:
|
|
358
|
+
valueFieldName: "entityId" # Which result field holds the value
|
|
359
|
+
itemLabelTemplate: "{{name}}" # Handlebars template for labels
|
|
360
|
+
itemValueTemplate: "{{entityId}}" # Handlebars template for values
|
|
361
|
+
navigateActionPermission: "Entity/Update"
|
|
362
|
+
searchQuery: # References list query below
|
|
363
|
+
name: getEntities
|
|
364
|
+
path: entities.items
|
|
365
|
+
params:
|
|
366
|
+
search: "{{ string search }}"
|
|
367
|
+
take: "{{ number pageSize }}"
|
|
368
|
+
skip: "{{ number skip }}"
|
|
369
|
+
filter: "{{ string filter }}"
|
|
370
|
+
valueQuery: # References single-item query below
|
|
371
|
+
name: getEntity
|
|
372
|
+
path: entity
|
|
373
|
+
params:
|
|
374
|
+
entityId: "{{entityId}}"
|
|
375
|
+
allowSearch: true
|
|
376
|
+
allowClear: true
|
|
377
|
+
dropDownToolbar: # Create button in dropdown
|
|
378
|
+
- component: button
|
|
379
|
+
name: createBtn
|
|
380
|
+
props:
|
|
381
|
+
label: { en-US: "Create Entity" }
|
|
382
|
+
icon: plus
|
|
383
|
+
onClick:
|
|
384
|
+
- dialog:
|
|
385
|
+
component: Entity/CreateEntity
|
|
386
|
+
onClose:
|
|
387
|
+
- selectValue: "{{ result.entityId }}"
|
|
388
|
+
queries:
|
|
389
|
+
- name: getEntities # Paginated search query
|
|
390
|
+
query:
|
|
391
|
+
command: >-
|
|
392
|
+
query($organizationId: Int!, $filter: String!, $search: String!, $take: Int!, $skip: Int!) {
|
|
393
|
+
entities(...) { items { entityId name } totalCount }
|
|
394
|
+
}
|
|
395
|
+
variables: { organizationId: "{{number organizationId}}", ... }
|
|
396
|
+
- name: getEntity # Single-value lookup query
|
|
397
|
+
query:
|
|
398
|
+
command: >-
|
|
399
|
+
query($organizationId: Int!, $entityId: Int!) {
|
|
400
|
+
entity(...) { entityId name }
|
|
401
|
+
}
|
|
402
|
+
variables: { entityId: "{{number entityId}}" }
|
|
403
|
+
onEditClick: # Edit action on selected item
|
|
404
|
+
- dialog:
|
|
405
|
+
component: { layout: { component: layout, children: [{ component: Entity/UpdateEntity }] } }
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Server Module Commands
|
|
411
|
+
|
|
412
|
+
Deploy, undeploy, and release commands are listed in the CLI section at the top of this file. For authentication setup (login, PAT tokens, org management): see [cxtms-developer/ref-cli-auth.md](skills/cxtms-developer/ref-cli-auth.md)
|
|
413
|
+
|
|
414
|
+
### Releasing App to GitHub
|
|
415
|
+
|
|
416
|
+
Use `app release` to release modified modules and workflows from the CX server to a GitHub repository. This creates a branch and pull request — it does NOT push directly to the target branch.
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Release all unpublished changes to GitHub (creates a PR) — message is required
|
|
420
|
+
npx cxtms app release -m "Add warehouse locations module"
|
|
421
|
+
|
|
422
|
+
# Release specific modules and/or workflows by YAML file
|
|
423
|
+
npx cxtms app release -m "Fix country module" modules/my-module.yaml
|
|
424
|
+
npx cxtms app release -m "Update billing" modules/a.yaml workflows/b.yaml
|
|
425
|
+
|
|
426
|
+
# Force release all modules and workflows (not just unpublished ones)
|
|
427
|
+
npx cxtms app release -m "Full republish" --force
|
|
428
|
+
|
|
429
|
+
# Release with explicit org
|
|
430
|
+
npx cxtms app release -m "Add warehouse locations module" --org 42
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**What `app release` does:**
|
|
434
|
+
1. Reads `app.yaml` for the `id` (appManifestId), repository, and branch
|
|
435
|
+
2. Increments the app version (patch bump)
|
|
436
|
+
3. Creates a `publish/{app-name}-v{version}-{timestamp}` branch on GitHub
|
|
437
|
+
4. Commits `app.yaml` + selected module/workflow YAML files to the branch
|
|
438
|
+
5. Creates a pull request from the publish branch to the target branch
|
|
439
|
+
6. Marks published modules and workflows as `hasUnpublishedChanges: false`
|
|
440
|
+
|
|
441
|
+
**This is a release-to-git operation** — it commits the current server-side YAML directly to GitHub via the API. No local git repo is involved. The modules and workflows being released are taken from the CX server database, not from local files. The YAML file arguments only identify *which* items to include by their IDs.
|
|
442
|
+
|
|
443
|
+
**Important:** Modules and workflows must be deployed to the TMS server before they can be released. Use `cxtms appmodule deploy` or `cxtms workflow deploy` first, then `cxtms app release` to commit them to GitHub.
|
|
444
|
+
|
|
445
|
+
**Do NOT run `app release` automatically.** Only release when the user explicitly requests it. Releasing creates a branch and PR on GitHub, so it should be done once when all changes are ready — not after every deploy.
|
|
446
|
+
|
|
447
|
+
**Prerequisites:**
|
|
448
|
+
- `app.yaml` must exist with a valid `id` field
|
|
449
|
+
- The app manifest must be installed on the server (`app install` first)
|
|
450
|
+
- The server must have a GitHub token configured for the organization
|
|
451
|
+
- The repository and branch must be set on the app manifest
|
|
452
|
+
|
|
453
|
+
**Related commands:**
|
|
454
|
+
- `npx cxtms app install` — install/refresh app from GitHub into the server
|
|
455
|
+
- `npx cxtms app install --force` — force reinstall even if same version
|
|
456
|
+
- `npx cxtms app install --branch develop` — install from a specific branch
|
|
457
|
+
- `npx cxtms app install --skip-changed` — skip modules with local changes
|
|
458
|
+
- `npx cxtms app list` — list installed app manifests on the server
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
# Generation Rules
|
|
463
|
+
|
|
464
|
+
1. **Always scaffold via `cxtms create module` first** — never write YAML from scratch, never copy templates manually
|
|
465
|
+
2. **Use localized strings** `{ en-US: "..." }` for all user-visible text
|
|
466
|
+
3. **Follow naming conventions**:
|
|
467
|
+
- Module names: PascalCase (e.g., `WarehouseLocations`)
|
|
468
|
+
- Component names: Module/Component pattern (e.g., `WarehouseLocations/List`)
|
|
469
|
+
- Route paths: kebab-case (e.g., `/warehouse-locations`)
|
|
470
|
+
- Permission names: PascalCase with slashes (e.g., `WarehouseLocations/Read`, `System/Contacts/Update`)
|
|
471
|
+
4. **Template expressions** use `{{ expression }}` syntax (double curly braces)
|
|
472
|
+
5. **Include filePath** property pointing to the YAML file location
|
|
473
|
+
6. **Set proper entityKind** when defining entities (Order, Contact, OrderEntity, AccountingTransaction, Calendar, CalendarEvent, Other)
|
|
474
|
+
7. **DataGrid options** requires ALL properties: query, rootEntityName, entityKeys, navigationType, enableDynamicGrid, enableViews, enableSearch, enablePagination, enableColumns, enableFilter, defaultView, onRowClick
|
|
475
|
+
8. **Form component** requires `validationSchema` in props
|
|
476
|
+
9. **Do not change `appModuleId` or `filePath`** — set correctly by CLI scaffold
|
|
477
|
+
10. **Always validate** the final YAML: `npx cxtms <file.yaml>`
|