@cyberismo/data-handler 0.0.8 → 0.0.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.
- package/dist/command-handler.d.ts +11 -2
- package/dist/command-handler.js +61 -18
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.js +8 -8
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/calculate.d.ts +7 -44
- package/dist/commands/calculate.js +8 -389
- package/dist/commands/calculate.js.map +1 -1
- package/dist/commands/create.d.ts +6 -3
- package/dist/commands/create.js +27 -5
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/edit.d.ts +15 -3
- package/dist/commands/edit.js +52 -9
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/export.d.ts +11 -9
- package/dist/commands/export.js +80 -28
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +7 -0
- package/dist/commands/import.js +13 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/move.d.ts +11 -12
- package/dist/commands/move.js +12 -13
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/remove.d.ts +1 -3
- package/dist/commands/remove.js +4 -6
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.d.ts +1 -3
- package/dist/commands/rename.js +3 -6
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +37 -5
- package/dist/commands/show.js +89 -8
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/transition.d.ts +1 -3
- package/dist/commands/transition.js +3 -5
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.d.ts +5 -1
- package/dist/commands/update.js +7 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +31 -4
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/card-container.d.ts +6 -0
- package/dist/containers/card-container.js +61 -0
- package/dist/containers/card-container.js.map +1 -1
- package/dist/containers/project/calculation-engine.d.ts +90 -0
- package/dist/containers/project/calculation-engine.js +402 -0
- package/dist/containers/project/calculation-engine.js.map +1 -0
- package/dist/containers/project/resource-collector.js +9 -13
- package/dist/containers/project/resource-collector.js.map +1 -1
- package/dist/containers/project.d.ts +18 -1
- package/dist/containers/project.js +28 -55
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +5 -0
- package/dist/containers/template.js +9 -0
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/macros.d.ts +4 -2
- package/dist/interfaces/project-interfaces.d.ts +21 -0
- package/dist/interfaces/project-interfaces.js +4 -0
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +4 -2
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/base-macro.d.ts +2 -1
- package/dist/macros/base-macro.js +14 -2
- package/dist/macros/base-macro.js.map +1 -1
- package/dist/macros/common.d.ts +16 -9
- package/dist/macros/common.js +22 -9
- package/dist/macros/common.js.map +1 -1
- package/dist/macros/createCards/index.d.ts +2 -2
- package/dist/macros/createCards/index.js +4 -0
- package/dist/macros/createCards/index.js.map +1 -1
- package/dist/macros/graph/index.d.ts +1 -3
- package/dist/macros/graph/index.js +1 -6
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/image/index.d.ts +39 -0
- package/dist/macros/image/index.js +82 -0
- package/dist/macros/image/index.js.map +1 -0
- package/dist/macros/image/metadata.d.ts +18 -0
- package/dist/macros/image/metadata.js +22 -0
- package/dist/macros/image/metadata.js.map +1 -0
- package/dist/macros/include/index.d.ts +31 -0
- package/dist/macros/include/index.js +94 -0
- package/dist/macros/include/index.js.map +1 -0
- package/dist/macros/include/metadata.d.ts +15 -0
- package/dist/macros/include/metadata.js +19 -0
- package/dist/macros/include/metadata.js.map +1 -0
- package/dist/macros/index.d.ts +33 -31
- package/dist/macros/index.js +142 -71
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/percentage/index.d.ts +28 -0
- package/dist/macros/percentage/index.js +33 -0
- package/dist/macros/percentage/index.js.map +1 -0
- package/dist/macros/percentage/metadata.d.ts +15 -0
- package/dist/macros/percentage/metadata.js +19 -0
- package/dist/macros/percentage/metadata.js.map +1 -0
- package/dist/macros/report/index.d.ts +2 -6
- package/dist/macros/report/index.js +3 -7
- package/dist/macros/report/index.js.map +1 -1
- package/dist/macros/scoreCard/index.d.ts +14 -15
- package/dist/macros/scoreCard/index.js +14 -18
- package/dist/macros/scoreCard/index.js.map +1 -1
- package/dist/macros/vega/index.d.ts +28 -0
- package/dist/macros/vega/index.js +27 -0
- package/dist/macros/vega/index.js.map +1 -0
- package/dist/macros/vega/metadata.d.ts +15 -0
- package/dist/macros/vega/metadata.js +7 -0
- package/dist/macros/vega/metadata.js.map +1 -0
- package/dist/macros/vegalite/index.d.ts +26 -0
- package/dist/macros/vegalite/index.js +24 -0
- package/dist/macros/vegalite/index.js.map +1 -0
- package/dist/macros/vegalite/metadata.d.ts +15 -0
- package/dist/macros/vegalite/metadata.js +7 -0
- package/dist/macros/vegalite/metadata.js.map +1 -0
- package/dist/macros/xref/index.d.ts +26 -0
- package/dist/macros/xref/index.js +53 -0
- package/dist/macros/xref/index.js.map +1 -0
- package/dist/macros/xref/metadata.d.ts +15 -0
- package/dist/macros/xref/metadata.js +19 -0
- package/dist/macros/xref/metadata.js.map +1 -0
- package/dist/module-manager.d.ts +1 -0
- package/dist/module-manager.js +14 -4
- package/dist/module-manager.js.map +1 -1
- package/dist/permissions/action-guard.d.ts +2 -2
- package/dist/permissions/action-guard.js +1 -1
- package/dist/permissions/action-guard.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +2 -0
- package/dist/resources/card-type-resource.js +63 -0
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +2 -0
- package/dist/resources/file-resource.js +12 -4
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +19 -0
- package/dist/resources/folder-resource.js +51 -2
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.js +1 -1
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.js +1 -1
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/report-resource.js +1 -1
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +8 -0
- package/dist/resources/resource-object.js +10 -1
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.js +1 -1
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +2 -0
- package/dist/resources/workflow-resource.js +53 -9
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/svg/index.d.ts +15 -0
- package/dist/svg/index.js +16 -0
- package/dist/svg/index.js.map +1 -0
- package/dist/svg/lib.d.ts +9 -0
- package/dist/svg/lib.js +26 -0
- package/dist/svg/lib.js.map +1 -0
- package/dist/svg/percentage.d.ts +25 -0
- package/dist/svg/percentage.js +90 -0
- package/dist/svg/percentage.js.map +1 -0
- package/dist/svg/scoreCard.d.ts +19 -0
- package/dist/svg/scoreCard.js +55 -0
- package/dist/svg/scoreCard.js.map +1 -0
- package/dist/types/queries.d.ts +8 -7
- package/dist/types/queries.js.map +1 -1
- package/dist/utils/card-utils.d.ts +6 -0
- package/dist/utils/card-utils.js +12 -0
- package/dist/utils/card-utils.js.map +1 -1
- package/dist/utils/clingo-facts.d.ts +2 -1
- package/dist/utils/clingo-facts.js +19 -2
- package/dist/utils/clingo-facts.js.map +1 -1
- package/dist/utils/clingo-parser.d.ts +1 -0
- package/dist/utils/clingo-parser.js +22 -100
- package/dist/utils/clingo-parser.js.map +1 -1
- package/dist/utils/constants.d.ts +7 -0
- package/dist/utils/constants.js +14 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/csv.js.map +1 -1
- package/dist/utils/report.d.ts +17 -3
- package/dist/utils/report.js +38 -2
- package/dist/utils/report.js.map +1 -1
- package/dist/utils/resource-utils.d.ts +2 -1
- package/dist/utils/resource-utils.js +12 -3
- package/dist/utils/resource-utils.js.map +1 -1
- package/dist/utils/user-preferences.d.ts +1 -11
- package/dist/utils/user-preferences.js +30 -13
- package/dist/utils/user-preferences.js.map +1 -1
- package/dist/utils/validate.d.ts +2 -3
- package/dist/utils/validate.js +2 -2
- package/dist/utils/validate.js.map +1 -1
- package/package.json +8 -6
- package/src/command-handler.ts +96 -17
- package/src/command-manager.ts +8 -8
- package/src/commands/calculate.ts +11 -525
- package/src/commands/create.ts +35 -6
- package/src/commands/edit.ts +94 -11
- package/src/commands/export.ts +104 -31
- package/src/commands/import.ts +16 -0
- package/src/commands/move.ts +12 -15
- package/src/commands/remove.ts +4 -8
- package/src/commands/rename.ts +3 -12
- package/src/commands/show.ts +126 -9
- package/src/commands/transition.ts +3 -7
- package/src/commands/update.ts +6 -0
- package/src/commands/validate.ts +41 -13
- package/src/containers/card-container.ts +74 -0
- package/src/containers/project/calculation-engine.ts +535 -0
- package/src/containers/project/resource-collector.ts +13 -15
- package/src/containers/project.ts +30 -66
- package/src/containers/template.ts +16 -0
- package/src/index.ts +13 -2
- package/src/interfaces/macros.ts +4 -1
- package/src/interfaces/project-interfaces.ts +27 -0
- package/src/interfaces/resource-interfaces.ts +5 -2
- package/src/macros/base-macro.ts +19 -4
- package/src/macros/common.ts +22 -9
- package/src/macros/createCards/index.ts +6 -2
- package/src/macros/graph/index.ts +6 -10
- package/src/macros/image/index.ts +128 -0
- package/src/macros/image/metadata.ts +25 -0
- package/src/macros/include/index.ts +143 -0
- package/src/macros/include/metadata.ts +22 -0
- package/src/macros/index.ts +150 -98
- package/src/macros/percentage/index.ts +50 -0
- package/src/macros/percentage/metadata.ts +22 -0
- package/src/macros/report/index.ts +4 -12
- package/src/macros/scoreCard/index.ts +21 -25
- package/src/macros/vega/index.ts +55 -0
- package/src/macros/vega/metadata.ts +21 -0
- package/src/macros/vegalite/index.ts +46 -0
- package/src/macros/vegalite/metadata.ts +21 -0
- package/src/macros/xref/index.ts +73 -0
- package/src/macros/xref/metadata.ts +22 -0
- package/src/module-manager.ts +15 -5
- package/src/permissions/action-guard.ts +3 -3
- package/src/resources/card-type-resource.ts +100 -0
- package/src/resources/file-resource.ts +16 -4
- package/src/resources/folder-resource.ts +59 -2
- package/src/resources/graph-model-resource.ts +1 -1
- package/src/resources/graph-view-resource.ts +1 -1
- package/src/resources/report-resource.ts +1 -1
- package/src/resources/resource-object.ts +19 -1
- package/src/resources/template-resource.ts +1 -1
- package/src/resources/workflow-resource.ts +68 -13
- package/src/svg/index.ts +15 -0
- package/src/svg/lib.ts +31 -0
- package/src/svg/percentage.ts +97 -0
- package/src/svg/scoreCard.ts +88 -0
- package/src/types/queries.ts +8 -7
- package/src/types/string-pixel-width.d.ts +23 -0
- package/src/utils/card-utils.ts +13 -0
- package/src/utils/clingo-facts.ts +65 -3
- package/src/utils/clingo-parser.ts +31 -144
- package/src/utils/constants.ts +16 -0
- package/src/utils/csv.ts +1 -1
- package/src/utils/report.ts +45 -4
- package/src/utils/resource-utils.ts +12 -2
- package/src/utils/user-preferences.ts +32 -14
- package/src/utils/validate.ts +3 -3
package/src/commands/show.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
16
16
|
import { homedir } from 'node:os';
|
|
17
17
|
import { join, resolve } from 'node:path';
|
|
18
18
|
import { spawn } from 'node:child_process';
|
|
19
|
-
import { writeFile } from 'node:fs/promises';
|
|
19
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
20
20
|
|
|
21
21
|
import mime from 'mime-types';
|
|
22
22
|
|
|
@@ -30,6 +30,8 @@ import type {
|
|
|
30
30
|
ProjectMetadata,
|
|
31
31
|
Resource,
|
|
32
32
|
CardLocation,
|
|
33
|
+
Context,
|
|
34
|
+
ResourceFolderType,
|
|
33
35
|
} from '../interfaces/project-interfaces.js';
|
|
34
36
|
import type {
|
|
35
37
|
CardType,
|
|
@@ -38,13 +40,19 @@ import type {
|
|
|
38
40
|
Workflow,
|
|
39
41
|
} from '../interfaces/resource-interfaces.js';
|
|
40
42
|
import { Project, type ResourcesFrom } from '../containers/project.js';
|
|
41
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
type ResourceName,
|
|
45
|
+
resourceName,
|
|
46
|
+
resourceNameToPath,
|
|
47
|
+
resourceNameToString,
|
|
48
|
+
} from '../utils/resource-utils.js';
|
|
42
49
|
import { TemplateResource } from '../resources/template-resource.js';
|
|
43
50
|
import { UserPreferences } from '../utils/user-preferences.js';
|
|
44
51
|
|
|
45
52
|
import ReportMacro from '../macros/report/index.js';
|
|
46
53
|
import TaskQueue from '../macros/task-queue.js';
|
|
47
|
-
import
|
|
54
|
+
import { evaluateMacros } from '../macros/index.js';
|
|
55
|
+
import { FolderResource } from '../resources/folder-resource.js';
|
|
48
56
|
|
|
49
57
|
/**
|
|
50
58
|
* Show command.
|
|
@@ -54,11 +62,9 @@ export class Show {
|
|
|
54
62
|
string,
|
|
55
63
|
(from?: ResourcesFrom) => Promise<Resource[]>
|
|
56
64
|
>;
|
|
57
|
-
constructor(
|
|
58
|
-
private project: Project,
|
|
59
|
-
private calculate: Calculate,
|
|
60
|
-
) {
|
|
65
|
+
constructor(private project: Project) {
|
|
61
66
|
this.resourceFunction = new Map([
|
|
67
|
+
['calculations', this.project.calculations.bind(this.project)],
|
|
62
68
|
['cardTypes', this.project.cardTypes.bind(this.project)],
|
|
63
69
|
['fieldTypes', this.project.fieldTypes.bind(this.project)],
|
|
64
70
|
['graphModels', this.project.graphModels.bind(this.project)],
|
|
@@ -119,6 +125,27 @@ export class Show {
|
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Shows all template cards in a project.
|
|
130
|
+
* @returns all template cards in a project.
|
|
131
|
+
*/
|
|
132
|
+
public async showAllTemplateCards(): Promise<
|
|
133
|
+
{ name: string; cards: Card[] }[]
|
|
134
|
+
> {
|
|
135
|
+
return Promise.all(
|
|
136
|
+
(await this.project.templates()).map(async (template) => {
|
|
137
|
+
const templateResource = new TemplateResource(
|
|
138
|
+
this.project,
|
|
139
|
+
resourceName(template.name),
|
|
140
|
+
);
|
|
141
|
+
return {
|
|
142
|
+
name: template.name,
|
|
143
|
+
cards: await templateResource.templateObject().showTemplateCards(),
|
|
144
|
+
};
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
122
149
|
/**
|
|
123
150
|
* Shows all attachments (either template or project attachments) from a project.
|
|
124
151
|
* @returns array of card attachments
|
|
@@ -264,6 +291,15 @@ export class Show {
|
|
|
264
291
|
return this.project.listCards(cardsFrom);
|
|
265
292
|
}
|
|
266
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Shows the content of a logic program.
|
|
296
|
+
* @param cardKey The key of the card.
|
|
297
|
+
* @returns the content of the logic program.
|
|
298
|
+
*/
|
|
299
|
+
public async showCardLogicProgram(cardKey: string) {
|
|
300
|
+
return this.project.calculationEngine.cardLogicProgram(cardKey);
|
|
301
|
+
}
|
|
302
|
+
|
|
267
303
|
/**
|
|
268
304
|
* Shows all card types in a project.
|
|
269
305
|
* @returns array of card type details
|
|
@@ -282,6 +318,57 @@ export class Show {
|
|
|
282
318
|
return results.filter((item) => item);
|
|
283
319
|
}
|
|
284
320
|
|
|
321
|
+
/**
|
|
322
|
+
* Shows the content of a file in a resource.
|
|
323
|
+
* @param resourceName Name of the resource.
|
|
324
|
+
* @param fileName Name of the file to show.
|
|
325
|
+
* @returns the content of the file.
|
|
326
|
+
*/
|
|
327
|
+
public async showFile(
|
|
328
|
+
resourceName: ResourceName,
|
|
329
|
+
fileName: string,
|
|
330
|
+
): Promise<string> {
|
|
331
|
+
const resourceNameStr = resourceNameToString(resourceName);
|
|
332
|
+
if (
|
|
333
|
+
!(await this.project.resourceExists(
|
|
334
|
+
resourceName.type as ResourceFolderType,
|
|
335
|
+
resourceNameStr,
|
|
336
|
+
))
|
|
337
|
+
) {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`Resource '${resourceNameStr}' does not exist in the project`,
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
const resource = Project.resourceObject(this.project, resourceName);
|
|
343
|
+
if (!(resource instanceof FolderResource)) {
|
|
344
|
+
throw new Error(`Resource '${resourceNameStr}' is not a folder resource`);
|
|
345
|
+
}
|
|
346
|
+
return resource.showFile(fileName);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Shows all file names in a folder resource.
|
|
351
|
+
* @param resourceName Name of the resource.
|
|
352
|
+
* @returns all file names in the resource.
|
|
353
|
+
*/
|
|
354
|
+
public async showFileNames(resourceName: ResourceName): Promise<string[]> {
|
|
355
|
+
const resourceNameStr = resourceNameToString(resourceName);
|
|
356
|
+
if (
|
|
357
|
+
!(await this.project.resourceExists(
|
|
358
|
+
resourceName.type as ResourceFolderType,
|
|
359
|
+
resourceNameStr,
|
|
360
|
+
))
|
|
361
|
+
) {
|
|
362
|
+
throw new Error(
|
|
363
|
+
`Resource '${resourceNameStr}' does not exist in the project`,
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
const resource = Project.resourceObject(this.project, resourceName);
|
|
367
|
+
if (!(resource instanceof FolderResource)) {
|
|
368
|
+
throw new Error(`Resource '${resourceNameStr}' is not a folder resource`);
|
|
369
|
+
}
|
|
370
|
+
return resource.showFileNames();
|
|
371
|
+
}
|
|
285
372
|
/**
|
|
286
373
|
* Returns all unique labels in a project
|
|
287
374
|
* @returns labels in a list
|
|
@@ -297,6 +384,15 @@ export class Show {
|
|
|
297
384
|
return Array.from(new Set(labels));
|
|
298
385
|
}
|
|
299
386
|
|
|
387
|
+
/**
|
|
388
|
+
* Shows the content of a logic program.
|
|
389
|
+
* @param resource Name of the resource.
|
|
390
|
+
* @returns the content of the logic program.
|
|
391
|
+
*/
|
|
392
|
+
public async showLogicProgram(resource: ResourceName) {
|
|
393
|
+
return this.project.calculationEngine.resourceLogicProgram(resource);
|
|
394
|
+
}
|
|
395
|
+
|
|
300
396
|
/**
|
|
301
397
|
* Shows details of a module.
|
|
302
398
|
* @param moduleName name of a module
|
|
@@ -349,6 +445,7 @@ export class Show {
|
|
|
349
445
|
reportName: string,
|
|
350
446
|
cardKey: string,
|
|
351
447
|
parameters: object,
|
|
448
|
+
context: Context,
|
|
352
449
|
outputPath?: string,
|
|
353
450
|
): Promise<string> {
|
|
354
451
|
if (
|
|
@@ -359,16 +456,25 @@ export class Show {
|
|
|
359
456
|
throw new Error(`Report '${reportName}' does not exist`);
|
|
360
457
|
}
|
|
361
458
|
|
|
362
|
-
|
|
363
|
-
const
|
|
459
|
+
await this.project.calculationEngine.generate();
|
|
460
|
+
const reportMacro = new ReportMacro(new TaskQueue());
|
|
461
|
+
let result = await reportMacro.handleStatic(
|
|
364
462
|
{
|
|
365
463
|
project: this.project,
|
|
366
464
|
cardKey: cardKey,
|
|
367
465
|
mode: 'static',
|
|
466
|
+
context,
|
|
368
467
|
},
|
|
369
468
|
{ name: reportName, ...parameters },
|
|
370
469
|
);
|
|
371
470
|
|
|
471
|
+
result = await evaluateMacros(result, {
|
|
472
|
+
project: this.project,
|
|
473
|
+
cardKey: cardKey,
|
|
474
|
+
mode: 'static',
|
|
475
|
+
context,
|
|
476
|
+
});
|
|
477
|
+
|
|
372
478
|
// Show the results either in the console or write to a file.
|
|
373
479
|
if (outputPath) {
|
|
374
480
|
try {
|
|
@@ -393,6 +499,17 @@ export class Show {
|
|
|
393
499
|
name: string,
|
|
394
500
|
showUse: boolean = false,
|
|
395
501
|
): Promise<ResourceContent | undefined> {
|
|
502
|
+
// TODO: remove this workaround once calculations are implemented as a resource class
|
|
503
|
+
if (resourceName(name).type === 'calculations') {
|
|
504
|
+
const nameObj = resourceName(name);
|
|
505
|
+
const path = resourceNameToPath(this.project, nameObj, '.lp');
|
|
506
|
+
return {
|
|
507
|
+
name,
|
|
508
|
+
displayName: nameObj.identifier,
|
|
509
|
+
calculation: await readFile(path, 'utf-8'),
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
396
513
|
const strictNameCheck = true;
|
|
397
514
|
const resource = Project.resourceObject(
|
|
398
515
|
this.project,
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { ActionGuard } from '../permissions/action-guard.js';
|
|
15
|
-
import type { Calculate } from './calculate.js';
|
|
16
15
|
import type {
|
|
17
16
|
CardType,
|
|
18
17
|
Workflow,
|
|
@@ -22,10 +21,7 @@ import { CardMetadataUpdater } from '../card-metadata-updater.js';
|
|
|
22
21
|
import type { Project } from '../containers/project.js';
|
|
23
22
|
|
|
24
23
|
export class Transition {
|
|
25
|
-
constructor(
|
|
26
|
-
private project: Project,
|
|
27
|
-
private calculateCmd: Calculate,
|
|
28
|
-
) {}
|
|
24
|
+
constructor(private project: Project) {}
|
|
29
25
|
|
|
30
26
|
/**
|
|
31
27
|
* Transitions a card from its current state to a new state.
|
|
@@ -93,7 +89,7 @@ export class Transition {
|
|
|
93
89
|
);
|
|
94
90
|
}
|
|
95
91
|
|
|
96
|
-
const actionGuard = new ActionGuard(this.
|
|
92
|
+
const actionGuard = new ActionGuard(this.project.calculationEngine);
|
|
97
93
|
await actionGuard.checkPermission('transition', cardKey, transition.name);
|
|
98
94
|
|
|
99
95
|
details.metadata.workflowState = found.toState;
|
|
@@ -119,7 +115,7 @@ export class Transition {
|
|
|
119
115
|
// Wrapper to run onTransition query.
|
|
120
116
|
private async transitionChangesQuery(cardKey: string, transition: string) {
|
|
121
117
|
if (!cardKey || !transition) return undefined;
|
|
122
|
-
return this.
|
|
118
|
+
return this.project.calculationEngine.runQuery('onTransition', 'localApp', {
|
|
123
119
|
cardKey,
|
|
124
120
|
transition,
|
|
125
121
|
});
|
package/src/commands/update.ts
CHANGED
|
@@ -34,6 +34,7 @@ export class Update {
|
|
|
34
34
|
* @param key Property to change in resource JSON
|
|
35
35
|
* @param value Value for 'key'
|
|
36
36
|
* @param optionalDetail Additional detail needed for some operations. For example, 'update' needs a new value.
|
|
37
|
+
* @param mappingTable Optional mapping table for workflow state transitions (only used for workflow changes)
|
|
37
38
|
*/
|
|
38
39
|
public async updateValue<Type>(
|
|
39
40
|
name: string,
|
|
@@ -41,6 +42,7 @@ export class Update {
|
|
|
41
42
|
key: string,
|
|
42
43
|
value: Type,
|
|
43
44
|
optionalDetail?: Type, // todo: for 'rank' it might be reasonable to accept also 'number'
|
|
45
|
+
mappingTable?: { stateMapping: Record<string, string> },
|
|
44
46
|
) {
|
|
45
47
|
const resource = Project.resourceObject(this.project, resourceName(name));
|
|
46
48
|
const op: Operation<Type> = {
|
|
@@ -60,6 +62,10 @@ export class Update {
|
|
|
60
62
|
(op as ChangeOperation<Type>).to = optionalDetail
|
|
61
63
|
? optionalDetail
|
|
62
64
|
: (value as Type);
|
|
65
|
+
// Add mapping table if provided (for workflow changes)
|
|
66
|
+
if (mappingTable) {
|
|
67
|
+
(op as ChangeOperation<Type>).mappingTable = mappingTable;
|
|
68
|
+
}
|
|
63
69
|
} else if (operation === 'rank') {
|
|
64
70
|
(op as RankOperation<Type>).newIndex = optionalDetail as number;
|
|
65
71
|
(op as RankOperation<Type>).target = value;
|
package/src/commands/validate.ts
CHANGED
|
@@ -42,7 +42,7 @@ import { isTemplateCard } from '../utils/card-utils.js';
|
|
|
42
42
|
import { pathExists } from '../utils/file-utils.js';
|
|
43
43
|
import { Project } from '../containers/project.js';
|
|
44
44
|
import { readJsonFile } from '../utils/json.js';
|
|
45
|
-
import { resourceName } from '../utils/resource-utils.js';
|
|
45
|
+
import { type ResourceName, resourceName } from '../utils/resource-utils.js';
|
|
46
46
|
|
|
47
47
|
const invalidNames = new RegExp(
|
|
48
48
|
'[<>:"/\\|?*\x00-\x1F]|^(?:aux|con|clock$|nul|prn|com[1-9]|lpt[1-9])$', // eslint-disable-line no-control-regex
|
|
@@ -52,7 +52,6 @@ const SHORT_TEXT_MAX_LENGTH = 80;
|
|
|
52
52
|
|
|
53
53
|
import * as EmailValidator from 'email-validator';
|
|
54
54
|
import { evaluateMacros } from '../macros/index.js';
|
|
55
|
-
import { Calculate } from './calculate.js';
|
|
56
55
|
const baseDir = dirname(fileURLToPath(import.meta.url));
|
|
57
56
|
const subFoldersToValidate = ['.cards', 'cardRoot'];
|
|
58
57
|
|
|
@@ -482,7 +481,8 @@ export class Validate {
|
|
|
482
481
|
* returns true if identifier is valid, and false otherwise.
|
|
483
482
|
*/
|
|
484
483
|
public static isValidIdentifierName(identifier: string): boolean {
|
|
485
|
-
const validIdentifier = new RegExp('^[A-Za-z0-9
|
|
484
|
+
const validIdentifier = new RegExp('^[A-Za-z0-9._-]+$');
|
|
485
|
+
|
|
486
486
|
const contentValidated = validIdentifier.test(identifier);
|
|
487
487
|
const lengthValidated = identifier.length > 0 && identifier.length < 256;
|
|
488
488
|
const notInvalidIdentifier = !invalidNames.test(identifier);
|
|
@@ -547,7 +547,6 @@ export class Validate {
|
|
|
547
547
|
} else {
|
|
548
548
|
const errorMsg: string[] = [];
|
|
549
549
|
const project = new Project(projectPath);
|
|
550
|
-
const calculate = new Calculate(project);
|
|
551
550
|
|
|
552
551
|
// Then, validate that each 'contentSchema' children as well.
|
|
553
552
|
const result = await this.readAndValidateContentFiles(
|
|
@@ -562,7 +561,15 @@ export class Validate {
|
|
|
562
561
|
const cards = await project.cards();
|
|
563
562
|
cards.push(...(await project.allTemplateCards()));
|
|
564
563
|
|
|
564
|
+
const cardIds = new Map<string, number>();
|
|
565
|
+
|
|
565
566
|
for (const card of cards) {
|
|
567
|
+
if (cardIds.has(card.key)) {
|
|
568
|
+
cardIds.set(card.key, (cardIds.get(card.key) || 0) + 1);
|
|
569
|
+
} else {
|
|
570
|
+
cardIds.set(card.key, 1);
|
|
571
|
+
}
|
|
572
|
+
|
|
566
573
|
if (card.metadata) {
|
|
567
574
|
// validate card's workflow
|
|
568
575
|
if (!isTemplateCard(card)) {
|
|
@@ -591,15 +598,12 @@ export class Validate {
|
|
|
591
598
|
|
|
592
599
|
// Validate macros in content
|
|
593
600
|
if (card.content) {
|
|
594
|
-
await evaluateMacros(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
},
|
|
601
|
-
calculate,
|
|
602
|
-
);
|
|
601
|
+
await evaluateMacros(card.content, {
|
|
602
|
+
context: 'localApp',
|
|
603
|
+
mode: 'validate',
|
|
604
|
+
project,
|
|
605
|
+
cardKey: card.key,
|
|
606
|
+
});
|
|
603
607
|
}
|
|
604
608
|
}
|
|
605
609
|
if (errorMsg.length) {
|
|
@@ -607,6 +611,12 @@ export class Validate {
|
|
|
607
611
|
.filter(this.removeDuplicateEntries)
|
|
608
612
|
.join('\n');
|
|
609
613
|
}
|
|
614
|
+
// Validate that there are no duplicate card keys
|
|
615
|
+
for (const [key, count] of cardIds) {
|
|
616
|
+
if (count > 1) {
|
|
617
|
+
validationErrors += `Duplicate card key '${key}' found ${count} times\n`;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
610
620
|
}
|
|
611
621
|
} catch (error) {
|
|
612
622
|
validationErrors += errorFunction(error);
|
|
@@ -919,6 +929,24 @@ export class Validate {
|
|
|
919
929
|
return validationErrors.join('\n');
|
|
920
930
|
}
|
|
921
931
|
|
|
932
|
+
/**
|
|
933
|
+
* Validates a single resource.
|
|
934
|
+
* @param resource Resource to validate
|
|
935
|
+
* @returns string containing all validation errors
|
|
936
|
+
*/
|
|
937
|
+
public async validateResource(
|
|
938
|
+
resourceName: ResourceName,
|
|
939
|
+
project: Project,
|
|
940
|
+
): Promise<string> {
|
|
941
|
+
try {
|
|
942
|
+
const resource = Project.resourceObject(project, resourceName);
|
|
943
|
+
await resource.validate();
|
|
944
|
+
return '';
|
|
945
|
+
} catch (error) {
|
|
946
|
+
return errorFunction(error);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
922
950
|
/**
|
|
923
951
|
* Possibly creates (if no instance exists) and returns an instance of Validate command.
|
|
924
952
|
* @returns instance of Validate command.
|
|
@@ -17,6 +17,8 @@ import { basename, join, sep } from 'node:path';
|
|
|
17
17
|
import type { Dirent } from 'node:fs';
|
|
18
18
|
import { readdir, readFile, writeFile } from 'node:fs/promises';
|
|
19
19
|
|
|
20
|
+
import { findParentPath } from '../utils/card-utils.js';
|
|
21
|
+
import { readJsonFile } from '../utils/json.js';
|
|
20
22
|
import { writeJsonFile } from '../utils/json.js';
|
|
21
23
|
import { getFilesSync } from '../utils/file-utils.js';
|
|
22
24
|
|
|
@@ -24,6 +26,7 @@ import { getFilesSync } from '../utils/file-utils.js';
|
|
|
24
26
|
import {
|
|
25
27
|
type CardAttachment,
|
|
26
28
|
type Card,
|
|
29
|
+
type CardMetadata,
|
|
27
30
|
CardNameRegEx,
|
|
28
31
|
type FetchCardDetails,
|
|
29
32
|
} from '../interfaces/project-interfaces.js';
|
|
@@ -375,4 +378,75 @@ export class CardContainer {
|
|
|
375
378
|
await writeJsonFile(metadataFile, card.metadata);
|
|
376
379
|
}
|
|
377
380
|
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Show cards with hierarchy structure from a given path.
|
|
384
|
+
* @param path The path to read cards from
|
|
385
|
+
* @returns an array of cards with proper parent-child relationships.
|
|
386
|
+
*/
|
|
387
|
+
protected async showCards(path: string): Promise<Card[]> {
|
|
388
|
+
const cards: Card[] = [];
|
|
389
|
+
const cardPathMap = new Map<string, Card>();
|
|
390
|
+
const entries = await readdir(path, {
|
|
391
|
+
withFileTypes: true,
|
|
392
|
+
recursive: true,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
// Checks if Dirent folder is a card folder
|
|
396
|
+
function cardFolder(
|
|
397
|
+
entry: Dirent,
|
|
398
|
+
cardPathMap: Map<string, Card>,
|
|
399
|
+
): Card | undefined {
|
|
400
|
+
const fullPath = join(entry.parentPath, entry.name);
|
|
401
|
+
if (!cardPathMap.has(fullPath)) {
|
|
402
|
+
const newCard: Card = {
|
|
403
|
+
key: entry.name,
|
|
404
|
+
path: fullPath,
|
|
405
|
+
children: [],
|
|
406
|
+
attachments: [],
|
|
407
|
+
};
|
|
408
|
+
cardPathMap.set(fullPath, newCard);
|
|
409
|
+
return newCard;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Process card directories first
|
|
414
|
+
entries
|
|
415
|
+
.filter((entry) => entry.isDirectory() && CardNameRegEx.test(entry.name))
|
|
416
|
+
.forEach((entry) => {
|
|
417
|
+
const card = cardFolder(entry, cardPathMap);
|
|
418
|
+
if (card) cards.push(card);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// Process metadata files in parallel
|
|
422
|
+
await Promise.all(
|
|
423
|
+
entries
|
|
424
|
+
.filter(
|
|
425
|
+
(entry) =>
|
|
426
|
+
entry.isFile() && entry.name === CardContainer.cardMetadataFile,
|
|
427
|
+
)
|
|
428
|
+
.map(async (entry) => {
|
|
429
|
+
const parentCard = cardPathMap.get(entry.parentPath);
|
|
430
|
+
if (!parentCard) return;
|
|
431
|
+
parentCard.metadata = (await readJsonFile(
|
|
432
|
+
join(entry.parentPath, entry.name),
|
|
433
|
+
)) as CardMetadata;
|
|
434
|
+
}),
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
// Finally, build the card hierarchy
|
|
438
|
+
Array.from(cardPathMap.entries()).map(([cardPath, card]) => {
|
|
439
|
+
const parentPath = findParentPath(cardPath);
|
|
440
|
+
if (!parentPath) return;
|
|
441
|
+
const parentCard = cardPathMap.get(parentPath);
|
|
442
|
+
if (!parentCard) return;
|
|
443
|
+
|
|
444
|
+
parentCard.children.push(card);
|
|
445
|
+
const index = cards.indexOf(card);
|
|
446
|
+
if (index > -1) {
|
|
447
|
+
cards.splice(index, 1);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
return cards;
|
|
451
|
+
}
|
|
378
452
|
}
|