@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,356 @@
|
|
|
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
|
+
// node
|
|
16
|
+
import fs from 'node:fs';
|
|
17
|
+
import { platform, tmpdir } from 'node:os';
|
|
18
|
+
import { appendFile, copyFile, mkdir, writeFile } from 'node:fs/promises';
|
|
19
|
+
import { mkdtempSync, writeFileSync } from 'node:fs';
|
|
20
|
+
import { dirname, join, resolve } from 'node:path';
|
|
21
|
+
import { spawnSync } from 'node:child_process';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
|
|
24
|
+
import git from 'isomorphic-git';
|
|
25
|
+
import { dump } from 'js-yaml';
|
|
26
|
+
|
|
27
|
+
import { type Calculate, type Show } from './index.js';
|
|
28
|
+
import { Export } from './export.js';
|
|
29
|
+
import type { Card } from '../interfaces/project-interfaces.js';
|
|
30
|
+
import type { CardType } from '../interfaces/resource-interfaces.js';
|
|
31
|
+
import { errorFunction } from '../utils/log-utils.js';
|
|
32
|
+
import type { Project } from '../containers/project.js';
|
|
33
|
+
import { sortItems } from '../utils/lexorank.js';
|
|
34
|
+
import { getStaticDirectoryPath } from '@cyberismo/resources';
|
|
35
|
+
|
|
36
|
+
interface ExportOptions {
|
|
37
|
+
silent: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class ExportSite extends Export {
|
|
41
|
+
private tmpDir: string = '';
|
|
42
|
+
private moduleDir: string = '';
|
|
43
|
+
private pagesDir: string = '';
|
|
44
|
+
private imagesDir: string = '';
|
|
45
|
+
private playbookDir: string = '';
|
|
46
|
+
private playbookFile: string = '';
|
|
47
|
+
private navFile: string = '';
|
|
48
|
+
private options: ExportOptions | undefined;
|
|
49
|
+
|
|
50
|
+
constructor(project: Project, calculateCmd: Calculate, showCmd: Show) {
|
|
51
|
+
super(project, calculateCmd, showCmd);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Writes index.html file into cards folder that just redirects to the first card.
|
|
55
|
+
private createCardsIndex(destination: string, cardKey: string) {
|
|
56
|
+
const indexFile = join(destination, 'cards', 'index.html');
|
|
57
|
+
const indexContent = `<meta http-equiv="refresh" content="0; url=${cardKey}.html">`;
|
|
58
|
+
try {
|
|
59
|
+
fs.writeFileSync(indexFile, indexContent);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
throw new Error(errorFunction(error));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// todo: change this so that split temp folder creation to its own method.
|
|
66
|
+
// then parallelize this and export() as much as you can.
|
|
67
|
+
private async initDirectories() {
|
|
68
|
+
// Create temporary adoc output directory
|
|
69
|
+
try {
|
|
70
|
+
this.tmpDir = mkdtempSync(join(tmpdir(), 'cards-'));
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw new Error(errorFunction(error));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Antora requires the content directory to be a Git repository
|
|
76
|
+
await this.initRepo();
|
|
77
|
+
|
|
78
|
+
// Create the pages and images directories
|
|
79
|
+
this.moduleDir = join(this.tmpDir, 'modules', 'ROOT');
|
|
80
|
+
this.pagesDir = join(this.moduleDir, 'pages');
|
|
81
|
+
this.imagesDir = join(this.moduleDir, 'assets', 'images');
|
|
82
|
+
this.navFile = join(this.moduleDir, 'nav.adoc');
|
|
83
|
+
|
|
84
|
+
const promiseContainer: Promise<string | undefined>[] = [];
|
|
85
|
+
promiseContainer.push(mkdir(this.pagesDir, { recursive: true }));
|
|
86
|
+
promiseContainer.push(mkdir(this.imagesDir, { recursive: true }));
|
|
87
|
+
await Promise.all(promiseContainer);
|
|
88
|
+
|
|
89
|
+
// Create the playbook directory
|
|
90
|
+
this.playbookDir = mkdtempSync(join(tmpdir(), 'cards-playbook-'));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Generate the site from the source files using Antora.
|
|
94
|
+
private generate(outputPath: string) {
|
|
95
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
96
|
+
const __dirname = dirname(__filename);
|
|
97
|
+
|
|
98
|
+
const absoluteOutputPath = resolve(process.cwd(), outputPath);
|
|
99
|
+
|
|
100
|
+
const additionalArguments = [
|
|
101
|
+
'--to-dir',
|
|
102
|
+
absoluteOutputPath,
|
|
103
|
+
this.playbookFile,
|
|
104
|
+
];
|
|
105
|
+
if (this.options && this.options?.silent) {
|
|
106
|
+
additionalArguments.unshift('--silent');
|
|
107
|
+
}
|
|
108
|
+
// Use spawnsync to npx execute the program "antora"
|
|
109
|
+
try {
|
|
110
|
+
// Allthough we use pnpm as the package manager, we rather use npx at runtime, because it is shipped with node
|
|
111
|
+
spawnSync('npx', ['antora', ...additionalArguments], {
|
|
112
|
+
stdio: 'inherit',
|
|
113
|
+
shell: platform() === 'win32',
|
|
114
|
+
cwd: __dirname,
|
|
115
|
+
});
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw new Error(errorFunction(error));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Create the Antora playbook.
|
|
122
|
+
private async createPlaybook(cards: Card[]) {
|
|
123
|
+
let startPage: string = '';
|
|
124
|
+
|
|
125
|
+
if (cards[0]) {
|
|
126
|
+
startPage = cards[0].key + '.adoc';
|
|
127
|
+
} else {
|
|
128
|
+
throw new Error('Cannot create a playbook for an empty card set');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const playbook = {
|
|
132
|
+
site: {
|
|
133
|
+
title: this.project.configuration.name,
|
|
134
|
+
start_page: `cards:ROOT:${startPage}`,
|
|
135
|
+
},
|
|
136
|
+
content: {
|
|
137
|
+
sources: [
|
|
138
|
+
{
|
|
139
|
+
url: this.tmpDir,
|
|
140
|
+
branches: 'HEAD',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
urls: {
|
|
145
|
+
html_extension_style: 'default',
|
|
146
|
+
},
|
|
147
|
+
ui: {
|
|
148
|
+
bundle: {
|
|
149
|
+
url: join(await getStaticDirectoryPath(), 'ui-bundle'),
|
|
150
|
+
snapshot: true,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
this.playbookFile = join(this.playbookDir, 'antora-playbook.yml');
|
|
156
|
+
writeFileSync(this.playbookFile, dump(playbook));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Create the Antora site descriptor.
|
|
160
|
+
private createDescriptor() {
|
|
161
|
+
const projectName = this.project.configuration.name;
|
|
162
|
+
const descriptor = {
|
|
163
|
+
name: 'cards',
|
|
164
|
+
title: projectName,
|
|
165
|
+
version: null,
|
|
166
|
+
nav: ['modules/ROOT/nav.adoc'],
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const descriptorPath = join(this.tmpDir, 'antora.yml');
|
|
170
|
+
try {
|
|
171
|
+
writeFileSync(descriptorPath, dump(descriptor));
|
|
172
|
+
} catch (error) {
|
|
173
|
+
throw new Error(errorFunction(error));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Initialise the temporary directory as a temporary Git repository.
|
|
178
|
+
private async initRepo() {
|
|
179
|
+
try {
|
|
180
|
+
await git.init({ fs, dir: this.tmpDir });
|
|
181
|
+
writeFileSync(join(this.tmpDir, '.gitkeep'), '');
|
|
182
|
+
await git.add({ fs, dir: this.tmpDir, filepath: '.gitkeep' });
|
|
183
|
+
} catch (error) {
|
|
184
|
+
throw new Error(errorFunction(error));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
await git.commit({
|
|
189
|
+
fs,
|
|
190
|
+
dir: this.tmpDir,
|
|
191
|
+
author: {
|
|
192
|
+
name: 'Cyberismo Cards',
|
|
193
|
+
email: 'info@cyberismo.com',
|
|
194
|
+
},
|
|
195
|
+
message: 'Add .gitkeep',
|
|
196
|
+
});
|
|
197
|
+
} catch (error) {
|
|
198
|
+
throw new Error(errorFunction(error));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Write cards as Antora-compatible AsciiDoc to the given location
|
|
203
|
+
// @param path Directory where the cards should be written
|
|
204
|
+
// @param cards Array of Cards
|
|
205
|
+
// @param depth Navigation depth - this is used in recursion to format the hierarchical menu
|
|
206
|
+
private async toAdocDirectoryAsContent(
|
|
207
|
+
path: string,
|
|
208
|
+
cards: Card[],
|
|
209
|
+
depth: number,
|
|
210
|
+
) {
|
|
211
|
+
depth++;
|
|
212
|
+
|
|
213
|
+
// Sort the cards by rank
|
|
214
|
+
cards = sortItems(cards, function (card) {
|
|
215
|
+
return card.metadata?.rank || '1|z';
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Ensure the target path exists
|
|
219
|
+
await mkdir(path, { recursive: true });
|
|
220
|
+
for (const card of cards) {
|
|
221
|
+
// Construct path for individual card file
|
|
222
|
+
const cardPath = join(path, card.key + '.adoc');
|
|
223
|
+
const cardXRef = cardPath.slice(this.pagesDir.length);
|
|
224
|
+
let navFileContent = '';
|
|
225
|
+
if (card.metadata?.progress) {
|
|
226
|
+
navFileContent =
|
|
227
|
+
'*'.repeat(depth) +
|
|
228
|
+
` xref:${cardXRef}[${card.metadata?.title} (${card.metadata?.progress}%)]\n`;
|
|
229
|
+
} else {
|
|
230
|
+
navFileContent =
|
|
231
|
+
'*'.repeat(depth) + ` xref:${cardXRef}[${card.metadata?.title}]\n`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
await appendFile(this.navFile, navFileContent);
|
|
235
|
+
|
|
236
|
+
let tempContent: string = '';
|
|
237
|
+
if (card.metadata) {
|
|
238
|
+
const cardTypeForCard = await this.project.resource<CardType>(
|
|
239
|
+
card.metadata?.cardType,
|
|
240
|
+
);
|
|
241
|
+
tempContent = '\n= ';
|
|
242
|
+
tempContent += card.metadata?.title
|
|
243
|
+
? `${card.metadata.title}\n\n`
|
|
244
|
+
: 'Untitled\n\n';
|
|
245
|
+
tempContent += super.metaToAdoc(card, cardTypeForCard);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (card.content) {
|
|
249
|
+
tempContent += '\n' + card.content;
|
|
250
|
+
}
|
|
251
|
+
if (tempContent !== '') {
|
|
252
|
+
await writeFile(cardPath, tempContent);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (card.children && card.children.length > 0) {
|
|
256
|
+
// Recurse into the child cards
|
|
257
|
+
await this.toAdocDirectoryAsContent(path, card.children, depth);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (card.attachments) {
|
|
261
|
+
const promiseContainer = [];
|
|
262
|
+
for (const attachment of card.attachments) {
|
|
263
|
+
const source = join(attachment.path, attachment.fileName);
|
|
264
|
+
const destination = join(this.imagesDir, `${attachment.fileName}`);
|
|
265
|
+
promiseContainer.push(copyFile(source, destination));
|
|
266
|
+
}
|
|
267
|
+
await Promise.all(promiseContainer);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
--depth;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Export the cards to the temporary directory as a full HTML site generated by Antora.
|
|
275
|
+
private async export(destination: string, cards: Card[]) {
|
|
276
|
+
await this.initDirectories();
|
|
277
|
+
this.createDescriptor();
|
|
278
|
+
await this.toAdocDirectoryAsContent(this.pagesDir, cards, 0);
|
|
279
|
+
await this.createPlaybook(cards);
|
|
280
|
+
this.generate(destination);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Export the card tree as an Antora site
|
|
285
|
+
* @param destination Path where the site is generated
|
|
286
|
+
* @param cardKey Optional; If defined exports the card tree from underneath this card.
|
|
287
|
+
*/
|
|
288
|
+
public async exportToSite(
|
|
289
|
+
destination: string,
|
|
290
|
+
cardKey?: string,
|
|
291
|
+
options?: ExportOptions,
|
|
292
|
+
): Promise<string> {
|
|
293
|
+
this.options = options;
|
|
294
|
+
const sourcePath: string = cardKey
|
|
295
|
+
? join(
|
|
296
|
+
this.project.paths.cardRootFolder,
|
|
297
|
+
this.project.pathToCard(cardKey),
|
|
298
|
+
)
|
|
299
|
+
: this.project.paths.cardRootFolder;
|
|
300
|
+
let cards: Card[] = [];
|
|
301
|
+
|
|
302
|
+
// If doing a partial tree export, put the parent information as it would have already been gathered.
|
|
303
|
+
if (cardKey) {
|
|
304
|
+
const card = await this.project.findSpecificCard(cardKey);
|
|
305
|
+
if (!card) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`Input validation error: cannot find card '${cardKey}'`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
cards.push({
|
|
311
|
+
key: cardKey,
|
|
312
|
+
path: sourcePath,
|
|
313
|
+
children: [],
|
|
314
|
+
attachments: [],
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
await this.calculateCmd.generate();
|
|
319
|
+
const tree = await this.calculateCmd.runQuery('tree');
|
|
320
|
+
|
|
321
|
+
if (cardKey) {
|
|
322
|
+
const targetCard = this.findCardInTree(tree, cardKey);
|
|
323
|
+
if (!targetCard) {
|
|
324
|
+
throw new Error(`Cannot find card '${cardKey}' in the tree hierarchy`);
|
|
325
|
+
}
|
|
326
|
+
cards = [await this.treeQueryResultToCard(targetCard)];
|
|
327
|
+
} else {
|
|
328
|
+
for (const treeQueryResult of tree) {
|
|
329
|
+
cards.push(await this.treeQueryResultToCard(treeQueryResult));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!cards.length) {
|
|
334
|
+
throw new Error('No cards found');
|
|
335
|
+
}
|
|
336
|
+
if (cards.length > 3000) {
|
|
337
|
+
throw new Error(
|
|
338
|
+
`There are ${cards.length} cards in the project. Exporting to a site only supports maximum of 3000 cards.`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
if (cards.length > 1000 && cards.length < 3000) {
|
|
342
|
+
console.warn(
|
|
343
|
+
`Warning: There are ${cards.length} cards in the project. There is a hard limit of 3000 cards that can be exported as a site.`,
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
await this.export(destination, cards);
|
|
348
|
+
if (cards.length > 0 && cards.at(0)) {
|
|
349
|
+
const firstCard = cards.at(0);
|
|
350
|
+
if (firstCard && firstCard.key) {
|
|
351
|
+
this.createCardsIndex(destination, firstCard.key);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return '';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
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
|
+
// node
|
|
16
|
+
import { appendFile, copyFile, mkdir, truncate } from 'node:fs/promises';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
|
|
19
|
+
// asciidoctor
|
|
20
|
+
import Processor from '@asciidoctor/core';
|
|
21
|
+
import type { Calculate, Show } from './index.js';
|
|
22
|
+
import type {
|
|
23
|
+
Card,
|
|
24
|
+
FetchCardDetails,
|
|
25
|
+
} from '../interfaces/project-interfaces.js';
|
|
26
|
+
import type { CardType } from '../interfaces/resource-interfaces.js';
|
|
27
|
+
import { Project } from '../containers/project.js';
|
|
28
|
+
import type { QueryResult } from '../types/queries.js';
|
|
29
|
+
import { sortItems } from '../utils/lexorank.js';
|
|
30
|
+
|
|
31
|
+
const attachmentFolder: string = 'a';
|
|
32
|
+
|
|
33
|
+
export class Export {
|
|
34
|
+
constructor(
|
|
35
|
+
protected project: Project,
|
|
36
|
+
protected calculateCmd: Calculate,
|
|
37
|
+
protected showCmd: Show,
|
|
38
|
+
) {}
|
|
39
|
+
|
|
40
|
+
// This file should set the top level items to the adoc.
|
|
41
|
+
private async toAdocFile(path: string, cards: Card[]) {
|
|
42
|
+
await appendFile(path, `:imagesdir: ./${attachmentFolder}/\n`);
|
|
43
|
+
await this.toAdocFileAsContent(path, cards);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Format card metadata to an AsciiDoc table.
|
|
47
|
+
protected metaToAdoc(card: Card, cardType: CardType | undefined): string {
|
|
48
|
+
let content = '';
|
|
49
|
+
if (card.metadata) {
|
|
50
|
+
content += `[.cyberismo-meta-wrapper]\n`;
|
|
51
|
+
content += '--\n';
|
|
52
|
+
content += `[.cyberismo-meta]\n`;
|
|
53
|
+
content += '[cols="1,1"]\n';
|
|
54
|
+
content += '[frame=none]\n';
|
|
55
|
+
content += '[grid=none]\n';
|
|
56
|
+
content += '|===\n';
|
|
57
|
+
content += `|Card key|${card.key}\n`;
|
|
58
|
+
content += `|Status|${card.metadata.workflowState}\n`;
|
|
59
|
+
content += `|Card type|${card.metadata.cardType}\n`;
|
|
60
|
+
content += `|Labels|${card.metadata.labels?.join(', ') || ''}`;
|
|
61
|
+
|
|
62
|
+
for (const [key, value] of Object.entries(card.metadata)) {
|
|
63
|
+
if (
|
|
64
|
+
cardType?.alwaysVisibleFields.includes(key) ||
|
|
65
|
+
cardType?.optionallyVisibleFields?.includes(key)
|
|
66
|
+
) {
|
|
67
|
+
const displayName = cardType?.customFields.find(
|
|
68
|
+
(item) => item.name === key,
|
|
69
|
+
)?.displayName;
|
|
70
|
+
let nameToShow = displayName
|
|
71
|
+
? displayName
|
|
72
|
+
: key[0].toUpperCase() + key.slice(1);
|
|
73
|
+
if (nameToShow === 'WorkflowState') {
|
|
74
|
+
nameToShow = 'Workflow state';
|
|
75
|
+
} else if (nameToShow === 'Cardtype') {
|
|
76
|
+
nameToShow = 'Card type';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Escape pipe character in cell values
|
|
80
|
+
let escapedValue = 'N/A';
|
|
81
|
+
|
|
82
|
+
if (value) {
|
|
83
|
+
escapedValue = value.toString().replaceAll('|', '\\|');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
content += `|${nameToShow}|${escapedValue}\n`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
content += '|===\n';
|
|
90
|
+
content += '--\n';
|
|
91
|
+
}
|
|
92
|
+
return content;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private async toAdocFileAsContent(path: string, cards: Card[]) {
|
|
96
|
+
for (const card of cards) {
|
|
97
|
+
let fileContent = '';
|
|
98
|
+
|
|
99
|
+
if (card.metadata?.title) {
|
|
100
|
+
fileContent += `== ${card.metadata.title}\n\n`;
|
|
101
|
+
} else {
|
|
102
|
+
fileContent += `== ${card.key}\n\n`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (card.metadata) {
|
|
106
|
+
const cardTypeForCard = await this.project.resource<CardType>(
|
|
107
|
+
card.metadata?.cardType,
|
|
108
|
+
);
|
|
109
|
+
const metaDataContent = this.metaToAdoc(card, cardTypeForCard);
|
|
110
|
+
fileContent += metaDataContent;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (card.content) {
|
|
114
|
+
fileContent += card.content;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (card.attachments) {
|
|
118
|
+
const promiseContainer = [];
|
|
119
|
+
for (const attachment of card.attachments) {
|
|
120
|
+
const destination = join(
|
|
121
|
+
dirname(path),
|
|
122
|
+
attachmentFolder,
|
|
123
|
+
attachment.fileName,
|
|
124
|
+
);
|
|
125
|
+
const source = join(attachment.path, attachment.fileName);
|
|
126
|
+
promiseContainer.push(copyFile(source, destination));
|
|
127
|
+
}
|
|
128
|
+
await Promise.all(promiseContainer);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Add separator between cards
|
|
132
|
+
fileContent += '\n\n';
|
|
133
|
+
|
|
134
|
+
if (fileContent) {
|
|
135
|
+
await appendFile(path, fileContent);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (card.children) {
|
|
139
|
+
await this.toAdocFileAsContent(path, card.children);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Recursively searches for a card with the specified key in the tree hierarchy.
|
|
146
|
+
* @param treeItems Array of tree query results to search through
|
|
147
|
+
* @param targetKey The key of the card to find
|
|
148
|
+
* @returns The found tree item or null if not found
|
|
149
|
+
*/
|
|
150
|
+
protected findCardInTree(
|
|
151
|
+
treeItems: QueryResult<'tree'>[],
|
|
152
|
+
targetKey: string,
|
|
153
|
+
): QueryResult<'tree'> | null {
|
|
154
|
+
for (const item of treeItems) {
|
|
155
|
+
if (item.key === targetKey) {
|
|
156
|
+
return item;
|
|
157
|
+
}
|
|
158
|
+
if (item.children && item.children.length > 0) {
|
|
159
|
+
const foundInChildren = this.findCardInTree(item.children, targetKey);
|
|
160
|
+
if (foundInChildren) {
|
|
161
|
+
return foundInChildren;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Convert treeQueryResult object into a Card object and add content, metadata & attachments
|
|
170
|
+
* Handles card children recursively
|
|
171
|
+
* @param treeQueryResult tree query result object
|
|
172
|
+
*/
|
|
173
|
+
protected async treeQueryResultToCard(
|
|
174
|
+
treeQueryResult: QueryResult<'tree'>,
|
|
175
|
+
): Promise<Card> {
|
|
176
|
+
const card: Card = {
|
|
177
|
+
key: treeQueryResult.key,
|
|
178
|
+
path: '',
|
|
179
|
+
children: [],
|
|
180
|
+
attachments: [],
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Get content and attachments separately, not included in queries
|
|
184
|
+
const fetchCardDetails: FetchCardDetails = {
|
|
185
|
+
attachments: true,
|
|
186
|
+
children: false,
|
|
187
|
+
content: true,
|
|
188
|
+
contentType: 'adoc',
|
|
189
|
+
metadata: true,
|
|
190
|
+
parent: false,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const cardDetailsResponse = await this.showCmd.showCardDetails(
|
|
194
|
+
fetchCardDetails,
|
|
195
|
+
card.key,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
let asciiDocContent = '';
|
|
199
|
+
const projectPath = this.project.basePath;
|
|
200
|
+
try {
|
|
201
|
+
const { evaluateMacros } = await import('../macros/index.js');
|
|
202
|
+
asciiDocContent = await evaluateMacros(
|
|
203
|
+
cardDetailsResponse.content || '',
|
|
204
|
+
{
|
|
205
|
+
mode: 'static',
|
|
206
|
+
projectPath,
|
|
207
|
+
cardKey: card.key,
|
|
208
|
+
},
|
|
209
|
+
);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
asciiDocContent = `Macro error: ${error instanceof Error ? error.message : 'Unknown error'}\n\n${asciiDocContent}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
card.path = cardDetailsResponse.path;
|
|
215
|
+
card.metadata = cardDetailsResponse.metadata;
|
|
216
|
+
card.metadata!.progress = treeQueryResult.progress;
|
|
217
|
+
card.content = asciiDocContent;
|
|
218
|
+
card.attachments = cardDetailsResponse.attachments;
|
|
219
|
+
|
|
220
|
+
for (const result of treeQueryResult.children ?? []) {
|
|
221
|
+
card.children!.push(await this.treeQueryResultToCard(result));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return card;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Exports the card(s) to ascii doc.
|
|
229
|
+
* @param destination Path to where the resulting file(s) will be created.
|
|
230
|
+
* @param cardKey If not exporting the whole card tree, card key of parent card.
|
|
231
|
+
* @returns status message
|
|
232
|
+
*/
|
|
233
|
+
public async exportToADoc(
|
|
234
|
+
destination: string,
|
|
235
|
+
cardKey?: string,
|
|
236
|
+
): Promise<string> {
|
|
237
|
+
const sourcePath: string = this.project.paths.cardRootFolder;
|
|
238
|
+
let cards: Card[] = [];
|
|
239
|
+
|
|
240
|
+
// If doing a partial tree export, put the parent information as it would have already been gathered.
|
|
241
|
+
if (cardKey) {
|
|
242
|
+
const card = await this.project.findSpecificCard(cardKey);
|
|
243
|
+
if (!card) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Input validation error: cannot find card '${cardKey}'`,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
cards.push({
|
|
249
|
+
key: cardKey,
|
|
250
|
+
path: sourcePath,
|
|
251
|
+
children: [],
|
|
252
|
+
attachments: [],
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
await this.calculateCmd.generate();
|
|
257
|
+
const tree = await this.calculateCmd.runQuery('tree');
|
|
258
|
+
|
|
259
|
+
if (cardKey) {
|
|
260
|
+
const targetCard = this.findCardInTree(tree, cardKey);
|
|
261
|
+
if (!targetCard) {
|
|
262
|
+
throw new Error(`Cannot find card '${cardKey}' in the tree hierarchy`);
|
|
263
|
+
}
|
|
264
|
+
cards = [await this.treeQueryResultToCard(targetCard)];
|
|
265
|
+
} else {
|
|
266
|
+
for (const treeQueryResult of tree) {
|
|
267
|
+
cards.push(await this.treeQueryResultToCard(treeQueryResult));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Sort the cards by rank
|
|
272
|
+
cards = sortItems(cards, function (card) {
|
|
273
|
+
return card.metadata?.rank || '1|z';
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
await mkdir(join(destination, attachmentFolder), { recursive: true });
|
|
277
|
+
const resultDocumentPath: string = join(
|
|
278
|
+
destination,
|
|
279
|
+
Project.cardContentFile,
|
|
280
|
+
);
|
|
281
|
+
let message = '';
|
|
282
|
+
try {
|
|
283
|
+
await truncate(resultDocumentPath, 0);
|
|
284
|
+
message = `Using existing output file '${resultDocumentPath}'`;
|
|
285
|
+
} catch {
|
|
286
|
+
message = `Creating output file '${resultDocumentPath}'`;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
await this.toAdocFile(resultDocumentPath, cards);
|
|
290
|
+
return message;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Exports the card(s) to HTML and opens the browser.
|
|
295
|
+
* @param destination Path to where the resulting file(s) will be created.
|
|
296
|
+
* @param cardKey Optional; If not exporting the whole card tree, card key of parent card.
|
|
297
|
+
*/
|
|
298
|
+
public async exportToHTML(
|
|
299
|
+
destination: string,
|
|
300
|
+
cardKey?: string,
|
|
301
|
+
): Promise<string> {
|
|
302
|
+
let message = '';
|
|
303
|
+
await this.exportToADoc(destination, cardKey).then((msg) => {
|
|
304
|
+
message = msg;
|
|
305
|
+
const asciiDocProcessor = Processor();
|
|
306
|
+
const adocFile = join(destination, Project.cardContentFile);
|
|
307
|
+
asciiDocProcessor.convertFile(adocFile, {
|
|
308
|
+
safe: 'safe',
|
|
309
|
+
base_dir: '/',
|
|
310
|
+
standalone: true,
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
return message;
|
|
314
|
+
}
|
|
315
|
+
}
|