@cyberismo/data-handler 0.0.14 → 0.0.16
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 +8 -4
- package/dist/card-metadata-updater.js.map +1 -1
- package/dist/command-handler.d.ts +4 -0
- package/dist/command-handler.js +29 -19
- package/dist/command-handler.js.map +1 -1
- package/dist/command-manager.d.ts +25 -2
- package/dist/command-manager.js +30 -5
- package/dist/command-manager.js.map +1 -1
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.js +45 -93
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/edit.d.ts +1 -15
- package/dist/commands/edit.js +15 -89
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/export.d.ts +11 -2
- package/dist/commands/export.js +58 -58
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +9 -1
- package/dist/commands/import.js +17 -11
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/move.d.ts +1 -2
- package/dist/commands/move.js +107 -146
- package/dist/commands/move.js.map +1 -1
- package/dist/commands/remove.d.ts +8 -1
- package/dist/commands/remove.js +17 -48
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rename.d.ts +4 -9
- package/dist/commands/rename.js +34 -108
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/show.d.ts +22 -34
- package/dist/commands/show.js +103 -151
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/transition.d.ts +9 -2
- package/dist/commands/transition.js +49 -44
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.d.ts +18 -12
- package/dist/commands/update.js +34 -18
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.d.ts +18 -10
- package/dist/commands/validate.js +101 -47
- package/dist/commands/validate.js.map +1 -1
- package/dist/containers/card-container.d.ts +87 -24
- package/dist/containers/card-container.js +183 -279
- package/dist/containers/card-container.js.map +1 -1
- package/dist/containers/project/calculation-engine.d.ts +13 -4
- package/dist/containers/project/calculation-engine.js +79 -77
- package/dist/containers/project/calculation-engine.js.map +1 -1
- package/dist/containers/project/card-cache.d.ts +146 -0
- package/dist/containers/project/card-cache.js +411 -0
- package/dist/containers/project/card-cache.js.map +1 -0
- package/dist/containers/project/project-paths.d.ts +5 -4
- package/dist/containers/project/project-paths.js +16 -12
- package/dist/containers/project/project-paths.js.map +1 -1
- package/dist/containers/project/resource-cache.d.ts +169 -0
- package/dist/containers/project/resource-cache.js +507 -0
- package/dist/containers/project/resource-cache.js.map +1 -0
- package/dist/containers/project/resource-handler.d.ts +129 -0
- package/dist/containers/project/resource-handler.js +206 -0
- package/dist/containers/project/resource-handler.js.map +1 -0
- package/dist/containers/project.d.ts +114 -195
- package/dist/containers/project.js +425 -535
- package/dist/containers/project.js.map +1 -1
- package/dist/containers/template.d.ts +22 -32
- package/dist/containers/template.js +113 -115
- package/dist/containers/template.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/folder-content-interfaces.d.ts +7 -4
- package/dist/interfaces/folder-content-interfaces.js +3 -3
- package/dist/interfaces/folder-content-interfaces.js.map +1 -1
- package/dist/interfaces/macros.d.ts +1 -0
- package/dist/interfaces/macros.js +1 -1
- package/dist/interfaces/macros.js.map +1 -1
- package/dist/interfaces/project-interfaces.d.ts +7 -5
- package/dist/interfaces/project-interfaces.js.map +1 -1
- package/dist/interfaces/resource-interfaces.d.ts +25 -22
- package/dist/interfaces/resource-interfaces.js +3 -0
- package/dist/interfaces/resource-interfaces.js.map +1 -1
- package/dist/macros/common.d.ts +10 -10
- package/dist/macros/createCards/index.d.ts +0 -13
- package/dist/macros/createCards/index.js.map +1 -1
- package/dist/macros/createCards/types.d.ts +44 -0
- package/dist/macros/createCards/types.js +15 -0
- package/dist/macros/createCards/types.js.map +1 -0
- package/dist/macros/graph/index.d.ts +2 -6
- package/dist/macros/graph/index.js +14 -28
- package/dist/macros/graph/index.js.map +1 -1
- package/dist/macros/graph/types.d.ts +23 -0
- package/dist/macros/graph/types.js +15 -0
- package/dist/macros/graph/types.js.map +1 -0
- package/dist/macros/image/index.d.ts +8 -16
- package/dist/macros/image/index.js +36 -33
- package/dist/macros/image/index.js.map +1 -1
- package/dist/macros/image/types.d.ts +38 -0
- package/dist/macros/image/types.js +15 -0
- package/dist/macros/image/types.js.map +1 -0
- package/dist/macros/include/index.d.ts +1 -6
- package/dist/macros/include/index.js +4 -7
- package/dist/macros/include/index.js.map +1 -1
- package/dist/macros/include/types.d.ts +31 -0
- package/dist/macros/include/types.js +15 -0
- package/dist/macros/include/types.js.map +1 -0
- package/dist/macros/index.d.ts +1 -1
- package/dist/macros/index.js +2 -2
- package/dist/macros/index.js.map +1 -1
- package/dist/macros/percentage/index.d.ts +0 -6
- package/dist/macros/percentage/index.js.map +1 -1
- package/dist/macros/percentage/types.d.ts +31 -0
- package/dist/macros/percentage/types.js +15 -0
- package/dist/macros/percentage/types.js.map +1 -0
- package/dist/macros/report/index.d.ts +0 -3
- package/dist/macros/report/index.js +3 -6
- package/dist/macros/report/index.js.map +1 -1
- package/dist/macros/report/types.d.ts +19 -0
- package/dist/macros/report/types.js +15 -0
- package/dist/macros/report/types.js.map +1 -0
- package/dist/macros/scoreCard/index.d.ts +0 -6
- package/dist/macros/scoreCard/index.js.map +1 -1
- package/dist/macros/scoreCard/types.d.ts +31 -0
- package/dist/macros/scoreCard/types.js +15 -0
- package/dist/macros/scoreCard/types.js.map +1 -0
- package/dist/macros/types.d.ts +25 -0
- package/dist/macros/types.js +2 -0
- package/dist/macros/types.js.map +1 -0
- package/dist/macros/vega/index.d.ts +0 -4
- package/dist/macros/vega/index.js.map +1 -1
- package/dist/macros/vega/types.d.ts +20 -0
- package/dist/macros/vega/types.js +2 -0
- package/dist/macros/vega/types.js.map +1 -0
- package/dist/macros/vegalite/index.d.ts +0 -4
- package/dist/macros/vegalite/index.js.map +1 -1
- package/dist/macros/vegalite/types.d.ts +20 -0
- package/dist/macros/vegalite/types.js +15 -0
- package/dist/macros/vegalite/types.js.map +1 -0
- package/dist/macros/xref/index.d.ts +0 -3
- package/dist/macros/xref/index.js +5 -14
- package/dist/macros/xref/index.js.map +1 -1
- package/dist/macros/xref/types.d.ts +19 -0
- package/dist/macros/xref/types.js +15 -0
- package/dist/macros/xref/types.js.map +1 -0
- package/dist/module-manager.d.ts +16 -3
- package/dist/module-manager.js +55 -23
- package/dist/module-manager.js.map +1 -1
- package/dist/project-settings.d.ts +16 -3
- package/dist/project-settings.js +79 -14
- package/dist/project-settings.js.map +1 -1
- package/dist/resources/calculation-resource.d.ts +6 -33
- package/dist/resources/calculation-resource.js +11 -60
- package/dist/resources/calculation-resource.js.map +1 -1
- package/dist/resources/card-type-resource.d.ts +10 -22
- package/dist/resources/card-type-resource.js +46 -66
- package/dist/resources/card-type-resource.js.map +1 -1
- package/dist/resources/create-defaults.d.ts +3 -2
- package/dist/resources/create-defaults.js +3 -2
- package/dist/resources/create-defaults.js.map +1 -1
- package/dist/resources/field-type-resource.d.ts +8 -22
- package/dist/resources/field-type-resource.js +35 -60
- package/dist/resources/field-type-resource.js.map +1 -1
- package/dist/resources/file-resource.d.ts +14 -35
- package/dist/resources/file-resource.js +22 -301
- package/dist/resources/file-resource.js.map +1 -1
- package/dist/resources/folder-resource.d.ts +44 -66
- package/dist/resources/folder-resource.js +102 -149
- package/dist/resources/folder-resource.js.map +1 -1
- package/dist/resources/graph-model-resource.d.ts +9 -34
- package/dist/resources/graph-model-resource.js +18 -64
- package/dist/resources/graph-model-resource.js.map +1 -1
- package/dist/resources/graph-view-resource.d.ts +9 -29
- package/dist/resources/graph-view-resource.js +13 -48
- package/dist/resources/graph-view-resource.js.map +1 -1
- package/dist/resources/link-type-resource.d.ts +9 -23
- package/dist/resources/link-type-resource.js +11 -33
- package/dist/resources/link-type-resource.js.map +1 -1
- package/dist/resources/report-resource.d.ts +10 -23
- package/dist/resources/report-resource.js +20 -67
- package/dist/resources/report-resource.js.map +1 -1
- package/dist/resources/resource-object.d.ts +143 -23
- package/dist/resources/resource-object.js +369 -48
- package/dist/resources/resource-object.js.map +1 -1
- package/dist/resources/template-resource.d.ts +10 -17
- package/dist/resources/template-resource.js +19 -27
- package/dist/resources/template-resource.js.map +1 -1
- package/dist/resources/workflow-resource.d.ts +9 -25
- package/dist/resources/workflow-resource.js +25 -55
- package/dist/resources/workflow-resource.js.map +1 -1
- package/dist/utils/card-utils.d.ts +69 -19
- package/dist/utils/card-utils.js +179 -30
- package/dist/utils/card-utils.js.map +1 -1
- package/dist/utils/clingo-fact-builder.d.ts +25 -14
- package/dist/utils/clingo-fact-builder.js +27 -5
- package/dist/utils/clingo-fact-builder.js.map +1 -1
- package/dist/utils/clingo-facts.js +14 -7
- package/dist/utils/clingo-facts.js.map +1 -1
- package/dist/utils/clingo-parser.js +1 -1
- package/dist/utils/clingo-parser.js.map +1 -1
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +4 -0
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/csv.js +1 -1
- package/dist/utils/csv.js.map +1 -1
- package/dist/utils/resource-utils.d.ts +1 -0
- package/dist/utils/resource-utils.js +2 -1
- package/dist/utils/resource-utils.js.map +1 -1
- package/package.json +11 -11
- package/src/card-metadata-updater.ts +9 -7
- package/src/command-handler.ts +35 -23
- package/src/command-manager.ts +32 -19
- package/src/commands/create.ts +59 -160
- package/src/commands/edit.ts +16 -132
- package/src/commands/export.ts +71 -81
- package/src/commands/import.ts +26 -18
- package/src/commands/move.ts +143 -179
- package/src/commands/remove.ts +20 -59
- package/src/commands/rename.ts +45 -156
- package/src/commands/show.ts +153 -211
- package/src/commands/transition.ts +53 -58
- package/src/commands/update.ts +44 -23
- package/src/commands/validate.ts +108 -82
- package/src/containers/card-container.ts +200 -360
- package/src/containers/project/calculation-engine.ts +81 -105
- package/src/containers/project/card-cache.ts +497 -0
- package/src/containers/project/project-paths.ts +21 -13
- package/src/containers/project/resource-cache.ts +648 -0
- package/src/containers/project/resource-handler.ts +265 -0
- package/src/containers/project.ts +551 -693
- package/src/containers/template.ts +129 -142
- package/src/index.ts +1 -0
- package/src/interfaces/folder-content-interfaces.ts +14 -7
- package/src/interfaces/macros.ts +2 -0
- package/src/interfaces/project-interfaces.ts +14 -7
- package/src/interfaces/resource-interfaces.ts +30 -27
- package/src/macros/createCards/index.ts +1 -12
- package/src/macros/createCards/types.ts +46 -0
- package/src/macros/graph/index.ts +27 -52
- package/src/macros/graph/types.ts +24 -0
- package/src/macros/image/index.ts +50 -61
- package/src/macros/image/types.ts +39 -0
- package/src/macros/include/index.ts +6 -15
- package/src/macros/include/types.ts +32 -0
- package/src/macros/index.ts +2 -2
- package/src/macros/percentage/index.ts +1 -7
- package/src/macros/percentage/types.ts +32 -0
- package/src/macros/report/index.ts +4 -13
- package/src/macros/report/types.ts +20 -0
- package/src/macros/scoreCard/index.ts +1 -7
- package/src/macros/scoreCard/types.ts +32 -0
- package/src/macros/types.ts +48 -0
- package/src/macros/vega/index.ts +1 -4
- package/src/macros/vega/types.ts +21 -0
- package/src/macros/vegalite/index.ts +1 -4
- package/src/macros/vegalite/types.ts +22 -0
- package/src/macros/xref/index.ts +6 -20
- package/src/macros/xref/types.ts +20 -0
- package/src/module-manager.ts +79 -22
- package/src/project-settings.ts +84 -15
- package/src/resources/calculation-resource.ts +21 -91
- package/src/resources/card-type-resource.ts +74 -109
- package/src/resources/create-defaults.ts +3 -2
- package/src/resources/field-type-resource.ts +61 -104
- package/src/resources/file-resource.ts +33 -441
- package/src/resources/folder-resource.ts +130 -207
- package/src/resources/graph-model-resource.ts +36 -95
- package/src/resources/graph-view-resource.ts +28 -70
- package/src/resources/link-type-resource.ts +23 -53
- package/src/resources/report-resource.ts +34 -96
- package/src/resources/resource-object.ts +511 -66
- package/src/resources/template-resource.ts +32 -44
- package/src/resources/workflow-resource.ts +42 -85
- package/src/utils/card-utils.ts +217 -31
- package/src/utils/clingo-fact-builder.ts +28 -16
- package/src/utils/clingo-facts.ts +16 -7
- package/src/utils/clingo-parser.ts +1 -1
- package/src/utils/constants.ts +6 -0
- package/src/utils/csv.ts +1 -1
- package/src/utils/resource-utils.ts +2 -1
- package/dist/containers/project/resource-collector.d.ts +0 -87
- package/dist/containers/project/resource-collector.js +0 -337
- package/dist/containers/project/resource-collector.js.map +0 -1
- package/src/containers/project/resource-collector.ts +0 -396
|
@@ -15,119 +15,59 @@
|
|
|
15
15
|
import { basename, dirname, join, normalize } from 'node:path';
|
|
16
16
|
import { mkdir, readdir, readFile, rename, rm } from 'node:fs/promises';
|
|
17
17
|
|
|
18
|
-
import
|
|
19
|
-
import type {
|
|
20
|
-
ContentUpdateKey,
|
|
21
|
-
ResourceContent,
|
|
22
|
-
UpdateKey,
|
|
23
|
-
} from '../interfaces/resource-interfaces.js';
|
|
24
|
-
import type { ResourceFolderType } from '../interfaces/project-interfaces.js';
|
|
25
|
-
import type { Schema } from 'jsonschema';
|
|
26
|
-
|
|
27
|
-
import {
|
|
28
|
-
DefaultContent,
|
|
29
|
-
FileResource,
|
|
30
|
-
Project,
|
|
31
|
-
resourceName,
|
|
32
|
-
resourceNameToString,
|
|
33
|
-
sortCards,
|
|
34
|
-
} from './file-resource.js';
|
|
18
|
+
import { isContentKey } from '../interfaces/resource-interfaces.js';
|
|
35
19
|
import {
|
|
36
20
|
filename,
|
|
37
|
-
|
|
21
|
+
contentPropertyName,
|
|
38
22
|
} from '../interfaces/folder-content-interfaces.js';
|
|
39
|
-
import {
|
|
23
|
+
import { formatJson } from '../utils/json.js';
|
|
40
24
|
import { VALID_FOLDER_RESOURCE_FILES } from '../utils/constants.js';
|
|
41
25
|
import { writeFileSafe } from '../utils/file-utils.js';
|
|
26
|
+
import { ResourceObject } from './resource-object.js';
|
|
27
|
+
import { resourceName } from '../utils/resource-utils.js';
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
sortCards,
|
|
52
|
-
};
|
|
29
|
+
import type { UpdateKey } from '../interfaces/resource-interfaces.js';
|
|
30
|
+
import type { FolderResourceContent } from '../interfaces/folder-content-interfaces.js';
|
|
31
|
+
import type { Operation } from './resource-object.js';
|
|
32
|
+
import type { Project } from '../containers/project.js';
|
|
33
|
+
import type { ResourceFolderType } from '../interfaces/project-interfaces.js';
|
|
34
|
+
import type { ResourceBaseMetadata } from '../interfaces/resource-interfaces.js';
|
|
35
|
+
import type { ResourceName } from '../utils/resource-utils.js';
|
|
36
|
+
import type { ShowReturnType } from './resource-object.js';
|
|
53
37
|
|
|
54
38
|
/**
|
|
55
|
-
* Folder type resource class.
|
|
39
|
+
* Folder type resource class.
|
|
40
|
+
* These are resources that have their own folders for content.
|
|
56
41
|
*/
|
|
57
|
-
export class FolderResource
|
|
42
|
+
export abstract class FolderResource<
|
|
43
|
+
T extends ResourceBaseMetadata,
|
|
44
|
+
U extends FolderResourceContent,
|
|
45
|
+
> extends ResourceObject<T, U> {
|
|
58
46
|
protected internalFolder: string = '';
|
|
47
|
+
private resourceContent: U = {} as U;
|
|
59
48
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Constructs a FolderResource object.
|
|
51
|
+
* @param project Project in which this resource exists.
|
|
52
|
+
* @param name Name for the resource.
|
|
53
|
+
* @param type Type for this resource.
|
|
54
|
+
*/
|
|
63
55
|
constructor(project: Project, name: ResourceName, type: ResourceFolderType) {
|
|
64
56
|
super(project, name, type);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Clears the content files cache.
|
|
68
|
-
private clearContentCache() {
|
|
69
|
-
this.contentFilesCache.clear();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Type guard to check if a key is a ContentUpdateKey
|
|
73
|
-
private isContentUpdateKey(key: UpdateKey): key is ContentUpdateKey {
|
|
74
|
-
return typeof key === 'object' && key.key === 'content' && 'subKey' in key;
|
|
57
|
+
this.initialize();
|
|
75
58
|
}
|
|
76
59
|
|
|
77
60
|
/**
|
|
78
61
|
* Creates a new folder type object. Base class writes the object to disk automatically.
|
|
79
62
|
* @param newContent Content for the type.
|
|
80
63
|
*/
|
|
81
|
-
protected async create(newContent?:
|
|
64
|
+
protected async create(newContent?: T) {
|
|
65
|
+
// Validate resource identifier before creating on disk
|
|
66
|
+
this.validateResourceIdentifier();
|
|
82
67
|
await super.create(newContent);
|
|
83
68
|
await mkdir(this.internalFolder, { recursive: true });
|
|
84
69
|
}
|
|
85
70
|
|
|
86
|
-
/**
|
|
87
|
-
* Gets content of all files to properties.
|
|
88
|
-
* @returns object with property names as keys and file contents as values.
|
|
89
|
-
*/
|
|
90
|
-
public async contentData(): Promise<Record<string, string | Schema>> {
|
|
91
|
-
const fileNames = await this.showFileNames();
|
|
92
|
-
const content: Record<string, string | Schema> = {};
|
|
93
|
-
|
|
94
|
-
for (const fileName of fileNames) {
|
|
95
|
-
const name = propertyName(fileName);
|
|
96
|
-
if (name) {
|
|
97
|
-
const JSONFile = name === 'schema';
|
|
98
|
-
content[name] = await this.showFile(fileName, JSONFile);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return content;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Returns content data.
|
|
107
|
-
*/
|
|
108
|
-
public get data() {
|
|
109
|
-
return super.data;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Deletes file(s) from disk and clears out the memory resident object.
|
|
114
|
-
*/
|
|
115
|
-
protected async delete() {
|
|
116
|
-
await super.delete();
|
|
117
|
-
await rm(this.internalFolder, { recursive: true, force: true });
|
|
118
|
-
this.clearContentCache();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Get (resource folder) type name
|
|
122
|
-
protected get getType() {
|
|
123
|
-
return super.getType;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Get logger instance
|
|
127
|
-
protected get logger() {
|
|
128
|
-
return super.getLogger(this.getType);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
71
|
/**
|
|
132
72
|
* Initialize the resource item.
|
|
133
73
|
*/
|
|
@@ -141,85 +81,42 @@ export class FolderResource extends FileResource {
|
|
|
141
81
|
}
|
|
142
82
|
|
|
143
83
|
/**
|
|
144
|
-
*
|
|
145
|
-
* @param
|
|
146
|
-
*/
|
|
147
|
-
protected async rename(newName: ResourceName) {
|
|
148
|
-
return super.rename(newName);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Shows metadata of the resource.
|
|
153
|
-
* @returns resource type's metadata.
|
|
154
|
-
*/
|
|
155
|
-
protected async show(): Promise<ResourceContent> {
|
|
156
|
-
return super.show();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* TODO: to be made protected - no direct access to files
|
|
161
|
-
* Shows the content of a file in the resource.
|
|
162
|
-
* @param fileName Name of the file to show.
|
|
163
|
-
* @param json Content is JSON file.
|
|
164
|
-
* @returns the content of the file.
|
|
84
|
+
* For handling name changes.
|
|
85
|
+
* @param previousName The previous name before the change
|
|
165
86
|
*/
|
|
166
|
-
|
|
167
|
-
fileName: string,
|
|
168
|
-
json: boolean = false,
|
|
169
|
-
): Promise<string> {
|
|
170
|
-
// Always first check cache...
|
|
171
|
-
if (this.contentFilesCache.has(fileName)) {
|
|
172
|
-
const cached = this.contentFilesCache.get(fileName)!;
|
|
173
|
-
return json ? JSON.parse(cached) : cached;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ...cache miss, read from filesystem
|
|
177
|
-
const filePath = join(this.internalFolder, fileName);
|
|
178
|
-
const content = json
|
|
179
|
-
? await readJsonFile(filePath)
|
|
180
|
-
: await readFile(filePath, 'utf8');
|
|
181
|
-
|
|
182
|
-
// Update cache
|
|
183
|
-
const contentStr =
|
|
184
|
-
typeof content === 'string' ? content : JSON.stringify(content, null, 2);
|
|
185
|
-
this.contentFilesCache.set(fileName, contentStr);
|
|
186
|
-
|
|
187
|
-
return json ? content : contentStr;
|
|
188
|
-
}
|
|
87
|
+
protected abstract onNameChange?(previousName: string): Promise<void>;
|
|
189
88
|
|
|
190
89
|
/**
|
|
191
|
-
*
|
|
192
|
-
* Shows all file names in the resource.
|
|
193
|
-
* @returns all file names in the resource.
|
|
90
|
+
* Set content files. Should not be called by others than resource cache.
|
|
194
91
|
*/
|
|
195
|
-
public
|
|
196
|
-
|
|
197
|
-
if (this.contentFilesCache.size > 0) {
|
|
198
|
-
return Array.from(this.contentFilesCache.keys());
|
|
199
|
-
}
|
|
92
|
+
public setContentFiles(contentFiles: Map<string, string>) {
|
|
93
|
+
const content = {} as Record<string, unknown>;
|
|
200
94
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// Update cache by reading all files. Each method call updates specific cache item.
|
|
208
|
-
for (const fileName of validFiles) {
|
|
209
|
-
await this.showFile(fileName);
|
|
95
|
+
for (const [fileName, fileContent] of contentFiles.entries()) {
|
|
96
|
+
const key = contentPropertyName(fileName);
|
|
97
|
+
if (key) {
|
|
98
|
+
const isJson = key === 'schema';
|
|
99
|
+
content[key] = isJson ? JSON.parse(fileContent) : fileContent;
|
|
100
|
+
}
|
|
210
101
|
}
|
|
211
102
|
|
|
212
|
-
|
|
103
|
+
this.resourceContent = content as U;
|
|
213
104
|
}
|
|
214
105
|
|
|
215
106
|
/**
|
|
216
|
-
*
|
|
217
|
-
* @param contentFiles Object with file names as keys and file contents as values.
|
|
107
|
+
* Load all content files from the internal folder and set them.
|
|
218
108
|
*/
|
|
219
|
-
protected async
|
|
220
|
-
|
|
221
|
-
|
|
109
|
+
protected async loadContentFiles() {
|
|
110
|
+
const contentFiles = new Map<string, string>();
|
|
111
|
+
const files = await readdir(this.internalFolder, { withFileTypes: true });
|
|
112
|
+
for (const file of files) {
|
|
113
|
+
if (file.isFile() && VALID_FOLDER_RESOURCE_FILES.includes(file.name)) {
|
|
114
|
+
const filePath = join(this.internalFolder, file.name);
|
|
115
|
+
const content = await readFile(filePath, 'utf-8');
|
|
116
|
+
contentFiles.set(file.name, content);
|
|
117
|
+
}
|
|
222
118
|
}
|
|
119
|
+
this.setContentFiles(contentFiles);
|
|
223
120
|
}
|
|
224
121
|
|
|
225
122
|
/**
|
|
@@ -227,7 +124,7 @@ export class FolderResource extends FileResource {
|
|
|
227
124
|
* @param fileName The name of the file to update.
|
|
228
125
|
* @param changedContent The new content for the file.
|
|
229
126
|
*/
|
|
230
|
-
|
|
127
|
+
public async updateFile(fileName: string, changedContent: string) {
|
|
231
128
|
const filePath = join(this.internalFolder, fileName);
|
|
232
129
|
|
|
233
130
|
// Do not allow updating file in other directories
|
|
@@ -243,32 +140,96 @@ export class FolderResource extends FileResource {
|
|
|
243
140
|
}
|
|
244
141
|
// check if the file is allow-listed
|
|
245
142
|
if (!VALID_FOLDER_RESOURCE_FILES.includes(fileName)) {
|
|
246
|
-
throw new Error(`File '${fileName}' is not allowed`);
|
|
143
|
+
throw new Error(`File '${fileName}' is not allowed to be updated`);
|
|
247
144
|
}
|
|
248
145
|
|
|
249
146
|
await writeFileSafe(filePath, changedContent, { flag: 'w' });
|
|
250
147
|
|
|
251
|
-
// Update
|
|
252
|
-
|
|
148
|
+
// Update this resource's content
|
|
149
|
+
const key = contentPropertyName(fileName);
|
|
150
|
+
if (key) {
|
|
151
|
+
const isJson = key === 'schema';
|
|
152
|
+
(this.resourceContent as Record<string, unknown>)[key] = isJson
|
|
153
|
+
? JSON.parse(changedContent)
|
|
154
|
+
: changedContent;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Writes resource content to disk.
|
|
160
|
+
*/
|
|
161
|
+
protected async write() {
|
|
162
|
+
const folderName = basename(this.internalFolder);
|
|
163
|
+
|
|
164
|
+
// Check if "name" has changed. Changing "name" means renaming the file.
|
|
165
|
+
const nameInContent = resourceName(this.content.name).identifier;
|
|
166
|
+
if (folderName !== nameInContent) {
|
|
167
|
+
const newFolderName = join(this.resourceFolder, nameInContent);
|
|
168
|
+
await rename(this.internalFolder, newFolderName);
|
|
169
|
+
this.internalFolder = newFolderName;
|
|
170
|
+
}
|
|
171
|
+
return super.write();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gets content of all files to properties.
|
|
176
|
+
* @returns object with property names as keys and file contents as values.
|
|
177
|
+
*/
|
|
178
|
+
public contentData(): U {
|
|
179
|
+
// TODO: Instead of casting, validate that content matches U
|
|
180
|
+
// This requires a runtime schema for U to be defined(via an abstract variable)
|
|
181
|
+
|
|
182
|
+
return this.resourceContent;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Deletes file and content folder from disk and clears out the memory resident object.
|
|
187
|
+
*/
|
|
188
|
+
public async delete() {
|
|
189
|
+
await super.delete();
|
|
190
|
+
await rm(this.internalFolder, { recursive: true, force: true });
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Shows metadata of the resource and content of the resource.
|
|
195
|
+
* @template T Resource type
|
|
196
|
+
* @template U Resource content
|
|
197
|
+
* @returns resource type's metadata and content.
|
|
198
|
+
*/
|
|
199
|
+
public show(): ShowReturnType<T, U> {
|
|
200
|
+
this.assertResourceExists();
|
|
201
|
+
return {
|
|
202
|
+
...this.content,
|
|
203
|
+
content: this.contentData(),
|
|
204
|
+
};
|
|
253
205
|
}
|
|
254
206
|
|
|
255
207
|
/**
|
|
256
208
|
* Updates resource.
|
|
257
|
-
* @param
|
|
209
|
+
* @param updateKey Key to modify
|
|
258
210
|
* @param op Operation to perform on 'key'
|
|
259
211
|
* @throws if key is unknown.
|
|
260
212
|
*/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
213
|
+
public async update<Type, K extends string>(
|
|
214
|
+
updateKey: UpdateKey<K>,
|
|
215
|
+
op: Operation<Type>,
|
|
216
|
+
) {
|
|
217
|
+
const { key } = updateKey;
|
|
218
|
+
if (isContentKey(updateKey)) {
|
|
219
|
+
const fileName = filename(updateKey.subKey)!;
|
|
220
|
+
const fileContent = super.handleScalar(op);
|
|
221
|
+
const fileContentString =
|
|
222
|
+
typeof fileContent === 'string'
|
|
223
|
+
? fileContent
|
|
224
|
+
: formatJson(fileContent as object); // TODO: Fix operation types. In practice, content files are either strings or objects
|
|
225
|
+
|
|
226
|
+
await this.updateFile(fileName, fileContentString);
|
|
266
227
|
return;
|
|
267
228
|
}
|
|
268
229
|
|
|
269
230
|
const nameChange = key === 'name';
|
|
270
231
|
const existingName = this.content.name;
|
|
271
|
-
await super.update(
|
|
232
|
+
await super.update(updateKey, op);
|
|
272
233
|
const content = structuredClone(this.content);
|
|
273
234
|
|
|
274
235
|
if (key === 'name') {
|
|
@@ -281,48 +242,10 @@ export class FolderResource extends FileResource {
|
|
|
281
242
|
throw new Error(`Unknown property '${key}' for folder resource`);
|
|
282
243
|
}
|
|
283
244
|
|
|
284
|
-
await super.postUpdate(content,
|
|
245
|
+
await super.postUpdate(content, updateKey, op);
|
|
285
246
|
|
|
286
247
|
if (nameChange) {
|
|
287
248
|
await this.onNameChange?.(existingName);
|
|
288
249
|
}
|
|
289
250
|
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* For handling name changes.
|
|
293
|
-
* @param previousName The previous name before the change
|
|
294
|
-
*/
|
|
295
|
-
protected async onNameChange?(previousName: string): Promise<void>;
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Returns an array of card keys, and/or resource names where this resource is used.
|
|
299
|
-
* @param cards Optional. If defined, only these cards are checked.
|
|
300
|
-
* @returns an array of card keys, and/or resource names where this resource is used.
|
|
301
|
-
*/
|
|
302
|
-
protected async usage(cards?: Card[]): Promise<string[]> {
|
|
303
|
-
return super.usage(cards);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Writes resource content to disk.
|
|
308
|
-
*/
|
|
309
|
-
protected async write() {
|
|
310
|
-
const folderName = basename(this.internalFolder);
|
|
311
|
-
|
|
312
|
-
// Check if "name" has changed. Changing "name" means renaming the file.
|
|
313
|
-
const nameInContent = resourceName(this.content.name).identifier;
|
|
314
|
-
if (folderName !== nameInContent) {
|
|
315
|
-
const newFolderName = join(this.resourceFolder, nameInContent);
|
|
316
|
-
await rename(this.internalFolder, newFolderName);
|
|
317
|
-
this.internalFolder = newFolderName;
|
|
318
|
-
}
|
|
319
|
-
return super.write();
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Validates the resource. If object is invalid, throws.
|
|
324
|
-
*/
|
|
325
|
-
protected async validate(content?: object) {
|
|
326
|
-
return super.validate(content);
|
|
327
|
-
}
|
|
328
251
|
}
|
|
@@ -12,40 +12,37 @@
|
|
|
12
12
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import { extname, join } from 'node:path';
|
|
15
|
+
import { join } from 'node:path';
|
|
17
16
|
|
|
17
|
+
import { DefaultContent } from './create-defaults.js';
|
|
18
|
+
import { FolderResource } from './folder-resource.js';
|
|
19
|
+
import { resourceNameToString } from '../utils/resource-utils.js';
|
|
20
|
+
import { sortCards } from '../utils/card-utils.js';
|
|
21
|
+
import { writeFileSafe } from '../utils/file-utils.js';
|
|
22
|
+
import { CONTENT_FILES } from '../interfaces/folder-content-interfaces.js';
|
|
23
|
+
|
|
24
|
+
import type { Card } from '../interfaces/project-interfaces.js';
|
|
18
25
|
import type {
|
|
19
|
-
Card,
|
|
20
|
-
Operation,
|
|
21
|
-
Project,
|
|
22
|
-
ResourceName,
|
|
23
|
-
} from './folder-resource.js';
|
|
24
|
-
import {
|
|
25
|
-
DefaultContent,
|
|
26
|
-
FolderResource,
|
|
27
|
-
resourceNameToString,
|
|
28
|
-
sortCards,
|
|
29
|
-
} from './folder-resource.js';
|
|
30
|
-
import type {
|
|
31
|
-
GraphModel,
|
|
32
26
|
GraphModelMetadata,
|
|
33
|
-
|
|
27
|
+
UpdateKey,
|
|
34
28
|
} from '../interfaces/resource-interfaces.js';
|
|
35
29
|
import type { GraphModelContent } from '../interfaces/folder-content-interfaces.js';
|
|
36
|
-
import {
|
|
30
|
+
import type { Operation } from './resource-object.js';
|
|
31
|
+
import type { Project } from '../containers/project.js';
|
|
32
|
+
import type { ResourceName } from '../utils/resource-utils.js';
|
|
37
33
|
|
|
38
34
|
/**
|
|
39
35
|
* Graph model resource class.
|
|
40
36
|
*/
|
|
41
|
-
export class GraphModelResource extends FolderResource
|
|
37
|
+
export class GraphModelResource extends FolderResource<
|
|
38
|
+
GraphModelMetadata,
|
|
39
|
+
GraphModelContent
|
|
40
|
+
> {
|
|
42
41
|
constructor(project: Project, name: ResourceName) {
|
|
43
42
|
super(project, name, 'graphModels');
|
|
44
43
|
|
|
45
44
|
this.contentSchemaId = 'graphModelSchema';
|
|
46
45
|
this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
|
|
47
|
-
|
|
48
|
-
this.initialize();
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
/**
|
|
@@ -55,7 +52,7 @@ export class GraphModelResource extends FolderResource {
|
|
|
55
52
|
protected async onNameChange(existingName: string): Promise<void> {
|
|
56
53
|
await Promise.all([
|
|
57
54
|
super.updateHandleBars(existingName, this.content.name, [
|
|
58
|
-
|
|
55
|
+
join(this.internalFolder, CONTENT_FILES.model),
|
|
59
56
|
]),
|
|
60
57
|
super.updateCalculations(existingName, this.content.name),
|
|
61
58
|
]);
|
|
@@ -80,44 +77,14 @@ export class GraphModelResource extends FolderResource {
|
|
|
80
77
|
await super.create(newContent);
|
|
81
78
|
|
|
82
79
|
// Create the internal folder in 'create', instead of 'write'.
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Returns resource content.
|
|
95
|
-
*/
|
|
96
|
-
public get data(): GraphModel {
|
|
97
|
-
return super.data as GraphModel;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Deletes file and folder that this resource is based on.
|
|
102
|
-
*/
|
|
103
|
-
public async delete() {
|
|
104
|
-
return super.delete();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Returns calculation file that this graph model has.
|
|
109
|
-
* @returns calculation file name that this graph model has.
|
|
110
|
-
*/
|
|
111
|
-
public async calculationFile(nameOnly: boolean = false): Promise<string> {
|
|
112
|
-
return (
|
|
113
|
-
await readdir(this.internalFolder, {
|
|
114
|
-
withFileTypes: true,
|
|
115
|
-
recursive: true,
|
|
116
|
-
})
|
|
117
|
-
)
|
|
118
|
-
.filter((dirent) => dirent.isFile() && extname(dirent.name) === '.lp')
|
|
119
|
-
.map((item) => (nameOnly ? item.name : join(item.parentPath, item.name)))
|
|
120
|
-
.at(0)!;
|
|
80
|
+
const modelContent = `% add your calculations here for '${this.resourceName.identifier}'`;
|
|
81
|
+
const modelFile = CONTENT_FILES.model;
|
|
82
|
+
const calculationsFile = join(this.internalFolder, modelFile);
|
|
83
|
+
await writeFileSafe(calculationsFile, modelContent, {
|
|
84
|
+
flag: 'wx',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await this.loadContentFiles();
|
|
121
88
|
}
|
|
122
89
|
|
|
123
90
|
/**
|
|
@@ -130,33 +97,24 @@ export class GraphModelResource extends FolderResource {
|
|
|
130
97
|
return this.onNameChange(existingName);
|
|
131
98
|
}
|
|
132
99
|
|
|
133
|
-
/**
|
|
134
|
-
* Shows metadata of the resource.
|
|
135
|
-
* @returns graph model metadata.
|
|
136
|
-
*/
|
|
137
|
-
public async show(): Promise<GraphModel> {
|
|
138
|
-
const baseData = (await super.show()) as GraphModelMetadata;
|
|
139
|
-
return {
|
|
140
|
-
...baseData,
|
|
141
|
-
content: (await super.contentData()) as GraphModelContent,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
100
|
/**
|
|
146
101
|
* Updates graph model resource.
|
|
147
|
-
* @param
|
|
102
|
+
* @param updateKey Key to modify
|
|
148
103
|
* @param op Operation to perform on 'key'
|
|
149
104
|
*/
|
|
150
|
-
public async update<Type
|
|
151
|
-
|
|
152
|
-
|
|
105
|
+
public async update<Type, K extends string>(
|
|
106
|
+
updateKey: UpdateKey<K>,
|
|
107
|
+
op: Operation<Type>,
|
|
108
|
+
) {
|
|
109
|
+
if (updateKey.key === 'category') {
|
|
110
|
+
const content = structuredClone(this.content);
|
|
153
111
|
content.category = super.handleScalar(op) as string;
|
|
154
112
|
|
|
155
|
-
await super.postUpdate(content,
|
|
113
|
+
await super.postUpdate(content, updateKey, op);
|
|
156
114
|
return;
|
|
157
115
|
}
|
|
158
116
|
|
|
159
|
-
await super.update(
|
|
117
|
+
await super.update(updateKey, op);
|
|
160
118
|
}
|
|
161
119
|
|
|
162
120
|
/**
|
|
@@ -167,28 +125,11 @@ export class GraphModelResource extends FolderResource {
|
|
|
167
125
|
* @returns array of card keys and calculation filenames that refer this resource.
|
|
168
126
|
*/
|
|
169
127
|
public async usage(cards?: Card[]): Promise<string[]> {
|
|
170
|
-
const allCards = cards ??
|
|
128
|
+
const allCards = cards ?? super.cards();
|
|
171
129
|
const [relevantCards, calculations] = await Promise.all([
|
|
172
130
|
super.usage(allCards),
|
|
173
131
|
super.calculations(),
|
|
174
132
|
]);
|
|
175
133
|
return [...relevantCards.sort(sortCards), ...calculations];
|
|
176
134
|
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Validates graphModel.
|
|
180
|
-
* @throws when there are validation errors.
|
|
181
|
-
* @param content Content to be validated.
|
|
182
|
-
* @note If content is not provided, base class validation will use resource's current content.
|
|
183
|
-
*/
|
|
184
|
-
public async validate(content?: object) {
|
|
185
|
-
return super.validate(content);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Create the graph model's folder and calculation file.
|
|
190
|
-
*/
|
|
191
|
-
public async write() {
|
|
192
|
-
await super.write();
|
|
193
|
-
}
|
|
194
135
|
}
|