eventmodeler 0.4.7 → 0.6.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.
Files changed (204) hide show
  1. package/dist/api/client-config.js +10 -0
  2. package/dist/api/generated/client/client.gen.js +235 -0
  3. package/dist/api/generated/client/index.js +6 -0
  4. package/dist/api/generated/client/types.gen.js +2 -0
  5. package/dist/api/generated/client/utils.gen.js +228 -0
  6. package/dist/api/generated/client.gen.js +4 -0
  7. package/dist/api/generated/core/auth.gen.js +14 -0
  8. package/dist/api/generated/core/bodySerializer.gen.js +57 -0
  9. package/dist/api/generated/core/params.gen.js +100 -0
  10. package/dist/api/generated/core/pathSerializer.gen.js +106 -0
  11. package/dist/api/generated/core/queryKeySerializer.gen.js +92 -0
  12. package/dist/api/generated/core/serverSentEvents.gen.js +133 -0
  13. package/dist/api/generated/core/types.gen.js +2 -0
  14. package/dist/api/generated/core/utils.gen.js +87 -0
  15. package/dist/api/generated/index.js +2 -0
  16. package/dist/api/generated/sdk.gen.js +4222 -0
  17. package/dist/api/generated/types.gen.js +2 -0
  18. package/dist/api/generated/zod.gen.js +7217 -0
  19. package/dist/commands/add.js +315 -0
  20. package/dist/commands/auth.js +14 -0
  21. package/dist/commands/create.js +192 -0
  22. package/dist/commands/design.js +108 -0
  23. package/dist/commands/guide.js +15 -0
  24. package/dist/commands/init.js +21 -0
  25. package/dist/commands/list-schemas.js +177 -0
  26. package/dist/commands/list.js +39 -0
  27. package/dist/commands/loop.js +101 -0
  28. package/dist/commands/map.js +40 -0
  29. package/dist/commands/mark.js +27 -0
  30. package/dist/commands/move.js +35 -0
  31. package/dist/commands/remove.js +170 -0
  32. package/dist/commands/rename.js +53 -0
  33. package/dist/commands/resize.js +30 -0
  34. package/dist/commands/search.js +14 -0
  35. package/dist/commands/set.js +199 -0
  36. package/dist/commands/show-schemas.js +259 -0
  37. package/dist/commands/show.js +56 -0
  38. package/dist/commands/summary.js +13 -0
  39. package/dist/commands/update.js +240 -0
  40. package/dist/index.js +46 -2379
  41. package/dist/lib/auth.js +1 -1
  42. package/dist/lib/config.js +0 -15
  43. package/dist/lib/excalidraw-schema.js +66 -0
  44. package/dist/lib/globals.js +8 -0
  45. package/dist/lib/model.js +11 -0
  46. package/dist/lib/project-config.js +20 -0
  47. package/dist/lib/resolve.js +59 -0
  48. package/dist/lib/scenario.js +15 -0
  49. package/dist/slices/add-scenario/index.js +2 -206
  50. package/dist/slices/guide/guides/codegen.js +1 -1
  51. package/dist/slices/guide/guides/connect-slices.js +12 -37
  52. package/dist/slices/guide/guides/create-slices.js +110 -140
  53. package/dist/slices/guide/guides/explore.js +37 -26
  54. package/dist/slices/guide/guides/information-flow.js +70 -82
  55. package/dist/slices/guide/guides/scenarios.js +82 -137
  56. package/dist/slices/guide/index.js +6 -6
  57. package/dist/slices/help/index.js +96 -0
  58. package/dist/slices/help/topics/build-codegen.js +109 -0
  59. package/dist/slices/help/topics/build-slice.js +147 -0
  60. package/dist/slices/help/topics/check-completeness.js +57 -0
  61. package/dist/slices/help/topics/connect-slices.js +99 -0
  62. package/dist/slices/help/topics/explore-model.js +112 -0
  63. package/dist/slices/help/topics/json-reference.js +188 -0
  64. package/dist/slices/help/topics/linked-copies.js +89 -0
  65. package/dist/slices/help/topics/manipulate-canvas.js +150 -0
  66. package/dist/slices/help/topics/write-scenarios.js +162 -0
  67. package/dist/slices/init/index.js +10 -4
  68. package/dist/slices/init/loop.js +60 -0
  69. package/dist/slices/login/index.js +2 -2
  70. package/dist/slices/logout/index.js +2 -2
  71. package/dist/slices/whoami/index.js +11 -36
  72. package/package.json +8 -3
  73. package/dist/api/index.d.ts +0 -285
  74. package/dist/api/index.js +0 -323
  75. package/dist/cloud/slices/index.d.ts +0 -276
  76. package/dist/cloud/slices/index.js +0 -406
  77. package/dist/eventmodeler.js +0 -5646
  78. package/dist/formatters.d.ts +0 -17
  79. package/dist/formatters.js +0 -482
  80. package/dist/index.d.ts +0 -2
  81. package/dist/lib/auth.d.ts +0 -24
  82. package/dist/lib/backend.d.ts +0 -43
  83. package/dist/lib/backend.js +0 -73
  84. package/dist/lib/chapter-utils.d.ts +0 -13
  85. package/dist/lib/chapter-utils.js +0 -71
  86. package/dist/lib/cloud-client.d.ts +0 -69
  87. package/dist/lib/cloud-client.js +0 -364
  88. package/dist/lib/config.d.ts +0 -30
  89. package/dist/lib/diff/merge-rules.d.ts +0 -45
  90. package/dist/lib/diff/merge-rules.js +0 -210
  91. package/dist/lib/diff/model-differ.d.ts +0 -8
  92. package/dist/lib/diff/model-differ.js +0 -568
  93. package/dist/lib/diff/three-way-merge.d.ts +0 -7
  94. package/dist/lib/diff/three-way-merge.js +0 -390
  95. package/dist/lib/diff/types.d.ts +0 -75
  96. package/dist/lib/diff/types.js +0 -1
  97. package/dist/lib/element-lookup.d.ts +0 -58
  98. package/dist/lib/element-lookup.js +0 -126
  99. package/dist/lib/file-loader.d.ts +0 -8
  100. package/dist/lib/file-loader.js +0 -108
  101. package/dist/lib/flow-utils.d.ts +0 -53
  102. package/dist/lib/flow-utils.js +0 -348
  103. package/dist/lib/format.d.ts +0 -10
  104. package/dist/lib/format.js +0 -23
  105. package/dist/lib/project-config.d.ts +0 -27
  106. package/dist/lib/slice-utils.d.ts +0 -59
  107. package/dist/lib/slice-utils.js +0 -140
  108. package/dist/local/slices/index.d.ts +0 -11
  109. package/dist/local/slices/index.js +0 -13
  110. package/dist/projection.d.ts +0 -3
  111. package/dist/projection.js +0 -828
  112. package/dist/slices/add-field/index.d.ts +0 -8
  113. package/dist/slices/add-field/index.js +0 -211
  114. package/dist/slices/add-scenario/index.d.ts +0 -27
  115. package/dist/slices/codegen-chapter-events/index.d.ts +0 -2
  116. package/dist/slices/codegen-chapter-events/index.js +0 -145
  117. package/dist/slices/codegen-slice/index.d.ts +0 -2
  118. package/dist/slices/codegen-slice/index.js +0 -448
  119. package/dist/slices/create-automation-slice/index.d.ts +0 -2
  120. package/dist/slices/create-automation-slice/index.js +0 -304
  121. package/dist/slices/create-flow/index.d.ts +0 -2
  122. package/dist/slices/create-flow/index.js +0 -183
  123. package/dist/slices/create-state-change-slice/index.d.ts +0 -2
  124. package/dist/slices/create-state-change-slice/index.js +0 -263
  125. package/dist/slices/create-state-view-slice/index.d.ts +0 -2
  126. package/dist/slices/create-state-view-slice/index.js +0 -128
  127. package/dist/slices/diff/index.d.ts +0 -11
  128. package/dist/slices/diff/index.js +0 -293
  129. package/dist/slices/export-eventmodel-to-json/index.d.ts +0 -2
  130. package/dist/slices/export-eventmodel-to-json/index.js +0 -355
  131. package/dist/slices/git/index.d.ts +0 -2
  132. package/dist/slices/git/index.js +0 -125
  133. package/dist/slices/guide/guides/codegen.d.ts +0 -5
  134. package/dist/slices/guide/guides/connect-slices.d.ts +0 -5
  135. package/dist/slices/guide/guides/create-slices.d.ts +0 -5
  136. package/dist/slices/guide/guides/explore.d.ts +0 -5
  137. package/dist/slices/guide/guides/information-flow.d.ts +0 -5
  138. package/dist/slices/guide/guides/scenarios.d.ts +0 -5
  139. package/dist/slices/guide/index.d.ts +0 -1
  140. package/dist/slices/import/index.d.ts +0 -8
  141. package/dist/slices/import/index.js +0 -63
  142. package/dist/slices/init/index.d.ts +0 -5
  143. package/dist/slices/list-chapters/index.d.ts +0 -3
  144. package/dist/slices/list-chapters/index.js +0 -21
  145. package/dist/slices/list-commands/index.d.ts +0 -3
  146. package/dist/slices/list-commands/index.js +0 -20
  147. package/dist/slices/list-events/index.d.ts +0 -3
  148. package/dist/slices/list-events/index.js +0 -98
  149. package/dist/slices/list-processors/index.d.ts +0 -3
  150. package/dist/slices/list-processors/index.js +0 -20
  151. package/dist/slices/list-readmodels/index.d.ts +0 -3
  152. package/dist/slices/list-readmodels/index.js +0 -21
  153. package/dist/slices/list-scenarios/index.d.ts +0 -3
  154. package/dist/slices/list-scenarios/index.js +0 -35
  155. package/dist/slices/list-screens/index.d.ts +0 -3
  156. package/dist/slices/list-screens/index.js +0 -47
  157. package/dist/slices/list-slices/index.d.ts +0 -3
  158. package/dist/slices/list-slices/index.js +0 -35
  159. package/dist/slices/login/index.d.ts +0 -1
  160. package/dist/slices/logout/index.d.ts +0 -1
  161. package/dist/slices/map-fields/index.d.ts +0 -2
  162. package/dist/slices/map-fields/index.js +0 -269
  163. package/dist/slices/mark-slice-status/index.d.ts +0 -2
  164. package/dist/slices/mark-slice-status/index.js +0 -31
  165. package/dist/slices/merge/index.d.ts +0 -19
  166. package/dist/slices/merge/index.js +0 -147
  167. package/dist/slices/open-app/index.d.ts +0 -1
  168. package/dist/slices/remove-field/index.d.ts +0 -8
  169. package/dist/slices/remove-field/index.js +0 -167
  170. package/dist/slices/remove-scenario/index.d.ts +0 -2
  171. package/dist/slices/remove-scenario/index.js +0 -77
  172. package/dist/slices/search/index.d.ts +0 -3
  173. package/dist/slices/search/index.js +0 -302
  174. package/dist/slices/show-actor/index.d.ts +0 -4
  175. package/dist/slices/show-actor/index.js +0 -115
  176. package/dist/slices/show-aggregate/index.d.ts +0 -3
  177. package/dist/slices/show-aggregate/index.js +0 -108
  178. package/dist/slices/show-aggregate-completeness/index.d.ts +0 -4
  179. package/dist/slices/show-aggregate-completeness/index.js +0 -181
  180. package/dist/slices/show-chapter/index.d.ts +0 -3
  181. package/dist/slices/show-chapter/index.js +0 -195
  182. package/dist/slices/show-command/index.d.ts +0 -3
  183. package/dist/slices/show-command/index.js +0 -133
  184. package/dist/slices/show-completeness/index.d.ts +0 -4
  185. package/dist/slices/show-completeness/index.js +0 -731
  186. package/dist/slices/show-event/index.d.ts +0 -3
  187. package/dist/slices/show-event/index.js +0 -118
  188. package/dist/slices/show-model-summary/index.d.ts +0 -3
  189. package/dist/slices/show-model-summary/index.js +0 -31
  190. package/dist/slices/show-processor/index.d.ts +0 -3
  191. package/dist/slices/show-processor/index.js +0 -111
  192. package/dist/slices/show-readmodel/index.d.ts +0 -3
  193. package/dist/slices/show-readmodel/index.js +0 -158
  194. package/dist/slices/show-scenario/index.d.ts +0 -3
  195. package/dist/slices/show-scenario/index.js +0 -196
  196. package/dist/slices/show-screen/index.d.ts +0 -3
  197. package/dist/slices/show-screen/index.js +0 -139
  198. package/dist/slices/show-slice/index.d.ts +0 -3
  199. package/dist/slices/show-slice/index.js +0 -696
  200. package/dist/slices/update-field/index.d.ts +0 -15
  201. package/dist/slices/update-field/index.js +0 -208
  202. package/dist/slices/whoami/index.d.ts +0 -2
  203. package/dist/types.d.ts +0 -195
  204. package/dist/types.js +0 -1
@@ -1,293 +0,0 @@
1
- import { execSync } from 'node:child_process';
2
- import * as fs from 'node:fs';
3
- import { loadModel, loadModelFromContent } from '../../lib/file-loader.js';
4
- import { diffModels } from '../../lib/diff/model-differ.js';
5
- import { escapeXml, outputJson } from '../../lib/format.js';
6
- function formatFieldChangeXml(change, indent) {
7
- const typeAttr = change.changeType;
8
- const pathAttr = escapeXml(change.fieldPath);
9
- if (change.changeType === 'added') {
10
- const fieldType = change.newValue?.fieldType ?? 'unknown';
11
- return `${indent}<field-${typeAttr} path="${pathAttr}" type="${fieldType}"/>`;
12
- }
13
- else if (change.changeType === 'removed') {
14
- const fieldType = change.oldValue?.fieldType ?? 'unknown';
15
- return `${indent}<field-${typeAttr} path="${pathAttr}" type="${fieldType}"/>`;
16
- }
17
- else {
18
- const oldType = change.oldValue?.fieldType ?? 'unknown';
19
- const newType = change.newValue?.fieldType ?? 'unknown';
20
- return `${indent}<field-${typeAttr} path="${pathAttr}" old-type="${oldType}" new-type="${newType}"/>`;
21
- }
22
- }
23
- function formatEntityChangeXml(change) {
24
- const lines = [];
25
- const typeAttr = escapeXml(change.entityType);
26
- const nameAttr = escapeXml(change.entityName);
27
- const idAttr = escapeXml(change.entityId);
28
- if (change.changeType === 'added') {
29
- lines.push(` <added type="${typeAttr}" name="${nameAttr}" id="${idAttr}"/>`);
30
- }
31
- else if (change.changeType === 'removed') {
32
- lines.push(` <removed type="${typeAttr}" name="${nameAttr}" id="${idAttr}"/>`);
33
- }
34
- else {
35
- const hasChanges = (change.propertyChanges && change.propertyChanges.length > 0) ||
36
- (change.fieldChanges && change.fieldChanges.length > 0);
37
- if (hasChanges) {
38
- lines.push(` <modified type="${typeAttr}" name="${nameAttr}" id="${idAttr}">`);
39
- if (change.propertyChanges) {
40
- for (const prop of change.propertyChanges) {
41
- const propName = escapeXml(prop.property);
42
- const oldVal = escapeXml(String(prop.oldValue ?? ''));
43
- const newVal = escapeXml(String(prop.newValue ?? ''));
44
- lines.push(` <property-changed name="${propName}" old="${oldVal}" new="${newVal}"/>`);
45
- }
46
- }
47
- if (change.fieldChanges) {
48
- lines.push(' <field-changes>');
49
- for (const fieldChange of change.fieldChanges) {
50
- lines.push(formatFieldChangeXml(fieldChange, ' '));
51
- }
52
- lines.push(' </field-changes>');
53
- }
54
- lines.push(' </modified>');
55
- }
56
- else {
57
- lines.push(` <modified type="${typeAttr}" name="${nameAttr}" id="${idAttr}"/>`);
58
- }
59
- }
60
- return lines.join('\n');
61
- }
62
- function formatFlowChangeXml(change) {
63
- const typeAttr = escapeXml(change.flowType);
64
- const sourceAttr = escapeXml(change.sourceName ?? '');
65
- const targetAttr = escapeXml(change.targetName ?? '');
66
- if (change.changeType === 'added') {
67
- return ` <flow-added type="${typeAttr}" source="${sourceAttr}" target="${targetAttr}"/>`;
68
- }
69
- else if (change.changeType === 'removed') {
70
- return ` <flow-removed type="${typeAttr}" source="${sourceAttr}" target="${targetAttr}"/>`;
71
- }
72
- else {
73
- const mappingCount = change.mappingChanges?.length ?? 0;
74
- return ` <flow-modified type="${typeAttr}" source="${sourceAttr}" target="${targetAttr}" mapping-changes="${mappingCount}"/>`;
75
- }
76
- }
77
- function formatDiffXml(result) {
78
- const lines = [];
79
- lines.push('<diff>');
80
- lines.push(` <summary added="${result.summary.added}" removed="${result.summary.removed}" modified="${result.summary.modified}"/>`);
81
- if (result.entityChanges.length > 0) {
82
- lines.push(' <entity-changes>');
83
- for (const change of result.entityChanges) {
84
- lines.push(formatEntityChangeXml(change));
85
- }
86
- lines.push(' </entity-changes>');
87
- }
88
- if (result.flowChanges.length > 0) {
89
- lines.push(' <flow-changes>');
90
- for (const change of result.flowChanges) {
91
- lines.push(formatFlowChangeXml(change));
92
- }
93
- lines.push(' </flow-changes>');
94
- }
95
- lines.push('</diff>');
96
- return lines.join('\n');
97
- }
98
- function formatDiffJson(result) {
99
- return {
100
- summary: result.summary,
101
- entityChanges: result.entityChanges.map((c) => ({
102
- type: c.entityType,
103
- id: c.entityId,
104
- name: c.entityName,
105
- change: c.changeType,
106
- propertyChanges: c.propertyChanges,
107
- fieldChanges: c.fieldChanges?.map((f) => ({
108
- path: f.fieldPath,
109
- change: f.changeType,
110
- oldType: f.oldValue?.fieldType,
111
- newType: f.newValue?.fieldType,
112
- })),
113
- })),
114
- flowChanges: result.flowChanges.map((c) => ({
115
- id: c.flowId,
116
- type: c.flowType,
117
- change: c.changeType,
118
- source: c.sourceName,
119
- target: c.targetName,
120
- mappingChanges: c.mappingChanges?.length,
121
- })),
122
- };
123
- }
124
- function formatEntityType(type) {
125
- const typeNames = {
126
- command: 'Command',
127
- event: 'Event',
128
- readModel: 'Read Model',
129
- screen: 'Screen',
130
- processor: 'Processor',
131
- slice: 'Slice',
132
- chapter: 'Chapter',
133
- aggregate: 'Aggregate',
134
- actor: 'Actor',
135
- scenario: 'Scenario',
136
- flow: 'Flow',
137
- };
138
- return typeNames[type] ?? type;
139
- }
140
- function formatDiffText(result) {
141
- const lines = [];
142
- const { added, removed, modified } = result.summary;
143
- const total = added + removed + modified;
144
- if (total === 0) {
145
- return 'No changes detected.';
146
- }
147
- lines.push(`${total} change${total === 1 ? '' : 's'}: ${added} added, ${removed} removed, ${modified} modified\n`);
148
- // Group changes by type
149
- const addedChanges = result.entityChanges.filter((c) => c.changeType === 'added');
150
- const removedChanges = result.entityChanges.filter((c) => c.changeType === 'removed');
151
- const modifiedChanges = result.entityChanges.filter((c) => c.changeType === 'modified');
152
- if (addedChanges.length > 0) {
153
- lines.push('Added:');
154
- for (const change of addedChanges) {
155
- lines.push(` + ${formatEntityType(change.entityType)} "${change.entityName}"`);
156
- }
157
- lines.push('');
158
- }
159
- if (removedChanges.length > 0) {
160
- lines.push('Removed:');
161
- for (const change of removedChanges) {
162
- lines.push(` - ${formatEntityType(change.entityType)} "${change.entityName}"`);
163
- }
164
- lines.push('');
165
- }
166
- if (modifiedChanges.length > 0) {
167
- lines.push('Modified:');
168
- for (const change of modifiedChanges) {
169
- lines.push(` ~ ${formatEntityType(change.entityType)} "${change.entityName}"`);
170
- if (change.propertyChanges) {
171
- for (const prop of change.propertyChanges) {
172
- if (prop.property === 'name') {
173
- lines.push(` renamed from "${prop.oldValue}" to "${prop.newValue}"`);
174
- }
175
- else if (prop.property === 'status') {
176
- lines.push(` status: ${prop.oldValue} -> ${prop.newValue}`);
177
- }
178
- else {
179
- lines.push(` ${prop.property} changed`);
180
- }
181
- }
182
- }
183
- if (change.fieldChanges) {
184
- for (const field of change.fieldChanges) {
185
- if (field.changeType === 'added') {
186
- lines.push(` + field "${field.fieldPath}" (${field.newValue?.fieldType})`);
187
- }
188
- else if (field.changeType === 'removed') {
189
- lines.push(` - field "${field.fieldPath}"`);
190
- }
191
- else {
192
- lines.push(` ~ field "${field.fieldPath}": ${field.oldValue?.fieldType} -> ${field.newValue?.fieldType}`);
193
- }
194
- }
195
- }
196
- }
197
- lines.push('');
198
- }
199
- // Flow changes
200
- const addedFlows = result.flowChanges.filter((c) => c.changeType === 'added');
201
- const removedFlows = result.flowChanges.filter((c) => c.changeType === 'removed');
202
- const modifiedFlows = result.flowChanges.filter((c) => c.changeType === 'modified');
203
- if (addedFlows.length > 0) {
204
- lines.push('Flows Added:');
205
- for (const flow of addedFlows) {
206
- lines.push(` + ${flow.sourceName} -> ${flow.targetName}`);
207
- }
208
- lines.push('');
209
- }
210
- if (removedFlows.length > 0) {
211
- lines.push('Flows Removed:');
212
- for (const flow of removedFlows) {
213
- lines.push(` - ${flow.sourceName} -> ${flow.targetName}`);
214
- }
215
- lines.push('');
216
- }
217
- if (modifiedFlows.length > 0) {
218
- lines.push('Flows Modified:');
219
- for (const flow of modifiedFlows) {
220
- const mappingCount = flow.mappingChanges?.length ?? 0;
221
- lines.push(` ~ ${flow.sourceName} -> ${flow.targetName} (${mappingCount} mapping changes)`);
222
- }
223
- lines.push('');
224
- }
225
- return lines.join('\n').trim();
226
- }
227
- /**
228
- * Get file content from a git ref (e.g., HEAD, HEAD~1, branch name)
229
- */
230
- function getGitFileContent(filePath, ref) {
231
- try {
232
- // Get the relative path from the repo root
233
- const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
234
- const absolutePath = fs.realpathSync(filePath);
235
- const relativePath = absolutePath.replace(repoRoot + '/', '');
236
- const content = execSync(`git show ${ref}:${relativePath}`, {
237
- encoding: 'utf-8',
238
- stdio: ['pipe', 'pipe', 'pipe'],
239
- });
240
- return content;
241
- }
242
- catch {
243
- return null;
244
- }
245
- }
246
- function outputDiff(result, format) {
247
- if (format === 'json') {
248
- outputJson(formatDiffJson(result));
249
- }
250
- else if (format === 'text') {
251
- console.log(formatDiffText(result));
252
- }
253
- else {
254
- console.log(formatDiffXml(result));
255
- }
256
- }
257
- /**
258
- * Diff two eventmodel files or compare a file against a git ref.
259
- *
260
- * Usage:
261
- * diff(file1, file2, format) - Compare two files
262
- * diff(file1, undefined, format, ref) - Compare file against git ref (default: HEAD)
263
- */
264
- export function diff(basePath, comparePath, format, gitRef) {
265
- // Single file mode: compare against git ref
266
- if (!comparePath) {
267
- const ref = gitRef ?? 'HEAD';
268
- const gitContent = getGitFileContent(basePath, ref);
269
- if (gitContent === null) {
270
- console.error(`Error: Could not get ${basePath} from git ref '${ref}'`);
271
- console.error('Make sure the file is tracked by git and the ref exists.');
272
- process.exit(2);
273
- }
274
- const baseModel = loadModelFromContent(gitContent);
275
- const compareModel = loadModel(basePath);
276
- const result = diffModels(baseModel, compareModel);
277
- outputDiff(result, format);
278
- return;
279
- }
280
- // Two file mode: compare two files
281
- if (!fs.existsSync(basePath)) {
282
- console.error(`Error: File not found: ${basePath}`);
283
- process.exit(2);
284
- }
285
- if (!fs.existsSync(comparePath)) {
286
- console.error(`Error: File not found: ${comparePath}`);
287
- process.exit(2);
288
- }
289
- const baseModel = loadModel(basePath);
290
- const compareModel = loadModel(comparePath);
291
- const result = diffModels(baseModel, compareModel);
292
- outputDiff(result, format);
293
- }
@@ -1,2 +0,0 @@
1
- import type { EventModel } from '../../types.js';
2
- export declare function exportEventmodelToJson(model: EventModel): void;
@@ -1,355 +0,0 @@
1
- function mapFieldType(fieldType) {
2
- // Map our field types to spec field types
3
- const typeMap = {
4
- 'UUID': 'UUID',
5
- 'Boolean': 'Boolean',
6
- 'Double': 'Double',
7
- 'Decimal': 'Decimal',
8
- 'Date': 'Date',
9
- 'DateTime': 'DateTime',
10
- 'Long': 'Long',
11
- 'Int': 'Int',
12
- 'String': 'String',
13
- 'Custom': 'Custom',
14
- };
15
- return typeMap[fieldType] || 'String';
16
- }
17
- function mapStatus(status) {
18
- const statusMap = {
19
- 'created': 'Created',
20
- 'done': 'Done',
21
- 'in-progress': 'InProgress',
22
- 'blocked': 'InProgress', // No blocked in spec, map to InProgress
23
- };
24
- return statusMap[status];
25
- }
26
- function convertField(field) {
27
- const specField = {
28
- name: field.name,
29
- type: mapFieldType(field.fieldType),
30
- };
31
- if (field.isOptional)
32
- specField.optional = true;
33
- if (field.isGenerated)
34
- specField.generated = true;
35
- if (field.subfields && field.subfields.length > 0) {
36
- specField.subfields = field.subfields.map(convertField);
37
- }
38
- return specField;
39
- }
40
- function isInSlice(slice, pos, width, height) {
41
- const centerX = pos.x + width / 2;
42
- const centerY = pos.y + height / 2;
43
- return (centerX >= slice.position.x &&
44
- centerX <= slice.position.x + slice.size.width &&
45
- centerY >= slice.position.y &&
46
- centerY <= slice.position.y + slice.size.height);
47
- }
48
- function getInboundDependencies(model, entityId, entityType) {
49
- const deps = [];
50
- for (const flow of model.flows.values()) {
51
- if (flow.targetId === entityId) {
52
- let sourceTitle = '';
53
- let sourceType = 'COMMAND';
54
- const cmd = model.commands.get(flow.sourceId);
55
- const evt = model.events.get(flow.sourceId);
56
- const rm = model.readModels.get(flow.sourceId);
57
- const scr = model.screens.get(flow.sourceId);
58
- const proc = model.processors.get(flow.sourceId);
59
- if (cmd) {
60
- sourceTitle = cmd.name;
61
- sourceType = 'COMMAND';
62
- }
63
- else if (evt) {
64
- sourceTitle = evt.name;
65
- sourceType = 'EVENT';
66
- }
67
- else if (rm) {
68
- sourceTitle = rm.name;
69
- sourceType = 'READMODEL';
70
- }
71
- else if (scr) {
72
- sourceTitle = scr.name;
73
- sourceType = 'SCREEN';
74
- }
75
- else if (proc) {
76
- sourceTitle = proc.name;
77
- sourceType = 'AUTOMATION';
78
- }
79
- if (sourceTitle) {
80
- deps.push({
81
- id: flow.id,
82
- title: sourceTitle,
83
- type: 'INBOUND',
84
- elementType: sourceType,
85
- });
86
- }
87
- }
88
- }
89
- return deps;
90
- }
91
- function getOutboundDependencies(model, entityId, entityType) {
92
- const deps = [];
93
- for (const flow of model.flows.values()) {
94
- if (flow.sourceId === entityId) {
95
- let targetTitle = '';
96
- let targetType = 'EVENT';
97
- const cmd = model.commands.get(flow.targetId);
98
- const evt = model.events.get(flow.targetId);
99
- const rm = model.readModels.get(flow.targetId);
100
- const scr = model.screens.get(flow.targetId);
101
- const proc = model.processors.get(flow.targetId);
102
- if (cmd) {
103
- targetTitle = cmd.name;
104
- targetType = 'COMMAND';
105
- }
106
- else if (evt) {
107
- targetTitle = evt.name;
108
- targetType = 'EVENT';
109
- }
110
- else if (rm) {
111
- targetTitle = rm.name;
112
- targetType = 'READMODEL';
113
- }
114
- else if (scr) {
115
- targetTitle = scr.name;
116
- targetType = 'SCREEN';
117
- }
118
- else if (proc) {
119
- targetTitle = proc.name;
120
- targetType = 'AUTOMATION';
121
- }
122
- if (targetTitle) {
123
- deps.push({
124
- id: flow.id,
125
- title: targetTitle,
126
- type: 'OUTBOUND',
127
- elementType: targetType,
128
- });
129
- }
130
- }
131
- }
132
- return deps;
133
- }
134
- function determineSliceType(commands, events, processors) {
135
- // If there are processors, it's an automation slice
136
- if (processors.length > 0)
137
- return 'AUTOMATION';
138
- // If there are commands and events, it's a state change
139
- if (commands.length > 0 && events.length > 0)
140
- return 'STATE_CHANGE';
141
- // Otherwise it's a state view (read-only)
142
- return 'STATE_VIEW';
143
- }
144
- // Check if two rectangles overlap
145
- function rectanglesOverlap(r1, r2) {
146
- return (r1.x < r2.x + r2.width &&
147
- r1.x + r1.width > r2.x &&
148
- r1.y < r2.y + r2.height &&
149
- r1.y + r1.height > r2.y);
150
- }
151
- // Find aggregates that overlap with the slice
152
- function getAggregatesForSlice(model, slice) {
153
- const sliceRect = {
154
- x: slice.position.x,
155
- y: slice.position.y,
156
- width: slice.size.width,
157
- height: slice.size.height,
158
- };
159
- const aggregateNames = [];
160
- for (const aggregate of model.aggregates.values()) {
161
- const aggRect = {
162
- x: aggregate.position.x,
163
- y: aggregate.position.y,
164
- width: aggregate.size.width,
165
- height: aggregate.size.height,
166
- };
167
- if (rectanglesOverlap(sliceRect, aggRect)) {
168
- aggregateNames.push(aggregate.name);
169
- }
170
- }
171
- return aggregateNames;
172
- }
173
- // Find actors that overlap with the slice
174
- function getActorsForSlice(model, slice) {
175
- const sliceRect = {
176
- x: slice.position.x,
177
- y: slice.position.y,
178
- width: slice.size.width,
179
- height: slice.size.height,
180
- };
181
- const actors = [];
182
- for (const actor of model.actors.values()) {
183
- const actorRect = {
184
- x: actor.position.x,
185
- y: actor.position.y,
186
- width: actor.size.width,
187
- height: actor.size.height,
188
- };
189
- if (rectanglesOverlap(sliceRect, actorRect)) {
190
- actors.push({
191
- name: actor.name,
192
- authRequired: false, // Default - we don't track this property yet
193
- });
194
- }
195
- }
196
- return actors;
197
- }
198
- export function exportEventmodelToJson(model) {
199
- const specSlices = [];
200
- // Sort slices by position
201
- const sortedSlices = [...model.slices.values()].sort((a, b) => a.position.x - b.position.x);
202
- for (const slice of sortedSlices) {
203
- // Find components in this slice
204
- const commands = [];
205
- const events = [];
206
- const readModels = [];
207
- const screens = [];
208
- const processors = [];
209
- for (const cmd of model.commands.values()) {
210
- if (isInSlice(slice, cmd.position, cmd.width, cmd.height)) {
211
- commands.push(cmd);
212
- }
213
- }
214
- // Filter out linked copies - only export originals
215
- for (const evt of model.events.values()) {
216
- if (!evt.originalNodeId && isInSlice(slice, evt.position, evt.width, evt.height)) {
217
- events.push(evt);
218
- }
219
- }
220
- // Filter out linked copies - only export originals
221
- for (const rm of model.readModels.values()) {
222
- if (!rm.originalNodeId && isInSlice(slice, rm.position, rm.width, rm.height)) {
223
- readModels.push(rm);
224
- }
225
- }
226
- // Filter out linked copies - only export originals
227
- for (const scr of model.screens.values()) {
228
- if (!scr.originalNodeId && isInSlice(slice, scr.position, scr.width, scr.height)) {
229
- screens.push(scr);
230
- }
231
- }
232
- for (const proc of model.processors.values()) {
233
- if (isInSlice(slice, proc.position, proc.width, proc.height)) {
234
- processors.push(proc);
235
- }
236
- }
237
- // Find scenarios for this slice
238
- const scenarios = [...model.scenarios.values()].filter(s => s.sliceId === slice.id);
239
- // Convert to spec format
240
- const specSlice = {
241
- id: slice.id,
242
- title: slice.name,
243
- sliceType: determineSliceType(commands, events, processors),
244
- status: mapStatus(slice.status),
245
- commands: commands.map(cmd => ({
246
- id: cmd.id,
247
- title: cmd.name,
248
- type: 'COMMAND',
249
- fields: cmd.fields.map(convertField),
250
- dependencies: [
251
- ...getInboundDependencies(model, cmd.id, 'COMMAND'),
252
- ...getOutboundDependencies(model, cmd.id, 'COMMAND'),
253
- ],
254
- })),
255
- events: events.map(evt => ({
256
- id: evt.id,
257
- title: evt.name,
258
- type: 'EVENT',
259
- fields: evt.fields.map(convertField),
260
- dependencies: [
261
- ...getInboundDependencies(model, evt.id, 'EVENT'),
262
- ...getOutboundDependencies(model, evt.id, 'EVENT'),
263
- ],
264
- })),
265
- readmodels: readModels.map(rm => ({
266
- id: rm.id,
267
- title: rm.name,
268
- type: 'READMODEL',
269
- fields: rm.fields.map(convertField),
270
- dependencies: [
271
- ...getInboundDependencies(model, rm.id, 'READMODEL'),
272
- ...getOutboundDependencies(model, rm.id, 'READMODEL'),
273
- ],
274
- })),
275
- screens: screens.map(scr => ({
276
- id: scr.id,
277
- title: scr.name,
278
- type: 'SCREEN',
279
- fields: scr.fields.map(convertField),
280
- dependencies: [
281
- ...getInboundDependencies(model, scr.id, 'SCREEN'),
282
- ...getOutboundDependencies(model, scr.id, 'SCREEN'),
283
- ],
284
- })),
285
- processors: processors.map(proc => ({
286
- id: proc.id,
287
- title: proc.name,
288
- type: 'AUTOMATION',
289
- fields: proc.fields.map(convertField),
290
- dependencies: [
291
- ...getInboundDependencies(model, proc.id, 'AUTOMATION'),
292
- ...getOutboundDependencies(model, proc.id, 'AUTOMATION'),
293
- ],
294
- })),
295
- tables: [],
296
- actors: getActorsForSlice(model, slice),
297
- aggregates: getAggregatesForSlice(model, slice),
298
- specifications: scenarios.map(scenario => {
299
- const givenSteps = scenario.givenEvents.map(given => {
300
- const evt = model.events.get(given.eventStickyId);
301
- return {
302
- id: given.eventStickyId,
303
- title: evt?.name ?? 'Unknown',
304
- elementType: 'EVENT',
305
- fields: given.fieldValues,
306
- };
307
- });
308
- const whenSteps = [];
309
- if (scenario.whenCommand) {
310
- const cmd = model.commands.get(scenario.whenCommand.commandStickyId);
311
- whenSteps.push({
312
- id: scenario.whenCommand.commandStickyId,
313
- title: cmd?.name ?? 'Unknown',
314
- elementType: 'COMMAND',
315
- fields: scenario.whenCommand.fieldValues,
316
- });
317
- }
318
- const thenSteps = [];
319
- if (scenario.then.type === 'events' && scenario.then.expectedEvents) {
320
- for (const expected of scenario.then.expectedEvents) {
321
- const evt = model.events.get(expected.eventStickyId);
322
- thenSteps.push({
323
- id: expected.eventStickyId,
324
- title: evt?.name ?? 'Unknown',
325
- elementType: 'EVENT',
326
- fields: expected.fieldValues,
327
- });
328
- }
329
- }
330
- else if (scenario.then.type === 'readModelAssertion' && scenario.then.readModelAssertion) {
331
- const rm = model.readModels.get(scenario.then.readModelAssertion.readModelStickyId);
332
- thenSteps.push({
333
- id: scenario.then.readModelAssertion.readModelStickyId,
334
- title: rm?.name ?? 'Unknown',
335
- elementType: 'READMODEL',
336
- fields: scenario.then.readModelAssertion.expectedFieldValues,
337
- });
338
- }
339
- return {
340
- id: scenario.id,
341
- title: scenario.name,
342
- linkedId: slice.id,
343
- given: givenSteps,
344
- when: whenSteps,
345
- then: thenSteps,
346
- };
347
- }),
348
- };
349
- specSlices.push(specSlice);
350
- }
351
- const exportData = {
352
- slices: specSlices,
353
- };
354
- console.log(JSON.stringify(exportData, null, 2));
355
- }
@@ -1,2 +0,0 @@
1
- export declare function gitSetup(global: boolean): void;
2
- export declare function gitStatus(): void;