@cyberismo/data-handler 0.0.17 → 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.
@@ -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