@cyberismo/data-handler 0.0.5 → 0.0.7
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/README.md +1 -0
- package/dist/card-metadata-updater.d.ts +1 -0
- package/dist/card-metadata-updater.js +7 -2
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.d.ts +6 -1
- package/dist/command-handler.js +16 -15
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +15 -4
- package/dist/command-manager.js +41 -9
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/calculate.d.ts +4 -10
- package/dist/commands/calculate.js +67 -78
- package/dist/commands/calculate.js.map +1 -1
- package/dist/commands/export.js +3 -3
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +3 -8
- package/dist/commands/import.js +10 -14
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/index.d.ts +1 -2
- package/dist/commands/index.js +1 -2
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/show.d.ts +6 -3
- package/dist/commands/show.js +8 -5
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.js +6 -4
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/project/project-content-watcher.d.ts +28 -0
- package/dist/containers/project/project-content-watcher.js +54 -0
- package/dist/containers/project/project-content-watcher.js.map +1 -0
- package/dist/containers/project/project-paths.js +1 -1
- package/dist/containers/project/project-paths.js.map +1 -1
- package/dist/containers/project.d.ts +9 -2
- package/dist/containers/project.js +49 -1
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +1 -0
- package/dist/containers/template.js +7 -2
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/macros.d.ts +2 -1
- package/dist/interfaces/project-interfaces.d.ts +5 -0
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +14 -22
- package/dist/interfaces/resource-interfaces.js +10 -9
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/graph/index.d.ts +1 -1
- package/dist/macros/graph/index.js +12 -12
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/index.d.ts +24 -3
- package/dist/macros/index.js +11 -4
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/report/index.d.ts +13 -10
- package/dist/macros/report/index.js +26 -38
- package/dist/macros/report/index.js.map +1 -1
- package/dist/module-manager.d.ts +16 -7
- package/dist/module-manager.js +142 -112
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.js +6 -0
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/array-handler.js +6 -1
- package/dist/resources/array-handler.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +13 -9
- package/dist/resources/card-type-resource.js +47 -23
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.d.ts +10 -9
- package/dist/resources/create-defaults.js +15 -12
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +0 -1
- package/dist/resources/field-type-resource.js +2 -10
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +7 -7
- package/dist/resources/file-resource.js +32 -7
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +10 -9
- package/dist/resources/folder-resource.js +10 -9
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +5 -6
- package/dist/resources/report-resource.js +16 -7
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/template-resource.d.ts +5 -6
- package/dist/resources/template-resource.js +7 -6
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +15 -8
- package/dist/resources/workflow-resource.js +124 -8
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/types/queries.d.ts +11 -10
- package/dist/types/queries.js +10 -9
- package/dist/types/queries.js.map +1 -1
- package/dist/utils/clingo-fact-builder.d.ts +1 -0
- package/dist/utils/clingo-fact-builder.js +8 -3
- package/dist/utils/clingo-fact-builder.js.map +1 -1
- package/dist/utils/clingo-facts.js +15 -11
- package/dist/utils/clingo-facts.js.map +1 -1
- package/dist/utils/constants.d.ts +18 -12
- package/dist/utils/constants.js +18 -11
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/log-utils.d.ts +15 -2
- package/dist/utils/log-utils.js +20 -37
- package/dist/utils/log-utils.js.map +1 -1
- package/dist/utils/report.d.ts +27 -0
- package/dist/utils/report.js +60 -0
- package/dist/utils/report.js.map +1 -0
- package/dist/utils/resource-utils.js +3 -0
- package/dist/utils/resource-utils.js.map +1 -1
- package/dist/utils/sanitize-svg.d.ts +3 -4
- package/dist/utils/sanitize-svg.js +4 -7
- package/dist/utils/sanitize-svg.js.map +1 -1
- package/dist/utils/validate.js +2 -1
- package/dist/utils/validate.js.map +1 -1
- package/package.json +9 -10
- package/src/card-metadata-updater.ts +7 -2
- package/src/command-handler.ts +23 -13
- package/src/command-manager.ts +54 -13
- package/src/commands/calculate.ts +90 -106
- package/src/commands/export.ts +3 -2
- package/src/commands/import.ts +16 -16
- package/src/commands/index.ts +0 -2
- package/src/commands/remove.ts +1 -1
- package/src/commands/show.ts +13 -5
- package/src/commands/validate.ts +14 -9
- package/src/containers/project/project-content-watcher.ts +65 -0
- package/src/containers/project/project-paths.ts +1 -1
- package/src/containers/project.ts +60 -1
- package/src/containers/template.ts +7 -2
- package/src/index.ts +2 -0
- package/src/interfaces/macros.ts +2 -1
- package/src/interfaces/project-interfaces.ts +8 -0
- package/src/interfaces/resource-interfaces.ts +15 -22
- package/src/macros/graph/index.ts +17 -12
- package/src/macros/index.ts +32 -6
- package/src/macros/report/index.ts +32 -42
- package/src/module-manager.ts +183 -139
- package/src/project-settings.ts +7 -0
- package/src/resources/array-handler.ts +7 -2
- package/src/resources/card-type-resource.ts +61 -46
- package/src/resources/create-defaults.ts +15 -12
- package/src/resources/field-type-resource.ts +2 -17
- package/src/resources/file-resource.ts +46 -8
- package/src/resources/folder-resource.ts +11 -10
- package/src/resources/report-resource.ts +19 -7
- package/src/resources/template-resource.ts +7 -6
- package/src/resources/workflow-resource.ts +155 -8
- package/src/types/queries.ts +11 -10
- package/src/utils/clingo-fact-builder.ts +8 -3
- package/src/utils/clingo-facts.ts +18 -12
- package/src/utils/constants.ts +20 -12
- package/src/utils/log-utils.ts +24 -45
- package/src/utils/report.ts +86 -0
- package/src/utils/resource-utils.ts +4 -0
- package/src/utils/sanitize-svg.ts +4 -9
- package/src/utils/validate.ts +3 -2
- package/dist/commands/export-site.d.ts +0 -45
- package/dist/commands/export-site.js +0 -301
- package/dist/commands/export-site.js.map +0 -1
- package/src/commands/export-site.ts +0 -356
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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/>.
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
import type {
|
|
@@ -22,6 +24,7 @@ import type {
|
|
|
22
24
|
ChangeOperation,
|
|
23
25
|
Operation,
|
|
24
26
|
Project,
|
|
27
|
+
RemoveOperation,
|
|
25
28
|
ResourceName,
|
|
26
29
|
} from './file-resource.js';
|
|
27
30
|
import {
|
|
@@ -46,6 +49,27 @@ export class WorkflowResource extends FileResource {
|
|
|
46
49
|
this.initialize();
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
// Collect all cards that use this workflow.
|
|
53
|
+
private async collectCardsUsingWorkflow(): Promise<Card[]> {
|
|
54
|
+
const cardTypes = await this.project.cardTypes(ResourcesFrom.localOnly);
|
|
55
|
+
const promises: Promise<Card[]>[] = [];
|
|
56
|
+
for (const cardType of cardTypes) {
|
|
57
|
+
const object = new CardTypeResource(
|
|
58
|
+
this.project,
|
|
59
|
+
resourceName(cardType.name),
|
|
60
|
+
);
|
|
61
|
+
if (
|
|
62
|
+
object.data &&
|
|
63
|
+
(object.data as CardType).workflow ===
|
|
64
|
+
resourceNameToString(this.resourceName)
|
|
65
|
+
) {
|
|
66
|
+
// fetch all cards with card type
|
|
67
|
+
promises.push(this.collectCards({ metadata: true }, cardType.name));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return (await Promise.all(promises)).flat();
|
|
71
|
+
}
|
|
72
|
+
|
|
49
73
|
// When resource name changes.
|
|
50
74
|
private async handleNameChange(existingName: string) {
|
|
51
75
|
await Promise.all([
|
|
@@ -56,6 +80,96 @@ export class WorkflowResource extends FileResource {
|
|
|
56
80
|
await this.write();
|
|
57
81
|
}
|
|
58
82
|
|
|
83
|
+
// Handle change of workflow state.
|
|
84
|
+
private async handleStateChange(op: ChangeOperation<WorkflowState>) {
|
|
85
|
+
const content = { ...(this.content as Workflow) };
|
|
86
|
+
const stateName = (
|
|
87
|
+
(op.target as WorkflowState).name
|
|
88
|
+
? (op.target as WorkflowState).name
|
|
89
|
+
: op.target
|
|
90
|
+
) as string;
|
|
91
|
+
// Check that state can be changed to
|
|
92
|
+
content.transitions = content.transitions.filter(
|
|
93
|
+
(t) => t.toState !== stateName,
|
|
94
|
+
);
|
|
95
|
+
content.transitions.forEach((t) => {
|
|
96
|
+
t.fromState = t.fromState.filter((state) => state !== stateName);
|
|
97
|
+
});
|
|
98
|
+
// validate that new state contains 'name' and 'category'
|
|
99
|
+
if (op.to.name === undefined || op.to.category === undefined) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Cannot change state '${stateName}' for workflow '${this.content.name}'.
|
|
102
|
+
Updated state must have 'name' and 'category' properties.`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
// Update all cards that use this state.
|
|
106
|
+
const toStateName = op.to.name;
|
|
107
|
+
|
|
108
|
+
await this.updateCardStates(stateName, toStateName);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Handle removal of workflow state.
|
|
112
|
+
// State can be removed with or without replacement.
|
|
113
|
+
private async handleStateRemoval(op: RemoveOperation<WorkflowState>) {
|
|
114
|
+
const content = { ...(this.content as Workflow) };
|
|
115
|
+
const stateName = (
|
|
116
|
+
(op.target as WorkflowState).name
|
|
117
|
+
? (op.target as WorkflowState).name
|
|
118
|
+
: op.target
|
|
119
|
+
) as string;
|
|
120
|
+
|
|
121
|
+
// If there is no replacement value, remove all transitions "to" and "from" this state.
|
|
122
|
+
if (!op.replacementValue) {
|
|
123
|
+
content.transitions = content.transitions.filter(
|
|
124
|
+
(t) => t.toState !== stateName,
|
|
125
|
+
);
|
|
126
|
+
content.transitions.forEach((t) => {
|
|
127
|
+
t.fromState = t.fromState.filter((state) => state !== stateName);
|
|
128
|
+
});
|
|
129
|
+
} else {
|
|
130
|
+
// Replace transitions "to" the removed state with the replacement state.
|
|
131
|
+
const replacementState = op.replacementValue;
|
|
132
|
+
const stateExists = content.states.some(
|
|
133
|
+
(state) => state.name === replacementState.name,
|
|
134
|
+
);
|
|
135
|
+
if (!stateExists) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Cannot change to unknown state '${replacementState.name}' for Workflow`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
content.transitions.forEach((t) => {
|
|
142
|
+
if (t.toState === stateName) {
|
|
143
|
+
t.toState = replacementState.name;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
// Replace transitions "from" the removed state with the replacement state.
|
|
147
|
+
content.transitions.forEach((t) => {
|
|
148
|
+
t.fromState = t.fromState.map((state) =>
|
|
149
|
+
state === stateName ? replacementState.name : state,
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
// Update all cards that use this state.
|
|
153
|
+
await this.updateCardStates(stateName, replacementState.name);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Check if operation is a string operation.
|
|
158
|
+
private isStringOperation(op: Operation<unknown>): op is Operation<string> {
|
|
159
|
+
return typeof op.target === 'string';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Update card states when state is changed
|
|
163
|
+
private async updateCardStates(oldState: string, newState: string) {
|
|
164
|
+
const cards = await this.collectCardsUsingWorkflow();
|
|
165
|
+
cards.forEach(async (card) => {
|
|
166
|
+
if (card.metadata?.workflowState === oldState) {
|
|
167
|
+
card.metadata.workflowState = newState;
|
|
168
|
+
await this.project.updateCardMetadata(card, card.metadata);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
59
173
|
// Update dependant card types.
|
|
60
174
|
private async updateCardTypes(oldName: string) {
|
|
61
175
|
const cardTypes = await this.project.cardTypes(ResourcesFrom.localOnly);
|
|
@@ -156,6 +270,39 @@ export class WorkflowResource extends FileResource {
|
|
|
156
270
|
throw new Error(`Unknown property '${key}' for Workflow`);
|
|
157
271
|
}
|
|
158
272
|
|
|
273
|
+
if (key === 'states' && op.name === 'remove') {
|
|
274
|
+
// If workflow state is removed, remove all transitions "to" and "from" this state.
|
|
275
|
+
let removeOp: RemoveOperation<WorkflowState>;
|
|
276
|
+
if (this.isStringOperation(op)) {
|
|
277
|
+
const toBeRemovedState = (this.content as Workflow).states.find(
|
|
278
|
+
(state) => state.name === op.target,
|
|
279
|
+
);
|
|
280
|
+
removeOp = {
|
|
281
|
+
name: 'remove',
|
|
282
|
+
target: toBeRemovedState as WorkflowState,
|
|
283
|
+
};
|
|
284
|
+
} else {
|
|
285
|
+
removeOp = op as RemoveOperation<WorkflowState>;
|
|
286
|
+
}
|
|
287
|
+
await this.handleStateRemoval(removeOp);
|
|
288
|
+
} else if (key === 'states' && op.name === 'change') {
|
|
289
|
+
// If workflow state is renamed, replace all transitions "to" and "from" the old state with new state.
|
|
290
|
+
let changeOp: ChangeOperation<WorkflowState>;
|
|
291
|
+
if (this.isStringOperation(op)) {
|
|
292
|
+
const toBeChangedState = (this.content as Workflow).states.find(
|
|
293
|
+
(state) => state.name === op.target,
|
|
294
|
+
);
|
|
295
|
+
changeOp = {
|
|
296
|
+
name: 'change',
|
|
297
|
+
target: toBeChangedState as WorkflowState,
|
|
298
|
+
to: { name: op.to },
|
|
299
|
+
};
|
|
300
|
+
} else {
|
|
301
|
+
changeOp = op as ChangeOperation<WorkflowState>;
|
|
302
|
+
}
|
|
303
|
+
await this.handleStateChange(changeOp);
|
|
304
|
+
}
|
|
305
|
+
|
|
159
306
|
await super.postUpdate(content, key, op);
|
|
160
307
|
|
|
161
308
|
// Renaming this workflow causes that references to its name must be updated.
|
package/src/types/queries.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -134,7 +135,7 @@ interface CardQueryField extends BaseResult {
|
|
|
134
135
|
visibility: 'always' | 'optional';
|
|
135
136
|
index: number;
|
|
136
137
|
fieldDisplayName: string;
|
|
137
|
-
|
|
138
|
+
description: string;
|
|
138
139
|
dataType: DataType;
|
|
139
140
|
isCalculated: boolean;
|
|
140
141
|
value: string | number | boolean | null | EnumValue | ListValueItem[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { INT32_MAX } from './constants.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getChildLogger } from './log-utils.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
Cyberismo
|
|
@@ -40,6 +40,11 @@ export class ClingoFactBuilder {
|
|
|
40
40
|
protected predicate: string;
|
|
41
41
|
private end: string;
|
|
42
42
|
private arguments: ClingoArgumentInternal[] = [];
|
|
43
|
+
private get logger() {
|
|
44
|
+
return getChildLogger({
|
|
45
|
+
module: 'clingoFactBuilder',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
43
48
|
|
|
44
49
|
constructor(predicate: string, end: string = '.') {
|
|
45
50
|
this.predicate = predicate;
|
|
@@ -120,7 +125,7 @@ export class ClingoFactBuilder {
|
|
|
120
125
|
} else if (typeof value === 'number') {
|
|
121
126
|
let floored = Math.floor(value);
|
|
122
127
|
if (floored !== value) {
|
|
123
|
-
logger.warn(
|
|
128
|
+
this.logger.warn(
|
|
124
129
|
{
|
|
125
130
|
value,
|
|
126
131
|
},
|
|
@@ -130,7 +135,7 @@ export class ClingoFactBuilder {
|
|
|
130
135
|
|
|
131
136
|
const exceedsInt32Max = floored > INT32_MAX;
|
|
132
137
|
if (exceedsInt32Max || floored < -INT32_MAX) {
|
|
133
|
-
logger.warn(
|
|
138
|
+
this.logger.warn(
|
|
134
139
|
{
|
|
135
140
|
value,
|
|
136
141
|
},
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
12
|
*/
|
|
12
13
|
import { sep } from 'node:path';
|
|
13
14
|
|
|
@@ -249,6 +250,11 @@ export const createCardFacts = async (card: Card, project: Project) => {
|
|
|
249
250
|
b.addLiteralArguments(card.key, parentsPath),
|
|
250
251
|
);
|
|
251
252
|
}
|
|
253
|
+
builder.addCustomFact(Facts.Common.FIELD, (b) =>
|
|
254
|
+
b
|
|
255
|
+
.addLiteralArgument(card.key)
|
|
256
|
+
.addArguments('container', isTemplateCard(card) ? 'template' : 'project'),
|
|
257
|
+
);
|
|
252
258
|
|
|
253
259
|
return builder.buildAll();
|
|
254
260
|
};
|
|
@@ -270,12 +276,12 @@ export const createFieldTypeFacts = (fieldType: FieldType) => {
|
|
|
270
276
|
fieldType.displayName,
|
|
271
277
|
);
|
|
272
278
|
|
|
273
|
-
if (fieldType.
|
|
279
|
+
if (fieldType.description)
|
|
274
280
|
builder.addFact(
|
|
275
281
|
Facts.Common.FIELD,
|
|
276
282
|
fieldType.name,
|
|
277
|
-
'
|
|
278
|
-
fieldType.
|
|
283
|
+
'description',
|
|
284
|
+
fieldType.description,
|
|
279
285
|
);
|
|
280
286
|
|
|
281
287
|
builder.addFact(
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import type { PredefinedCardMetadata } from '../interfaces/project-interfaces.js';
|
|
2
|
-
|
|
3
|
-
export const INT32_MAX = 2147483647; // 2^31-1
|
|
4
1
|
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
import type { PredefinedCardMetadata } from '../interfaces/project-interfaces.js';
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
14
|
-
*/
|
|
16
|
+
export const INT32_MAX = 2147483647; // 2^31-1
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
|
-
* These are names
|
|
19
|
+
* These are field names that are non-custom fields that present in metadata
|
|
18
20
|
*/
|
|
19
21
|
export const PREDEFINED_FIELDS = [
|
|
20
22
|
'rank',
|
|
@@ -23,8 +25,14 @@ export const PREDEFINED_FIELDS = [
|
|
|
23
25
|
'workflowState',
|
|
24
26
|
'lastUpdated',
|
|
25
27
|
'lastTransitioned',
|
|
28
|
+
'templateCardKey',
|
|
26
29
|
] satisfies (keyof PredefinedCardMetadata)[];
|
|
27
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Checks if the given value is a predefined field.
|
|
33
|
+
* @param value The field name to check.
|
|
34
|
+
* @returns True if the value is a predefined field, false otherwise.
|
|
35
|
+
*/
|
|
28
36
|
export function isPredefinedField(
|
|
29
37
|
value: string,
|
|
30
38
|
): value is keyof PredefinedCardMetadata {
|
package/src/utils/log-utils.ts
CHANGED
|
@@ -9,54 +9,33 @@
|
|
|
9
9
|
You should have received a copy of the GNU Affero General Public
|
|
10
10
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
11
11
|
*/
|
|
12
|
+
import pino, { type ChildLoggerOptions, type Logger } from 'pino';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const LOG_FILE_LOCATION: string = join(
|
|
17
|
-
fileURLToPath(import.meta.url),
|
|
18
|
-
'../../../../../logs/data-handler.trace',
|
|
19
|
-
);
|
|
14
|
+
// This could be also a more generic interface, but since we use pino and this is an internal package, let's keep it simple
|
|
15
|
+
// silent logger as default
|
|
16
|
+
let _logger: Logger = pino.default({ level: 'silent' });
|
|
20
17
|
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
if (process.env.NODE_ENV === 'development') {
|
|
44
|
-
// In dev mode, only stdout and debug logs by default
|
|
45
|
-
return pino.default({
|
|
46
|
-
level: 'trace',
|
|
47
|
-
transport: {
|
|
48
|
-
targets: all,
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
return pino.default({
|
|
53
|
-
level: 'trace',
|
|
54
|
-
transport: file,
|
|
55
|
-
});
|
|
18
|
+
export function setLogger(logger: Logger) {
|
|
19
|
+
_logger = logger;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the logger instance.
|
|
23
|
+
*/
|
|
24
|
+
export function getLogger(): Logger {
|
|
25
|
+
return _logger;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns a child logger instance.
|
|
29
|
+
* @param context Context to add to the logger.
|
|
30
|
+
* @param options Options to pass to the logger.
|
|
31
|
+
* @returns Child logger instance.
|
|
32
|
+
*/
|
|
33
|
+
export function getChildLogger(
|
|
34
|
+
context: { module: string } & Record<string, unknown>,
|
|
35
|
+
options?: ChildLoggerOptions,
|
|
36
|
+
): Logger {
|
|
37
|
+
return _logger.child(context, options);
|
|
56
38
|
}
|
|
57
|
-
|
|
58
|
-
export const logger = getLogger();
|
|
59
|
-
|
|
60
39
|
/**
|
|
61
40
|
* Returns error message string from an Error object.
|
|
62
41
|
* @param error Error object
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
import Handlebars from 'handlebars';
|
|
13
|
+
import type { Calculate } from '../commands/index.js';
|
|
14
|
+
import { registerEmptyMacros } from '../macros/index.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Formats a value from a logic program for use to graphviz
|
|
18
|
+
* @param value - The value to format
|
|
19
|
+
* @returns The formatted value
|
|
20
|
+
*/
|
|
21
|
+
export function formatAttributeValue(value?: string) {
|
|
22
|
+
if (!value) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
// value is an html-like string
|
|
26
|
+
if (value.length > 1 && value.startsWith('<') && value.endsWith('>')) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
// value is a normal string and needs to be wrapped in quotes
|
|
30
|
+
return `"${value}"`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parameters for the core generation function
|
|
35
|
+
*/
|
|
36
|
+
interface GenerateReportContentParams {
|
|
37
|
+
calculate: Calculate;
|
|
38
|
+
contentTemplate: string;
|
|
39
|
+
queryTemplate: string;
|
|
40
|
+
options: Record<string, string>;
|
|
41
|
+
graph?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generates report content based on a report definition, project context, and options,
|
|
46
|
+
* by utilizing the ReportRunner class.
|
|
47
|
+
*
|
|
48
|
+
* @param params - The parameters for report generation.
|
|
49
|
+
* @returns The rendered report content as a string.
|
|
50
|
+
* @throws Error if the report definition is invalid, schema validation fails, or logic program execution fails.
|
|
51
|
+
*/
|
|
52
|
+
export async function generateReportContent(
|
|
53
|
+
params: GenerateReportContentParams,
|
|
54
|
+
): Promise<string> {
|
|
55
|
+
const {
|
|
56
|
+
calculate,
|
|
57
|
+
contentTemplate,
|
|
58
|
+
queryTemplate,
|
|
59
|
+
graph,
|
|
60
|
+
options, // Destructure options
|
|
61
|
+
} = params;
|
|
62
|
+
|
|
63
|
+
const handlebars = Handlebars.create();
|
|
64
|
+
|
|
65
|
+
// Compile and execute the query template
|
|
66
|
+
const template = handlebars.compile(queryTemplate, {
|
|
67
|
+
strict: true,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const result = await calculate.runLogicProgram(template(options));
|
|
71
|
+
|
|
72
|
+
if (result.error) {
|
|
73
|
+
throw new Error(result.error);
|
|
74
|
+
}
|
|
75
|
+
// register empty macros so that other macros aren't touched yet
|
|
76
|
+
registerEmptyMacros(handlebars);
|
|
77
|
+
|
|
78
|
+
if (graph) {
|
|
79
|
+
handlebars.registerHelper('formatAttributeValue', formatAttributeValue);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return handlebars.compile(contentTemplate)({
|
|
83
|
+
...options,
|
|
84
|
+
...result,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
@@ -140,6 +140,10 @@ export function pathToResourceName(
|
|
|
140
140
|
if (!identifier || !type || !prefix) {
|
|
141
141
|
throw new Error(`invalid path: ${path}`);
|
|
142
142
|
}
|
|
143
|
+
if (identifierIndex + 1 !== parts.length) {
|
|
144
|
+
throw new Error(`not a resource path: ${path}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
return {
|
|
144
148
|
prefix: prefix,
|
|
145
149
|
type: type,
|
|
@@ -25,22 +25,17 @@ const removeSvgWidthAndHeight = (node: Element) => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Sanitize an SVG
|
|
29
|
-
* @param
|
|
28
|
+
* Sanitize an SVG string and return a base64-encoded string
|
|
29
|
+
* @param svg - SVG content as a string
|
|
30
30
|
* @returns base64-encoded sanitized SVG string
|
|
31
31
|
*/
|
|
32
|
-
export function sanitizeSvgBase64(
|
|
32
|
+
export function sanitizeSvgBase64(svg: string): string {
|
|
33
33
|
const DOMPurify = createDOMPurify(window as unknown as WindowLike);
|
|
34
34
|
|
|
35
|
-
const dirty = buffer.toString('utf-8');
|
|
36
|
-
|
|
37
35
|
DOMPurify.setConfig({ USE_PROFILES: { svg: true } });
|
|
38
36
|
DOMPurify.addHook('afterSanitizeAttributes', removeSvgWidthAndHeight);
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Remove link titles, quick fix for Clingraph/Graphviz generated titles for links that are quite strange
|
|
43
|
-
cleaned = cleaned.replace(/\s*xlink:title=(["']).*?\1/g, '');
|
|
38
|
+
const cleaned = DOMPurify.sanitize(svg);
|
|
44
39
|
|
|
45
40
|
return Buffer.from(cleaned, 'utf-8').toString('base64');
|
|
46
41
|
}
|
package/src/utils/validate.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { type Schema, Validator } from 'jsonschema';
|
|
13
13
|
import { DHValidationError, SchemaNotFound } from '../exceptions/index.js';
|
|
14
|
-
import { schemas } from '@cyberismo/
|
|
14
|
+
import { schemas } from '@cyberismo/assets';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Validates a JSON object against a schema
|
|
@@ -40,7 +40,8 @@ export function validateJson<T>(
|
|
|
40
40
|
if (!validator) {
|
|
41
41
|
validator = new Validator();
|
|
42
42
|
for (const schema of schemas) {
|
|
43
|
-
|
|
43
|
+
// For some reason, the draft-07 schema is not a valid Schema, so we need to cast it
|
|
44
|
+
validator.addSchema(schema as Schema, schema.$id);
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -1,45 +0,0 @@
|
|
|
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
|
-
import { type Calculate, type Show } from './index.js';
|
|
15
|
-
import { Export } from './export.js';
|
|
16
|
-
import type { Project } from '../containers/project.js';
|
|
17
|
-
interface ExportOptions {
|
|
18
|
-
silent: boolean;
|
|
19
|
-
}
|
|
20
|
-
export declare class ExportSite extends Export {
|
|
21
|
-
private tmpDir;
|
|
22
|
-
private moduleDir;
|
|
23
|
-
private pagesDir;
|
|
24
|
-
private imagesDir;
|
|
25
|
-
private playbookDir;
|
|
26
|
-
private playbookFile;
|
|
27
|
-
private navFile;
|
|
28
|
-
private options;
|
|
29
|
-
constructor(project: Project, calculateCmd: Calculate, showCmd: Show);
|
|
30
|
-
private createCardsIndex;
|
|
31
|
-
private initDirectories;
|
|
32
|
-
private generate;
|
|
33
|
-
private createPlaybook;
|
|
34
|
-
private createDescriptor;
|
|
35
|
-
private initRepo;
|
|
36
|
-
private toAdocDirectoryAsContent;
|
|
37
|
-
private export;
|
|
38
|
-
/**
|
|
39
|
-
* Export the card tree as an Antora site
|
|
40
|
-
* @param destination Path where the site is generated
|
|
41
|
-
* @param cardKey Optional; If defined exports the card tree from underneath this card.
|
|
42
|
-
*/
|
|
43
|
-
exportToSite(destination: string, cardKey?: string, options?: ExportOptions): Promise<string>;
|
|
44
|
-
}
|
|
45
|
-
export {};
|