@living-architecture/riviere-cli 0.2.1 → 0.2.3

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.
Files changed (97) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +14 -6
  3. package/dist/bin.js +24428 -0
  4. package/dist/index.js +24444 -7
  5. package/package.json +4 -4
  6. package/dist/cli.d.ts +0 -8
  7. package/dist/cli.d.ts.map +0 -1
  8. package/dist/cli.js +0 -65
  9. package/dist/command-test-fixtures.d.ts +0 -110
  10. package/dist/command-test-fixtures.d.ts.map +0 -1
  11. package/dist/command-test-fixtures.js +0 -184
  12. package/dist/commands/builder/add-component.d.ts +0 -4
  13. package/dist/commands/builder/add-component.d.ts.map +0 -1
  14. package/dist/commands/builder/add-component.js +0 -204
  15. package/dist/commands/builder/add-domain.d.ts +0 -3
  16. package/dist/commands/builder/add-domain.d.ts.map +0 -1
  17. package/dist/commands/builder/add-domain.js +0 -56
  18. package/dist/commands/builder/add-source.d.ts +0 -3
  19. package/dist/commands/builder/add-source.d.ts.map +0 -1
  20. package/dist/commands/builder/add-source.js +0 -28
  21. package/dist/commands/builder/check-consistency.d.ts +0 -3
  22. package/dist/commands/builder/check-consistency.d.ts.map +0 -1
  23. package/dist/commands/builder/check-consistency.js +0 -27
  24. package/dist/commands/builder/component-checklist.d.ts +0 -3
  25. package/dist/commands/builder/component-checklist.d.ts.map +0 -1
  26. package/dist/commands/builder/component-checklist.js +0 -43
  27. package/dist/commands/builder/component-summary.d.ts +0 -3
  28. package/dist/commands/builder/component-summary.d.ts.map +0 -1
  29. package/dist/commands/builder/component-summary.js +0 -23
  30. package/dist/commands/builder/enrich.d.ts +0 -3
  31. package/dist/commands/builder/enrich.d.ts.map +0 -1
  32. package/dist/commands/builder/enrich.js +0 -85
  33. package/dist/commands/builder/finalize.d.ts +0 -3
  34. package/dist/commands/builder/finalize.d.ts.map +0 -1
  35. package/dist/commands/builder/finalize.js +0 -37
  36. package/dist/commands/builder/init.d.ts +0 -3
  37. package/dist/commands/builder/init.d.ts.map +0 -1
  38. package/dist/commands/builder/init.js +0 -100
  39. package/dist/commands/builder/link-external.d.ts +0 -3
  40. package/dist/commands/builder/link-external.d.ts.map +0 -1
  41. package/dist/commands/builder/link-external.js +0 -70
  42. package/dist/commands/builder/link-http.d.ts +0 -3
  43. package/dist/commands/builder/link-http.d.ts.map +0 -1
  44. package/dist/commands/builder/link-http.js +0 -130
  45. package/dist/commands/builder/link-infrastructure.d.ts +0 -7
  46. package/dist/commands/builder/link-infrastructure.d.ts.map +0 -1
  47. package/dist/commands/builder/link-infrastructure.js +0 -41
  48. package/dist/commands/builder/link.d.ts +0 -3
  49. package/dist/commands/builder/link.d.ts.map +0 -1
  50. package/dist/commands/builder/link.js +0 -73
  51. package/dist/commands/builder/validate.d.ts +0 -3
  52. package/dist/commands/builder/validate.d.ts.map +0 -1
  53. package/dist/commands/builder/validate.js +0 -29
  54. package/dist/commands/query/component-output.d.ts +0 -9
  55. package/dist/commands/query/component-output.d.ts.map +0 -1
  56. package/dist/commands/query/component-output.js +0 -8
  57. package/dist/commands/query/components.d.ts +0 -3
  58. package/dist/commands/query/components.d.ts.map +0 -1
  59. package/dist/commands/query/components.js +0 -45
  60. package/dist/commands/query/domains.d.ts +0 -3
  61. package/dist/commands/query/domains.d.ts.map +0 -1
  62. package/dist/commands/query/domains.js +0 -22
  63. package/dist/commands/query/entry-points.d.ts +0 -3
  64. package/dist/commands/query/entry-points.d.ts.map +0 -1
  65. package/dist/commands/query/entry-points.js +0 -22
  66. package/dist/commands/query/load-graph.d.ts +0 -16
  67. package/dist/commands/query/load-graph.d.ts.map +0 -1
  68. package/dist/commands/query/load-graph.js +0 -50
  69. package/dist/commands/query/orphans.d.ts +0 -3
  70. package/dist/commands/query/orphans.d.ts.map +0 -1
  71. package/dist/commands/query/orphans.js +0 -22
  72. package/dist/commands/query/search.d.ts +0 -3
  73. package/dist/commands/query/search.d.ts.map +0 -1
  74. package/dist/commands/query/search.js +0 -25
  75. package/dist/commands/query/trace.d.ts +0 -3
  76. package/dist/commands/query/trace.d.ts.map +0 -1
  77. package/dist/commands/query/trace.js +0 -41
  78. package/dist/component-types.d.ts +0 -15
  79. package/dist/component-types.d.ts.map +0 -1
  80. package/dist/component-types.js +0 -39
  81. package/dist/error-codes.d.ts +0 -15
  82. package/dist/error-codes.d.ts.map +0 -1
  83. package/dist/error-codes.js +0 -15
  84. package/dist/file-existence.d.ts +0 -2
  85. package/dist/file-existence.d.ts.map +0 -1
  86. package/dist/file-existence.js +0 -16
  87. package/dist/graph-path.d.ts +0 -3
  88. package/dist/graph-path.d.ts.map +0 -1
  89. package/dist/graph-path.js +0 -8
  90. package/dist/index.d.ts +0 -5
  91. package/dist/index.d.ts.map +0 -1
  92. package/dist/output.d.ts +0 -17
  93. package/dist/output.d.ts.map +0 -1
  94. package/dist/output.js +0 -7
  95. package/dist/validation.d.ts +0 -12
  96. package/dist/validation.d.ts.map +0 -1
  97. package/dist/validation.js +0 -51
@@ -1,56 +0,0 @@
1
- import { Command } from 'commander';
2
- import { writeFile } from 'node:fs/promises';
3
- import { DuplicateDomainError } from '@living-architecture/riviere-builder';
4
- import { formatError, formatSuccess } from '../../output';
5
- import { CliErrorCode } from '../../error-codes';
6
- import { getDefaultGraphPathDescription } from '../../graph-path';
7
- import { isValidSystemType, VALID_SYSTEM_TYPES } from '../../component-types';
8
- import { withGraphBuilder } from './link-infrastructure';
9
- export function createAddDomainCommand() {
10
- return new Command('add-domain')
11
- .description('Add a domain to the graph')
12
- .addHelpText('after', `
13
- Examples:
14
- $ riviere builder add-domain --name orders --system-type domain \\
15
- --description "Order management"
16
-
17
- $ riviere builder add-domain --name checkout-bff --system-type bff \\
18
- --description "Checkout backend-for-frontend"
19
- `)
20
- .requiredOption('--name <name>', 'Domain name')
21
- .requiredOption('--description <description>', 'Domain description')
22
- .requiredOption('--system-type <type>', 'System type (domain, bff, ui, other)')
23
- .option('--graph <path>', getDefaultGraphPathDescription())
24
- .option('--json', 'Output result as JSON')
25
- .action(async (options) => {
26
- if (!isValidSystemType(options.systemType)) {
27
- console.log(JSON.stringify(formatError(CliErrorCode.ValidationError, `Invalid system type: ${options.systemType}`, [`Valid types: ${VALID_SYSTEM_TYPES.join(', ')}`])));
28
- return;
29
- }
30
- const systemType = options.systemType;
31
- await withGraphBuilder(options.graph, async (builder, graphPath) => {
32
- try {
33
- builder.addDomain({
34
- name: options.name,
35
- description: options.description,
36
- systemType,
37
- });
38
- }
39
- catch (error) {
40
- if (error instanceof DuplicateDomainError) {
41
- console.log(JSON.stringify(formatError(CliErrorCode.DuplicateDomain, error.message, ['Use a different domain name'])));
42
- return;
43
- }
44
- throw error;
45
- }
46
- await writeFile(graphPath, builder.serialize(), 'utf-8');
47
- if (options.json === true) {
48
- console.log(JSON.stringify(formatSuccess({
49
- name: options.name,
50
- description: options.description,
51
- systemType: options.systemType,
52
- })));
53
- }
54
- });
55
- });
56
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createAddSourceCommand(): Command;
3
- //# sourceMappingURL=add-source.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-source.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/add-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,sBAAsB,IAAI,OAAO,CA+BhD"}
@@ -1,28 +0,0 @@
1
- import { Command } from 'commander';
2
- import { writeFile } from 'node:fs/promises';
3
- import { formatSuccess } from '../../output';
4
- import { getDefaultGraphPathDescription } from '../../graph-path';
5
- import { withGraphBuilder } from './link-infrastructure';
6
- export function createAddSourceCommand() {
7
- return new Command('add-source')
8
- .description('Add a source repository to the graph')
9
- .addHelpText('after', `
10
- Examples:
11
- $ riviere builder add-source --repository https://github.com/org/orders-service
12
- $ riviere builder add-source --repository https://github.com/org/payments-api --json
13
- `)
14
- .requiredOption('--repository <url>', 'Source repository URL')
15
- .option('--graph <path>', getDefaultGraphPathDescription())
16
- .option('--json', 'Output result as JSON')
17
- .action(async (options) => {
18
- await withGraphBuilder(options.graph, async (builder, graphPath) => {
19
- builder.addSource({ repository: options.repository });
20
- await writeFile(graphPath, builder.serialize(), 'utf-8');
21
- if (options.json === true) {
22
- console.log(JSON.stringify(formatSuccess({
23
- repository: options.repository,
24
- })));
25
- }
26
- });
27
- });
28
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createCheckConsistencyCommand(): Command;
3
- //# sourceMappingURL=check-consistency.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"check-consistency.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/check-consistency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,6BAA6B,IAAI,OAAO,CA8BvD"}
@@ -1,27 +0,0 @@
1
- import { Command } from 'commander';
2
- import { getDefaultGraphPathDescription } from '../../graph-path';
3
- import { formatSuccess } from '../../output';
4
- import { withGraphBuilder } from './link-infrastructure';
5
- export function createCheckConsistencyCommand() {
6
- return new Command('check-consistency')
7
- .description('Check for structural issues in the graph')
8
- .addHelpText('after', `
9
- Examples:
10
- $ riviere builder check-consistency
11
- $ riviere builder check-consistency --json
12
- `)
13
- .option('--graph <path>', getDefaultGraphPathDescription())
14
- .option('--json', 'Output result as JSON')
15
- .action(async (options) => {
16
- await withGraphBuilder(options.graph, async (builder) => {
17
- const warnings = builder.warnings();
18
- const consistent = warnings.length === 0;
19
- if (options.json === true) {
20
- console.log(JSON.stringify(formatSuccess({
21
- consistent,
22
- warnings,
23
- })));
24
- }
25
- });
26
- });
27
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createComponentChecklistCommand(): Command;
3
- //# sourceMappingURL=component-checklist.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-checklist.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/component-checklist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,+BAA+B,IAAI,OAAO,CAmDzD"}
@@ -1,43 +0,0 @@
1
- import { Command } from 'commander';
2
- import { getDefaultGraphPathDescription } from '../../graph-path';
3
- import { formatError, formatSuccess } from '../../output';
4
- import { CliErrorCode } from '../../error-codes';
5
- import { isValidComponentType } from '../../component-types';
6
- import { withGraphBuilder } from './link-infrastructure';
7
- export function createComponentChecklistCommand() {
8
- return new Command('component-checklist')
9
- .description('List components as a checklist for linking/enrichment')
10
- .addHelpText('after', `
11
- Examples:
12
- $ riviere builder component-checklist
13
- $ riviere builder component-checklist --type DomainOp
14
- $ riviere builder component-checklist --type API --json
15
- `)
16
- .option('--graph <path>', getDefaultGraphPathDescription())
17
- .option('--json', 'Output result as JSON')
18
- .option('--type <type>', 'Filter by component type')
19
- .action(async (options) => {
20
- if (options.type !== undefined && !isValidComponentType(options.type)) {
21
- console.log(JSON.stringify(formatError(CliErrorCode.InvalidComponentType, `Invalid component type: ${options.type}`, [
22
- 'Valid types: UI, API, UseCase, DomainOp, Event, EventHandler, Custom',
23
- ])));
24
- return;
25
- }
26
- await withGraphBuilder(options.graph, async (builder) => {
27
- const allComponents = builder.query().components();
28
- const filteredComponents = options.type !== undefined ? allComponents.filter((c) => c.type === options.type) : allComponents;
29
- const checklistItems = filteredComponents.map((c) => ({
30
- id: c.id,
31
- type: c.type,
32
- name: c.name,
33
- domain: c.domain,
34
- }));
35
- if (options.json === true) {
36
- console.log(JSON.stringify(formatSuccess({
37
- total: checklistItems.length,
38
- components: checklistItems,
39
- })));
40
- }
41
- });
42
- });
43
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createComponentSummaryCommand(): Command;
3
- //# sourceMappingURL=component-summary.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-summary.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/component-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD"}
@@ -1,23 +0,0 @@
1
- import { Command } from 'commander';
2
- import { getDefaultGraphPathDescription } from '../../graph-path';
3
- import { formatSuccess } from '../../output';
4
- import { withGraphBuilder } from './link-infrastructure';
5
- export function createComponentSummaryCommand() {
6
- return new Command('component-summary')
7
- .description('Show component counts by type and domain')
8
- .addHelpText('after', `
9
- Examples:
10
- $ riviere builder component-summary
11
- $ riviere builder component-summary --json
12
- `)
13
- .option('--graph <path>', getDefaultGraphPathDescription())
14
- .option('--json', 'Output result as JSON')
15
- .action(async (options) => {
16
- await withGraphBuilder(options.graph, async (builder) => {
17
- const stats = builder.stats();
18
- if (options.json === true) {
19
- console.log(JSON.stringify(formatSuccess(stats)));
20
- }
21
- });
22
- });
23
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createEnrichCommand(): Command;
3
- //# sourceMappingURL=enrich.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enrich.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/enrich.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDpC,wBAAgB,mBAAmB,IAAI,OAAO,CAsD7C"}
@@ -1,85 +0,0 @@
1
- import { Command } from 'commander';
2
- import { writeFile } from 'node:fs/promises';
3
- import { InvalidEnrichmentTargetError } from '@living-architecture/riviere-builder';
4
- import { withGraphBuilder, handleComponentNotFoundError } from './link-infrastructure';
5
- import { formatError, formatSuccess } from '../../output';
6
- import { CliErrorCode } from '../../error-codes';
7
- import { getDefaultGraphPathDescription } from '../../graph-path';
8
- function collectOption(value, previous) {
9
- return [...previous, value];
10
- }
11
- function parseStateChange(input) {
12
- const [from, to, ...rest] = input.split(':');
13
- if (from === undefined || to === undefined || rest.length > 0) {
14
- return undefined;
15
- }
16
- return { from, to };
17
- }
18
- function parseStateChanges(inputs) {
19
- const stateChanges = [];
20
- for (const sc of inputs) {
21
- const parsed = parseStateChange(sc);
22
- if (parsed === undefined) {
23
- return { success: false, invalidInput: sc };
24
- }
25
- stateChanges.push(parsed);
26
- }
27
- return { success: true, stateChanges };
28
- }
29
- function handleEnrichmentError(error) {
30
- if (error instanceof InvalidEnrichmentTargetError) {
31
- console.log(JSON.stringify(formatError(CliErrorCode.InvalidComponentType, error.message, [])));
32
- return;
33
- }
34
- handleComponentNotFoundError(error);
35
- }
36
- export function createEnrichCommand() {
37
- return new Command('enrich')
38
- .description('Enrich a DomainOp component with entity, state changes, and business rules')
39
- .addHelpText('after', `
40
- Examples:
41
- $ riviere builder enrich \\
42
- --id "orders:checkout:domainop:orderbegin" \\
43
- --entity Order \\
44
- --state-change "Draft:Placed" \\
45
- --business-rule "Order must have at least one item"
46
-
47
- $ riviere builder enrich \\
48
- --id "payments:gateway:domainop:paymentprocess" \\
49
- --state-change "Pending:Processing" \\
50
- --state-change "Processing:Completed" \\
51
- --business-rule "Amount must be positive" \\
52
- --business-rule "Currency must be valid"
53
- `)
54
- .requiredOption('--id <component-id>', 'Component ID to enrich')
55
- .option('--entity <name>', 'Entity name')
56
- .option('--state-change <from:to>', 'State transition (repeatable)', collectOption, [])
57
- .option('--business-rule <rule>', 'Business rule (repeatable)', collectOption, [])
58
- .option('--graph <path>', getDefaultGraphPathDescription())
59
- .option('--json', 'Output result as JSON')
60
- .action(async (options) => {
61
- const parseResult = parseStateChanges(options.stateChange);
62
- if (!parseResult.success) {
63
- const msg = `Invalid state-change format: '${parseResult.invalidInput}'. Expected 'from:to'.`;
64
- console.log(JSON.stringify(formatError(CliErrorCode.ValidationError, msg, [])));
65
- return;
66
- }
67
- await withGraphBuilder(options.graph, async (builder, graphPath) => {
68
- try {
69
- builder.enrichComponent(options.id, {
70
- ...(options.entity !== undefined && { entity: options.entity }),
71
- ...(parseResult.stateChanges.length > 0 && { stateChanges: parseResult.stateChanges }),
72
- ...(options.businessRule.length > 0 && { businessRules: options.businessRule }),
73
- });
74
- }
75
- catch (error) {
76
- handleEnrichmentError(error);
77
- return;
78
- }
79
- await writeFile(graphPath, builder.serialize(), 'utf-8');
80
- if (options.json === true) {
81
- console.log(JSON.stringify(formatSuccess({ componentId: options.id })));
82
- }
83
- });
84
- });
85
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createFinalizeCommand(): Command;
3
- //# sourceMappingURL=finalize.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"finalize.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/finalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,qBAAqB,IAAI,OAAO,CAwC/C"}
@@ -1,37 +0,0 @@
1
- import { Command } from 'commander';
2
- import { writeFile } from 'node:fs/promises';
3
- import { formatError, formatSuccess } from '../../output';
4
- import { CliErrorCode } from '../../error-codes';
5
- import { getDefaultGraphPathDescription } from '../../graph-path';
6
- import { withGraphBuilder } from './link-infrastructure';
7
- export function createFinalizeCommand() {
8
- return new Command('finalize')
9
- .description('Validate and export the final graph')
10
- .addHelpText('after', `
11
- Examples:
12
- $ riviere builder finalize
13
- $ riviere builder finalize --output ./dist/architecture.json
14
- $ riviere builder finalize --json
15
- `)
16
- .option('--graph <path>', getDefaultGraphPathDescription())
17
- .option('--output <path>', 'Output path for finalized graph (defaults to input path)')
18
- .option('--json', 'Output result as JSON')
19
- .action(async (options) => {
20
- await withGraphBuilder(options.graph, async (builder, graphPath) => {
21
- const validationResult = builder.validate();
22
- if (!validationResult.valid) {
23
- const messages = validationResult.errors.map((e) => e.message).join('; ');
24
- console.log(JSON.stringify(formatError(CliErrorCode.ValidationError, `Validation failed: ${messages}`, [
25
- 'Fix the validation errors and try again',
26
- ])));
27
- return;
28
- }
29
- const outputPath = options.output ?? graphPath;
30
- const finalGraph = builder.build();
31
- await writeFile(outputPath, JSON.stringify(finalGraph, null, 2), 'utf-8');
32
- if (options.json === true) {
33
- console.log(JSON.stringify(formatSuccess({ path: outputPath })));
34
- }
35
- });
36
- });
37
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createInitCommand(): Command;
3
- //# sourceMappingURL=init.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqDpC,wBAAgB,iBAAiB,IAAI,OAAO,CAiG3C"}
@@ -1,100 +0,0 @@
1
- import { Command } from 'commander';
2
- import { mkdir, writeFile } from 'node:fs/promises';
3
- import { dirname } from 'node:path';
4
- import { RiviereBuilder } from '@living-architecture/riviere-builder';
5
- import { formatError, formatSuccess } from '../../output';
6
- import { CliErrorCode } from '../../error-codes';
7
- import { fileExists } from '../../file-existence';
8
- import { resolveGraphPath, getDefaultGraphPathDescription } from '../../graph-path';
9
- import { isValidSystemType } from '../../component-types';
10
- function isDomainInputParsed(value) {
11
- if (typeof value !== 'object' || value === null) {
12
- return false;
13
- }
14
- return ('name' in value &&
15
- typeof value.name === 'string' &&
16
- 'description' in value &&
17
- typeof value.description === 'string' &&
18
- 'systemType' in value &&
19
- typeof value.systemType === 'string' &&
20
- isValidSystemType(value.systemType));
21
- }
22
- function parseDomainJson(value, previous) {
23
- const parsed = JSON.parse(value);
24
- if (!isDomainInputParsed(parsed)) {
25
- throw new Error(`Invalid domain JSON: ${value}`);
26
- }
27
- return [...previous, parsed];
28
- }
29
- function collectSource(value, previous) {
30
- return [...previous, value];
31
- }
32
- export function createInitCommand() {
33
- return new Command('init')
34
- .description('Initialize a new graph')
35
- .addHelpText('after', `
36
- Examples:
37
- $ riviere builder init --source https://github.com/org/repo \\
38
- --domain '{"name":"orders","description":"Order management","systemType":"domain"}'
39
-
40
- $ riviere builder init --name "ecommerce" \\
41
- --source https://github.com/org/orders \\
42
- --source https://github.com/org/payments \\
43
- --domain '{"name":"orders","description":"Order management","systemType":"domain"}' \\
44
- --domain '{"name":"payments","description":"Payment processing","systemType":"domain"}'
45
- `)
46
- .option('--name <name>', 'System name')
47
- .option('--graph <path>', getDefaultGraphPathDescription())
48
- .option('--json', 'Output result as JSON')
49
- .option('--source <url>', 'Source repository URL (repeatable)', collectSource, [])
50
- .option('--domain <json>', 'Domain as JSON (repeatable)', parseDomainJson, [])
51
- .action(async (options) => {
52
- // Validate required flags
53
- if (options.source.length === 0) {
54
- console.log(JSON.stringify(formatError(CliErrorCode.ValidationError, 'At least one source required', [
55
- 'Add --source <url> flag',
56
- ])));
57
- return;
58
- }
59
- if (options.domain.length === 0) {
60
- console.log(JSON.stringify(formatError(CliErrorCode.ValidationError, 'At least one domain required', [
61
- 'Add --domain <json> flag',
62
- ])));
63
- return;
64
- }
65
- const graphPath = resolveGraphPath(options.graph);
66
- const graphDir = dirname(graphPath);
67
- const graphExists = await fileExists(graphPath);
68
- if (graphExists) {
69
- console.log(JSON.stringify(formatError(CliErrorCode.GraphExists, `Graph already exists at ${graphPath}`, [
70
- 'Delete the file to reinitialize',
71
- ])));
72
- return;
73
- }
74
- const domains = {};
75
- for (const d of options.domain) {
76
- domains[d.name] = {
77
- description: d.description,
78
- systemType: d.systemType,
79
- };
80
- }
81
- const builderOptions = {
82
- sources: options.source.map((url) => ({ repository: url })),
83
- domains,
84
- };
85
- if (options.name !== undefined) {
86
- builderOptions.name = options.name;
87
- }
88
- const builder = RiviereBuilder.new(builderOptions);
89
- await mkdir(graphDir, { recursive: true });
90
- await writeFile(graphPath, builder.serialize(), 'utf-8');
91
- if (options.json === true) {
92
- const domainNames = options.domain.map((d) => d.name);
93
- console.log(JSON.stringify(formatSuccess({
94
- path: graphPath,
95
- sources: options.source.length,
96
- domains: domainNames,
97
- })));
98
- }
99
- });
100
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createLinkExternalCommand(): Command;
3
- //# sourceMappingURL=link-external.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"link-external.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/link-external.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC,wBAAgB,yBAAyB,IAAI,OAAO,CAiEnD"}
@@ -1,70 +0,0 @@
1
- import { Command } from 'commander';
2
- import { writeFile } from 'node:fs/promises';
3
- import { getDefaultGraphPathDescription, resolveGraphPath } from '../../graph-path';
4
- import { fileExists } from '../../file-existence';
5
- import { formatSuccess } from '../../output';
6
- import { isValidLinkType } from '../../component-types';
7
- import { validateLinkType } from '../../validation';
8
- import { loadGraphBuilder, reportGraphNotFound, tryBuilderOperation } from './link-infrastructure';
9
- function buildExternalTarget(options) {
10
- return {
11
- name: options.targetName,
12
- ...(options.targetDomain && { domain: options.targetDomain }),
13
- ...(options.targetUrl && { url: options.targetUrl }),
14
- };
15
- }
16
- export function createLinkExternalCommand() {
17
- return new Command('link-external')
18
- .description('Link a component to an external system')
19
- .addHelpText('after', `
20
- Examples:
21
- $ riviere builder link-external \\
22
- --from "payments:gateway:usecase:processpayment" \\
23
- --target-name "Stripe" \\
24
- --target-url "https://api.stripe.com" \\
25
- --link-type sync
26
-
27
- $ riviere builder link-external \\
28
- --from "shipping:tracking:usecase:updatetracking" \\
29
- --target-name "FedEx API" \\
30
- --target-domain "shipping" \\
31
- --link-type async
32
- `)
33
- .requiredOption('--from <component-id>', 'Source component ID')
34
- .requiredOption('--target-name <name>', 'External target name')
35
- .option('--target-domain <domain>', 'External target domain')
36
- .option('--target-url <url>', 'External target URL')
37
- .option('--link-type <type>', 'Link type (sync, async)')
38
- .option('--graph <path>', getDefaultGraphPathDescription())
39
- .option('--json', 'Output result as JSON')
40
- .action(async (options) => {
41
- const linkTypeValidation = validateLinkType(options.linkType);
42
- if (!linkTypeValidation.valid) {
43
- console.log(linkTypeValidation.errorJson);
44
- return;
45
- }
46
- const graphPath = resolveGraphPath(options.graph);
47
- const graphExists = await fileExists(graphPath);
48
- if (!graphExists) {
49
- reportGraphNotFound(graphPath);
50
- return;
51
- }
52
- const builder = await loadGraphBuilder(graphPath);
53
- const target = buildExternalTarget(options);
54
- const externalLinkInput = {
55
- from: options.from,
56
- target,
57
- };
58
- if (options.linkType !== undefined && isValidLinkType(options.linkType)) {
59
- externalLinkInput.type = options.linkType;
60
- }
61
- const externalLink = tryBuilderOperation(() => builder.linkExternal(externalLinkInput));
62
- if (externalLink === undefined) {
63
- return;
64
- }
65
- await writeFile(graphPath, builder.serialize(), 'utf-8');
66
- if (options.json) {
67
- console.log(JSON.stringify(formatSuccess({ externalLink })));
68
- }
69
- });
70
- }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createLinkHttpCommand(): Command;
3
- //# sourceMappingURL=link-http.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"link-http.d.ts","sourceRoot":"","sources":["../../../src/commands/builder/link-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoGpC,wBAAgB,qBAAqB,IAAI,OAAO,CA+F/C"}