@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,224 @@
|
|
|
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
|
|
6
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
7
|
+
the Free Software Foundation. This program is distributed in the hope that it
|
|
8
|
+
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
9
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
See the GNU Affero General Public License for more details.
|
|
11
|
+
You should have received a copy of the GNU Affero General Public
|
|
12
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { extname, join } from 'node:path';
|
|
18
|
+
|
|
19
|
+
import { copyDir } from '../utils/file-utils.js';
|
|
20
|
+
import type {
|
|
21
|
+
Card,
|
|
22
|
+
Operation,
|
|
23
|
+
Project,
|
|
24
|
+
ResourceName,
|
|
25
|
+
} from './folder-resource.js';
|
|
26
|
+
import {
|
|
27
|
+
DefaultContent,
|
|
28
|
+
FolderResource,
|
|
29
|
+
resourceNameToString,
|
|
30
|
+
sortCards,
|
|
31
|
+
} from './folder-resource.js';
|
|
32
|
+
import type {
|
|
33
|
+
Report,
|
|
34
|
+
ReportMetadata,
|
|
35
|
+
} from '../interfaces/resource-interfaces.js';
|
|
36
|
+
import type { Schema } from 'jsonschema';
|
|
37
|
+
import { getStaticDirectoryPath } from '@cyberismo/resources';
|
|
38
|
+
|
|
39
|
+
const CARD_CONTENT_HANDLEBAR_FILE = 'index.adoc.hbs';
|
|
40
|
+
const QUERY_HANDLEBAR_FILE = 'query.lp.hbs';
|
|
41
|
+
const REPORT_SCHEMA_FILE = 'parameterSchema.json';
|
|
42
|
+
|
|
43
|
+
const staticDirectoryPath = await getStaticDirectoryPath();
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Report resource class.
|
|
47
|
+
*/
|
|
48
|
+
export class ReportResource extends FolderResource {
|
|
49
|
+
private reportSchema: Schema;
|
|
50
|
+
constructor(project: Project, name: ResourceName) {
|
|
51
|
+
super(project, name, 'reports');
|
|
52
|
+
|
|
53
|
+
this.contentSchemaId = 'reportSchema';
|
|
54
|
+
this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
|
|
55
|
+
|
|
56
|
+
this.initialize();
|
|
57
|
+
|
|
58
|
+
const schemaPath = join(this.internalFolder, REPORT_SCHEMA_FILE);
|
|
59
|
+
this.reportSchema = this.readSchemaFile(schemaPath);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Path to content folder.
|
|
63
|
+
// @todo: create the files' content dynamically.
|
|
64
|
+
private defaultReportLocation: string = join(
|
|
65
|
+
staticDirectoryPath,
|
|
66
|
+
'defaultReport',
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// When resource name changes.
|
|
70
|
+
private async handleNameChange(existingName: string) {
|
|
71
|
+
await Promise.all([
|
|
72
|
+
super.updateHandleBars(
|
|
73
|
+
existingName,
|
|
74
|
+
this.content.name,
|
|
75
|
+
await this.handleBarFiles(),
|
|
76
|
+
),
|
|
77
|
+
super.updateCalculations(existingName, this.content.name),
|
|
78
|
+
]);
|
|
79
|
+
// Finally, write updated content.
|
|
80
|
+
await this.write();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Try to read schema file content
|
|
84
|
+
private readSchemaFile(path: string) {
|
|
85
|
+
try {
|
|
86
|
+
const schema = readFileSync(path);
|
|
87
|
+
return JSON.parse(schema.toString());
|
|
88
|
+
} catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Sets new metadata into the report object.
|
|
95
|
+
* @param newContent metadata content for the report.
|
|
96
|
+
* @throws if 'newContent' is not valid.
|
|
97
|
+
*/
|
|
98
|
+
public async createReport() {
|
|
99
|
+
const defaultContent = DefaultContent.report(
|
|
100
|
+
resourceNameToString(this.resourceName),
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
await super.create(defaultContent);
|
|
104
|
+
|
|
105
|
+
// Copy report default structure to destination.
|
|
106
|
+
await copyDir(this.defaultReportLocation, this.internalFolder);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Returns resource content.
|
|
111
|
+
*/
|
|
112
|
+
public get data(): ReportMetadata {
|
|
113
|
+
return super.data as ReportMetadata;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Deletes file and folder that this resource is based on.
|
|
118
|
+
*/
|
|
119
|
+
public async delete() {
|
|
120
|
+
return super.delete();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns list of handlebar filenames that this report has.
|
|
125
|
+
* @returns list of handlebar filenames that this report has.
|
|
126
|
+
*/
|
|
127
|
+
public async handleBarFiles() {
|
|
128
|
+
return (
|
|
129
|
+
await readdir(this.internalFolder, {
|
|
130
|
+
withFileTypes: true,
|
|
131
|
+
recursive: true,
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
.filter((dirent) => dirent.isFile() && extname(dirent.name) === '.hbs')
|
|
135
|
+
.map((item) => join(item.parentPath, item.name));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Renames the object and the file.
|
|
140
|
+
* @param newName New name for the resource.
|
|
141
|
+
*/
|
|
142
|
+
public async rename(newName: ResourceName) {
|
|
143
|
+
const existingName = this.content.name;
|
|
144
|
+
await super.rename(newName);
|
|
145
|
+
return this.handleNameChange(existingName);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Shows metadata of the resource.
|
|
150
|
+
* @returns report metadata.
|
|
151
|
+
*/
|
|
152
|
+
public async show(): Promise<Report> {
|
|
153
|
+
const reportMetadata = (await super.show()) as ReportMetadata;
|
|
154
|
+
return {
|
|
155
|
+
name: resourceNameToString(this.resourceName),
|
|
156
|
+
metadata: reportMetadata,
|
|
157
|
+
contentTemplate: (
|
|
158
|
+
await readFile(join(this.internalFolder, CARD_CONTENT_HANDLEBAR_FILE))
|
|
159
|
+
).toString(),
|
|
160
|
+
queryTemplate: (
|
|
161
|
+
await readFile(join(this.internalFolder, QUERY_HANDLEBAR_FILE))
|
|
162
|
+
).toString(),
|
|
163
|
+
schema: this.reportSchema,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Updates report resource.
|
|
169
|
+
* @param key Key to modify
|
|
170
|
+
* @param op Operation to perform on 'key'
|
|
171
|
+
* @throws if key is unknown.
|
|
172
|
+
*/
|
|
173
|
+
public async update<Type>(key: string, op: Operation<Type>) {
|
|
174
|
+
const nameChange = key === 'name';
|
|
175
|
+
const existingName = this.content.name;
|
|
176
|
+
|
|
177
|
+
await super.update(key, op);
|
|
178
|
+
|
|
179
|
+
const content = { ...(this.content as ReportMetadata) };
|
|
180
|
+
|
|
181
|
+
if (key === 'name') {
|
|
182
|
+
content.name = super.handleScalar(op) as string;
|
|
183
|
+
} else if (key === 'displayName') {
|
|
184
|
+
content.displayName = super.handleScalar(op) as string;
|
|
185
|
+
} else if (key === 'description') {
|
|
186
|
+
content.description = super.handleScalar(op) as string;
|
|
187
|
+
} else if (key === 'category') {
|
|
188
|
+
content.category = super.handleScalar(op) as string;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
await super.postUpdate(content, key, op);
|
|
192
|
+
|
|
193
|
+
// Renaming this report causes that references to its name must be updated.
|
|
194
|
+
if (nameChange) {
|
|
195
|
+
await this.handleNameChange(existingName);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* List where this resource is used.
|
|
201
|
+
* Always returns card key references first, then calculation references.
|
|
202
|
+
*
|
|
203
|
+
* @param cards Optional. Check these cards for usage of this resource. If undefined, will check all cards.
|
|
204
|
+
* @returns array of card keys and calculation filenames that refer this resource.
|
|
205
|
+
*/
|
|
206
|
+
public async usage(cards?: Card[]): Promise<string[]> {
|
|
207
|
+
const allCards = cards ?? (await super.cards());
|
|
208
|
+
const [relevantCards, calculations] = await Promise.all([
|
|
209
|
+
super.usage(allCards),
|
|
210
|
+
super.calculations(),
|
|
211
|
+
]);
|
|
212
|
+
return [...relevantCards.sort(sortCards), ...calculations];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Validates report.
|
|
217
|
+
* @throws when there are validation errors.
|
|
218
|
+
* @param content Content to be validated.
|
|
219
|
+
* @note If content is not provided, base class validation will use resource's current content.
|
|
220
|
+
*/
|
|
221
|
+
public async validate(content?: object) {
|
|
222
|
+
return super.validate(content);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
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
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
14
|
+
|
|
15
|
+
// node
|
|
16
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
17
|
+
import { basename, join } from 'node:path';
|
|
18
|
+
|
|
19
|
+
import { ArrayHandler } from './array-handler.js';
|
|
20
|
+
import type {
|
|
21
|
+
Card,
|
|
22
|
+
ResourceFolderType,
|
|
23
|
+
} from '../interfaces/project-interfaces.js';
|
|
24
|
+
import { type Project, ResourcesFrom } from '../containers/project.js';
|
|
25
|
+
import type { ResourceContent } from '../interfaces/resource-interfaces.js';
|
|
26
|
+
import type { ResourceName } from '../utils/resource-utils.js';
|
|
27
|
+
|
|
28
|
+
// Possible operations to perform when doing "update"
|
|
29
|
+
export type UpdateOperations = 'add' | 'change' | 'rank' | 'remove';
|
|
30
|
+
//| 'elementTypeChange';
|
|
31
|
+
|
|
32
|
+
// Base class for update operations.
|
|
33
|
+
type BaseOperation<T> = {
|
|
34
|
+
name: 'add' | 'change' | 'rank' | 'remove';
|
|
35
|
+
target: T;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Add item to an array.
|
|
39
|
+
export type AddOperation<T> = BaseOperation<T> & {
|
|
40
|
+
name: 'add';
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Change item in an array or property in an object or rename a scalar.
|
|
44
|
+
export type ChangeOperation<T> = BaseOperation<T> & {
|
|
45
|
+
name: 'change';
|
|
46
|
+
to: T;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Move item in an array to new position.
|
|
50
|
+
export type RankOperation<T> = BaseOperation<T> & {
|
|
51
|
+
name: 'rank';
|
|
52
|
+
newIndex: number;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Remove item from an array.
|
|
56
|
+
export type RemoveOperation<T> = BaseOperation<T> & {
|
|
57
|
+
name: 'remove';
|
|
58
|
+
replacementValue?: T;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type Operation<T> =
|
|
62
|
+
| AddOperation<T>
|
|
63
|
+
| ChangeOperation<T>
|
|
64
|
+
| RankOperation<T>
|
|
65
|
+
| RemoveOperation<T>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Abstract class for resources.
|
|
69
|
+
*/
|
|
70
|
+
export abstract class AbstractResource {
|
|
71
|
+
protected abstract calculate(): Promise<void>; // update resource specific calculations
|
|
72
|
+
protected abstract create(content?: ResourceContent): Promise<void>; // create a new with the content (memory)
|
|
73
|
+
protected abstract delete(): Promise<void>; // delete from disk
|
|
74
|
+
protected abstract read(): Promise<void>; // read content from disk (replaces existing content, if any)
|
|
75
|
+
protected abstract rename(newName: ResourceName): Promise<void>; // change name of the resource and filename; same as update('name', ...)
|
|
76
|
+
protected abstract show(): Promise<ResourceContent>; // return the content as JSON
|
|
77
|
+
protected abstract update<Type>(
|
|
78
|
+
key: string,
|
|
79
|
+
operation: Operation<Type>,
|
|
80
|
+
): Promise<void>; // change one key of resource
|
|
81
|
+
protected abstract usage(cards?: Card[]): Promise<string[]>; // list of card keys or resource names where this resource is used in
|
|
82
|
+
protected abstract validate(content?: object): Promise<void>; // validate the content
|
|
83
|
+
protected abstract write(): Promise<void>; // write content to disk
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Base class for all resources.
|
|
88
|
+
*/
|
|
89
|
+
export class ResourceObject extends AbstractResource {
|
|
90
|
+
protected moduleResource: boolean;
|
|
91
|
+
protected contentSchema: JSON = {} as JSON;
|
|
92
|
+
protected contentSchemaId: string = '';
|
|
93
|
+
protected type: ResourceFolderType = '' as ResourceFolderType;
|
|
94
|
+
protected resourceFolder: string = '';
|
|
95
|
+
|
|
96
|
+
constructor(
|
|
97
|
+
protected project: Project,
|
|
98
|
+
protected resourceName: ResourceName,
|
|
99
|
+
) {
|
|
100
|
+
super();
|
|
101
|
+
this.moduleResource =
|
|
102
|
+
this.resourceName.prefix !== this.project.projectPrefix;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected async calculate() {}
|
|
106
|
+
protected async create(_content?: ResourceContent) {}
|
|
107
|
+
protected async delete() {}
|
|
108
|
+
protected async read() {}
|
|
109
|
+
protected async rename(_name: ResourceName) {}
|
|
110
|
+
protected async show(): Promise<ResourceContent> {
|
|
111
|
+
return {} as ResourceContent;
|
|
112
|
+
}
|
|
113
|
+
protected async update<Type>(_key: string, _op: Operation<Type>) {}
|
|
114
|
+
protected async usage(_cards?: Card[]): Promise<string[]> {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
protected async validate(_content?: object) {}
|
|
118
|
+
protected async write() {}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Returns .schema content file.
|
|
122
|
+
* @param schemaId schema id
|
|
123
|
+
* @returns .schema content.
|
|
124
|
+
*/
|
|
125
|
+
protected contentSchemaContent(schemaId: string): JSON {
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
id: schemaId,
|
|
129
|
+
version: 1,
|
|
130
|
+
},
|
|
131
|
+
] as unknown as JSON;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Handles operation to an array.
|
|
136
|
+
* @param operation Operation to perform on array.
|
|
137
|
+
* @param arrayName Name of the array, for error messages.
|
|
138
|
+
* @param array Array to be updated.
|
|
139
|
+
* @returns Changed array after the operation.
|
|
140
|
+
*/
|
|
141
|
+
protected handleArray<Type>(
|
|
142
|
+
operation: Operation<Type>,
|
|
143
|
+
arrayName: string,
|
|
144
|
+
array: Type[],
|
|
145
|
+
): Type[] {
|
|
146
|
+
const handler = new ArrayHandler<Type>();
|
|
147
|
+
let result: Type[] = [];
|
|
148
|
+
try {
|
|
149
|
+
result = handler.handleArray(operation, array);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (error instanceof Error) {
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Cannot perform operation on '${arrayName}'. ${error.message}`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Updates scalar value. The only accepted operation is 'change'
|
|
162
|
+
* @param operation Operation to perform on scalar.
|
|
163
|
+
* @returns What the scalar should be changed to.
|
|
164
|
+
*/
|
|
165
|
+
protected handleScalar<Type>(operation: Operation<Type>): Type {
|
|
166
|
+
if (
|
|
167
|
+
operation.name === 'add' ||
|
|
168
|
+
operation.name === 'rank' ||
|
|
169
|
+
operation.name === 'remove'
|
|
170
|
+
) {
|
|
171
|
+
throw new Error(`Cannot do operation ${operation.name} on scalar value`);
|
|
172
|
+
}
|
|
173
|
+
return (operation as ChangeOperation<Type>).to;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Update calculation files.
|
|
178
|
+
* @param from Resource name to update
|
|
179
|
+
* @param to New name for resource
|
|
180
|
+
*/
|
|
181
|
+
protected async updateCalculations(from: string, to: string) {
|
|
182
|
+
if (!from.trim() || !to.trim()) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
'updateCalculations: "from" and "to" parameters must not be empty',
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const calculations = await this.project.calculations(
|
|
189
|
+
ResourcesFrom.localOnly,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
await Promise.all(
|
|
193
|
+
calculations.map(async (calculation) => {
|
|
194
|
+
if (!calculation.path) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`Calculation file's '${calculation.name}' path is not defined`,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const filename = join(calculation.path, basename(calculation.name));
|
|
201
|
+
try {
|
|
202
|
+
const content = await readFile(filename, 'utf-8');
|
|
203
|
+
const updatedContent = content.replaceAll(from, to);
|
|
204
|
+
await writeFile(filename, updatedContent);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Failed to process file ${filename}: ${(error as Error).message}`,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}),
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Update references in handlebars.
|
|
216
|
+
* @param from Resource name to update
|
|
217
|
+
* @param to New name for resource
|
|
218
|
+
* @param handleBarFiles Optional. List of handlebar files. If omitted, affects all handlebar files in the project.
|
|
219
|
+
*/
|
|
220
|
+
protected async updateHandleBars(
|
|
221
|
+
from: string,
|
|
222
|
+
to: string,
|
|
223
|
+
handleBarFiles?: string[],
|
|
224
|
+
) {
|
|
225
|
+
if (!from.trim() || !to.trim()) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
'updateHandleBars: "from" and "to" parameters must not be empty',
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (!handleBarFiles) {
|
|
232
|
+
handleBarFiles = await this.project.reportHandlerBarFiles(
|
|
233
|
+
ResourcesFrom.localOnly,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Process all files in parallel.
|
|
238
|
+
await Promise.all(
|
|
239
|
+
handleBarFiles.map(async (handleBarFile) => {
|
|
240
|
+
const content = await readFile(handleBarFile);
|
|
241
|
+
const updatedContent = content.toString().replaceAll(from, to);
|
|
242
|
+
await writeFile(handleBarFile, Buffer.from(updatedContent));
|
|
243
|
+
}),
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
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
|
|
6
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
7
|
+
the Free Software Foundation. This program is distributed in the hope that it
|
|
8
|
+
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
9
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
See the GNU Affero General Public License for more details.
|
|
11
|
+
You should have received a copy of the GNU Affero General Public
|
|
12
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { basename, dirname, join } from 'node:path';
|
|
16
|
+
import { mkdir } from 'node:fs/promises';
|
|
17
|
+
|
|
18
|
+
import type {
|
|
19
|
+
Card,
|
|
20
|
+
Operation,
|
|
21
|
+
Project,
|
|
22
|
+
ResourceName,
|
|
23
|
+
} from './folder-resource.js';
|
|
24
|
+
import {
|
|
25
|
+
DefaultContent,
|
|
26
|
+
FolderResource,
|
|
27
|
+
resourceNameToString,
|
|
28
|
+
sortCards,
|
|
29
|
+
} from './folder-resource.js';
|
|
30
|
+
import type {
|
|
31
|
+
TemplateConfiguration,
|
|
32
|
+
TemplateMetadata,
|
|
33
|
+
} from '../interfaces/resource-interfaces.js';
|
|
34
|
+
import { Template } from '../containers/template.js';
|
|
35
|
+
import { writeJsonFile } from '../utils/json.js';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Template resource class.
|
|
39
|
+
*/
|
|
40
|
+
export class TemplateResource extends FolderResource {
|
|
41
|
+
private cardContainer: Template;
|
|
42
|
+
private cardsFolder = '';
|
|
43
|
+
private cardsSchema = super.contentSchemaContent('cardBaseSchema');
|
|
44
|
+
|
|
45
|
+
constructor(project: Project, name: ResourceName) {
|
|
46
|
+
super(project, name, 'templates');
|
|
47
|
+
|
|
48
|
+
this.contentSchemaId = 'templateSchema';
|
|
49
|
+
this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
|
|
50
|
+
|
|
51
|
+
this.initialize();
|
|
52
|
+
this.cardsFolder = join(this.internalFolder, 'c');
|
|
53
|
+
|
|
54
|
+
// Each template resource contains a template card container (with template cards).
|
|
55
|
+
this.cardContainer = new Template(this.project, {
|
|
56
|
+
name: basename(this.fileName),
|
|
57
|
+
path: dirname(this.fileName),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// When resource name changes.
|
|
62
|
+
private async handleNameChange(existingName: string) {
|
|
63
|
+
await Promise.all([
|
|
64
|
+
super.updateHandleBars(existingName, this.content.name),
|
|
65
|
+
super.updateCalculations(existingName, this.content.name),
|
|
66
|
+
]);
|
|
67
|
+
// Finally, write updated content.
|
|
68
|
+
await this.write();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Sets new metadata into the template object.
|
|
73
|
+
* @param newContent metadata content for the template.
|
|
74
|
+
* @throws if 'newContent' is not valid.
|
|
75
|
+
*/
|
|
76
|
+
public async create(newContent?: TemplateMetadata) {
|
|
77
|
+
if (!newContent) {
|
|
78
|
+
newContent = DefaultContent.template(
|
|
79
|
+
resourceNameToString(this.resourceName),
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
82
|
+
await this.validate(newContent);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return super.create(newContent);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns content data.
|
|
90
|
+
*/
|
|
91
|
+
public get data(): TemplateMetadata {
|
|
92
|
+
return super.data as TemplateMetadata;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Deletes file and folder that this resource is based on.
|
|
97
|
+
*/
|
|
98
|
+
public async delete() {
|
|
99
|
+
return super.delete();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Renames the object and the file.
|
|
104
|
+
* @param newName New name for the resource.
|
|
105
|
+
*/
|
|
106
|
+
public async rename(newName: ResourceName) {
|
|
107
|
+
const existingName = this.content.name;
|
|
108
|
+
await super.rename(newName);
|
|
109
|
+
return this.handleNameChange(existingName);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Shows metadata of the resource.
|
|
114
|
+
* @returns template metadata.
|
|
115
|
+
*/
|
|
116
|
+
public async show(): Promise<TemplateConfiguration> {
|
|
117
|
+
const templateMetadata = (await super.show()) as TemplateMetadata;
|
|
118
|
+
const container = this.templateObject();
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
metadata: templateMetadata,
|
|
122
|
+
name: resourceNameToString(this.resourceName),
|
|
123
|
+
path: this.fileName,
|
|
124
|
+
numberOfCards: (await container.listCards()).length,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Returns template card container object.
|
|
130
|
+
* @returns template container object
|
|
131
|
+
*/
|
|
132
|
+
public templateObject(): Template {
|
|
133
|
+
return this.cardContainer;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Updates template resource.
|
|
138
|
+
* @param key Key to modify
|
|
139
|
+
* @param op Operation to perform on 'key'
|
|
140
|
+
* @throws if key is unknown.
|
|
141
|
+
*/
|
|
142
|
+
public async update<Type>(key: string, op: Operation<Type>) {
|
|
143
|
+
const nameChange = key === 'name';
|
|
144
|
+
const existingName = this.content.name;
|
|
145
|
+
|
|
146
|
+
await super.update(key, op);
|
|
147
|
+
|
|
148
|
+
const content = { ...(this.content as TemplateMetadata) };
|
|
149
|
+
|
|
150
|
+
if (key === 'name') {
|
|
151
|
+
content.name = super.handleScalar(op) as string;
|
|
152
|
+
} else if (key === 'displayName') {
|
|
153
|
+
content.displayName = super.handleScalar(op) as string;
|
|
154
|
+
} else if (key === 'description') {
|
|
155
|
+
content.description = super.handleScalar(op) as string;
|
|
156
|
+
} else if (key === 'category') {
|
|
157
|
+
content.category = super.handleScalar(op) as string;
|
|
158
|
+
} else {
|
|
159
|
+
throw new Error(`Unknown property '${key}' for Template`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await super.postUpdate(content, key, op);
|
|
163
|
+
|
|
164
|
+
// Renaming this template causes that references to its name must be updated.
|
|
165
|
+
if (nameChange) {
|
|
166
|
+
await this.handleNameChange(existingName);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* List where template is used.
|
|
172
|
+
* Always returns card key references first, then calculation references.
|
|
173
|
+
*
|
|
174
|
+
* @param cards Optional. Check these cards for usage of this resource. If undefined, will check all cards.
|
|
175
|
+
* @returns array of card keys, and calculation filenames that refer this resource.
|
|
176
|
+
*/
|
|
177
|
+
public async usage(cards?: Card[]): Promise<string[]> {
|
|
178
|
+
const allCards = cards ?? (await super.cards());
|
|
179
|
+
const [relevantCards, calculations] = await Promise.all([
|
|
180
|
+
super.usage(allCards),
|
|
181
|
+
super.calculations(),
|
|
182
|
+
]);
|
|
183
|
+
return [...relevantCards.sort(sortCards), ...calculations];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Validates template.
|
|
188
|
+
* @throws when there are validation errors.
|
|
189
|
+
* @param content Content to be validated.
|
|
190
|
+
* @note If content is not provided, base class validation will use resource's current content.
|
|
191
|
+
*/
|
|
192
|
+
public async validate(content?: object) {
|
|
193
|
+
return super.validate(content);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Create the template's cards folder.
|
|
198
|
+
*/
|
|
199
|
+
public async write() {
|
|
200
|
+
await super.write();
|
|
201
|
+
this.cardsFolder = join(this.internalFolder, 'c');
|
|
202
|
+
|
|
203
|
+
// Create folder for cards and put proper content schema file there
|
|
204
|
+
const schemaContentFile = join(this.cardsFolder, '.schema');
|
|
205
|
+
await mkdir(this.cardsFolder, { recursive: true });
|
|
206
|
+
await writeJsonFile(schemaContentFile, this.cardsSchema, {
|
|
207
|
+
flag: 'wx',
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|