@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
|
@@ -13,25 +13,39 @@
|
|
|
13
13
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
14
14
|
|
|
15
15
|
// node
|
|
16
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
16
|
+
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
17
17
|
import { basename, join } from 'node:path';
|
|
18
18
|
|
|
19
|
-
import { hasCode } from '../utils/error-utils.js';
|
|
20
|
-
|
|
21
19
|
import { ArrayHandler } from './array-handler.js';
|
|
20
|
+
import { deleteFile, pathExists } from '../utils/file-utils.js';
|
|
21
|
+
import { getChildLogger } from '../utils/log-utils.js';
|
|
22
|
+
import {
|
|
23
|
+
readJsonFile,
|
|
24
|
+
readJsonFileSync,
|
|
25
|
+
writeJsonFile,
|
|
26
|
+
} from '../utils/json.js';
|
|
27
|
+
import {
|
|
28
|
+
resourceName,
|
|
29
|
+
resourceNameToPath,
|
|
30
|
+
resourceNameToString,
|
|
31
|
+
type ResourceName,
|
|
32
|
+
} from '../utils/resource-utils.js';
|
|
33
|
+
import { ResourcesFrom } from '../containers/project.js';
|
|
34
|
+
|
|
22
35
|
import type {
|
|
23
36
|
Card,
|
|
24
37
|
ResourceFolderType,
|
|
25
38
|
} from '../interfaces/project-interfaces.js';
|
|
26
39
|
import type { Logger } from 'pino';
|
|
27
|
-
import {
|
|
28
|
-
import type {
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
import type { Project } from '../containers/project.js';
|
|
41
|
+
import type {
|
|
42
|
+
ResourceBaseMetadata,
|
|
43
|
+
UpdateKey,
|
|
44
|
+
} from '../interfaces/resource-interfaces.js';
|
|
45
|
+
import type { Validate } from '../commands/validate.js';
|
|
31
46
|
|
|
32
47
|
// Possible operations to perform when doing "update"
|
|
33
48
|
export type UpdateOperations = 'add' | 'change' | 'rank' | 'remove';
|
|
34
|
-
//| 'elementTypeChange';
|
|
35
49
|
|
|
36
50
|
// Base class for update operations.
|
|
37
51
|
type BaseOperation<T> = {
|
|
@@ -80,18 +94,29 @@ export type OperationMap<T> = {
|
|
|
80
94
|
// Given an operation name, get the corresponding operation type
|
|
81
95
|
export type OperationFor<T, N extends UpdateOperations> = OperationMap<T>[N];
|
|
82
96
|
|
|
97
|
+
// T, but U is in the content field
|
|
98
|
+
export type ShowReturnType<T extends ResourceBaseMetadata, U = never> = Omit<
|
|
99
|
+
T,
|
|
100
|
+
'content'
|
|
101
|
+
> & {
|
|
102
|
+
[K in 'content' as [U] extends [never] ? never : K]: U;
|
|
103
|
+
};
|
|
104
|
+
|
|
83
105
|
/**
|
|
84
106
|
* Abstract class for resources.
|
|
85
107
|
*/
|
|
86
|
-
export abstract class AbstractResource
|
|
108
|
+
export abstract class AbstractResource<
|
|
109
|
+
T extends ResourceBaseMetadata,
|
|
110
|
+
U = never, // determines type returned by show()
|
|
111
|
+
> {
|
|
87
112
|
protected abstract calculate(): Promise<void>; // update resource specific calculations
|
|
88
|
-
protected abstract create(content?:
|
|
113
|
+
protected abstract create(content?: T): Promise<void>; // create a new with the content (memory)
|
|
89
114
|
protected abstract delete(): Promise<void>; // delete from disk
|
|
90
115
|
protected abstract read(): Promise<void>; // read content from disk (replaces existing content, if any)
|
|
91
116
|
protected abstract rename(newName: ResourceName): Promise<void>; // change name of the resource and filename; same as update('name', ...)
|
|
92
|
-
protected abstract show():
|
|
93
|
-
protected abstract update<Type>(
|
|
94
|
-
|
|
117
|
+
protected abstract show(): ShowReturnType<T, U>; // return the content as JSON
|
|
118
|
+
protected abstract update<Type, K extends string>(
|
|
119
|
+
updateKey: UpdateKey<K>,
|
|
95
120
|
operation: Operation<Type>,
|
|
96
121
|
): Promise<void>; // change one key of resource
|
|
97
122
|
protected abstract usage(cards?: Card[]): Promise<string[]>; // list of card keys or resource names where this resource is used in
|
|
@@ -102,47 +127,124 @@ export abstract class AbstractResource {
|
|
|
102
127
|
protected abstract getLogger(loggerName: string): Logger;
|
|
103
128
|
}
|
|
104
129
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
130
|
+
type ValidateInstance = InstanceType<typeof Validate>;
|
|
131
|
+
|
|
132
|
+
export abstract class ResourceObject<
|
|
133
|
+
T extends ResourceBaseMetadata,
|
|
134
|
+
U,
|
|
135
|
+
> extends AbstractResource<T, U> {
|
|
136
|
+
private static validateInstancePromise?: Promise<ValidateInstance>;
|
|
137
|
+
|
|
138
|
+
protected content: T;
|
|
109
139
|
protected moduleResource: boolean;
|
|
110
140
|
protected contentSchema: JSON = {} as JSON;
|
|
111
141
|
protected contentSchemaId: string = '';
|
|
112
142
|
protected type: ResourceFolderType = '' as ResourceFolderType;
|
|
113
143
|
protected resourceFolder: string = '';
|
|
144
|
+
protected logger: Logger;
|
|
114
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Path to the resource metadata file (the .json file).
|
|
148
|
+
*/
|
|
149
|
+
public fileName: string = '';
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Constructs a ResourceObject instance
|
|
153
|
+
* @param project Project where this resource is
|
|
154
|
+
* @param resourceName Name for the resource
|
|
155
|
+
* @param type Type of resource
|
|
156
|
+
*/
|
|
115
157
|
constructor(
|
|
116
158
|
protected project: Project,
|
|
117
159
|
protected resourceName: ResourceName,
|
|
160
|
+
type: ResourceFolderType,
|
|
118
161
|
) {
|
|
119
162
|
super();
|
|
120
163
|
this.moduleResource =
|
|
121
164
|
this.resourceName.prefix !== this.project.projectPrefix;
|
|
165
|
+
this.type = type;
|
|
166
|
+
this.logger = this.getLogger(this.getType);
|
|
167
|
+
this.content = { name: '' } as T; // not found if name is empty
|
|
122
168
|
}
|
|
123
169
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
protected async show(): Promise<ResourceContent> {
|
|
130
|
-
return {} as ResourceContent;
|
|
170
|
+
// Check if resource already exists. First checks the cache, then filesystem.
|
|
171
|
+
private exists(): boolean {
|
|
172
|
+
const name = resourceNameToString(this.resourceName);
|
|
173
|
+
const existsInCache = this.project.resources.exists(name);
|
|
174
|
+
return existsInCache || pathExists(this.fileName);
|
|
131
175
|
}
|
|
132
|
-
|
|
176
|
+
|
|
177
|
+
// Gets Validate command instance.
|
|
178
|
+
private static async getValidate(): Promise<ValidateInstance> {
|
|
179
|
+
// a bit hacky solution to avoid circular dependencies
|
|
180
|
+
if (!this.validateInstancePromise) {
|
|
181
|
+
this.validateInstancePromise = import('../commands/validate.js').then(
|
|
182
|
+
({ Validate }) => Validate.getInstance(),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
return this.validateInstancePromise;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Gets handlebar files.
|
|
189
|
+
private async reportHandlerBarFiles(from: ResourcesFrom = ResourcesFrom.all) {
|
|
190
|
+
const reports = this.project.resources.reports(from);
|
|
191
|
+
const handleBarFiles: string[] = [];
|
|
192
|
+
for (const report of reports) {
|
|
193
|
+
handleBarFiles.push(...(await report.handleBarFiles()));
|
|
194
|
+
}
|
|
195
|
+
return handleBarFiles;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Type of resource.
|
|
199
|
+
private resourceType(): ResourceFolderType {
|
|
133
200
|
return this.type;
|
|
134
201
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Checks if resource exists.
|
|
205
|
+
* This should only throw, if someone creates resources directly; ie. not through the cache
|
|
206
|
+
* @throws if resource does not exist
|
|
207
|
+
*/
|
|
208
|
+
protected assertResourceExists() {
|
|
209
|
+
if (!this.exists()) {
|
|
210
|
+
const resourceType = `${this.type[0].toUpperCase()}${this.type.slice(1, this.type.length - 1)}`;
|
|
211
|
+
const name = resourceNameToString(this.resourceName);
|
|
212
|
+
throw new Error(
|
|
213
|
+
`${resourceType} '${name}' does not exist in the project`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
139
216
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Calculate; empty implementation.
|
|
220
|
+
*/
|
|
221
|
+
protected async calculate() {}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Calculations that use this resource.
|
|
225
|
+
* @throws if accessing calculations files failed
|
|
226
|
+
*/
|
|
227
|
+
protected async calculations(): Promise<string[]> {
|
|
228
|
+
const references: string[] = [];
|
|
229
|
+
const resourceName = resourceNameToString(this.resourceName);
|
|
230
|
+
for (const calculation of this.project.resources.calculations()) {
|
|
231
|
+
const content = calculation.contentData();
|
|
232
|
+
if (content.calculation && content.calculation.includes(resourceName)) {
|
|
233
|
+
references.push(calculation.data!.name);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return references;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Cards from project.
|
|
241
|
+
*/
|
|
242
|
+
protected cards(): Card[] {
|
|
243
|
+
return [
|
|
244
|
+
...this.project.cards(undefined),
|
|
245
|
+
...this.project.allTemplateCards(),
|
|
246
|
+
];
|
|
143
247
|
}
|
|
144
|
-
protected async validate(_content?: object) {}
|
|
145
|
-
protected async write() {}
|
|
146
248
|
|
|
147
249
|
/**
|
|
148
250
|
* Returns .schema content file.
|
|
@@ -158,12 +260,81 @@ export class ResourceObject extends AbstractResource {
|
|
|
158
260
|
] as unknown as JSON;
|
|
159
261
|
}
|
|
160
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Creates resource.
|
|
265
|
+
* @param newContent Content for resource.
|
|
266
|
+
* @throws when resource already exists in the project.
|
|
267
|
+
*/
|
|
268
|
+
protected async create(newContent?: T) {
|
|
269
|
+
this.validateResourceIdentifier();
|
|
270
|
+
|
|
271
|
+
if (this.exists()) {
|
|
272
|
+
throw new Error(
|
|
273
|
+
`Resource '${this.resourceName.identifier}' already exists in the project`,
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (this.resourceFolder === '') {
|
|
278
|
+
this.resourceName = resourceName(
|
|
279
|
+
`${this.project.projectPrefix}/${this.type}/${this.resourceName.identifier}`,
|
|
280
|
+
);
|
|
281
|
+
this.resourceFolder = this.project.paths.resourcePath(
|
|
282
|
+
this.resourceName.type as ResourceFolderType,
|
|
283
|
+
);
|
|
284
|
+
this.fileName = join(
|
|
285
|
+
this.resourceFolder,
|
|
286
|
+
this.resourceName.identifier + '.json',
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const validator = await ResourceObject.getValidate();
|
|
291
|
+
const validName = validator.validResourceName(
|
|
292
|
+
this.resourceType(),
|
|
293
|
+
resourceNameToString(this.resourceName),
|
|
294
|
+
this.project.projectPrefixes(),
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
let validContent = {} as T;
|
|
298
|
+
if (newContent) {
|
|
299
|
+
validContent = newContent;
|
|
300
|
+
validContent.name = validName;
|
|
301
|
+
} else {
|
|
302
|
+
validContent.description = '';
|
|
303
|
+
validContent.displayName = '';
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this.content = validContent;
|
|
307
|
+
await this.write();
|
|
308
|
+
|
|
309
|
+
const resourceString = resourceNameToString(this.resourceName);
|
|
310
|
+
this.project.resources.add(resourceString, this);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Gets a logger instance.
|
|
315
|
+
* @param loggerName
|
|
316
|
+
* @returns logger instance
|
|
317
|
+
*/
|
|
318
|
+
protected getLogger(loggerName: string): Logger {
|
|
319
|
+
return getChildLogger({
|
|
320
|
+
module: loggerName,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Returns type of this resource.
|
|
326
|
+
*/
|
|
327
|
+
protected get getType(): string {
|
|
328
|
+
return this.type;
|
|
329
|
+
}
|
|
330
|
+
|
|
161
331
|
/**
|
|
162
332
|
* Handles operation to an array.
|
|
163
333
|
* @param operation Operation to perform on array.
|
|
164
334
|
* @param arrayName Name of the array, for error messages.
|
|
165
335
|
* @param array Array to be updated.
|
|
166
336
|
* @returns Changed array after the operation.
|
|
337
|
+
* @throws when operation cannot be done.
|
|
167
338
|
*/
|
|
168
339
|
protected handleArray<Type>(
|
|
169
340
|
operation: Operation<Type>,
|
|
@@ -188,6 +359,7 @@ export class ResourceObject extends AbstractResource {
|
|
|
188
359
|
* Updates scalar value. The only accepted operation is 'change'
|
|
189
360
|
* @param operation Operation to perform on scalar.
|
|
190
361
|
* @returns What the scalar should be changed to.
|
|
362
|
+
* @throws when operation cannot be done
|
|
191
363
|
*/
|
|
192
364
|
protected handleScalar<Type>(operation: Operation<Type>): Type {
|
|
193
365
|
if (
|
|
@@ -197,13 +369,185 @@ export class ResourceObject extends AbstractResource {
|
|
|
197
369
|
) {
|
|
198
370
|
throw new Error(`Cannot do operation ${operation.name} on scalar value`);
|
|
199
371
|
}
|
|
200
|
-
return
|
|
372
|
+
return operation.to;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Initialize the resource.
|
|
377
|
+
*/
|
|
378
|
+
protected initialize() {
|
|
379
|
+
if (this.resourceName.type === '') {
|
|
380
|
+
this.resourceName.type = this.type;
|
|
381
|
+
}
|
|
382
|
+
if (this.resourceName.prefix === '') {
|
|
383
|
+
this.resourceName.prefix = this.project.projectPrefix;
|
|
384
|
+
}
|
|
385
|
+
if (this.type) {
|
|
386
|
+
this.moduleResource =
|
|
387
|
+
this.resourceName.prefix !== this.project.projectPrefix;
|
|
388
|
+
this.resourceFolder = this.moduleResource
|
|
389
|
+
? join(
|
|
390
|
+
this.project.paths.modulesFolder,
|
|
391
|
+
this.resourceName.prefix,
|
|
392
|
+
this.resourceName.type,
|
|
393
|
+
)
|
|
394
|
+
: this.project.paths.resourcePath(this.type);
|
|
395
|
+
this.fileName = resourceNameToPath(this.project, this.resourceName);
|
|
396
|
+
}
|
|
397
|
+
// Only load content from disk if resource exists in the cache registry
|
|
398
|
+
if (
|
|
399
|
+
this.project.resources.exists(resourceNameToString(this.resourceName))
|
|
400
|
+
) {
|
|
401
|
+
try {
|
|
402
|
+
this.content = readJsonFileSync(this.fileName);
|
|
403
|
+
} catch {
|
|
404
|
+
this.logger.debug(
|
|
405
|
+
`Initializing resource '${resourceNameToString(this.resourceName)}' failed: failed to read file '${this.fileName}'`,
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Called after inherited class has finished 'update' operation.
|
|
413
|
+
* @param content New content for resource
|
|
414
|
+
* @param updateKey Which property to change
|
|
415
|
+
* @param op What kind of operation is performed to updateKey
|
|
416
|
+
* @throws if validation fails after the update
|
|
417
|
+
*/
|
|
418
|
+
protected async postUpdate<Type, K extends string>(
|
|
419
|
+
content: T,
|
|
420
|
+
updateKey: UpdateKey<K>,
|
|
421
|
+
op: Operation<Type>,
|
|
422
|
+
) {
|
|
423
|
+
function toValue(op: Operation<Type>) {
|
|
424
|
+
if (op.name === 'rank') return op.newIndex;
|
|
425
|
+
if (op.name === 'add') return JSON.stringify(op.target);
|
|
426
|
+
if (op.name === 'remove') return JSON.stringify(op.target);
|
|
427
|
+
if (op.name === 'change') return JSON.stringify(op.to);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Check that new name is valid.
|
|
431
|
+
if (op.name === 'change' && updateKey.key === 'name') {
|
|
432
|
+
const newName = resourceName(
|
|
433
|
+
(op as ChangeOperation<string>).to as string,
|
|
434
|
+
);
|
|
435
|
+
content.name = await this.validName(newName);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Once changes have been made; validate the content.
|
|
439
|
+
try {
|
|
440
|
+
await this.validate(content);
|
|
441
|
+
} catch (error) {
|
|
442
|
+
if (error instanceof Error) {
|
|
443
|
+
const errorValue = typeof op === 'object' ? toValue(op) : op;
|
|
444
|
+
throw new Error(
|
|
445
|
+
`Cannot ${op.name} '${updateKey.key}' --> '${errorValue}: ${error.message}'`,
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
this.content = content;
|
|
451
|
+
await this.write();
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Reads content from file to memory.
|
|
456
|
+
*/
|
|
457
|
+
protected async read() {
|
|
458
|
+
this.content = await readJsonFile(this.fileName);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Renames resource.
|
|
463
|
+
* @param newName New name for the resource.
|
|
464
|
+
* @throws if trying to rename module resource, or
|
|
465
|
+
* if resource does not exist,
|
|
466
|
+
* if trying to rename so that type changes
|
|
467
|
+
*/
|
|
468
|
+
protected async rename(newName: ResourceName) {
|
|
469
|
+
if (this.moduleResource) {
|
|
470
|
+
throw new Error(`Cannot rename module resources`);
|
|
471
|
+
}
|
|
472
|
+
if (!this.exists()) {
|
|
473
|
+
throw new Error(
|
|
474
|
+
`Resource '${this.resourceName.identifier}' does not exist`,
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
if (newName.prefix !== this.project.projectPrefix) {
|
|
478
|
+
throw new Error('Can only rename project resources');
|
|
479
|
+
}
|
|
480
|
+
if (newName.type !== this.resourceName.type) {
|
|
481
|
+
throw new Error('Cannot change resource type');
|
|
482
|
+
}
|
|
483
|
+
const validator = await ResourceObject.getValidate();
|
|
484
|
+
validator.validResourceName(
|
|
485
|
+
this.resourceType(),
|
|
486
|
+
resourceNameToString(newName),
|
|
487
|
+
this.project.projectPrefixes(),
|
|
488
|
+
);
|
|
489
|
+
const newFilename = join(
|
|
490
|
+
this.project.paths.resourcePath(newName.type as ResourceFolderType),
|
|
491
|
+
newName.identifier + '.json',
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
const oldName = resourceNameToString(this.resourceName);
|
|
495
|
+
await rename(this.fileName, newFilename);
|
|
496
|
+
|
|
497
|
+
this.fileName = newFilename;
|
|
498
|
+
this.content.name = resourceNameToString(newName);
|
|
499
|
+
this.resourceName = newName;
|
|
500
|
+
|
|
501
|
+
this.project.resources.rename(oldName, this.content.name);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Update resource; the base class makes some checks only.
|
|
506
|
+
* @template type Resource type
|
|
507
|
+
* @template K Resource key
|
|
508
|
+
* @throws if resource does not exist, or
|
|
509
|
+
* if trying to update module content, or
|
|
510
|
+
* if key is empty
|
|
511
|
+
*/
|
|
512
|
+
protected async update<Type, K extends string>(
|
|
513
|
+
key: UpdateKey<K>,
|
|
514
|
+
_op: Operation<Type>,
|
|
515
|
+
): Promise<void> {
|
|
516
|
+
const content = this.data;
|
|
517
|
+
if (!content) {
|
|
518
|
+
throw new Error(
|
|
519
|
+
`Resource '${resourceNameToString(this.resourceName)}' does not exist`,
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
if (this.moduleResource) {
|
|
523
|
+
throw new Error(`Cannot update module resources`);
|
|
524
|
+
}
|
|
525
|
+
if (key.key === '' || key === undefined) {
|
|
526
|
+
throw new Error(`Cannot update empty key`);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Validates resource identifier to prevent filesystem operations with invalid names
|
|
532
|
+
* todo: To Validate?
|
|
533
|
+
*/
|
|
534
|
+
protected validateResourceIdentifier() {
|
|
535
|
+
if (!this.moduleResource && this.resourceName.identifier) {
|
|
536
|
+
const identifier = this.resourceName.identifier;
|
|
537
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(identifier)) {
|
|
538
|
+
throw new Error(
|
|
539
|
+
`Resource identifier must follow naming rules. Identifier '${identifier}' is invalid`,
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
201
543
|
}
|
|
202
544
|
|
|
203
545
|
/**
|
|
204
546
|
* Update calculation files.
|
|
205
547
|
* @param from Resource name to update
|
|
206
548
|
* @param to New name for resource
|
|
549
|
+
* @throws if 'from' or 'to' is empty string, or
|
|
550
|
+
* if there was error accessing calculation files.
|
|
207
551
|
*/
|
|
208
552
|
protected async updateCalculations(from: string, to: string) {
|
|
209
553
|
if (!from.trim() || !to.trim()) {
|
|
@@ -212,41 +556,16 @@ export class ResourceObject extends AbstractResource {
|
|
|
212
556
|
);
|
|
213
557
|
}
|
|
214
558
|
|
|
215
|
-
const calculations =
|
|
559
|
+
const calculations = this.project.resources.calculations(
|
|
216
560
|
ResourcesFrom.localOnly,
|
|
217
561
|
);
|
|
218
562
|
|
|
219
563
|
await Promise.all(
|
|
220
564
|
calculations.map(async (calculation) => {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const base = basename(calculation.name);
|
|
228
|
-
const fileNameWithExtension = base.endsWith('.lp')
|
|
229
|
-
? base
|
|
230
|
-
: base + '.lp';
|
|
231
|
-
const filename = join(calculation.path, fileNameWithExtension);
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
const content = await readFile(filename, 'utf-8');
|
|
235
|
-
const updatedContent = content.replaceAll(from, to);
|
|
236
|
-
await writeFile(filename, updatedContent);
|
|
237
|
-
} catch (error) {
|
|
238
|
-
if (hasCode(error) && error.code === 'ENOENT') {
|
|
239
|
-
// Skip files that don't exist (they may have been renamed or deleted)
|
|
240
|
-
this.getLogger(this.getType).warn(
|
|
241
|
-
`Skipping non-existent file: ${filename}`,
|
|
242
|
-
);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
if (error instanceof Error) {
|
|
246
|
-
throw new Error(
|
|
247
|
-
`Failed to process file while updating calculation ${filename}: ${error.message}`,
|
|
248
|
-
);
|
|
249
|
-
}
|
|
565
|
+
const content = calculation.contentData();
|
|
566
|
+
if (content.calculation) {
|
|
567
|
+
const updatedContent = content.calculation.replaceAll(from, to);
|
|
568
|
+
await calculation.updateFile('calculation.lp', updatedContent);
|
|
250
569
|
}
|
|
251
570
|
}),
|
|
252
571
|
);
|
|
@@ -257,6 +576,7 @@ export class ResourceObject extends AbstractResource {
|
|
|
257
576
|
* @param from Resource name to update
|
|
258
577
|
* @param to New name for resource
|
|
259
578
|
* @param handleBarFiles Optional. List of handlebar files. If omitted, affects all handlebar files in the project.
|
|
579
|
+
* @throws if 'from' or 'to' is empty string
|
|
260
580
|
*/
|
|
261
581
|
protected async updateHandleBars(
|
|
262
582
|
from: string,
|
|
@@ -270,7 +590,7 @@ export class ResourceObject extends AbstractResource {
|
|
|
270
590
|
}
|
|
271
591
|
|
|
272
592
|
if (!handleBarFiles) {
|
|
273
|
-
handleBarFiles = await this.
|
|
593
|
+
handleBarFiles = await this.reportHandlerBarFiles(
|
|
274
594
|
ResourcesFrom.localOnly,
|
|
275
595
|
);
|
|
276
596
|
}
|
|
@@ -284,4 +604,129 @@ export class ResourceObject extends AbstractResource {
|
|
|
284
604
|
}),
|
|
285
605
|
);
|
|
286
606
|
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Check if there are references to the resource in the card content.
|
|
610
|
+
* @note that this needs to be async, since inherited classes need to async operations
|
|
611
|
+
* @param cards cards to check
|
|
612
|
+
* @throws if resource does not exist
|
|
613
|
+
*/
|
|
614
|
+
protected async usage(cards?: Card[]): Promise<string[]> {
|
|
615
|
+
if (!this.exists()) {
|
|
616
|
+
throw new Error(
|
|
617
|
+
`Resource '${this.resourceName.identifier}' does not exist in the project`,
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
const cardArray = cards?.length ? cards : this.project.cards(undefined);
|
|
621
|
+
|
|
622
|
+
return cardArray
|
|
623
|
+
.filter((card) =>
|
|
624
|
+
card.content?.includes(resourceNameToString(this.resourceName)),
|
|
625
|
+
)
|
|
626
|
+
.map((card) => card.key);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Checks if resource name is valid.
|
|
631
|
+
* @param newName New name for resource.
|
|
632
|
+
* @returns valid name
|
|
633
|
+
*/
|
|
634
|
+
protected async validName(newName: ResourceName) {
|
|
635
|
+
const validator = await ResourceObject.getValidate();
|
|
636
|
+
const validName = validator.validResourceName(
|
|
637
|
+
this.resourceType(),
|
|
638
|
+
resourceNameToString(newName),
|
|
639
|
+
this.project.projectPrefixes(),
|
|
640
|
+
);
|
|
641
|
+
return validName;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Write the content from memory to disk.
|
|
646
|
+
* @throws if trying to write a module resource.
|
|
647
|
+
*/
|
|
648
|
+
protected async write() {
|
|
649
|
+
if (this.moduleResource) {
|
|
650
|
+
throw new Error(`Cannot change module resources`);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Create folder for resources and add correct .schema file.
|
|
654
|
+
await mkdir(this.resourceFolder, { recursive: true });
|
|
655
|
+
await writeJsonFile(
|
|
656
|
+
join(this.resourceFolder, '.schema'),
|
|
657
|
+
this.contentSchema,
|
|
658
|
+
{
|
|
659
|
+
flag: 'wx',
|
|
660
|
+
},
|
|
661
|
+
);
|
|
662
|
+
// Check if "name" has changed. Changing "name" means renaming the file.
|
|
663
|
+
const nameInContent = resourceName(this.content.name).identifier + '.json';
|
|
664
|
+
const currentFileName = basename(this.fileName);
|
|
665
|
+
const resourceString = resourceNameToString(this.resourceName);
|
|
666
|
+
|
|
667
|
+
if (nameInContent !== currentFileName) {
|
|
668
|
+
const newFileName = join(this.resourceFolder, nameInContent);
|
|
669
|
+
await rename(this.fileName, newFileName);
|
|
670
|
+
this.fileName = newFileName;
|
|
671
|
+
this.resourceName = resourceName(this.content.name);
|
|
672
|
+
this.project.resources.rename(resourceString, this.content.name);
|
|
673
|
+
}
|
|
674
|
+
await writeJsonFile(this.fileName, this.content);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Returns memory resident data as JSON.
|
|
679
|
+
* This is basically same as 'show' but doesn't do any checks; just returns the current content.
|
|
680
|
+
* @returns metadata content or undefined if resource does not exist.
|
|
681
|
+
*/
|
|
682
|
+
public get data() {
|
|
683
|
+
return this.content.name !== '' ? this.content : undefined;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Deletes the file and removes the resource from project.
|
|
688
|
+
* @throws if resource is a module resource, or
|
|
689
|
+
* if resource does not exist, or
|
|
690
|
+
* if resource is used by other resources.
|
|
691
|
+
*/
|
|
692
|
+
public async delete() {
|
|
693
|
+
if (this.moduleResource) {
|
|
694
|
+
throw new Error(
|
|
695
|
+
`Cannot delete resource ${resourceNameToString(this.resourceName)}: It is a module resource`,
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
if (!this.fileName.endsWith('.json')) {
|
|
699
|
+
this.fileName += '.json';
|
|
700
|
+
}
|
|
701
|
+
if (!this.exists()) {
|
|
702
|
+
throw new Error(
|
|
703
|
+
`Resource '${this.resourceName.identifier}' does not exist in the project`,
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
const usedIn = await this.usage();
|
|
707
|
+
if (usedIn.length > 0) {
|
|
708
|
+
throw new Error(
|
|
709
|
+
`Cannot delete resource ${resourceNameToString(this.resourceName)}. It is used by: ${usedIn.join(', ')}`,
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
await deleteFile(this.fileName);
|
|
713
|
+
this.project.resources.remove(resourceNameToString(this.resourceName));
|
|
714
|
+
this.fileName = '';
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Validates the content of the resource.
|
|
719
|
+
* @param content Content to be validated.
|
|
720
|
+
* @throws if content is invalid.
|
|
721
|
+
*/
|
|
722
|
+
public async validate(content?: object) {
|
|
723
|
+
const validator = await ResourceObject.getValidate();
|
|
724
|
+
const invalidJson = validator.validateJson(
|
|
725
|
+
content ? content : this.content,
|
|
726
|
+
this.contentSchemaId,
|
|
727
|
+
);
|
|
728
|
+
if (invalidJson.length) {
|
|
729
|
+
throw new Error(`Invalid content JSON: ${invalidJson}`);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
287
732
|
}
|