@cyberismo/data-handler 0.0.13 → 0.0.15

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 (262) hide show
  1. package/dist/card-metadata-updater.js +1 -3
  2. package/dist/card-metadata-updater.js.map +1 -1
  3. package/dist/command-handler.js +13 -17
  4. package/dist/command-handler.js.map +1 -1
  5. package/dist/command-manager.d.ts +1 -1
  6. package/dist/command-manager.js +4 -3
  7. package/dist/command-manager.js.map +1 -1
  8. package/dist/commands/create.d.ts +3 -3
  9. package/dist/commands/create.js +20 -81
  10. package/dist/commands/create.js.map +1 -1
  11. package/dist/commands/edit.d.ts +12 -25
  12. package/dist/commands/edit.js +25 -74
  13. package/dist/commands/edit.js.map +1 -1
  14. package/dist/commands/export.js +4 -17
  15. package/dist/commands/export.js.map +1 -1
  16. package/dist/commands/fetch.js +2 -1
  17. package/dist/commands/fetch.js.map +1 -1
  18. package/dist/commands/import.js +3 -5
  19. package/dist/commands/import.js.map +1 -1
  20. package/dist/commands/move.d.ts +1 -2
  21. package/dist/commands/move.js +108 -146
  22. package/dist/commands/move.js.map +1 -1
  23. package/dist/commands/remove.js +15 -49
  24. package/dist/commands/remove.js.map +1 -1
  25. package/dist/commands/rename.d.ts +1 -0
  26. package/dist/commands/rename.js +13 -7
  27. package/dist/commands/rename.js.map +1 -1
  28. package/dist/commands/show.d.ts +7 -25
  29. package/dist/commands/show.js +39 -113
  30. package/dist/commands/show.js.map +1 -1
  31. package/dist/commands/transition.js +27 -30
  32. package/dist/commands/transition.js.map +1 -1
  33. package/dist/commands/update.d.ts +5 -3
  34. package/dist/commands/update.js +19 -5
  35. package/dist/commands/update.js.map +1 -1
  36. package/dist/commands/validate.d.ts +3 -3
  37. package/dist/commands/validate.js +20 -27
  38. package/dist/commands/validate.js.map +1 -1
  39. package/dist/containers/card-container.d.ts +87 -24
  40. package/dist/containers/card-container.js +183 -279
  41. package/dist/containers/card-container.js.map +1 -1
  42. package/dist/containers/project/calculation-engine.d.ts +6 -0
  43. package/dist/containers/project/calculation-engine.js +36 -29
  44. package/dist/containers/project/calculation-engine.js.map +1 -1
  45. package/dist/containers/project/card-cache.d.ts +146 -0
  46. package/dist/containers/project/card-cache.js +411 -0
  47. package/dist/containers/project/card-cache.js.map +1 -0
  48. package/dist/containers/project/resource-collector.d.ts +24 -1
  49. package/dist/containers/project/resource-collector.js +8 -1
  50. package/dist/containers/project/resource-collector.js.map +1 -1
  51. package/dist/containers/project.d.ts +119 -84
  52. package/dist/containers/project.js +423 -253
  53. package/dist/containers/project.js.map +1 -1
  54. package/dist/containers/template.d.ts +15 -31
  55. package/dist/containers/template.js +97 -104
  56. package/dist/containers/template.js.map +1 -1
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.js +1 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/interfaces/folder-content-interfaces.d.ts +12 -5
  61. package/dist/interfaces/folder-content-interfaces.js +5 -3
  62. package/dist/interfaces/folder-content-interfaces.js.map +1 -1
  63. package/dist/interfaces/macros.d.ts +1 -0
  64. package/dist/interfaces/macros.js +1 -1
  65. package/dist/interfaces/macros.js.map +1 -1
  66. package/dist/interfaces/project-interfaces.d.ts +16 -10
  67. package/dist/interfaces/project-interfaces.js +10 -8
  68. package/dist/interfaces/project-interfaces.js.map +1 -1
  69. package/dist/interfaces/resource-interfaces.d.ts +21 -22
  70. package/dist/interfaces/resource-interfaces.js +3 -0
  71. package/dist/interfaces/resource-interfaces.js.map +1 -1
  72. package/dist/macros/common.d.ts +10 -10
  73. package/dist/macros/createCards/index.d.ts +0 -13
  74. package/dist/macros/createCards/index.js.map +1 -1
  75. package/dist/macros/createCards/types.d.ts +44 -0
  76. package/dist/macros/createCards/types.js +15 -0
  77. package/dist/macros/createCards/types.js.map +1 -0
  78. package/dist/macros/graph/index.d.ts +2 -6
  79. package/dist/macros/graph/index.js +2 -2
  80. package/dist/macros/graph/index.js.map +1 -1
  81. package/dist/macros/graph/types.d.ts +23 -0
  82. package/dist/macros/graph/types.js +15 -0
  83. package/dist/macros/graph/types.js.map +1 -0
  84. package/dist/macros/image/index.d.ts +8 -16
  85. package/dist/macros/image/index.js +36 -33
  86. package/dist/macros/image/index.js.map +1 -1
  87. package/dist/macros/image/types.d.ts +38 -0
  88. package/dist/macros/image/types.js +15 -0
  89. package/dist/macros/image/types.js.map +1 -0
  90. package/dist/macros/include/index.d.ts +1 -6
  91. package/dist/macros/include/index.js +4 -7
  92. package/dist/macros/include/index.js.map +1 -1
  93. package/dist/macros/include/types.d.ts +31 -0
  94. package/dist/macros/include/types.js +15 -0
  95. package/dist/macros/include/types.js.map +1 -0
  96. package/dist/macros/percentage/index.d.ts +0 -6
  97. package/dist/macros/percentage/index.js.map +1 -1
  98. package/dist/macros/percentage/types.d.ts +31 -0
  99. package/dist/macros/percentage/types.js +15 -0
  100. package/dist/macros/percentage/types.js.map +1 -0
  101. package/dist/macros/report/index.d.ts +0 -3
  102. package/dist/macros/report/index.js.map +1 -1
  103. package/dist/macros/report/types.d.ts +19 -0
  104. package/dist/macros/report/types.js +15 -0
  105. package/dist/macros/report/types.js.map +1 -0
  106. package/dist/macros/scoreCard/index.d.ts +0 -6
  107. package/dist/macros/scoreCard/index.js.map +1 -1
  108. package/dist/macros/scoreCard/types.d.ts +31 -0
  109. package/dist/macros/scoreCard/types.js +15 -0
  110. package/dist/macros/scoreCard/types.js.map +1 -0
  111. package/dist/macros/types.d.ts +25 -0
  112. package/dist/macros/types.js +2 -0
  113. package/dist/macros/types.js.map +1 -0
  114. package/dist/macros/vega/index.d.ts +0 -4
  115. package/dist/macros/vega/index.js.map +1 -1
  116. package/dist/macros/vega/types.d.ts +20 -0
  117. package/dist/macros/vega/types.js +2 -0
  118. package/dist/macros/vega/types.js.map +1 -0
  119. package/dist/macros/vegalite/index.d.ts +0 -4
  120. package/dist/macros/vegalite/index.js.map +1 -1
  121. package/dist/macros/vegalite/types.d.ts +20 -0
  122. package/dist/macros/vegalite/types.js +15 -0
  123. package/dist/macros/vegalite/types.js.map +1 -0
  124. package/dist/macros/xref/index.d.ts +0 -3
  125. package/dist/macros/xref/index.js +5 -14
  126. package/dist/macros/xref/index.js.map +1 -1
  127. package/dist/macros/xref/types.d.ts +19 -0
  128. package/dist/macros/xref/types.js +15 -0
  129. package/dist/macros/xref/types.js.map +1 -0
  130. package/dist/module-manager.js +4 -4
  131. package/dist/module-manager.js.map +1 -1
  132. package/dist/project-settings.js.map +1 -1
  133. package/dist/resources/calculation-resource.d.ts +43 -0
  134. package/dist/resources/calculation-resource.js +75 -0
  135. package/dist/resources/calculation-resource.js.map +1 -0
  136. package/dist/resources/card-type-resource.d.ts +4 -21
  137. package/dist/resources/card-type-resource.js +13 -44
  138. package/dist/resources/card-type-resource.js.map +1 -1
  139. package/dist/resources/create-defaults.d.ts +13 -6
  140. package/dist/resources/create-defaults.js +19 -5
  141. package/dist/resources/create-defaults.js.map +1 -1
  142. package/dist/resources/field-type-resource.d.ts +4 -21
  143. package/dist/resources/field-type-resource.js +14 -38
  144. package/dist/resources/field-type-resource.js.map +1 -1
  145. package/dist/resources/file-resource.d.ts +12 -29
  146. package/dist/resources/file-resource.js +19 -287
  147. package/dist/resources/file-resource.js.map +1 -1
  148. package/dist/resources/folder-resource.d.ts +32 -51
  149. package/dist/resources/folder-resource.js +68 -96
  150. package/dist/resources/folder-resource.js.map +1 -1
  151. package/dist/resources/graph-model-resource.d.ts +5 -33
  152. package/dist/resources/graph-model-resource.js +8 -61
  153. package/dist/resources/graph-model-resource.js.map +1 -1
  154. package/dist/resources/graph-view-resource.d.ts +5 -28
  155. package/dist/resources/graph-view-resource.js +6 -45
  156. package/dist/resources/graph-view-resource.js.map +1 -1
  157. package/dist/resources/link-type-resource.d.ts +4 -21
  158. package/dist/resources/link-type-resource.js +6 -31
  159. package/dist/resources/link-type-resource.js.map +1 -1
  160. package/dist/resources/report-resource.d.ts +5 -17
  161. package/dist/resources/report-resource.js +6 -44
  162. package/dist/resources/report-resource.js.map +1 -1
  163. package/dist/resources/resource-object.d.ts +58 -23
  164. package/dist/resources/resource-object.js +307 -26
  165. package/dist/resources/resource-object.js.map +1 -1
  166. package/dist/resources/template-resource.d.ts +4 -15
  167. package/dist/resources/template-resource.js +10 -25
  168. package/dist/resources/template-resource.js.map +1 -1
  169. package/dist/resources/workflow-resource.d.ts +4 -23
  170. package/dist/resources/workflow-resource.js +12 -38
  171. package/dist/resources/workflow-resource.js.map +1 -1
  172. package/dist/utils/card-utils.d.ts +69 -19
  173. package/dist/utils/card-utils.js +179 -30
  174. package/dist/utils/card-utils.js.map +1 -1
  175. package/dist/utils/clingo-facts.js +11 -3
  176. package/dist/utils/clingo-facts.js.map +1 -1
  177. package/dist/utils/clingo-parser.js +1 -1
  178. package/dist/utils/clingo-parser.js.map +1 -1
  179. package/dist/utils/constants.d.ts +2 -0
  180. package/dist/utils/constants.js +5 -0
  181. package/dist/utils/constants.js.map +1 -1
  182. package/dist/utils/csv.js +1 -1
  183. package/dist/utils/csv.js.map +1 -1
  184. package/dist/utils/error-utils.d.ts +34 -0
  185. package/dist/utils/error-utils.js +56 -0
  186. package/dist/utils/error-utils.js.map +1 -0
  187. package/dist/utils/log-utils.d.ts +0 -27
  188. package/dist/utils/log-utils.js +0 -58
  189. package/dist/utils/log-utils.js.map +1 -1
  190. package/dist/utils/user-preferences.js +6 -3
  191. package/dist/utils/user-preferences.js.map +1 -1
  192. package/package.json +5 -5
  193. package/src/card-metadata-updater.ts +3 -5
  194. package/src/command-handler.ts +14 -19
  195. package/src/command-manager.ts +4 -3
  196. package/src/commands/create.ts +28 -112
  197. package/src/commands/edit.ts +27 -118
  198. package/src/commands/export.ts +8 -29
  199. package/src/commands/fetch.ts +2 -1
  200. package/src/commands/import.ts +4 -6
  201. package/src/commands/move.ts +144 -179
  202. package/src/commands/remove.ts +12 -54
  203. package/src/commands/rename.ts +22 -7
  204. package/src/commands/show.ts +51 -156
  205. package/src/commands/transition.ts +30 -33
  206. package/src/commands/update.ts +27 -9
  207. package/src/commands/validate.ts +22 -37
  208. package/src/containers/card-container.ts +200 -360
  209. package/src/containers/project/calculation-engine.ts +43 -33
  210. package/src/containers/project/card-cache.ts +497 -0
  211. package/src/containers/project/resource-collector.ts +9 -1
  212. package/src/containers/project.ts +533 -328
  213. package/src/containers/template.ts +109 -127
  214. package/src/index.ts +1 -0
  215. package/src/interfaces/folder-content-interfaces.ts +23 -5
  216. package/src/interfaces/macros.ts +2 -0
  217. package/src/interfaces/project-interfaces.ts +19 -10
  218. package/src/interfaces/resource-interfaces.ts +22 -24
  219. package/src/macros/createCards/index.ts +1 -12
  220. package/src/macros/createCards/types.ts +46 -0
  221. package/src/macros/graph/index.ts +3 -7
  222. package/src/macros/graph/types.ts +24 -0
  223. package/src/macros/image/index.ts +50 -61
  224. package/src/macros/image/types.ts +39 -0
  225. package/src/macros/include/index.ts +6 -15
  226. package/src/macros/include/types.ts +32 -0
  227. package/src/macros/percentage/index.ts +1 -7
  228. package/src/macros/percentage/types.ts +32 -0
  229. package/src/macros/report/index.ts +1 -4
  230. package/src/macros/report/types.ts +20 -0
  231. package/src/macros/scoreCard/index.ts +1 -7
  232. package/src/macros/scoreCard/types.ts +32 -0
  233. package/src/macros/types.ts +48 -0
  234. package/src/macros/vega/index.ts +1 -4
  235. package/src/macros/vega/types.ts +21 -0
  236. package/src/macros/vegalite/index.ts +1 -4
  237. package/src/macros/vegalite/types.ts +22 -0
  238. package/src/macros/xref/index.ts +6 -20
  239. package/src/macros/xref/types.ts +20 -0
  240. package/src/module-manager.ts +5 -5
  241. package/src/project-settings.ts +1 -1
  242. package/src/resources/calculation-resource.ts +101 -0
  243. package/src/resources/card-type-resource.ts +24 -59
  244. package/src/resources/create-defaults.ts +21 -5
  245. package/src/resources/field-type-resource.ts +22 -51
  246. package/src/resources/file-resource.ts +27 -403
  247. package/src/resources/folder-resource.ts +99 -125
  248. package/src/resources/graph-model-resource.ts +17 -74
  249. package/src/resources/graph-view-resource.ts +14 -54
  250. package/src/resources/link-type-resource.ts +13 -40
  251. package/src/resources/report-resource.ts +17 -57
  252. package/src/resources/resource-object.ts +454 -39
  253. package/src/resources/template-resource.ts +16 -29
  254. package/src/resources/workflow-resource.ts +26 -50
  255. package/src/utils/card-utils.ts +217 -31
  256. package/src/utils/clingo-facts.ts +13 -3
  257. package/src/utils/clingo-parser.ts +1 -1
  258. package/src/utils/constants.ts +7 -0
  259. package/src/utils/csv.ts +1 -1
  260. package/src/utils/error-utils.ts +62 -0
  261. package/src/utils/log-utils.ts +0 -68
  262. package/src/utils/user-preferences.ts +7 -3
@@ -17,10 +17,7 @@ import type { MacroGenerationContext } from '../../interfaces/macros.js';
17
17
  import macroMetadata from './metadata.js';
18
18
  import BaseMacro from '../base-macro.js';
19
19
  import type TaskQueue from '../task-queue.js';
20
-
21
- export interface XrefMacroOptions {
22
- cardKey: string;
23
- }
20
+ import type { XrefMacroOptions } from './types.js';
24
21
 
25
22
  export default class XrefMacro extends BaseMacro {
26
23
  constructor(tasksQueue: TaskQueue) {
@@ -36,7 +33,7 @@ export default class XrefMacro extends BaseMacro {
36
33
  input: unknown,
37
34
  ): Promise<string> => {
38
35
  const options = this.validate(input);
39
- const card = await this.getCard(options.cardKey, context);
36
+ const card = this.getCard(options.cardKey, context);
40
37
 
41
38
  if (!card || !card.metadata) {
42
39
  throw new Error(`Card key ${options.cardKey} not found`);
@@ -48,23 +45,12 @@ export default class XrefMacro extends BaseMacro {
48
45
 
49
46
  handleInject = async (context: MacroGenerationContext, input: unknown) => {
50
47
  const options = this.validate(input);
51
- const card = await this.getCard(options.cardKey, context);
52
-
53
- if (!card || !card.metadata) {
54
- throw new Error(`Card key ${options.cardKey} not found`);
55
- }
56
-
57
- return `xref:${options.cardKey}.adoc[${card.metadata.title}]`;
48
+ const card = this.getCard(options.cardKey, context);
49
+ return `xref:${options.cardKey}.adoc[${card?.metadata?.title}]`;
58
50
  };
59
51
 
60
- private async getCard(cardKey: string, context: MacroGenerationContext) {
61
- const card = await context.project.cardDetailsById(cardKey, {
62
- metadata: true,
63
- });
64
- if (!card || !card.metadata) {
65
- throw new Error(`Card key ${cardKey} not found`);
66
- }
67
- return card;
52
+ private getCard(cardKey: string, context: MacroGenerationContext) {
53
+ return context.project.findCard(cardKey);
68
54
  }
69
55
 
70
56
  private validate(input: unknown): XrefMacroOptions {
@@ -0,0 +1,20 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2025
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU Affero General Public License version 3 as published by
7
+ the Free Software Foundation. This program is distributed in the hope that it
8
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
+ See the GNU Affero General Public License for more details.
11
+ You should have received a copy of the GNU Affero General Public
12
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
13
+ */
14
+
15
+ export interface XrefMacroOptions {
16
+ /**
17
+ * Card of the card being referenced
18
+ */
19
+ cardKey: string;
20
+ }
@@ -309,10 +309,10 @@ export class ModuleManager {
309
309
 
310
310
  // Collect modules that could be removed from .cards/modules when
311
311
  // 'moduleName' is removed.
312
- private async orphanedModules(
312
+ private orphanedModules(
313
313
  dependencies: DependencyGraph,
314
314
  moduleName: string,
315
- ): Promise<string[]> {
315
+ ): string[] {
316
316
  const projectModules = this.project.configuration.modules;
317
317
  const removableTransientModules: string[] = [];
318
318
  if (dependencies.has(moduleName)) {
@@ -558,6 +558,7 @@ export class ModuleManager {
558
558
  );
559
559
  }
560
560
  const sourceProject = new Project(source);
561
+ await sourceProject.populateCaches();
561
562
  const modulePrefix = sourceProject.projectPrefix;
562
563
  const destinationPath = join(
563
564
  this.project.paths.modulesFolder,
@@ -625,7 +626,7 @@ export class ModuleManager {
625
626
  // but modules under .cards/modules must be checked not to be used by
626
627
  // other modules.
627
628
  if (this.canBeRemoved(dependencies, moduleName)) {
628
- const orphans = await this.orphanedModules(dependencies, moduleName);
629
+ const orphans = this.orphanedModules(dependencies, moduleName);
629
630
  await deleteDir(module.path);
630
631
  for (const moduleToDelete of orphans) {
631
632
  const modulePath = join(
@@ -634,9 +635,8 @@ export class ModuleManager {
634
635
  );
635
636
  await deleteDir(modulePath);
636
637
  }
637
- await this.project.collectModuleResources();
638
638
  }
639
- await this.project.configuration.removeModule(moduleName);
639
+ await this.project.removeModule(moduleName);
640
640
  }
641
641
 
642
642
  /**
@@ -61,7 +61,7 @@ export class ProjectConfiguration implements ProjectSettings {
61
61
 
62
62
  // Sets configuration values from file.
63
63
  private readSettings() {
64
- const settings = readJsonFileSync(this.settingPath) as ProjectConfiguration;
64
+ const settings = readJsonFileSync(this.settingPath);
65
65
  if (!settings) {
66
66
  throw new Error(`File at '${this.settingPath}' is not a valid JSON file`);
67
67
  }
@@ -0,0 +1,101 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2025
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU Affero General Public License version 3 as published by
7
+ the Free Software Foundation. This program is distributed in the hope that it
8
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
+ See the GNU Affero General Public License for more details.
11
+ You should have received a copy of the GNU Affero General Public
12
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
13
+ */
14
+
15
+ import { join } from 'node:path';
16
+
17
+ import {
18
+ DefaultContent,
19
+ FolderResource,
20
+ resourceNameToString,
21
+ sortCards,
22
+ } from './folder-resource.js';
23
+ import { writeFileSafe } from '../utils/file-utils.js';
24
+
25
+ import { type CalculationMetadata } from '../interfaces/resource-interfaces.js';
26
+ import type { CalculationContent } from '../interfaces/folder-content-interfaces.js';
27
+ import type { Card, Project, ResourceName } from './file-resource.js';
28
+
29
+ /**
30
+ * Calculation resource class.
31
+ */
32
+ export class CalculationResource extends FolderResource<
33
+ CalculationMetadata,
34
+ CalculationContent
35
+ > {
36
+ private calculationsFile = 'calculation.lp';
37
+ constructor(project: Project, name: ResourceName) {
38
+ super(project, name, 'calculations');
39
+
40
+ this.contentSchemaId = 'calculationSchema';
41
+ this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
42
+ }
43
+
44
+ // When resource name changes
45
+ protected async onNameChange(existingName: string) {
46
+ await super.updateCalculations(existingName, this.content.name);
47
+ await this.write();
48
+ }
49
+
50
+ /**
51
+ * Creates a new calculation object and file.
52
+ * @param newContent Content for the calculation.
53
+ */
54
+ public async create(newContent?: CalculationMetadata) {
55
+ if (!newContent) {
56
+ newContent = DefaultContent.calculation(
57
+ resourceNameToString(this.resourceName),
58
+ );
59
+ } else {
60
+ await this.validate(newContent);
61
+ }
62
+ await super.create(newContent);
63
+
64
+ const calculationsFile = join(this.internalFolder, this.calculationsFile);
65
+ await writeFileSafe(
66
+ calculationsFile,
67
+ `% add your calculations here for '${this.resourceName.identifier}'`,
68
+ {
69
+ flag: 'wx',
70
+ },
71
+ );
72
+ }
73
+ /**
74
+ * Renames resource metadata file and renames memory resident object 'name'.
75
+ * @param newName New name for the resource.
76
+ */
77
+ public async rename(newName: ResourceName) {
78
+ const existingName = this.content.name;
79
+ await super.rename(newName);
80
+ return this.onNameChange(existingName);
81
+ }
82
+
83
+ /**
84
+ * List where calculation resource is used in cards, or other calculation resources.
85
+ * Always returns card key references first, then calculation references.
86
+ *
87
+ * @param cards Optional. Check these cards for usage of this resource. If undefined, will check all cards.
88
+ * @returns array of card keys and calculation filenames that refer this resource.
89
+ */
90
+ public async usage(cards?: Card[]): Promise<string[]> {
91
+ const allCards = cards || (await super.cards());
92
+
93
+ const [cardContentReferences, calculations] = await Promise.all([
94
+ super.usage(allCards),
95
+ super.calculations(),
96
+ ]);
97
+
98
+ const cardReferences = cardContentReferences.sort(sortCards);
99
+ return [...new Set([...cardReferences, ...calculations])];
100
+ }
101
+ }
@@ -16,6 +16,7 @@ import type {
16
16
  CardType,
17
17
  CustomField,
18
18
  LinkType,
19
+ UpdateKey,
19
20
  Workflow,
20
21
  } from '../interfaces/resource-interfaces.js';
21
22
  import { FieldTypeResource } from './field-type-resource.js';
@@ -40,19 +41,18 @@ import { Validate } from '../commands/index.js';
40
41
  /**
41
42
  * Card type resource class.
42
43
  */
43
- export class CardTypeResource extends FileResource {
44
+ export class CardTypeResource extends FileResource<CardType> {
44
45
  constructor(project: Project, name: ResourceName) {
45
46
  super(project, name, 'cardTypes');
46
47
 
47
48
  this.contentSchemaId = 'cardTypeSchema';
48
49
  this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
49
50
 
50
- this.initialize();
51
51
  this.setContainerValues();
52
52
  }
53
53
 
54
54
  // Returns cards that have this card type.
55
- private async cardsWithCardType(cards: Card[]): Promise<string[]> {
55
+ private cardsWithCardType(cards: Card[]): string[] {
56
56
  const resourceName = resourceNameToString(this.resourceName);
57
57
  return cards
58
58
  .filter((card) => card.metadata?.cardType === resourceName)
@@ -72,13 +72,7 @@ export class CardTypeResource extends FileResource {
72
72
  if (op && op.name === 'rank') return;
73
73
 
74
74
  // Collect both project cards and template cards.
75
- const cards = await this.collectCards(
76
- {
77
- metadata: true,
78
- content: true,
79
- },
80
- this.content.name,
81
- );
75
+ const cards = await this.collectCards(this.content.name);
82
76
 
83
77
  if (op && op.name === 'change') {
84
78
  const from = (op as ChangeOperation<string>).target;
@@ -113,7 +107,7 @@ export class CardTypeResource extends FileResource {
113
107
 
114
108
  // When resource name changes.
115
109
  private async handleNameChange(existingName: string) {
116
- const current = this.content as CardType;
110
+ const current = this.content;
117
111
  const prefixes = await this.project.projectPrefixes();
118
112
  if (current.customFields) {
119
113
  current.customFields.map(
@@ -160,20 +154,14 @@ export class CardTypeResource extends FileResource {
160
154
  op: ChangeOperation<Type>,
161
155
  ) {
162
156
  await this.verifyStateMapping(stateMapping, op);
163
- const cards = await this.collectCards(
164
- {
165
- metadata: true,
166
- content: true,
167
- },
168
- this.content.name,
169
- );
157
+ const cards = await this.collectCards(this.content.name);
170
158
 
171
159
  const unmappedStates: string[] = [];
172
160
 
173
161
  // Update each card's workflowState if it has a mapping
174
162
  const updatePromises = cards.map(async (card) => {
175
163
  if (card.metadata && card.metadata.workflowState) {
176
- const currentState = card.metadata.workflowState as string;
164
+ const currentState = card.metadata.workflowState;
177
165
  const newState = stateMapping[currentState];
178
166
 
179
167
  if (newState && newState !== currentState) {
@@ -198,8 +186,10 @@ export class CardTypeResource extends FileResource {
198
186
  }
199
187
 
200
188
  // Checks if field type exists in this card type.
201
- private async hasFieldType(field: Partial<CustomField>): Promise<boolean> {
202
- return this.data.customFields.some((item) => item.name === field.name);
189
+ private hasFieldType(field: Partial<CustomField>): boolean {
190
+ return (
191
+ this.data?.customFields.some((item) => item.name === field.name) || false
192
+ );
203
193
  }
204
194
 
205
195
  // Remove value from array.
@@ -251,7 +241,7 @@ export class CardTypeResource extends FileResource {
251
241
 
252
242
  // Sets content container values to be either '[]' or with proper values.
253
243
  private setContainerValues() {
254
- const content = this.content as CardType;
244
+ const content = this.content;
255
245
  if (content.customFields) {
256
246
  for (const item of content.customFields) {
257
247
  // Set "isCalculated" if it is missing; default = false
@@ -311,7 +301,7 @@ export class CardTypeResource extends FileResource {
311
301
  target: oldName,
312
302
  to: this.content.name,
313
303
  } as ChangeOperation<string>;
314
- updates.push(object.update(field, op));
304
+ updates.push(object.update({ key: field }, op));
315
305
  }
316
306
  }
317
307
 
@@ -423,7 +413,7 @@ export class CardTypeResource extends FileResource {
423
413
  `Cannot create cardType without providing workflow for it`,
424
414
  );
425
415
  }
426
- const validWorkflowName = await Validate.getInstance().validResourceName(
416
+ const validWorkflowName = Validate.getInstance().validResourceName(
427
417
  'workflows',
428
418
  resourceNameToString(resourceName(workflowName)),
429
419
  await this.project.projectPrefixes(),
@@ -441,20 +431,6 @@ export class CardTypeResource extends FileResource {
441
431
  return super.create(content);
442
432
  }
443
433
 
444
- /**
445
- * Returns content data.
446
- */
447
- public get data(): CardType {
448
- return super.data as CardType;
449
- }
450
-
451
- /**
452
- * Deletes file(s) from disk and clears out the memory resident object.
453
- */
454
- public async delete() {
455
- return super.delete();
456
- }
457
-
458
434
  /**
459
435
  * Renames resource metadata file and renames memory resident object 'name'.
460
436
  * @param newName New name for the resource.
@@ -465,26 +441,22 @@ export class CardTypeResource extends FileResource {
465
441
  return this.handleNameChange(existingName);
466
442
  }
467
443
 
468
- /**
469
- * Shows metadata of the resource.
470
- * @returns card type metadata.
471
- */
472
- public async show(): Promise<CardType> {
473
- return super.show() as Promise<CardType>;
474
- }
475
-
476
444
  /**
477
445
  * Updates card type resource.
478
- * @param key Key to modify
446
+ * @param updateKey Key to modify
479
447
  * @param op Operation to perform on 'key'
480
448
  */
481
- public async update<Type>(key: string, op: Operation<Type>) {
449
+ public async update<Type, K extends string>(
450
+ updateKey: UpdateKey<K>,
451
+ op: Operation<Type>,
452
+ ) {
453
+ const { key } = updateKey;
482
454
  const nameChange = key === 'name';
483
455
  const customFieldsChange = key === 'customFields';
484
456
  const existingName = this.content.name;
485
- await super.update(key, op);
457
+ await super.update(updateKey, op);
486
458
 
487
- const content = structuredClone(this.content) as CardType;
459
+ const content = structuredClone(this.content);
488
460
  if (key === 'name') {
489
461
  content.name = super.handleScalar(op) as string;
490
462
  } else if (key === 'alwaysVisibleFields') {
@@ -525,7 +497,7 @@ export class CardTypeResource extends FileResource {
525
497
  } else {
526
498
  throw new Error(`Unknown property '${key}' for CardType`);
527
499
  }
528
- await super.postUpdate(content, key, op);
500
+ await super.postUpdate(content, updateKey, op);
529
501
 
530
502
  // Renaming this card type causes that references to its name must be updated.
531
503
  if (nameChange) {
@@ -544,7 +516,7 @@ export class CardTypeResource extends FileResource {
544
516
  * @returns array of card keys, resource names and calculation filenames that refer this resource.
545
517
  */
546
518
  public async usage(cards?: Card[]): Promise<string[]> {
547
- const allCards = cards ?? (await super.cards());
519
+ const allCards = cards ?? super.cards();
548
520
  const [
549
521
  cardsWithCardType,
550
522
  cardContentReferences,
@@ -566,11 +538,4 @@ export class CardTypeResource extends FileResource {
566
538
  ...new Set([...cardReferences, ...relevantLinkTypes, ...calculations]),
567
539
  ];
568
540
  }
569
-
570
- /**
571
- * Validates the resource. If object is invalid, throws.
572
- */
573
- public async validate(content?: object) {
574
- return super.validate(content);
575
- }
576
541
  }
@@ -1,18 +1,20 @@
1
1
  /**
2
2
  Cyberismo
3
3
  Copyright © Cyberismo Ltd and contributors 2024
4
+
4
5
  This program is free software: you can redistribute it and/or modify it under
5
6
  the terms of the GNU Affero General Public License version 3 as published by
6
- the Free Software Foundation.
7
- This program is distributed in the hope that it will be useful, but WITHOUT
8
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9
- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
10
- details. You should have received a copy of the GNU Affero General Public
7
+ the Free Software Foundation. This program is distributed in the hope that it
8
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
+ See the GNU Affero General Public License for more details.
11
+ You should have received a copy of the GNU Affero General Public
11
12
  License along with this program. If not, see <https://www.gnu.org/licenses/>.
12
13
  */
13
14
 
14
15
  import type { Card } from '../interfaces/project-interfaces.js';
15
16
  import type {
17
+ CalculationMetadata,
16
18
  CardType,
17
19
  DataType,
18
20
  FieldType,
@@ -70,6 +72,20 @@ export abstract class DefaultContent {
70
72
  );
71
73
  }
72
74
 
75
+ /**
76
+ * Default content for calculation.
77
+ * @param calculationName calculation name
78
+ * @returns Default content for calculation.
79
+ */
80
+ static calculation(calculationName: string): CalculationMetadata {
81
+ return {
82
+ name: calculationName,
83
+ displayName: '',
84
+ description: undefined,
85
+ calculation: 'calculation.lp',
86
+ };
87
+ }
88
+
73
89
  /**
74
90
  * Default content for card type.
75
91
  * @param cardTypeName card type name
@@ -33,6 +33,7 @@ import type {
33
33
  DataType,
34
34
  EnumDefinition,
35
35
  FieldType,
36
+ UpdateKey,
36
37
  } from '../interfaces/resource-interfaces.js';
37
38
  import { CardTypeResource } from './card-type-resource.js';
38
39
  import {
@@ -48,7 +49,7 @@ const SHORT_TEXT_MAX_LENGTH = 80;
48
49
  /**
49
50
  * Field type resource class.
50
51
  */
51
- export class FieldTypeResource extends FileResource {
52
+ export class FieldTypeResource extends FileResource<FieldType> {
52
53
  // Initialize data type change helpers (fromType, toType) to some values.
53
54
  // The actual types are set, if this Field Type's dataType is changed.
54
55
  private fromType: DataType = 'integer';
@@ -59,8 +60,6 @@ export class FieldTypeResource extends FileResource {
59
60
 
60
61
  this.contentSchemaId = 'fieldTypeSchema';
61
62
  this.contentSchema = super.contentSchemaContent(this.contentSchemaId);
62
-
63
- this.initialize();
64
63
  }
65
64
 
66
65
  // Cards from given array that include this field type.
@@ -130,7 +129,7 @@ export class FieldTypeResource extends FileResource {
130
129
  function affectedCard(card: Card): boolean {
131
130
  if (!card.metadata) return false;
132
131
  return cardTypesThatUseThisFieldType.some(
133
- (item) => item === card.metadata!.cardType,
132
+ (item) => item === card.metadata?.cardType,
134
133
  );
135
134
  }
136
135
 
@@ -139,12 +138,11 @@ export class FieldTypeResource extends FileResource {
139
138
  cardTypesThatUseThisFieldType.push(...cardTypes);
140
139
 
141
140
  // Then collect cards (both project and local template) that use those card types.
142
- const projectCards = (
143
- await this.project.cards(this.project.paths.cardRootFolder, {
144
- metadata: true,
145
- })
146
- ).filter((card) => affectedCard(card));
147
- const templateCards = (await this.project.allTemplateCards())
141
+ const projectCards = this.project
142
+ .cards(this.project.paths.cardRootFolder)
143
+ .filter((card) => affectedCard(card));
144
+ const templateCards = this.project
145
+ .allTemplateCards()
148
146
  .filter((card) => !card.path.includes('modules'))
149
147
  .filter((card) => affectedCard(card));
150
148
  const allCards = [...projectCards, ...templateCards];
@@ -213,9 +211,7 @@ export class FieldTypeResource extends FileResource {
213
211
  const removedValue = (op.target as EnumDefinition).enumValue;
214
212
  const cardTypes = await this.relevantCardTypes(ResourcesFrom.localOnly);
215
213
  const allCards = await Promise.all(
216
- cardTypes.map((cardType) =>
217
- this.collectCards({ metadata: true }, cardType),
218
- ),
214
+ cardTypes.map((cardType) => this.collectCards(cardType)),
219
215
  );
220
216
  const cardsToUpdate = allCards
221
217
  .flat()
@@ -290,13 +286,13 @@ export class FieldTypeResource extends FileResource {
290
286
  this.project,
291
287
  resourceName(cardType.name),
292
288
  );
293
- const data = object.data as CardType;
289
+ const data = object.data;
294
290
  if (data) {
295
291
  const found = data.customFields
296
292
  ? data.customFields.find((item) => item.name === oldName)
297
293
  : undefined;
298
294
  if (found) {
299
- await object.update('customFields', op);
295
+ await object.update({ key: 'customFields' }, op);
300
296
  }
301
297
  }
302
298
  }
@@ -322,20 +318,6 @@ export class FieldTypeResource extends FileResource {
322
318
  return super.create(content);
323
319
  }
324
320
 
325
- /**
326
- * Returns content data.
327
- */
328
- public get data(): FieldType {
329
- return super.data as FieldType;
330
- }
331
-
332
- /**
333
- * Deletes file(s) from disk and clears out the memory resident object.
334
- */
335
- public async delete() {
336
- return super.delete();
337
- }
338
-
339
321
  /**
340
322
  * Returns all possible field types.
341
323
  * @returns all possible field types.
@@ -407,33 +389,29 @@ export class FieldTypeResource extends FileResource {
407
389
  return this.handleNameChange(existingName);
408
390
  }
409
391
 
410
- /**
411
- * Shows metadata of the resource.
412
- * @returns field type metadata.
413
- */
414
- public async show(): Promise<FieldType> {
415
- return super.show() as Promise<FieldType>;
416
- }
417
-
418
392
  /**
419
393
  * Updates field type resource.
420
- * @param key Key to modify
394
+ * @param updateKey Key to modify
421
395
  * @param op Operation to perform on 'key'
422
396
  * @throws
423
397
  * - when called with unknown data type
424
398
  * - when called with data type conversion that cannot be done
425
399
  * - when called with unknown property to update
426
400
  */
427
- public async update<Type>(key: string, op: Operation<Type>) {
401
+ public async update<Type, K extends string>(
402
+ updateKey: UpdateKey<K>,
403
+ op: Operation<Type>,
404
+ ) {
405
+ const { key } = updateKey;
428
406
  const nameChange = key === 'name';
429
407
  const typeChange = key === 'dataType';
430
408
  const enumChange = key === 'enumValues';
431
409
  const existingName = this.content.name;
432
- const existingType = (this.content as FieldType).dataType;
410
+ const existingType = this.content.dataType;
433
411
 
434
- await super.update(key, op);
412
+ await super.update(updateKey, op);
435
413
 
436
- const content = structuredClone(this.content) as FieldType;
414
+ const content = structuredClone(this.content);
437
415
  if (key === 'name') {
438
416
  content.name = super.handleScalar(op) as string;
439
417
  } else if (key === 'dataType') {
@@ -473,7 +451,7 @@ export class FieldTypeResource extends FileResource {
473
451
  throw new Error(`Unknown property '${key}' for FieldType`);
474
452
  }
475
453
 
476
- await super.postUpdate(content, key, op);
454
+ await super.postUpdate(content, updateKey, op);
477
455
 
478
456
  if (nameChange) {
479
457
  // Renaming this field type causes that references to its name must be updated.
@@ -494,7 +472,7 @@ export class FieldTypeResource extends FileResource {
494
472
  * @returns array of card keys, resource names and calculation filenames that refer this resource.
495
473
  */
496
474
  public async usage(cards?: Card[]): Promise<string[]> {
497
- const allCards = cards ?? (await super.cards());
475
+ const allCards = cards ?? super.cards();
498
476
 
499
477
  const [cardContentReferences, relevantLinkTypes, calculations] =
500
478
  await Promise.all([
@@ -513,11 +491,4 @@ export class FieldTypeResource extends FileResource {
513
491
  ...new Set([...cardReferences, ...relevantLinkTypes, ...calculations]),
514
492
  ];
515
493
  }
516
-
517
- /**
518
- * Validates the resource. If object is invalid, throws.
519
- */
520
- public async validate(content?: object) {
521
- return super.validate(content);
522
- }
523
494
  }