@cyberismo/data-handler 0.0.14 → 0.0.16
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 +8 -4
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.d.ts +4 -0
- package/dist/command-handler.js +29 -19
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +25 -2
- package/dist/command-manager.js +30 -5
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.js +45 -93
- 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.d.ts +11 -2
- package/dist/commands/export.js +58 -58
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +9 -1
- package/dist/commands/import.js +17 -11
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/move.d.ts +1 -2
- package/dist/commands/move.js +107 -146
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/remove.d.ts +8 -1
- package/dist/commands/remove.js +17 -48
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.d.ts +4 -9
- package/dist/commands/rename.js +34 -108
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +22 -34
- package/dist/commands/show.js +103 -151
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/transition.d.ts +9 -2
- package/dist/commands/transition.js +49 -44
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.d.ts +18 -12
- package/dist/commands/update.js +34 -18
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.d.ts +18 -10
- package/dist/commands/validate.js +101 -47
- 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 +13 -4
- package/dist/containers/project/calculation-engine.js +79 -77
- 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/project-paths.d.ts +5 -4
- package/dist/containers/project/project-paths.js +16 -12
- package/dist/containers/project/project-paths.js.map +1 -1
- package/dist/containers/project/resource-cache.d.ts +169 -0
- package/dist/containers/project/resource-cache.js +507 -0
- package/dist/containers/project/resource-cache.js.map +1 -0
- package/dist/containers/project/resource-handler.d.ts +129 -0
- package/dist/containers/project/resource-handler.js +206 -0
- package/dist/containers/project/resource-handler.js.map +1 -0
- package/dist/containers/project.d.ts +114 -195
- package/dist/containers/project.js +425 -535
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +22 -32
- package/dist/containers/template.js +113 -115
- 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 +7 -4
- package/dist/interfaces/folder-content-interfaces.js +3 -3
- 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 +7 -5
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +25 -22
- 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 +14 -28
- 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/index.d.ts +1 -1
- package/dist/macros/index.js +2 -2
- package/dist/macros/index.js.map +1 -1
- 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 +3 -6
- 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.d.ts +16 -3
- package/dist/module-manager.js +55 -23
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.d.ts +16 -3
- package/dist/project-settings.js +79 -14
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/calculation-resource.d.ts +6 -33
- package/dist/resources/calculation-resource.js +11 -60
- package/dist/resources/calculation-resource.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +10 -22
- package/dist/resources/card-type-resource.js +46 -66
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.d.ts +3 -2
- package/dist/resources/create-defaults.js +3 -2
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +8 -22
- package/dist/resources/field-type-resource.js +35 -60
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +14 -35
- package/dist/resources/file-resource.js +22 -301
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +44 -66
- package/dist/resources/folder-resource.js +102 -149
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.d.ts +9 -34
- package/dist/resources/graph-model-resource.js +18 -64
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.d.ts +9 -29
- package/dist/resources/graph-view-resource.js +13 -48
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/link-type-resource.d.ts +9 -23
- package/dist/resources/link-type-resource.js +11 -33
- package/dist/resources/link-type-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +10 -23
- package/dist/resources/report-resource.js +20 -67
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +143 -23
- package/dist/resources/resource-object.js +369 -48
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.d.ts +10 -17
- package/dist/resources/template-resource.js +19 -27
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +9 -25
- package/dist/resources/workflow-resource.js +25 -55
- 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-fact-builder.d.ts +25 -14
- package/dist/utils/clingo-fact-builder.js +27 -5
- package/dist/utils/clingo-fact-builder.js.map +1 -1
- package/dist/utils/clingo-facts.js +14 -7
- 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/dist/utils/resource-utils.d.ts +1 -0
- package/dist/utils/resource-utils.js +2 -1
- package/dist/utils/resource-utils.js.map +1 -1
- package/package.json +11 -11
- package/src/card-metadata-updater.ts +9 -7
- package/src/command-handler.ts +35 -23
- package/src/command-manager.ts +32 -19
- package/src/commands/create.ts +59 -160
- package/src/commands/edit.ts +16 -132
- package/src/commands/export.ts +71 -81
- package/src/commands/import.ts +26 -18
- package/src/commands/move.ts +143 -179
- package/src/commands/remove.ts +20 -59
- package/src/commands/rename.ts +45 -156
- package/src/commands/show.ts +153 -211
- package/src/commands/transition.ts +53 -58
- package/src/commands/update.ts +44 -23
- package/src/commands/validate.ts +108 -82
- package/src/containers/card-container.ts +200 -360
- package/src/containers/project/calculation-engine.ts +81 -105
- package/src/containers/project/card-cache.ts +497 -0
- package/src/containers/project/project-paths.ts +21 -13
- package/src/containers/project/resource-cache.ts +648 -0
- package/src/containers/project/resource-handler.ts +265 -0
- package/src/containers/project.ts +551 -693
- package/src/containers/template.ts +129 -142
- package/src/index.ts +1 -0
- package/src/interfaces/folder-content-interfaces.ts +14 -7
- package/src/interfaces/macros.ts +2 -0
- package/src/interfaces/project-interfaces.ts +14 -7
- package/src/interfaces/resource-interfaces.ts +30 -27
- package/src/macros/createCards/index.ts +1 -12
- package/src/macros/createCards/types.ts +46 -0
- package/src/macros/graph/index.ts +27 -52
- 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/index.ts +2 -2
- package/src/macros/percentage/index.ts +1 -7
- package/src/macros/percentage/types.ts +32 -0
- package/src/macros/report/index.ts +4 -13
- 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 +79 -22
- package/src/project-settings.ts +84 -15
- package/src/resources/calculation-resource.ts +21 -91
- package/src/resources/card-type-resource.ts +74 -109
- package/src/resources/create-defaults.ts +3 -2
- package/src/resources/field-type-resource.ts +61 -104
- package/src/resources/file-resource.ts +33 -441
- package/src/resources/folder-resource.ts +130 -207
- package/src/resources/graph-model-resource.ts +36 -95
- package/src/resources/graph-view-resource.ts +28 -70
- package/src/resources/link-type-resource.ts +23 -53
- package/src/resources/report-resource.ts +34 -96
- package/src/resources/resource-object.ts +511 -66
- package/src/resources/template-resource.ts +32 -44
- package/src/resources/workflow-resource.ts +42 -85
- package/src/utils/card-utils.ts +217 -31
- package/src/utils/clingo-fact-builder.ts +28 -16
- package/src/utils/clingo-facts.ts +16 -7
- package/src/utils/clingo-parser.ts +1 -1
- package/src/utils/constants.ts +6 -0
- package/src/utils/csv.ts +1 -1
- package/src/utils/resource-utils.ts +2 -1
- package/dist/containers/project/resource-collector.d.ts +0 -87
- package/dist/containers/project/resource-collector.js +0 -337
- package/dist/containers/project/resource-collector.js.map +0 -1
- package/src/containers/project/resource-collector.ts +0 -396
|
@@ -13,28 +13,23 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// node
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import { readdir, readFile, writeFile } from 'node:fs/promises';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { writeFile } from 'node:fs/promises';
|
|
19
18
|
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
19
|
+
import { CardCache } from './project/card-cache.js';
|
|
20
|
+
import { cardPathParts } from '../utils/card-utils.js';
|
|
21
|
+
import { deleteDir } from '../utils/file-utils.js';
|
|
23
22
|
import { writeJsonFile } from '../utils/json.js';
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
type CardMetadata,
|
|
30
|
-
CardNameRegEx,
|
|
31
|
-
type FetchCardDetails,
|
|
24
|
+
import type {
|
|
25
|
+
CardAttachment,
|
|
26
|
+
Card,
|
|
27
|
+
FetchCardDetails,
|
|
32
28
|
} from '../interfaces/project-interfaces.js';
|
|
33
29
|
|
|
34
|
-
// asciidoctor
|
|
35
30
|
import asciidoctor from '@asciidoctor/core';
|
|
36
31
|
|
|
37
|
-
import
|
|
32
|
+
import { ROOT } from '../utils/constants.js';
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
35
|
* Card container base class. Used for both Project and Template.
|
|
@@ -42,411 +37,256 @@ import mime from 'mime-types';
|
|
|
42
37
|
*/
|
|
43
38
|
export class CardContainer {
|
|
44
39
|
public basePath: string;
|
|
40
|
+
protected cardCache: CardCache;
|
|
45
41
|
protected containerName: string;
|
|
42
|
+
protected prefix: string;
|
|
46
43
|
|
|
47
|
-
static projectConfigFileName = 'cardsConfig.json';
|
|
48
|
-
static cardMetadataFile = 'index.json';
|
|
49
44
|
static cardContentFile = 'index.adoc';
|
|
45
|
+
static cardMetadataFile = 'index.json';
|
|
46
|
+
static projectConfigFileName = 'cardsConfig.json';
|
|
50
47
|
static schemaContentFile = '.schema';
|
|
51
48
|
|
|
52
|
-
constructor(path: string, name: string) {
|
|
49
|
+
constructor(path: string, prefix: string, name: string) {
|
|
53
50
|
this.basePath = path;
|
|
54
51
|
this.containerName = name;
|
|
52
|
+
this.prefix = prefix;
|
|
53
|
+
this.cardCache = new CardCache(this.prefix);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
//
|
|
58
|
-
private
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
56
|
+
// Filters one card to only include the details requested.
|
|
57
|
+
private filterCardDetails(
|
|
58
|
+
card: Card,
|
|
59
|
+
details: FetchCardDetails = {
|
|
60
|
+
attachments: true,
|
|
61
|
+
children: true,
|
|
62
|
+
content: true,
|
|
63
|
+
metadata: true,
|
|
64
|
+
parent: true,
|
|
65
|
+
},
|
|
66
|
+
): Card {
|
|
67
|
+
const filteredCard: Card = {
|
|
68
|
+
key: card.key,
|
|
69
|
+
path: card.path,
|
|
70
|
+
children: details.children ? card.children : [],
|
|
71
|
+
attachments: details.attachments ? card.attachments : [],
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (details.content) {
|
|
75
|
+
filteredCard.content = card.content;
|
|
77
76
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// For each attachment folder, collect all files.
|
|
81
|
-
if (CardNameRegEx.test(entry.name)) {
|
|
82
|
-
currentPaths.push(join(entry.parentPath, entry.name));
|
|
83
|
-
} else if (entry.name === 'c') {
|
|
84
|
-
continue;
|
|
85
|
-
} else if (entry.name === 'a') {
|
|
86
|
-
const attachmentFolder = join(entry.parentPath, entry.name);
|
|
87
|
-
const cardItem = basename(entry.parentPath) || '';
|
|
88
|
-
let entryAttachments: Dirent[] = [];
|
|
89
|
-
try {
|
|
90
|
-
entryAttachments = await readdir(attachmentFolder, {
|
|
91
|
-
withFileTypes: true,
|
|
92
|
-
});
|
|
93
|
-
} catch {
|
|
94
|
-
// ignore readdir errors
|
|
95
|
-
}
|
|
96
|
-
entryAttachments.forEach((attachment) =>
|
|
97
|
-
attachments.push({
|
|
98
|
-
card: cardItem,
|
|
99
|
-
fileName: attachment.name,
|
|
100
|
-
path: attachment.parentPath,
|
|
101
|
-
mimeType: mime.lookup(attachment.name) || null,
|
|
102
|
-
}),
|
|
103
|
-
);
|
|
104
|
-
}
|
|
77
|
+
if (details.metadata) {
|
|
78
|
+
filteredCard.metadata = structuredClone(card.metadata);
|
|
105
79
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const promises = currentPaths.map((item) =>
|
|
109
|
-
this.doCollectAttachments(item, attachments),
|
|
110
|
-
);
|
|
111
|
-
await Promise.all(promises);
|
|
112
|
-
}
|
|
113
|
-
return attachments;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Collects all cards from container.
|
|
117
|
-
private async doCollectCards(
|
|
118
|
-
path: string,
|
|
119
|
-
cards: Card[],
|
|
120
|
-
details: FetchCardDetails = {},
|
|
121
|
-
directChildrenOnly: boolean = false,
|
|
122
|
-
): Promise<Card[]> {
|
|
123
|
-
let entries = [];
|
|
124
|
-
try {
|
|
125
|
-
entries = await readdir(path, { withFileTypes: true });
|
|
126
|
-
} catch {
|
|
127
|
-
return cards;
|
|
80
|
+
if (details.parent) {
|
|
81
|
+
filteredCard.parent = card.parent;
|
|
128
82
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
for (const entry of entries) {
|
|
133
|
-
if (entry.isDirectory()) {
|
|
134
|
-
const currentPath = join(entry.parentPath, entry.name);
|
|
135
|
-
currentPaths.push(currentPath);
|
|
136
|
-
if (CardNameRegEx.test(entry.name)) {
|
|
137
|
-
if (directChildrenOnly) {
|
|
138
|
-
// Make recursion stop on the level where first children cards are found.
|
|
139
|
-
finish = true;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const attachmentFiles: CardAttachment[] = [];
|
|
143
|
-
const promiseContainer = [
|
|
144
|
-
this.getContent(currentPath, details.content),
|
|
145
|
-
this.getMetadata(currentPath, details.metadata),
|
|
146
|
-
this.getChildren(currentPath, details),
|
|
147
|
-
this.getAttachments(
|
|
148
|
-
currentPath,
|
|
149
|
-
attachmentFiles,
|
|
150
|
-
details.attachments,
|
|
151
|
-
),
|
|
152
|
-
];
|
|
153
|
-
const [cardContent, cardMetadata, cardChildren] =
|
|
154
|
-
await Promise.all(promiseContainer);
|
|
155
|
-
|
|
156
|
-
cards.push({
|
|
157
|
-
key: entry.name,
|
|
158
|
-
path: currentPath,
|
|
159
|
-
children: details.children ? (cardChildren as Card[]) : [],
|
|
160
|
-
attachments: details.attachments ? [...attachmentFiles] : [],
|
|
161
|
-
...(details.content && { content: cardContent as string }),
|
|
162
|
-
...(details.metadata && {
|
|
163
|
-
metadata: JSON.parse(cardMetadata as string),
|
|
164
|
-
}),
|
|
165
|
-
...(details.parent && { parent: this.parentCard(currentPath) }),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
83
|
+
if (details.calculations) {
|
|
84
|
+
filteredCard.calculations = card.calculations;
|
|
169
85
|
}
|
|
170
86
|
|
|
171
|
-
|
|
172
|
-
if (!finish && currentPaths) {
|
|
173
|
-
const promises = currentPaths.map((item) =>
|
|
174
|
-
this.doCollectCards(item, cards, details, directChildrenOnly),
|
|
175
|
-
);
|
|
176
|
-
await Promise.all(promises);
|
|
177
|
-
}
|
|
178
|
-
return cards;
|
|
87
|
+
return filteredCard;
|
|
179
88
|
}
|
|
180
89
|
|
|
181
|
-
//
|
|
182
|
-
private
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
let asciiDocProcessor;
|
|
190
|
-
// optimization: do not create AsciiDoctor Processor, unless it is needed.
|
|
191
|
-
if (details.contentType && details.contentType === 'html') {
|
|
192
|
-
asciiDocProcessor = asciidoctor();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
for (const entry of entries) {
|
|
196
|
-
if (entry.isDirectory()) {
|
|
197
|
-
const currentPath = join(entry.parentPath, entry.name);
|
|
198
|
-
if (entry.name === cardKey) {
|
|
199
|
-
const attachmentFiles: CardAttachment[] = [];
|
|
200
|
-
const promiseContainer = [
|
|
201
|
-
this.getContent(currentPath, details.content),
|
|
202
|
-
this.getMetadata(currentPath, details.metadata),
|
|
203
|
-
this.getChildren(currentPath, details),
|
|
204
|
-
this.getAttachments(
|
|
205
|
-
currentPath,
|
|
206
|
-
attachmentFiles,
|
|
207
|
-
details.attachments,
|
|
208
|
-
),
|
|
209
|
-
];
|
|
210
|
-
const [cardContent, cardMetadata, cardChildren] =
|
|
211
|
-
await Promise.all(promiseContainer);
|
|
212
|
-
|
|
213
|
-
const content =
|
|
214
|
-
details.contentType && details.contentType === 'html'
|
|
215
|
-
? asciiDocProcessor?.convert(cardContent as string)
|
|
216
|
-
: cardContent;
|
|
217
|
-
|
|
218
|
-
foundCards.push({
|
|
219
|
-
key: entry.name,
|
|
220
|
-
path: currentPath,
|
|
221
|
-
children: details.children ? (cardChildren as Card[]) : [],
|
|
222
|
-
attachments: details.attachments ? [...attachmentFiles] : [],
|
|
223
|
-
...(details.content && { content: content as string }),
|
|
224
|
-
...(details.metadata && {
|
|
225
|
-
metadata: JSON.parse(cardMetadata as string),
|
|
226
|
-
}),
|
|
227
|
-
...(details.parent && { parent: this.parentCard(currentPath) }),
|
|
228
|
-
...(details.calculations && { calculations: [] }),
|
|
229
|
-
});
|
|
230
|
-
break; //optimization - there can only be one.
|
|
231
|
-
}
|
|
232
|
-
// Only continue, if the card has not been found.
|
|
233
|
-
if (foundCards.length === 0) {
|
|
234
|
-
await this.doFindCard(currentPath, cardKey, details, foundCards);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return foundCards;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Gets conditionally attachments
|
|
242
|
-
private async getAttachments(
|
|
243
|
-
currentPath: string,
|
|
244
|
-
files: CardAttachment[],
|
|
245
|
-
include?: boolean,
|
|
246
|
-
): Promise<string | CardAttachment[] | Card[]> {
|
|
247
|
-
return include ? this.doCollectAttachments(currentPath, files) : [];
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Gets conditionally children
|
|
251
|
-
private async getChildren(
|
|
252
|
-
currentPath: string,
|
|
253
|
-
details: FetchCardDetails = {},
|
|
254
|
-
): Promise<string | CardAttachment[] | Card[]> {
|
|
255
|
-
return details.children ? this.childrenCards(currentPath, details) : [];
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Gets conditionally content
|
|
259
|
-
private async getContent(
|
|
260
|
-
currentPath: string,
|
|
261
|
-
include?: boolean,
|
|
262
|
-
): Promise<string | CardAttachment[] | Card[]> {
|
|
263
|
-
return include
|
|
264
|
-
? readFile(join(currentPath, CardContainer.cardContentFile), {
|
|
265
|
-
encoding: 'utf-8',
|
|
266
|
-
})
|
|
267
|
-
: '';
|
|
90
|
+
// Filters cards to only include the details requested.
|
|
91
|
+
private filterCardsDetails(
|
|
92
|
+
cards: Card[],
|
|
93
|
+
details?: FetchCardDetails,
|
|
94
|
+
): Card[] {
|
|
95
|
+
return cards.map((card) => {
|
|
96
|
+
return this.filterCardDetails(card, details);
|
|
97
|
+
});
|
|
268
98
|
}
|
|
269
99
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
encoding: 'utf-8',
|
|
278
|
-
})
|
|
279
|
-
: '';
|
|
280
|
-
metadata = this.injectLinksIfMissing(metadata);
|
|
281
|
-
return metadata;
|
|
100
|
+
/**
|
|
101
|
+
* Determines the container from a given path.
|
|
102
|
+
* @param path The filesystem path to analyze
|
|
103
|
+
* @returns Location string: 'project' for project cards, template name for template cards
|
|
104
|
+
*/
|
|
105
|
+
protected determineContainer(path: string): string {
|
|
106
|
+
return cardPathParts(this.prefix, path).template || 'project';
|
|
282
107
|
}
|
|
283
108
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
metadata = metadata.slice(0, end - 1) + ',\n "links": []\n' + '}';
|
|
289
|
-
}
|
|
290
|
-
return metadata;
|
|
291
|
-
}
|
|
109
|
+
/**
|
|
110
|
+
* Populates the card cache with all cards from all locations.
|
|
111
|
+
*/
|
|
112
|
+
protected async populateCardsCache(): Promise<void> {}
|
|
292
113
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
pathParts.at(pathParts.length - 2) === 'cardRoot' ||
|
|
298
|
-
(pathParts.length > 3 &&
|
|
299
|
-
pathParts.at(pathParts.length - 4) === 'templates')
|
|
300
|
-
) {
|
|
301
|
-
return 'root';
|
|
302
|
-
} else {
|
|
303
|
-
return pathParts.at(pathParts.length - 3);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
114
|
+
/**
|
|
115
|
+
* Populates template cards into the cache.
|
|
116
|
+
*/
|
|
117
|
+
protected async populateTemplateCards(): Promise<void> {}
|
|
306
118
|
|
|
307
|
-
|
|
308
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Lists all attachments from the container.
|
|
121
|
+
* @param path Path where attachments should be collected.
|
|
122
|
+
* @returns attachments from the container.
|
|
123
|
+
*/
|
|
124
|
+
protected attachments(path: string): CardAttachment[] {
|
|
309
125
|
const attachments: CardAttachment[] = [];
|
|
310
|
-
const cards: Card[] = [];
|
|
311
|
-
await this.doCollectCards(path, cards, { attachments: true });
|
|
312
126
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
127
|
+
const targetLocation = this.determineContainer(path);
|
|
128
|
+
const cards = [...this.cardCache.getCards()];
|
|
129
|
+
const filteredCards = cards.filter((card) => {
|
|
130
|
+
if (card.attachments.length === 0) {
|
|
131
|
+
return false;
|
|
316
132
|
}
|
|
133
|
+
return card.location === targetLocation;
|
|
317
134
|
});
|
|
318
135
|
|
|
136
|
+
filteredCards.forEach((item) => attachments.push(...item.attachments));
|
|
319
137
|
return attachments;
|
|
320
138
|
}
|
|
321
139
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Shows all cards from the container with the given details (by default all of them).
|
|
142
|
+
* @param path Path where cards should be listed.
|
|
143
|
+
* @param details Which details of the card should be included
|
|
144
|
+
* @returns all cards from the container
|
|
145
|
+
*/
|
|
146
|
+
protected cards(path: string, details?: FetchCardDetails): Card[] {
|
|
147
|
+
if (!this.cardCache.isPopulated) {
|
|
148
|
+
throw new Error('Cards cache is not populated!');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const targetLocation = this.determineContainer(path);
|
|
152
|
+
const relevantCards = this.cardCache
|
|
153
|
+
.getCards()
|
|
154
|
+
.filter((cachedCard) => cachedCard.location === targetLocation);
|
|
155
|
+
return this.filterCardsDetails(relevantCards, details);
|
|
336
156
|
}
|
|
337
157
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Finds a specific card.
|
|
160
|
+
* @param cardKey Card key to find
|
|
161
|
+
* @param details Card details to be included in the card
|
|
162
|
+
* @throws if card does not exist in the container
|
|
163
|
+
*/
|
|
164
|
+
protected findCard(cardKey: string, details?: FetchCardDetails): Card {
|
|
165
|
+
const cachedCard = this.cardCache.getCard(cardKey);
|
|
166
|
+
if (cachedCard) {
|
|
167
|
+
// Apply content type transformation if needed
|
|
168
|
+
const content = cachedCard.content;
|
|
169
|
+
if (details?.contentType === 'html' && content) {
|
|
170
|
+
const processor = asciidoctor();
|
|
171
|
+
processor.convert(content) as string;
|
|
172
|
+
}
|
|
173
|
+
return this.filterCardDetails(cachedCard, details);
|
|
174
|
+
}
|
|
175
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
347
176
|
}
|
|
348
177
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
);
|
|
356
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Removes a card. If card has children, they are removed as well.
|
|
180
|
+
* @param cardKey Card key to remove.
|
|
181
|
+
* @returns true, if card was removed; false otherwise
|
|
182
|
+
*/
|
|
183
|
+
protected async removeCard(cardKey: string): Promise<boolean> {
|
|
184
|
+
const card = this.cardCache.getCard(cardKey);
|
|
185
|
+
if (card) {
|
|
186
|
+
// Children must removed first
|
|
187
|
+
const children = card.children;
|
|
188
|
+
for (const child of children) {
|
|
189
|
+
await this.removeCard(child);
|
|
190
|
+
}
|
|
191
|
+
await deleteDir(card.path);
|
|
192
|
+
return this.cardCache.deleteCard(cardKey);
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
357
195
|
}
|
|
358
196
|
|
|
359
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Persists the whole card.
|
|
199
|
+
* @param card Card to persist
|
|
200
|
+
*/
|
|
360
201
|
protected async saveCard(card: Card) {
|
|
361
202
|
await this.saveCardContent(card);
|
|
362
203
|
await this.saveCardMetadata(card);
|
|
363
204
|
}
|
|
364
205
|
|
|
365
|
-
|
|
366
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Persists card content.
|
|
208
|
+
* @param card Card to persist.
|
|
209
|
+
* @returns true if card was updated; false otherwise.
|
|
210
|
+
*/
|
|
211
|
+
protected async saveCardContent(card: Card): Promise<boolean> {
|
|
367
212
|
if (card.content != null) {
|
|
368
213
|
const contentFile = join(card.path, CardContainer.cardContentFile);
|
|
369
214
|
await writeFile(contentFile, card.content);
|
|
215
|
+
return this.cardCache.updateCardContent(card.key, card.content);
|
|
370
216
|
}
|
|
217
|
+
return false;
|
|
371
218
|
}
|
|
372
219
|
|
|
373
|
-
|
|
374
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Persists card metadata.
|
|
222
|
+
* @param card Card to persist
|
|
223
|
+
* @returns true if card was updated; false otherwise.
|
|
224
|
+
*/
|
|
225
|
+
protected async saveCardMetadata(card: Card): Promise<boolean> {
|
|
375
226
|
if (card.metadata != null) {
|
|
376
227
|
const metadataFile = join(card.path, CardContainer.cardMetadataFile);
|
|
377
228
|
card.metadata!.lastUpdated = new Date().toISOString();
|
|
378
229
|
await writeJsonFile(metadataFile, card.metadata);
|
|
230
|
+
return this.cardCache.updateCardMetadata(card.key, card.metadata);
|
|
379
231
|
}
|
|
232
|
+
return false;
|
|
380
233
|
}
|
|
381
234
|
|
|
382
235
|
/**
|
|
383
|
-
* Show cards
|
|
384
|
-
* @param path The path to
|
|
385
|
-
* @returns an array of cards with
|
|
236
|
+
* Show root cards from a given path.
|
|
237
|
+
* @param path The path to get cards from
|
|
238
|
+
* @returns an array of root-level cards (each with their children populated).
|
|
386
239
|
*/
|
|
387
|
-
protected
|
|
388
|
-
const
|
|
389
|
-
const
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
});
|
|
240
|
+
protected showCards(path: string): Card[] {
|
|
241
|
+
const container = this.determineContainer(path);
|
|
242
|
+
const rootCards: Card[] = [];
|
|
243
|
+
const relevantCards = Array.from(this.cardCache.getCards()).filter(
|
|
244
|
+
(cachedCard) => cachedCard.location === container,
|
|
245
|
+
);
|
|
394
246
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
path: fullPath,
|
|
405
|
-
children: [],
|
|
406
|
-
attachments: [],
|
|
247
|
+
relevantCards.forEach((card) => {
|
|
248
|
+
if (
|
|
249
|
+
card.parent === ROOT ||
|
|
250
|
+
!card.parent ||
|
|
251
|
+
!relevantCards.find((cachedCard) => cachedCard.key === card.parent)
|
|
252
|
+
) {
|
|
253
|
+
const cardWithChildren: Card = {
|
|
254
|
+
...card,
|
|
255
|
+
children: card.children,
|
|
407
256
|
};
|
|
408
|
-
|
|
409
|
-
return newCard;
|
|
257
|
+
rootCards.push(cardWithChildren);
|
|
410
258
|
}
|
|
411
|
-
}
|
|
259
|
+
});
|
|
412
260
|
|
|
413
|
-
|
|
414
|
-
|
|
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
|
-
);
|
|
261
|
+
return rootCards;
|
|
262
|
+
}
|
|
436
263
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
264
|
+
/**
|
|
265
|
+
* Checks if container has the specified card.
|
|
266
|
+
* @param cardKey Card key to check
|
|
267
|
+
* @return true, if card is in the container
|
|
268
|
+
*/
|
|
269
|
+
public hasCard(cardKey: string): boolean {
|
|
270
|
+
return this.cardCache.hasCard(cardKey);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Checks if container has the specified project card.
|
|
275
|
+
* @param cardKey Card key to check
|
|
276
|
+
* @return true, if card is in the container
|
|
277
|
+
*/
|
|
278
|
+
public hasProjectCard(cardKey: string): boolean {
|
|
279
|
+
const cachedCard = this.cardCache.getCard(cardKey);
|
|
280
|
+
return cachedCard ? cachedCard.location === 'project' : false;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Checks if container has the specified template card.
|
|
285
|
+
* @param cardKey Card key to check
|
|
286
|
+
* @return true, if card is in the container
|
|
287
|
+
*/
|
|
288
|
+
public hasTemplateCard(cardKey: string): boolean {
|
|
289
|
+
const cachedCard = this.cardCache.getCard(cardKey);
|
|
290
|
+
return cachedCard ? cachedCard.location !== 'project' : false;
|
|
451
291
|
}
|
|
452
292
|
}
|