@cyberismo/data-handler 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/card-metadata-updater.js +1 -3
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.js +10 -16
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +1 -1
- package/dist/command-manager.js +4 -3
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/create.js +13 -59
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/edit.d.ts +1 -15
- package/dist/commands/edit.js +15 -89
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/export.js +4 -17
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.js +3 -5
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/move.d.ts +1 -2
- package/dist/commands/move.js +108 -146
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/remove.js +9 -44
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.js +2 -7
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +7 -25
- package/dist/commands/show.js +38 -102
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/transition.js +27 -30
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.d.ts +5 -3
- package/dist/commands/update.js +19 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.d.ts +3 -3
- package/dist/commands/validate.js +19 -26
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/card-container.d.ts +87 -24
- package/dist/containers/card-container.js +183 -279
- package/dist/containers/card-container.js.map +1 -1
- package/dist/containers/project/calculation-engine.d.ts +6 -0
- package/dist/containers/project/calculation-engine.js +19 -12
- package/dist/containers/project/calculation-engine.js.map +1 -1
- package/dist/containers/project/card-cache.d.ts +146 -0
- package/dist/containers/project/card-cache.js +411 -0
- package/dist/containers/project/card-cache.js.map +1 -0
- package/dist/containers/project/resource-collector.d.ts +24 -1
- package/dist/containers/project/resource-collector.js +8 -1
- package/dist/containers/project/resource-collector.js.map +1 -1
- package/dist/containers/project.d.ts +117 -83
- package/dist/containers/project.js +418 -252
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +15 -31
- package/dist/containers/template.js +97 -104
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/folder-content-interfaces.d.ts +2 -1
- package/dist/interfaces/folder-content-interfaces.js.map +1 -1
- package/dist/interfaces/macros.d.ts +1 -0
- package/dist/interfaces/macros.js +1 -1
- package/dist/interfaces/macros.js.map +1 -1
- package/dist/interfaces/project-interfaces.d.ts +5 -1
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +11 -21
- package/dist/interfaces/resource-interfaces.js +3 -0
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/common.d.ts +10 -10
- package/dist/macros/createCards/index.d.ts +0 -13
- package/dist/macros/createCards/index.js.map +1 -1
- package/dist/macros/createCards/types.d.ts +44 -0
- package/dist/macros/createCards/types.js +15 -0
- package/dist/macros/createCards/types.js.map +1 -0
- package/dist/macros/graph/index.d.ts +2 -6
- package/dist/macros/graph/index.js +2 -2
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/graph/types.d.ts +23 -0
- package/dist/macros/graph/types.js +15 -0
- package/dist/macros/graph/types.js.map +1 -0
- package/dist/macros/image/index.d.ts +8 -16
- package/dist/macros/image/index.js +36 -33
- package/dist/macros/image/index.js.map +1 -1
- package/dist/macros/image/types.d.ts +38 -0
- package/dist/macros/image/types.js +15 -0
- package/dist/macros/image/types.js.map +1 -0
- package/dist/macros/include/index.d.ts +1 -6
- package/dist/macros/include/index.js +4 -7
- package/dist/macros/include/index.js.map +1 -1
- package/dist/macros/include/types.d.ts +31 -0
- package/dist/macros/include/types.js +15 -0
- package/dist/macros/include/types.js.map +1 -0
- package/dist/macros/percentage/index.d.ts +0 -6
- package/dist/macros/percentage/index.js.map +1 -1
- package/dist/macros/percentage/types.d.ts +31 -0
- package/dist/macros/percentage/types.js +15 -0
- package/dist/macros/percentage/types.js.map +1 -0
- package/dist/macros/report/index.d.ts +0 -3
- package/dist/macros/report/index.js.map +1 -1
- package/dist/macros/report/types.d.ts +19 -0
- package/dist/macros/report/types.js +15 -0
- package/dist/macros/report/types.js.map +1 -0
- package/dist/macros/scoreCard/index.d.ts +0 -6
- package/dist/macros/scoreCard/index.js.map +1 -1
- package/dist/macros/scoreCard/types.d.ts +31 -0
- package/dist/macros/scoreCard/types.js +15 -0
- package/dist/macros/scoreCard/types.js.map +1 -0
- package/dist/macros/types.d.ts +25 -0
- package/dist/macros/types.js +2 -0
- package/dist/macros/types.js.map +1 -0
- package/dist/macros/vega/index.d.ts +0 -4
- package/dist/macros/vega/index.js.map +1 -1
- package/dist/macros/vega/types.d.ts +20 -0
- package/dist/macros/vega/types.js +2 -0
- package/dist/macros/vega/types.js.map +1 -0
- package/dist/macros/vegalite/index.d.ts +0 -4
- package/dist/macros/vegalite/index.js.map +1 -1
- package/dist/macros/vegalite/types.d.ts +20 -0
- package/dist/macros/vegalite/types.js +15 -0
- package/dist/macros/vegalite/types.js.map +1 -0
- package/dist/macros/xref/index.d.ts +0 -3
- package/dist/macros/xref/index.js +5 -14
- package/dist/macros/xref/index.js.map +1 -1
- package/dist/macros/xref/types.d.ts +19 -0
- package/dist/macros/xref/types.js +15 -0
- package/dist/macros/xref/types.js.map +1 -0
- package/dist/module-manager.js +4 -4
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/calculation-resource.d.ts +4 -32
- package/dist/resources/calculation-resource.js +0 -55
- package/dist/resources/calculation-resource.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +4 -21
- package/dist/resources/card-type-resource.js +13 -44
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +4 -21
- package/dist/resources/field-type-resource.js +14 -38
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +12 -29
- package/dist/resources/file-resource.js +19 -293
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +31 -50
- package/dist/resources/folder-resource.js +68 -96
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.d.ts +5 -33
- package/dist/resources/graph-model-resource.js +8 -61
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.d.ts +5 -28
- package/dist/resources/graph-view-resource.js +6 -45
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/link-type-resource.d.ts +4 -21
- package/dist/resources/link-type-resource.js +6 -31
- package/dist/resources/link-type-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +5 -17
- package/dist/resources/report-resource.js +6 -44
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +58 -23
- package/dist/resources/resource-object.js +293 -24
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.d.ts +4 -15
- package/dist/resources/template-resource.js +10 -25
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +4 -23
- package/dist/resources/workflow-resource.js +12 -38
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/utils/card-utils.d.ts +69 -19
- package/dist/utils/card-utils.js +179 -30
- package/dist/utils/card-utils.js.map +1 -1
- package/dist/utils/clingo-facts.js +11 -3
- package/dist/utils/clingo-facts.js.map +1 -1
- package/dist/utils/clingo-parser.js +1 -1
- package/dist/utils/clingo-parser.js.map +1 -1
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +4 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/csv.js +1 -1
- package/dist/utils/csv.js.map +1 -1
- package/package.json +5 -5
- package/src/card-metadata-updater.ts +3 -5
- package/src/command-handler.ts +11 -18
- package/src/command-manager.ts +4 -3
- package/src/commands/create.ts +17 -83
- package/src/commands/edit.ts +16 -132
- package/src/commands/export.ts +8 -29
- package/src/commands/import.ts +4 -6
- package/src/commands/move.ts +144 -179
- package/src/commands/remove.ts +9 -52
- package/src/commands/rename.ts +2 -7
- package/src/commands/show.ts +50 -143
- package/src/commands/transition.ts +30 -33
- package/src/commands/update.ts +27 -9
- package/src/commands/validate.ts +21 -36
- package/src/containers/card-container.ts +200 -360
- package/src/containers/project/calculation-engine.ts +21 -13
- package/src/containers/project/card-cache.ts +497 -0
- package/src/containers/project/resource-collector.ts +9 -1
- package/src/containers/project.ts +529 -327
- package/src/containers/template.ts +109 -127
- package/src/index.ts +1 -0
- package/src/interfaces/folder-content-interfaces.ts +7 -1
- package/src/interfaces/macros.ts +2 -0
- package/src/interfaces/project-interfaces.ts +7 -1
- package/src/interfaces/resource-interfaces.ts +12 -24
- package/src/macros/createCards/index.ts +1 -12
- package/src/macros/createCards/types.ts +46 -0
- package/src/macros/graph/index.ts +3 -7
- package/src/macros/graph/types.ts +24 -0
- package/src/macros/image/index.ts +50 -61
- package/src/macros/image/types.ts +39 -0
- package/src/macros/include/index.ts +6 -15
- package/src/macros/include/types.ts +32 -0
- package/src/macros/percentage/index.ts +1 -7
- package/src/macros/percentage/types.ts +32 -0
- package/src/macros/report/index.ts +1 -4
- package/src/macros/report/types.ts +20 -0
- package/src/macros/scoreCard/index.ts +1 -7
- package/src/macros/scoreCard/types.ts +32 -0
- package/src/macros/types.ts +48 -0
- package/src/macros/vega/index.ts +1 -4
- package/src/macros/vega/types.ts +21 -0
- package/src/macros/vegalite/index.ts +1 -4
- package/src/macros/vegalite/types.ts +22 -0
- package/src/macros/xref/index.ts +6 -20
- package/src/macros/xref/types.ts +20 -0
- package/src/module-manager.ts +5 -5
- package/src/project-settings.ts +1 -1
- package/src/resources/calculation-resource.ts +6 -76
- package/src/resources/card-type-resource.ts +24 -59
- package/src/resources/field-type-resource.ts +22 -51
- package/src/resources/file-resource.ts +27 -409
- package/src/resources/folder-resource.ts +98 -124
- package/src/resources/graph-model-resource.ts +17 -74
- package/src/resources/graph-view-resource.ts +14 -54
- package/src/resources/link-type-resource.ts +13 -40
- package/src/resources/report-resource.ts +17 -57
- package/src/resources/resource-object.ts +435 -32
- package/src/resources/template-resource.ts +16 -29
- package/src/resources/workflow-resource.ts +26 -50
- package/src/utils/card-utils.ts +217 -31
- package/src/utils/clingo-facts.ts +13 -3
- package/src/utils/clingo-parser.ts +1 -1
- package/src/utils/constants.ts +6 -0
- package/src/utils/csv.ts +1 -1
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type {
|
|
16
16
|
CardType,
|
|
17
|
+
UpdateKey,
|
|
17
18
|
Workflow,
|
|
18
19
|
WorkflowState,
|
|
19
20
|
WorkflowTransition,
|
|
@@ -39,14 +40,12 @@ import { resourceName } from './file-resource.js';
|
|
|
39
40
|
/**
|
|
40
41
|
* Workflow resource class.
|
|
41
42
|
*/
|
|
42
|
-
export class WorkflowResource extends FileResource {
|
|
43
|
+
export class WorkflowResource extends FileResource<Workflow> {
|
|
43
44
|
constructor(project: Project, name: ResourceName) {
|
|
44
45
|
super(project, name, 'workflows');
|
|
45
46
|
|
|
46
47
|
this.contentSchemaId = 'workflowSchema';
|
|
47
48
|
this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
|
|
48
|
-
|
|
49
|
-
this.initialize();
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
// Collect all cards that use this workflow.
|
|
@@ -60,11 +59,10 @@ export class WorkflowResource extends FileResource {
|
|
|
60
59
|
);
|
|
61
60
|
if (
|
|
62
61
|
object.data &&
|
|
63
|
-
|
|
64
|
-
resourceNameToString(this.resourceName)
|
|
62
|
+
object.data.workflow === resourceNameToString(this.resourceName)
|
|
65
63
|
) {
|
|
66
64
|
// fetch all cards with card type
|
|
67
|
-
promises.push(this.collectCards(
|
|
65
|
+
promises.push(this.collectCards(cardType.name));
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
return (await Promise.all(promises)).flat();
|
|
@@ -82,7 +80,7 @@ export class WorkflowResource extends FileResource {
|
|
|
82
80
|
|
|
83
81
|
// Handle change of workflow state.
|
|
84
82
|
private async handleStateChange(op: ChangeOperation<WorkflowState>) {
|
|
85
|
-
const content = structuredClone(this.content)
|
|
83
|
+
const content = structuredClone(this.content);
|
|
86
84
|
const stateName = this.targetName(op) as string;
|
|
87
85
|
// Check that state can be changed to
|
|
88
86
|
content.transitions = content.transitions.filter(
|
|
@@ -107,7 +105,7 @@ export class WorkflowResource extends FileResource {
|
|
|
107
105
|
// Handle removal of workflow state.
|
|
108
106
|
// State can be removed with or without replacement.
|
|
109
107
|
private async handleStateRemoval(op: RemoveOperation<WorkflowState>) {
|
|
110
|
-
const content = structuredClone(this.content)
|
|
108
|
+
const content = structuredClone(this.content);
|
|
111
109
|
const stateName = this.targetName(op) as string;
|
|
112
110
|
|
|
113
111
|
// If there is no replacement value, remove all transitions "to" and "from" this state.
|
|
@@ -153,8 +151,8 @@ export class WorkflowResource extends FileResource {
|
|
|
153
151
|
}
|
|
154
152
|
|
|
155
153
|
// Potentially updates the changed transition with current properties.
|
|
156
|
-
private
|
|
157
|
-
const content = structuredClone(this.content)
|
|
154
|
+
private transitionObject(op: ChangeOperation<WorkflowTransition>) {
|
|
155
|
+
const content = structuredClone(this.content);
|
|
158
156
|
const targetTransitionName = this.targetName(op);
|
|
159
157
|
const currentTransition = content.transitions.filter(
|
|
160
158
|
(item) => item.name === targetTransitionName,
|
|
@@ -212,8 +210,13 @@ export class WorkflowResource extends FileResource {
|
|
|
212
210
|
this.project,
|
|
213
211
|
resourceName(cardType.name),
|
|
214
212
|
);
|
|
215
|
-
if (object.data &&
|
|
216
|
-
await object.update(
|
|
213
|
+
if (object.data && object.data.workflow === oldName) {
|
|
214
|
+
await object.update(
|
|
215
|
+
{
|
|
216
|
+
key: 'workflow',
|
|
217
|
+
},
|
|
218
|
+
op,
|
|
219
|
+
);
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
}
|
|
@@ -234,21 +237,6 @@ export class WorkflowResource extends FileResource {
|
|
|
234
237
|
return super.create(newContent);
|
|
235
238
|
}
|
|
236
239
|
|
|
237
|
-
/**
|
|
238
|
-
* Returns content data.
|
|
239
|
-
*/
|
|
240
|
-
public get data(): Workflow {
|
|
241
|
-
return super.data as Workflow;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Deletes file that this object is based on.
|
|
246
|
-
* If there are card types that depended on this workflow, they are now invalid.
|
|
247
|
-
*/
|
|
248
|
-
public async delete() {
|
|
249
|
-
return super.delete();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
240
|
/**
|
|
253
241
|
* Renames the object and the file.
|
|
254
242
|
* @param newName New name for the resource.
|
|
@@ -259,25 +247,21 @@ export class WorkflowResource extends FileResource {
|
|
|
259
247
|
return this.handleNameChange(existingName);
|
|
260
248
|
}
|
|
261
249
|
|
|
262
|
-
/**
|
|
263
|
-
* Shows metadata of the resource.
|
|
264
|
-
* @returns workflow metadata.
|
|
265
|
-
*/
|
|
266
|
-
public async show(): Promise<Workflow> {
|
|
267
|
-
return super.show() as Promise<Workflow>;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
250
|
/**
|
|
271
251
|
* Updates workflow resource.
|
|
272
|
-
* @param
|
|
252
|
+
* @param updateKey Key to modify
|
|
273
253
|
* @param op Operation to perform on 'key'
|
|
274
254
|
* @throws if key is unknown.
|
|
275
255
|
*/
|
|
276
|
-
public async update<Type
|
|
256
|
+
public async update<Type, K extends string>(
|
|
257
|
+
updateKey: UpdateKey<K>,
|
|
258
|
+
op: Operation<Type>,
|
|
259
|
+
) {
|
|
260
|
+
const { key } = updateKey;
|
|
277
261
|
const nameChange = key === 'name';
|
|
278
262
|
const existingName = this.content.name;
|
|
279
263
|
|
|
280
|
-
await super.update(
|
|
264
|
+
await super.update(updateKey, op);
|
|
281
265
|
|
|
282
266
|
const content = structuredClone(this.content) as Workflow;
|
|
283
267
|
|
|
@@ -334,7 +318,7 @@ export class WorkflowResource extends FileResource {
|
|
|
334
318
|
// If workflow state is removed, remove all transitions "to" and "from" this state.
|
|
335
319
|
let removeOp: RemoveOperation<WorkflowState>;
|
|
336
320
|
if (this.isStringOperation(op)) {
|
|
337
|
-
const toBeRemovedState =
|
|
321
|
+
const toBeRemovedState = this.content.states.find(
|
|
338
322
|
(state) => state.name === op.target,
|
|
339
323
|
);
|
|
340
324
|
removeOp = {
|
|
@@ -349,7 +333,7 @@ export class WorkflowResource extends FileResource {
|
|
|
349
333
|
// If workflow state is renamed, replace all transitions "to" and "from" the old state with new state.
|
|
350
334
|
let changeOp: ChangeOperation<WorkflowState>;
|
|
351
335
|
if (this.isStringOperation(op)) {
|
|
352
|
-
const toBeChangedState =
|
|
336
|
+
const toBeChangedState = this.content.states.find(
|
|
353
337
|
(state) => state.name === op.target,
|
|
354
338
|
);
|
|
355
339
|
changeOp = {
|
|
@@ -363,7 +347,7 @@ export class WorkflowResource extends FileResource {
|
|
|
363
347
|
await this.handleStateChange(changeOp);
|
|
364
348
|
}
|
|
365
349
|
|
|
366
|
-
await super.postUpdate(content,
|
|
350
|
+
await super.postUpdate(content, updateKey, op);
|
|
367
351
|
|
|
368
352
|
// Renaming this workflow causes that references to its name must be updated.
|
|
369
353
|
if (nameChange) {
|
|
@@ -381,7 +365,7 @@ export class WorkflowResource extends FileResource {
|
|
|
381
365
|
*/
|
|
382
366
|
public async usage(cards?: Card[]): Promise<string[]> {
|
|
383
367
|
const resourceName = resourceNameToString(this.resourceName);
|
|
384
|
-
const allCards = cards ??
|
|
368
|
+
const allCards = cards ?? super.cards();
|
|
385
369
|
const cardTypes = await this.project.cardTypes(ResourcesFrom.all);
|
|
386
370
|
const cardTypeReferences = await Promise.all(
|
|
387
371
|
cardTypes.map(async (cardType) => {
|
|
@@ -401,12 +385,4 @@ export class WorkflowResource extends FileResource {
|
|
|
401
385
|
...calculations,
|
|
402
386
|
];
|
|
403
387
|
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Validates workflow.
|
|
407
|
-
* @throws when there are validation errors.
|
|
408
|
-
*/
|
|
409
|
-
public validate(content?: object): Promise<void> {
|
|
410
|
-
return super.validate(content);
|
|
411
|
-
}
|
|
412
388
|
}
|
package/src/utils/card-utils.ts
CHANGED
|
@@ -1,25 +1,161 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
4
13
|
|
|
5
|
-
|
|
14
|
+
import { sep } from 'node:path';
|
|
15
|
+
import { CARD_KEY_SEPARATOR, ROOT } from './constants.js';
|
|
6
16
|
|
|
7
|
-
|
|
17
|
+
import type {
|
|
18
|
+
Card,
|
|
19
|
+
CardWithChildrenCards,
|
|
20
|
+
} from '../interfaces/project-interfaces.js';
|
|
21
|
+
import type { Project } from '../resources/folder-resource.js';
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Builds card hierarchy from flat card list with nested card objects.
|
|
25
|
+
* This converts the cards hierarchy (where children are string[]) to
|
|
26
|
+
* CardWithChildrenCards[] (where children are Card[]).
|
|
27
|
+
* @param flatCards Cards in a flat array.
|
|
28
|
+
* @returns Cards in hierarchical array with nested card objects
|
|
29
|
+
*/
|
|
30
|
+
export const buildCardHierarchy = (
|
|
31
|
+
flatCards: Card[],
|
|
32
|
+
): CardWithChildrenCards[] => {
|
|
33
|
+
const cardMap = new Map(flatCards.map((card) => [card.key, card]));
|
|
12
34
|
|
|
13
|
-
|
|
35
|
+
// Helper to get cards as a map
|
|
36
|
+
function cards(flatCards: Card[]) {
|
|
37
|
+
const cardMap = new Map(
|
|
38
|
+
flatCards.map((card) => [
|
|
39
|
+
card.key,
|
|
40
|
+
{ ...card, children: [] as string[] },
|
|
41
|
+
]),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const rootCards: Card[] = [];
|
|
45
|
+
cardMap.forEach((card) => {
|
|
46
|
+
if (card.parent && cardMap.has(card.parent)) {
|
|
47
|
+
const parentCard = cardMap.get(card.parent);
|
|
48
|
+
if (parentCard) {
|
|
49
|
+
parentCard.children.push(card.key);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
rootCards.push(card);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return rootCards;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Helper to convert from string[] => Card[] children
|
|
60
|
+
function convert(card: Card): CardWithChildrenCards {
|
|
61
|
+
const childrenCards = card.children.map((childKey) => {
|
|
62
|
+
const childCard = cardMap.get(childKey)!;
|
|
63
|
+
return convert(childCard);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
...card,
|
|
68
|
+
childrenCards,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const rootCards = cards(flatCards);
|
|
73
|
+
return rootCards.map(convert);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Breaks card path to logical parts: cardKey, list of parents, prefix and template
|
|
78
|
+
* If this is a root card, then parents is undefined.
|
|
79
|
+
* If this is not a template card, then template is undefined.
|
|
80
|
+
* @param prefix Project prefix.
|
|
81
|
+
* @param cardPath Card path to break into parts.
|
|
82
|
+
* @returns Card parts
|
|
83
|
+
* @todo: This could also return module name, if card is from a module
|
|
84
|
+
*/
|
|
85
|
+
export const cardPathParts = (
|
|
86
|
+
prefix: string,
|
|
87
|
+
cardPath: string,
|
|
88
|
+
): {
|
|
89
|
+
cardKey: string | undefined;
|
|
90
|
+
parents: (string | undefined)[];
|
|
91
|
+
prefix: string;
|
|
92
|
+
template: string;
|
|
93
|
+
} => {
|
|
94
|
+
const pathParts = cardPath.split(sep);
|
|
95
|
+
const cardKey = pathParts.at(pathParts.length - 1);
|
|
96
|
+
const parents = [];
|
|
97
|
+
let template = '';
|
|
98
|
+
let startIndex = -1;
|
|
99
|
+
let templatesNameIndex = -1;
|
|
100
|
+
|
|
101
|
+
const cardRootIndex = pathParts.indexOf('cardRoot');
|
|
102
|
+
const projectInternalsIndex = pathParts.indexOf('.cards');
|
|
14
103
|
|
|
15
|
-
|
|
104
|
+
if (projectInternalsIndex === -1 && cardRootIndex >= 0) {
|
|
105
|
+
startIndex = projectInternalsIndex;
|
|
106
|
+
} else if (projectInternalsIndex >= 0 && cardRootIndex === -1) {
|
|
107
|
+
const templatesIndex = pathParts.indexOf('templates');
|
|
108
|
+
startIndex = templatesIndex;
|
|
109
|
+
if (templatesIndex === -1) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Invalid card path. Template card must have 'templates' in path`,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const modulesIndex = pathParts.indexOf('modules');
|
|
115
|
+
if (modulesIndex !== -1) {
|
|
116
|
+
prefix = pathParts.at(modulesIndex + 1) || '';
|
|
117
|
+
}
|
|
118
|
+
templatesNameIndex = templatesIndex + 1;
|
|
119
|
+
template = `${prefix}/templates/${pathParts.at(templatesNameIndex)}`;
|
|
120
|
+
} else {
|
|
121
|
+
throw new Error(`Card must be either project card, or template card`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Look for parents in the path.
|
|
125
|
+
let previousWasParent = false;
|
|
126
|
+
for (let index = startIndex; index <= pathParts.length; index++) {
|
|
127
|
+
if (previousWasParent) {
|
|
128
|
+
previousWasParent = false;
|
|
129
|
+
parents.push(pathParts.at(index - 2));
|
|
130
|
+
}
|
|
131
|
+
const cardsSubFolder = pathParts.at(index) === 'c';
|
|
132
|
+
const ignoreOrNotTemplatesParent =
|
|
133
|
+
index - 1 !== templatesNameIndex || templatesNameIndex === -1;
|
|
134
|
+
if (cardsSubFolder && ignoreOrNotTemplatesParent) {
|
|
135
|
+
previousWasParent = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
16
138
|
|
|
17
|
-
|
|
139
|
+
return {
|
|
140
|
+
cardKey: cardKey,
|
|
141
|
+
parents: parents,
|
|
142
|
+
prefix: prefix,
|
|
143
|
+
template: template,
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Find parent path from a card path
|
|
149
|
+
* @param cardPath Card path to find parent path from.
|
|
150
|
+
* @returns Parent path
|
|
151
|
+
*/
|
|
18
152
|
export const findParentPath = (cardPath: string): string | null => {
|
|
19
153
|
const pathParts = cardPath.split(sep);
|
|
20
154
|
const hasChildren = pathParts.lastIndexOf('c');
|
|
21
155
|
|
|
22
|
-
if (hasChildren <= 0)
|
|
156
|
+
if (hasChildren <= 0) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
23
159
|
|
|
24
160
|
const parentPathParts = [...pathParts];
|
|
25
161
|
parentPathParts.splice(hasChildren, 1);
|
|
@@ -28,21 +164,53 @@ export const findParentPath = (cardPath: string): string | null => {
|
|
|
28
164
|
|
|
29
165
|
/**
|
|
30
166
|
* Flattens card tree so that children are shown on same level regardless of nesting level.
|
|
31
|
-
* @param array
|
|
32
|
-
* @
|
|
167
|
+
* @param array Card tree to flatten
|
|
168
|
+
* @parent project Project to use
|
|
169
|
+
* @returns Flattened card tree.
|
|
33
170
|
*/
|
|
34
|
-
export const flattenCardArray = (array: Card[]) => {
|
|
171
|
+
export const flattenCardArray = (array: Card[], project: Project) => {
|
|
35
172
|
const result: Card[] = [];
|
|
173
|
+
|
|
36
174
|
array.forEach((item) => {
|
|
37
175
|
const { key, path, children, attachments, metadata } = item;
|
|
38
|
-
|
|
176
|
+
const childCardIds = project
|
|
177
|
+
.cardKeysToCards(children)
|
|
178
|
+
.map((item) => item.key);
|
|
179
|
+
|
|
180
|
+
result.push({
|
|
181
|
+
key,
|
|
182
|
+
path,
|
|
183
|
+
children: [...childCardIds],
|
|
184
|
+
attachments,
|
|
185
|
+
metadata,
|
|
186
|
+
});
|
|
39
187
|
if (children) {
|
|
40
|
-
result.push(
|
|
188
|
+
result.push(
|
|
189
|
+
...flattenCardArray(project.cardKeysToCards(children), project),
|
|
190
|
+
);
|
|
41
191
|
}
|
|
42
192
|
});
|
|
43
193
|
return result;
|
|
44
194
|
};
|
|
45
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Checks if given card is in some module.
|
|
198
|
+
* @param card Card object to check
|
|
199
|
+
* @returns true if card exists in a module; false otherwise
|
|
200
|
+
*/
|
|
201
|
+
export const isModuleCard = (card: Card) => {
|
|
202
|
+
return card.path.includes(`${sep}modules${sep}`);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Checks if given path is from a module.
|
|
207
|
+
* @param path Path to check
|
|
208
|
+
* @returns true if path is from a module; false otherwise
|
|
209
|
+
*/
|
|
210
|
+
export const isModulePath = (path: string) => {
|
|
211
|
+
return path.includes(`${sep}modules${sep}`);
|
|
212
|
+
};
|
|
213
|
+
|
|
46
214
|
/**
|
|
47
215
|
* Checks if given card is in some template.
|
|
48
216
|
* @param card card object to check
|
|
@@ -55,6 +223,37 @@ export const isTemplateCard = (card: Card) => {
|
|
|
55
223
|
);
|
|
56
224
|
};
|
|
57
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Returns module name from card key
|
|
228
|
+
* @param cardKey Card key
|
|
229
|
+
* @returns module name
|
|
230
|
+
* @todo: should be renamed to modulePrefixFromCardKey
|
|
231
|
+
*/
|
|
232
|
+
export const moduleNameFromCardKey = (cardKey: string) => {
|
|
233
|
+
const parts = cardKey.split(CARD_KEY_SEPARATOR);
|
|
234
|
+
if (parts.length !== 2) {
|
|
235
|
+
throw new Error(`Invalid card key: ${cardKey}`);
|
|
236
|
+
}
|
|
237
|
+
return parts[0];
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Finds parent card key
|
|
242
|
+
* @param cardPath Card path from which to find parent card
|
|
243
|
+
* @returns Parent card key
|
|
244
|
+
*/
|
|
245
|
+
export function parentCard(cardPath: string) {
|
|
246
|
+
const pathParts = cardPath.split(sep);
|
|
247
|
+
if (
|
|
248
|
+
pathParts.at(pathParts.length - 2) === 'cardRoot' ||
|
|
249
|
+
(pathParts.length > 3 && pathParts.at(pathParts.length - 4) === 'templates')
|
|
250
|
+
) {
|
|
251
|
+
return ROOT;
|
|
252
|
+
} else {
|
|
253
|
+
return pathParts.at(pathParts.length - 3);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
58
257
|
/**
|
|
59
258
|
* Sorts array of cards first using prefix and then using ID.
|
|
60
259
|
* Prefixes are returned in alphabetical order, and then in numeric order within same prefix.
|
|
@@ -64,8 +263,8 @@ export const isTemplateCard = (card: Card) => {
|
|
|
64
263
|
* @returns Cards ordered; first by prefixes, then by ID.
|
|
65
264
|
*/
|
|
66
265
|
export const sortCards = (a: string, b: string) => {
|
|
67
|
-
const aParts = a.split(
|
|
68
|
-
const bParts = b.split(
|
|
266
|
+
const aParts = a.split(CARD_KEY_SEPARATOR);
|
|
267
|
+
const bParts = b.split(CARD_KEY_SEPARATOR);
|
|
69
268
|
if (aParts[0] !== bParts[0]) {
|
|
70
269
|
if (aParts[0] > bParts[0]) return 1;
|
|
71
270
|
if (aParts[0] < bParts[0]) return -1;
|
|
@@ -81,16 +280,3 @@ export const sortCards = (a: string, b: string) => {
|
|
|
81
280
|
if (aParts[1] < bParts[1]) return -1;
|
|
82
281
|
return 0;
|
|
83
282
|
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Returns module name from card key
|
|
87
|
-
* @param cardKey card key
|
|
88
|
-
* @returns module name
|
|
89
|
-
*/
|
|
90
|
-
export const moduleNameFromCardKey = (cardKey: string) => {
|
|
91
|
-
const parts = cardKey.split('_');
|
|
92
|
-
if (parts.length !== 2) {
|
|
93
|
-
throw new Error(`Invalid card key: ${cardKey}`);
|
|
94
|
-
}
|
|
95
|
-
return parts[0];
|
|
96
|
-
};
|
|
@@ -168,6 +168,7 @@ export const createWorkflowFacts = (workflow: Workflow) => {
|
|
|
168
168
|
*/
|
|
169
169
|
export const createCardFacts = async (card: Card, project: Project) => {
|
|
170
170
|
// Small helper to deduce parent path
|
|
171
|
+
// todo: Should use card-utils
|
|
171
172
|
function parentPath(cardPath: string) {
|
|
172
173
|
const pathParts = cardPath.split(sep);
|
|
173
174
|
if (pathParts.at(pathParts.length - 2) === 'cardRoot') {
|
|
@@ -178,6 +179,7 @@ export const createCardFacts = async (card: Card, project: Project) => {
|
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
// Helper to deduce template parent path.
|
|
182
|
+
// todo: Should use card-utils
|
|
181
183
|
function parentPathFromTemplate(card: Card) {
|
|
182
184
|
const cardPath = card.path;
|
|
183
185
|
const pathParts = cardPath.split(sep);
|
|
@@ -201,10 +203,18 @@ export const createCardFacts = async (card: Card, project: Project) => {
|
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
205
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
206
|
+
// Use card.parent if available, otherwise fall back to path-based calculation
|
|
207
|
+
const parentsPath =
|
|
208
|
+
card.parent && card.parent !== 'root'
|
|
209
|
+
? card.parent
|
|
210
|
+
: isTemplateCard(card)
|
|
211
|
+
? parentPathFromTemplate(card)
|
|
212
|
+
: parentPath(card.path);
|
|
213
|
+
|
|
207
214
|
const builder = new ClingoProgramBuilder().addComment(card.key);
|
|
215
|
+
if (!isTemplateCard(card)) {
|
|
216
|
+
builder.addCustomFact('card', (b) => b.addLiteralArgument(card.key));
|
|
217
|
+
}
|
|
208
218
|
|
|
209
219
|
if (card.metadata) {
|
|
210
220
|
for (const [field, value] of Object.entries(card.metadata)) {
|
|
@@ -103,7 +103,7 @@ class ClingoParser {
|
|
|
103
103
|
childObject: (parentKey: string, name: string, collection: string) => {
|
|
104
104
|
this.childObjectQueue.push({ parentKey, name, collection });
|
|
105
105
|
},
|
|
106
|
-
field:
|
|
106
|
+
field: (
|
|
107
107
|
key: string,
|
|
108
108
|
fieldName: string,
|
|
109
109
|
fieldValue: string,
|
package/src/utils/constants.ts
CHANGED
|
@@ -13,11 +13,17 @@
|
|
|
13
13
|
|
|
14
14
|
import type { PredefinedCardMetadata } from '../interfaces/project-interfaces.js';
|
|
15
15
|
|
|
16
|
+
// Card key separator between project prefix and card ID
|
|
17
|
+
export const CARD_KEY_SEPARATOR = '_';
|
|
18
|
+
|
|
16
19
|
export const INT32_MAX = 2147483647; // 2^31-1
|
|
17
20
|
|
|
18
21
|
// Maximum level offset for includeMacro
|
|
19
22
|
export const MAX_LEVEL_OFFSET = 5;
|
|
20
23
|
|
|
24
|
+
// Root parent name
|
|
25
|
+
export const ROOT = 'root';
|
|
26
|
+
|
|
21
27
|
/**
|
|
22
28
|
* These are file names that are valid for folder resources.
|
|
23
29
|
* Note that the folders might still contain other files, such as .schema files,
|
package/src/utils/csv.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { readFile } from 'fs/promises';
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
14
|
import { parse } from 'csv-parse/sync';
|
|
15
15
|
import type { CSVRowRaw } from '../interfaces/project-interfaces.js';
|
|
16
16
|
|