eventmodeler 0.2.9 → 0.3.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/index.js +25 -13
- package/dist/lib/chapter-utils.d.ts +13 -0
- package/dist/lib/chapter-utils.js +71 -0
- package/dist/lib/flow-utils.d.ts +52 -0
- package/dist/lib/flow-utils.js +305 -0
- package/dist/lib/slice-utils.js +17 -4
- package/dist/slices/add-field/index.d.ts +2 -0
- package/dist/slices/add-field/index.js +46 -3
- package/dist/slices/codegen-slice/index.js +2 -13
- package/dist/slices/list-slices/index.d.ts +1 -1
- package/dist/slices/list-slices/index.js +17 -2
- package/dist/slices/remove-field/index.d.ts +2 -0
- package/dist/slices/remove-field/index.js +59 -3
- package/dist/slices/show-chapter/index.js +162 -2
- package/dist/slices/show-slice/index.js +242 -10
- package/dist/slices/update-field/index.d.ts +2 -0
- package/dist/slices/update-field/index.js +57 -3
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { escapeXml, escapeXmlText, outputJson } from '../../lib/format.js';
|
|
2
2
|
import { findElementOrExit } from '../../lib/element-lookup.js';
|
|
3
|
+
import { findChapterForSlice, getChapterHierarchy } from '../../lib/chapter-utils.js';
|
|
4
|
+
import { getInboundFlows, getOutboundFlows, getFlowsForElement, } from '../../lib/flow-utils.js';
|
|
3
5
|
function formatFieldValues(values) {
|
|
4
6
|
if (!values || Object.keys(values).length === 0)
|
|
5
7
|
return '';
|
|
@@ -102,9 +104,91 @@ function findActorForScreen(model, screen) {
|
|
|
102
104
|
}
|
|
103
105
|
return null;
|
|
104
106
|
}
|
|
107
|
+
function formatChapterXml(hierarchy, indent) {
|
|
108
|
+
let xml = `${indent}<chapter id="${hierarchy.id}" name="${escapeXml(hierarchy.name)}"`;
|
|
109
|
+
if (hierarchy.parent) {
|
|
110
|
+
xml += '>\n';
|
|
111
|
+
xml += formatChapterXml(hierarchy.parent, indent + ' ');
|
|
112
|
+
xml += `${indent}</chapter>\n`;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
xml += '/>\n';
|
|
116
|
+
}
|
|
117
|
+
return xml;
|
|
118
|
+
}
|
|
119
|
+
// Format inline flow annotations for a component
|
|
120
|
+
function formatFlowAnnotationsXml(elementId, incoming, outgoing, componentIds, indent) {
|
|
121
|
+
let xml = '';
|
|
122
|
+
// Flows coming into this element
|
|
123
|
+
const flowsFrom = incoming.map(f => {
|
|
124
|
+
const external = !componentIds.has(f.source.id);
|
|
125
|
+
return external
|
|
126
|
+
? `${escapeXml(f.source.name)} (${f.source.type}) [external]`
|
|
127
|
+
: `${escapeXml(f.source.name)} (${f.source.type})`;
|
|
128
|
+
});
|
|
129
|
+
if (flowsFrom.length > 0) {
|
|
130
|
+
xml += `${indent}<flows-from>${flowsFrom.join(', ')}</flows-from>\n`;
|
|
131
|
+
}
|
|
132
|
+
// Flows going out of this element
|
|
133
|
+
const flowsTo = outgoing.map(f => {
|
|
134
|
+
const external = !componentIds.has(f.target.id);
|
|
135
|
+
return external
|
|
136
|
+
? `${escapeXml(f.target.name)} (${f.target.type}) [external]`
|
|
137
|
+
: `${escapeXml(f.target.name)} (${f.target.type})`;
|
|
138
|
+
});
|
|
139
|
+
if (flowsTo.length > 0) {
|
|
140
|
+
xml += `${indent}<flows-to>${flowsTo.join(', ')}</flows-to>\n`;
|
|
141
|
+
}
|
|
142
|
+
return xml;
|
|
143
|
+
}
|
|
144
|
+
// Format inbound flows section
|
|
145
|
+
function formatInboundFlowsXml(flows) {
|
|
146
|
+
if (flows.length === 0)
|
|
147
|
+
return '';
|
|
148
|
+
let xml = ' <inbound-flows>\n';
|
|
149
|
+
for (const flow of flows) {
|
|
150
|
+
xml += ` <flow type="${flow.flowType}">\n`;
|
|
151
|
+
const sourceSliceInfo = flow.sourceSlice ? ` slice="${escapeXml(flow.sourceSlice.name)}"` : '';
|
|
152
|
+
xml += ` <from${sourceSliceInfo}>${escapeXml(flow.source.name)} (${flow.source.type})</from>\n`;
|
|
153
|
+
xml += ` <to>${escapeXml(flow.target.name)} (${flow.target.type})</to>\n`;
|
|
154
|
+
if (flow.fieldMappings.length > 0) {
|
|
155
|
+
xml += ' <mappings>\n';
|
|
156
|
+
for (const mapping of flow.fieldMappings) {
|
|
157
|
+
xml += ` <map from="${escapeXml(mapping.from)}" to="${escapeXml(mapping.to)}"/>\n`;
|
|
158
|
+
}
|
|
159
|
+
xml += ' </mappings>\n';
|
|
160
|
+
}
|
|
161
|
+
xml += ' </flow>\n';
|
|
162
|
+
}
|
|
163
|
+
xml += ' </inbound-flows>\n';
|
|
164
|
+
return xml;
|
|
165
|
+
}
|
|
166
|
+
// Format outbound flows section
|
|
167
|
+
function formatOutboundFlowsXml(flows) {
|
|
168
|
+
if (flows.length === 0)
|
|
169
|
+
return '';
|
|
170
|
+
let xml = ' <outbound-flows>\n';
|
|
171
|
+
for (const flow of flows) {
|
|
172
|
+
xml += ` <flow type="${flow.flowType}">\n`;
|
|
173
|
+
xml += ` <from>${escapeXml(flow.source.name)} (${flow.source.type})</from>\n`;
|
|
174
|
+
const targetSliceInfo = flow.targetSlice ? ` slice="${escapeXml(flow.targetSlice.name)}"` : '';
|
|
175
|
+
xml += ` <to${targetSliceInfo}>${escapeXml(flow.target.name)} (${flow.target.type})</to>\n`;
|
|
176
|
+
if (flow.fieldMappings.length > 0) {
|
|
177
|
+
xml += ' <mappings>\n';
|
|
178
|
+
for (const mapping of flow.fieldMappings) {
|
|
179
|
+
xml += ` <map from="${escapeXml(mapping.from)}" to="${escapeXml(mapping.to)}"/>\n`;
|
|
180
|
+
}
|
|
181
|
+
xml += ' </mappings>\n';
|
|
182
|
+
}
|
|
183
|
+
xml += ' </flow>\n';
|
|
184
|
+
}
|
|
185
|
+
xml += ' </outbound-flows>\n';
|
|
186
|
+
return xml;
|
|
187
|
+
}
|
|
105
188
|
function formatSliceXml(model, slice) {
|
|
106
189
|
const components = getSliceComponents(model, slice);
|
|
107
190
|
const scenarios = [...model.scenarios.values()].filter(s => s.sliceId === slice.id);
|
|
191
|
+
const chapter = findChapterForSlice(model, slice);
|
|
108
192
|
const componentIds = new Set();
|
|
109
193
|
components.commands.forEach(c => componentIds.add(c.id));
|
|
110
194
|
components.events.forEach(e => componentIds.add(e.id));
|
|
@@ -113,6 +197,9 @@ function formatSliceXml(model, slice) {
|
|
|
113
197
|
components.processors.forEach(p => componentIds.add(p.id));
|
|
114
198
|
const flows = [...model.flows.values()].filter(f => componentIds.has(f.sourceId) || componentIds.has(f.targetId));
|
|
115
199
|
const internalFlows = flows.filter(f => componentIds.has(f.sourceId) && componentIds.has(f.targetId));
|
|
200
|
+
// Get inbound and outbound flows for the slice
|
|
201
|
+
const inboundFlows = getInboundFlows(model, slice);
|
|
202
|
+
const outboundFlows = getOutboundFlows(model, slice);
|
|
116
203
|
function getName(id) {
|
|
117
204
|
return (model.commands.get(id)?.name ??
|
|
118
205
|
model.events.get(id)?.name ??
|
|
@@ -122,6 +209,9 @@ function formatSliceXml(model, slice) {
|
|
|
122
209
|
id);
|
|
123
210
|
}
|
|
124
211
|
let xml = `<slice id="${slice.id}" name="${escapeXml(slice.name)}" status="${slice.status}">\n`;
|
|
212
|
+
if (chapter) {
|
|
213
|
+
xml += formatChapterXml(getChapterHierarchy(model, chapter), ' ');
|
|
214
|
+
}
|
|
125
215
|
xml += ' <components>\n';
|
|
126
216
|
for (const screen of components.screens) {
|
|
127
217
|
// Check if this is a linked copy
|
|
@@ -137,6 +227,9 @@ function formatSliceXml(model, slice) {
|
|
|
137
227
|
const actor = findActorForScreen(model, screen);
|
|
138
228
|
const actorAttr = actor ? ` actor="${escapeXml(actor.name)}"` : '';
|
|
139
229
|
xml += ` <screen id="${screen.id}" name="${escapeXml(screen.name)}"${copyAttr}${originAttr}${actorAttr}>\n`;
|
|
230
|
+
// Add flow annotations
|
|
231
|
+
const screenFlows = getFlowsForElement(model, screen.id);
|
|
232
|
+
xml += formatFlowAnnotationsXml(screen.id, screenFlows.incoming, screenFlows.outgoing, componentIds, ' ');
|
|
140
233
|
if (screen.fields.length > 0) {
|
|
141
234
|
xml += ' <fields>\n';
|
|
142
235
|
for (const field of screen.fields) {
|
|
@@ -148,6 +241,9 @@ function formatSliceXml(model, slice) {
|
|
|
148
241
|
}
|
|
149
242
|
for (const command of components.commands) {
|
|
150
243
|
xml += ` <command id="${command.id}" name="${escapeXml(command.name)}">\n`;
|
|
244
|
+
// Add flow annotations
|
|
245
|
+
const commandFlows = getFlowsForElement(model, command.id);
|
|
246
|
+
xml += formatFlowAnnotationsXml(command.id, commandFlows.incoming, commandFlows.outgoing, componentIds, ' ');
|
|
151
247
|
if (command.fields.length > 0) {
|
|
152
248
|
xml += ' <fields>\n';
|
|
153
249
|
for (const field of command.fields) {
|
|
@@ -179,6 +275,9 @@ function formatSliceXml(model, slice) {
|
|
|
179
275
|
const aggregate = findAggregateForEvent(model, event);
|
|
180
276
|
const aggregateAttr = aggregate ? ` aggregate="${escapeXml(aggregate.name)}"` : '';
|
|
181
277
|
xml += ` <event id="${event.id}" name="${escapeXml(event.name)}"${copyAttr}${originAttr}${aggregateAttr}>\n`;
|
|
278
|
+
// Add flow annotations
|
|
279
|
+
const eventFlows = getFlowsForElement(model, event.id);
|
|
280
|
+
xml += formatFlowAnnotationsXml(event.id, eventFlows.incoming, eventFlows.outgoing, componentIds, ' ');
|
|
182
281
|
if (event.fields.length > 0) {
|
|
183
282
|
xml += ' <fields>\n';
|
|
184
283
|
for (const field of event.fields) {
|
|
@@ -210,6 +309,9 @@ function formatSliceXml(model, slice) {
|
|
|
210
309
|
}
|
|
211
310
|
}
|
|
212
311
|
xml += ` <read-model id="${readModel.id}" name="${escapeXml(readModel.name)}"${copyAttr}${originAttr}>\n`;
|
|
312
|
+
// Add flow annotations
|
|
313
|
+
const rmFlows = getFlowsForElement(model, readModel.id);
|
|
314
|
+
xml += formatFlowAnnotationsXml(readModel.id, rmFlows.incoming, rmFlows.outgoing, componentIds, ' ');
|
|
213
315
|
if (readModel.fields.length > 0) {
|
|
214
316
|
xml += ' <fields>\n';
|
|
215
317
|
for (const field of readModel.fields) {
|
|
@@ -221,6 +323,9 @@ function formatSliceXml(model, slice) {
|
|
|
221
323
|
}
|
|
222
324
|
for (const processor of components.processors) {
|
|
223
325
|
xml += ` <processor id="${processor.id}" name="${escapeXml(processor.name)}">\n`;
|
|
326
|
+
// Add flow annotations
|
|
327
|
+
const procFlows = getFlowsForElement(model, processor.id);
|
|
328
|
+
xml += formatFlowAnnotationsXml(processor.id, procFlows.incoming, procFlows.outgoing, componentIds, ' ');
|
|
224
329
|
if (processor.fields.length > 0) {
|
|
225
330
|
xml += ' <fields>\n';
|
|
226
331
|
for (const field of processor.fields) {
|
|
@@ -297,6 +402,9 @@ function formatSliceXml(model, slice) {
|
|
|
297
402
|
}
|
|
298
403
|
xml += ' </scenarios>\n';
|
|
299
404
|
}
|
|
405
|
+
// Add inbound and outbound flows sections
|
|
406
|
+
xml += formatInboundFlowsXml(inboundFlows);
|
|
407
|
+
xml += formatOutboundFlowsXml(outboundFlows);
|
|
300
408
|
xml += '</slice>';
|
|
301
409
|
return xml;
|
|
302
410
|
}
|
|
@@ -321,6 +429,7 @@ function fieldToJson(field) {
|
|
|
321
429
|
function formatSliceJson(model, slice) {
|
|
322
430
|
const components = getSliceComponents(model, slice);
|
|
323
431
|
const scenarios = [...model.scenarios.values()].filter(s => s.sliceId === slice.id);
|
|
432
|
+
const chapter = findChapterForSlice(model, slice);
|
|
324
433
|
const componentIds = new Set();
|
|
325
434
|
components.commands.forEach(c => componentIds.add(c.id));
|
|
326
435
|
components.events.forEach(e => componentIds.add(e.id));
|
|
@@ -329,6 +438,9 @@ function formatSliceJson(model, slice) {
|
|
|
329
438
|
components.processors.forEach(p => componentIds.add(p.id));
|
|
330
439
|
const flows = [...model.flows.values()].filter(f => componentIds.has(f.sourceId) || componentIds.has(f.targetId));
|
|
331
440
|
const internalFlows = flows.filter(f => componentIds.has(f.sourceId) && componentIds.has(f.targetId));
|
|
441
|
+
// Get inbound and outbound flows for the slice
|
|
442
|
+
const inboundFlows = getInboundFlows(model, slice);
|
|
443
|
+
const outboundFlows = getOutboundFlows(model, slice);
|
|
332
444
|
function getName(id) {
|
|
333
445
|
return (model.commands.get(id)?.name ??
|
|
334
446
|
model.events.get(id)?.name ??
|
|
@@ -341,6 +453,7 @@ function formatSliceJson(model, slice) {
|
|
|
341
453
|
id: slice.id,
|
|
342
454
|
name: slice.name,
|
|
343
455
|
status: slice.status,
|
|
456
|
+
...(chapter && { chapter: getChapterHierarchy(model, chapter) }),
|
|
344
457
|
components: {
|
|
345
458
|
screens: components.screens.map(screen => {
|
|
346
459
|
const screenObj = {
|
|
@@ -357,13 +470,47 @@ function formatSliceJson(model, slice) {
|
|
|
357
470
|
const actor = findActorForScreen(model, screen);
|
|
358
471
|
if (actor)
|
|
359
472
|
screenObj.actor = actor.name;
|
|
473
|
+
// Add flow annotations
|
|
474
|
+
const screenFlows = getFlowsForElement(model, screen.id);
|
|
475
|
+
if (screenFlows.incoming.length > 0) {
|
|
476
|
+
screenObj.flowsFrom = screenFlows.incoming.map(f => ({
|
|
477
|
+
element: f.source.name,
|
|
478
|
+
type: f.source.type,
|
|
479
|
+
external: !componentIds.has(f.source.id)
|
|
480
|
+
}));
|
|
481
|
+
}
|
|
482
|
+
if (screenFlows.outgoing.length > 0) {
|
|
483
|
+
screenObj.flowsTo = screenFlows.outgoing.map(f => ({
|
|
484
|
+
element: f.target.name,
|
|
485
|
+
type: f.target.type,
|
|
486
|
+
external: !componentIds.has(f.target.id)
|
|
487
|
+
}));
|
|
488
|
+
}
|
|
360
489
|
return screenObj;
|
|
361
490
|
}),
|
|
362
|
-
commands: components.commands.map(cmd =>
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
491
|
+
commands: components.commands.map(cmd => {
|
|
492
|
+
const cmdObj = {
|
|
493
|
+
id: cmd.id,
|
|
494
|
+
name: cmd.name,
|
|
495
|
+
fields: cmd.fields.map(fieldToJson)
|
|
496
|
+
};
|
|
497
|
+
const cmdFlows = getFlowsForElement(model, cmd.id);
|
|
498
|
+
if (cmdFlows.incoming.length > 0) {
|
|
499
|
+
cmdObj.flowsFrom = cmdFlows.incoming.map(f => ({
|
|
500
|
+
element: f.source.name,
|
|
501
|
+
type: f.source.type,
|
|
502
|
+
external: !componentIds.has(f.source.id)
|
|
503
|
+
}));
|
|
504
|
+
}
|
|
505
|
+
if (cmdFlows.outgoing.length > 0) {
|
|
506
|
+
cmdObj.flowsTo = cmdFlows.outgoing.map(f => ({
|
|
507
|
+
element: f.target.name,
|
|
508
|
+
type: f.target.type,
|
|
509
|
+
external: !componentIds.has(f.target.id)
|
|
510
|
+
}));
|
|
511
|
+
}
|
|
512
|
+
return cmdObj;
|
|
513
|
+
}),
|
|
367
514
|
events: components.events.map(event => {
|
|
368
515
|
const eventObj = {
|
|
369
516
|
id: event.id,
|
|
@@ -379,6 +526,22 @@ function formatSliceJson(model, slice) {
|
|
|
379
526
|
const aggregate = findAggregateForEvent(model, event);
|
|
380
527
|
if (aggregate)
|
|
381
528
|
eventObj.aggregate = aggregate.name;
|
|
529
|
+
// Add flow annotations
|
|
530
|
+
const eventFlows = getFlowsForElement(model, event.id);
|
|
531
|
+
if (eventFlows.incoming.length > 0) {
|
|
532
|
+
eventObj.flowsFrom = eventFlows.incoming.map(f => ({
|
|
533
|
+
element: f.source.name,
|
|
534
|
+
type: f.source.type,
|
|
535
|
+
external: !componentIds.has(f.source.id)
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
if (eventFlows.outgoing.length > 0) {
|
|
539
|
+
eventObj.flowsTo = eventFlows.outgoing.map(f => ({
|
|
540
|
+
element: f.target.name,
|
|
541
|
+
type: f.target.type,
|
|
542
|
+
external: !componentIds.has(f.target.id)
|
|
543
|
+
}));
|
|
544
|
+
}
|
|
382
545
|
return eventObj;
|
|
383
546
|
}),
|
|
384
547
|
readModels: components.readModels.map(rm => {
|
|
@@ -393,13 +556,47 @@ function formatSliceJson(model, slice) {
|
|
|
393
556
|
if (originSlice)
|
|
394
557
|
rmObj.originSlice = originSlice.name;
|
|
395
558
|
}
|
|
559
|
+
// Add flow annotations
|
|
560
|
+
const rmFlows = getFlowsForElement(model, rm.id);
|
|
561
|
+
if (rmFlows.incoming.length > 0) {
|
|
562
|
+
rmObj.flowsFrom = rmFlows.incoming.map(f => ({
|
|
563
|
+
element: f.source.name,
|
|
564
|
+
type: f.source.type,
|
|
565
|
+
external: !componentIds.has(f.source.id)
|
|
566
|
+
}));
|
|
567
|
+
}
|
|
568
|
+
if (rmFlows.outgoing.length > 0) {
|
|
569
|
+
rmObj.flowsTo = rmFlows.outgoing.map(f => ({
|
|
570
|
+
element: f.target.name,
|
|
571
|
+
type: f.target.type,
|
|
572
|
+
external: !componentIds.has(f.target.id)
|
|
573
|
+
}));
|
|
574
|
+
}
|
|
396
575
|
return rmObj;
|
|
397
576
|
}),
|
|
398
|
-
processors: components.processors.map(proc =>
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
577
|
+
processors: components.processors.map(proc => {
|
|
578
|
+
const procObj = {
|
|
579
|
+
id: proc.id,
|
|
580
|
+
name: proc.name,
|
|
581
|
+
fields: proc.fields.map(fieldToJson)
|
|
582
|
+
};
|
|
583
|
+
const procFlows = getFlowsForElement(model, proc.id);
|
|
584
|
+
if (procFlows.incoming.length > 0) {
|
|
585
|
+
procObj.flowsFrom = procFlows.incoming.map(f => ({
|
|
586
|
+
element: f.source.name,
|
|
587
|
+
type: f.source.type,
|
|
588
|
+
external: !componentIds.has(f.source.id)
|
|
589
|
+
}));
|
|
590
|
+
}
|
|
591
|
+
if (procFlows.outgoing.length > 0) {
|
|
592
|
+
procObj.flowsTo = procFlows.outgoing.map(f => ({
|
|
593
|
+
element: f.target.name,
|
|
594
|
+
type: f.target.type,
|
|
595
|
+
external: !componentIds.has(f.target.id)
|
|
596
|
+
}));
|
|
597
|
+
}
|
|
598
|
+
return procObj;
|
|
599
|
+
})
|
|
403
600
|
}
|
|
404
601
|
};
|
|
405
602
|
if (internalFlows.length > 0) {
|
|
@@ -460,6 +657,41 @@ function formatSliceJson(model, slice) {
|
|
|
460
657
|
return scenarioObj;
|
|
461
658
|
});
|
|
462
659
|
}
|
|
660
|
+
// Add inbound and outbound flows
|
|
661
|
+
if (inboundFlows.length > 0) {
|
|
662
|
+
result.inboundFlows = inboundFlows.map(f => ({
|
|
663
|
+
type: f.flowType,
|
|
664
|
+
from: {
|
|
665
|
+
element: f.source.name,
|
|
666
|
+
type: f.source.type,
|
|
667
|
+
...(f.sourceSlice && { slice: f.sourceSlice.name })
|
|
668
|
+
},
|
|
669
|
+
to: {
|
|
670
|
+
element: f.target.name,
|
|
671
|
+
type: f.target.type
|
|
672
|
+
},
|
|
673
|
+
...(f.fieldMappings.length > 0 && {
|
|
674
|
+
mappings: f.fieldMappings.map(m => ({ from: m.from, to: m.to }))
|
|
675
|
+
})
|
|
676
|
+
}));
|
|
677
|
+
}
|
|
678
|
+
if (outboundFlows.length > 0) {
|
|
679
|
+
result.outboundFlows = outboundFlows.map(f => ({
|
|
680
|
+
type: f.flowType,
|
|
681
|
+
from: {
|
|
682
|
+
element: f.source.name,
|
|
683
|
+
type: f.source.type
|
|
684
|
+
},
|
|
685
|
+
to: {
|
|
686
|
+
element: f.target.name,
|
|
687
|
+
type: f.target.type,
|
|
688
|
+
...(f.targetSlice && { slice: f.targetSlice.name })
|
|
689
|
+
},
|
|
690
|
+
...(f.fieldMappings.length > 0 && {
|
|
691
|
+
mappings: f.fieldMappings.map(m => ({ from: m.from, to: m.to }))
|
|
692
|
+
})
|
|
693
|
+
}));
|
|
694
|
+
}
|
|
463
695
|
return result;
|
|
464
696
|
}
|
|
465
697
|
export function showSlice(model, name, format) {
|
|
@@ -33,13 +33,13 @@ function createUpdatedField(original, updates) {
|
|
|
33
33
|
}
|
|
34
34
|
export function updateField(model, filePath, options, fieldName, updates) {
|
|
35
35
|
// Determine which entity type
|
|
36
|
-
const entityCount = [options.command, options.event, options.readModel].filter(Boolean).length;
|
|
36
|
+
const entityCount = [options.command, options.event, options.readModel, options.screen, options.processor].filter(Boolean).length;
|
|
37
37
|
if (entityCount === 0) {
|
|
38
|
-
console.error('Error: Must specify one of --command, --event,
|
|
38
|
+
console.error('Error: Must specify one of --command, --event, --read-model, --screen, or --processor');
|
|
39
39
|
process.exit(1);
|
|
40
40
|
}
|
|
41
41
|
if (entityCount > 1) {
|
|
42
|
-
console.error('Error: Can only specify one of --command, --event,
|
|
42
|
+
console.error('Error: Can only specify one of --command, --event, --read-model, --screen, or --processor');
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
45
|
if (options.command) {
|
|
@@ -51,6 +51,12 @@ export function updateField(model, filePath, options, fieldName, updates) {
|
|
|
51
51
|
else if (options.readModel) {
|
|
52
52
|
updateReadModelField(model, filePath, options.readModel, fieldName, updates);
|
|
53
53
|
}
|
|
54
|
+
else if (options.screen) {
|
|
55
|
+
updateScreenField(model, filePath, options.screen, fieldName, updates);
|
|
56
|
+
}
|
|
57
|
+
else if (options.processor) {
|
|
58
|
+
updateProcessorField(model, filePath, options.processor, fieldName, updates);
|
|
59
|
+
}
|
|
54
60
|
}
|
|
55
61
|
function updateCommandField(model, filePath, commandName, fieldName, updates) {
|
|
56
62
|
const command = findElementOrExit(model.commands, commandName, 'command');
|
|
@@ -124,6 +130,54 @@ function updateReadModelField(model, filePath, readModelName, fieldName, updates
|
|
|
124
130
|
console.log(`Updated field "${field.name}" on read model "${readModel.name}"`);
|
|
125
131
|
logUpdates(updates);
|
|
126
132
|
}
|
|
133
|
+
function updateScreenField(model, filePath, screenName, fieldName, updates) {
|
|
134
|
+
const screen = findElementOrExit(model.screens, screenName, 'screen');
|
|
135
|
+
const field = findFieldByName(screen.fields, fieldName);
|
|
136
|
+
if (!field) {
|
|
137
|
+
console.error(`Error: Field "${fieldName}" not found on screen "${screen.name}"`);
|
|
138
|
+
if (screen.fields.length > 0) {
|
|
139
|
+
console.error('Available fields:');
|
|
140
|
+
for (const f of screen.fields) {
|
|
141
|
+
console.error(` - ${f.name}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const updatedField = createUpdatedField(field, updates);
|
|
147
|
+
appendEvent(filePath, {
|
|
148
|
+
type: 'ScreenFieldAdjusted',
|
|
149
|
+
screenId: screen.id,
|
|
150
|
+
fieldId: field.id,
|
|
151
|
+
field: updatedField,
|
|
152
|
+
timestamp: Date.now(),
|
|
153
|
+
});
|
|
154
|
+
console.log(`Updated field "${field.name}" on screen "${screen.name}"`);
|
|
155
|
+
logUpdates(updates);
|
|
156
|
+
}
|
|
157
|
+
function updateProcessorField(model, filePath, processorName, fieldName, updates) {
|
|
158
|
+
const processor = findElementOrExit(model.processors, processorName, 'processor');
|
|
159
|
+
const field = findFieldByName(processor.fields, fieldName);
|
|
160
|
+
if (!field) {
|
|
161
|
+
console.error(`Error: Field "${fieldName}" not found on processor "${processor.name}"`);
|
|
162
|
+
if (processor.fields.length > 0) {
|
|
163
|
+
console.error('Available fields:');
|
|
164
|
+
for (const f of processor.fields) {
|
|
165
|
+
console.error(` - ${f.name}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
const updatedField = createUpdatedField(field, updates);
|
|
171
|
+
appendEvent(filePath, {
|
|
172
|
+
type: 'ProcessorFieldAdjusted',
|
|
173
|
+
processorId: processor.id,
|
|
174
|
+
fieldId: field.id,
|
|
175
|
+
field: updatedField,
|
|
176
|
+
timestamp: Date.now(),
|
|
177
|
+
});
|
|
178
|
+
console.log(`Updated field "${field.name}" on processor "${processor.name}"`);
|
|
179
|
+
logUpdates(updates);
|
|
180
|
+
}
|
|
127
181
|
function logUpdates(updates) {
|
|
128
182
|
if (updates.optional !== undefined) {
|
|
129
183
|
console.log(` isOptional: ${updates.optional}`);
|