@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.
Files changed (280) hide show
  1. package/dist/card-metadata-updater.js +8 -4
  2. package/dist/card-metadata-updater.js.map +1 -1
  3. package/dist/command-handler.d.ts +4 -0
  4. package/dist/command-handler.js +29 -19
  5. package/dist/command-handler.js.map +1 -1
  6. package/dist/command-manager.d.ts +25 -2
  7. package/dist/command-manager.js +30 -5
  8. package/dist/command-manager.js.map +1 -1
  9. package/dist/commands/create.d.ts +1 -1
  10. package/dist/commands/create.js +45 -93
  11. package/dist/commands/create.js.map +1 -1
  12. package/dist/commands/edit.d.ts +1 -15
  13. package/dist/commands/edit.js +15 -89
  14. package/dist/commands/edit.js.map +1 -1
  15. package/dist/commands/export.d.ts +11 -2
  16. package/dist/commands/export.js +58 -58
  17. package/dist/commands/export.js.map +1 -1
  18. package/dist/commands/import.d.ts +9 -1
  19. package/dist/commands/import.js +17 -11
  20. package/dist/commands/import.js.map +1 -1
  21. package/dist/commands/move.d.ts +1 -2
  22. package/dist/commands/move.js +107 -146
  23. package/dist/commands/move.js.map +1 -1
  24. package/dist/commands/remove.d.ts +8 -1
  25. package/dist/commands/remove.js +17 -48
  26. package/dist/commands/remove.js.map +1 -1
  27. package/dist/commands/rename.d.ts +4 -9
  28. package/dist/commands/rename.js +34 -108
  29. package/dist/commands/rename.js.map +1 -1
  30. package/dist/commands/show.d.ts +22 -34
  31. package/dist/commands/show.js +103 -151
  32. package/dist/commands/show.js.map +1 -1
  33. package/dist/commands/transition.d.ts +9 -2
  34. package/dist/commands/transition.js +49 -44
  35. package/dist/commands/transition.js.map +1 -1
  36. package/dist/commands/update.d.ts +18 -12
  37. package/dist/commands/update.js +34 -18
  38. package/dist/commands/update.js.map +1 -1
  39. package/dist/commands/validate.d.ts +18 -10
  40. package/dist/commands/validate.js +101 -47
  41. package/dist/commands/validate.js.map +1 -1
  42. package/dist/containers/card-container.d.ts +87 -24
  43. package/dist/containers/card-container.js +183 -279
  44. package/dist/containers/card-container.js.map +1 -1
  45. package/dist/containers/project/calculation-engine.d.ts +13 -4
  46. package/dist/containers/project/calculation-engine.js +79 -77
  47. package/dist/containers/project/calculation-engine.js.map +1 -1
  48. package/dist/containers/project/card-cache.d.ts +146 -0
  49. package/dist/containers/project/card-cache.js +411 -0
  50. package/dist/containers/project/card-cache.js.map +1 -0
  51. package/dist/containers/project/project-paths.d.ts +5 -4
  52. package/dist/containers/project/project-paths.js +16 -12
  53. package/dist/containers/project/project-paths.js.map +1 -1
  54. package/dist/containers/project/resource-cache.d.ts +169 -0
  55. package/dist/containers/project/resource-cache.js +507 -0
  56. package/dist/containers/project/resource-cache.js.map +1 -0
  57. package/dist/containers/project/resource-handler.d.ts +129 -0
  58. package/dist/containers/project/resource-handler.js +206 -0
  59. package/dist/containers/project/resource-handler.js.map +1 -0
  60. package/dist/containers/project.d.ts +114 -195
  61. package/dist/containers/project.js +425 -535
  62. package/dist/containers/project.js.map +1 -1
  63. package/dist/containers/template.d.ts +22 -32
  64. package/dist/containers/template.js +113 -115
  65. package/dist/containers/template.js.map +1 -1
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.js +1 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/interfaces/folder-content-interfaces.d.ts +7 -4
  70. package/dist/interfaces/folder-content-interfaces.js +3 -3
  71. package/dist/interfaces/folder-content-interfaces.js.map +1 -1
  72. package/dist/interfaces/macros.d.ts +1 -0
  73. package/dist/interfaces/macros.js +1 -1
  74. package/dist/interfaces/macros.js.map +1 -1
  75. package/dist/interfaces/project-interfaces.d.ts +7 -5
  76. package/dist/interfaces/project-interfaces.js.map +1 -1
  77. package/dist/interfaces/resource-interfaces.d.ts +25 -22
  78. package/dist/interfaces/resource-interfaces.js +3 -0
  79. package/dist/interfaces/resource-interfaces.js.map +1 -1
  80. package/dist/macros/common.d.ts +10 -10
  81. package/dist/macros/createCards/index.d.ts +0 -13
  82. package/dist/macros/createCards/index.js.map +1 -1
  83. package/dist/macros/createCards/types.d.ts +44 -0
  84. package/dist/macros/createCards/types.js +15 -0
  85. package/dist/macros/createCards/types.js.map +1 -0
  86. package/dist/macros/graph/index.d.ts +2 -6
  87. package/dist/macros/graph/index.js +14 -28
  88. package/dist/macros/graph/index.js.map +1 -1
  89. package/dist/macros/graph/types.d.ts +23 -0
  90. package/dist/macros/graph/types.js +15 -0
  91. package/dist/macros/graph/types.js.map +1 -0
  92. package/dist/macros/image/index.d.ts +8 -16
  93. package/dist/macros/image/index.js +36 -33
  94. package/dist/macros/image/index.js.map +1 -1
  95. package/dist/macros/image/types.d.ts +38 -0
  96. package/dist/macros/image/types.js +15 -0
  97. package/dist/macros/image/types.js.map +1 -0
  98. package/dist/macros/include/index.d.ts +1 -6
  99. package/dist/macros/include/index.js +4 -7
  100. package/dist/macros/include/index.js.map +1 -1
  101. package/dist/macros/include/types.d.ts +31 -0
  102. package/dist/macros/include/types.js +15 -0
  103. package/dist/macros/include/types.js.map +1 -0
  104. package/dist/macros/index.d.ts +1 -1
  105. package/dist/macros/index.js +2 -2
  106. package/dist/macros/index.js.map +1 -1
  107. package/dist/macros/percentage/index.d.ts +0 -6
  108. package/dist/macros/percentage/index.js.map +1 -1
  109. package/dist/macros/percentage/types.d.ts +31 -0
  110. package/dist/macros/percentage/types.js +15 -0
  111. package/dist/macros/percentage/types.js.map +1 -0
  112. package/dist/macros/report/index.d.ts +0 -3
  113. package/dist/macros/report/index.js +3 -6
  114. package/dist/macros/report/index.js.map +1 -1
  115. package/dist/macros/report/types.d.ts +19 -0
  116. package/dist/macros/report/types.js +15 -0
  117. package/dist/macros/report/types.js.map +1 -0
  118. package/dist/macros/scoreCard/index.d.ts +0 -6
  119. package/dist/macros/scoreCard/index.js.map +1 -1
  120. package/dist/macros/scoreCard/types.d.ts +31 -0
  121. package/dist/macros/scoreCard/types.js +15 -0
  122. package/dist/macros/scoreCard/types.js.map +1 -0
  123. package/dist/macros/types.d.ts +25 -0
  124. package/dist/macros/types.js +2 -0
  125. package/dist/macros/types.js.map +1 -0
  126. package/dist/macros/vega/index.d.ts +0 -4
  127. package/dist/macros/vega/index.js.map +1 -1
  128. package/dist/macros/vega/types.d.ts +20 -0
  129. package/dist/macros/vega/types.js +2 -0
  130. package/dist/macros/vega/types.js.map +1 -0
  131. package/dist/macros/vegalite/index.d.ts +0 -4
  132. package/dist/macros/vegalite/index.js.map +1 -1
  133. package/dist/macros/vegalite/types.d.ts +20 -0
  134. package/dist/macros/vegalite/types.js +15 -0
  135. package/dist/macros/vegalite/types.js.map +1 -0
  136. package/dist/macros/xref/index.d.ts +0 -3
  137. package/dist/macros/xref/index.js +5 -14
  138. package/dist/macros/xref/index.js.map +1 -1
  139. package/dist/macros/xref/types.d.ts +19 -0
  140. package/dist/macros/xref/types.js +15 -0
  141. package/dist/macros/xref/types.js.map +1 -0
  142. package/dist/module-manager.d.ts +16 -3
  143. package/dist/module-manager.js +55 -23
  144. package/dist/module-manager.js.map +1 -1
  145. package/dist/project-settings.d.ts +16 -3
  146. package/dist/project-settings.js +79 -14
  147. package/dist/project-settings.js.map +1 -1
  148. package/dist/resources/calculation-resource.d.ts +6 -33
  149. package/dist/resources/calculation-resource.js +11 -60
  150. package/dist/resources/calculation-resource.js.map +1 -1
  151. package/dist/resources/card-type-resource.d.ts +10 -22
  152. package/dist/resources/card-type-resource.js +46 -66
  153. package/dist/resources/card-type-resource.js.map +1 -1
  154. package/dist/resources/create-defaults.d.ts +3 -2
  155. package/dist/resources/create-defaults.js +3 -2
  156. package/dist/resources/create-defaults.js.map +1 -1
  157. package/dist/resources/field-type-resource.d.ts +8 -22
  158. package/dist/resources/field-type-resource.js +35 -60
  159. package/dist/resources/field-type-resource.js.map +1 -1
  160. package/dist/resources/file-resource.d.ts +14 -35
  161. package/dist/resources/file-resource.js +22 -301
  162. package/dist/resources/file-resource.js.map +1 -1
  163. package/dist/resources/folder-resource.d.ts +44 -66
  164. package/dist/resources/folder-resource.js +102 -149
  165. package/dist/resources/folder-resource.js.map +1 -1
  166. package/dist/resources/graph-model-resource.d.ts +9 -34
  167. package/dist/resources/graph-model-resource.js +18 -64
  168. package/dist/resources/graph-model-resource.js.map +1 -1
  169. package/dist/resources/graph-view-resource.d.ts +9 -29
  170. package/dist/resources/graph-view-resource.js +13 -48
  171. package/dist/resources/graph-view-resource.js.map +1 -1
  172. package/dist/resources/link-type-resource.d.ts +9 -23
  173. package/dist/resources/link-type-resource.js +11 -33
  174. package/dist/resources/link-type-resource.js.map +1 -1
  175. package/dist/resources/report-resource.d.ts +10 -23
  176. package/dist/resources/report-resource.js +20 -67
  177. package/dist/resources/report-resource.js.map +1 -1
  178. package/dist/resources/resource-object.d.ts +143 -23
  179. package/dist/resources/resource-object.js +369 -48
  180. package/dist/resources/resource-object.js.map +1 -1
  181. package/dist/resources/template-resource.d.ts +10 -17
  182. package/dist/resources/template-resource.js +19 -27
  183. package/dist/resources/template-resource.js.map +1 -1
  184. package/dist/resources/workflow-resource.d.ts +9 -25
  185. package/dist/resources/workflow-resource.js +25 -55
  186. package/dist/resources/workflow-resource.js.map +1 -1
  187. package/dist/utils/card-utils.d.ts +69 -19
  188. package/dist/utils/card-utils.js +179 -30
  189. package/dist/utils/card-utils.js.map +1 -1
  190. package/dist/utils/clingo-fact-builder.d.ts +25 -14
  191. package/dist/utils/clingo-fact-builder.js +27 -5
  192. package/dist/utils/clingo-fact-builder.js.map +1 -1
  193. package/dist/utils/clingo-facts.js +14 -7
  194. package/dist/utils/clingo-facts.js.map +1 -1
  195. package/dist/utils/clingo-parser.js +1 -1
  196. package/dist/utils/clingo-parser.js.map +1 -1
  197. package/dist/utils/constants.d.ts +2 -0
  198. package/dist/utils/constants.js +4 -0
  199. package/dist/utils/constants.js.map +1 -1
  200. package/dist/utils/csv.js +1 -1
  201. package/dist/utils/csv.js.map +1 -1
  202. package/dist/utils/resource-utils.d.ts +1 -0
  203. package/dist/utils/resource-utils.js +2 -1
  204. package/dist/utils/resource-utils.js.map +1 -1
  205. package/package.json +11 -11
  206. package/src/card-metadata-updater.ts +9 -7
  207. package/src/command-handler.ts +35 -23
  208. package/src/command-manager.ts +32 -19
  209. package/src/commands/create.ts +59 -160
  210. package/src/commands/edit.ts +16 -132
  211. package/src/commands/export.ts +71 -81
  212. package/src/commands/import.ts +26 -18
  213. package/src/commands/move.ts +143 -179
  214. package/src/commands/remove.ts +20 -59
  215. package/src/commands/rename.ts +45 -156
  216. package/src/commands/show.ts +153 -211
  217. package/src/commands/transition.ts +53 -58
  218. package/src/commands/update.ts +44 -23
  219. package/src/commands/validate.ts +108 -82
  220. package/src/containers/card-container.ts +200 -360
  221. package/src/containers/project/calculation-engine.ts +81 -105
  222. package/src/containers/project/card-cache.ts +497 -0
  223. package/src/containers/project/project-paths.ts +21 -13
  224. package/src/containers/project/resource-cache.ts +648 -0
  225. package/src/containers/project/resource-handler.ts +265 -0
  226. package/src/containers/project.ts +551 -693
  227. package/src/containers/template.ts +129 -142
  228. package/src/index.ts +1 -0
  229. package/src/interfaces/folder-content-interfaces.ts +14 -7
  230. package/src/interfaces/macros.ts +2 -0
  231. package/src/interfaces/project-interfaces.ts +14 -7
  232. package/src/interfaces/resource-interfaces.ts +30 -27
  233. package/src/macros/createCards/index.ts +1 -12
  234. package/src/macros/createCards/types.ts +46 -0
  235. package/src/macros/graph/index.ts +27 -52
  236. package/src/macros/graph/types.ts +24 -0
  237. package/src/macros/image/index.ts +50 -61
  238. package/src/macros/image/types.ts +39 -0
  239. package/src/macros/include/index.ts +6 -15
  240. package/src/macros/include/types.ts +32 -0
  241. package/src/macros/index.ts +2 -2
  242. package/src/macros/percentage/index.ts +1 -7
  243. package/src/macros/percentage/types.ts +32 -0
  244. package/src/macros/report/index.ts +4 -13
  245. package/src/macros/report/types.ts +20 -0
  246. package/src/macros/scoreCard/index.ts +1 -7
  247. package/src/macros/scoreCard/types.ts +32 -0
  248. package/src/macros/types.ts +48 -0
  249. package/src/macros/vega/index.ts +1 -4
  250. package/src/macros/vega/types.ts +21 -0
  251. package/src/macros/vegalite/index.ts +1 -4
  252. package/src/macros/vegalite/types.ts +22 -0
  253. package/src/macros/xref/index.ts +6 -20
  254. package/src/macros/xref/types.ts +20 -0
  255. package/src/module-manager.ts +79 -22
  256. package/src/project-settings.ts +84 -15
  257. package/src/resources/calculation-resource.ts +21 -91
  258. package/src/resources/card-type-resource.ts +74 -109
  259. package/src/resources/create-defaults.ts +3 -2
  260. package/src/resources/field-type-resource.ts +61 -104
  261. package/src/resources/file-resource.ts +33 -441
  262. package/src/resources/folder-resource.ts +130 -207
  263. package/src/resources/graph-model-resource.ts +36 -95
  264. package/src/resources/graph-view-resource.ts +28 -70
  265. package/src/resources/link-type-resource.ts +23 -53
  266. package/src/resources/report-resource.ts +34 -96
  267. package/src/resources/resource-object.ts +511 -66
  268. package/src/resources/template-resource.ts +32 -44
  269. package/src/resources/workflow-resource.ts +42 -85
  270. package/src/utils/card-utils.ts +217 -31
  271. package/src/utils/clingo-fact-builder.ts +28 -16
  272. package/src/utils/clingo-facts.ts +16 -7
  273. package/src/utils/clingo-parser.ts +1 -1
  274. package/src/utils/constants.ts +6 -0
  275. package/src/utils/csv.ts +1 -1
  276. package/src/utils/resource-utils.ts +2 -1
  277. package/dist/containers/project/resource-collector.d.ts +0 -87
  278. package/dist/containers/project/resource-collector.js +0 -337
  279. package/dist/containers/project/resource-collector.js.map +0 -1
  280. package/src/containers/project/resource-collector.ts +0 -396
@@ -12,41 +12,21 @@
12
12
  */
13
13
 
14
14
  // node
15
- import { basename, join, resolve, sep } from 'node:path';
16
- import {
17
- constants as fsConstants,
18
- copyFile,
19
- mkdir,
20
- writeFile,
21
- } from 'node:fs/promises';
15
+ import { join, resolve } from 'node:path';
16
+ import { mkdir, writeFile } from 'node:fs/promises';
22
17
 
18
+ import { SCHEMA_VERSION } from '@cyberismo/assets';
23
19
  import { errorFunction } from '../utils/error-utils.js';
24
20
  import { Project } from '../containers/project.js';
25
- import { Validate } from './index.js';
21
+ import { Validate } from './validate.js';
26
22
 
27
23
  import { EMPTY_RANK, sortItems } from '../utils/lexorank.js';
28
- import type {
29
- DataType,
30
- Link,
31
- LinkType,
32
- } from '../interfaces/resource-interfaces.js';
33
- import { pathExists } from '../utils/file-utils.js';
24
+ import { isModulePath } from '../utils/card-utils.js';
25
+ import type { DataType } from '../interfaces/resource-interfaces.js';
34
26
  import type { Card, ProjectFile } from '../interfaces/project-interfaces.js';
35
27
  import { resourceName, resourceNameToString } from '../utils/resource-utils.js';
36
28
  import { writeJsonFile } from '../utils/json.js';
37
29
 
38
- import { CalculationResource } from '../resources/calculation-resource.js';
39
- import { CardTypeResource } from '../resources/card-type-resource.js';
40
- import { FieldTypeResource } from '../resources/field-type-resource.js';
41
- import { GraphModelResource } from '../resources/graph-model-resource.js';
42
- import { GraphViewResource } from '../resources/graph-view-resource.js';
43
- import { LinkTypeResource } from '../resources/link-type-resource.js';
44
- import { ReportResource } from '../resources/report-resource.js';
45
- import { TemplateResource } from '../resources/template-resource.js';
46
- import { WorkflowResource } from '../resources/workflow-resource.js';
47
-
48
- const MODULES_PATH = `${sep}modules${sep}`;
49
-
50
30
  // todo: Is there a easy to way to make JSON schema into a TypeScript interface/type?
51
31
  // Check this out: https://www.npmjs.com/package/json-schema-to-ts
52
32
 
@@ -65,6 +45,7 @@ export class Create {
65
45
  {
66
46
  path: '.cards/local',
67
47
  content: {
48
+ schemaVersion: SCHEMA_VERSION,
68
49
  cardKeyPrefix: '$PROJECT-PREFIX',
69
50
  name: '$PROJECT-NAME',
70
51
  modules: [],
@@ -114,24 +95,14 @@ export class Create {
114
95
  if (cardTypeName === undefined) {
115
96
  throw new Error(`Input validation error: card type cannot be empty`);
116
97
  }
117
- // Use slice to get a copy of a string.
118
- const origTemplateName = templateName.slice(0);
119
- const templateResource = new TemplateResource(
120
- this.project,
121
- resourceName(templateName),
98
+ const templateResource = this.project.resources.byType(
99
+ templateName,
100
+ 'templates',
122
101
  );
123
102
  const templateObject = templateResource.templateObject();
103
+ const specificCard = card ? templateObject.findCard(card) : undefined;
124
104
 
125
- const specificCard = card
126
- ? await templateObject.findSpecificCard(card)
127
- : undefined;
128
- if (card && !specificCard) {
129
- throw new Error(
130
- `Card '${card}' was not found from template '${origTemplateName}'`,
131
- );
132
- }
133
-
134
- if (templateObject.templateFolder().includes(`${sep}modules${sep}`)) {
105
+ if (isModulePath(templateObject.templateFolder())) {
135
106
  throw new Error(`Cannot add cards to imported module templates`);
136
107
  }
137
108
 
@@ -182,32 +153,12 @@ export class Create {
182
153
  attachment: string,
183
154
  buffer?: Buffer,
184
155
  ) {
185
- if (!buffer && !pathExists(attachment)) {
186
- throw new Error(
187
- `Input validation error: cannot find attachment '${attachment}'`,
188
- );
189
- }
190
- const attachmentFolder = await this.project.cardAttachmentFolder(cardKey);
191
-
192
- // Imported templates cannot be modified.
193
- // @todo: make MODULES_PATH project level constant
194
- if (attachmentFolder.includes(MODULES_PATH)) {
195
- throw new Error(`Cannot modify imported module`);
196
- }
197
-
198
156
  try {
199
- await mkdir(attachmentFolder, { recursive: true }).then(async () => {
200
- if (!buffer) {
201
- return copyFile(
202
- attachment,
203
- join(attachmentFolder, basename(attachment)),
204
- fsConstants.COPYFILE_EXCL,
205
- );
206
- }
207
- return writeFile(join(attachmentFolder, basename(attachment)), buffer, {
208
- flag: 'wx',
209
- });
210
- });
157
+ await this.project.createCardAttachment(
158
+ cardKey,
159
+ attachment,
160
+ buffer || attachment,
161
+ );
211
162
  } catch (error) {
212
163
  throw new Error(errorFunction(error));
213
164
  }
@@ -218,11 +169,9 @@ export class Create {
218
169
  * @param calculationName name for the calculation resource
219
170
  */
220
171
  public async createCalculation(calculationName: string) {
221
- const calculation = new CalculationResource(
222
- this.project,
223
- resourceName(calculationName),
224
- );
225
- await calculation.create();
172
+ return this.project.resources
173
+ .byType(calculationName, 'calculations')
174
+ .create();
226
175
  }
227
176
 
228
177
  /**
@@ -235,29 +184,22 @@ export class Create {
235
184
  templateName: string,
236
185
  parentCardKey?: string,
237
186
  ): Promise<Card[]> {
238
- const templateResource = new TemplateResource(
239
- this.project,
240
- resourceName(templateName),
187
+ const templateResource = this.project.resources.byType(
188
+ templateName,
189
+ 'templates',
241
190
  );
242
191
 
243
- await Validate.getInstance().validResourceName(
192
+ Validate.getInstance().validResourceName(
244
193
  'templates',
245
194
  resourceNameToString(resourceName(templateName)),
246
- await this.project.projectPrefixes(),
195
+ this.project.projectPrefixes(),
247
196
  );
248
197
 
249
198
  await templateResource.validate();
250
199
 
251
200
  const specificCard = parentCardKey
252
- ? await this.project.findSpecificCard(parentCardKey, {
253
- metadata: true,
254
- children: true,
255
- })
201
+ ? this.project.findCard(parentCardKey)
256
202
  : undefined;
257
- if (parentCardKey && !specificCard) {
258
- throw new Error(`Card '${parentCardKey}' not found from project`);
259
- }
260
-
261
203
  const templateObject = templateResource.templateObject();
262
204
  if (!templateObject || !templateObject.isCreated()) {
263
205
  throw new Error(`Template '${templateName}' not found from project`);
@@ -265,7 +207,6 @@ export class Create {
265
207
 
266
208
  const createdCards = await templateObject.createCards(specificCard);
267
209
  if (createdCards.length > 0) {
268
- await this.project.handleNewCards(createdCards);
269
210
  // Note: This assumes that parent keys will be ahead of 'a' in the sort order.
270
211
  const sorted = sortItems(createdCards, (item) => {
271
212
  return `${item.parent === 'root' ? 'a' : item.parent}${item.metadata?.rank || EMPTY_RANK}`;
@@ -281,12 +222,9 @@ export class Create {
281
222
  * @param workflowName workflow name to use in the card type.
282
223
  */
283
224
  public async createCardType(cardTypeName: string, workflowName: string) {
284
- const cardType = new CardTypeResource(
285
- this.project,
286
- resourceName(cardTypeName),
287
- );
288
-
289
- await cardType.createCardType(workflowName);
225
+ return this.project.resources
226
+ .byType(cardTypeName, 'cardTypes')
227
+ .createCardType(workflowName);
290
228
  }
291
229
 
292
230
  /**
@@ -295,11 +233,9 @@ export class Create {
295
233
  * @param dataType data type for the field type
296
234
  */
297
235
  public async createFieldType(fieldTypeName: string, dataType: DataType) {
298
- const fieldType = new FieldTypeResource(
299
- this.project,
300
- resourceName(fieldTypeName),
301
- );
302
- await fieldType.createFieldType(dataType);
236
+ return this.project.resources
237
+ .byType(fieldTypeName, 'fieldTypes')
238
+ .createFieldType(dataType);
303
239
  }
304
240
 
305
241
  /**
@@ -307,23 +243,17 @@ export class Create {
307
243
  * @param graphModelName name for the graph model.
308
244
  */
309
245
  public async createGraphModel(graphModelName: string) {
310
- const graphModel = new GraphModelResource(
311
- this.project,
312
- resourceName(graphModelName),
313
- );
314
- await graphModel.create();
246
+ return this.project.resources
247
+ .byType(graphModelName, 'graphModels')
248
+ .create();
315
249
  }
316
250
 
317
251
  /**
318
252
  * Creates a new graph view.
319
- * @param graphModelName name for the graph view.
253
+ * @param graphViewName name for the graph view.
320
254
  */
321
255
  public async createGraphView(graphViewName: string) {
322
- const graphView = new GraphViewResource(
323
- this.project,
324
- resourceName(graphViewName),
325
- );
326
- await graphView.create();
256
+ return this.project.resources.byType(graphViewName, 'graphViews').create();
327
257
  }
328
258
 
329
259
  /**
@@ -336,13 +266,8 @@ export class Create {
336
266
  throw new Error(`Not a valid label name'`);
337
267
  }
338
268
 
339
- const card = await this.project.findSpecificCard(cardKey, {
340
- metadata: true,
341
- });
342
- if (!card) {
343
- throw new Error(`Card '${cardKey}' does not exist in the project`);
344
- }
345
- const labels = card.metadata?.labels ?? [];
269
+ const card = this.project.findCard(cardKey);
270
+ const labels = structuredClone(card.metadata?.labels) ?? [];
346
271
 
347
272
  if (labels.includes(label)) {
348
273
  throw new Error('Label already exists');
@@ -357,11 +282,7 @@ export class Create {
357
282
  * @param linkTypeName name for the link type.
358
283
  */
359
284
  public async createLinkType(linkTypeName: string) {
360
- const linkType = new LinkTypeResource(
361
- this.project,
362
- resourceName(linkTypeName),
363
- );
364
- await linkType.create();
285
+ return this.project.resources.byType(linkTypeName, 'linkTypes').create();
365
286
  }
366
287
 
367
288
  /**
@@ -382,29 +303,12 @@ export class Create {
382
303
  }
383
304
 
384
305
  // Determine the card path
385
- const card = await this.project.findSpecificCard(cardKey, {
386
- metadata: true,
387
- });
388
- if (!card) {
389
- throw new Error(`Card '${cardKey}' does not exist in the project`);
390
- }
391
-
392
- const destinationCard = await this.project.findSpecificCard(
393
- destinationCardKey,
394
- {
395
- metadata: true,
396
- },
397
- );
398
- if (!destinationCard) {
399
- throw new Error(
400
- `Card '${destinationCardKey}' does not exist in the project`,
401
- );
402
- }
306
+ const card = this.project.findCard(cardKey);
307
+ const destinationCard = this.project.findCard(destinationCardKey);
403
308
  // make sure the link type exists
404
- const linkTypeObject = await this.project.resource<LinkType>(linkType);
405
- if (!linkTypeObject) {
406
- throw new Error(`Link type '${linkType}' does not exist in the project`);
407
- }
309
+ const linkTypeObject = this.project.resources
310
+ .byType(linkType, 'linkTypes')
311
+ .show();
408
312
 
409
313
  // make sure that if linkDescription is not enabled, linkDescription is not provided
410
314
  if (
@@ -453,7 +357,7 @@ export class Create {
453
357
  );
454
358
  }
455
359
 
456
- const links: Link[] = card.metadata?.links || [];
360
+ const links = card.metadata?.links || [];
457
361
  links.push({
458
362
  linkType,
459
363
  cardKey: destinationCardKey,
@@ -482,6 +386,12 @@ export class Create {
482
386
 
483
387
  const projectFolders: string[] = ['.cards/local', 'cardRoot'];
484
388
 
389
+ if (!Validate.validateFolder(projectPath)) {
390
+ throw new Error(
391
+ `Input validation error: folder name '${projectPath}' is invalid`,
392
+ );
393
+ }
394
+
485
395
  if (
486
396
  projectPrefix === undefined ||
487
397
  projectPrefix.length < 3 ||
@@ -552,8 +462,7 @@ export class Create {
552
462
  * @param name name of the report
553
463
  */
554
464
  public async createReport(name: string) {
555
- const report = new ReportResource(this.project, resourceName(name));
556
- await report.createReport();
465
+ return this.project.resources.byType(name, 'reports').createReport();
557
466
  }
558
467
 
559
468
  /**
@@ -562,14 +471,9 @@ export class Create {
562
471
  * @param templateContent JSON content for the template file.
563
472
  */
564
473
  public async createTemplate(templateName: string, templateContent: string) {
565
- const template = new TemplateResource(
566
- this.project,
567
- resourceName(templateName),
568
- );
569
-
570
- await template.create(
571
- templateContent ? JSON.parse(templateContent) : undefined,
572
- );
474
+ return this.project.resources
475
+ .byType(templateName, 'templates')
476
+ .create(templateContent ? JSON.parse(templateContent) : undefined);
573
477
  }
574
478
 
575
479
  /**
@@ -578,13 +482,8 @@ export class Create {
578
482
  * @param workflowContent workflow content JSON
579
483
  */
580
484
  public async createWorkflow(workflowName: string, workflowContent: string) {
581
- const workflow = new WorkflowResource(
582
- this.project,
583
- resourceName(workflowName),
584
- );
585
-
586
- await workflow.create(
587
- workflowContent ? JSON.parse(workflowContent) : undefined,
588
- );
485
+ return this.project.resources
486
+ .byType(workflowName, 'workflows')
487
+ .create(workflowContent ? JSON.parse(workflowContent) : undefined);
589
488
  }
590
489
  }
@@ -17,19 +17,10 @@ import { homedir } from 'node:os';
17
17
  import { spawnSync } from 'node:child_process';
18
18
 
19
19
  import { ActionGuard } from '../permissions/action-guard.js';
20
- import { CalculationResource } from '../resources/calculation-resource.js';
21
- import { FolderResource } from '../resources/folder-resource.js';
22
20
  import { Project } from '../containers/project.js';
23
- import { propertyName } from '../interfaces/folder-content-interfaces.js';
24
- import { resourceNameToString } from '../utils/resource-utils.js';
25
21
  import { UserPreferences } from '../utils/user-preferences.js';
26
22
 
27
- import type { ContentPropertyName } from '../interfaces/folder-content-interfaces.js';
28
- import type {
29
- MetadataContent,
30
- ResourceFolderType,
31
- } from '../interfaces/project-interfaces.js';
32
- import type { ResourceName } from '../utils/resource-utils.js';
23
+ import type { MetadataContent } from '../interfaces/project-interfaces.js';
33
24
 
34
25
  export class Edit {
35
26
  private project: Project;
@@ -38,60 +29,12 @@ export class Edit {
38
29
  this.project = project;
39
30
  }
40
31
 
41
- /**
42
- * Updates a calculation file.
43
- * @param resourceName The name of the resource to update.
44
- * @param changedContent The new content for the calculation.
45
- */
46
- public async editCalculation(
47
- resourceName: ResourceName,
48
- changedContent: string,
49
- ) {
50
- if (resourceName.prefix !== this.project.projectPrefix) {
51
- throw new Error(
52
- `Resource '${resourceName.identifier}' is not a local resource`,
53
- );
54
- }
55
- const resourceNameString = resourceNameToString(resourceName);
56
- if (
57
- !(await this.project.resourceExists(
58
- resourceName.type as ResourceFolderType,
59
- resourceNameString,
60
- ))
61
- ) {
62
- throw new Error(
63
- `Resource '${resourceNameString}' does not exist in the project`,
64
- );
65
- }
66
- const calculationResource = new CalculationResource(
67
- this.project,
68
- resourceName,
69
- );
70
- const contentUpdateKey = {
71
- key: 'content',
72
- subKey: 'calculation',
73
- };
74
- await calculationResource.update(
75
- // TODO: Let's fix this while we get rid of updating filenames directly a bit later.
76
- contentUpdateKey as unknown as ContentPropertyName,
77
- {
78
- name: 'change',
79
- target: resourceNameString,
80
- to: changedContent,
81
- },
82
- );
83
- }
84
-
85
32
  /**
86
33
  * Opens the content and metadata files for a card in the code editor
87
34
  * @param cardKey - The key of the card to open. Required.
88
35
  */
89
- public async editCard(cardKey: string) {
90
- // Determine the card path
91
- const cardPath = this.project.pathToCard(cardKey);
92
- if (!cardPath) {
93
- throw new Error(`Card '${cardKey}' does not exist in the project`);
94
- }
36
+ public editCard(cardKey: string) {
37
+ const card = this.project.findCard(cardKey);
95
38
 
96
39
  // Read the user preferences
97
40
  const prefs = new UserPreferences(
@@ -99,9 +42,8 @@ export class Edit {
99
42
  ).getPreferences();
100
43
 
101
44
  // Construct paths for the card components (json and adoc)
102
- const cardDirPath = join(this.project.paths.cardRootFolder, cardPath);
103
- const cardContentPath = join(cardDirPath, Project.cardContentFile);
104
- const cardJsonPath = join(cardDirPath, Project.cardMetadataFile);
45
+ const cardContentPath = join(card.path, Project.cardContentFile);
46
+ const cardJsonPath = join(card.path, Project.cardMetadataFile);
105
47
 
106
48
  // Extract the editor settings from the preferences.
107
49
  const editorPrefs = prefs.editCommand[process.platform];
@@ -112,7 +54,7 @@ export class Edit {
112
54
  const editorArgs = editorArgPrefs.map((arg) => {
113
55
  arg = arg.replace(/\{\{\s*cardContentPath\s*\}\}/, cardContentPath);
114
56
  arg = arg.replace(/\{\{\s*cardJsonPath\s*\}\}/, cardJsonPath);
115
- arg = arg.replace(/\{\{\s*cardDirPath\s*\}\}/, cardDirPath);
57
+ arg = arg.replace(/\{\{\s*cardDirPath\s*\}\}/, card.path);
116
58
 
117
59
  return arg;
118
60
  });
@@ -135,19 +77,14 @@ export class Edit {
135
77
  * @param changedContent New content for the card.
136
78
  */
137
79
  public async editCardContent(cardKey: string, changedContent: string) {
138
- const isTemplateCard = await this.project.isTemplateCard(cardKey);
139
- if (isTemplateCard) {
80
+ if (this.project.hasTemplateCard(cardKey)) {
140
81
  return this.project.updateCardContent(cardKey, changedContent);
141
82
  }
142
- const cardPath = this.project.pathToCard(cardKey);
143
- if (!cardPath) {
144
- throw new Error(`Card '${cardKey}' does not exist in the project`);
83
+ if (this.project.findCard(cardKey)) {
84
+ const actionGuard = new ActionGuard(this.project.calculationEngine);
85
+ await actionGuard.checkPermission('editContent', cardKey);
86
+ await this.project.updateCardContent(cardKey, changedContent);
145
87
  }
146
-
147
- const actionGuard = new ActionGuard(this.project.calculationEngine);
148
- await actionGuard.checkPermission('editContent', cardKey);
149
-
150
- await this.project.updateCardContent(cardKey, changedContent);
151
88
  }
152
89
 
153
90
  /**
@@ -164,68 +101,15 @@ export class Edit {
164
101
  if (!changedKey) {
165
102
  throw new Error(`Changed key cannot be empty`);
166
103
  }
167
- const isTemplateCard = await this.project.isTemplateCard(cardKey);
168
- if (isTemplateCard) {
104
+ if (this.project.hasTemplateCard(cardKey)) {
169
105
  return this.project.updateCardMetadataKey(cardKey, changedKey, newValue);
170
106
  }
171
107
 
172
- // Determine the card path
173
- const cardPath = this.project.pathToCard(cardKey);
174
- if (!cardPath) {
175
- throw new Error(`Card '${cardKey}' does not exist in the project`);
176
- }
177
-
178
108
  // check for editing rights
179
- const actionGuard = new ActionGuard(this.project.calculationEngine);
180
- await actionGuard.checkPermission('editField', cardKey, changedKey);
181
- await this.project.updateCardMetadataKey(cardKey, changedKey, newValue);
182
- }
183
-
184
- /**
185
- * Update a file of a folder resource. Cannot be used to create a new file.
186
- * @param resourceName The name of the resource to update.
187
- * @param fileName The name of the file to update.
188
- * @param changedContent The new content for the file.
189
- */
190
- public async editResourceContent(
191
- resourceName: ResourceName,
192
- fileName: string,
193
- changedContent: string,
194
- ) {
195
- const resourceNameString = resourceNameToString(resourceName);
196
- if (
197
- !(await this.project.resourceExists(
198
- resourceName.type as ResourceFolderType,
199
- resourceNameString,
200
- ))
201
- ) {
202
- throw new Error(
203
- `Resource '${resourceNameString}' does not exist in the project`,
204
- );
109
+ if (this.project.findCard(cardKey)) {
110
+ const actionGuard = new ActionGuard(this.project.calculationEngine);
111
+ await actionGuard.checkPermission('editField', cardKey, changedKey);
112
+ await this.project.updateCardMetadataKey(cardKey, changedKey, newValue);
205
113
  }
206
- const resource = Project.resourceObject(this.project, resourceName);
207
- if (!(resource instanceof FolderResource)) {
208
- throw new Error(
209
- `Resource '${resourceNameString}' is not a folder resource`,
210
- );
211
- }
212
-
213
- // TODO: The caller should not pass filename, but content type
214
- // Once that is in place, this check can be removed
215
- const propName: ContentPropertyName | undefined = propertyName(fileName);
216
- if (!propName) {
217
- throw new Error(`File '${fileName}' is not allowed`);
218
- }
219
-
220
- const contentUpdateKey = {
221
- key: 'content',
222
- subKey: propName,
223
- };
224
- // TODO: Let's fix this while we get rid of updating filenames directly a bit later.
225
- return resource.update(contentUpdateKey as unknown as ContentPropertyName, {
226
- name: 'change',
227
- target: '',
228
- to: changedContent,
229
- });
230
114
  }
231
115
  }