eventmodeler 0.6.0 → 0.6.2

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 (73) hide show
  1. package/dist/index.js +7133 -34
  2. package/package.json +5 -4
  3. package/dist/api/client-config.js +0 -10
  4. package/dist/api/generated/client/client.gen.js +0 -235
  5. package/dist/api/generated/client/index.js +0 -6
  6. package/dist/api/generated/client/types.gen.js +0 -2
  7. package/dist/api/generated/client/utils.gen.js +0 -228
  8. package/dist/api/generated/client.gen.js +0 -4
  9. package/dist/api/generated/core/auth.gen.js +0 -14
  10. package/dist/api/generated/core/bodySerializer.gen.js +0 -57
  11. package/dist/api/generated/core/params.gen.js +0 -100
  12. package/dist/api/generated/core/pathSerializer.gen.js +0 -106
  13. package/dist/api/generated/core/queryKeySerializer.gen.js +0 -92
  14. package/dist/api/generated/core/serverSentEvents.gen.js +0 -133
  15. package/dist/api/generated/core/types.gen.js +0 -2
  16. package/dist/api/generated/core/utils.gen.js +0 -87
  17. package/dist/api/generated/index.js +0 -2
  18. package/dist/api/generated/sdk.gen.js +0 -4222
  19. package/dist/api/generated/types.gen.js +0 -2
  20. package/dist/api/generated/zod.gen.js +0 -7217
  21. package/dist/commands/add.js +0 -315
  22. package/dist/commands/auth.js +0 -14
  23. package/dist/commands/create.js +0 -192
  24. package/dist/commands/design.js +0 -108
  25. package/dist/commands/guide.js +0 -15
  26. package/dist/commands/init.js +0 -21
  27. package/dist/commands/list-schemas.js +0 -177
  28. package/dist/commands/list.js +0 -39
  29. package/dist/commands/loop.js +0 -101
  30. package/dist/commands/map.js +0 -40
  31. package/dist/commands/mark.js +0 -27
  32. package/dist/commands/move.js +0 -35
  33. package/dist/commands/remove.js +0 -170
  34. package/dist/commands/rename.js +0 -53
  35. package/dist/commands/resize.js +0 -30
  36. package/dist/commands/search.js +0 -14
  37. package/dist/commands/set.js +0 -199
  38. package/dist/commands/show-schemas.js +0 -259
  39. package/dist/commands/show.js +0 -56
  40. package/dist/commands/summary.js +0 -13
  41. package/dist/commands/update.js +0 -240
  42. package/dist/lib/auth.js +0 -331
  43. package/dist/lib/config.js +0 -80
  44. package/dist/lib/excalidraw-schema.js +0 -66
  45. package/dist/lib/globals.js +0 -8
  46. package/dist/lib/model.js +0 -11
  47. package/dist/lib/project-config.js +0 -103
  48. package/dist/lib/resolve.js +0 -59
  49. package/dist/lib/scenario.js +0 -15
  50. package/dist/slices/add-scenario/index.js +0 -103
  51. package/dist/slices/guide/guides/codegen.js +0 -339
  52. package/dist/slices/guide/guides/connect-slices.js +0 -202
  53. package/dist/slices/guide/guides/create-slices.js +0 -273
  54. package/dist/slices/guide/guides/explore.js +0 -238
  55. package/dist/slices/guide/guides/information-flow.js +0 -304
  56. package/dist/slices/guide/guides/scenarios.js +0 -214
  57. package/dist/slices/guide/index.js +0 -40
  58. package/dist/slices/help/index.js +0 -96
  59. package/dist/slices/help/topics/build-codegen.js +0 -109
  60. package/dist/slices/help/topics/build-slice.js +0 -147
  61. package/dist/slices/help/topics/check-completeness.js +0 -57
  62. package/dist/slices/help/topics/connect-slices.js +0 -99
  63. package/dist/slices/help/topics/explore-model.js +0 -112
  64. package/dist/slices/help/topics/json-reference.js +0 -188
  65. package/dist/slices/help/topics/linked-copies.js +0 -89
  66. package/dist/slices/help/topics/manipulate-canvas.js +0 -150
  67. package/dist/slices/help/topics/write-scenarios.js +0 -162
  68. package/dist/slices/init/index.js +0 -86
  69. package/dist/slices/init/loop.js +0 -60
  70. package/dist/slices/login/index.js +0 -20
  71. package/dist/slices/logout/index.js +0 -14
  72. package/dist/slices/open-app/index.js +0 -36
  73. package/dist/slices/whoami/index.js +0 -19
@@ -1,21 +0,0 @@
1
- import { init } from '../slices/init/index';
2
- import { initLoop } from '../slices/init/loop';
3
- export function registerInitCommands(program) {
4
- const cmd = program.command('init')
5
- .description('Initialize project and link to an event model')
6
- .action(() => init());
7
- cmd.command('loop')
8
- .description('Scaffold a loop config and sample generate.sh script')
9
- .addHelpText('after', `
10
- Writes a default "loop" block to .eventmodeler.json:
11
- { "loop": { "command": "./generate.sh", "interval": 30 } }
12
-
13
- And creates generate.sh — a script skeleton that marks the slice
14
- in-progress, exports it as JSON, runs your codegen, and marks
15
- done/blocked. Edit generate.sh to plug in your own logic.
16
-
17
- Run the loop with:
18
- eventmodeler loop
19
- `)
20
- .action(() => initLoop());
21
- }
@@ -1,177 +0,0 @@
1
- // Response shapes for list/summary/search commands, pulled from the backend ReadModels.
2
- // Attached to each command's --help so agents can consume without out-of-band docs.
3
- const envelope = (itemShape) => `Response (JSON on stdout):
4
-
5
- {
6
- "items": [
7
- ${itemShape.split('\n').map((l) => ` ${l}`).join('\n')}
8
- ]
9
- }`;
10
- export const LIST_SLICES_HELP = `
11
- ${envelope(`{
12
- "sliceId": "<uuid>",
13
- "modelId": "<uuid>",
14
- "name": "Place Order",
15
- "status": "created" | "planned" | "in-progress" | "blocked" | "done",
16
- "chapterName": "User Onboarding" | null,
17
- "x": 0, "y": 0, "width": 0, "height": 0
18
- }`)}
19
-
20
- Filter locally with jq:
21
- eventmodeler list slices | jq '[.items[] | select(.status=="planned")]'
22
- `;
23
- export const LIST_EVENTS_HELP = `
24
- ${envelope(`{
25
- "eventStickyId": "<uuid>",
26
- "modelId": "<uuid>",
27
- "name": "OrderPlaced",
28
- "aggregateName": "Order" | null,
29
- "fieldCount": 0,
30
- "copyCount": 0,
31
- "isLinkedCopy": false,
32
- "originalId": "<uuid>" | null,
33
- "originSlice": "Place Order" | null,
34
- "x": 0, "y": 0, "width": 0, "height": 0
35
- }`)}
36
- `;
37
- export const LIST_COMMANDS_HELP = `
38
- ${envelope(`{
39
- "commandStickyId": "<uuid>",
40
- "modelId": "<uuid>",
41
- "name": "PlaceOrder",
42
- "fieldCount": 0,
43
- "x": 0, "y": 0
44
- }`)}
45
- `;
46
- export const LIST_READMODELS_HELP = `
47
- ${envelope(`{
48
- "readModelStickyId": "<uuid>",
49
- "modelId": "<uuid>",
50
- "name": "OrderSummary",
51
- "fieldCount": 0,
52
- "isLinkedCopy": false,
53
- "originalId": "<uuid>" | null,
54
- "x": 0, "y": 0
55
- }`)}
56
- `;
57
- export const LIST_SCREENS_HELP = `
58
- ${envelope(`{
59
- "screenId": "<uuid>",
60
- "modelId": "<uuid>",
61
- "name": "OrderForm",
62
- "actorId": "<uuid>" | null,
63
- "actorName": "Customer" | null,
64
- "fieldCount": 0,
65
- "x": 0, "y": 0, "width": 0, "height": 0
66
- }`)}
67
- `;
68
- export const LIST_PROCESSORS_HELP = `
69
- ${envelope(`{
70
- "processorId": "<uuid>",
71
- "modelId": "<uuid>",
72
- "name": "PaymentProcessor",
73
- "fieldCount": 0,
74
- "x": 0, "y": 0
75
- }`)}
76
- `;
77
- export const LIST_EXTERNAL_EVENTS_HELP = `
78
- ${envelope(`{
79
- "externalEventId": "<uuid>",
80
- "modelId": "<uuid>",
81
- "name": "StripeChargeSucceeded",
82
- "fieldCount": 0,
83
- "isLinkedCopy": false,
84
- "originalId": "<uuid>" | null,
85
- "x": 0, "y": 0, "width": 0, "height": 0
86
- }`)}
87
- `;
88
- export const LIST_AGGREGATES_HELP = `
89
- ${envelope(`{
90
- "aggregateId": "<uuid>",
91
- "modelId": "<uuid>",
92
- "name": "Order",
93
- "eventCount": 0,
94
- "idFieldName": "orderId" | null,
95
- "idFieldType": "UUID" | null,
96
- "x": 0, "y": 0, "width": 0, "height": 0
97
- }`)}
98
- `;
99
- export const LIST_ACTORS_HELP = `
100
- ${envelope(`{
101
- "actorId": "<uuid>",
102
- "modelId": "<uuid>",
103
- "name": "Customer",
104
- "screenCount": 0,
105
- "x": 0, "y": 0, "width": 0, "height": 0
106
- }`)}
107
- `;
108
- export const LIST_CHAPTERS_HELP = `
109
- ${envelope(`{
110
- "chapterId": "<uuid>",
111
- "modelId": "<uuid>",
112
- "name": "User Onboarding",
113
- "x": 0, "y": 0, "width": 0, "height": 0
114
- }`)}
115
- `;
116
- export const LIST_CONTEXTS_HELP = `
117
- ${envelope(`{
118
- "contextId": "<uuid>",
119
- "modelId": "<uuid>",
120
- "name": "Orders",
121
- "x": 0, "y": 0, "width": 0, "height": 0
122
- }`)}
123
- `;
124
- export const LIST_SWIMLANES_HELP = `
125
- ${envelope(`{
126
- "swimLaneId": "<uuid>",
127
- "modelId": "<uuid>",
128
- "name": "Finance",
129
- "x": 0, "y": 0, "width": 0, "height": 0
130
- }`)}
131
- `;
132
- export const LIST_NOTES_HELP = `
133
- ${envelope(`{
134
- "noteId": "<uuid>",
135
- "modelId": "<uuid>",
136
- "name": "Reminder",
137
- "description": "Handle retries",
138
- "x": 0, "y": 0, "width": 0, "height": 0
139
- }`)}
140
- `;
141
- export const LIST_SCENARIOS_HELP = `
142
- ${envelope(`{
143
- "scenarioId": "<uuid>",
144
- "modelId": "<uuid>",
145
- "name": "happy path",
146
- "sliceId": "<uuid>" | null,
147
- "sliceName": "Place Order" | null
148
- }`)}
149
- `;
150
- export const SUMMARY_HELP = `
151
- Response (JSON on stdout):
152
-
153
- {
154
- "modelId": "<uuid>",
155
- "actorCount": 0,
156
- "aggregateCount": 0,
157
- "chapterCount": 0,
158
- "commandCount": 0,
159
- "eventCount": 0,
160
- "flowCount": 0,
161
- "processorCount": 0,
162
- "readModelCount": 0,
163
- "scenarioCount": 0,
164
- "screenCount": 0,
165
- "sliceCount": 0
166
- }
167
- `;
168
- export const SEARCH_HELP = `
169
- ${envelope(`{
170
- "elementId": "<uuid>",
171
- "modelId": "<uuid>",
172
- "elementType": "event" | "command" | "readmodel" | "screen"
173
- | "processor" | "external-event" | "slice"
174
- | "chapter" | "context" | "aggregate" | "actor",
175
- "name": "OrderPlaced"
176
- }`)}
177
- `;
@@ -1,39 +0,0 @@
1
- import { requireModelId } from '../lib/model';
2
- import { unwrap, out } from '../lib/resolve';
3
- import * as sdk from '../api/generated/sdk.gen';
4
- import { LIST_SLICES_HELP, LIST_EVENTS_HELP, LIST_COMMANDS_HELP, LIST_READMODELS_HELP, LIST_SCREENS_HELP, LIST_PROCESSORS_HELP, LIST_EXTERNAL_EVENTS_HELP, LIST_AGGREGATES_HELP, LIST_ACTORS_HELP, LIST_CHAPTERS_HELP, LIST_CONTEXTS_HELP, LIST_SWIMLANES_HELP, LIST_NOTES_HELP, LIST_SCENARIOS_HELP, } from './list-schemas';
5
- export function registerListCommands(program) {
6
- const list = program.command('list').description('List entities in the model');
7
- list.command('slices')
8
- .description('List all slices')
9
- .option('--chapter <name>', 'Filter by chapter')
10
- .addHelpText('after', LIST_SLICES_HELP)
11
- .action(async (opts) => {
12
- const modelId = requireModelId();
13
- out(unwrap(await sdk.listSlices({ path: { modelId }, query: { search: opts.chapter } })));
14
- });
15
- const entries = [
16
- ['events', sdk.listEvents, LIST_EVENTS_HELP],
17
- ['commands', sdk.listCommands, LIST_COMMANDS_HELP],
18
- ['chapters', sdk.listChapters, LIST_CHAPTERS_HELP],
19
- ['aggregates', sdk.listAggregates, LIST_AGGREGATES_HELP],
20
- ['actors', sdk.listActors, LIST_ACTORS_HELP],
21
- ['readmodels', sdk.listReadModels, LIST_READMODELS_HELP],
22
- ['screens', sdk.listScreens, LIST_SCREENS_HELP],
23
- ['processors', sdk.listProcessors, LIST_PROCESSORS_HELP],
24
- ['scenarios', sdk.listScenarios, LIST_SCENARIOS_HELP],
25
- ['contexts', sdk.listContexts, LIST_CONTEXTS_HELP],
26
- ['swimlanes', sdk.listSwimLanes, LIST_SWIMLANES_HELP],
27
- ['notes', sdk.listNotes, LIST_NOTES_HELP],
28
- ['external-events', sdk.listExternalEvents, LIST_EXTERNAL_EVENTS_HELP],
29
- ];
30
- for (const [name, fn, help] of entries) {
31
- list.command(name)
32
- .description(`List all ${name}`)
33
- .addHelpText('after', help)
34
- .action(async () => {
35
- const modelId = requireModelId();
36
- out(unwrap(await fn({ path: { modelId } })));
37
- });
38
- }
39
- }
@@ -1,101 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { requireModelId } from '../lib/model';
3
- import { loadLoopConfig } from '../lib/project-config';
4
- import { unwrap } from '../lib/resolve';
5
- import * as sdk from '../api/generated/sdk.gen';
6
- export function registerLoopCommands(program) {
7
- const loop = program.command('loop')
8
- .description('Poll the model for planned slices and run a command against each')
9
- .addHelpText('after', `
10
- Config (.eventmodeler.json):
11
- {
12
- "loop": {
13
- "command": "./run-agent.sh",
14
- "interval": 30
15
- }
16
- }
17
-
18
- How it works:
19
- 1. Every <interval> seconds, fetch all slices
20
- 2. For each slice with status "planned", run: <command> <sliceName>
21
- 3. Repeat
22
-
23
- Script contract:
24
- Your script owns every status transition.
25
- - Mark the slice "in-progress" at the start so the next poll skips it.
26
- - Mark "done" on success or "blocked" on failure before exiting.
27
- - If the script crashes without marking, the slice stays "planned"
28
- and the next poll retries it (self-healing).
29
-
30
- Inside your script:
31
- SLICE="$1"
32
- eventmodeler mark "$SLICE" in-progress
33
- eventmodeler show slice "$SLICE" > slice.json
34
- # ... do codegen / call an AI / run tests ...
35
- eventmodeler mark "$SLICE" done # or: mark "$SLICE" blocked
36
-
37
- Other valid commands: any shell-runnable invocation (python run.py,
38
- node handler.js, claude -p '...'). The slice name is appended as the
39
- final argument.
40
-
41
- Stop the loop with Ctrl+C.
42
- `);
43
- loop.action(async () => {
44
- const modelId = requireModelId();
45
- const config = loadLoopConfig();
46
- if (!config) {
47
- console.error('Error: No "loop" config in .eventmodeler.json.');
48
- console.error('Add: { "loop": { "command": "./your-script.sh", "interval": 30 } }');
49
- process.exit(1);
50
- }
51
- const { command, interval } = config;
52
- console.log(`Loop started. Polling every ${interval}s. Command: ${command}`);
53
- console.log('Press Ctrl+C to stop.');
54
- let stopping = false;
55
- process.on('SIGINT', () => {
56
- if (stopping)
57
- process.exit(1);
58
- stopping = true;
59
- console.log('\nStopping after current iteration...');
60
- });
61
- while (!stopping) {
62
- await tick(modelId, command);
63
- if (stopping)
64
- break;
65
- await sleep(interval * 1000);
66
- }
67
- process.exit(0);
68
- });
69
- }
70
- async function tick(modelId, command) {
71
- const stamp = new Date().toISOString();
72
- try {
73
- const result = unwrap(await sdk.listSlices({ path: { modelId }, query: {} }));
74
- const planned = result.items.filter((s) => s.status === 'planned');
75
- if (planned.length === 0) {
76
- console.log(`[${stamp}] No planned slices.`);
77
- return;
78
- }
79
- console.log(`[${stamp}] ${planned.length} planned slice(s).`);
80
- for (const slice of planned) {
81
- console.log(` -> ${slice.name}`);
82
- await runScript(command, slice.name);
83
- }
84
- }
85
- catch (err) {
86
- console.error(`[${stamp}] Poll error: ${err.message ?? err}`);
87
- }
88
- }
89
- function runScript(command, sliceName) {
90
- return new Promise((resolve) => {
91
- const child = spawn(command, [sliceName], { stdio: 'inherit', shell: true });
92
- child.on('close', () => resolve());
93
- child.on('error', (err) => {
94
- console.error(`Script error: ${err.message}`);
95
- resolve();
96
- });
97
- });
98
- }
99
- function sleep(ms) {
100
- return new Promise((resolve) => setTimeout(resolve, ms));
101
- }
@@ -1,40 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { requireModelId } from '../lib/model';
3
- import { resolveAnyElement, unwrap } from '../lib/resolve';
4
- import * as sdk from '../api/generated/sdk.gen';
5
- export function registerMapCommands(program) {
6
- program.command('map')
7
- .description('Map fields between elements')
8
- .command('fields <json>')
9
- .description('Add field mappings to a flow')
10
- .requiredOption('--from <source>', 'Source element name')
11
- .requiredOption('--to <target>', 'Target element name')
12
- .action(async (json, opts) => {
13
- const modelId = requireModelId();
14
- const { elementId: sourceId } = await resolveAnyElement(modelId, opts.from);
15
- const { elementId: targetId } = await resolveAnyElement(modelId, opts.to);
16
- const flowResult = unwrap(await sdk.resolveFlow({
17
- query: { modelId, sourceId, targetId }
18
- }));
19
- const flowId = flowResult.flowId;
20
- const mappings = JSON.parse(json);
21
- for (const m of mappings) {
22
- const sourceResolve = unwrap(await sdk.resolveField({
23
- query: { modelId, elementId: sourceId, fieldName: m.source }
24
- }));
25
- const targetResolve = unwrap(await sdk.resolveField({
26
- query: { modelId, elementId: targetId, fieldName: m.target }
27
- }));
28
- unwrap(await sdk.addFieldMapping({
29
- body: {
30
- modelId,
31
- flowId,
32
- mappingId: randomUUID(),
33
- sourceFieldId: sourceResolve.fieldId,
34
- targetFieldId: targetResolve.fieldId,
35
- }
36
- }));
37
- }
38
- console.log(`Added ${mappings.length} field mapping(s).`);
39
- });
40
- }
@@ -1,27 +0,0 @@
1
- import { getGlobalId } from '../lib/globals';
2
- import { requireModelId } from '../lib/model';
3
- import { resolve, unwrap } from '../lib/resolve';
4
- import * as sdk from '../api/generated/sdk.gen';
5
- const STATUS_MAP = {
6
- planned: sdk.markSliceAsPlanned,
7
- created: sdk.markSliceAsCreated,
8
- 'in-progress': sdk.markSliceAsInProgress,
9
- blocked: sdk.markSliceAsBlocked,
10
- done: sdk.markSliceAsDone,
11
- };
12
- export function registerMarkCommands(program) {
13
- program.command('mark [sliceName] <status>')
14
- .description('Mark a slice status (planned|created|in-progress|blocked|done)')
15
- .action(async (sliceNameOrStatus, statusOrUndefined, cmd) => {
16
- const modelId = requireModelId();
17
- const hasId = getGlobalId();
18
- const sliceName = statusOrUndefined ? sliceNameOrStatus : '';
19
- const status = statusOrUndefined ?? sliceNameOrStatus;
20
- const fn = STATUS_MAP[status];
21
- if (!fn)
22
- throw new Error(`Unknown status: ${status}. Valid: ${Object.keys(STATUS_MAP).join(', ')}`);
23
- const sliceId = await resolve(modelId, 'slice', sliceName, hasId);
24
- unwrap(await fn({ body: { modelId, sliceId } }));
25
- console.log(`Marked slice as ${status}.`);
26
- });
27
- }
@@ -1,35 +0,0 @@
1
- import { getGlobalId } from '../lib/globals';
2
- import { requireModelId } from '../lib/model';
3
- import { resolve, unwrap, elementIdKey } from '../lib/resolve';
4
- import * as sdk from '../api/generated/sdk.gen';
5
- const MOVE_MAP = {
6
- slice: sdk.moveSlice,
7
- command: sdk.moveCommandSticky,
8
- event: sdk.moveEventSticky,
9
- readmodel: sdk.moveReadModelSticky,
10
- screen: sdk.moveScreen,
11
- processor: sdk.moveProcessor,
12
- aggregate: sdk.moveAggregate,
13
- actor: sdk.moveActor,
14
- chapter: sdk.moveChapter,
15
- context: sdk.moveContext,
16
- 'external-event': sdk.moveExternalEvent,
17
- note: sdk.moveNote,
18
- swimlane: sdk.moveSwimLane,
19
- };
20
- export function registerMoveCommands(program) {
21
- program.command('move <type> [name]')
22
- .description('Move an element to a new position')
23
- .requiredOption('--x <n>', 'X coordinate', Number)
24
- .requiredOption('--y <n>', 'Y coordinate', Number)
25
- .action(async (type, name, opts, cmd) => {
26
- const modelId = requireModelId();
27
- const fn = MOVE_MAP[type];
28
- if (!fn)
29
- throw new Error(`Unknown type: ${type}. Valid types: ${Object.keys(MOVE_MAP).join(', ')}`);
30
- const id = await resolve(modelId, type, name ?? '', getGlobalId());
31
- const key = elementIdKey(type);
32
- unwrap(await fn({ body: { modelId, [key]: id, x: opts.x, y: opts.y } }));
33
- console.log(`Moved ${type} to (${opts.x}, ${opts.y}).`);
34
- });
35
- }
@@ -1,170 +0,0 @@
1
- import { getGlobalId } from '../lib/globals';
2
- import { requireModelId } from '../lib/model';
3
- import { resolve, resolveAnyElement, unwrap, elementIdKey } from '../lib/resolve';
4
- import { resolveScenarioId } from '../lib/scenario';
5
- import * as sdk from '../api/generated/sdk.gen';
6
- const REMOVE_MAP = {
7
- slice: sdk.removeSlice,
8
- command: sdk.removeCommandSticky,
9
- event: sdk.removeEventSticky,
10
- readmodel: sdk.removeReadModelSticky,
11
- screen: sdk.removeScreen,
12
- processor: sdk.removeProcessor,
13
- aggregate: sdk.removeAggregate,
14
- actor: sdk.removeActor,
15
- chapter: sdk.removeChapter,
16
- context: sdk.removeContext,
17
- 'external-event': sdk.removeExternalEvent,
18
- note: sdk.removeNote,
19
- swimlane: sdk.removeSwimLane,
20
- };
21
- const REMOVE_FIELD_MAP = {
22
- command: sdk.removeCommandField,
23
- event: sdk.removeEventField,
24
- readmodel: sdk.removeReadModelField,
25
- screen: sdk.removeScreenField,
26
- processor: sdk.removeProcessorField,
27
- 'external-event': sdk.removeExternalEventField,
28
- };
29
- const REMOVE_SUBFIELD_MAP = {
30
- command: sdk.removeCommandSubfield,
31
- event: sdk.removeEventSubfield,
32
- readmodel: sdk.removeReadModelSubfield,
33
- screen: sdk.removeScreenSubfield,
34
- processor: sdk.removeProcessorSubfield,
35
- 'external-event': sdk.removeExternalEventSubfield,
36
- };
37
- export function registerRemoveCommands(program) {
38
- const remove = program.command('remove').description('Remove elements from the model');
39
- // remove <type> [name] — generic element removal
40
- for (const [type, fn] of Object.entries(REMOVE_MAP)) {
41
- if (type === 'scenario')
42
- continue; // handled separately below
43
- remove.command(`${type} [name]`)
44
- .description(`Remove a ${type}`)
45
- .action(async (name, cmd) => {
46
- const modelId = requireModelId();
47
- const id = await resolve(modelId, type, name ?? '', getGlobalId());
48
- const key = elementIdKey(type);
49
- unwrap(await fn({ body: { modelId, [key]: id } }));
50
- console.log(`Removed ${type}.`);
51
- });
52
- }
53
- // remove scenario [name]
54
- remove.command('scenario [name]')
55
- .description('Remove a scenario')
56
- .action(async (name) => {
57
- const modelId = requireModelId();
58
- const scenarioId = await resolveScenarioId(modelId, name ?? '', getGlobalId());
59
- unwrap(await sdk.removeScenario({ body: { modelId, scenarioId } }));
60
- console.log('Removed scenario.');
61
- });
62
- // remove field <elementName> --field <name>
63
- remove.command('field [elementName]')
64
- .description('Remove a field from an element')
65
- .requiredOption('--field <name>', 'Field name to remove')
66
- .action(async (elementName, opts, cmd) => {
67
- const modelId = requireModelId();
68
- const { elementId, elementType } = await resolveAnyElement(modelId, elementName ?? '', getGlobalId());
69
- const fn = REMOVE_FIELD_MAP[elementType];
70
- if (!fn)
71
- throw new Error(`Cannot remove fields from type: ${elementType}`);
72
- const fieldResult = unwrap(await sdk.resolveField({
73
- query: { modelId, elementId, fieldName: opts.field }
74
- }));
75
- const fieldId = fieldResult.fieldId;
76
- const key = elementIdKey(elementType);
77
- unwrap(await fn({ body: { modelId, [key]: elementId, fieldId } }));
78
- console.log(`Removed field "${opts.field}".`);
79
- });
80
- // remove subfield [elementName] --subfield <subfieldId>
81
- remove.command('subfield [elementName]')
82
- .description('Remove a subfield from an element')
83
- .requiredOption('--subfield <id>', 'Subfield ID (from show output)')
84
- .action(async (elementName, opts, cmd) => {
85
- const modelId = requireModelId();
86
- const { elementId, elementType } = await resolveAnyElement(modelId, elementName ?? '', getGlobalId());
87
- const fn = REMOVE_SUBFIELD_MAP[elementType];
88
- if (!fn)
89
- throw new Error(`Cannot remove subfields from type: ${elementType}`);
90
- const key = elementIdKey(elementType);
91
- unwrap(await fn({ body: { modelId, [key]: elementId, subfieldId: opts.subfield } }));
92
- console.log('Removed subfield.');
93
- });
94
- // remove mapping --from <source> --to <target> --mapping <mappingId>
95
- remove.command('mapping')
96
- .description('Remove a field mapping from a flow')
97
- .requiredOption('--from <source>', 'Source element name')
98
- .requiredOption('--to <target>', 'Target element name')
99
- .requiredOption('--mapping <id>', 'Mapping ID (from show output)')
100
- .action(async (opts) => {
101
- const modelId = requireModelId();
102
- const { elementId: sourceId } = await resolveAnyElement(modelId, opts.from);
103
- const { elementId: targetId } = await resolveAnyElement(modelId, opts.to);
104
- const flowResult = unwrap(await sdk.resolveFlow({
105
- query: { modelId, sourceId, targetId }
106
- }));
107
- const flowId = flowResult.flowId;
108
- unwrap(await sdk.removeFieldMapping({ body: { modelId, flowId, mappingId: opts.mapping } }));
109
- console.log('Removed field mapping.');
110
- });
111
- // remove entry --scenario <name> --section given|when|then --entry <entryId>
112
- const REMOVE_ENTRY_MAP = {
113
- given: sdk.removeScenarioGivenEntry,
114
- when: sdk.removeScenarioWhenEntry,
115
- then: sdk.removeScenarioThenEntry,
116
- };
117
- remove.command('entry')
118
- .description('Remove a GWT entry from a scenario')
119
- .requiredOption('--scenario <name>', 'Scenario name')
120
- .requiredOption('--section <section>', 'Section: given, when, or then')
121
- .requiredOption('--entry <entryId>', 'Entry ID (from show output)')
122
- .action(async (opts) => {
123
- const modelId = requireModelId();
124
- const scenarioId = await resolveScenarioId(modelId, opts.scenario, getGlobalId());
125
- const fn = REMOVE_ENTRY_MAP[opts.section];
126
- if (!fn)
127
- throw new Error(`Unknown section: ${opts.section}. Use given, when, or then.`);
128
- unwrap(await fn({ body: { modelId, scenarioId, entryId: opts.entry } }));
129
- console.log(`Removed ${opts.section} entry.`);
130
- });
131
- // remove example --scenario <name> --entry <entryId> --type event|command|readmodel --field <name>
132
- const REMOVE_FIELD_VALUE_MAP = {
133
- event: sdk.removeScenarioEventFieldValue,
134
- command: sdk.removeScenarioCommandFieldValue,
135
- readmodel: sdk.removeScenarioReadModelFieldValue,
136
- };
137
- remove.command('example')
138
- .description('Remove a field example value from a scenario entry')
139
- .requiredOption('--scenario <name>', 'Scenario name')
140
- .requiredOption('--entry <entryId>', 'Entry ID (from show output)')
141
- .requiredOption('--type <type>', 'Entry type: event, command, or readmodel')
142
- .requiredOption('--field <name>', 'Field name to clear')
143
- .action(async (opts) => {
144
- const modelId = requireModelId();
145
- const scenarioId = await resolveScenarioId(modelId, opts.scenario, getGlobalId());
146
- const fn = REMOVE_FIELD_VALUE_MAP[opts.type];
147
- if (!fn)
148
- throw new Error(`Cannot remove examples from type: ${opts.type}. Use event, command, or readmodel.`);
149
- unwrap(await fn({
150
- body: { modelId, scenarioId, entryId: opts.entry, fieldName: opts.field }
151
- }));
152
- console.log(`Removed example "${opts.field}".`);
153
- });
154
- // remove flow --from <source> --to <target>
155
- remove.command('flow')
156
- .description('Remove a flow between two elements')
157
- .requiredOption('--from <source>', 'Source element name')
158
- .requiredOption('--to <target>', 'Target element name')
159
- .action(async (opts) => {
160
- const modelId = requireModelId();
161
- const { elementId: sourceId } = await resolveAnyElement(modelId, opts.from);
162
- const { elementId: targetId } = await resolveAnyElement(modelId, opts.to);
163
- const flowResult = unwrap(await sdk.resolveFlow({
164
- query: { modelId, sourceId, targetId }
165
- }));
166
- const flowId = flowResult.flowId;
167
- unwrap(await sdk.removeFlow({ body: { modelId, flowId } }));
168
- console.log('Removed flow.');
169
- });
170
- }
@@ -1,53 +0,0 @@
1
- import { getGlobalId } from '../lib/globals';
2
- import { requireModelId } from '../lib/model';
3
- import { resolve, unwrap, elementIdKey } from '../lib/resolve';
4
- import * as sdk from '../api/generated/sdk.gen';
5
- const RENAME_MAP = {
6
- slice: sdk.renameSlice,
7
- command: sdk.renameCommandSticky,
8
- event: sdk.renameEventSticky,
9
- readmodel: sdk.renameReadModelSticky,
10
- screen: sdk.renameScreen,
11
- processor: sdk.renameProcessor,
12
- aggregate: sdk.renameAggregate,
13
- actor: sdk.renameActor,
14
- chapter: sdk.renameChapter,
15
- context: sdk.renameContext,
16
- scenario: sdk.renameScenario,
17
- 'external-event': sdk.renameExternalEvent,
18
- note: sdk.renameNote,
19
- swimlane: sdk.renameSwimLane,
20
- };
21
- export function registerRenameCommands(program) {
22
- program.command('rename')
23
- .description('Rename an element')
24
- .argument('<type>', `Element type (${Object.keys(RENAME_MAP).join(', ')})`)
25
- .argument('<names...>', 'Old name and new name (or just new name with --id)')
26
- .action(async (type, names, _opts, cmd) => {
27
- const modelId = requireModelId();
28
- const fn = RENAME_MAP[type];
29
- if (!fn)
30
- throw new Error(`Unknown type: ${type}. Valid: ${Object.keys(RENAME_MAP).join(', ')}`);
31
- const idOverride = getGlobalId();
32
- let oldName;
33
- let newName;
34
- if (idOverride) {
35
- // With --id, all positional args are the new name
36
- newName = names.join(' ');
37
- oldName = '';
38
- }
39
- else if (names.length >= 2) {
40
- // Last arg is new name, rest is old name
41
- newName = names[names.length - 1];
42
- oldName = names.slice(0, -1).join(' ');
43
- }
44
- else {
45
- console.error('Usage: eventmodeler rename <type> "Old Name" "New Name"');
46
- console.error(' or: eventmodeler --id <uuid> rename <type> "New Name"');
47
- process.exit(1);
48
- }
49
- const id = await resolve(modelId, type, oldName, idOverride);
50
- unwrap(await fn({ body: { modelId, [elementIdKey(type)]: id, name: newName } }));
51
- console.log(`Renamed ${type} to "${newName}"`);
52
- });
53
- }