@cyberismo/data-handler 0.0.16 → 0.0.18

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 (94) hide show
  1. package/dist/command-handler.js +5 -7
  2. package/dist/command-handler.js.map +1 -1
  3. package/dist/command-manager.js +4 -4
  4. package/dist/command-manager.js.map +1 -1
  5. package/dist/commands/create.js +1 -1
  6. package/dist/commands/create.js.map +1 -1
  7. package/dist/commands/fetch.d.ts +8 -0
  8. package/dist/commands/fetch.js +101 -23
  9. package/dist/commands/fetch.js.map +1 -1
  10. package/dist/commands/import.d.ts +5 -2
  11. package/dist/commands/import.js +12 -3
  12. package/dist/commands/import.js.map +1 -1
  13. package/dist/commands/remove.d.ts +3 -1
  14. package/dist/commands/remove.js +7 -1
  15. package/dist/commands/remove.js.map +1 -1
  16. package/dist/commands/rename.js +5 -0
  17. package/dist/commands/rename.js.map +1 -1
  18. package/dist/commands/show.d.ts +4 -2
  19. package/dist/commands/show.js +8 -2
  20. package/dist/commands/show.js.map +1 -1
  21. package/dist/commands/validate.js +3 -5
  22. package/dist/commands/validate.js.map +1 -1
  23. package/dist/containers/card-container.d.ts +7 -5
  24. package/dist/containers/card-container.js +30 -5
  25. package/dist/containers/card-container.js.map +1 -1
  26. package/dist/containers/project/project-paths.d.ts +2 -0
  27. package/dist/containers/project/project-paths.js +6 -0
  28. package/dist/containers/project/project-paths.js.map +1 -1
  29. package/dist/containers/project/resource-cache.js +9 -7
  30. package/dist/containers/project/resource-cache.js.map +1 -1
  31. package/dist/containers/project.d.ts +11 -2
  32. package/dist/containers/project.js +54 -8
  33. package/dist/containers/project.js.map +1 -1
  34. package/dist/containers/template.js +4 -4
  35. package/dist/containers/template.js.map +1 -1
  36. package/dist/interfaces/command-options.d.ts +3 -1
  37. package/dist/interfaces/project-interfaces.d.ts +5 -5
  38. package/dist/interfaces/project-interfaces.js.map +1 -1
  39. package/dist/project-settings.d.ts +5 -0
  40. package/dist/project-settings.js +12 -0
  41. package/dist/project-settings.js.map +1 -1
  42. package/dist/resources/card-type-resource.d.ts +6 -2
  43. package/dist/resources/card-type-resource.js +68 -86
  44. package/dist/resources/card-type-resource.js.map +1 -1
  45. package/dist/resources/field-type-resource.d.ts +5 -1
  46. package/dist/resources/field-type-resource.js +49 -54
  47. package/dist/resources/field-type-resource.js.map +1 -1
  48. package/dist/resources/file-resource.d.ts +14 -1
  49. package/dist/resources/file-resource.js +29 -0
  50. package/dist/resources/file-resource.js.map +1 -1
  51. package/dist/resources/link-type-resource.d.ts +5 -1
  52. package/dist/resources/link-type-resource.js +28 -30
  53. package/dist/resources/link-type-resource.js.map +1 -1
  54. package/dist/resources/resource-object.d.ts +1 -0
  55. package/dist/resources/resource-object.js +52 -1
  56. package/dist/resources/resource-object.js.map +1 -1
  57. package/dist/resources/template-resource.js +5 -26
  58. package/dist/resources/template-resource.js.map +1 -1
  59. package/dist/resources/workflow-resource.d.ts +1 -1
  60. package/dist/resources/workflow-resource.js +79 -76
  61. package/dist/resources/workflow-resource.js.map +1 -1
  62. package/dist/utils/configuration-logger.d.ts +91 -0
  63. package/dist/utils/configuration-logger.js +151 -0
  64. package/dist/utils/configuration-logger.js.map +1 -0
  65. package/dist/utils/constants.d.ts +1 -1
  66. package/dist/utils/constants.js +5 -3
  67. package/dist/utils/constants.js.map +1 -1
  68. package/package.json +4 -4
  69. package/src/command-handler.ts +17 -9
  70. package/src/command-manager.ts +4 -4
  71. package/src/commands/create.ts +1 -1
  72. package/src/commands/fetch.ts +143 -34
  73. package/src/commands/import.ts +13 -1
  74. package/src/commands/remove.ts +10 -1
  75. package/src/commands/rename.ts +15 -0
  76. package/src/commands/show.ts +11 -3
  77. package/src/commands/validate.ts +3 -7
  78. package/src/containers/card-container.ts +37 -5
  79. package/src/containers/project/project-paths.ts +8 -0
  80. package/src/containers/project/resource-cache.ts +12 -9
  81. package/src/containers/project.ts +76 -9
  82. package/src/containers/template.ts +4 -4
  83. package/src/interfaces/command-options.ts +3 -1
  84. package/src/interfaces/project-interfaces.ts +5 -5
  85. package/src/project-settings.ts +13 -0
  86. package/src/resources/card-type-resource.ts +91 -109
  87. package/src/resources/field-type-resource.ts +60 -64
  88. package/src/resources/file-resource.ts +43 -1
  89. package/src/resources/link-type-resource.ts +32 -36
  90. package/src/resources/resource-object.ts +73 -1
  91. package/src/resources/template-resource.ts +6 -26
  92. package/src/resources/workflow-resource.ts +102 -93
  93. package/src/utils/configuration-logger.ts +206 -0
  94. package/src/utils/constants.ts +5 -3
@@ -22,7 +22,8 @@ import type {
22
22
  import type { Project } from '../containers/project.js';
23
23
  import type { ResourceBaseMetadata } from '../interfaces/resource-interfaces.js';
24
24
  import type { ResourceName } from '../utils/resource-utils.js';
25
- import type { ShowReturnType } from './resource-object.js';
25
+ import type { Operation, ShowReturnType } from './resource-object.js';
26
+ import type { UpdateKey } from '../interfaces/resource-interfaces.js';
26
27
 
27
28
  /**
28
29
  * Base class for file based resources (card types, field types, link types, workflows, ...)
@@ -59,6 +60,13 @@ export abstract class FileResource<
59
60
  );
60
61
  return cards;
61
62
  }
63
+
64
+ /**
65
+ * For handling name changes.
66
+ * @param previousName The previous name before the change
67
+ */
68
+ protected abstract onNameChange?(previousName: string): Promise<void>;
69
+
62
70
  // Updates resource key to a new prefix
63
71
  protected updatePrefixInResourceName(name: string, prefixes: string[]) {
64
72
  const { identifier, prefix, type } = resourceName(name);
@@ -70,6 +78,40 @@ export abstract class FileResource<
70
78
  : name;
71
79
  }
72
80
 
81
+ /**
82
+ * Updates resource.
83
+ * @param updateKey Key to modify
84
+ * @param op Operation to perform on 'key'
85
+ * @throws if key is unknown.
86
+ */
87
+ public async update<Type, K extends string>(
88
+ updateKey: UpdateKey<K>,
89
+ op: Operation<Type>,
90
+ ) {
91
+ const { key } = updateKey;
92
+
93
+ const nameChange = key === 'name';
94
+ const existingName = this.content.name;
95
+ await super.update(updateKey, op);
96
+ const content = structuredClone(this.content);
97
+
98
+ if (key === 'name') {
99
+ content.name = super.handleScalar(op) as string;
100
+ } else if (key === 'displayName') {
101
+ content.displayName = super.handleScalar(op) as string;
102
+ } else if (key === 'description') {
103
+ content.description = super.handleScalar(op) as string;
104
+ } else {
105
+ throw new Error(`Unknown property '${key}' for folder resource`);
106
+ }
107
+
108
+ await super.postUpdate(content, updateKey, op);
109
+
110
+ if (nameChange) {
111
+ await this.onNameChange?.(existingName);
112
+ }
113
+ }
114
+
73
115
  /**
74
116
  * Returns the resource metadata content.
75
117
  * @returns metadata content
@@ -32,8 +32,11 @@ export class LinkTypeResource extends FileResource<LinkType> {
32
32
  this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
33
33
  }
34
34
 
35
- // When resource name changes.
36
- private async handleNameChange(existingName: string) {
35
+ /**
36
+ * When resource name changes.
37
+ * @param existingName Current resource name.
38
+ */
39
+ protected async onNameChange(existingName: string) {
37
40
  const current = this.content;
38
41
  const prefixes = this.project.projectPrefixes();
39
42
  if (current.sourceCardTypes) {
@@ -76,7 +79,7 @@ export class LinkTypeResource extends FileResource<LinkType> {
76
79
  public async rename(newName: ResourceName) {
77
80
  const existingName = this.content.name;
78
81
  await super.rename(newName);
79
- return this.handleNameChange(existingName);
82
+ return this.onNameChange(existingName);
80
83
  }
81
84
 
82
85
  /**
@@ -89,41 +92,34 @@ export class LinkTypeResource extends FileResource<LinkType> {
89
92
  op: Operation<Type>,
90
93
  ) {
91
94
  const { key } = updateKey;
92
- const nameChange = key === 'name';
93
- const existingName = this.content.name;
94
95
 
95
- await super.update(updateKey, op);
96
-
97
- const content = structuredClone(this.content);
98
- if (key === 'name') {
99
- content.name = super.handleScalar(op) as string;
100
- } else if (key === 'destinationCardTypes') {
101
- content.destinationCardTypes = super.handleArray(
102
- op,
103
- key,
104
- content.destinationCardTypes as Type[],
105
- ) as string[];
106
- } else if (key === 'enableLinkDescription') {
107
- content.enableLinkDescription = super.handleScalar(op) as boolean;
108
- } else if (key === 'inboundDisplayName') {
109
- content.inboundDisplayName = super.handleScalar(op) as string;
110
- } else if (key === 'outboundDisplayName') {
111
- content.outboundDisplayName = super.handleScalar(op) as string;
112
- } else if (key === 'sourceCardTypes') {
113
- content.sourceCardTypes = super.handleArray(
114
- op,
115
- key,
116
- content.sourceCardTypes as Type[],
117
- ) as string[];
96
+ if (key === 'name' || key === 'displayName' || key === 'description') {
97
+ await super.update(updateKey, op);
118
98
  } else {
119
- throw new Error(`Unknown property '${key}' for FieldType`);
120
- }
121
-
122
- await super.postUpdate(content, updateKey, op);
123
-
124
- // Renaming this card type causes that references to its name must be updated.
125
- if (nameChange) {
126
- await this.handleNameChange(existingName);
99
+ const content = structuredClone(this.content);
100
+ if (key === 'destinationCardTypes') {
101
+ content.destinationCardTypes = super.handleArray(
102
+ op,
103
+ key,
104
+ content.destinationCardTypes as Type[],
105
+ ) as string[];
106
+ } else if (key === 'enableLinkDescription') {
107
+ content.enableLinkDescription = super.handleScalar(op) as boolean;
108
+ } else if (key === 'inboundDisplayName') {
109
+ content.inboundDisplayName = super.handleScalar(op) as string;
110
+ } else if (key === 'outboundDisplayName') {
111
+ content.outboundDisplayName = super.handleScalar(op) as string;
112
+ } else if (key === 'sourceCardTypes') {
113
+ content.sourceCardTypes = super.handleArray(
114
+ op,
115
+ key,
116
+ content.sourceCardTypes as Type[],
117
+ ) as string[];
118
+ } else {
119
+ throw new Error(`Unknown property '${key}' for LinkType`);
120
+ }
121
+
122
+ await super.postUpdate(content, updateKey, op);
127
123
  }
128
124
  }
129
125
 
@@ -44,6 +44,11 @@ import type {
44
44
  } from '../interfaces/resource-interfaces.js';
45
45
  import type { Validate } from '../commands/validate.js';
46
46
 
47
+ import {
48
+ ConfigurationLogger,
49
+ ConfigurationOperation,
50
+ } from '../utils/configuration-logger.js';
51
+
47
52
  // Possible operations to perform when doing "update"
48
53
  export type UpdateOperations = 'add' | 'change' | 'rank' | 'remove';
49
54
 
@@ -308,6 +313,9 @@ export abstract class ResourceObject<
308
313
 
309
314
  const resourceString = resourceNameToString(this.resourceName);
310
315
  this.project.resources.add(resourceString, this);
316
+
317
+ // Log resource creation to migration log
318
+ await this.logResourceOperation('create');
311
319
  }
312
320
 
313
321
  /**
@@ -408,6 +416,56 @@ export abstract class ResourceObject<
408
416
  }
409
417
  }
410
418
 
419
+ // Log details
420
+ protected async logResourceOperation<Type>(
421
+ operationType: 'create' | 'delete' | 'update' | 'rename',
422
+ op?: Operation<Type>,
423
+ key?: string,
424
+ ): Promise<void> {
425
+ let configOperation: ConfigurationOperation;
426
+ const target = resourceNameToString(this.resourceName);
427
+ const parameters: Record<string, unknown> = { type: this.type };
428
+
429
+ switch (operationType) {
430
+ case 'create':
431
+ configOperation = ConfigurationOperation.RESOURCE_CREATE;
432
+ break;
433
+ case 'delete':
434
+ configOperation = ConfigurationOperation.RESOURCE_DELETE;
435
+ break;
436
+ case 'update':
437
+ configOperation = ConfigurationOperation.RESOURCE_UPDATE;
438
+ if (op) {
439
+ parameters.operation = op.name;
440
+ }
441
+ if (key) {
442
+ parameters.key = key;
443
+ }
444
+ break;
445
+ case 'rename':
446
+ configOperation = ConfigurationOperation.RESOURCE_RENAME;
447
+ if (op && op.name === 'change') {
448
+ const changeOp = op as ChangeOperation<string>;
449
+ parameters.oldName = changeOp.target;
450
+ parameters.newName = changeOp.to;
451
+ }
452
+ break;
453
+ default:
454
+ throw new Error(`Unknown operation type: ${operationType}`);
455
+ }
456
+
457
+ await ConfigurationLogger.log(
458
+ this.project.basePath,
459
+ configOperation,
460
+ target,
461
+ {
462
+ parameters,
463
+ },
464
+ );
465
+
466
+ this.logger.info(`Configuration: ${configOperation} - ${target}`);
467
+ }
468
+
411
469
  /**
412
470
  * Called after inherited class has finished 'update' operation.
413
471
  * @param content New content for resource
@@ -449,6 +507,9 @@ export abstract class ResourceObject<
449
507
 
450
508
  this.content = content;
451
509
  await this.write();
510
+
511
+ // Log resource update to migration log
512
+ await this.logResourceOperation('update', op, updateKey.key);
452
513
  }
453
514
 
454
515
  /**
@@ -496,9 +557,17 @@ export abstract class ResourceObject<
496
557
 
497
558
  this.fileName = newFilename;
498
559
  this.content.name = resourceNameToString(newName);
560
+ const newNameString = this.content.name;
499
561
  this.resourceName = newName;
500
562
 
501
- this.project.resources.rename(oldName, this.content.name);
563
+ this.project.resources.rename(oldName, newNameString);
564
+
565
+ // Log resource rename to migration log
566
+ await this.logResourceOperation('rename', {
567
+ name: 'change',
568
+ target: oldName,
569
+ to: newNameString,
570
+ } as ChangeOperation<string>);
502
571
  }
503
572
 
504
573
  /**
@@ -712,6 +781,9 @@ export abstract class ResourceObject<
712
781
  await deleteFile(this.fileName);
713
782
  this.project.resources.remove(resourceNameToString(this.resourceName));
714
783
  this.fileName = '';
784
+
785
+ // Log resource deletion to migration log
786
+ await this.logResourceOperation('delete');
715
787
  }
716
788
 
717
789
  /**
@@ -140,35 +140,15 @@ export class TemplateResource extends FolderResource<TemplateMetadata, never> {
140
140
  updateKey: UpdateKey<K>,
141
141
  op: Operation<Type>,
142
142
  ) {
143
- const { key } = updateKey;
144
- const nameChange = key === 'name';
145
- const existingName = this.content.name;
146
-
147
- // Only call super.update for keys that base class supports
148
- if (key === 'name' || key === 'displayName' || key === 'description') {
149
- await super.update(updateKey, op);
150
- }
151
-
152
- const content = structuredClone(this.content);
153
-
154
- if (key === 'name') {
155
- content.name = super.handleScalar(op) as string;
156
- } else if (key === 'displayName') {
157
- content.displayName = super.handleScalar(op) as string;
158
- } else if (key === 'description') {
159
- content.description = super.handleScalar(op) as string;
160
- } else if (key === 'category') {
143
+ if (updateKey.key === 'category') {
144
+ const content = structuredClone(this.content);
161
145
  content.category = super.handleScalar(op) as string;
162
- } else {
163
- throw new Error(`Unknown property '${key}' for Template`);
164
- }
165
146
 
166
- await super.postUpdate(content, updateKey, op);
167
-
168
- // Renaming this template causes that references to its name must be updated.
169
- if (nameChange) {
170
- await this.onNameChange(existingName);
147
+ await super.postUpdate(content, updateKey, op);
148
+ return;
171
149
  }
150
+
151
+ await super.update(updateKey, op);
172
152
  }
173
153
 
174
154
  /**
@@ -56,10 +56,11 @@ export class WorkflowResource extends FileResource<Workflow> {
56
56
  }
57
57
 
58
58
  // When resource name changes.
59
- private async handleNameChange(existingName: string) {
59
+ protected async onNameChange(existingName: string) {
60
60
  await Promise.all([
61
61
  super.updateHandleBars(existingName, this.content.name),
62
62
  super.updateCalculations(existingName, this.content.name),
63
+ this.updateCardTypes(existingName),
63
64
  ]);
64
65
  // Finally, write updated content.
65
66
  await this.write();
@@ -193,12 +194,15 @@ export class WorkflowResource extends FileResource<Workflow> {
193
194
  to: this.content.name,
194
195
  } as ChangeOperation<string>;
195
196
  for (const cardType of cardTypes) {
196
- await cardType.update(
197
- {
198
- key: 'workflow',
199
- },
200
- op,
201
- );
197
+ // Only update card types that use this workflow
198
+ if (cardType.data?.workflow === oldName) {
199
+ await cardType.update(
200
+ {
201
+ key: 'workflow',
202
+ },
203
+ op,
204
+ );
205
+ }
202
206
  }
203
207
  }
204
208
 
@@ -225,7 +229,7 @@ export class WorkflowResource extends FileResource<Workflow> {
225
229
  public async rename(newName: ResourceName) {
226
230
  const existingName = this.content.name;
227
231
  await super.rename(newName);
228
- return this.handleNameChange(existingName);
232
+ return this.onNameChange(existingName);
229
233
  }
230
234
 
231
235
  /**
@@ -239,101 +243,106 @@ export class WorkflowResource extends FileResource<Workflow> {
239
243
  op: Operation<Type>,
240
244
  ) {
241
245
  const { key } = updateKey;
242
- const nameChange = key === 'name';
243
- const existingName = this.content.name;
244
246
 
245
- await super.update(updateKey, op);
246
-
247
- const content = structuredClone(this.content) as Workflow;
248
-
249
- if (key === 'name') {
250
- content.name = super.handleScalar(op) as string;
251
- } else if (key === 'displayName') {
252
- content.displayName = super.handleScalar(op) as string;
253
- } else if (key === 'description') {
254
- content.description = super.handleScalar(op) as string;
255
- } else if (key === 'states') {
256
- content.states = super.handleArray(
257
- op,
258
- key,
259
- content.states as Type[],
260
- ) as WorkflowState[];
261
- } else if (key === 'transitions') {
262
- content.transitions = super.handleArray(
263
- op,
264
- key,
265
- content.transitions as WorkflowTransition[] as Type[],
266
- ) as WorkflowTransition[];
247
+ if (key === 'name' || key === 'displayName' || key === 'description') {
248
+ await super.update(updateKey, op);
267
249
  } else {
268
- throw new Error(`Unknown property '${key}' for Workflow`);
269
- }
270
-
271
- // If workflow transition is removed, then above call to 'handleArray' is all that is needed.
272
-
273
- if (key === 'transitions' && op.name === 'change') {
274
- // If workflow transition is changed, update to full object and change the content.
275
- let changeOp: ChangeOperation<WorkflowTransition>;
276
- if (this.isStringOperation(op)) {
277
- const targetTransition = (this.content as Workflow).transitions.find(
278
- (transition) => transition.name === op.target,
279
- )!;
280
- changeOp = {
281
- name: 'change',
282
- target: targetTransition as WorkflowTransition,
283
- to: {
284
- name: op.to,
285
- toState: targetTransition.toState,
286
- fromState: targetTransition.fromState,
287
- },
288
- };
289
- } else {
290
- changeOp = op as ChangeOperation<WorkflowTransition>;
250
+ const content = structuredClone(this.content) as Workflow;
251
+
252
+ // Validate state change operations before processing
253
+ if (key === 'states' && op.name === 'change') {
254
+ const changeOp = op as ChangeOperation<WorkflowState>;
255
+ if (
256
+ changeOp.to.name === undefined ||
257
+ changeOp.to.category === undefined
258
+ ) {
259
+ const stateName =
260
+ changeOp.target['name' as keyof typeof changeOp.target] ||
261
+ changeOp.target;
262
+ throw new Error(
263
+ `Cannot change state '${stateName}' for workflow '${this.content.name}'.
264
+ Updated state must have 'name' and 'category' properties.`,
265
+ );
266
+ }
291
267
  }
292
- const newTransition = await this.transitionObject(changeOp);
293
- content.transitions = content.transitions.map((item) =>
294
- item.name == newTransition.name ? newTransition : item,
295
- );
296
- }
297
268
 
298
- if (key === 'states' && op.name === 'remove') {
299
- // If workflow state is removed, remove all transitions "to" and "from" this state.
300
- let removeOp: RemoveOperation<WorkflowState>;
301
- if (this.isStringOperation(op)) {
302
- const toBeRemovedState = this.content.states.find(
303
- (state) => state.name === op.target,
304
- );
305
- removeOp = {
306
- name: 'remove',
307
- target: toBeRemovedState as WorkflowState,
308
- };
269
+ if (key === 'states') {
270
+ content.states = super.handleArray(
271
+ op,
272
+ key,
273
+ content.states as Type[],
274
+ ) as WorkflowState[];
275
+ } else if (key === 'transitions') {
276
+ content.transitions = super.handleArray(
277
+ op,
278
+ key,
279
+ content.transitions as WorkflowTransition[] as Type[],
280
+ ) as WorkflowTransition[];
309
281
  } else {
310
- removeOp = op as RemoveOperation<WorkflowState>;
282
+ throw new Error(`Unknown property '${key}' for Workflow`);
311
283
  }
312
- await this.handleStateRemoval(removeOp);
313
- } else if (key === 'states' && op.name === 'change') {
314
- // If workflow state is renamed, replace all transitions "to" and "from" the old state with new state.
315
- let changeOp: ChangeOperation<WorkflowState>;
316
- if (this.isStringOperation(op)) {
317
- const toBeChangedState = this.content.states.find(
318
- (state) => state.name === op.target,
284
+
285
+ // If workflow transition is removed, then above call to 'handleArray' is all that is needed.
286
+
287
+ if (key === 'transitions' && op.name === 'change') {
288
+ // If workflow transition is changed, update to full object and change the content.
289
+ let changeOp: ChangeOperation<WorkflowTransition>;
290
+ if (this.isStringOperation(op)) {
291
+ const targetTransition = (this.content as Workflow).transitions.find(
292
+ (transition) => transition.name === op.target,
293
+ )!;
294
+ changeOp = {
295
+ name: 'change',
296
+ target: targetTransition as WorkflowTransition,
297
+ to: {
298
+ name: op.to,
299
+ toState: targetTransition.toState,
300
+ fromState: targetTransition.fromState,
301
+ },
302
+ };
303
+ } else {
304
+ changeOp = op as ChangeOperation<WorkflowTransition>;
305
+ }
306
+ const newTransition = await this.transitionObject(changeOp);
307
+ content.transitions = content.transitions.map((item) =>
308
+ item.name == newTransition.name ? newTransition : item,
319
309
  );
320
- changeOp = {
321
- name: 'change',
322
- target: toBeChangedState as WorkflowState,
323
- to: { name: op.to },
324
- };
325
- } else {
326
- changeOp = op as ChangeOperation<WorkflowState>;
327
310
  }
328
- await this.handleStateChange(changeOp);
329
- }
330
311
 
331
- await super.postUpdate(content, updateKey, op);
312
+ if (key === 'states' && op.name === 'remove') {
313
+ // If workflow state is removed, remove all transitions "to" and "from" this state.
314
+ let removeOp: RemoveOperation<WorkflowState>;
315
+ if (this.isStringOperation(op)) {
316
+ const toBeRemovedState = this.content.states.find(
317
+ (state) => state.name === op.target,
318
+ );
319
+ removeOp = {
320
+ name: 'remove',
321
+ target: toBeRemovedState as WorkflowState,
322
+ };
323
+ } else {
324
+ removeOp = op as RemoveOperation<WorkflowState>;
325
+ }
326
+ await this.handleStateRemoval(removeOp);
327
+ } else if (key === 'states' && op.name === 'change') {
328
+ // If workflow state is renamed, replace all transitions "to" and "from" the old state with new state.
329
+ let changeOp: ChangeOperation<WorkflowState>;
330
+ if (this.isStringOperation(op)) {
331
+ const toBeChangedState = this.content.states.find(
332
+ (state) => state.name === op.target,
333
+ );
334
+ changeOp = {
335
+ name: 'change',
336
+ target: toBeChangedState as WorkflowState,
337
+ to: { name: op.to },
338
+ };
339
+ } else {
340
+ changeOp = op as ChangeOperation<WorkflowState>;
341
+ }
342
+ await this.handleStateChange(changeOp);
343
+ }
332
344
 
333
- // Renaming this workflow causes that references to its name must be updated.
334
- if (nameChange) {
335
- await this.handleNameChange(existingName);
336
- await this.updateCardTypes(existingName);
345
+ await super.postUpdate(content, updateKey, op);
337
346
  }
338
347
  }
339
348