@cyberismo/data-handler 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/card-metadata-updater.js +1 -1
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.d.ts +26 -39
- package/dist/command-handler.js +76 -31
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +2 -1
- package/dist/command-manager.js +4 -2
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/calculate.d.ts +7 -0
- package/dist/commands/calculate.js +9 -0
- package/dist/commands/calculate.js.map +1 -1
- package/dist/commands/create.d.ts +5 -0
- package/dist/commands/create.js +15 -8
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/fetch.d.ts +24 -0
- package/dist/commands/fetch.js +118 -0
- package/dist/commands/fetch.js.map +1 -0
- package/dist/commands/import.js +2 -2
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/index.d.ts +2 -1
- package/dist/commands/index.js +2 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/remove.d.ts +1 -0
- package/dist/commands/remove.js +16 -12
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.js +4 -6
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +22 -1
- package/dist/commands/show.js +56 -0
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/update.d.ts +11 -1
- package/dist/commands/update.js +14 -2
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.d.ts +2 -1
- package/dist/commands/validate.js +10 -10
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/card-container.js +1 -1
- package/dist/containers/card-container.js.map +1 -1
- package/dist/containers/project/calculation-engine.d.ts +8 -0
- package/dist/containers/project/calculation-engine.js +21 -10
- package/dist/containers/project/calculation-engine.js.map +1 -1
- package/dist/containers/project.d.ts +19 -8
- package/dist/containers/project.js +52 -34
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.js +1 -1
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/command-options.d.ts +81 -0
- package/dist/interfaces/command-options.js +14 -0
- package/dist/interfaces/command-options.js.map +1 -0
- package/dist/interfaces/folder-content-interfaces.d.ts +50 -0
- package/dist/interfaces/folder-content-interfaces.js +45 -0
- package/dist/interfaces/folder-content-interfaces.js.map +1 -0
- package/dist/interfaces/project-interfaces.d.ts +13 -2
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +28 -10
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/base-macro.d.ts +1 -1
- package/dist/macros/base-macro.js +1 -1
- package/dist/macros/base-macro.js.map +1 -1
- package/dist/macros/createCards/index.d.ts +1 -1
- package/dist/macros/createCards/index.js +1 -1
- package/dist/macros/createCards/index.js.map +1 -1
- package/dist/macros/graph/index.d.ts +1 -1
- package/dist/macros/graph/index.js +21 -29
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/image/index.d.ts +1 -1
- package/dist/macros/image/index.js +1 -7
- package/dist/macros/image/index.js.map +1 -1
- package/dist/macros/include/index.d.ts +1 -1
- package/dist/macros/include/index.js +1 -1
- package/dist/macros/include/index.js.map +1 -1
- package/dist/macros/index.d.ts +12 -5
- package/dist/macros/index.js +19 -7
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/percentage/index.d.ts +1 -1
- package/dist/macros/percentage/index.js +1 -1
- package/dist/macros/percentage/index.js.map +1 -1
- package/dist/macros/report/index.d.ts +1 -1
- package/dist/macros/report/index.js +5 -5
- package/dist/macros/report/index.js.map +1 -1
- package/dist/macros/scoreCard/index.d.ts +1 -1
- package/dist/macros/scoreCard/index.js +1 -1
- package/dist/macros/scoreCard/index.js.map +1 -1
- package/dist/macros/vega/index.d.ts +1 -1
- package/dist/macros/vega/index.js +1 -1
- package/dist/macros/vega/index.js.map +1 -1
- package/dist/macros/vegalite/index.d.ts +1 -1
- package/dist/macros/vegalite/index.js +1 -1
- package/dist/macros/vegalite/index.js.map +1 -1
- package/dist/macros/xref/index.d.ts +1 -1
- package/dist/macros/xref/index.js +1 -1
- package/dist/macros/xref/index.js.map +1 -1
- package/dist/project-settings.d.ts +14 -1
- package/dist/project-settings.js +51 -1
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/card-type-resource.js +11 -5
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +5 -0
- package/dist/resources/field-type-resource.js +9 -4
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +37 -9
- package/dist/resources/folder-resource.js +108 -12
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.d.ts +7 -4
- package/dist/resources/graph-model-resource.js +12 -25
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.d.ts +7 -4
- package/dist/resources/graph-view-resource.js +15 -31
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/link-type-resource.js +1 -1
- package/dist/resources/link-type-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +14 -10
- package/dist/resources/report-resource.js +41 -45
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +7 -0
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.d.ts +5 -1
- package/dist/resources/template-resource.js +12 -7
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.js +12 -5
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/utils/log-utils.js +1 -1
- package/dist/utils/log-utils.js.map +1 -1
- package/dist/utils/report.js +6 -0
- package/dist/utils/report.js.map +1 -1
- package/dist/utils/resource-utils.d.ts +8 -0
- package/dist/utils/resource-utils.js +11 -0
- package/dist/utils/resource-utils.js.map +1 -1
- package/package.json +11 -11
- package/src/card-metadata-updater.ts +1 -1
- package/src/command-handler.ts +129 -61
- package/src/command-manager.ts +4 -1
- package/src/commands/calculate.ts +18 -0
- package/src/commands/create.ts +31 -19
- package/src/commands/fetch.ts +152 -0
- package/src/commands/import.ts +2 -0
- package/src/commands/index.ts +2 -0
- package/src/commands/remove.ts +18 -12
- package/src/commands/rename.ts +11 -11
- package/src/commands/show.ts +72 -0
- package/src/commands/update.ts +20 -2
- package/src/commands/validate.ts +13 -10
- package/src/containers/card-container.ts +1 -1
- package/src/containers/project/calculation-engine.ts +27 -11
- package/src/containers/project.ts +71 -61
- package/src/containers/template.ts +1 -1
- package/src/index.ts +36 -2
- package/src/interfaces/command-options.ts +144 -0
- package/src/interfaces/folder-content-interfaces.ts +69 -0
- package/src/interfaces/project-interfaces.ts +18 -0
- package/src/interfaces/resource-interfaces.ts +41 -12
- package/src/macros/base-macro.ts +5 -2
- package/src/macros/createCards/index.ts +1 -1
- package/src/macros/graph/index.ts +47 -51
- package/src/macros/image/index.ts +1 -7
- package/src/macros/include/index.ts +1 -1
- package/src/macros/index.ts +19 -7
- package/src/macros/percentage/index.ts +1 -1
- package/src/macros/report/index.ts +5 -5
- package/src/macros/scoreCard/index.ts +1 -1
- package/src/macros/vega/index.ts +1 -1
- package/src/macros/vegalite/index.ts +1 -1
- package/src/macros/xref/index.ts +1 -1
- package/src/project-settings.ts +62 -1
- package/src/resources/card-type-resource.ts +12 -6
- package/src/resources/field-type-resource.ts +9 -4
- package/src/resources/folder-resource.ts +149 -19
- package/src/resources/graph-model-resource.ts +16 -27
- package/src/resources/graph-view-resource.ts +23 -33
- package/src/resources/link-type-resource.ts +1 -1
- package/src/resources/report-resource.ts +60 -62
- package/src/resources/resource-object.ts +11 -0
- package/src/resources/template-resource.ts +12 -7
- package/src/resources/workflow-resource.ts +11 -6
- package/src/utils/log-utils.ts +1 -1
- package/src/utils/report.ts +6 -0
- package/src/utils/resource-utils.ts +16 -0
|
@@ -164,6 +164,7 @@ export interface ProjectMetadata {
|
|
|
164
164
|
path: string;
|
|
165
165
|
prefix: string;
|
|
166
166
|
modules: string[];
|
|
167
|
+
hubs: HubSetting[];
|
|
167
168
|
numberOfCards: number;
|
|
168
169
|
}
|
|
169
170
|
|
|
@@ -172,6 +173,20 @@ export interface ProjectSettings {
|
|
|
172
173
|
cardKeyPrefix: string;
|
|
173
174
|
name: string;
|
|
174
175
|
modules: ModuleSetting[];
|
|
176
|
+
hubs: HubSetting[];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Hub configuration
|
|
180
|
+
export interface HubSetting {
|
|
181
|
+
location: string;
|
|
182
|
+
description?: string;
|
|
183
|
+
displayName?: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Module configuration for a hub.
|
|
187
|
+
export interface ModuleSettingFromHub extends ModuleSetting {
|
|
188
|
+
documentationLocation: string;
|
|
189
|
+
displayName: string;
|
|
175
190
|
}
|
|
176
191
|
|
|
177
192
|
// Module configuration.
|
|
@@ -195,6 +210,7 @@ export type RemovableResourceTypes =
|
|
|
195
210
|
| 'fieldType'
|
|
196
211
|
| 'graphModel'
|
|
197
212
|
| 'graphView'
|
|
213
|
+
| 'hub'
|
|
198
214
|
| 'link'
|
|
199
215
|
| 'linkType'
|
|
200
216
|
| 'module'
|
|
@@ -229,6 +245,8 @@ export type ResourceTypes =
|
|
|
229
245
|
| 'attachments'
|
|
230
246
|
| 'calculation'
|
|
231
247
|
| 'cards'
|
|
248
|
+
| 'hubs'
|
|
249
|
+
| 'importableModules'
|
|
232
250
|
| 'label'
|
|
233
251
|
| 'labels'
|
|
234
252
|
| 'links'
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
GraphModelContent,
|
|
16
|
+
GraphViewContent,
|
|
17
|
+
ReportContent,
|
|
18
|
+
} from './folder-content-interfaces.js';
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Each resource represents a file (or a folder in some cases) with metadata stored
|
|
@@ -32,6 +36,12 @@ export interface CardType extends ResourceBaseMetadata {
|
|
|
32
36
|
optionallyVisibleFields: string[];
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
// Base content update key interface
|
|
40
|
+
export interface ContentUpdateKey {
|
|
41
|
+
key: 'content';
|
|
42
|
+
subKey: string; // Resource-specific types should narrow this
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
// Custom field
|
|
36
46
|
// todo: merge with FieldType.
|
|
37
47
|
export interface CustomField {
|
|
@@ -71,19 +81,29 @@ export interface FieldType extends ResourceBaseMetadata {
|
|
|
71
81
|
export interface GraphModelMetadata extends ResourceBaseMetadata {
|
|
72
82
|
category?: string;
|
|
73
83
|
}
|
|
74
|
-
|
|
75
84
|
export interface GraphModel extends GraphModelMetadata {
|
|
76
|
-
|
|
85
|
+
content: GraphModelContent;
|
|
77
86
|
}
|
|
87
|
+
export type GraphModelContentPropertyName = 'model';
|
|
88
|
+
export interface GraphModelContentUpdateKey {
|
|
89
|
+
key: 'content';
|
|
90
|
+
subKey: GraphModelContentPropertyName;
|
|
91
|
+
}
|
|
92
|
+
export type GraphModelUpdateKey = string | GraphModelContentUpdateKey;
|
|
78
93
|
|
|
79
94
|
// Graph view content.
|
|
80
95
|
export interface GraphViewMetadata extends ResourceBaseMetadata {
|
|
81
96
|
category?: string;
|
|
82
97
|
}
|
|
83
|
-
|
|
98
|
+
export type GraphViewContentPropertyName = 'viewTemplate';
|
|
84
99
|
export interface GraphView extends GraphViewMetadata {
|
|
85
|
-
|
|
100
|
+
content: GraphViewContent;
|
|
86
101
|
}
|
|
102
|
+
export interface GraphViewContentUpdateKey {
|
|
103
|
+
key: 'content';
|
|
104
|
+
subKey: GraphViewContentPropertyName;
|
|
105
|
+
}
|
|
106
|
+
export type GraphViewUpdateKey = string | GraphViewContentUpdateKey;
|
|
87
107
|
|
|
88
108
|
// Link content.
|
|
89
109
|
export interface Link {
|
|
@@ -103,13 +123,20 @@ export interface LinkType extends ResourceBaseMetadata {
|
|
|
103
123
|
|
|
104
124
|
// Report resource.
|
|
105
125
|
export interface Report extends ResourceBaseMetadata {
|
|
106
|
-
|
|
107
|
-
metadata: ReportMetadata;
|
|
108
|
-
contentTemplate: string;
|
|
109
|
-
queryTemplate: string;
|
|
110
|
-
schema?: Schema;
|
|
126
|
+
content: ReportContent;
|
|
111
127
|
}
|
|
112
128
|
|
|
129
|
+
// Resource-specific content names
|
|
130
|
+
export type ReportContentPropertyName =
|
|
131
|
+
| 'contentTemplate'
|
|
132
|
+
| 'queryTemplate'
|
|
133
|
+
| 'schema';
|
|
134
|
+
export interface ReportContentUpdateKey {
|
|
135
|
+
key: 'content';
|
|
136
|
+
subKey: ReportContentPropertyName;
|
|
137
|
+
}
|
|
138
|
+
export type ReportUpdateKey = string | ReportContentUpdateKey;
|
|
139
|
+
|
|
113
140
|
// Metadata for report
|
|
114
141
|
export interface ReportMetadata extends ResourceBaseMetadata {
|
|
115
142
|
category: string;
|
|
@@ -136,10 +163,9 @@ export type ResourceContent =
|
|
|
136
163
|
| Workflow;
|
|
137
164
|
|
|
138
165
|
// Template configuration details.
|
|
139
|
-
export interface TemplateConfiguration extends
|
|
166
|
+
export interface TemplateConfiguration extends TemplateMetadata {
|
|
140
167
|
path: string;
|
|
141
168
|
numberOfCards: number;
|
|
142
|
-
metadata: TemplateMetadata;
|
|
143
169
|
}
|
|
144
170
|
|
|
145
171
|
// Template configuration content details.
|
|
@@ -147,6 +173,9 @@ export interface TemplateMetadata extends ResourceBaseMetadata {
|
|
|
147
173
|
category?: string;
|
|
148
174
|
}
|
|
149
175
|
|
|
176
|
+
// Generic update key
|
|
177
|
+
export type UpdateKey = string | ContentUpdateKey;
|
|
178
|
+
|
|
150
179
|
// Workflow's json file content.
|
|
151
180
|
export interface Workflow extends ResourceBaseMetadata {
|
|
152
181
|
states: WorkflowState[];
|
package/src/macros/base-macro.ts
CHANGED
|
@@ -63,7 +63,10 @@ abstract class BaseMacro {
|
|
|
63
63
|
input: unknown,
|
|
64
64
|
): Promise<string>;
|
|
65
65
|
|
|
66
|
-
protected abstract handleValidate(
|
|
66
|
+
protected abstract handleValidate(
|
|
67
|
+
context: MacroGenerationContext,
|
|
68
|
+
input: unknown,
|
|
69
|
+
): void;
|
|
67
70
|
|
|
68
71
|
public get metadata() {
|
|
69
72
|
return this.macroMetadata;
|
|
@@ -127,7 +130,7 @@ abstract class BaseMacro {
|
|
|
127
130
|
|
|
128
131
|
if (context.mode === 'validate') {
|
|
129
132
|
try {
|
|
130
|
-
this.handleValidate(JSON.parse(input));
|
|
133
|
+
this.handleValidate(context, JSON.parse(input));
|
|
131
134
|
} catch (error) {
|
|
132
135
|
if (error instanceof Error) {
|
|
133
136
|
const errorMessage = `From card '${context.cardKey}' a macro validation error:\n\n${error.message}.\n\nCard content:\n ${input}`;
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
import BaseMacro from '../base-macro.js';
|
|
15
15
|
import { createImage, validateMacroContent } from '../index.js';
|
|
16
16
|
import Handlebars from 'handlebars';
|
|
17
|
-
import { join } from 'node:path';
|
|
18
17
|
import type { MacroGenerationContext } from '../../interfaces/macros.js';
|
|
19
18
|
import macroMetadata from './metadata.js';
|
|
20
19
|
import { pathExists } from '../../utils/file-utils.js';
|
|
21
20
|
import { readFile } from 'node:fs/promises';
|
|
22
|
-
import {
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
23
22
|
import type { Schema } from 'jsonschema';
|
|
24
|
-
import { validateJson } from '../../utils/validate.js';
|
|
25
23
|
import type TaskQueue from '../task-queue.js';
|
|
26
24
|
import { ClingoError } from '@cyberismo/node-clingo';
|
|
25
|
+
import { resourceFilePath } from '../../utils/resource-utils.js';
|
|
26
|
+
import { resourceName } from '../../utils/resource-utils.js';
|
|
27
27
|
|
|
28
28
|
export interface GraphOptions {
|
|
29
29
|
model: string;
|
|
@@ -35,55 +35,23 @@ class ReportMacro extends BaseMacro {
|
|
|
35
35
|
super(macroMetadata, tasksQueue);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
handleValidate = (input: unknown) => {
|
|
39
|
-
this.parseOptions(input);
|
|
38
|
+
handleValidate = (context: MacroGenerationContext, input: unknown) => {
|
|
39
|
+
this.parseOptions(input, context);
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
handleStatic = async (context: MacroGenerationContext, input: unknown) => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
prefix,
|
|
56
|
-
type,
|
|
57
|
-
identifier,
|
|
58
|
-
fileName,
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const options = this.parseOptions(input);
|
|
63
|
-
|
|
64
|
-
let schema: Schema | null = null;
|
|
65
|
-
try {
|
|
66
|
-
schema = JSON.parse(
|
|
67
|
-
await readFile(
|
|
68
|
-
resourceNameToPath(options.view, 'parameterSchema.json'),
|
|
69
|
-
{ encoding: 'utf-8' },
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
} catch (err) {
|
|
73
|
-
this.logger.trace(
|
|
74
|
-
err,
|
|
75
|
-
'Graph schema not found or failed to read, skipping validation',
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (schema) {
|
|
80
|
-
validateJson(options, {
|
|
81
|
-
schema,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const modelLocation = resourceNameToPath(options.model, 'model.lp');
|
|
86
|
-
const viewLocation = resourceNameToPath(options.view, 'view.lp.hbs');
|
|
43
|
+
const options = this.parseOptions(input, context);
|
|
44
|
+
|
|
45
|
+
const modelLocation = resourceFilePath(
|
|
46
|
+
context.project,
|
|
47
|
+
resourceName(options.model),
|
|
48
|
+
'model.lp',
|
|
49
|
+
);
|
|
50
|
+
const viewLocation = resourceFilePath(
|
|
51
|
+
context.project,
|
|
52
|
+
resourceName(options.view),
|
|
53
|
+
'view.lp.hbs',
|
|
54
|
+
);
|
|
87
55
|
|
|
88
56
|
if (!pathExists(modelLocation)) {
|
|
89
57
|
throw new Error(`Graph: Model ${options.model} does not exist`);
|
|
@@ -128,8 +96,36 @@ class ReportMacro extends BaseMacro {
|
|
|
128
96
|
return createImage(result);
|
|
129
97
|
};
|
|
130
98
|
|
|
131
|
-
private parseOptions(
|
|
132
|
-
|
|
99
|
+
private parseOptions(
|
|
100
|
+
input: unknown,
|
|
101
|
+
context: MacroGenerationContext,
|
|
102
|
+
): GraphOptions {
|
|
103
|
+
const options = validateMacroContent<GraphOptions>(this.metadata, input);
|
|
104
|
+
|
|
105
|
+
let schema: Schema | null = null;
|
|
106
|
+
try {
|
|
107
|
+
schema = JSON.parse(
|
|
108
|
+
readFileSync(
|
|
109
|
+
resourceFilePath(
|
|
110
|
+
context.project,
|
|
111
|
+
resourceName(options.view),
|
|
112
|
+
'parameterSchema.json',
|
|
113
|
+
),
|
|
114
|
+
{ encoding: 'utf-8' },
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
this.logger.trace(
|
|
119
|
+
err,
|
|
120
|
+
'Graph schema not found or failed to read, skipping validation',
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (schema) {
|
|
125
|
+
validateMacroContent(this.metadata, input, schema);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return options;
|
|
133
129
|
}
|
|
134
130
|
}
|
|
135
131
|
|
|
@@ -44,7 +44,7 @@ export default class ImageMacro extends BaseMacro {
|
|
|
44
44
|
super(macroMetadata, tasksQueue);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
handleValidate = (input: unknown) => {
|
|
47
|
+
handleValidate = (_: MacroGenerationContext, input: unknown) => {
|
|
48
48
|
this.validate(input);
|
|
49
49
|
};
|
|
50
50
|
|
|
@@ -58,9 +58,6 @@ export default class ImageMacro extends BaseMacro {
|
|
|
58
58
|
// Get the attachment folder path
|
|
59
59
|
const attachmentFolder =
|
|
60
60
|
await context.project.cardAttachmentFolder(cardKey);
|
|
61
|
-
if (!attachmentFolder) {
|
|
62
|
-
throw new Error(`Card '${cardKey}' not found`);
|
|
63
|
-
}
|
|
64
61
|
|
|
65
62
|
// Read the file and convert to base64
|
|
66
63
|
const attachmentPath = join(attachmentFolder, options.fileName);
|
|
@@ -90,9 +87,6 @@ export default class ImageMacro extends BaseMacro {
|
|
|
90
87
|
// Verify that the card and attachment folder exist
|
|
91
88
|
const attachmentFolder =
|
|
92
89
|
await context.project.cardAttachmentFolder(cardKey);
|
|
93
|
-
if (!attachmentFolder) {
|
|
94
|
-
throw new Error(`Card '${cardKey}' not found`);
|
|
95
|
-
}
|
|
96
90
|
|
|
97
91
|
const attachmentPath = join(attachmentFolder, options.fileName);
|
|
98
92
|
if (!existsSync(attachmentPath)) {
|
package/src/macros/index.ts
CHANGED
|
@@ -153,6 +153,7 @@ export const macros: {
|
|
|
153
153
|
* Validates the content inside a macro
|
|
154
154
|
* @param macro - The macro to validate the content of
|
|
155
155
|
* @param data - The data to validate
|
|
156
|
+
* @param schema - Schema to use in validation
|
|
156
157
|
* @returns The validated data
|
|
157
158
|
*/
|
|
158
159
|
export function validateMacroContent<T>(
|
|
@@ -180,7 +181,10 @@ export function validateMacroContent<T>(
|
|
|
180
181
|
|
|
181
182
|
/**
|
|
182
183
|
* Registers the macros with Handlebars
|
|
183
|
-
* @param
|
|
184
|
+
* @param instance - Handlebar instance
|
|
185
|
+
* @param context - The context for macro generation
|
|
186
|
+
* @param tasks - Tasks to register
|
|
187
|
+
* @returns macro instances
|
|
184
188
|
*/
|
|
185
189
|
export function registerMacros(
|
|
186
190
|
instance: typeof Handlebars,
|
|
@@ -201,7 +205,8 @@ export function registerMacros(
|
|
|
201
205
|
}
|
|
202
206
|
/**
|
|
203
207
|
* Calculate amount of handlebars templates inside a string
|
|
204
|
-
* @param input
|
|
208
|
+
* @param input - String to calculate templates from
|
|
209
|
+
* @returns number of macros
|
|
205
210
|
*/
|
|
206
211
|
export function macroCount(input: string): number {
|
|
207
212
|
const regex = /{{#[\w\s-]+?}}/g;
|
|
@@ -224,11 +229,11 @@ export function registerEmptyMacros(instance: typeof Handlebars) {
|
|
|
224
229
|
}
|
|
225
230
|
|
|
226
231
|
/**
|
|
227
|
-
* Handle the macros in the content
|
|
232
|
+
* Handle the macros in the content.
|
|
228
233
|
* @param content - The content to handle the macros in
|
|
229
234
|
* @param context - The context for macro generation
|
|
230
|
-
* @param calculate - The calculate function
|
|
231
235
|
* @param preserveRawBlocks - If true, don't unescape raw blocks at the end (for nested evaluations)
|
|
236
|
+
* @returns macro result
|
|
232
237
|
*/
|
|
233
238
|
export async function evaluateMacros(
|
|
234
239
|
content: string,
|
|
@@ -240,7 +245,7 @@ export async function evaluateMacros(
|
|
|
240
245
|
registerMacros(handlebars, context, tasks);
|
|
241
246
|
let result = content;
|
|
242
247
|
while ((context.maxTries ?? 10) > 0) {
|
|
243
|
-
tasks.reset();
|
|
248
|
+
await tasks.reset();
|
|
244
249
|
try {
|
|
245
250
|
const compiled = handlebars.compile(preprocessRawBlocks(result), {
|
|
246
251
|
strict: true,
|
|
@@ -313,6 +318,7 @@ export function applyMacroResults(
|
|
|
313
318
|
* Handles errors that come when handling macros
|
|
314
319
|
* @param error - The error that was thrown
|
|
315
320
|
* @param macro - The macro that caused the error
|
|
321
|
+
* @param context - General context for the macro evaluation process
|
|
316
322
|
* @returns The error message that is valid adoc
|
|
317
323
|
*/
|
|
318
324
|
export function handleMacroError(
|
|
@@ -350,9 +356,14 @@ export function handleMacroError(
|
|
|
350
356
|
}
|
|
351
357
|
|
|
352
358
|
// This is used to generate unique keys for macros
|
|
353
|
-
// There might be a better way to do this
|
|
359
|
+
// TODO: There might be a better way to do this
|
|
354
360
|
let macroCounter = 0;
|
|
355
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Converts object to base64
|
|
364
|
+
* @param obj Object to convert
|
|
365
|
+
* @returns base64 conversion (as a Buffer)
|
|
366
|
+
*/
|
|
356
367
|
function objectToBase64(obj: unknown): string {
|
|
357
368
|
return Buffer.from(JSON.stringify(obj), 'utf-8').toString('base64');
|
|
358
369
|
}
|
|
@@ -393,8 +404,9 @@ export function createCodeBlock(content: string) {
|
|
|
393
404
|
}
|
|
394
405
|
|
|
395
406
|
/**
|
|
396
|
-
* Helper function for including base64 encoded images
|
|
407
|
+
* Helper function for including base64 encoded images
|
|
397
408
|
* @param image base64 encoded image
|
|
409
|
+
* @param controls Add controls
|
|
398
410
|
* @returns valid asciidoc with the image
|
|
399
411
|
*/
|
|
400
412
|
export function createImage(image: string, controls: boolean = true) {
|
|
@@ -30,7 +30,7 @@ class PercentageMacro extends BaseMacro {
|
|
|
30
30
|
constructor(tasksQueue: TaskQueue) {
|
|
31
31
|
super(macroMetadata, tasksQueue);
|
|
32
32
|
}
|
|
33
|
-
handleValidate = (data: string) => {
|
|
33
|
+
handleValidate = (_: MacroGenerationContext, data: string) => {
|
|
34
34
|
this.validate(data);
|
|
35
35
|
};
|
|
36
36
|
|
|
@@ -31,7 +31,7 @@ class ReportMacro extends BaseMacro {
|
|
|
31
31
|
constructor(tasks: TaskQueue) {
|
|
32
32
|
super(macroMetadata, tasks);
|
|
33
33
|
}
|
|
34
|
-
handleValidate = (input: unknown) => {
|
|
34
|
+
handleValidate = (_: MacroGenerationContext, input: unknown) => {
|
|
35
35
|
this.validate(input);
|
|
36
36
|
};
|
|
37
37
|
|
|
@@ -45,16 +45,16 @@ class ReportMacro extends BaseMacro {
|
|
|
45
45
|
|
|
46
46
|
if (!report) throw new Error(`Report ${options.name} does not exist`);
|
|
47
47
|
|
|
48
|
-
if (report.schema) {
|
|
48
|
+
if (report.content.schema) {
|
|
49
49
|
validateJson(options, {
|
|
50
|
-
schema: report.schema,
|
|
50
|
+
schema: report.content.schema,
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
return await generateReportContent({
|
|
55
55
|
calculate: context.project.calculationEngine,
|
|
56
|
-
contentTemplate: report.contentTemplate,
|
|
57
|
-
queryTemplate: report.queryTemplate,
|
|
56
|
+
contentTemplate: report.content.contentTemplate,
|
|
57
|
+
queryTemplate: report.content.queryTemplate,
|
|
58
58
|
options: {
|
|
59
59
|
cardKey: context.cardKey,
|
|
60
60
|
...options,
|
|
@@ -31,7 +31,7 @@ class ScoreCardMacro extends BaseMacro {
|
|
|
31
31
|
constructor(tasksQueue: TaskQueue) {
|
|
32
32
|
super(macroMetadata, tasksQueue);
|
|
33
33
|
}
|
|
34
|
-
handleValidate = (data: string) => {
|
|
34
|
+
handleValidate = (_: MacroGenerationContext, data: string) => {
|
|
35
35
|
this.validate(data);
|
|
36
36
|
};
|
|
37
37
|
|
package/src/macros/vega/index.ts
CHANGED
package/src/macros/xref/index.ts
CHANGED
package/src/project-settings.ts
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
|
|
14
14
|
import { writeJsonFile as atomicWrite } from 'write-json-file';
|
|
15
15
|
|
|
16
|
-
import { resolve } from 'path';
|
|
16
|
+
import { resolve } from 'node:path';
|
|
17
|
+
import { URL } from 'node:url';
|
|
17
18
|
|
|
18
19
|
import type {
|
|
20
|
+
HubSetting,
|
|
19
21
|
ModuleSetting,
|
|
20
22
|
ProjectSettings,
|
|
21
23
|
} from './interfaces/project-interfaces.js';
|
|
@@ -31,6 +33,7 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
31
33
|
name: string;
|
|
32
34
|
cardKeyPrefix: string;
|
|
33
35
|
modules: ModuleSetting[];
|
|
36
|
+
hubs: HubSetting[];
|
|
34
37
|
private settingPath: string;
|
|
35
38
|
|
|
36
39
|
constructor(path: string) {
|
|
@@ -38,6 +41,7 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
38
41
|
this.settingPath = path;
|
|
39
42
|
this.cardKeyPrefix = '';
|
|
40
43
|
this.modules = [];
|
|
44
|
+
this.hubs = [];
|
|
41
45
|
this.readSettings();
|
|
42
46
|
}
|
|
43
47
|
|
|
@@ -70,6 +74,7 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
70
74
|
this.cardKeyPrefix = settings.cardKeyPrefix;
|
|
71
75
|
this.name = settings.name;
|
|
72
76
|
this.modules = settings.modules || [];
|
|
77
|
+
this.hubs = settings.hubs || [];
|
|
73
78
|
} else {
|
|
74
79
|
throw new Error(`Invalid configuration file '${this.settingPath}'`);
|
|
75
80
|
}
|
|
@@ -81,9 +86,51 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
81
86
|
cardKeyPrefix: this.cardKeyPrefix,
|
|
82
87
|
name: this.name,
|
|
83
88
|
modules: this.modules,
|
|
89
|
+
hubs: this.hubs,
|
|
84
90
|
};
|
|
85
91
|
}
|
|
86
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Adds a new hub.
|
|
95
|
+
* @param hubName URL of the hub to add
|
|
96
|
+
* @throws if hub is already in the project or URL is invalid
|
|
97
|
+
*/
|
|
98
|
+
public async addHub(hubName: string) {
|
|
99
|
+
const trimmedHub = hubName?.trim();
|
|
100
|
+
if (!trimmedHub) {
|
|
101
|
+
throw new Error(`Cannot add empty hub to the project`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const exists = this.hubs.find((item) => item.location === trimmedHub);
|
|
105
|
+
if (exists) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Hub '${trimmedHub}' already exists as a hub for the project`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const hubUrl = new URL(trimmedHub);
|
|
113
|
+
if (!['http:', 'https:'].includes(hubUrl.protocol)) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Invalid URL protocol '${hubUrl.protocol}'. Only HTTP and HTTPS protocols are supported for hubs.`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
if (!hubUrl.hostname) {
|
|
119
|
+
throw new Error('Hub URL must have a valid hostname.');
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error instanceof TypeError) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Invalid hub URL '${trimmedHub}'. Please provide a valid HTTP or HTTPS URL.`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.hubs.push({ location: trimmedHub });
|
|
131
|
+
return this.save();
|
|
132
|
+
}
|
|
133
|
+
|
|
87
134
|
/**
|
|
88
135
|
* Adds new module to imported modules property.
|
|
89
136
|
* @param module Module to add as dependency
|
|
@@ -105,6 +152,20 @@ export class ProjectConfiguration implements ProjectSettings {
|
|
|
105
152
|
return this.save();
|
|
106
153
|
}
|
|
107
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Removes a hub.
|
|
157
|
+
* @param hubName Name of the hub to remove.
|
|
158
|
+
* @throws if hub is not part of the project
|
|
159
|
+
*/
|
|
160
|
+
public async removeHub(hubName: string) {
|
|
161
|
+
const exists = this.hubs.find((item) => item.location === hubName);
|
|
162
|
+
if (!exists) {
|
|
163
|
+
throw new Error(`Hub '${hubName}' not part of the project`);
|
|
164
|
+
}
|
|
165
|
+
this.hubs = this.hubs.filter((item) => item.location !== hubName);
|
|
166
|
+
return this.save();
|
|
167
|
+
}
|
|
168
|
+
|
|
108
169
|
/**
|
|
109
170
|
* Removes module from imported modules property.
|
|
110
171
|
* @param moduleName Name of the module to remove.
|
|
@@ -233,7 +233,10 @@ export class CardTypeResource extends FileResource {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
// If value from 'customFields' is removed, remove it also from 'optionallyVisible' and 'alwaysVisible' arrays.
|
|
236
|
-
private removeValueFromOtherArrays<Type>(
|
|
236
|
+
private removeValueFromOtherArrays<Type>(
|
|
237
|
+
op: Operation<Type>,
|
|
238
|
+
content: CardType,
|
|
239
|
+
) {
|
|
237
240
|
// Update target can be a string, or an object. Of object, fetch only 'name'
|
|
238
241
|
// todo: fetching 'name' or using string as name could be function in resource base class.
|
|
239
242
|
const target = (op as RemoveOperation<Type>).target as Type;
|
|
@@ -242,8 +245,8 @@ export class CardTypeResource extends FileResource {
|
|
|
242
245
|
field = { name: target['name' as keyof Type] };
|
|
243
246
|
}
|
|
244
247
|
const fieldName = (field ? field.name : target) as string;
|
|
245
|
-
this.removeValue(
|
|
246
|
-
this.removeValue(
|
|
248
|
+
this.removeValue(content.alwaysVisibleFields, fieldName);
|
|
249
|
+
this.removeValue(content.optionallyVisibleFields, fieldName);
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
// Sets content container values to be either '[]' or with proper values.
|
|
@@ -481,7 +484,7 @@ export class CardTypeResource extends FileResource {
|
|
|
481
484
|
const existingName = this.content.name;
|
|
482
485
|
await super.update(key, op);
|
|
483
486
|
|
|
484
|
-
const content = this.content as CardType;
|
|
487
|
+
const content = structuredClone(this.content) as CardType;
|
|
485
488
|
if (key === 'name') {
|
|
486
489
|
content.name = super.handleScalar(op) as string;
|
|
487
490
|
} else if (key === 'alwaysVisibleFields') {
|
|
@@ -513,12 +516,15 @@ export class CardTypeResource extends FileResource {
|
|
|
513
516
|
content.customFields as Type[],
|
|
514
517
|
) as CustomField[];
|
|
515
518
|
if (op.name === 'remove') {
|
|
516
|
-
this.removeValueFromOtherArrays(op);
|
|
519
|
+
this.removeValueFromOtherArrays(op, content);
|
|
517
520
|
}
|
|
521
|
+
} else if (key === 'description') {
|
|
522
|
+
content.description = super.handleScalar(op) as string;
|
|
523
|
+
} else if (key === 'displayName') {
|
|
524
|
+
content.displayName = super.handleScalar(op) as string;
|
|
518
525
|
} else {
|
|
519
526
|
throw new Error(`Unknown property '${key}' for CardType`);
|
|
520
527
|
}
|
|
521
|
-
|
|
522
528
|
await super.postUpdate(content, key, op);
|
|
523
529
|
|
|
524
530
|
// Renaming this card type causes that references to its name must be updated.
|