@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
@@ -13,8 +13,8 @@
13
13
 
14
14
  // node
15
15
  import { basename, join, resolve, sep } from 'node:path';
16
- import { copyFile, mkdir, readdir, rm, writeFile } from 'node:fs/promises';
17
16
  import { type Dirent, readdirSync } from 'node:fs';
17
+ import { copyFile, mkdir, rm, writeFile } from 'node:fs/promises';
18
18
 
19
19
  // Base class
20
20
  import { CardContainer } from './card-container.js';
@@ -23,11 +23,7 @@ import {
23
23
  type Card,
24
24
  type CardAttachment,
25
25
  CardNameRegEx,
26
- type FetchCardDetails,
27
- type FileContentType,
28
- type Resource,
29
26
  } from '../interfaces/project-interfaces.js';
30
- import type { CardType, Workflow } from '../interfaces/resource-interfaces.js';
31
27
  import { pathExists, stripExtension } from '../utils/file-utils.js';
32
28
  import { DefaultContent } from '../resources/create-defaults.js';
33
29
 
@@ -38,14 +34,21 @@ import {
38
34
  sortItems,
39
35
  } from '../utils/lexorank.js';
40
36
  import { getChildLogger } from '../utils/log-utils.js';
41
- import { readJsonFile } from '../utils/json.js';
37
+ import { isModulePath } from '../utils/card-utils.js';
42
38
  import { Project } from './project.js';
43
39
  import { resourceName } from '../utils/resource-utils.js';
44
40
 
41
+ import { ROOT } from '../utils/constants.js';
42
+
43
+ // @todo: Fix the constructor to not use Resource.
44
+ import type { Resource } from './project/resource-cache.js';
45
+
45
46
  // creates template instance based on a project path and name
46
47
  export class Template extends CardContainer {
48
+ private templateName: string;
47
49
  private templatePath: string;
48
50
  private templateCardsPath: string;
51
+ private fullTemplateName: string; // Full template name from resource (e.g., 'test/templates/page')
49
52
  private project: Project;
50
53
  private get logger() {
51
54
  return getChildLogger({
@@ -53,12 +56,19 @@ export class Template extends CardContainer {
53
56
  });
54
57
  }
55
58
 
59
+ /**
60
+ * Creates an instance of Template container that holds template related cards.
61
+ * @param project Project in which template is.
62
+ * @param template Template resource that this container is connected to.
63
+ */
64
+ // @todo: Fix the constructor to not use Resource, but resource full path
56
65
  constructor(project: Project, template: Resource) {
57
66
  // Templates might come from modules. Remove module name from template name.
58
67
  const templateName = stripExtension(basename(template.name));
59
- super(template.path!, templateName);
68
+ super(template.path, project.projectPrefix, templateName);
69
+ this.templateName = templateName;
70
+ this.fullTemplateName = template.name;
60
71
 
61
- // prevent constructing a new project object, if one is passed to this class.
62
72
  this.project = project;
63
73
  // optimization - if template.path is set - use it
64
74
  this.templatePath =
@@ -68,30 +78,6 @@ export class Template extends CardContainer {
68
78
  this.templateCardsPath = join(this.templatePath, 'c');
69
79
  }
70
80
 
71
- // Fetches project top level cards only.
72
- // Top level cards are those that have parent as 'root'.
73
- // todo: This should be in 'project' or 'card-container'
74
- private async rootLevelProjectCards(): Promise<Card[]> {
75
- const entries = (
76
- await readdir(this.project.paths.cardRootFolder, {
77
- withFileTypes: true,
78
- })
79
- ).filter((entry) => entry.isDirectory() && CardNameRegEx.test(entry.name));
80
- const cardPromises = entries.map(async (entry) => {
81
- const currentPath = join(entry.parentPath, entry.name);
82
- return {
83
- key: entry.name,
84
- path: currentPath,
85
- metadata: await readJsonFile(
86
- join(currentPath, CardContainer.cardMetadataFile),
87
- ),
88
- children: [],
89
- attachments: [],
90
- };
91
- });
92
- return Promise.all(cardPromises);
93
- }
94
-
95
81
  // Creates card(s) as project cards from template.
96
82
  private async doCreateCards(
97
83
  cards: Card[],
@@ -110,13 +96,13 @@ export class Template extends CardContainer {
110
96
 
111
97
  // Handle ranking for parent cards
112
98
  const parentCards = sortItems(
113
- cards.filter((c) => c.parent === 'root'),
99
+ cards.filter((c) => c.parent === ROOT),
114
100
  (c) => c?.metadata?.rank || '',
115
101
  );
116
102
 
117
103
  const futureSiblings = parentCard
118
- ? parentCard.children || []
119
- : await this.rootLevelProjectCards();
104
+ ? this.project.cardKeysToCards(parentCard.children)
105
+ : this.rootLevelProjectCards();
120
106
 
121
107
  let latestRank =
122
108
  sortItems(
@@ -165,6 +151,24 @@ export class Template extends CardContainer {
165
151
  }
166
152
 
167
153
  card.key = templateIDMap.get(card.key) || card.key;
154
+
155
+ // Set parent field based on template hierarchy and creation location
156
+ // Store the original template parent before key remapping
157
+ const originalParentKey = card.parent;
158
+
159
+ if (parentCard) {
160
+ if (!originalParentKey || originalParentKey === ROOT) {
161
+ card.parent = parentCard.key;
162
+ } else {
163
+ card.parent = templateIDMap.get(originalParentKey) || parentCard.key;
164
+ }
165
+ } else {
166
+ if (!originalParentKey || originalParentKey === ROOT) {
167
+ card.parent = ROOT;
168
+ } else {
169
+ card.parent = templateIDMap.get(originalParentKey) || ROOT;
170
+ }
171
+ }
168
172
  };
169
173
 
170
174
  // Process attachments
@@ -202,20 +206,14 @@ export class Template extends CardContainer {
202
206
  // Process metadata
203
207
  const processMetadata = async (card: Card, parentCards: Card[]) => {
204
208
  if (!card.metadata) return card;
209
+ const cardType = this.project.resources
210
+ .byType(card.metadata?.cardType, 'cardTypes')
211
+ .show();
205
212
 
206
- const cardType = await this.project.resource<CardType>(
207
- card.metadata.cardType || '',
208
- );
209
- if (!cardType) {
210
- throw new Error(
211
- `Card type '${card.metadata.cardType}' of card ${card.key} cannot be found`,
212
- );
213
- }
213
+ const workflow = this.project.resources
214
+ .byType(cardType.workflow, 'workflows')
215
+ .show();
214
216
 
215
- const workflow = await this.project.resource<Workflow>(cardType.workflow);
216
- if (!workflow) {
217
- throw new Error(`Workflow '${cardType.workflow}' cannot be found`);
218
- }
219
217
  const initialWorkflowState = workflow.transitions.find(
220
218
  (item) => item.fromState.includes('') || item.fromState.length === 0,
221
219
  );
@@ -256,8 +254,10 @@ export class Template extends CardContainer {
256
254
  const templatesFolder = this.templateFolder();
257
255
 
258
256
  // Process all cards in parallel
257
+ // Create deep copies to avoid mutating the cached template cards
259
258
  const processedCards = await Promise.all(
260
- cards.map(async (card) => {
259
+ cards.map(async (originalCard) => {
260
+ const card: Card = structuredClone(originalCard);
261
261
  // Update paths and keys
262
262
  updateCardPaths(card, templateIDMap, templatesFolder);
263
263
 
@@ -271,7 +271,7 @@ export class Template extends CardContainer {
271
271
  await mkdir(processedCard.path, { recursive: true });
272
272
 
273
273
  await Promise.all([
274
- processedCard.metadata && this.saveCardMetadata(processedCard),
274
+ this.saveCardMetadata(processedCard),
275
275
  writeFile(
276
276
  join(processedCard.path, Project.cardContentFile),
277
277
  processedAttachments.content || '',
@@ -280,16 +280,25 @@ export class Template extends CardContainer {
280
280
  return processedCard;
281
281
  }),
282
282
  );
283
+ await this.project.handleNewCards(processedCards);
283
284
  return processedCards;
284
285
  } catch (error) {
285
286
  await this.removeCards(templateIDMap);
286
- if (error instanceof Error) {
287
- throw new Error(`Failed to create cards: ${error.message}`);
288
- }
287
+ this.logger.error({ error }, 'Failed to create cards');
289
288
  throw error;
290
289
  }
291
290
  }
292
291
 
292
+ // Helper method to find a card.
293
+ private findCardDirect(cardKey: string): Card {
294
+ const allCards = this.cards();
295
+ const result = allCards.find((card) => card.key === cardKey);
296
+ if (!result) {
297
+ throw new Error(`Card '${cardKey}' is not part of template`);
298
+ }
299
+ return result;
300
+ }
301
+
293
302
  // fetches path to module.
294
303
  private moduleTemplatePath(templateName: string): string {
295
304
  // If template path has already been deduced, return it.
@@ -313,6 +322,7 @@ export class Template extends CardContainer {
313
322
  );
314
323
  const exists = pathExists(templateFolderInModule);
315
324
  if (exists) {
325
+ this.templatePath = templateFolderInModule;
316
326
  return templateFolderInModule;
317
327
  }
318
328
  }
@@ -320,16 +330,14 @@ export class Template extends CardContainer {
320
330
  }
321
331
 
322
332
  // Removes cards
333
+ // Helper for doCreateCards; not intended for any other use.
323
334
  private async removeCards(cardMap: Map<string, string>) {
324
- const tasks: Promise<Card | undefined>[] = [];
335
+ const cards: Card[] = [];
325
336
  // Find all cards that need to be removed.
326
337
  cardMap.forEach((createdCard) => {
327
- tasks.push(this.project.findSpecificCard(createdCard));
338
+ const card = this.project.findCard(createdCard);
339
+ cards.push(card);
328
340
  });
329
- // Remove empty results.
330
- const cards = (await Promise.all(tasks)).filter(
331
- (item) => item !== undefined,
332
- );
333
341
  // Delete card folders.
334
342
  const deleteAll: Promise<void>[] = [];
335
343
  cards.forEach((card) => {
@@ -338,6 +346,14 @@ export class Template extends CardContainer {
338
346
  await Promise.all(deleteAll);
339
347
  }
340
348
 
349
+ // Fetches project top level cards only.
350
+ private rootLevelProjectCards(): Card[] {
351
+ const allProjectCards = this.project.cards(
352
+ this.project.paths.cardRootFolder,
353
+ );
354
+ return allProjectCards.filter((card) => card.parent === ROOT);
355
+ }
356
+
341
357
  // Set path to template location.
342
358
  private setTemplatePath(templateName: string): string {
343
359
  const { prefix, identifier } = resourceName(templateName);
@@ -376,19 +392,20 @@ export class Template extends CardContainer {
376
392
  parentCard?: Card,
377
393
  ): Promise<string> {
378
394
  const destinationCardPath = parentCard
379
- ? join(await this.cardFolder(parentCard.key), 'c')
395
+ ? join(this.cardFolder(parentCard.key), 'c')
380
396
  : this.templateCardsPath;
381
397
  let newCardKey = '';
382
398
 
383
399
  try {
400
+ // todo: to use cache instead of file access
384
401
  if (!pathExists(this.templateFolder())) {
385
402
  throw new Error(`Template '${this.containerName}' does not exist`);
386
403
  }
387
- const cardType = await this.project.resource<CardType>(cardTypeName);
388
- if (cardType === undefined) {
389
- throw new Error(`Card type '${cardTypeName}' does not exist`);
390
- }
391
- if (parentCard && !this.hasCard(parentCard.key)) {
404
+ const cardType = this.project.resources
405
+ .byType(cardTypeName, 'cardTypes')
406
+ .show();
407
+
408
+ if (parentCard && !this.hasTemplateCard(parentCard.key)) {
392
409
  throw new Error(
393
410
  `Card '${parentCard.key}' does not exist in template '${this.containerName}'`,
394
411
  );
@@ -401,8 +418,8 @@ export class Template extends CardContainer {
401
418
  : join(this.templateCardsPath, newCardKey);
402
419
 
403
420
  const templateCards = parentCard
404
- ? parentCard.children || []
405
- : await this.cards();
421
+ ? this.project.cardKeysToCards(parentCard.children)
422
+ : this.cards();
406
423
  const defaultContent = DefaultContent.card(cardType, templateCards);
407
424
 
408
425
  await mkdir(templateCardToCreate, { recursive: true });
@@ -413,12 +430,13 @@ export class Template extends CardContainer {
413
430
  children: [],
414
431
  attachments: [],
415
432
  content: '',
433
+ parent: parentCard ? parentCard.key : ROOT,
416
434
  };
417
435
  await this.saveCard(defaultCard);
436
+ await this.project.handleNewCards([defaultCard]);
418
437
  } catch (error) {
419
- if (error instanceof Error) {
420
- throw new Error(error.message);
421
- }
438
+ this.logger.error({ error });
439
+ throw error;
422
440
  }
423
441
  return newCardKey;
424
442
  }
@@ -427,8 +445,8 @@ export class Template extends CardContainer {
427
445
  * Return all attachment in the template.
428
446
  * @returns all attachments in the template.
429
447
  */
430
- public async attachments(): Promise<CardAttachment[]> {
431
- return super.attachments(this.templateCardsPath);
448
+ public attachments(): CardAttachment[] {
449
+ return this.project.attachmentsByPath(this.templateCardsPath);
432
450
  }
433
451
 
434
452
  /**
@@ -436,58 +454,37 @@ export class Template extends CardContainer {
436
454
  * @param cardKey card key
437
455
  * @returns path to card's attachment folder.
438
456
  */
439
- public async cardAttachmentFolder(cardKey: string): Promise<string> {
440
- const pathToCard = await this.cardFolder(cardKey);
441
- if (!pathToCard) {
442
- throw new Error(`Template card '${cardKey}' not found`);
443
- }
457
+ public cardAttachmentFolder(cardKey: string): string {
458
+ const pathToCard = this.project.findCard(cardKey)?.path;
444
459
  return join(pathToCard, 'a');
445
460
  }
446
461
 
447
- /**
448
- * Returns details (as defined by cardDetails) of a card.
449
- * @param cardKey card key (project prefix and a number, e.g. test_1)
450
- * @param cardDetails which card details are returned.
451
- * @returns Card details, or undefined if the card cannot be found.
452
- */
453
- public async cardDetailsById(
454
- cardKey: string,
455
- cardDetails: FetchCardDetails,
456
- ): Promise<Card | undefined> {
457
- return super.findCard(this.templateCardsPath, cardKey, cardDetails);
458
- }
459
-
460
462
  /**
461
463
  * returns path to card's folder.
462
464
  * @param cardKey card key
463
465
  * @returns path to card's folder.
464
466
  */
465
- public async cardFolder(cardKey: string): Promise<string> {
466
- const found = await super.findCard(this.templateCardsPath, cardKey);
467
+ public cardFolder(cardKey: string): string {
468
+ const found = this.findCardDirect(cardKey);
467
469
  return found ? found.path : '';
468
470
  }
469
471
 
470
472
  /**
471
- * Returns all cards in the template. Cards have content and metadata.
473
+ * Returns all cards in the template.
472
474
  * @param placeHolderPath This is not used. Needed to be compatible with base class.
473
- * @param details Optional. Which details are returned for each card. If missing, default value will be used.
474
475
  * @returns Template cards in the template.
475
476
  */
476
- public async cards(
477
- placeHolderPath?: string,
478
- details?: FetchCardDetails,
479
- ): Promise<Card[]> {
477
+ public cards(placeHolderPath?: string): Card[] {
480
478
  if (placeHolderPath) {
481
479
  this.logger.warn('A non-used variable was used in the cards method');
482
480
  }
483
- const cardDetails = details
484
- ? details
485
- : {
486
- content: true,
487
- contentType: 'adoc' as FileContentType,
488
- metadata: true,
489
- };
490
- return super.cards(this.templateCardsPath, cardDetails);
481
+
482
+ // Filter cards from the project's card cache that belong to this template.
483
+ const allCards = [...this.project.cardsCache.getCards()];
484
+ return allCards.filter(
485
+ (card) =>
486
+ card.location !== 'project' && card.location === this.fullTemplateName,
487
+ );
491
488
  }
492
489
 
493
490
  /**
@@ -496,13 +493,7 @@ export class Template extends CardContainer {
496
493
  * @returns array of created card keys
497
494
  */
498
495
  public async createCards(parentCard?: Card): Promise<Card[]> {
499
- const cards = await this.cards('', {
500
- content: true,
501
- contentType: 'adoc',
502
- metadata: true,
503
- attachments: true,
504
- parent: true,
505
- });
496
+ const cards = this.cards();
506
497
  if (cards.length === 0) {
507
498
  throw new Error(
508
499
  `No cards in template '${this.containerName}'. Please add template cards with 'add' command first.`,
@@ -514,13 +505,9 @@ export class Template extends CardContainer {
514
505
  /**
515
506
  * Returns specific card.
516
507
  * @param cardKey Card key to find from template.
517
- * @param details Card details to include in return value.
518
508
  * @returns specific card details
519
509
  */
520
- public async findSpecificCard(
521
- cardKey: string,
522
- details: FetchCardDetails = {},
523
- ): Promise<Card | undefined> {
510
+ public findCard(cardKey: string): Card {
524
511
  const cardPrefix = cardKey.split('_').at(0);
525
512
  const moduleCardFromProject =
526
513
  this.basePath.includes('local') &&
@@ -530,18 +517,19 @@ export class Template extends CardContainer {
530
517
  this.project.projectPrefix === cardPrefix;
531
518
  // If the result is impossible, return undefined.
532
519
  if (moduleCardFromProject || projectCardFromModule) {
533
- return undefined;
520
+ throw new Error(`Card '${cardKey}' is not part of template`);
534
521
  }
535
- return super.findCard(this.templateCardsPath, cardKey, details);
522
+
523
+ return this.findCardDirect(cardKey);
536
524
  }
537
525
 
538
526
  /**
539
527
  * Checks if a specific card key exists in a template.
540
528
  * @param cardKey Card key to find from template.
541
- * @return true if card with a given card key exists in the template, false otherwise.
529
+ * @returns true if card with a given card key exists in the template, false otherwise.
542
530
  */
543
- public hasCard(cardKey: string): boolean {
544
- return super.hasCard(cardKey, this.templateCardsPath);
531
+ public hasTemplateCard(cardKey: string): boolean {
532
+ return this.project.hasTemplateCard(cardKey);
545
533
  }
546
534
 
547
535
  /**
@@ -549,15 +537,30 @@ export class Template extends CardContainer {
549
537
  * @returns true, if template is exists in project; false otherwise
550
538
  */
551
539
  public isCreated(): boolean {
540
+ // todo: to use cache instead of file access
552
541
  return pathExists(this.templateCardsPath);
553
542
  }
554
543
 
555
544
  /**
556
- * Returns an array of all the cards in the project. Cards don't have content nor metadata.
557
- * @returns all cards in the project.
545
+ * Returns an array of all the cards in the template.
546
+ * @returns all cards in the template.
558
547
  */
559
- public async listCards(): Promise<Card[]> {
560
- return super.cards(this.templateCardsPath);
548
+ public listCards(): Card[] {
549
+ // Construct the full template name to match what's stored in cache
550
+ const fullTemplateName = isModulePath(this.basePath)
551
+ ? `${this.basePath.split(`${sep}modules${sep}`)[1].split(`${sep}templates`)[0]}/templates/${this.templateName}`
552
+ : `${this.project.projectPrefix}/templates/${this.templateName}`;
553
+
554
+ const templateCards = Array.from(this.project.cardsCache.getCards()).filter(
555
+ (cachedCard) => {
556
+ if (cachedCard.location === 'project') {
557
+ return false;
558
+ }
559
+ const storedTemplateName = cachedCard.location;
560
+ return storedTemplateName === fullTemplateName;
561
+ },
562
+ );
563
+ return templateCards;
561
564
  }
562
565
 
563
566
  /**
@@ -568,14 +571,6 @@ export class Template extends CardContainer {
568
571
  return this.templateCardsPath;
569
572
  }
570
573
 
571
- /**
572
- * Path to template configuration json file.
573
- * @returns path to the template's configuration file.
574
- */
575
- public templateConfigurationFilePath(): string {
576
- return join(this.templatePath, '..', this.containerName + '.json');
577
- }
578
-
579
574
  /**
580
575
  * Returns path to 'templates' folder.
581
576
  * @returns path to the project's folder that contains templates.
@@ -583,12 +578,4 @@ export class Template extends CardContainer {
583
578
  public templateFolder(): string {
584
579
  return this.templatePath;
585
580
  }
586
-
587
- /**
588
- * Show cards of a template with hierarchy structure.
589
- * @returns an array of all template cards with proper parent-child relationships.
590
- */
591
- public async showTemplateCards(): Promise<Card[]> {
592
- return this.showCards(this.templateCardsPath);
593
- }
594
581
  }
package/src/index.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  } from './command-handler.js';
21
21
  import { Validate } from './commands/validate.js';
22
22
  export * from './interfaces/project-interfaces.js';
23
+ export * from './interfaces/macros.js';
23
24
  import { requestStatus } from './interfaces/request-status-interfaces.js';
24
25
  import { UpdateOperations } from './resources/resource-object.js';
25
26
  export type {
@@ -13,6 +13,8 @@
13
13
 
14
14
  import type { Schema } from 'jsonschema';
15
15
 
16
+ export type { Schema };
17
+
16
18
  // All file mappings for lookup (filename -> property name)
17
19
  export const ALL_FILE_MAPPINGS = {
18
20
  'calculation.lp': 'calculation',
@@ -24,7 +26,7 @@ export const ALL_FILE_MAPPINGS = {
24
26
  } as const;
25
27
 
26
28
  // Reverse mappings from property names to filenames
27
- export const REVERSE_FILE_MAPPINGS = {
29
+ export const CONTENT_FILES = {
28
30
  calculation: 'calculation.lp',
29
31
  contentTemplate: 'index.adoc.hbs',
30
32
  model: 'model.lp',
@@ -34,7 +36,7 @@ export const REVERSE_FILE_MAPPINGS = {
34
36
  } as const;
35
37
 
36
38
  // Union type of all valid content property names
37
- export type ContentPropertyName = keyof typeof REVERSE_FILE_MAPPINGS;
39
+ export type ContentPropertyName = keyof typeof CONTENT_FILES;
38
40
 
39
41
  // Content interface for Calculation resources
40
42
  export interface CalculationContent {
@@ -43,12 +45,13 @@ export interface CalculationContent {
43
45
 
44
46
  // Content interface for Graph Model resources
45
47
  export interface GraphModelContent {
46
- model?: string;
48
+ model: string;
47
49
  }
48
50
 
49
51
  // Content interface for Graph View resources
50
52
  export interface GraphViewContent {
51
53
  viewTemplate?: string;
54
+ schema?: Schema;
52
55
  }
53
56
 
54
57
  // Content interface for Report resources
@@ -58,15 +61,19 @@ export interface ReportContent {
58
61
  schema?: Schema;
59
62
  }
60
63
 
64
+ export type FolderResourceContent =
65
+ | CalculationContent
66
+ | GraphModelContent
67
+ | GraphViewContent
68
+ | ReportContent;
69
+
61
70
  /**
62
71
  * Get filename with property name
63
72
  * @param propertyName Property name.
64
73
  * @returns filename that matches property name
65
74
  */
66
75
  export function filename(propertyName: string): string | undefined {
67
- return REVERSE_FILE_MAPPINGS[
68
- propertyName as keyof typeof REVERSE_FILE_MAPPINGS
69
- ];
76
+ return CONTENT_FILES[propertyName as keyof typeof CONTENT_FILES];
70
77
  }
71
78
 
72
79
  /**
@@ -74,7 +81,7 @@ export function filename(propertyName: string): string | undefined {
74
81
  * @param filename Filename.
75
82
  * @returns property name that matches filename
76
83
  */
77
- export function propertyName(
84
+ export function contentPropertyName(
78
85
  filename: string,
79
86
  ): ContentPropertyName | undefined {
80
87
  return ALL_FILE_MAPPINGS[filename as keyof typeof ALL_FILE_MAPPINGS];
@@ -59,3 +59,5 @@ export interface HandlebarsOptions {
59
59
  }
60
60
 
61
61
  export type MacroName = keyof typeof macroMetadata;
62
+
63
+ export * from '../macros/types.js';
@@ -21,8 +21,14 @@ export interface Card {
21
21
  content?: string;
22
22
  metadata?: CardMetadata;
23
23
  parent?: string;
24
- children: Card[];
24
+ children: string[];
25
25
  attachments: CardAttachment[];
26
+ calculations?: unknown[];
27
+ }
28
+
29
+ // Single card, but childrenCards as Card array
30
+ export interface CardWithChildrenCards extends Card {
31
+ childrenCards: CardWithChildrenCards[];
26
32
  }
27
33
 
28
34
  // Attachment details
@@ -172,6 +178,7 @@ export interface ProjectMetadata {
172
178
 
173
179
  // Project's settings (=cardsConfig.json).
174
180
  export interface ProjectSettings {
181
+ schemaVersion?: number;
175
182
  cardKeyPrefix: string;
176
183
  name: string;
177
184
  modules: ModuleSetting[];
@@ -222,12 +229,9 @@ export type RemovableResourceTypes =
222
229
  | 'workflow'
223
230
  | 'label';
224
231
 
225
- // Project resource, such as workflow, template or card type as file system object.
226
- export interface Resource {
227
- name: string;
228
- path: string;
229
- }
230
-
232
+ // TODO: fix terminology. In DH, modules are not resources.
233
+ // Also, this contains non-folder resources
234
+ // This was done likely like this, because on the CLI, they act similarly to resources
231
235
  // Resources that have own folders.
232
236
  export type ResourceFolderType =
233
237
  | 'calculations'
@@ -241,6 +245,9 @@ export type ResourceFolderType =
241
245
  | 'templates'
242
246
  | 'workflows';
243
247
 
248
+ // This covers all 'true' resources
249
+ export type ResourceType = Exclude<ResourceFolderType, 'modules'>;
250
+
244
251
  // All resource types; both singular and plural.
245
252
  export type ResourceTypes =
246
253
  | RemovableResourceTypes