@cyberismo/data-handler 0.0.2
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/LICENSE +702 -0
- package/dist/card-metadata-updater.d.ts +33 -0
- package/dist/card-metadata-updater.js +121 -0
- package/dist/card-metadata-updater.js.map +1 -0
- package/dist/command-handler.d.ts +96 -0
- package/dist/command-handler.js +557 -0
- package/dist/command-handler.js.map +1 -0
- package/dist/command-manager.d.ts +43 -0
- package/dist/command-manager.js +73 -0
- package/dist/command-manager.js.map +1 -0
- package/dist/commands/calculate.d.ts +86 -0
- package/dist/commands/calculate.js +444 -0
- package/dist/commands/calculate.js.map +1 -0
- package/dist/commands/create.d.ts +114 -0
- package/dist/commands/create.js +389 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/edit.d.ts +37 -0
- package/dist/commands/edit.js +99 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/export-site.d.ts +45 -0
- package/dist/commands/export-site.js +301 -0
- package/dist/commands/export-site.js.map +1 -0
- package/dist/commands/export.d.ts +53 -0
- package/dist/commands/export.js +251 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +53 -0
- package/dist/commands/import.js +133 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/index.d.ts +26 -0
- package/dist/commands/index.js +27 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/move.d.ts +55 -0
- package/dist/commands/move.js +341 -0
- package/dist/commands/move.js.map +1 -0
- package/dist/commands/remove.d.ts +38 -0
- package/dist/commands/remove.js +192 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/rename.d.ts +46 -0
- package/dist/commands/rename.js +289 -0
- package/dist/commands/rename.js.map +1 -0
- package/dist/commands/show.d.ts +124 -0
- package/dist/commands/show.js +345 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/transition.d.ts +27 -0
- package/dist/commands/transition.js +92 -0
- package/dist/commands/transition.js.map +1 -0
- package/dist/commands/update.d.ts +29 -0
- package/dist/commands/update.js +64 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +143 -0
- package/dist/commands/validate.js +689 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/containers/card-container.d.ts +44 -0
- package/dist/containers/card-container.js +282 -0
- package/dist/containers/card-container.js.map +1 -0
- package/dist/containers/project/project-paths.d.ts +46 -0
- package/dist/containers/project/project-paths.js +105 -0
- package/dist/containers/project/project-paths.js.map +1 -0
- package/dist/containers/project/resource-collector.d.ts +86 -0
- package/dist/containers/project/resource-collector.js +331 -0
- package/dist/containers/project/resource-collector.js.map +1 -0
- package/dist/containers/project.d.ts +351 -0
- package/dist/containers/project.js +896 -0
- package/dist/containers/project.js.map +1 -0
- package/dist/containers/template.d.ts +108 -0
- package/dist/containers/template.js +433 -0
- package/dist/containers/template.js.map +1 -0
- package/dist/exceptions/index.d.ts +19 -0
- package/dist/exceptions/index.js +26 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/adoc.d.ts +12 -0
- package/dist/interfaces/adoc.js +13 -0
- package/dist/interfaces/adoc.js.map +1 -0
- package/dist/interfaces/macros.d.ts +45 -0
- package/dist/interfaces/macros.js +13 -0
- package/dist/interfaces/macros.js.map +1 -0
- package/dist/interfaces/project-interfaces.d.ts +121 -0
- package/dist/interfaces/project-interfaces.js +21 -0
- package/dist/interfaces/project-interfaces.js.map +1 -0
- package/dist/interfaces/request-status-interfaces.d.ts +28 -0
- package/dist/interfaces/request-status-interfaces.js +20 -0
- package/dist/interfaces/request-status-interfaces.js.map +1 -0
- package/dist/interfaces/resource-interfaces.d.ts +117 -0
- package/dist/interfaces/resource-interfaces.js +20 -0
- package/dist/interfaces/resource-interfaces.js.map +1 -0
- package/dist/macros/base-macro.d.ts +31 -0
- package/dist/macros/base-macro.js +126 -0
- package/dist/macros/base-macro.js.map +1 -0
- package/dist/macros/common.d.ts +17 -0
- package/dist/macros/common.js +23 -0
- package/dist/macros/common.js.map +1 -0
- package/dist/macros/createCards/index.d.ts +36 -0
- package/dist/macros/createCards/index.js +35 -0
- package/dist/macros/createCards/index.js.map +1 -0
- package/dist/macros/createCards/metadata.d.ts +14 -0
- package/dist/macros/createCards/metadata.js +18 -0
- package/dist/macros/createCards/metadata.js.map +1 -0
- package/dist/macros/graph/index.d.ts +29 -0
- package/dist/macros/graph/index.js +91 -0
- package/dist/macros/graph/index.js.map +1 -0
- package/dist/macros/graph/metadata.d.ts +14 -0
- package/dist/macros/graph/metadata.js +18 -0
- package/dist/macros/graph/metadata.js.map +1 -0
- package/dist/macros/index.d.ts +93 -0
- package/dist/macros/index.js +237 -0
- package/dist/macros/index.js.map +1 -0
- package/dist/macros/report/index.d.ts +26 -0
- package/dist/macros/report/index.js +70 -0
- package/dist/macros/report/index.js.map +1 -0
- package/dist/macros/report/metadata.d.ts +14 -0
- package/dist/macros/report/metadata.js +18 -0
- package/dist/macros/report/metadata.js.map +1 -0
- package/dist/macros/scoreCard/index.d.ts +30 -0
- package/dist/macros/scoreCard/index.js +38 -0
- package/dist/macros/scoreCard/index.js.map +1 -0
- package/dist/macros/scoreCard/metadata.d.ts +14 -0
- package/dist/macros/scoreCard/metadata.js +18 -0
- package/dist/macros/scoreCard/metadata.js.map +1 -0
- package/dist/macros/task-queue.d.ts +46 -0
- package/dist/macros/task-queue.js +69 -0
- package/dist/macros/task-queue.js.map +1 -0
- package/dist/module-manager.d.ts +62 -0
- package/dist/module-manager.js +350 -0
- package/dist/module-manager.js.map +1 -0
- package/dist/permissions/action-guard.d.ts +28 -0
- package/dist/permissions/action-guard.js +61 -0
- package/dist/permissions/action-guard.js.map +1 -0
- package/dist/project-settings.d.ts +42 -0
- package/dist/project-settings.js +120 -0
- package/dist/project-settings.js.map +1 -0
- package/dist/resources/array-handler.d.ts +28 -0
- package/dist/resources/array-handler.js +116 -0
- package/dist/resources/array-handler.js.map +1 -0
- package/dist/resources/card-type-resource.d.ts +72 -0
- package/dist/resources/card-type-resource.js +334 -0
- package/dist/resources/card-type-resource.js.map +1 -0
- package/dist/resources/create-defaults.d.ts +81 -0
- package/dist/resources/create-defaults.js +184 -0
- package/dist/resources/create-defaults.js.map +1 -0
- package/dist/resources/field-type-resource.d.ts +88 -0
- package/dist/resources/field-type-resource.js +411 -0
- package/dist/resources/field-type-resource.js.map +1 -0
- package/dist/resources/file-resource.d.ts +50 -0
- package/dist/resources/file-resource.js +301 -0
- package/dist/resources/file-resource.js.map +1 -0
- package/dist/resources/folder-resource.d.ts +66 -0
- package/dist/resources/folder-resource.js +100 -0
- package/dist/resources/folder-resource.js.map +1 -0
- package/dist/resources/graph-model-resource.d.ts +78 -0
- package/dist/resources/graph-model-resource.js +164 -0
- package/dist/resources/graph-model-resource.js.map +1 -0
- package/dist/resources/graph-view-resource.d.ts +78 -0
- package/dist/resources/graph-view-resource.js +163 -0
- package/dist/resources/graph-view-resource.js.map +1 -0
- package/dist/resources/link-type-resource.d.ts +62 -0
- package/dist/resources/link-type-resource.js +150 -0
- package/dist/resources/link-type-resource.js.map +1 -0
- package/dist/resources/report-resource.d.ts +77 -0
- package/dist/resources/report-resource.js +171 -0
- package/dist/resources/report-resource.js.map +1 -0
- package/dist/resources/resource-object.d.ts +108 -0
- package/dist/resources/resource-object.js +147 -0
- package/dist/resources/resource-object.js.map +1 -0
- package/dist/resources/template-resource.d.ts +82 -0
- package/dist/resources/template-resource.js +173 -0
- package/dist/resources/template-resource.js.map +1 -0
- package/dist/resources/workflow-resource.d.ts +67 -0
- package/dist/resources/workflow-resource.js +156 -0
- package/dist/resources/workflow-resource.js.map +1 -0
- package/dist/types/queries.d.ts +142 -0
- package/dist/types/queries.js +16 -0
- package/dist/types/queries.js.map +1 -0
- package/dist/utils/card-utils.d.ts +34 -0
- package/dist/utils/card-utils.js +78 -0
- package/dist/utils/card-utils.js.map +1 -0
- package/dist/utils/clingo-fact-builder.d.ts +58 -0
- package/dist/utils/clingo-fact-builder.js +126 -0
- package/dist/utils/clingo-fact-builder.js.map +1 -0
- package/dist/utils/clingo-facts.d.ts +97 -0
- package/dist/utils/clingo-facts.js +352 -0
- package/dist/utils/clingo-facts.js.map +1 -0
- package/dist/utils/clingo-parser.d.ts +59 -0
- package/dist/utils/clingo-parser.js +403 -0
- package/dist/utils/clingo-parser.js.map +1 -0
- package/dist/utils/clingo-program-builder.d.ts +39 -0
- package/dist/utils/clingo-program-builder.js +57 -0
- package/dist/utils/clingo-program-builder.js.map +1 -0
- package/dist/utils/common-utils.d.ts +24 -0
- package/dist/utils/common-utils.js +47 -0
- package/dist/utils/common-utils.js.map +1 -0
- package/dist/utils/constants.d.ts +18 -0
- package/dist/utils/constants.js +27 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/csv.d.ts +18 -0
- package/dist/utils/csv.js +45 -0
- package/dist/utils/csv.js.map +1 -0
- package/dist/utils/file-utils.d.ts +69 -0
- package/dist/utils/file-utils.js +158 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/dist/utils/json.d.ts +61 -0
- package/dist/utils/json.js +108 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/lexorank.d.ts +59 -0
- package/dist/utils/lexorank.js +159 -0
- package/dist/utils/lexorank.js.map +1 -0
- package/dist/utils/log-utils.d.ts +40 -0
- package/dist/utils/log-utils.js +109 -0
- package/dist/utils/log-utils.js.map +1 -0
- package/dist/utils/random.d.ts +19 -0
- package/dist/utils/random.js +34 -0
- package/dist/utils/random.js.map +1 -0
- package/dist/utils/resource-utils.d.ts +45 -0
- package/dist/utils/resource-utils.js +137 -0
- package/dist/utils/resource-utils.js.map +1 -0
- package/dist/utils/sanitize-svg.d.ts +18 -0
- package/dist/utils/sanitize-svg.js +38 -0
- package/dist/utils/sanitize-svg.js.map +1 -0
- package/dist/utils/user-preferences.d.ts +64 -0
- package/dist/utils/user-preferences.js +106 -0
- package/dist/utils/user-preferences.js.map +1 -0
- package/dist/utils/validate.d.ts +26 -0
- package/dist/utils/validate.js +53 -0
- package/dist/utils/validate.js.map +1 -0
- package/dist/utils/value-utils.d.ts +58 -0
- package/dist/utils/value-utils.js +181 -0
- package/dist/utils/value-utils.js.map +1 -0
- package/package.json +67 -0
- package/src/card-metadata-updater.ts +182 -0
- package/src/command-handler.ts +686 -0
- package/src/command-manager.ts +99 -0
- package/src/commands/calculate.ts +591 -0
- package/src/commands/create.ts +559 -0
- package/src/commands/edit.ts +123 -0
- package/src/commands/export-site.ts +356 -0
- package/src/commands/export.ts +315 -0
- package/src/commands/import.ts +169 -0
- package/src/commands/index.ts +42 -0
- package/src/commands/move.ts +451 -0
- package/src/commands/remove.ts +244 -0
- package/src/commands/rename.ts +378 -0
- package/src/commands/show.ts +442 -0
- package/src/commands/transition.ts +127 -0
- package/src/commands/update.ts +76 -0
- package/src/commands/validate.ts +962 -0
- package/src/containers/card-container.ts +378 -0
- package/src/containers/project/project-paths.ts +127 -0
- package/src/containers/project/resource-collector.ts +379 -0
- package/src/containers/project.ts +1135 -0
- package/src/containers/template.ts +573 -0
- package/src/exceptions/index.ts +29 -0
- package/src/index.ts +33 -0
- package/src/interfaces/adoc.ts +18 -0
- package/src/interfaces/macros.ts +54 -0
- package/src/interfaces/project-interfaces.ts +208 -0
- package/src/interfaces/request-status-interfaces.ts +30 -0
- package/src/interfaces/resource-interfaces.ts +179 -0
- package/src/macros/base-macro.ts +176 -0
- package/src/macros/common.ts +24 -0
- package/src/macros/createCards/index.ts +57 -0
- package/src/macros/createCards/metadata.ts +21 -0
- package/src/macros/graph/index.ts +130 -0
- package/src/macros/graph/metadata.ts +21 -0
- package/src/macros/index.ts +321 -0
- package/src/macros/report/index.ts +88 -0
- package/src/macros/report/metadata.ts +21 -0
- package/src/macros/scoreCard/index.ts +55 -0
- package/src/macros/scoreCard/metadata.ts +21 -0
- package/src/macros/task-queue.ts +79 -0
- package/src/module-manager.ts +443 -0
- package/src/permissions/action-guard.ts +77 -0
- package/src/project-settings.ts +140 -0
- package/src/resources/array-handler.ts +141 -0
- package/src/resources/card-type-resource.ts +455 -0
- package/src/resources/create-defaults.ts +216 -0
- package/src/resources/field-type-resource.ts +533 -0
- package/src/resources/file-resource.ts +433 -0
- package/src/resources/folder-resource.ts +140 -0
- package/src/resources/graph-model-resource.ts +205 -0
- package/src/resources/graph-view-resource.ts +199 -0
- package/src/resources/link-type-resource.ts +191 -0
- package/src/resources/report-resource.ts +224 -0
- package/src/resources/resource-object.ts +246 -0
- package/src/resources/template-resource.ts +210 -0
- package/src/resources/workflow-resource.ts +205 -0
- package/src/types/queries.ts +149 -0
- package/src/utils/card-utils.ts +83 -0
- package/src/utils/clingo-fact-builder.ts +167 -0
- package/src/utils/clingo-facts.ts +550 -0
- package/src/utils/clingo-parser.ts +519 -0
- package/src/utils/clingo-program-builder.ts +71 -0
- package/src/utils/common-utils.ts +54 -0
- package/src/utils/constants.ts +32 -0
- package/src/utils/csv.ts +53 -0
- package/src/utils/file-utils.ts +182 -0
- package/src/utils/json.ts +118 -0
- package/src/utils/lexorank.ts +180 -0
- package/src/utils/log-utils.ts +127 -0
- package/src/utils/random.ts +37 -0
- package/src/utils/resource-utils.ts +180 -0
- package/src/utils/sanitize-svg.ts +46 -0
- package/src/utils/user-preferences.ts +126 -0
- package/src/utils/validate.ts +66 -0
- package/src/utils/value-utils.ts +189 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
/**
|
|
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
|
+
*/
|
|
13
|
+
|
|
14
|
+
// node
|
|
15
|
+
import { basename, join, resolve, sep } from 'node:path';
|
|
16
|
+
import {
|
|
17
|
+
constants as fsConstants,
|
|
18
|
+
copyFile,
|
|
19
|
+
mkdir,
|
|
20
|
+
writeFile,
|
|
21
|
+
} from 'node:fs/promises';
|
|
22
|
+
|
|
23
|
+
import { type Calculate, Validate } from './index.js';
|
|
24
|
+
import { errorFunction } from '../utils/log-utils.js';
|
|
25
|
+
import { Project } from '../containers/project.js';
|
|
26
|
+
import { EMPTY_RANK, sortItems } from '../utils/lexorank.js';
|
|
27
|
+
import type {
|
|
28
|
+
DataType,
|
|
29
|
+
Link,
|
|
30
|
+
LinkType,
|
|
31
|
+
} from '../interfaces/resource-interfaces.js';
|
|
32
|
+
import { pathExists } from '../utils/file-utils.js';
|
|
33
|
+
import type { Card, ProjectFile } from '../interfaces/project-interfaces.js';
|
|
34
|
+
import { resourceName, resourceNameToString } from '../utils/resource-utils.js';
|
|
35
|
+
import { writeJsonFile } from '../utils/json.js';
|
|
36
|
+
|
|
37
|
+
import { CardTypeResource } from '../resources/card-type-resource.js';
|
|
38
|
+
import { FieldTypeResource } from '../resources/field-type-resource.js';
|
|
39
|
+
import { GraphModelResource } from '../resources/graph-model-resource.js';
|
|
40
|
+
import { GraphViewResource } from '../resources/graph-view-resource.js';
|
|
41
|
+
import { LinkTypeResource } from '../resources/link-type-resource.js';
|
|
42
|
+
import { ReportResource } from '../resources/report-resource.js';
|
|
43
|
+
import { TemplateResource } from '../resources/template-resource.js';
|
|
44
|
+
import { WorkflowResource } from '../resources/workflow-resource.js';
|
|
45
|
+
|
|
46
|
+
// todo: Is there a easy to way to make JSON schema into a TypeScript interface/type?
|
|
47
|
+
// Check this out: https://www.npmjs.com/package/json-schema-to-ts
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Handles all create commands.
|
|
51
|
+
*/
|
|
52
|
+
export class Create {
|
|
53
|
+
constructor(
|
|
54
|
+
private project: Project,
|
|
55
|
+
private calculateCmd: Calculate,
|
|
56
|
+
) {}
|
|
57
|
+
|
|
58
|
+
static JSONFileContent: ProjectFile[] = [
|
|
59
|
+
{
|
|
60
|
+
path: '.cards/local',
|
|
61
|
+
content: [{ id: 'cardsConfigSchema', version: 1 }],
|
|
62
|
+
name: Project.schemaContentFile,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
path: '.cards/local',
|
|
66
|
+
content: {
|
|
67
|
+
cardKeyPrefix: '$PROJECT-PREFIX',
|
|
68
|
+
name: '$PROJECT-NAME',
|
|
69
|
+
modules: [],
|
|
70
|
+
},
|
|
71
|
+
name: Project.projectConfigFileName,
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
static gitIgnoreContent: string = `.calc\n
|
|
76
|
+
.asciidoctor\n
|
|
77
|
+
.vscode\n
|
|
78
|
+
*.html\n
|
|
79
|
+
*.pdf\n
|
|
80
|
+
*.puml\n
|
|
81
|
+
**/.DS_Store\n
|
|
82
|
+
*-debug.log\n
|
|
83
|
+
*-error.log\n`;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Adds new cards to a template.
|
|
87
|
+
* @param cardTypeName Card type for new cards.
|
|
88
|
+
* @param templateName Template name to add cards into.
|
|
89
|
+
* @param card Optional, if defined adds a new child-card under the card.
|
|
90
|
+
* @param count How many cards to add. By default one.
|
|
91
|
+
* @returns non-empty string array with ids of added cards
|
|
92
|
+
*/
|
|
93
|
+
public async addCards(
|
|
94
|
+
cardTypeName: string,
|
|
95
|
+
templateName: string,
|
|
96
|
+
card?: string,
|
|
97
|
+
count: number = 1,
|
|
98
|
+
): Promise<string[]> {
|
|
99
|
+
if (
|
|
100
|
+
!templateName ||
|
|
101
|
+
!Validate.validateFolder(join(this.project.basePath, templateName))
|
|
102
|
+
) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Input validation error: template name is invalid '${templateName}'`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (cardTypeName === undefined) {
|
|
108
|
+
throw new Error(`Input validation error: card type cannot be empty`);
|
|
109
|
+
}
|
|
110
|
+
// Use slice to get a copy of a string.
|
|
111
|
+
const origTemplateName = templateName.slice(0);
|
|
112
|
+
const templateResource = new TemplateResource(
|
|
113
|
+
this.project,
|
|
114
|
+
resourceName(templateName),
|
|
115
|
+
);
|
|
116
|
+
const templateObject = templateResource.templateObject();
|
|
117
|
+
|
|
118
|
+
const specificCard = card
|
|
119
|
+
? await templateObject.findSpecificCard(card)
|
|
120
|
+
: undefined;
|
|
121
|
+
if (card && !specificCard) {
|
|
122
|
+
throw Error(
|
|
123
|
+
`Card '${card}' was not found from template '${origTemplateName}'`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (templateObject.templateFolder().includes(`${sep}modules${sep}`)) {
|
|
128
|
+
throw Error(`Cannot add cards to imported module templates`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Collect all add-card promises and settle them in parallel.
|
|
132
|
+
const promiseContainer = [];
|
|
133
|
+
const cardsContainer: string[] = [];
|
|
134
|
+
for (let cardCount = 0; cardCount < count; ++cardCount) {
|
|
135
|
+
promiseContainer.push(templateObject.addCard(cardTypeName, specificCard));
|
|
136
|
+
}
|
|
137
|
+
const promisesResult = await Promise.allSettled(promiseContainer).then(
|
|
138
|
+
(results) => {
|
|
139
|
+
for (const result of results) {
|
|
140
|
+
if (result.status !== 'fulfilled') {
|
|
141
|
+
throw new Error(result.reason);
|
|
142
|
+
}
|
|
143
|
+
cardsContainer.push(result.value);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
if (cardsContainer.length === 0) {
|
|
149
|
+
throw new Error(`Invalid value for 'repeat:' "${count}"`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (promisesResult === undefined) {
|
|
153
|
+
return cardsContainer;
|
|
154
|
+
} else {
|
|
155
|
+
throw new Error('Unknown error');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Adds an attachment to a card.
|
|
161
|
+
* @param cardKey card ID
|
|
162
|
+
* @param attachment path to an attachment file or attachment name if buffer is defined
|
|
163
|
+
* @param buffer (Optional) attachment buffer
|
|
164
|
+
*/
|
|
165
|
+
public async createAttachment(
|
|
166
|
+
cardKey: string,
|
|
167
|
+
attachment: string,
|
|
168
|
+
buffer?: Buffer,
|
|
169
|
+
) {
|
|
170
|
+
if (!buffer && !pathExists(attachment)) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Input validation error: cannot find attachment '${attachment}'`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
const attachmentFolder = await this.project.cardAttachmentFolder(cardKey);
|
|
176
|
+
if (!attachmentFolder) {
|
|
177
|
+
throw new Error(`Attachment folder for '${cardKey}' not found`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Imported templates cannot be modified.
|
|
181
|
+
if (attachmentFolder.includes(`${sep}modules${sep}`)) {
|
|
182
|
+
throw new Error(`Cannot modify imported module`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await mkdir(attachmentFolder, { recursive: true }).then(async () => {
|
|
187
|
+
if (!buffer) {
|
|
188
|
+
return copyFile(
|
|
189
|
+
attachment,
|
|
190
|
+
join(attachmentFolder, basename(attachment)),
|
|
191
|
+
fsConstants.COPYFILE_EXCL,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
return writeFile(join(attachmentFolder, basename(attachment)), buffer, {
|
|
195
|
+
flag: 'wx',
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
} catch (error) {
|
|
199
|
+
throw new Error(errorFunction(error));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Creates card(s) to a project. All cards from template are instantiated to the project.
|
|
205
|
+
* @param templateName name of a template to use
|
|
206
|
+
* @param parentCardKey (Optional) card-key of a parent card. If missing, cards are added to the card root.
|
|
207
|
+
* @returns array of card keys that were created. Cards are sorted by their parent key and rank. Template root cards are first but the order between other card groups is not guaranteed. However, the order of cards within a group is guaranteed to be ordered by rank.
|
|
208
|
+
*/
|
|
209
|
+
public async createCard(
|
|
210
|
+
templateName: string,
|
|
211
|
+
parentCardKey?: string,
|
|
212
|
+
): Promise<Card[]> {
|
|
213
|
+
const templateResource = new TemplateResource(
|
|
214
|
+
this.project,
|
|
215
|
+
resourceName(templateName),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
await Validate.getInstance().validResourceName(
|
|
219
|
+
'templates',
|
|
220
|
+
resourceNameToString(resourceName(templateName)),
|
|
221
|
+
await this.project.projectPrefixes(),
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
await templateResource.validate();
|
|
225
|
+
|
|
226
|
+
const specificCard = parentCardKey
|
|
227
|
+
? await this.project.findSpecificCard(parentCardKey, {
|
|
228
|
+
metadata: true,
|
|
229
|
+
children: true,
|
|
230
|
+
})
|
|
231
|
+
: undefined;
|
|
232
|
+
if (parentCardKey && !specificCard) {
|
|
233
|
+
throw new Error(`Card '${parentCardKey}' not found from project`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const templateObject = templateResource.templateObject();
|
|
237
|
+
if (!templateObject || !templateObject.isCreated()) {
|
|
238
|
+
throw new Error(`Template '${templateName}' not found from project`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const createdCards = await templateObject.createCards(specificCard);
|
|
242
|
+
if (createdCards.length > 0) {
|
|
243
|
+
await this.calculateCmd.handleNewCards(createdCards);
|
|
244
|
+
// Note: This assumes that parent keys will be ahead of 'a' in the sort order.
|
|
245
|
+
const sorted = sortItems(createdCards, (item) => {
|
|
246
|
+
return `${item.parent === 'root' ? 'a' : item.parent}${item.metadata?.rank || EMPTY_RANK}`;
|
|
247
|
+
});
|
|
248
|
+
return sorted;
|
|
249
|
+
}
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Creates a card type.
|
|
255
|
+
* @param cardTypeName name for the card type.
|
|
256
|
+
* @param workflowName workflow name to use in the card type.
|
|
257
|
+
*/
|
|
258
|
+
public async createCardType(cardTypeName: string, workflowName: string) {
|
|
259
|
+
const cardType = new CardTypeResource(
|
|
260
|
+
this.project,
|
|
261
|
+
resourceName(cardTypeName),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
await cardType.createCardType(workflowName);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Creates a new field type.
|
|
269
|
+
* @param fieldTypeName name for the field type.
|
|
270
|
+
* @param dataType data type for the field type
|
|
271
|
+
*/
|
|
272
|
+
public async createFieldType(fieldTypeName: string, dataType: DataType) {
|
|
273
|
+
const fieldType = new FieldTypeResource(
|
|
274
|
+
this.project,
|
|
275
|
+
resourceName(fieldTypeName),
|
|
276
|
+
);
|
|
277
|
+
await fieldType.createFieldType(dataType);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Creates a new graph model.
|
|
282
|
+
* @param graphModelName name for the graph model.
|
|
283
|
+
*/
|
|
284
|
+
public async createGraphModel(graphModelName: string) {
|
|
285
|
+
const graphModel = new GraphModelResource(
|
|
286
|
+
this.project,
|
|
287
|
+
resourceName(graphModelName),
|
|
288
|
+
);
|
|
289
|
+
await graphModel.create();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Creates a new graph view.
|
|
294
|
+
* @param graphModelName name for the graph view.
|
|
295
|
+
*/
|
|
296
|
+
public async createGraphView(graphViewName: string) {
|
|
297
|
+
const graphView = new GraphViewResource(
|
|
298
|
+
this.project,
|
|
299
|
+
resourceName(graphViewName),
|
|
300
|
+
);
|
|
301
|
+
await graphView.create();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Creates a label in the given card
|
|
306
|
+
* @param cardKey The card to which the label is added to
|
|
307
|
+
* @param label The label being added
|
|
308
|
+
*/
|
|
309
|
+
public async createLabel(cardKey: string, label: string) {
|
|
310
|
+
if (!Validate.isValidLabelName(label)) {
|
|
311
|
+
throw new Error(`Not a valid label name'`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const card = await this.project.findSpecificCard(cardKey, {
|
|
315
|
+
metadata: true,
|
|
316
|
+
});
|
|
317
|
+
if (!card) {
|
|
318
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
319
|
+
}
|
|
320
|
+
const labels = card.metadata?.labels ?? [];
|
|
321
|
+
|
|
322
|
+
if (labels.includes(label)) {
|
|
323
|
+
throw new Error('Label already exists');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
labels.push(label);
|
|
327
|
+
return this.project.updateCardMetadataKey(cardKey, 'labels', labels);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Creates a new link type.
|
|
332
|
+
* @param linkTypeName name for the link type.
|
|
333
|
+
*/
|
|
334
|
+
public async createLinkType(linkTypeName: string) {
|
|
335
|
+
const linkType = new LinkTypeResource(
|
|
336
|
+
this.project,
|
|
337
|
+
resourceName(linkTypeName),
|
|
338
|
+
);
|
|
339
|
+
await linkType.create();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Creates a link between two cards.
|
|
344
|
+
* @param cardKey The card to update
|
|
345
|
+
* @param destinationCardKey The card to link to
|
|
346
|
+
* @param linkType The type of link to add
|
|
347
|
+
* @param linkDescription Optional description of the link
|
|
348
|
+
*/
|
|
349
|
+
public async createLink(
|
|
350
|
+
cardKey: string,
|
|
351
|
+
destinationCardKey: string,
|
|
352
|
+
linkType: string,
|
|
353
|
+
linkDescription?: string,
|
|
354
|
+
) {
|
|
355
|
+
if (cardKey === destinationCardKey) {
|
|
356
|
+
throw new Error('Cannot link card to itself');
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Determine the card path
|
|
360
|
+
const card = await this.project.findSpecificCard(cardKey, {
|
|
361
|
+
metadata: true,
|
|
362
|
+
});
|
|
363
|
+
if (!card) {
|
|
364
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const destinationCard = await this.project.findSpecificCard(
|
|
368
|
+
destinationCardKey,
|
|
369
|
+
{
|
|
370
|
+
metadata: true,
|
|
371
|
+
},
|
|
372
|
+
);
|
|
373
|
+
if (!destinationCard) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
`Card '${destinationCardKey}' does not exist in the project`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
// make sure the link type exists
|
|
379
|
+
const linkTypeObject = await this.project.resource<LinkType>(linkType);
|
|
380
|
+
if (!linkTypeObject) {
|
|
381
|
+
throw new Error(`Link type '${linkType}' does not exist in the project`);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// make sure that if linkDescription is not enabled, linkDescription is not provided
|
|
385
|
+
if (
|
|
386
|
+
!linkTypeObject.enableLinkDescription &&
|
|
387
|
+
linkDescription !== undefined
|
|
388
|
+
) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
`Link type '${linkType}' does not allow link description`,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// make sure source card key exists in the link type sourceCardTypes
|
|
395
|
+
// if sourceCardTypes is empty, any card can be linked
|
|
396
|
+
if (
|
|
397
|
+
linkTypeObject.sourceCardTypes.length > 0 &&
|
|
398
|
+
!linkTypeObject.sourceCardTypes.includes(card.metadata!.cardType)
|
|
399
|
+
) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
`Card type '${card.metadata?.cardType}' cannot be linked with link type '${linkType}'`,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// make sure destination card key exists in the link type destinationCardTypes
|
|
406
|
+
// if destinationCardTypes is empty, any card can be linked
|
|
407
|
+
if (
|
|
408
|
+
linkTypeObject.destinationCardTypes.length > 0 &&
|
|
409
|
+
!linkTypeObject.destinationCardTypes.includes(
|
|
410
|
+
destinationCard.metadata!.cardType,
|
|
411
|
+
)
|
|
412
|
+
) {
|
|
413
|
+
throw new Error(
|
|
414
|
+
`Card type '${destinationCard.metadata!.cardType}' cannot be linked with link type '${linkType}'`,
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// if contains the same link, do not add it again
|
|
419
|
+
const existingLink = card.metadata?.links.find(
|
|
420
|
+
(l) =>
|
|
421
|
+
l.linkType === linkType &&
|
|
422
|
+
l.cardKey === destinationCardKey &&
|
|
423
|
+
l.linkDescription === linkDescription,
|
|
424
|
+
);
|
|
425
|
+
if (existingLink) {
|
|
426
|
+
throw new Error(
|
|
427
|
+
`Link from card '${cardKey}' to card '${destinationCardKey}' already exists`,
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const links: Link[] = card.metadata?.links || [];
|
|
432
|
+
links.push({
|
|
433
|
+
linkType,
|
|
434
|
+
cardKey: destinationCardKey,
|
|
435
|
+
linkDescription,
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
await this.project.updateCardMetadataKey(cardKey, 'links', links);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Creates a new project.
|
|
443
|
+
* @param projectPath where to create the project.
|
|
444
|
+
* @param projectPrefix prefix for the project.
|
|
445
|
+
* @param projectName name for the project.
|
|
446
|
+
*/
|
|
447
|
+
public static async createProject(
|
|
448
|
+
projectPath: string,
|
|
449
|
+
projectPrefix: string,
|
|
450
|
+
projectName: string,
|
|
451
|
+
) {
|
|
452
|
+
projectPath = resolve(projectPath);
|
|
453
|
+
|
|
454
|
+
if (!projectPath) {
|
|
455
|
+
throw new Error('Cannot create project without a path');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const projectFolders: string[] = ['.cards/local', 'cardRoot'];
|
|
459
|
+
|
|
460
|
+
if (
|
|
461
|
+
projectPrefix === undefined ||
|
|
462
|
+
projectPrefix.length < 3 ||
|
|
463
|
+
projectPrefix.length > 10
|
|
464
|
+
) {
|
|
465
|
+
throw new Error(
|
|
466
|
+
`Input validation error: prefix must be from 3 to 10 characters long. '${projectPrefix}' does not fulfill the condition.`,
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
if (!Validate.isValidProjectName(projectName)) {
|
|
470
|
+
throw new Error(
|
|
471
|
+
`Input validation error: invalid project name '${projectName}'`,
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
if (!Validate.validatePrefix(projectPrefix)) {
|
|
475
|
+
throw new Error(
|
|
476
|
+
`Input validation error: invalid prefix '${projectPrefix}'`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (Project.isCreated(projectPath)) {
|
|
481
|
+
throw new Error('Project already exists');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (!Validate.isValidProjectName(projectName)) {
|
|
485
|
+
throw new Error(
|
|
486
|
+
`Input validation error: invalid project name '${projectName}'`,
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
await mkdir(projectPath, { recursive: true }).then(async () => {
|
|
491
|
+
return await Promise.all(
|
|
492
|
+
projectFolders.map((folder) =>
|
|
493
|
+
mkdir(`${projectPath}/${folder}`, { recursive: true }),
|
|
494
|
+
),
|
|
495
|
+
);
|
|
496
|
+
});
|
|
497
|
+
Create.JSONFileContent.forEach(async (entry) => {
|
|
498
|
+
if ('cardKeyPrefix' in entry.content) {
|
|
499
|
+
if (entry.content.cardKeyPrefix.includes('$PROJECT-PREFIX')) {
|
|
500
|
+
entry.content.cardKeyPrefix = projectPrefix.toLowerCase();
|
|
501
|
+
}
|
|
502
|
+
if (entry.content.name.includes('$PROJECT-NAME')) {
|
|
503
|
+
entry.content.name = projectName;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
await writeJsonFile(
|
|
507
|
+
join(projectPath, entry.path, entry.name),
|
|
508
|
+
entry.content,
|
|
509
|
+
);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
try {
|
|
513
|
+
await writeFile(join(projectPath, '.gitignore'), this.gitIgnoreContent);
|
|
514
|
+
} catch {
|
|
515
|
+
console.error('Failed to create project');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Creates a report
|
|
521
|
+
* @param name name of the report
|
|
522
|
+
*/
|
|
523
|
+
public async createReport(name: string) {
|
|
524
|
+
const report = new ReportResource(this.project, resourceName(name));
|
|
525
|
+
await report.createReport();
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Creates a new template to a project.
|
|
530
|
+
* @param templateName Name of the template.
|
|
531
|
+
* @param templateContent JSON content for the template file.
|
|
532
|
+
*/
|
|
533
|
+
public async createTemplate(templateName: string, templateContent: string) {
|
|
534
|
+
const template = new TemplateResource(
|
|
535
|
+
this.project,
|
|
536
|
+
resourceName(templateName),
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
await template.create(
|
|
540
|
+
templateContent ? JSON.parse(templateContent) : undefined,
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Creates a workflow.
|
|
546
|
+
* @param workflowName workflow name
|
|
547
|
+
* @param workflowContent workflow content JSON
|
|
548
|
+
*/
|
|
549
|
+
public async createWorkflow(workflowName: string, workflowContent: string) {
|
|
550
|
+
const workflow = new WorkflowResource(
|
|
551
|
+
this.project,
|
|
552
|
+
resourceName(workflowName),
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
await workflow.create(
|
|
556
|
+
workflowContent ? JSON.parse(workflowContent) : undefined,
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
|
|
6
|
+
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
|
8
|
+
|
|
9
|
+
You should have received a copy of the GNU Affero General Public
|
|
10
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// node
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { homedir } from 'node:os';
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
17
|
+
|
|
18
|
+
import { ActionGuard } from '../permissions/action-guard.js';
|
|
19
|
+
import type { Calculate } from './index.js';
|
|
20
|
+
import type { MetadataContent } from '../interfaces/project-interfaces.js';
|
|
21
|
+
import { Project } from '../containers/project.js';
|
|
22
|
+
import { UserPreferences } from '../utils/user-preferences.js';
|
|
23
|
+
|
|
24
|
+
export class Edit {
|
|
25
|
+
private project: Project;
|
|
26
|
+
private calculateCmd: Calculate;
|
|
27
|
+
|
|
28
|
+
constructor(project: Project, calculateCmd: Calculate) {
|
|
29
|
+
this.project = project;
|
|
30
|
+
this.calculateCmd = calculateCmd;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Opens the content and metadata files for a card in the code editor
|
|
35
|
+
* @param cardKey - The key of the card to open. Required.
|
|
36
|
+
*/
|
|
37
|
+
public async editCard(cardKey: string) {
|
|
38
|
+
// Determine the card path
|
|
39
|
+
const cardPath = this.project.pathToCard(cardKey);
|
|
40
|
+
if (!cardPath) {
|
|
41
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Read the user preferences
|
|
45
|
+
const prefs = new UserPreferences(
|
|
46
|
+
join(homedir(), '.cyberismo', 'cards.prefs.json'),
|
|
47
|
+
).getPreferences();
|
|
48
|
+
|
|
49
|
+
// Construct paths for the card components (json and adoc)
|
|
50
|
+
const cardDirPath = join(this.project.paths.cardRootFolder, cardPath);
|
|
51
|
+
const cardContentPath = join(cardDirPath, Project.cardContentFile);
|
|
52
|
+
const cardJsonPath = join(cardDirPath, Project.cardMetadataFile);
|
|
53
|
+
|
|
54
|
+
// Extract the editor settings from the preferences.
|
|
55
|
+
const editorPrefs = prefs.editCommand[process.platform];
|
|
56
|
+
const editorCommand = editorPrefs.command;
|
|
57
|
+
const editorArgPrefs: string[] = editorPrefs.args; // Coarces the args to string[] for map() below
|
|
58
|
+
|
|
59
|
+
// Poor man's handlebars/moustache replacements
|
|
60
|
+
const editorArgs = editorArgPrefs.map((arg) => {
|
|
61
|
+
arg = arg.replace(/\{\{\s*cardContentPath\s*\}\}/, cardContentPath);
|
|
62
|
+
arg = arg.replace(/\{\{\s*cardJsonPath\s*\}\}/, cardJsonPath);
|
|
63
|
+
arg = arg.replace(/\{\{\s*cardDirPath\s*\}\}/, cardDirPath);
|
|
64
|
+
|
|
65
|
+
return arg;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Execute the editor synchronously and set it to inherit the parent process stdio.
|
|
69
|
+
// This enables terminal editors such as vim to grab the screen I/O
|
|
70
|
+
// from the command line cards process.
|
|
71
|
+
const result = spawnSync(editorCommand, editorArgs, {
|
|
72
|
+
stdio: 'inherit',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (result.status === null) {
|
|
76
|
+
throw new Error(`Cannot launch editor: ${result.error}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Updates card content (index.adoc) with incoming content.
|
|
82
|
+
* @param cardKey The card to update.
|
|
83
|
+
* @param changedContent New content for the card.
|
|
84
|
+
*/
|
|
85
|
+
public async editCardContent(cardKey: string, changedContent: string) {
|
|
86
|
+
// Determine the card path
|
|
87
|
+
const cardPath = this.project.pathToCard(cardKey);
|
|
88
|
+
if (!cardPath) {
|
|
89
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const actionGuard = new ActionGuard(this.calculateCmd);
|
|
93
|
+
await actionGuard.checkPermission('editContent', cardKey);
|
|
94
|
+
|
|
95
|
+
await this.project.updateCardContent(cardKey, changedContent);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Updates card metadata.
|
|
100
|
+
* @param cardKey The card to update
|
|
101
|
+
* @param changedKey Which metadata property was changed
|
|
102
|
+
* @param newValue New value for the metadata property
|
|
103
|
+
*/
|
|
104
|
+
public async editCardMetadata(
|
|
105
|
+
cardKey: string,
|
|
106
|
+
changedKey: string,
|
|
107
|
+
newValue: MetadataContent,
|
|
108
|
+
) {
|
|
109
|
+
// Determine the card path
|
|
110
|
+
const cardPath = this.project.pathToCard(cardKey);
|
|
111
|
+
if (!cardPath) {
|
|
112
|
+
throw new Error(`Card '${cardKey}' does not exist in the project`);
|
|
113
|
+
}
|
|
114
|
+
if (!changedKey) {
|
|
115
|
+
throw new Error(`Changed key cannot be empty`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// check for editing rights
|
|
119
|
+
const actionGuard = new ActionGuard(this.calculateCmd);
|
|
120
|
+
await actionGuard.checkPermission('editField', cardKey, changedKey);
|
|
121
|
+
await this.project.updateCardMetadataKey(cardKey, changedKey, newValue);
|
|
122
|
+
}
|
|
123
|
+
}
|