@cyberismo/data-handler 0.0.12 → 0.0.14
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/command-handler.d.ts +24 -42
- package/dist/command-handler.js +33 -26
- package/dist/command-handler.js.map +1 -1
- package/dist/commands/create.d.ts +3 -3
- package/dist/commands/create.js +7 -22
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/edit.d.ts +12 -11
- package/dist/commands/edit.js +41 -16
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/fetch.js +2 -1
- package/dist/commands/fetch.js.map +1 -1
- package/dist/commands/import.js +2 -2
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/remove.js +6 -5
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.d.ts +1 -0
- package/dist/commands/rename.js +11 -0
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +4 -0
- package/dist/commands/show.js +6 -12
- 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 +4 -3
- 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.js +18 -18
- package/dist/containers/project/calculation-engine.js.map +1 -1
- package/dist/containers/project.d.ts +2 -1
- package/dist/containers/project.js +5 -1
- package/dist/containers/project.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 +56 -0
- package/dist/interfaces/folder-content-interfaces.js +47 -0
- package/dist/interfaces/folder-content-interfaces.js.map +1 -0
- package/dist/interfaces/project-interfaces.d.ts +11 -9
- package/dist/interfaces/project-interfaces.js +10 -8
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +37 -10
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/report/index.js +4 -4
- package/dist/macros/report/index.js.map +1 -1
- package/dist/resources/calculation-resource.d.ts +71 -0
- package/dist/resources/calculation-resource.js +130 -0
- package/dist/resources/calculation-resource.js.map +1 -0
- package/dist/resources/card-type-resource.js +11 -5
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.d.ts +13 -6
- package/dist/resources/create-defaults.js +19 -5
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.js +1 -1
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.js +9 -3
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +38 -10
- 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 +12 -26
- 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 +14 -2
- 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 +6 -0
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/utils/constants.js +1 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/error-utils.d.ts +34 -0
- package/dist/utils/error-utils.js +56 -0
- package/dist/utils/error-utils.js.map +1 -0
- package/dist/utils/log-utils.d.ts +0 -27
- package/dist/utils/log-utils.js +0 -58
- package/dist/utils/log-utils.js.map +1 -1
- package/dist/utils/user-preferences.js +6 -3
- package/dist/utils/user-preferences.js.map +1 -1
- package/package.json +9 -7
- package/src/command-handler.ts +74 -59
- package/src/commands/create.ts +10 -28
- package/src/commands/edit.ts +51 -26
- package/src/commands/fetch.ts +2 -1
- package/src/commands/import.ts +2 -0
- package/src/commands/remove.ts +3 -2
- package/src/commands/rename.ts +20 -0
- package/src/commands/show.ts +5 -13
- package/src/commands/update.ts +20 -2
- package/src/commands/validate.ts +7 -3
- package/src/containers/card-container.ts +1 -1
- package/src/containers/project/calculation-engine.ts +23 -23
- package/src/containers/project.ts +4 -1
- package/src/index.ts +36 -2
- package/src/interfaces/command-options.ts +144 -0
- package/src/interfaces/folder-content-interfaces.ts +81 -0
- package/src/interfaces/project-interfaces.ts +12 -9
- package/src/interfaces/resource-interfaces.ts +51 -12
- package/src/macros/report/index.ts +4 -4
- package/src/resources/calculation-resource.ts +171 -0
- package/src/resources/card-type-resource.ts +12 -6
- package/src/resources/create-defaults.ts +21 -5
- package/src/resources/field-type-resource.ts +1 -1
- package/src/resources/file-resource.ts +9 -3
- package/src/resources/folder-resource.ts +150 -20
- package/src/resources/graph-model-resource.ts +16 -27
- package/src/resources/graph-view-resource.ts +16 -28
- package/src/resources/link-type-resource.ts +1 -1
- package/src/resources/report-resource.ts +60 -62
- package/src/resources/resource-object.ts +30 -7
- package/src/resources/template-resource.ts +12 -7
- package/src/resources/workflow-resource.ts +4 -0
- package/src/utils/constants.ts +1 -0
- package/src/utils/error-utils.ts +62 -0
- package/src/utils/log-utils.ts +0 -68
- package/src/utils/user-preferences.ts +7 -3
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2025
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Schema } from 'jsonschema';
|
|
15
|
+
|
|
16
|
+
// All file mappings for lookup (filename -> property name)
|
|
17
|
+
export const ALL_FILE_MAPPINGS = {
|
|
18
|
+
'calculation.lp': 'calculation',
|
|
19
|
+
'index.adoc.hbs': 'contentTemplate',
|
|
20
|
+
'model.lp': 'model',
|
|
21
|
+
'parameterSchema.json': 'schema',
|
|
22
|
+
'query.lp.hbs': 'queryTemplate',
|
|
23
|
+
'view.lp.hbs': 'viewTemplate',
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
// Reverse mappings from property names to filenames
|
|
27
|
+
export const REVERSE_FILE_MAPPINGS = {
|
|
28
|
+
calculation: 'calculation.lp',
|
|
29
|
+
contentTemplate: 'index.adoc.hbs',
|
|
30
|
+
model: 'model.lp',
|
|
31
|
+
queryTemplate: 'query.lp.hbs',
|
|
32
|
+
schema: 'parameterSchema.json',
|
|
33
|
+
viewTemplate: 'view.lp.hbs',
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
// Union type of all valid content property names
|
|
37
|
+
export type ContentPropertyName = keyof typeof REVERSE_FILE_MAPPINGS;
|
|
38
|
+
|
|
39
|
+
// Content interface for Calculation resources
|
|
40
|
+
export interface CalculationContent {
|
|
41
|
+
calculation: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Content interface for Graph Model resources
|
|
45
|
+
export interface GraphModelContent {
|
|
46
|
+
model?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Content interface for Graph View resources
|
|
50
|
+
export interface GraphViewContent {
|
|
51
|
+
viewTemplate?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Content interface for Report resources
|
|
55
|
+
export interface ReportContent {
|
|
56
|
+
contentTemplate: string;
|
|
57
|
+
queryTemplate: string;
|
|
58
|
+
schema?: Schema;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get filename with property name
|
|
63
|
+
* @param propertyName Property name.
|
|
64
|
+
* @returns filename that matches property name
|
|
65
|
+
*/
|
|
66
|
+
export function filename(propertyName: string): string | undefined {
|
|
67
|
+
return REVERSE_FILE_MAPPINGS[
|
|
68
|
+
propertyName as keyof typeof REVERSE_FILE_MAPPINGS
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get property name for a filename
|
|
74
|
+
* @param filename Filename.
|
|
75
|
+
* @returns property name that matches filename
|
|
76
|
+
*/
|
|
77
|
+
export function propertyName(
|
|
78
|
+
filename: string,
|
|
79
|
+
): ContentPropertyName | undefined {
|
|
80
|
+
return ALL_FILE_MAPPINGS[filename as keyof typeof ALL_FILE_MAPPINGS];
|
|
81
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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/>.
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
import type { Link, TemplateConfiguration } from './resource-interfaces.js';
|
|
@@ -205,6 +207,7 @@ export interface ModuleSettingOptions {
|
|
|
205
207
|
// Resources that are possible to remove.
|
|
206
208
|
export type RemovableResourceTypes =
|
|
207
209
|
| 'attachment'
|
|
210
|
+
| 'calculation'
|
|
208
211
|
| 'card'
|
|
209
212
|
| 'cardType'
|
|
210
213
|
| 'fieldType'
|
|
@@ -11,7 +11,12 @@
|
|
|
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
|
+
CalculationContent,
|
|
16
|
+
GraphModelContent,
|
|
17
|
+
GraphViewContent,
|
|
18
|
+
ReportContent,
|
|
19
|
+
} from './folder-content-interfaces.js';
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
22
|
* Each resource represents a file (or a folder in some cases) with metadata stored
|
|
@@ -23,6 +28,15 @@ import type { Schema } from 'jsonschema';
|
|
|
23
28
|
export interface CalculationMetadata extends ResourceBaseMetadata {
|
|
24
29
|
calculation: string;
|
|
25
30
|
}
|
|
31
|
+
export interface Calculation extends CalculationMetadata {
|
|
32
|
+
content: CalculationContent;
|
|
33
|
+
}
|
|
34
|
+
export type CalculationContentPropertyName = 'calculation';
|
|
35
|
+
export interface CalculationContentUpdateKey {
|
|
36
|
+
key: 'content';
|
|
37
|
+
subKey: CalculationContentPropertyName;
|
|
38
|
+
}
|
|
39
|
+
export type CalculationUpdateKey = string | CalculationContentUpdateKey;
|
|
26
40
|
|
|
27
41
|
// Card type content.
|
|
28
42
|
export interface CardType extends ResourceBaseMetadata {
|
|
@@ -32,6 +46,12 @@ export interface CardType extends ResourceBaseMetadata {
|
|
|
32
46
|
optionallyVisibleFields: string[];
|
|
33
47
|
}
|
|
34
48
|
|
|
49
|
+
// Base content update key interface
|
|
50
|
+
export interface ContentUpdateKey {
|
|
51
|
+
key: 'content';
|
|
52
|
+
subKey: string; // Resource-specific types should narrow this
|
|
53
|
+
}
|
|
54
|
+
|
|
35
55
|
// Custom field
|
|
36
56
|
// todo: merge with FieldType.
|
|
37
57
|
export interface CustomField {
|
|
@@ -71,19 +91,29 @@ export interface FieldType extends ResourceBaseMetadata {
|
|
|
71
91
|
export interface GraphModelMetadata extends ResourceBaseMetadata {
|
|
72
92
|
category?: string;
|
|
73
93
|
}
|
|
74
|
-
|
|
75
94
|
export interface GraphModel extends GraphModelMetadata {
|
|
76
|
-
|
|
95
|
+
content: GraphModelContent;
|
|
96
|
+
}
|
|
97
|
+
export type GraphModelContentPropertyName = 'model';
|
|
98
|
+
export interface GraphModelContentUpdateKey {
|
|
99
|
+
key: 'content';
|
|
100
|
+
subKey: GraphModelContentPropertyName;
|
|
77
101
|
}
|
|
102
|
+
export type GraphModelUpdateKey = string | GraphModelContentUpdateKey;
|
|
78
103
|
|
|
79
104
|
// Graph view content.
|
|
80
105
|
export interface GraphViewMetadata extends ResourceBaseMetadata {
|
|
81
106
|
category?: string;
|
|
82
107
|
}
|
|
83
|
-
|
|
108
|
+
export type GraphViewContentPropertyName = 'viewTemplate';
|
|
84
109
|
export interface GraphView extends GraphViewMetadata {
|
|
85
|
-
|
|
110
|
+
content: GraphViewContent;
|
|
111
|
+
}
|
|
112
|
+
export interface GraphViewContentUpdateKey {
|
|
113
|
+
key: 'content';
|
|
114
|
+
subKey: GraphViewContentPropertyName;
|
|
86
115
|
}
|
|
116
|
+
export type GraphViewUpdateKey = string | GraphViewContentUpdateKey;
|
|
87
117
|
|
|
88
118
|
// Link content.
|
|
89
119
|
export interface Link {
|
|
@@ -103,13 +133,20 @@ export interface LinkType extends ResourceBaseMetadata {
|
|
|
103
133
|
|
|
104
134
|
// Report resource.
|
|
105
135
|
export interface Report extends ResourceBaseMetadata {
|
|
106
|
-
|
|
107
|
-
metadata: ReportMetadata;
|
|
108
|
-
contentTemplate: string;
|
|
109
|
-
queryTemplate: string;
|
|
110
|
-
schema?: Schema;
|
|
136
|
+
content: ReportContent;
|
|
111
137
|
}
|
|
112
138
|
|
|
139
|
+
// Resource-specific content names
|
|
140
|
+
export type ReportContentPropertyName =
|
|
141
|
+
| 'contentTemplate'
|
|
142
|
+
| 'queryTemplate'
|
|
143
|
+
| 'schema';
|
|
144
|
+
export interface ReportContentUpdateKey {
|
|
145
|
+
key: 'content';
|
|
146
|
+
subKey: ReportContentPropertyName;
|
|
147
|
+
}
|
|
148
|
+
export type ReportUpdateKey = string | ReportContentUpdateKey;
|
|
149
|
+
|
|
113
150
|
// Metadata for report
|
|
114
151
|
export interface ReportMetadata extends ResourceBaseMetadata {
|
|
115
152
|
category: string;
|
|
@@ -136,10 +173,9 @@ export type ResourceContent =
|
|
|
136
173
|
| Workflow;
|
|
137
174
|
|
|
138
175
|
// Template configuration details.
|
|
139
|
-
export interface TemplateConfiguration extends
|
|
176
|
+
export interface TemplateConfiguration extends TemplateMetadata {
|
|
140
177
|
path: string;
|
|
141
178
|
numberOfCards: number;
|
|
142
|
-
metadata: TemplateMetadata;
|
|
143
179
|
}
|
|
144
180
|
|
|
145
181
|
// Template configuration content details.
|
|
@@ -147,6 +183,9 @@ export interface TemplateMetadata extends ResourceBaseMetadata {
|
|
|
147
183
|
category?: string;
|
|
148
184
|
}
|
|
149
185
|
|
|
186
|
+
// Generic update key
|
|
187
|
+
export type UpdateKey = string | ContentUpdateKey;
|
|
188
|
+
|
|
150
189
|
// Workflow's json file content.
|
|
151
190
|
export interface Workflow extends ResourceBaseMetadata {
|
|
152
191
|
states: WorkflowState[];
|
|
@@ -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,
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2025
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
7
|
+
the Free Software Foundation. This program is distributed in the hope that it
|
|
8
|
+
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
9
|
+
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
See the GNU Affero General Public License for more details.
|
|
11
|
+
You should have received a copy of the GNU Affero General Public
|
|
12
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
DefaultContent,
|
|
19
|
+
FolderResource,
|
|
20
|
+
resourceNameToString,
|
|
21
|
+
sortCards,
|
|
22
|
+
} from './folder-resource.js';
|
|
23
|
+
import { writeFileSafe } from '../utils/file-utils.js';
|
|
24
|
+
|
|
25
|
+
import type {
|
|
26
|
+
Calculation,
|
|
27
|
+
CalculationMetadata,
|
|
28
|
+
CalculationUpdateKey,
|
|
29
|
+
} from '../interfaces/resource-interfaces.js';
|
|
30
|
+
import type { CalculationContent } from '../interfaces/folder-content-interfaces.js';
|
|
31
|
+
import type {
|
|
32
|
+
Card,
|
|
33
|
+
Operation,
|
|
34
|
+
Project,
|
|
35
|
+
ResourceName,
|
|
36
|
+
} from './file-resource.js';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Calculation resource class.
|
|
40
|
+
*/
|
|
41
|
+
export class CalculationResource extends FolderResource {
|
|
42
|
+
private calculationsFile = 'calculation.lp';
|
|
43
|
+
constructor(project: Project, name: ResourceName) {
|
|
44
|
+
super(project, name, 'calculations');
|
|
45
|
+
|
|
46
|
+
this.contentSchemaId = 'calculationSchema';
|
|
47
|
+
this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
|
|
48
|
+
|
|
49
|
+
this.initialize();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// When resource name changes
|
|
53
|
+
protected async onNameChange(existingName: string) {
|
|
54
|
+
await super.updateCalculations(existingName, this.content.name);
|
|
55
|
+
await this.write();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a new calculation object and file.
|
|
60
|
+
* @param newContent Content for the calculation.
|
|
61
|
+
*/
|
|
62
|
+
public async create(newContent?: CalculationMetadata) {
|
|
63
|
+
if (!newContent) {
|
|
64
|
+
newContent = DefaultContent.calculation(
|
|
65
|
+
resourceNameToString(this.resourceName),
|
|
66
|
+
);
|
|
67
|
+
} else {
|
|
68
|
+
await this.validate(newContent);
|
|
69
|
+
}
|
|
70
|
+
await super.create(newContent);
|
|
71
|
+
|
|
72
|
+
const calculationsFile = join(this.internalFolder, this.calculationsFile);
|
|
73
|
+
await writeFileSafe(
|
|
74
|
+
calculationsFile,
|
|
75
|
+
`% add your calculations here for '${this.resourceName.identifier}'`,
|
|
76
|
+
{
|
|
77
|
+
flag: 'wx',
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Returns content data.
|
|
84
|
+
*/
|
|
85
|
+
public get data(): CalculationMetadata {
|
|
86
|
+
return super.data as CalculationMetadata;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Deletes files from disk and clears out the memory resident object.
|
|
91
|
+
*/
|
|
92
|
+
public async delete() {
|
|
93
|
+
await super.delete();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Renames resource metadata file and renames memory resident object 'name'.
|
|
98
|
+
* @param newName New name for the resource.
|
|
99
|
+
*/
|
|
100
|
+
public async rename(newName: ResourceName) {
|
|
101
|
+
const existingName = this.content.name;
|
|
102
|
+
await super.rename(newName);
|
|
103
|
+
return this.onNameChange(existingName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Shows metadata of the resource.
|
|
108
|
+
* @returns calculation metadata.
|
|
109
|
+
*/
|
|
110
|
+
public async show(): Promise<Calculation> {
|
|
111
|
+
const baseData = (await super.show()) as CalculationMetadata;
|
|
112
|
+
const fileContents = await super.contentData();
|
|
113
|
+
const content: CalculationContent = {
|
|
114
|
+
calculation: fileContents.calculation as string,
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
...baseData,
|
|
118
|
+
content: content,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Updates calculation resource.
|
|
124
|
+
* @template Type The type of the operation being operated on for the given key.
|
|
125
|
+
* @param key Key to modify
|
|
126
|
+
* @param op Operation to perform on 'key'
|
|
127
|
+
* @example
|
|
128
|
+
* // Update the description
|
|
129
|
+
* await calculation.update('description', { name: 'change', to: 'New description' });
|
|
130
|
+
* await calculation.update({ key: 'content', subKey: 'calculation' }, { name: 'change', to: 'new content' });
|
|
131
|
+
*/
|
|
132
|
+
public async update<Type>(key: CalculationUpdateKey, op: Operation<Type>) {
|
|
133
|
+
if (
|
|
134
|
+
typeof key === 'object' &&
|
|
135
|
+
key.key === 'content' &&
|
|
136
|
+
key.subKey === 'calculation'
|
|
137
|
+
) {
|
|
138
|
+
const calculationContent = super.handleScalar(op) as string;
|
|
139
|
+
await this.updateFile(this.calculationsFile, calculationContent);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await super.update(key, op);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* List where calculation resource is used in cards, or other calculation resources.
|
|
147
|
+
* Always returns card key references first, then calculation references.
|
|
148
|
+
*
|
|
149
|
+
* @param cards Optional. Check these cards for usage of this resource. If undefined, will check all cards.
|
|
150
|
+
* @returns array of card keys and calculation filenames that refer this resource.
|
|
151
|
+
*/
|
|
152
|
+
public async usage(cards?: Card[]): Promise<string[]> {
|
|
153
|
+
const allCards = cards || (await super.cards());
|
|
154
|
+
|
|
155
|
+
const [cardContentReferences, calculations] = await Promise.all([
|
|
156
|
+
super.usage(allCards),
|
|
157
|
+
super.calculations(),
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
const cardReferences = cardContentReferences.sort(sortCards);
|
|
161
|
+
return [...new Set([...cardReferences, ...calculations])];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Validates the resource. If object is invalid, throws.
|
|
166
|
+
* @param content Content to validate
|
|
167
|
+
*/
|
|
168
|
+
public async validate(content?: object) {
|
|
169
|
+
return super.validate(content);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -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.
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
Cyberismo
|
|
3
3
|
Copyright © Cyberismo Ltd and contributors 2024
|
|
4
|
+
|
|
4
5
|
This program is free software: you can redistribute it and/or modify it under
|
|
5
6
|
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
-
the Free Software Foundation.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
11
12
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
import type { Card } from '../interfaces/project-interfaces.js';
|
|
15
16
|
import type {
|
|
17
|
+
CalculationMetadata,
|
|
16
18
|
CardType,
|
|
17
19
|
DataType,
|
|
18
20
|
FieldType,
|
|
@@ -70,6 +72,20 @@ export abstract class DefaultContent {
|
|
|
70
72
|
);
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Default content for calculation.
|
|
77
|
+
* @param calculationName calculation name
|
|
78
|
+
* @returns Default content for calculation.
|
|
79
|
+
*/
|
|
80
|
+
static calculation(calculationName: string): CalculationMetadata {
|
|
81
|
+
return {
|
|
82
|
+
name: calculationName,
|
|
83
|
+
displayName: '',
|
|
84
|
+
description: undefined,
|
|
85
|
+
calculation: 'calculation.lp',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
/**
|
|
74
90
|
* Default content for card type.
|
|
75
91
|
* @param cardTypeName card type name
|
|
@@ -433,7 +433,7 @@ export class FieldTypeResource extends FileResource {
|
|
|
433
433
|
|
|
434
434
|
await super.update(key, op);
|
|
435
435
|
|
|
436
|
-
const content = this.content as FieldType;
|
|
436
|
+
const content = structuredClone(this.content) as FieldType;
|
|
437
437
|
if (key === 'name') {
|
|
438
438
|
content.name = super.handleScalar(op) as string;
|
|
439
439
|
} else if (key === 'dataType') {
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
} from './resource-object.js';
|
|
31
31
|
import { DefaultContent } from './create-defaults.js';
|
|
32
32
|
import { deleteFile, pathExists } from '../utils/file-utils.js';
|
|
33
|
+
import { hasCode } from '../utils/error-utils.js';
|
|
33
34
|
import { Project, ResourcesFrom } from '../containers/project.js';
|
|
34
35
|
import {
|
|
35
36
|
readJsonFile,
|
|
@@ -242,6 +243,11 @@ export class FileResource extends ResourceObject {
|
|
|
242
243
|
references.push(calculation.name);
|
|
243
244
|
}
|
|
244
245
|
} catch (error) {
|
|
246
|
+
// Skip files that don't exist (they may have been renamed or deleted)
|
|
247
|
+
if (hasCode(error) && error.code === 'ENOENT') {
|
|
248
|
+
this.logger.warn(`Skipping non-existent file: ${filename}`);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
245
251
|
throw new Error(
|
|
246
252
|
`Failed to process file ${filename}: ${(error as Error).message}`,
|
|
247
253
|
);
|
|
@@ -397,9 +403,9 @@ export class FileResource extends ResourceObject {
|
|
|
397
403
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
398
404
|
_op: Operation<Type>,
|
|
399
405
|
): Promise<void> {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
throw new Error(`Resource '${
|
|
406
|
+
if (!this.data) {
|
|
407
|
+
const name = resourceNameToString(this.resourceName);
|
|
408
|
+
throw new Error(`Resource '${name}' does not exist in the project`);
|
|
403
409
|
}
|
|
404
410
|
if (this.moduleResource) {
|
|
405
411
|
throw new Error(`Cannot update module resources`);
|