@cxtms/cx-schema 1.6.7 → 1.7.0

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/dist/cli.js CHANGED
@@ -82,7 +82,7 @@ loadEnvFile();
82
82
  // Constants
83
83
  // ============================================================================
84
84
  const VERSION = require('../package.json').version;
85
- const PROGRAM_NAME = 'cx-cli';
85
+ const PROGRAM_NAME = 'cxtms';
86
86
  // ============================================================================
87
87
  // Help Text
88
88
  // ============================================================================
@@ -117,6 +117,7 @@ ${chalk_1.default.bold.yellow('COMMANDS:')}
117
117
  ${chalk_1.default.green('appmodule')} Manage app modules on a CX server (deploy, undeploy)
118
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
+ ${chalk_1.default.green('query')} Run a GraphQL query against the CX server
120
121
  ${chalk_1.default.green('schema')} Show JSON schema for a component or task
121
122
  ${chalk_1.default.green('example')} Show example YAML for a component or task
122
123
  ${chalk_1.default.green('list')} List available schemas (modules, workflows, tasks)
@@ -287,6 +288,16 @@ ${chalk_1.default.bold.yellow('PUBLISH COMMANDS:')}
287
288
  ${chalk_1.default.gray('# Publish with explicit org ID')}
288
289
  ${chalk_1.default.cyan(`${PROGRAM_NAME} publish --org 42`)}
289
290
 
291
+ ${chalk_1.default.bold.yellow('QUERY COMMANDS:')}
292
+ ${chalk_1.default.gray('# Run an inline GraphQL query')}
293
+ ${chalk_1.default.cyan(`${PROGRAM_NAME} query '{ organizations(take: 5) { items { organizationId companyName } } }'`)}
294
+
295
+ ${chalk_1.default.gray('# Run a query from a .graphql file')}
296
+ ${chalk_1.default.cyan(`${PROGRAM_NAME} query my-query.graphql`)}
297
+
298
+ ${chalk_1.default.gray('# Pass variables as JSON')}
299
+ ${chalk_1.default.cyan(`${PROGRAM_NAME} query my-query.graphql --vars '{"id": 42}'`)}
300
+
290
301
  ${chalk_1.default.bold.yellow('VALIDATION TYPES:')}
291
302
  ${chalk_1.default.bold('module')} - CargoXplorer UI module definitions (components, routes, entities)
292
303
  ${chalk_1.default.bold('workflow')} - CargoXplorer workflow definitions (activities, tasks, triggers)
@@ -491,39 +502,39 @@ npm install @cxtms/cx-schema
491
502
 
492
503
  \`\`\`bash
493
504
  # Validate all modules
494
- npx cx-cli modules/*.yaml
505
+ npx cxtms modules/*.yaml
495
506
 
496
507
  # Validate all workflows
497
- npx cx-cli workflows/*.yaml
508
+ npx cxtms workflows/*.yaml
498
509
 
499
510
  # Validate with detailed output
500
- npx cx-cli --verbose modules/my-module.yaml
511
+ npx cxtms --verbose modules/my-module.yaml
501
512
 
502
513
  # Generate validation report
503
- npx cx-cli report modules/*.yaml workflows/*.yaml --report report.html
514
+ npx cxtms report modules/*.yaml workflows/*.yaml --report report.html
504
515
  \`\`\`
505
516
 
506
517
  ### Create new files
507
518
 
508
519
  \`\`\`bash
509
520
  # Create a new module
510
- npx cx-cli create module my-module
521
+ npx cxtms create module my-module
511
522
 
512
523
  # Create a new workflow
513
- npx cx-cli create workflow my-workflow
524
+ npx cxtms create workflow my-workflow
514
525
  \`\`\`
515
526
 
516
527
  ### View schemas and examples
517
528
 
518
529
  \`\`\`bash
519
530
  # List available schemas
520
- npx cx-cli list
531
+ npx cxtms list
521
532
 
522
533
  # View schema for a component
523
- npx cx-cli schema form
534
+ npx cxtms schema form
524
535
 
525
536
  # View example YAML
526
- npx cx-cli example workflow
537
+ npx cxtms example workflow
527
538
  \`\`\`
528
539
 
529
540
  ## Documentation
@@ -544,13 +555,13 @@ When making changes to YAML files, always validate them:
544
555
 
545
556
  \`\`\`bash
546
557
  # Validate a specific module file
547
- npx cx-cli modules/<module-name>.yaml
558
+ npx cxtms modules/<module-name>.yaml
548
559
 
549
560
  # Validate a specific workflow file
550
- npx cx-cli workflows/<workflow-name>.yaml
561
+ npx cxtms workflows/<workflow-name>.yaml
551
562
 
552
563
  # Validate all files with a report
553
- npx cx-cli report modules/*.yaml workflows/*.yaml --report validation-report.md
564
+ npx cxtms report modules/*.yaml workflows/*.yaml --report validation-report.md
554
565
  \`\`\`
555
566
 
556
567
  ## Schema Reference
@@ -559,14 +570,14 @@ Before editing components or tasks, check the schema:
559
570
 
560
571
  \`\`\`bash
561
572
  # View schema for components
562
- npx cx-cli schema form
563
- npx cx-cli schema dataGrid
564
- npx cx-cli schema layout
573
+ npx cxtms schema form
574
+ npx cxtms schema dataGrid
575
+ npx cxtms schema layout
565
576
 
566
577
  # View schema for workflow tasks
567
- npx cx-cli schema foreach
568
- npx cx-cli schema graphql
569
- npx cx-cli schema switch
578
+ npx cxtms schema foreach
579
+ npx cxtms schema graphql
580
+ npx cxtms schema switch
570
581
  \`\`\`
571
582
 
572
583
  ## Creating New Files
@@ -575,16 +586,16 @@ Use templates to create properly structured files:
575
586
 
576
587
  \`\`\`bash
577
588
  # Create a new module
578
- npx cx-cli create module <name>
589
+ npx cxtms create module <name>
579
590
 
580
591
  # Create a new workflow
581
- npx cx-cli create workflow <name>
592
+ npx cxtms create workflow <name>
582
593
 
583
594
  # Create from a specific template variant
584
- npx cx-cli create workflow <name> --template basic
595
+ npx cxtms create workflow <name> --template basic
585
596
 
586
597
  # Create inside a feature folder (features/<name>/workflows/)
587
- npx cx-cli create workflow <name> --feature billing
598
+ npx cxtms create workflow <name> --feature billing
588
599
  \`\`\`
589
600
 
590
601
  ## Module Structure
@@ -1392,23 +1403,23 @@ features/ # Feature-scoped modules and workflows
1392
1403
  workflows/
1393
1404
  \`\`\`
1394
1405
 
1395
- ### CLI — \`cx-cli\`
1406
+ ### CLI — \`cxtms\`
1396
1407
 
1397
1408
  **Always scaffold via CLI, never write YAML from scratch.**
1398
1409
 
1399
1410
  | Command | Description |
1400
1411
  |---------|-------------|
1401
- | \`npx cx-cli create module <name>\` | Scaffold a UI module |
1402
- | \`npx cx-cli create workflow <name>\` | Scaffold a workflow |
1403
- | \`npx cx-cli create module <name> --template <t>\` | Use a specific template |
1404
- | \`npx cx-cli create workflow <name> --template <t>\` | Use a specific template |
1405
- | \`npx cx-cli create module <name> --feature <f>\` | Place under features/<f>/modules/ |
1406
- | \`npx cx-cli <file.yaml>\` | Validate a YAML file |
1407
- | \`npx cx-cli <file.yaml> --verbose\` | Validate with detailed errors |
1408
- | \`npx cx-cli schema <name>\` | Show JSON schema for a component or task |
1409
- | \`npx cx-cli example <name>\` | Show example YAML |
1410
- | \`npx cx-cli list\` | List all available schemas |
1411
- | \`npx cx-cli extract <src> <comp> --to <tgt>\` | Move component between modules |
1412
+ | \`npx cxtms create module <name>\` | Scaffold a UI module |
1413
+ | \`npx cxtms create workflow <name>\` | Scaffold a workflow |
1414
+ | \`npx cxtms create module <name> --template <t>\` | Use a specific template |
1415
+ | \`npx cxtms create workflow <name> --template <t>\` | Use a specific template |
1416
+ | \`npx cxtms create module <name> --feature <f>\` | Place under features/<f>/modules/ |
1417
+ | \`npx cxtms <file.yaml>\` | Validate a YAML file |
1418
+ | \`npx cxtms <file.yaml> --verbose\` | Validate with detailed errors |
1419
+ | \`npx cxtms schema <name>\` | Show JSON schema for a component or task |
1420
+ | \`npx cxtms example <name>\` | Show example YAML |
1421
+ | \`npx cxtms list\` | List all available schemas |
1422
+ | \`npx cxtms extract <src> <comp> --to <tgt>\` | Move component between modules |
1412
1423
 
1413
1424
  **Module templates:** \`default\`, \`form\`, \`grid\`, \`select\`, \`configuration\`
1414
1425
  **Workflow templates:** \`basic\`, \`entity-trigger\`, \`document\`, \`scheduled\`, \`utility\`, \`webhook\`, \`public-api\`, \`mcp-tool\`, \`ftp-tracking\`, \`ftp-edi\`, \`api-tracking\`
@@ -1423,10 +1434,10 @@ features/ # Feature-scoped modules and workflows
1423
1434
 
1424
1435
  ### Workflow: Scaffold → Customize → Validate
1425
1436
 
1426
- 1. **Scaffold** — \`npx cx-cli create module|workflow <name> --template <t>\`
1437
+ 1. **Scaffold** — \`npx cxtms create module|workflow <name> --template <t>\`
1427
1438
  2. **Read** the generated file
1428
1439
  3. **Customize** for the use case
1429
- 4. **Validate** — \`npx cx-cli <file.yaml>\` — run after every change, fix all errors
1440
+ 4. **Validate** — \`npx cxtms <file.yaml>\` — run after every change, fix all errors
1430
1441
  ${CX_CLAUDE_MARKER}`;
1431
1442
  }
1432
1443
  function runSetupClaude() {
@@ -1570,7 +1581,7 @@ function startCallbackServer() {
1570
1581
  }
1571
1582
  async function registerOAuthClient(domain) {
1572
1583
  const res = await httpsPost(`${domain}/connect/register`, JSON.stringify({
1573
- client_name: `cx-cli-${crypto.randomBytes(4).toString('hex')}`,
1584
+ client_name: `cxtms-${crypto.randomBytes(4).toString('hex')}`,
1574
1585
  redirect_uris: [`http://localhost:${AUTH_CALLBACK_PORT}/callback`],
1575
1586
  grant_types: ['authorization_code', 'refresh_token'],
1576
1587
  response_types: ['code'],
@@ -1713,13 +1724,13 @@ async function graphqlRequest(domain, token, query, variables) {
1713
1724
  // Try refresh for OAuth sessions
1714
1725
  const stored = readSessionFile();
1715
1726
  if (!stored)
1716
- throw new Error('Session expired. Run `cx-cli login <url>` again.');
1727
+ throw new Error('Session expired. Run `cxtms login <url>` again.');
1717
1728
  try {
1718
1729
  const refreshed = await refreshTokens(stored);
1719
1730
  res = await graphqlPostWithAuth(domain, refreshed.access_token, body);
1720
1731
  }
1721
1732
  catch {
1722
- throw new Error('Session expired. Run `cx-cli login <url>` again.');
1733
+ throw new Error('Session expired. Run `cxtms login <url>` again.');
1723
1734
  }
1724
1735
  }
1725
1736
  // Try to parse GraphQL errors from 400 responses too
@@ -1808,7 +1819,7 @@ function resolveSession() {
1808
1819
  if (session)
1809
1820
  return session;
1810
1821
  // 2. Not logged in
1811
- console.error(chalk_1.default.red('Not logged in. Run `cx-cli login <url>` first.'));
1822
+ console.error(chalk_1.default.red('Not logged in. Run `cxtms login <url>` first.'));
1812
1823
  process.exit(2);
1813
1824
  }
1814
1825
  async function resolveOrgId(domain, token, override) {
@@ -1841,7 +1852,7 @@ async function resolveOrgId(domain, token, override) {
1841
1852
  for (const org of orgs) {
1842
1853
  console.error(chalk_1.default.white(` ${org.organizationId} ${org.companyName}`));
1843
1854
  }
1844
- console.error(chalk_1.default.gray(`\n Run \`cx-cli orgs select\` to choose, or pass --org <id>.\n`));
1855
+ console.error(chalk_1.default.gray(`\n Run \`cxtms orgs select\` to choose, or pass --org <id>.\n`));
1845
1856
  process.exit(2);
1846
1857
  }
1847
1858
  async function runAppModuleDeploy(file, orgOverride) {
@@ -1866,16 +1877,13 @@ async function runAppModuleDeploy(file, orgOverride) {
1866
1877
  console.error(chalk_1.default.red('Error: Module YAML is missing module.appModuleId'));
1867
1878
  process.exit(2);
1868
1879
  }
1869
- // Read app.yaml for appManifestId, fall back to cached session
1880
+ // Read app.yaml for appManifestId
1870
1881
  let appManifestId;
1871
1882
  const appYamlPath = path.join(process.cwd(), 'app.yaml');
1872
1883
  if (fs.existsSync(appYamlPath)) {
1873
1884
  const appYaml = yaml_1.default.parse(fs.readFileSync(appYamlPath, 'utf-8'));
1874
1885
  appManifestId = appYaml?.id;
1875
1886
  }
1876
- if (!appManifestId && session.app_manifest_id) {
1877
- appManifestId = session.app_manifest_id;
1878
- }
1879
1887
  console.log(chalk_1.default.bold.cyan('\n AppModule Deploy\n'));
1880
1888
  console.log(chalk_1.default.gray(` Server: ${new URL(domain).hostname}`));
1881
1889
  console.log(chalk_1.default.gray(` Org: ${orgId}`));
@@ -1993,25 +2001,19 @@ async function runOrgsUse(orgIdStr) {
1993
2001
  else {
1994
2002
  console.log(chalk_1.default.gray(` Org: (not set)`));
1995
2003
  }
1996
- if (session.app_manifest_id) {
1997
- console.log(chalk_1.default.white(` App: ${session.app_manifest_id}`));
1998
- }
1999
- else {
2000
- // Try reading from app.yaml
2001
- const appYamlPath = path.join(process.cwd(), 'app.yaml');
2002
- if (fs.existsSync(appYamlPath)) {
2003
- const appYaml = yaml_1.default.parse(fs.readFileSync(appYamlPath, 'utf-8'));
2004
- if (appYaml?.id) {
2005
- console.log(chalk_1.default.white(` App: ${appYaml.id} ${chalk_1.default.gray('(from app.yaml)')}`));
2006
- }
2007
- else {
2008
- console.log(chalk_1.default.gray(` App: (not set)`));
2009
- }
2004
+ const appYamlPath = path.join(process.cwd(), 'app.yaml');
2005
+ if (fs.existsSync(appYamlPath)) {
2006
+ const appYaml = yaml_1.default.parse(fs.readFileSync(appYamlPath, 'utf-8'));
2007
+ if (appYaml?.id) {
2008
+ console.log(chalk_1.default.white(` App: ${appYaml.id} ${chalk_1.default.gray('(from app.yaml)')}`));
2010
2009
  }
2011
2010
  else {
2012
2011
  console.log(chalk_1.default.gray(` App: (not set)`));
2013
2012
  }
2014
2013
  }
2014
+ else {
2015
+ console.log(chalk_1.default.gray(` App: (not set)`));
2016
+ }
2015
2017
  console.log('');
2016
2018
  return;
2017
2019
  }
@@ -2552,7 +2554,7 @@ async function runPatCreate(name) {
2552
2554
  console.log(chalk_1.default.cyan(` CXTMS_AUTH=${patToken}`));
2553
2555
  console.log(chalk_1.default.cyan(` CXTMS_SERVER=${domain}`));
2554
2556
  console.log();
2555
- console.log(chalk_1.default.gray('When CXTMS_AUTH is set, cx-cli will skip OAuth login and use the PAT token directly.'));
2557
+ console.log(chalk_1.default.gray('When CXTMS_AUTH is set, cxtms will skip OAuth login and use the PAT token directly.'));
2556
2558
  console.log(chalk_1.default.gray('You can also export these as environment variables instead of using .env.'));
2557
2559
  }
2558
2560
  async function runPatList() {
@@ -2628,7 +2630,7 @@ async function runPatSetup() {
2628
2630
  console.log(chalk_1.default.bold('To set up PAT authentication:'));
2629
2631
  console.log();
2630
2632
  console.log(chalk_1.default.white(' 1. Create a token:'));
2631
- console.log(chalk_1.default.cyan(' cx-cli pat create "my-token-name"'));
2633
+ console.log(chalk_1.default.cyan(' cxtms pat create "my-token-name"'));
2632
2634
  console.log();
2633
2635
  console.log(chalk_1.default.white(' 2. Add to your project .env file:'));
2634
2636
  console.log(chalk_1.default.cyan(' CXTMS_AUTH=pat_xxxxx'));
@@ -2757,6 +2759,41 @@ async function runPublish(featureDir, orgOverride) {
2757
2759
  }
2758
2760
  }
2759
2761
  // ============================================================================
2762
+ // Query Command
2763
+ // ============================================================================
2764
+ async function runQuery(queryArg, variables) {
2765
+ if (!queryArg) {
2766
+ console.error(chalk_1.default.red('Error: query argument required (inline GraphQL string or .graphql/.gql file path)'));
2767
+ process.exit(2);
2768
+ }
2769
+ // Resolve query: file path or inline string
2770
+ let query;
2771
+ if (queryArg.endsWith('.graphql') || queryArg.endsWith('.gql')) {
2772
+ if (!fs.existsSync(queryArg)) {
2773
+ console.error(chalk_1.default.red(`Error: file not found: ${queryArg}`));
2774
+ process.exit(2);
2775
+ }
2776
+ query = fs.readFileSync(queryArg, 'utf-8');
2777
+ }
2778
+ else {
2779
+ query = queryArg;
2780
+ }
2781
+ // Parse variables if provided
2782
+ let vars = {};
2783
+ if (variables) {
2784
+ try {
2785
+ vars = JSON.parse(variables);
2786
+ }
2787
+ catch {
2788
+ console.error(chalk_1.default.red('Error: --vars must be valid JSON'));
2789
+ process.exit(2);
2790
+ }
2791
+ }
2792
+ const session = resolveSession();
2793
+ const data = await graphqlRequest(session.domain, session.access_token, query, vars);
2794
+ console.log(JSON.stringify(data, null, 2));
2795
+ }
2796
+ // ============================================================================
2760
2797
  // Extract Command
2761
2798
  // ============================================================================
2762
2799
  function runExtract(sourceFile, componentName, targetFile, copy) {
@@ -2967,7 +3004,7 @@ function parseArgs(args) {
2967
3004
  reportFormat: 'json'
2968
3005
  };
2969
3006
  // Check for commands
2970
- const commands = ['validate', 'schema', 'example', 'list', 'help', 'version', 'report', 'init', 'create', 'extract', 'sync-schemas', 'install-skills', 'update', 'setup-claude', 'login', 'logout', 'pat', 'appmodule', 'orgs', 'workflow', 'publish'];
3007
+ const commands = ['validate', 'schema', 'example', 'list', 'help', 'version', 'report', 'init', 'create', 'extract', 'sync-schemas', 'install-skills', 'update', 'setup-claude', 'login', 'logout', 'pat', 'appmodule', 'orgs', 'workflow', 'publish', 'query'];
2971
3008
  if (args.length > 0 && commands.includes(args[0])) {
2972
3009
  command = args[0];
2973
3010
  args = args.slice(1);
@@ -3473,13 +3510,13 @@ function getSuggestion(error) {
3473
3510
  return 'Check that the value type matches the expected type (string, number, boolean, etc.)';
3474
3511
  }
3475
3512
  if (error.message.includes('additionalProperties')) {
3476
- return 'Remove unrecognized properties. Use `cx-cli schema <type>` to see allowed properties.';
3513
+ return 'Remove unrecognized properties. Use `cxtms schema <type>` to see allowed properties.';
3477
3514
  }
3478
3515
  return 'Review the schema requirements for this property';
3479
3516
  case 'yaml_syntax_error':
3480
3517
  return 'Check YAML indentation and syntax. Use a YAML linter to identify issues.';
3481
3518
  case 'invalid_task_type':
3482
- return `Use 'cx-cli list --type workflow' to see available task types`;
3519
+ return `Use 'cxtms list --type workflow' to see available task types`;
3483
3520
  case 'invalid_activity':
3484
3521
  return 'Each activity must have a "name" and "steps" array';
3485
3522
  default:
@@ -3853,7 +3890,7 @@ async function main() {
3853
3890
  }
3854
3891
  // Handle version
3855
3892
  if (options.version) {
3856
- console.log(`cx-cli v${VERSION}`);
3893
+ console.log(`cxtms v${VERSION}`);
3857
3894
  process.exit(0);
3858
3895
  }
3859
3896
  // Handle login command (no schemas needed)
@@ -3968,6 +4005,11 @@ async function main() {
3968
4005
  await runPublish(files[0] || options.feature, options.orgId);
3969
4006
  process.exit(0);
3970
4007
  }
4008
+ // Handle query command (no schemas needed)
4009
+ if (command === 'query') {
4010
+ await runQuery(files[0], options.vars);
4011
+ process.exit(0);
4012
+ }
3971
4013
  // Find schemas path
3972
4014
  const schemasPath = options.schemasPath || findSchemasPath();
3973
4015
  if (!schemasPath) {