@cxtms/cx-schema 1.6.5 → 1.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/cx-module/SKILL.md +13 -13
- package/.claude/skills/cx-workflow/SKILL.md +6 -6
- package/dist/cli.js +36 -36
- package/dist/cli.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validator.d.ts +4 -0
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +28 -2
- package/dist/validator.js.map +1 -1
- package/dist/workflowValidator.d.ts +4 -0
- package/dist/workflowValidator.d.ts.map +1 -1
- package/dist/workflowValidator.js +28 -2
- package/dist/workflowValidator.js.map +1 -1
- package/package.json +1 -1
- package/schemas/components/module.json +2 -2
- package/schemas/workflows/workflow.json +0 -4
- package/templates/module-form.yaml +1 -1
- package/templates/module-grid.yaml +1 -1
- package/templates/module-select.yaml +1 -1
- package/templates/module.yaml +1 -1
|
@@ -15,8 +15,8 @@ You are a CargoXplorer module YAML builder. You generate schema-valid YAML for C
|
|
|
15
15
|
- **List schemas**: `npx cx-cli list`
|
|
16
16
|
- **Extract**: `npx cx-cli extract <source> <component> --to <target>` — move components between modules
|
|
17
17
|
- **Feature folder**: `npx cx-cli create module <name> --template <template> --feature <feature-name>`
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
18
|
+
- **Deploy to server**: `npx cx-cli appmodule deploy <file.yaml>` — creates or updates module on the CX server
|
|
19
|
+
- **Undeploy from server**: `npx cx-cli appmodule undeploy <appModuleId>` — removes a module by UUID
|
|
20
20
|
- **Publish all**: `npx cx-cli publish [--feature <name>]` — push all modules and workflows to the server
|
|
21
21
|
|
|
22
22
|
## Generation Workflow
|
|
@@ -209,7 +209,7 @@ module:
|
|
|
209
209
|
description:
|
|
210
210
|
en-US: "Module description"
|
|
211
211
|
application: "CargoXplorer" # Required
|
|
212
|
-
|
|
212
|
+
filePath: "modules/<name>-module.yaml" # File path in repo
|
|
213
213
|
|
|
214
214
|
entities:
|
|
215
215
|
- name: <EntityName>
|
|
@@ -397,24 +397,24 @@ Reusable select components (e.g., `Countries/Select`, `Ports/Select`) follow thi
|
|
|
397
397
|
|
|
398
398
|
## Server Module Commands
|
|
399
399
|
|
|
400
|
-
###
|
|
400
|
+
### Deploy / Undeploy
|
|
401
401
|
|
|
402
402
|
```bash
|
|
403
|
-
#
|
|
404
|
-
npx cx-cli appmodule
|
|
403
|
+
# Deploy a module YAML to the server (creates or updates)
|
|
404
|
+
npx cx-cli appmodule deploy modules/my-module.yaml
|
|
405
405
|
|
|
406
|
-
#
|
|
407
|
-
npx cx-cli appmodule
|
|
406
|
+
# Deploy with explicit org ID
|
|
407
|
+
npx cx-cli appmodule deploy modules/my-module.yaml --org 42
|
|
408
408
|
|
|
409
|
-
#
|
|
410
|
-
npx cx-cli appmodule
|
|
409
|
+
# Undeploy an app module by UUID
|
|
410
|
+
npx cx-cli appmodule undeploy <appModuleId>
|
|
411
411
|
|
|
412
412
|
# Publish all modules and workflows (validates first)
|
|
413
413
|
npx cx-cli publish
|
|
414
414
|
npx cx-cli publish --feature billing
|
|
415
415
|
```
|
|
416
416
|
|
|
417
|
-
|
|
417
|
+
Deploy reads `module.appModuleId` from the YAML, queries the server, and creates or updates accordingly. Requires an active session (`cx-cli login` or PAT token — see cx-core skill).
|
|
418
418
|
|
|
419
419
|
---
|
|
420
420
|
|
|
@@ -428,9 +428,9 @@ Push reads `module.appModuleId` from the YAML, queries the server, and creates o
|
|
|
428
428
|
- Route paths: kebab-case (e.g., `/warehouse-locations`)
|
|
429
429
|
- Permission names: PascalCase with slashes (e.g., `WarehouseLocations/Read`, `System/Contacts/Update`)
|
|
430
430
|
4. **Template expressions** use `{{ expression }}` syntax (double curly braces)
|
|
431
|
-
5. **Include
|
|
431
|
+
5. **Include filePath** property pointing to the YAML file location
|
|
432
432
|
6. **Set proper entityKind** when defining entities (Order, Contact, OrderEntity, AccountingTransaction, Calendar, CalendarEvent, Other)
|
|
433
433
|
7. **DataGrid options** requires ALL properties: query, rootEntityName, entityKeys, navigationType, enableDynamicGrid, enableViews, enableSearch, enablePagination, enableColumns, enableFilter, defaultView, onRowClick
|
|
434
434
|
8. **Form component** requires `validationSchema` in props
|
|
435
|
-
9. **Do not change `appModuleId` or `
|
|
435
|
+
9. **Do not change `appModuleId` or `filePath`** — set correctly by CLI scaffold
|
|
436
436
|
10. **Always validate** the final YAML: `npx cx-cli <file.yaml>`
|
|
@@ -13,8 +13,8 @@ You are a CargoXplorer workflow YAML builder. You generate schema-valid YAML for
|
|
|
13
13
|
- **Examples**: `npx cx-cli example <task>` — show example YAML for a task
|
|
14
14
|
- **List schemas**: `npx cx-cli list --type workflow` — shows all available task schemas in the Tasks section
|
|
15
15
|
- **Feature folder**: `npx cx-cli create workflow <name> --template <template> --feature <feature-name>`
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
16
|
+
- **Deploy to server**: `npx cx-cli workflow deploy <file.yaml>` — creates or updates workflow on the CX server
|
|
17
|
+
- **Undeploy from server**: `npx cx-cli workflow undeploy <workflowId>` — removes a workflow by UUID
|
|
18
18
|
- **Execute**: `npx cx-cli workflow execute <workflowId|file.yaml> [--vars '<json>']` — trigger a workflow execution
|
|
19
19
|
- **List logs**: `npx cx-cli workflow logs <workflowId|file.yaml> [--from YYYY-MM-DD] [--to YYYY-MM-DD]` — list executions with log availability
|
|
20
20
|
- **Download log**: `npx cx-cli workflow log <executionId> [--json] [--console] [--output <file>]` — download execution log
|
|
@@ -315,21 +315,21 @@ Implicit variable: `iteration` (zero-based).
|
|
|
315
315
|
|
|
316
316
|
## Server Workflow Commands
|
|
317
317
|
|
|
318
|
-
###
|
|
318
|
+
### Deploy / Undeploy
|
|
319
319
|
|
|
320
320
|
```bash
|
|
321
321
|
# Push a workflow YAML to the server (creates or updates)
|
|
322
|
-
npx cx-cli workflow
|
|
322
|
+
npx cx-cli workflow deploy workflows/my-workflow.yaml
|
|
323
323
|
|
|
324
324
|
# Delete a workflow by UUID
|
|
325
|
-
npx cx-cli workflow
|
|
325
|
+
npx cx-cli workflow undeploy <workflowId>
|
|
326
326
|
|
|
327
327
|
# Publish all modules and workflows (validates first)
|
|
328
328
|
npx cx-cli publish
|
|
329
329
|
npx cx-cli publish --feature billing
|
|
330
330
|
```
|
|
331
331
|
|
|
332
|
-
|
|
332
|
+
Deploy reads `workflow.workflowId` from the YAML, queries the server, and creates or updates accordingly. Requires an active session (`cx-cli login` or PAT token — see cx-core skill).
|
|
333
333
|
|
|
334
334
|
### Execute
|
|
335
335
|
|
package/dist/cli.js
CHANGED
|
@@ -114,8 +114,8 @@ ${chalk_1.default.bold.yellow('COMMANDS:')}
|
|
|
114
114
|
${chalk_1.default.green('logout')} Logout from a CX environment
|
|
115
115
|
${chalk_1.default.green('pat')} Manage personal access tokens (create, list, revoke)
|
|
116
116
|
${chalk_1.default.green('orgs')} List, select, or set active organization
|
|
117
|
-
${chalk_1.default.green('appmodule')} Manage app modules on a CX server (
|
|
118
|
-
${chalk_1.default.green('workflow')} Manage workflows on a CX server (
|
|
117
|
+
${chalk_1.default.green('appmodule')} Manage app modules on a CX server (deploy, undeploy)
|
|
118
|
+
${chalk_1.default.green('workflow')} Manage workflows on a CX server (deploy, undeploy, execute, logs, log)
|
|
119
119
|
${chalk_1.default.green('publish')} Publish all modules and workflows to a CX server
|
|
120
120
|
${chalk_1.default.green('schema')} Show JSON schema for a component or task
|
|
121
121
|
${chalk_1.default.green('example')} Show example YAML for a component or task
|
|
@@ -245,21 +245,21 @@ ${chalk_1.default.bold.yellow('ORG COMMANDS:')}
|
|
|
245
245
|
${chalk_1.default.cyan(`${PROGRAM_NAME} orgs use`)}
|
|
246
246
|
|
|
247
247
|
${chalk_1.default.bold.yellow('APPMODULE COMMANDS:')}
|
|
248
|
-
${chalk_1.default.gray('#
|
|
249
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule
|
|
248
|
+
${chalk_1.default.gray('# Deploy a module YAML to the server (creates or updates)')}
|
|
249
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule deploy modules/my-module.yaml`)}
|
|
250
250
|
|
|
251
|
-
${chalk_1.default.gray('#
|
|
252
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule
|
|
251
|
+
${chalk_1.default.gray('# Deploy with explicit org ID')}
|
|
252
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule deploy modules/my-module.yaml --org 42`)}
|
|
253
253
|
|
|
254
|
-
${chalk_1.default.gray('#
|
|
255
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule
|
|
254
|
+
${chalk_1.default.gray('# Undeploy an app module by UUID')}
|
|
255
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} appmodule undeploy <appModuleId>`)}
|
|
256
256
|
|
|
257
257
|
${chalk_1.default.bold.yellow('WORKFLOW COMMANDS:')}
|
|
258
|
-
${chalk_1.default.gray('#
|
|
259
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow
|
|
258
|
+
${chalk_1.default.gray('# Deploy a workflow YAML to the server (creates or updates)')}
|
|
259
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow deploy workflows/my-workflow.yaml`)}
|
|
260
260
|
|
|
261
|
-
${chalk_1.default.gray('#
|
|
262
|
-
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow
|
|
261
|
+
${chalk_1.default.gray('# Undeploy a workflow by UUID')}
|
|
262
|
+
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow undeploy <workflowId>`)}
|
|
263
263
|
|
|
264
264
|
${chalk_1.default.gray('# Execute a workflow')}
|
|
265
265
|
${chalk_1.default.cyan(`${PROGRAM_NAME} workflow execute <workflowId|file.yaml>`)}
|
|
@@ -1844,10 +1844,10 @@ async function resolveOrgId(domain, token, override) {
|
|
|
1844
1844
|
console.error(chalk_1.default.gray(`\n Run \`cx-cli orgs select\` to choose, or pass --org <id>.\n`));
|
|
1845
1845
|
process.exit(2);
|
|
1846
1846
|
}
|
|
1847
|
-
async function
|
|
1847
|
+
async function runAppModuleDeploy(file, orgOverride) {
|
|
1848
1848
|
if (!file) {
|
|
1849
1849
|
console.error(chalk_1.default.red('Error: File path required'));
|
|
1850
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule
|
|
1850
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule deploy <file.yaml> [--org <id>]`));
|
|
1851
1851
|
process.exit(2);
|
|
1852
1852
|
}
|
|
1853
1853
|
if (!fs.existsSync(file)) {
|
|
@@ -1876,7 +1876,7 @@ async function runAppModulePush(file, orgOverride) {
|
|
|
1876
1876
|
if (!appManifestId && session.app_manifest_id) {
|
|
1877
1877
|
appManifestId = session.app_manifest_id;
|
|
1878
1878
|
}
|
|
1879
|
-
console.log(chalk_1.default.bold.cyan('\n AppModule
|
|
1879
|
+
console.log(chalk_1.default.bold.cyan('\n AppModule Deploy\n'));
|
|
1880
1880
|
console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
|
|
1881
1881
|
console.log(chalk_1.default.gray(` Org: ${orgId}`));
|
|
1882
1882
|
console.log(chalk_1.default.gray(` Module: ${appModuleId}`));
|
|
@@ -1930,17 +1930,17 @@ async function runAppModulePush(file, orgOverride) {
|
|
|
1930
1930
|
console.log(chalk_1.default.green(` ✓ Created: ${mod?.name || appModuleId}\n`));
|
|
1931
1931
|
}
|
|
1932
1932
|
}
|
|
1933
|
-
async function
|
|
1933
|
+
async function runAppModuleUndeploy(uuid, orgOverride) {
|
|
1934
1934
|
if (!uuid) {
|
|
1935
1935
|
console.error(chalk_1.default.red('Error: AppModule ID required'));
|
|
1936
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule
|
|
1936
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule undeploy <appModuleId> [--org <id>]`));
|
|
1937
1937
|
process.exit(2);
|
|
1938
1938
|
}
|
|
1939
1939
|
const session = resolveSession();
|
|
1940
1940
|
const domain = session.domain;
|
|
1941
1941
|
const token = session.access_token;
|
|
1942
1942
|
const orgId = await resolveOrgId(domain, token, orgOverride);
|
|
1943
|
-
console.log(chalk_1.default.bold.cyan('\n AppModule
|
|
1943
|
+
console.log(chalk_1.default.bold.cyan('\n AppModule Undeploy\n'));
|
|
1944
1944
|
console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
|
|
1945
1945
|
console.log(chalk_1.default.gray(` Org: ${orgId}`));
|
|
1946
1946
|
console.log(chalk_1.default.gray(` Module: ${uuid}`));
|
|
@@ -2087,10 +2087,10 @@ async function runOrgsSelect() {
|
|
|
2087
2087
|
// ============================================================================
|
|
2088
2088
|
// Workflow Commands
|
|
2089
2089
|
// ============================================================================
|
|
2090
|
-
async function
|
|
2090
|
+
async function runWorkflowDeploy(file, orgOverride) {
|
|
2091
2091
|
if (!file) {
|
|
2092
2092
|
console.error(chalk_1.default.red('Error: File path required'));
|
|
2093
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow
|
|
2093
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow deploy <file.yaml> [--org <id>]`));
|
|
2094
2094
|
process.exit(2);
|
|
2095
2095
|
}
|
|
2096
2096
|
if (!fs.existsSync(file)) {
|
|
@@ -2109,7 +2109,7 @@ async function runWorkflowPush(file, orgOverride) {
|
|
|
2109
2109
|
process.exit(2);
|
|
2110
2110
|
}
|
|
2111
2111
|
const workflowName = parsed?.workflow?.name || workflowId;
|
|
2112
|
-
console.log(chalk_1.default.bold.cyan('\n Workflow
|
|
2112
|
+
console.log(chalk_1.default.bold.cyan('\n Workflow Deploy\n'));
|
|
2113
2113
|
console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
|
|
2114
2114
|
console.log(chalk_1.default.gray(` Org: ${orgId}`));
|
|
2115
2115
|
console.log(chalk_1.default.gray(` Workflow: ${workflowName}`));
|
|
@@ -2156,17 +2156,17 @@ async function runWorkflowPush(file, orgOverride) {
|
|
|
2156
2156
|
console.log(chalk_1.default.green(` ✓ Created: ${workflowName}\n`));
|
|
2157
2157
|
}
|
|
2158
2158
|
}
|
|
2159
|
-
async function
|
|
2159
|
+
async function runWorkflowUndeploy(uuid, orgOverride) {
|
|
2160
2160
|
if (!uuid) {
|
|
2161
2161
|
console.error(chalk_1.default.red('Error: Workflow ID required'));
|
|
2162
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow
|
|
2162
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow undeploy <workflowId> [--org <id>]`));
|
|
2163
2163
|
process.exit(2);
|
|
2164
2164
|
}
|
|
2165
2165
|
const session = resolveSession();
|
|
2166
2166
|
const domain = session.domain;
|
|
2167
2167
|
const token = session.access_token;
|
|
2168
2168
|
const orgId = await resolveOrgId(domain, token, orgOverride);
|
|
2169
|
-
console.log(chalk_1.default.bold.cyan('\n Workflow
|
|
2169
|
+
console.log(chalk_1.default.bold.cyan('\n Workflow Undeploy\n'));
|
|
2170
2170
|
console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
|
|
2171
2171
|
console.log(chalk_1.default.gray(` Org: ${orgId}`));
|
|
2172
2172
|
console.log(chalk_1.default.gray(` Workflow: ${uuid}`));
|
|
@@ -2721,7 +2721,7 @@ async function runPublish(featureDir, orgOverride) {
|
|
|
2721
2721
|
console.log(chalk_1.default.gray(`\n Found ${workflowFiles.length} workflow(s), ${moduleFiles.length} module(s)\n`));
|
|
2722
2722
|
let succeeded = 0;
|
|
2723
2723
|
let failed = 0;
|
|
2724
|
-
// Step 3:
|
|
2724
|
+
// Step 3: Deploy workflows
|
|
2725
2725
|
for (const file of workflowFiles) {
|
|
2726
2726
|
const relPath = path.relative(process.cwd(), file);
|
|
2727
2727
|
const result = await pushWorkflowQuiet(domain, token, orgId, file);
|
|
@@ -2734,7 +2734,7 @@ async function runPublish(featureDir, orgOverride) {
|
|
|
2734
2734
|
failed++;
|
|
2735
2735
|
}
|
|
2736
2736
|
}
|
|
2737
|
-
// Step 4:
|
|
2737
|
+
// Step 4: Deploy modules
|
|
2738
2738
|
for (const file of moduleFiles) {
|
|
2739
2739
|
const relPath = path.relative(process.cwd(), file);
|
|
2740
2740
|
const result = await pushModuleQuiet(domain, token, orgId, file, appManifestId);
|
|
@@ -3925,15 +3925,15 @@ async function main() {
|
|
|
3925
3925
|
// Handle appmodule command (no schemas needed)
|
|
3926
3926
|
if (command === 'appmodule') {
|
|
3927
3927
|
const sub = files[0];
|
|
3928
|
-
if (sub === '
|
|
3929
|
-
await
|
|
3928
|
+
if (sub === 'deploy') {
|
|
3929
|
+
await runAppModuleDeploy(files[1], options.orgId);
|
|
3930
3930
|
}
|
|
3931
|
-
else if (sub === '
|
|
3932
|
-
await
|
|
3931
|
+
else if (sub === 'undeploy') {
|
|
3932
|
+
await runAppModuleUndeploy(files[1], options.orgId);
|
|
3933
3933
|
}
|
|
3934
3934
|
else {
|
|
3935
3935
|
console.error(chalk_1.default.red(`Unknown appmodule subcommand: ${sub || '(none)'}`));
|
|
3936
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule <
|
|
3936
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} appmodule <deploy|undeploy> ...`));
|
|
3937
3937
|
process.exit(2);
|
|
3938
3938
|
}
|
|
3939
3939
|
process.exit(0);
|
|
@@ -3941,11 +3941,11 @@ async function main() {
|
|
|
3941
3941
|
// Handle workflow command (no schemas needed)
|
|
3942
3942
|
if (command === 'workflow') {
|
|
3943
3943
|
const sub = files[0];
|
|
3944
|
-
if (sub === '
|
|
3945
|
-
await
|
|
3944
|
+
if (sub === 'deploy') {
|
|
3945
|
+
await runWorkflowDeploy(files[1], options.orgId);
|
|
3946
3946
|
}
|
|
3947
|
-
else if (sub === '
|
|
3948
|
-
await
|
|
3947
|
+
else if (sub === 'undeploy') {
|
|
3948
|
+
await runWorkflowUndeploy(files[1], options.orgId);
|
|
3949
3949
|
}
|
|
3950
3950
|
else if (sub === 'execute') {
|
|
3951
3951
|
await runWorkflowExecute(files[1], options.orgId, options.vars);
|
|
@@ -3958,7 +3958,7 @@ async function main() {
|
|
|
3958
3958
|
}
|
|
3959
3959
|
else {
|
|
3960
3960
|
console.error(chalk_1.default.red(`Unknown workflow subcommand: ${sub || '(none)'}`));
|
|
3961
|
-
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow <
|
|
3961
|
+
console.error(chalk_1.default.gray(`Usage: ${PROGRAM_NAME} workflow <deploy|undeploy|execute|logs|log> ...`));
|
|
3962
3962
|
process.exit(2);
|
|
3963
3963
|
}
|
|
3964
3964
|
process.exit(0);
|