@finos/legend-application-studio 26.1.9 → 26.1.10

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 (86) hide show
  1. package/lib/components/editor/StatusBar.d.ts.map +1 -1
  2. package/lib/components/editor/StatusBar.js +1 -4
  3. package/lib/components/editor/StatusBar.js.map +1 -1
  4. package/lib/components/editor/editor-group/{FileGenerationViewer.d.ts → ArtifactGenerationViewer.d.ts} +2 -2
  5. package/lib/components/editor/editor-group/ArtifactGenerationViewer.d.ts.map +1 -0
  6. package/lib/components/editor/editor-group/ArtifactGenerationViewer.js +32 -0
  7. package/lib/components/editor/editor-group/ArtifactGenerationViewer.js.map +1 -0
  8. package/lib/components/editor/editor-group/EditorGroup.js +6 -6
  9. package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
  10. package/lib/components/editor/editor-group/data-editor/DataElementEditor.d.ts.map +1 -1
  11. package/lib/components/editor/editor-group/data-editor/DataElementEditor.js +1 -1
  12. package/lib/components/editor/editor-group/data-editor/DataElementEditor.js.map +1 -1
  13. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
  14. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js +1 -1
  15. package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js.map +1 -1
  16. package/lib/components/editor/editor-group/element-generation-editor/FileGenerationEditor.js +1 -1
  17. package/lib/components/editor/editor-group/element-generation-editor/FileGenerationEditor.js.map +1 -1
  18. package/lib/components/editor/editor-group/element-generation-editor/FileSystemViewer.d.ts.map +1 -1
  19. package/lib/components/editor/editor-group/element-generation-editor/FileSystemViewer.js +1 -1
  20. package/lib/components/editor/editor-group/element-generation-editor/FileSystemViewer.js.map +1 -1
  21. package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.js +1 -1
  22. package/lib/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.js.map +1 -1
  23. package/lib/components/editor/panel-group/DevToolPanel.d.ts.map +1 -1
  24. package/lib/components/editor/panel-group/DevToolPanel.js +4 -1
  25. package/lib/components/editor/panel-group/DevToolPanel.js.map +1 -1
  26. package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
  27. package/lib/components/editor/side-bar/CreateNewElementModal.js +1 -1
  28. package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
  29. package/lib/components/editor/side-bar/Explorer.js +1 -1
  30. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  31. package/lib/index.css +1 -1
  32. package/lib/package.json +3 -3
  33. package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
  34. package/lib/stores/editor/EditorGraphState.js +7 -6
  35. package/lib/stores/editor/EditorGraphState.js.map +1 -1
  36. package/lib/stores/editor/EditorStore.js +2 -2
  37. package/lib/stores/editor/EditorStore.js.map +1 -1
  38. package/lib/stores/editor/ExplorerTreeState.d.ts +3 -3
  39. package/lib/stores/editor/ExplorerTreeState.d.ts.map +1 -1
  40. package/lib/stores/editor/ExplorerTreeState.js +10 -10
  41. package/lib/stores/editor/ExplorerTreeState.js.map +1 -1
  42. package/lib/stores/editor/NewElementState.d.ts +3 -3
  43. package/lib/stores/editor/NewElementState.d.ts.map +1 -1
  44. package/lib/stores/editor/NewElementState.js +2 -2
  45. package/lib/stores/editor/NewElementState.js.map +1 -1
  46. package/lib/stores/editor/editor-state/{FileGenerationViewerState.d.ts → ArtifactGenerationViewerState.d.ts} +4 -4
  47. package/lib/stores/editor/editor-state/ArtifactGenerationViewerState.d.ts.map +1 -0
  48. package/lib/stores/editor/editor-state/{FileGenerationViewerState.js → ArtifactGenerationViewerState.js} +10 -9
  49. package/lib/stores/editor/editor-state/ArtifactGenerationViewerState.js.map +1 -0
  50. package/lib/stores/editor/editor-state/FileGenerationState.js +1 -1
  51. package/lib/stores/editor/editor-state/FileGenerationState.js.map +1 -1
  52. package/lib/stores/editor/editor-state/GraphGenerationState.d.ts +32 -19
  53. package/lib/stores/editor/editor-state/GraphGenerationState.d.ts.map +1 -1
  54. package/lib/stores/editor/editor-state/GraphGenerationState.js +173 -113
  55. package/lib/stores/editor/editor-state/GraphGenerationState.js.map +1 -1
  56. package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.js +1 -1
  57. package/lib/stores/editor/editor-state/element-editor-state/ElementEditorState.js.map +1 -1
  58. package/lib/stores/project-view/ProjectViewerStore.js +1 -1
  59. package/lib/stores/project-view/ProjectViewerStore.js.map +1 -1
  60. package/package.json +13 -13
  61. package/src/components/editor/StatusBar.tsx +1 -4
  62. package/src/components/editor/editor-group/{FileGenerationViewer.tsx → ArtifactGenerationViewer.tsx} +28 -25
  63. package/src/components/editor/editor-group/EditorGroup.tsx +6 -6
  64. package/src/components/editor/editor-group/data-editor/DataElementEditor.tsx +1 -1
  65. package/src/components/editor/editor-group/data-editor/EmbeddedDataEditor.tsx +1 -1
  66. package/src/components/editor/editor-group/element-generation-editor/FileGenerationEditor.tsx +1 -1
  67. package/src/components/editor/editor-group/element-generation-editor/FileSystemViewer.tsx +4 -4
  68. package/src/components/editor/editor-group/external-format-editor/DSL_ExternalFormat_SchemaSetElementEditor.tsx +1 -1
  69. package/src/components/editor/panel-group/DevToolPanel.tsx +14 -0
  70. package/src/components/editor/side-bar/CreateNewElementModal.tsx +3 -5
  71. package/src/components/editor/side-bar/Explorer.tsx +1 -1
  72. package/src/stores/editor/EditorGraphState.ts +7 -6
  73. package/src/stores/editor/EditorStore.ts +2 -2
  74. package/src/stores/editor/ExplorerTreeState.ts +10 -10
  75. package/src/stores/editor/NewElementState.ts +5 -5
  76. package/src/stores/editor/editor-state/{FileGenerationViewerState.ts → ArtifactGenerationViewerState.ts} +12 -9
  77. package/src/stores/editor/editor-state/FileGenerationState.ts +1 -1
  78. package/src/stores/editor/editor-state/GraphGenerationState.ts +258 -170
  79. package/src/stores/editor/editor-state/element-editor-state/ElementEditorState.ts +1 -1
  80. package/src/stores/project-view/ProjectViewerStore.ts +1 -1
  81. package/tsconfig.json +2 -2
  82. package/lib/components/editor/editor-group/FileGenerationViewer.d.ts.map +0 -1
  83. package/lib/components/editor/editor-group/FileGenerationViewer.js +0 -32
  84. package/lib/components/editor/editor-group/FileGenerationViewer.js.map +0 -1
  85. package/lib/stores/editor/editor-state/FileGenerationViewerState.d.ts.map +0 -1
  86. package/lib/stores/editor/editor-state/FileGenerationViewerState.js.map +0 -1
@@ -17,10 +17,10 @@
17
17
  import type { EditorStore } from '../EditorStore.js';
18
18
  import { EditorState } from './EditorState.js';
19
19
  import { observable, makeObservable, computed } from 'mobx';
20
- import type { FileSystem_File } from '../utils/FileSystemTreeUtils.js';
21
- import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
22
20
  import { returnUndefOnError } from '@finos/legend-shared';
21
+ import { DEFAULT_TAB_SIZE } from '@finos/legend-application';
23
22
  import { CODE_EDITOR_LANGUAGE } from '@finos/legend-lego/code-editor';
23
+ import type { FileSystem_File } from '../utils/FileSystemTreeUtils.js';
24
24
 
25
25
  export const getTextContent = (
26
26
  content: string,
@@ -51,30 +51,33 @@ export const getEditorLanguageForFormat = (
51
51
  }
52
52
  };
53
53
 
54
- export class FileGenerationViewerState extends EditorState {
55
- file: FileSystem_File;
54
+ export class ArtifactGenerationViewerState extends EditorState {
55
+ artifact: FileSystem_File;
56
56
 
57
57
  constructor(editorStore: EditorStore, file: FileSystem_File) {
58
58
  super(editorStore);
59
59
 
60
60
  makeObservable(this, {
61
- file: observable,
61
+ artifact: observable,
62
62
  label: computed,
63
63
  generatedFilePath: computed,
64
64
  });
65
65
 
66
- this.file = file;
66
+ this.artifact = file;
67
67
  }
68
68
 
69
69
  get label(): string {
70
- return this.file.name;
70
+ return this.artifact.name;
71
71
  }
72
72
 
73
73
  override match(tab: EditorState): boolean {
74
- return tab instanceof FileGenerationViewerState && tab.file === this.file;
74
+ return (
75
+ tab instanceof ArtifactGenerationViewerState &&
76
+ tab.artifact === this.artifact
77
+ );
75
78
  }
76
79
 
77
80
  get generatedFilePath(): string {
78
- return this.file.path;
81
+ return this.artifact.path;
79
82
  }
80
83
  }
@@ -230,7 +230,7 @@ export class FileGenerationState extends GeneratedFileStructureState {
230
230
  return;
231
231
  }
232
232
  const mode =
233
- this.editorStore.graphState.graphGenerationState.getFileGenerationConfiguration(
233
+ this.editorStore.graphState.graphGenerationState.globalFileGenerationState.getFileGenerationConfiguration(
234
234
  this.fileGeneration.type,
235
235
  ).generationMode;
236
236
  const result =
@@ -31,22 +31,8 @@ import {
31
31
  isNonNullable,
32
32
  ActionState,
33
33
  } from '@finos/legend-shared';
34
- import { LEGEND_STUDIO_APP_EVENT } from '../../../__lib__/LegendStudioEvent.js';
35
- import {
36
- type FileSystemTreeNodeData,
37
- type FileResult,
38
- FileSystem_Directory,
39
- GENERATION_FILE_ROOT_NAME,
40
- FileSystem_File,
41
- openNode,
42
- populateDirectoryTreeNodeChildren,
43
- buildFileSystemDirectory,
44
- reprocessOpenNodes,
45
- getFileSystemTreeData,
46
- } from '../utils/FileSystemTreeUtils.js';
47
34
  import type { TreeData } from '@finos/legend-art';
48
35
  import type { EditorStore } from '../EditorStore.js';
49
- import { FileGenerationViewerState } from './FileGenerationViewerState.js';
50
36
  import type { EditorState } from './EditorState.js';
51
37
  import { ElementEditorState } from './element-editor-state/ElementEditorState.js';
52
38
  import { ElementFileGenerationState } from './element-editor-state/ElementFileGenerationState.js';
@@ -56,77 +42,66 @@ import {
56
42
  type GenerationOutput,
57
43
  type DSL_Generation_PureGraphManagerPlugin_Extension,
58
44
  type GenerationTreeNode,
45
+ ArtifactGenerationExtensionResult,
59
46
  Class,
60
47
  Enumeration,
61
48
  GenerationSpecification,
62
49
  ELEMENT_PATH_DELIMITER,
63
50
  } from '@finos/legend-graph';
64
- import type { DSL_Generation_LegendStudioApplicationPlugin_Extension } from '../../extensions/DSL_Generation_LegendStudioApplicationPlugin_Extension.js';
65
51
  import { ExternalFormatState } from './ExternalFormatState.js';
52
+ import { ExplorerTreeRootPackageLabel } from '../ExplorerTreeState.js';
53
+ import type { DSL_Generation_LegendStudioApplicationPlugin_Extension } from '../../extensions/DSL_Generation_LegendStudioApplicationPlugin_Extension.js';
54
+ import { LEGEND_STUDIO_APP_EVENT } from '../../../__lib__/LegendStudioEvent.js';
55
+ import {
56
+ FileSystem_Directory,
57
+ type FileSystemTreeNodeData,
58
+ FileSystem_File,
59
+ GENERATION_FILE_ROOT_NAME,
60
+ buildFileSystemDirectory,
61
+ getFileSystemTreeData,
62
+ reprocessOpenNodes,
63
+ type FileResult,
64
+ openNode,
65
+ populateDirectoryTreeNodeChildren,
66
+ } from '../utils/FileSystemTreeUtils.js';
67
+ import { ArtifactGenerationViewerState } from './ArtifactGenerationViewerState.js';
66
68
  import {
67
69
  generationSpecification_addFileGeneration,
68
70
  generationSpecification_addGenerationElement,
69
71
  } from '../../graph-modifier/DSL_Generation_GraphModifierHelper.js';
70
- import { ExplorerTreeRootPackageLabel } from '../ExplorerTreeState.js';
71
72
 
72
73
  export const DEFAULT_GENERATION_SPECIFICATION_NAME =
73
74
  'MyGenerationSpecification';
74
75
 
75
- export type FileGenerationTypeOption = {
76
+ export type GenerationTypeOption = {
76
77
  value: string;
77
78
  label: string;
78
79
  };
79
80
 
80
- export class GraphGenerationState {
81
+ export class DEPREACTED_GlobalFileGenerationState {
82
+ readonly graphGenerationState: GraphGenerationState;
81
83
  readonly editorStore: EditorStore;
82
- readonly clearingGenerationEntitiesState = ActionState.create();
83
-
84
- isRunningGlobalGenerate = false;
85
- generatedEntities = new Map<string, Entity[]>();
86
- externalFormatState: ExternalFormatState;
87
84
  // NOTE: this will eventually be removed once we also do model/schema import using external format
88
85
  // See https://github.com/finos/legend-studio/issues/866
89
86
  fileGenerationConfigurations: GenerationConfigurationDescription[] = [];
90
- // file generation output
91
- rootFileDirectory: FileSystem_Directory;
92
- filesIndex = new Map<string, FileSystem_File>();
93
- selectedNode?: FileSystemTreeNodeData | undefined;
94
87
 
95
- constructor(editorStore: EditorStore) {
96
- makeObservable<GraphGenerationState>(this, {
97
- isRunningGlobalGenerate: observable,
98
- generatedEntities: observable.shallow,
99
- clearingGenerationEntitiesState: observable,
88
+ constructor(
89
+ graphGenerationState: GraphGenerationState,
90
+ editorStore: EditorStore,
91
+ ) {
92
+ makeObservable(this, {
100
93
  fileGenerationConfigurations: observable,
101
- externalFormatState: observable,
102
- rootFileDirectory: observable,
103
- filesIndex: observable,
104
- selectedNode: observable.ref,
105
94
  fileGenerationConfigurationOptions: computed,
106
95
  supportedFileGenerationConfigurationsForCurrentElement: computed,
107
96
  setFileGenerationConfigurations: action,
108
- processGenerationResult: action,
109
- reprocessGenerationFileState: action,
110
- reprocessNodeTree: action,
111
- onTreeNodeSelect: action,
112
- setSelectedNode: action,
113
- emptyFileGeneration: action,
114
- possiblyAddMissingGenerationSpecifications: flow,
115
97
  fetchAvailableFileGenerationDescriptions: flow,
116
- globalGenerate: flow,
117
- generateModels: flow,
118
- generateFiles: flow,
119
- clearGenerations: flow,
98
+ DEPREACTED_generateFiles: flow,
120
99
  });
121
-
100
+ this.graphGenerationState = graphGenerationState;
122
101
  this.editorStore = editorStore;
123
- this.rootFileDirectory = new FileSystem_Directory(
124
- GENERATION_FILE_ROOT_NAME,
125
- );
126
- this.externalFormatState = new ExternalFormatState(editorStore);
127
102
  }
128
103
 
129
- get fileGenerationConfigurationOptions(): FileGenerationTypeOption[] {
104
+ get fileGenerationConfigurationOptions(): GenerationTypeOption[] {
130
105
  return this.fileGenerationConfigurations
131
106
  .slice()
132
107
  .sort((a, b): number => a.label.localeCompare(b.label))
@@ -172,11 +147,57 @@ export class GraphGenerationState {
172
147
  return [];
173
148
  }
174
149
 
175
- findGenerationParentPath(genChildPath: string): string | undefined {
176
- const genEntity = Array.from(this.generatedEntities.entries()).find(
177
- ([, genEntities]) => genEntities.find((m) => m.path === genChildPath),
178
- );
179
- return genEntity?.[0];
150
+ /**
151
+ * Generated file generations in the graph.
152
+ * NOTE: This method does not update graph and application only the files are generated.
153
+ */
154
+ *DEPREACTED_generateFiles(
155
+ generationOutputIndex: Map<string, GenerationOutput[]>,
156
+ ): GeneratorFn<void> {
157
+ try {
158
+ const generationSpecs =
159
+ this.editorStore.graphManagerState.graph.ownGenerationSpecifications;
160
+ if (!generationSpecs.length) {
161
+ return;
162
+ }
163
+ assertTrue(
164
+ generationSpecs.length === 1,
165
+ `Can't generate models: only one generation specification permitted to generate`,
166
+ );
167
+ const generationSpec = generationSpecs[0] as GenerationSpecification;
168
+ const fileGenerations = generationSpec.fileGenerations;
169
+ // we don't need to keep 'fetching' the main model as it won't grow with each file generation
170
+ for (const fileGeneration of fileGenerations) {
171
+ let result: GenerationOutput[] = [];
172
+ try {
173
+ const mode =
174
+ this.editorStore.graphState.graphGenerationState.globalFileGenerationState.getFileGenerationConfiguration(
175
+ fileGeneration.value.type,
176
+ ).generationMode;
177
+ result =
178
+ (yield this.editorStore.graphManagerState.graphManager.generateFile(
179
+ fileGeneration.value,
180
+ mode,
181
+ this.editorStore.graphManagerState.graph,
182
+ )) as GenerationOutput[];
183
+ } catch (error) {
184
+ assertErrorThrown(error);
185
+ throw new Error(
186
+ `Can't generate files using specification '${fileGeneration.value.path}'. Error: ${error.message}`,
187
+ );
188
+ }
189
+ generationOutputIndex.set(fileGeneration.value.path, result);
190
+ }
191
+ } catch (error) {
192
+ assertErrorThrown(error);
193
+ this.editorStore.applicationStore.logService.error(
194
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERATION_FAILURE),
195
+ error,
196
+ );
197
+ this.editorStore.graphState.editorStore.applicationStore.notificationService.notifyError(
198
+ `${error.message}`,
199
+ );
200
+ }
180
201
  }
181
202
 
182
203
  setFileGenerationConfigurations(
@@ -213,6 +234,70 @@ export class GraphGenerationState {
213
234
  this.editorStore.applicationStore.notificationService.notifyError(error);
214
235
  }
215
236
  }
237
+ }
238
+
239
+ export class GraphGenerationState {
240
+ editorStore: EditorStore;
241
+ isRunningGlobalGenerate = false;
242
+ generatedEntities = new Map<string, Entity[]>();
243
+ clearingGenerationEntitiesState = ActionState.create();
244
+ externalFormatState: ExternalFormatState;
245
+ globalFileGenerationState: DEPREACTED_GlobalFileGenerationState;
246
+ // file generation output
247
+ rootFileDirectory: FileSystem_Directory;
248
+ filesIndex = new Map<string, FileSystem_File>();
249
+ selectedNode?: FileSystemTreeNodeData | undefined;
250
+ // Note for now generation of artifact generations is set to false.
251
+ // This is to explore the performance impact of inlcuding this in the generation action and whether we always
252
+ // generate artifacts or add inputs to the api to choose which ones we generate.
253
+ enableArtifactGeneration = false;
254
+
255
+ constructor(editorStore: EditorStore) {
256
+ makeObservable<GraphGenerationState>(this, {
257
+ isRunningGlobalGenerate: observable,
258
+ generatedEntities: observable.shallow,
259
+ clearingGenerationEntitiesState: observable,
260
+ externalFormatState: observable,
261
+ enableArtifactGeneration: observable,
262
+ globalFileGenerationState: observable,
263
+ rootFileDirectory: observable,
264
+ filesIndex: observable,
265
+ selectedNode: observable.ref,
266
+ processGenerationResult: action,
267
+ reprocessGenerationFileState: action,
268
+ setEnableArtifactGeneration: action,
269
+ reprocessNodeTree: action,
270
+ onTreeNodeSelect: action,
271
+ setSelectedNode: action,
272
+ emptyGeneratedArtifacts: action,
273
+ possiblyAddMissingGenerationSpecifications: flow,
274
+ globalGenerate: flow,
275
+ generateModels: flow,
276
+ generateArtifacts: flow,
277
+ clearGenerations: flow,
278
+ });
279
+
280
+ this.editorStore = editorStore;
281
+ this.externalFormatState = new ExternalFormatState(editorStore);
282
+ this.globalFileGenerationState = new DEPREACTED_GlobalFileGenerationState(
283
+ this,
284
+ editorStore,
285
+ );
286
+ this.rootFileDirectory = new FileSystem_Directory(
287
+ GENERATION_FILE_ROOT_NAME,
288
+ );
289
+ }
290
+
291
+ setEnableArtifactGeneration(val: boolean): void {
292
+ this.enableArtifactGeneration = val;
293
+ }
294
+
295
+ findGenerationParentPath(genChildPath: string): string | undefined {
296
+ const genEntity = Array.from(this.generatedEntities.entries()).find(
297
+ ([, genEntities]) => genEntities.find((m) => m.path === genChildPath),
298
+ );
299
+ return genEntity?.[0];
300
+ }
216
301
 
217
302
  /**
218
303
  * Global generation is tied to the generation specification of the project. Every time a generation element
@@ -227,7 +312,7 @@ export class GraphGenerationState {
227
312
  this.isRunningGlobalGenerate = true;
228
313
  try {
229
314
  yield flowResult(this.generateModels());
230
- yield flowResult(this.generateFiles());
315
+ yield flowResult(this.generateArtifacts());
231
316
  } catch (error) {
232
317
  assertErrorThrown(error);
233
318
  this.editorStore.applicationStore.logService.error(
@@ -296,47 +381,29 @@ export class GraphGenerationState {
296
381
  }
297
382
 
298
383
  /**
299
- * Generated file generations in the graph.
384
+ * Generated artifacts generations in graph
300
385
  * NOTE: This method does not update graph and application only the files are generated.
301
386
  */
302
- *generateFiles(): GeneratorFn<void> {
387
+ *generateArtifacts(): GeneratorFn<void> {
303
388
  try {
304
- this.emptyFileGeneration();
389
+ this.emptyGeneratedArtifacts();
305
390
  const generationOutputIndex = new Map<string, GenerationOutput[]>();
306
- const generationSpecs =
307
- this.editorStore.graphManagerState.graph.ownGenerationSpecifications;
308
- if (!generationSpecs.length) {
309
- return;
310
- }
311
- assertTrue(
312
- generationSpecs.length === 1,
313
- `Can't generate models: only one generation specification permitted to generate`,
391
+ // handle deprecated file generations
392
+ yield flowResult(
393
+ this.globalFileGenerationState.DEPREACTED_generateFiles(
394
+ generationOutputIndex,
395
+ ),
314
396
  );
315
- const generationSpec = generationSpecs[0] as GenerationSpecification;
316
- const fileGenerations = generationSpec.fileGenerations;
317
- // we don't need to keep 'fetching' the main model as it won't grow with each file generation
318
- for (const fileGeneration of fileGenerations) {
319
- let result: GenerationOutput[] = [];
320
- try {
321
- const mode =
322
- this.editorStore.graphState.graphGenerationState.getFileGenerationConfiguration(
323
- fileGeneration.value.type,
324
- ).generationMode;
325
- result =
326
- (yield this.editorStore.graphManagerState.graphManager.generateFile(
327
- fileGeneration.value,
328
- mode,
329
- this.editorStore.graphManagerState.graph,
330
- )) as GenerationOutput[];
331
- } catch (error) {
332
- assertErrorThrown(error);
333
- throw new Error(
334
- `Can't generate files using specification '${fileGeneration.value.path}'. Error: ${error.message}`,
335
- );
336
- }
337
- generationOutputIndex.set(fileGeneration.value.path, result);
397
+ let artifacts = new ArtifactGenerationExtensionResult();
398
+ if (this.enableArtifactGeneration) {
399
+ artifacts =
400
+ (yield this.editorStore.graphManagerState.graphManager.generateArtifacts(
401
+ this.editorStore.graphManagerState.graph,
402
+ )) as ArtifactGenerationExtensionResult;
338
403
  }
339
- this.processGenerationResult(generationOutputIndex);
404
+
405
+ // handle results
406
+ this.processGenerationResult(artifacts, generationOutputIndex);
340
407
  } catch (error) {
341
408
  assertErrorThrown(error);
342
409
  this.editorStore.applicationStore.logService.error(
@@ -349,75 +416,16 @@ export class GraphGenerationState {
349
416
  }
350
417
  }
351
418
 
352
- /**
353
- * Used to clear generation entities as well as the generation model
354
- */
355
- *clearGenerations(): GeneratorFn<void> {
356
- this.clearingGenerationEntitiesState.inProgress();
357
- this.generatedEntities = new Map<string, Entity[]>();
358
- this.emptyFileGeneration();
359
- yield flowResult(
360
- this.editorStore.graphState.updateGenerationGraphAndApplication(),
361
- );
362
- this.clearingGenerationEntitiesState.complete();
363
- }
364
-
365
- /**
366
- * Method adds generation specification if
367
- * 1. no generation specification has been defined in graph
368
- * 2. there exists a generation element
369
- */
370
- *possiblyAddMissingGenerationSpecifications(): GeneratorFn<void> {
371
- if (
372
- !this.editorStore.graphManagerState.graph.ownGenerationSpecifications
373
- .length
374
- ) {
375
- const modelGenerationElements = this.editorStore.pluginManager
376
- .getPureGraphManagerPlugins()
377
- .flatMap(
378
- (plugin) =>
379
- (
380
- plugin as DSL_Generation_PureGraphManagerPlugin_Extension
381
- ).getExtraModelGenerationElementGetters?.() ?? [],
382
- )
383
- .flatMap((getter) => getter(this.editorStore.graphManagerState.graph));
384
- const fileGenerations =
385
- this.editorStore.graphManagerState.graph.ownFileGenerations;
386
- if (modelGenerationElements.length || fileGenerations.length) {
387
- const generationSpec = new GenerationSpecification(
388
- DEFAULT_GENERATION_SPECIFICATION_NAME,
389
- );
390
- modelGenerationElements.forEach((e) =>
391
- generationSpecification_addGenerationElement(generationSpec, e),
392
- );
393
- fileGenerations.forEach((e) =>
394
- generationSpecification_addFileGeneration(generationSpec, e),
395
- );
396
- // NOTE: add generation specification at the same package as the first generation element found.
397
- // we might want to revisit this decision?
398
- const specPackage = guaranteeNonNullable(
399
- [...modelGenerationElements, ...fileGenerations][0]?.package,
400
- );
401
- yield flowResult(
402
- this.editorStore.graphEditorMode.addElement(
403
- generationSpec,
404
- specPackage.path,
405
- false,
406
- ),
407
- );
408
- }
409
- }
410
- }
411
-
412
- // File Generation Tree
419
+ // Artifact Generation Tree
413
420
  processGenerationResult(
421
+ artifacts: ArtifactGenerationExtensionResult,
414
422
  generationOutputIndex: Map<string, GenerationOutput[]>,
415
423
  ): void {
416
424
  // empty file index and the directory, we keep the open nodes to reprocess them
417
- this.emptyFileGeneration();
425
+ this.emptyGeneratedArtifacts();
418
426
  const directoryTreeData =
419
427
  this.editorStore.graphState.editorStore.explorerTreeState
420
- .fileGenerationTreeData;
428
+ .artifactsGenerationTreeData;
421
429
  const openedNodeIds = directoryTreeData
422
430
  ? Array.from(directoryTreeData.nodes.values())
423
431
  .filter((node) => node.isOpen)
@@ -425,14 +433,15 @@ export class GraphGenerationState {
425
433
  : [];
426
434
  // we read the generation outputs and clean
427
435
  const generationResultIndex = new Map<string, FileResult>();
436
+ // handle DEPRECATED file gen for backward compatible
428
437
  Array.from(generationOutputIndex.entries()).forEach((entry) => {
429
- const fileGeneration =
438
+ const generator =
430
439
  this.editorStore.graphManagerState.graph.getNullableFileGeneration(
431
440
  entry[0],
432
441
  );
433
442
  const rootFolder =
434
- fileGeneration?.generationOutputPath ??
435
- fileGeneration?.path.split(ELEMENT_PATH_DELIMITER).join('_');
443
+ generator?.generationOutputPath ??
444
+ generator?.path.split(ELEMENT_PATH_DELIMITER).join('_');
436
445
  const generationOutputs = entry[1];
437
446
  generationOutputs.forEach((genOutput) => {
438
447
  genOutput.cleanFileName(rootFolder);
@@ -444,10 +453,29 @@ export class GraphGenerationState {
444
453
  }
445
454
  generationResultIndex.set(genOutput.fileName, {
446
455
  value: genOutput,
447
- parentId: fileGeneration?.path,
456
+ parentId: generator?.path,
448
457
  });
449
458
  });
450
459
  });
460
+ artifacts.values
461
+ .map((v) => v.artifactsByExtensionElements)
462
+ .flat()
463
+ .forEach((artifactByElement) => {
464
+ artifactByElement.files.forEach((genOutput) => {
465
+ genOutput.cleanFileName();
466
+ if (generationResultIndex.has(genOutput.fileName)) {
467
+ this.editorStore.applicationStore.logService.warn(
468
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.GENERATION_FAILURE),
469
+ `Found 2 generation outputs with same path '${genOutput.fileName}'`,
470
+ );
471
+ }
472
+ generationResultIndex.set(genOutput.fileName, {
473
+ value: genOutput,
474
+ parentId: artifactByElement.element,
475
+ });
476
+ });
477
+ });
478
+
451
479
  // take generation outputs and put them into the root directory
452
480
  buildFileSystemDirectory(
453
481
  this.rootFileDirectory,
@@ -455,16 +483,16 @@ export class GraphGenerationState {
455
483
  this.filesIndex,
456
484
  );
457
485
  // after building root directory set the generation tree data
458
- this.editorStore.graphState.editorStore.explorerTreeState.setFileGenerationTreeData(
486
+ this.editorStore.graphState.editorStore.explorerTreeState.setArtifactsGenerationTreeData(
459
487
  getFileSystemTreeData(
460
488
  this.editorStore.graphState.graphGenerationState.rootFileDirectory,
461
489
  ExplorerTreeRootPackageLabel.FILE_GENERATION,
462
490
  ),
463
491
  );
464
- this.editorStore.graphState.editorStore.explorerTreeState.setFileGenerationTreeData(
492
+ this.editorStore.graphState.editorStore.explorerTreeState.setArtifactsGenerationTreeData(
465
493
  this.reprocessNodeTree(
466
494
  Array.from(generationResultIndex.values()),
467
- this.editorStore.graphState.editorStore.explorerTreeState.getFileGenerationTreeData(),
495
+ this.editorStore.graphState.editorStore.explorerTreeState.getArtifactsGenerationTreeData(),
468
496
  openedNodeIds,
469
497
  ),
470
498
  );
@@ -477,10 +505,10 @@ export class GraphGenerationState {
477
505
  reprocessGenerationFileState(
478
506
  editorState: EditorState,
479
507
  ): EditorState | undefined {
480
- if (editorState instanceof FileGenerationViewerState) {
481
- const fileNode = this.filesIndex.get(editorState.file.path);
508
+ if (editorState instanceof ArtifactGenerationViewerState) {
509
+ const fileNode = this.filesIndex.get(editorState.artifact.path);
482
510
  if (fileNode) {
483
- editorState.file = fileNode;
511
+ editorState.artifact = fileNode;
484
512
  return editorState;
485
513
  } else {
486
514
  return undefined;
@@ -533,11 +561,11 @@ export class GraphGenerationState {
533
561
  }
534
562
  if (!reprocess && node.fileNode instanceof FileSystem_File) {
535
563
  this.editorStore.tabManagerState.openTab(
536
- new FileGenerationViewerState(this.editorStore, node.fileNode),
564
+ new ArtifactGenerationViewerState(this.editorStore, node.fileNode),
537
565
  );
538
566
  }
539
567
  this.setSelectedNode(node);
540
- this.editorStore.graphState.editorStore.explorerTreeState.setFileGenerationTreeData(
568
+ this.editorStore.graphState.editorStore.explorerTreeState.setArtifactsGenerationTreeData(
541
569
  { ...treeData },
542
570
  );
543
571
  }
@@ -552,10 +580,70 @@ export class GraphGenerationState {
552
580
  this.selectedNode = node;
553
581
  }
554
582
 
555
- emptyFileGeneration(): void {
583
+ emptyGeneratedArtifacts(): void {
556
584
  this.filesIndex = new Map<string, FileSystem_File>();
557
585
  this.rootFileDirectory = new FileSystem_Directory(
558
586
  GENERATION_FILE_ROOT_NAME,
559
587
  );
560
588
  }
589
+
590
+ /**
591
+ * Used to clear generation entities as well as the generation model
592
+ */
593
+ *clearGenerations(): GeneratorFn<void> {
594
+ this.clearingGenerationEntitiesState.inProgress();
595
+ this.generatedEntities = new Map<string, Entity[]>();
596
+ this.emptyGeneratedArtifacts();
597
+ yield flowResult(
598
+ this.editorStore.graphState.updateGenerationGraphAndApplication(),
599
+ );
600
+ this.clearingGenerationEntitiesState.complete();
601
+ }
602
+
603
+ /**
604
+ * Method adds generation specification if
605
+ * 1. no generation specification has been defined in graph
606
+ * 2. there exists a generation element
607
+ */
608
+ *possiblyAddMissingGenerationSpecifications(): GeneratorFn<void> {
609
+ if (
610
+ !this.editorStore.graphManagerState.graph.ownGenerationSpecifications
611
+ .length
612
+ ) {
613
+ const modelGenerationElements = this.editorStore.pluginManager
614
+ .getPureGraphManagerPlugins()
615
+ .flatMap(
616
+ (plugin) =>
617
+ (
618
+ plugin as DSL_Generation_PureGraphManagerPlugin_Extension
619
+ ).getExtraModelGenerationElementGetters?.() ?? [],
620
+ )
621
+ .flatMap((getter) => getter(this.editorStore.graphManagerState.graph));
622
+ const fileGenerations =
623
+ this.editorStore.graphManagerState.graph.ownFileGenerations;
624
+ if (modelGenerationElements.length || fileGenerations.length) {
625
+ const generationSpec = new GenerationSpecification(
626
+ DEFAULT_GENERATION_SPECIFICATION_NAME,
627
+ );
628
+ modelGenerationElements.forEach((e) =>
629
+ generationSpecification_addGenerationElement(generationSpec, e),
630
+ );
631
+ fileGenerations.forEach((e) =>
632
+ generationSpecification_addFileGeneration(generationSpec, e),
633
+ );
634
+ // NOTE: add generation specification at the same package as the first generation element found.
635
+ // we might want to revisit this decision?
636
+ const specPackage = guaranteeNonNullable(
637
+ [...modelGenerationElements, ...fileGenerations][0]?.package,
638
+ );
639
+ yield flowResult(
640
+ this.editorStore.graphEditorMode.addElement(
641
+ generationSpec,
642
+ specPackage.path,
643
+ false,
644
+ ),
645
+ );
646
+ }
647
+ }
648
+ }
561
649
  }
@@ -88,7 +88,7 @@ export class FileGenerationViewModeState extends ElementGenerationModeState {
88
88
  }
89
89
 
90
90
  get label(): string {
91
- return this.editorStore.graphState.graphGenerationState.getFileGenerationConfiguration(
91
+ return this.editorStore.graphState.graphGenerationState.globalFileGenerationState.getFileGenerationConfiguration(
92
92
  this.elementGenerationState.fileGenerationType,
93
93
  ).label;
94
94
  }
@@ -439,7 +439,7 @@ export class ProjectViewerStore {
439
439
 
440
440
  // fetch available editor configurations
441
441
  yield Promise.all([
442
- this.editorStore.graphState.graphGenerationState.fetchAvailableFileGenerationDescriptions(),
442
+ this.editorStore.graphState.graphGenerationState.globalFileGenerationState.fetchAvailableFileGenerationDescriptions(),
443
443
  this.editorStore.graphState.graphGenerationState.externalFormatState.fetchExternalFormatDescriptions(),
444
444
  this.editorStore.graphState.graphGenerationState.externalFormatState.fetchExternalFormatDescriptions(),
445
445
  this.editorStore.graphState.fetchAvailableFunctionActivatorConfigurations(),