@cyberismo/data-handler 0.0.14 → 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 (240) 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 +10 -16
  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.js +13 -59
  9. package/dist/commands/create.js.map +1 -1
  10. package/dist/commands/edit.d.ts +1 -15
  11. package/dist/commands/edit.js +15 -89
  12. package/dist/commands/edit.js.map +1 -1
  13. package/dist/commands/export.js +4 -17
  14. package/dist/commands/export.js.map +1 -1
  15. package/dist/commands/import.js +3 -5
  16. package/dist/commands/import.js.map +1 -1
  17. package/dist/commands/move.d.ts +1 -2
  18. package/dist/commands/move.js +108 -146
  19. package/dist/commands/move.js.map +1 -1
  20. package/dist/commands/remove.js +9 -44
  21. package/dist/commands/remove.js.map +1 -1
  22. package/dist/commands/rename.js +2 -7
  23. package/dist/commands/rename.js.map +1 -1
  24. package/dist/commands/show.d.ts +7 -25
  25. package/dist/commands/show.js +38 -102
  26. package/dist/commands/show.js.map +1 -1
  27. package/dist/commands/transition.js +27 -30
  28. package/dist/commands/transition.js.map +1 -1
  29. package/dist/commands/update.d.ts +5 -3
  30. package/dist/commands/update.js +19 -5
  31. package/dist/commands/update.js.map +1 -1
  32. package/dist/commands/validate.d.ts +3 -3
  33. package/dist/commands/validate.js +19 -26
  34. package/dist/commands/validate.js.map +1 -1
  35. package/dist/containers/card-container.d.ts +87 -24
  36. package/dist/containers/card-container.js +183 -279
  37. package/dist/containers/card-container.js.map +1 -1
  38. package/dist/containers/project/calculation-engine.d.ts +6 -0
  39. package/dist/containers/project/calculation-engine.js +19 -12
  40. package/dist/containers/project/calculation-engine.js.map +1 -1
  41. package/dist/containers/project/card-cache.d.ts +146 -0
  42. package/dist/containers/project/card-cache.js +411 -0
  43. package/dist/containers/project/card-cache.js.map +1 -0
  44. package/dist/containers/project/resource-collector.d.ts +24 -1
  45. package/dist/containers/project/resource-collector.js +8 -1
  46. package/dist/containers/project/resource-collector.js.map +1 -1
  47. package/dist/containers/project.d.ts +117 -83
  48. package/dist/containers/project.js +418 -252
  49. package/dist/containers/project.js.map +1 -1
  50. package/dist/containers/template.d.ts +15 -31
  51. package/dist/containers/template.js +97 -104
  52. package/dist/containers/template.js.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.js +1 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/interfaces/folder-content-interfaces.d.ts +2 -1
  57. package/dist/interfaces/folder-content-interfaces.js.map +1 -1
  58. package/dist/interfaces/macros.d.ts +1 -0
  59. package/dist/interfaces/macros.js +1 -1
  60. package/dist/interfaces/macros.js.map +1 -1
  61. package/dist/interfaces/project-interfaces.d.ts +5 -1
  62. package/dist/interfaces/project-interfaces.js.map +1 -1
  63. package/dist/interfaces/resource-interfaces.d.ts +11 -21
  64. package/dist/interfaces/resource-interfaces.js +3 -0
  65. package/dist/interfaces/resource-interfaces.js.map +1 -1
  66. package/dist/macros/common.d.ts +10 -10
  67. package/dist/macros/createCards/index.d.ts +0 -13
  68. package/dist/macros/createCards/index.js.map +1 -1
  69. package/dist/macros/createCards/types.d.ts +44 -0
  70. package/dist/macros/createCards/types.js +15 -0
  71. package/dist/macros/createCards/types.js.map +1 -0
  72. package/dist/macros/graph/index.d.ts +2 -6
  73. package/dist/macros/graph/index.js +2 -2
  74. package/dist/macros/graph/index.js.map +1 -1
  75. package/dist/macros/graph/types.d.ts +23 -0
  76. package/dist/macros/graph/types.js +15 -0
  77. package/dist/macros/graph/types.js.map +1 -0
  78. package/dist/macros/image/index.d.ts +8 -16
  79. package/dist/macros/image/index.js +36 -33
  80. package/dist/macros/image/index.js.map +1 -1
  81. package/dist/macros/image/types.d.ts +38 -0
  82. package/dist/macros/image/types.js +15 -0
  83. package/dist/macros/image/types.js.map +1 -0
  84. package/dist/macros/include/index.d.ts +1 -6
  85. package/dist/macros/include/index.js +4 -7
  86. package/dist/macros/include/index.js.map +1 -1
  87. package/dist/macros/include/types.d.ts +31 -0
  88. package/dist/macros/include/types.js +15 -0
  89. package/dist/macros/include/types.js.map +1 -0
  90. package/dist/macros/percentage/index.d.ts +0 -6
  91. package/dist/macros/percentage/index.js.map +1 -1
  92. package/dist/macros/percentage/types.d.ts +31 -0
  93. package/dist/macros/percentage/types.js +15 -0
  94. package/dist/macros/percentage/types.js.map +1 -0
  95. package/dist/macros/report/index.d.ts +0 -3
  96. package/dist/macros/report/index.js.map +1 -1
  97. package/dist/macros/report/types.d.ts +19 -0
  98. package/dist/macros/report/types.js +15 -0
  99. package/dist/macros/report/types.js.map +1 -0
  100. package/dist/macros/scoreCard/index.d.ts +0 -6
  101. package/dist/macros/scoreCard/index.js.map +1 -1
  102. package/dist/macros/scoreCard/types.d.ts +31 -0
  103. package/dist/macros/scoreCard/types.js +15 -0
  104. package/dist/macros/scoreCard/types.js.map +1 -0
  105. package/dist/macros/types.d.ts +25 -0
  106. package/dist/macros/types.js +2 -0
  107. package/dist/macros/types.js.map +1 -0
  108. package/dist/macros/vega/index.d.ts +0 -4
  109. package/dist/macros/vega/index.js.map +1 -1
  110. package/dist/macros/vega/types.d.ts +20 -0
  111. package/dist/macros/vega/types.js +2 -0
  112. package/dist/macros/vega/types.js.map +1 -0
  113. package/dist/macros/vegalite/index.d.ts +0 -4
  114. package/dist/macros/vegalite/index.js.map +1 -1
  115. package/dist/macros/vegalite/types.d.ts +20 -0
  116. package/dist/macros/vegalite/types.js +15 -0
  117. package/dist/macros/vegalite/types.js.map +1 -0
  118. package/dist/macros/xref/index.d.ts +0 -3
  119. package/dist/macros/xref/index.js +5 -14
  120. package/dist/macros/xref/index.js.map +1 -1
  121. package/dist/macros/xref/types.d.ts +19 -0
  122. package/dist/macros/xref/types.js +15 -0
  123. package/dist/macros/xref/types.js.map +1 -0
  124. package/dist/module-manager.js +4 -4
  125. package/dist/module-manager.js.map +1 -1
  126. package/dist/project-settings.js.map +1 -1
  127. package/dist/resources/calculation-resource.d.ts +4 -32
  128. package/dist/resources/calculation-resource.js +0 -55
  129. package/dist/resources/calculation-resource.js.map +1 -1
  130. package/dist/resources/card-type-resource.d.ts +4 -21
  131. package/dist/resources/card-type-resource.js +13 -44
  132. package/dist/resources/card-type-resource.js.map +1 -1
  133. package/dist/resources/field-type-resource.d.ts +4 -21
  134. package/dist/resources/field-type-resource.js +14 -38
  135. package/dist/resources/field-type-resource.js.map +1 -1
  136. package/dist/resources/file-resource.d.ts +12 -29
  137. package/dist/resources/file-resource.js +19 -293
  138. package/dist/resources/file-resource.js.map +1 -1
  139. package/dist/resources/folder-resource.d.ts +31 -50
  140. package/dist/resources/folder-resource.js +68 -96
  141. package/dist/resources/folder-resource.js.map +1 -1
  142. package/dist/resources/graph-model-resource.d.ts +5 -33
  143. package/dist/resources/graph-model-resource.js +8 -61
  144. package/dist/resources/graph-model-resource.js.map +1 -1
  145. package/dist/resources/graph-view-resource.d.ts +5 -28
  146. package/dist/resources/graph-view-resource.js +6 -45
  147. package/dist/resources/graph-view-resource.js.map +1 -1
  148. package/dist/resources/link-type-resource.d.ts +4 -21
  149. package/dist/resources/link-type-resource.js +6 -31
  150. package/dist/resources/link-type-resource.js.map +1 -1
  151. package/dist/resources/report-resource.d.ts +5 -17
  152. package/dist/resources/report-resource.js +6 -44
  153. package/dist/resources/report-resource.js.map +1 -1
  154. package/dist/resources/resource-object.d.ts +58 -23
  155. package/dist/resources/resource-object.js +293 -24
  156. package/dist/resources/resource-object.js.map +1 -1
  157. package/dist/resources/template-resource.d.ts +4 -15
  158. package/dist/resources/template-resource.js +10 -25
  159. package/dist/resources/template-resource.js.map +1 -1
  160. package/dist/resources/workflow-resource.d.ts +4 -23
  161. package/dist/resources/workflow-resource.js +12 -38
  162. package/dist/resources/workflow-resource.js.map +1 -1
  163. package/dist/utils/card-utils.d.ts +69 -19
  164. package/dist/utils/card-utils.js +179 -30
  165. package/dist/utils/card-utils.js.map +1 -1
  166. package/dist/utils/clingo-facts.js +11 -3
  167. package/dist/utils/clingo-facts.js.map +1 -1
  168. package/dist/utils/clingo-parser.js +1 -1
  169. package/dist/utils/clingo-parser.js.map +1 -1
  170. package/dist/utils/constants.d.ts +2 -0
  171. package/dist/utils/constants.js +4 -0
  172. package/dist/utils/constants.js.map +1 -1
  173. package/dist/utils/csv.js +1 -1
  174. package/dist/utils/csv.js.map +1 -1
  175. package/package.json +5 -5
  176. package/src/card-metadata-updater.ts +3 -5
  177. package/src/command-handler.ts +11 -18
  178. package/src/command-manager.ts +4 -3
  179. package/src/commands/create.ts +17 -83
  180. package/src/commands/edit.ts +16 -132
  181. package/src/commands/export.ts +8 -29
  182. package/src/commands/import.ts +4 -6
  183. package/src/commands/move.ts +144 -179
  184. package/src/commands/remove.ts +9 -52
  185. package/src/commands/rename.ts +2 -7
  186. package/src/commands/show.ts +50 -143
  187. package/src/commands/transition.ts +30 -33
  188. package/src/commands/update.ts +27 -9
  189. package/src/commands/validate.ts +21 -36
  190. package/src/containers/card-container.ts +200 -360
  191. package/src/containers/project/calculation-engine.ts +21 -13
  192. package/src/containers/project/card-cache.ts +497 -0
  193. package/src/containers/project/resource-collector.ts +9 -1
  194. package/src/containers/project.ts +529 -327
  195. package/src/containers/template.ts +109 -127
  196. package/src/index.ts +1 -0
  197. package/src/interfaces/folder-content-interfaces.ts +7 -1
  198. package/src/interfaces/macros.ts +2 -0
  199. package/src/interfaces/project-interfaces.ts +7 -1
  200. package/src/interfaces/resource-interfaces.ts +12 -24
  201. package/src/macros/createCards/index.ts +1 -12
  202. package/src/macros/createCards/types.ts +46 -0
  203. package/src/macros/graph/index.ts +3 -7
  204. package/src/macros/graph/types.ts +24 -0
  205. package/src/macros/image/index.ts +50 -61
  206. package/src/macros/image/types.ts +39 -0
  207. package/src/macros/include/index.ts +6 -15
  208. package/src/macros/include/types.ts +32 -0
  209. package/src/macros/percentage/index.ts +1 -7
  210. package/src/macros/percentage/types.ts +32 -0
  211. package/src/macros/report/index.ts +1 -4
  212. package/src/macros/report/types.ts +20 -0
  213. package/src/macros/scoreCard/index.ts +1 -7
  214. package/src/macros/scoreCard/types.ts +32 -0
  215. package/src/macros/types.ts +48 -0
  216. package/src/macros/vega/index.ts +1 -4
  217. package/src/macros/vega/types.ts +21 -0
  218. package/src/macros/vegalite/index.ts +1 -4
  219. package/src/macros/vegalite/types.ts +22 -0
  220. package/src/macros/xref/index.ts +6 -20
  221. package/src/macros/xref/types.ts +20 -0
  222. package/src/module-manager.ts +5 -5
  223. package/src/project-settings.ts +1 -1
  224. package/src/resources/calculation-resource.ts +6 -76
  225. package/src/resources/card-type-resource.ts +24 -59
  226. package/src/resources/field-type-resource.ts +22 -51
  227. package/src/resources/file-resource.ts +27 -409
  228. package/src/resources/folder-resource.ts +98 -124
  229. package/src/resources/graph-model-resource.ts +17 -74
  230. package/src/resources/graph-view-resource.ts +14 -54
  231. package/src/resources/link-type-resource.ts +13 -40
  232. package/src/resources/report-resource.ts +17 -57
  233. package/src/resources/resource-object.ts +435 -32
  234. package/src/resources/template-resource.ts +16 -29
  235. package/src/resources/workflow-resource.ts +26 -50
  236. package/src/utils/card-utils.ts +217 -31
  237. package/src/utils/clingo-facts.ts +13 -3
  238. package/src/utils/clingo-parser.ts +1 -1
  239. package/src/utils/constants.ts +6 -0
  240. package/src/utils/csv.ts +1 -1
@@ -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,8 +23,6 @@ import {
23
23
  type Card,
24
24
  type CardAttachment,
25
25
  CardNameRegEx,
26
- type FetchCardDetails,
27
- type FileContentType,
28
26
  type Resource,
29
27
  } from '../interfaces/project-interfaces.js';
30
28
  import type { CardType, Workflow } from '../interfaces/resource-interfaces.js';
@@ -38,14 +36,18 @@ import {
38
36
  sortItems,
39
37
  } from '../utils/lexorank.js';
40
38
  import { getChildLogger } from '../utils/log-utils.js';
41
- import { readJsonFile } from '../utils/json.js';
39
+ import { isModulePath } from '../utils/card-utils.js';
42
40
  import { Project } from './project.js';
43
41
  import { resourceName } from '../utils/resource-utils.js';
44
42
 
43
+ import { ROOT } from '../utils/constants.js';
44
+
45
45
  // creates template instance based on a project path and name
46
46
  export class Template extends CardContainer {
47
+ private templateName: string;
47
48
  private templatePath: string;
48
49
  private templateCardsPath: string;
50
+ private fullTemplateName: string; // Full template name from resource (e.g., 'test/templates/page')
49
51
  private project: Project;
50
52
  private get logger() {
51
53
  return getChildLogger({
@@ -56,9 +58,10 @@ export class Template extends CardContainer {
56
58
  constructor(project: Project, template: Resource) {
57
59
  // Templates might come from modules. Remove module name from template name.
58
60
  const templateName = stripExtension(basename(template.name));
59
- super(template.path!, templateName);
61
+ super(template.path, project.projectPrefix, templateName);
62
+ this.templateName = templateName;
63
+ this.fullTemplateName = template.name;
60
64
 
61
- // prevent constructing a new project object, if one is passed to this class.
62
65
  this.project = project;
63
66
  // optimization - if template.path is set - use it
64
67
  this.templatePath =
@@ -68,30 +71,6 @@ export class Template extends CardContainer {
68
71
  this.templateCardsPath = join(this.templatePath, 'c');
69
72
  }
70
73
 
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
74
  // Creates card(s) as project cards from template.
96
75
  private async doCreateCards(
97
76
  cards: Card[],
@@ -110,13 +89,13 @@ export class Template extends CardContainer {
110
89
 
111
90
  // Handle ranking for parent cards
112
91
  const parentCards = sortItems(
113
- cards.filter((c) => c.parent === 'root'),
92
+ cards.filter((c) => c.parent === ROOT),
114
93
  (c) => c?.metadata?.rank || '',
115
94
  );
116
95
 
117
96
  const futureSiblings = parentCard
118
- ? parentCard.children || []
119
- : await this.rootLevelProjectCards();
97
+ ? this.project.cardKeysToCards(parentCard.children)
98
+ : this.rootLevelProjectCards();
120
99
 
121
100
  let latestRank =
122
101
  sortItems(
@@ -165,6 +144,24 @@ export class Template extends CardContainer {
165
144
  }
166
145
 
167
146
  card.key = templateIDMap.get(card.key) || card.key;
147
+
148
+ // Set parent field based on template hierarchy and creation location
149
+ // Store the original template parent before key remapping
150
+ const originalParentKey = card.parent;
151
+
152
+ if (parentCard) {
153
+ if (!originalParentKey || originalParentKey === ROOT) {
154
+ card.parent = parentCard.key;
155
+ } else {
156
+ card.parent = templateIDMap.get(originalParentKey) || parentCard.key;
157
+ }
158
+ } else {
159
+ if (!originalParentKey || originalParentKey === ROOT) {
160
+ card.parent = ROOT;
161
+ } else {
162
+ card.parent = templateIDMap.get(originalParentKey) || ROOT;
163
+ }
164
+ }
168
165
  };
169
166
 
170
167
  // Process attachments
@@ -203,16 +200,14 @@ export class Template extends CardContainer {
203
200
  const processMetadata = async (card: Card, parentCards: Card[]) => {
204
201
  if (!card.metadata) return card;
205
202
 
206
- const cardType = await this.project.resource<CardType>(
207
- card.metadata.cardType || '',
208
- );
203
+ const cardType = this.project.resource<CardType>(card.metadata?.cardType);
209
204
  if (!cardType) {
210
205
  throw new Error(
211
- `Card type '${card.metadata.cardType}' of card ${card.key} cannot be found`,
206
+ `Card type '${card.metadata?.cardType}' of card ${card.key} cannot be found`,
212
207
  );
213
208
  }
214
209
 
215
- const workflow = await this.project.resource<Workflow>(cardType.workflow);
210
+ const workflow = this.project.resource<Workflow>(cardType.workflow);
216
211
  if (!workflow) {
217
212
  throw new Error(`Workflow '${cardType.workflow}' cannot be found`);
218
213
  }
@@ -256,8 +251,10 @@ export class Template extends CardContainer {
256
251
  const templatesFolder = this.templateFolder();
257
252
 
258
253
  // Process all cards in parallel
254
+ // Create deep copies to avoid mutating the cached template cards
259
255
  const processedCards = await Promise.all(
260
- cards.map(async (card) => {
256
+ cards.map(async (originalCard) => {
257
+ const card: Card = structuredClone(originalCard);
261
258
  // Update paths and keys
262
259
  updateCardPaths(card, templateIDMap, templatesFolder);
263
260
 
@@ -280,16 +277,25 @@ export class Template extends CardContainer {
280
277
  return processedCard;
281
278
  }),
282
279
  );
280
+ await this.project.handleNewCards(processedCards);
283
281
  return processedCards;
284
282
  } catch (error) {
285
283
  await this.removeCards(templateIDMap);
286
- if (error instanceof Error) {
287
- throw new Error(`Failed to create cards: ${error.message}`);
288
- }
284
+ this.logger.error({ error }, 'Failed to create cards');
289
285
  throw error;
290
286
  }
291
287
  }
292
288
 
289
+ // Helper method to find a card.
290
+ private findCardDirect(cardKey: string): Card {
291
+ const allCards = this.cards();
292
+ const result = allCards.find((card) => card.key === cardKey);
293
+ if (!result) {
294
+ throw new Error(`Card '${cardKey}' is not part of template`);
295
+ }
296
+ return result;
297
+ }
298
+
293
299
  // fetches path to module.
294
300
  private moduleTemplatePath(templateName: string): string {
295
301
  // If template path has already been deduced, return it.
@@ -313,6 +319,7 @@ export class Template extends CardContainer {
313
319
  );
314
320
  const exists = pathExists(templateFolderInModule);
315
321
  if (exists) {
322
+ this.templatePath = templateFolderInModule;
316
323
  return templateFolderInModule;
317
324
  }
318
325
  }
@@ -320,16 +327,14 @@ export class Template extends CardContainer {
320
327
  }
321
328
 
322
329
  // Removes cards
330
+ // Helper for doCreateCards; not intended for any other use.
323
331
  private async removeCards(cardMap: Map<string, string>) {
324
- const tasks: Promise<Card | undefined>[] = [];
332
+ const cards: Card[] = [];
325
333
  // Find all cards that need to be removed.
326
334
  cardMap.forEach((createdCard) => {
327
- tasks.push(this.project.findSpecificCard(createdCard));
335
+ const card = this.project.findCard(createdCard);
336
+ cards.push(card);
328
337
  });
329
- // Remove empty results.
330
- const cards = (await Promise.all(tasks)).filter(
331
- (item) => item !== undefined,
332
- );
333
338
  // Delete card folders.
334
339
  const deleteAll: Promise<void>[] = [];
335
340
  cards.forEach((card) => {
@@ -338,6 +343,14 @@ export class Template extends CardContainer {
338
343
  await Promise.all(deleteAll);
339
344
  }
340
345
 
346
+ // Fetches project top level cards only.
347
+ private rootLevelProjectCards(): Card[] {
348
+ const allProjectCards = this.project.cards(
349
+ this.project.paths.cardRootFolder,
350
+ );
351
+ return allProjectCards.filter((card) => card.parent === ROOT);
352
+ }
353
+
341
354
  // Set path to template location.
342
355
  private setTemplatePath(templateName: string): string {
343
356
  const { prefix, identifier } = resourceName(templateName);
@@ -384,11 +397,11 @@ export class Template extends CardContainer {
384
397
  if (!pathExists(this.templateFolder())) {
385
398
  throw new Error(`Template '${this.containerName}' does not exist`);
386
399
  }
387
- const cardType = await this.project.resource<CardType>(cardTypeName);
400
+ const cardType = this.project.resource<CardType>(cardTypeName);
388
401
  if (cardType === undefined) {
389
402
  throw new Error(`Card type '${cardTypeName}' does not exist`);
390
403
  }
391
- if (parentCard && !this.hasCard(parentCard.key)) {
404
+ if (parentCard && !this.hasTemplateCard(parentCard.key)) {
392
405
  throw new Error(
393
406
  `Card '${parentCard.key}' does not exist in template '${this.containerName}'`,
394
407
  );
@@ -401,8 +414,8 @@ export class Template extends CardContainer {
401
414
  : join(this.templateCardsPath, newCardKey);
402
415
 
403
416
  const templateCards = parentCard
404
- ? parentCard.children || []
405
- : await this.cards();
417
+ ? this.project.cardKeysToCards(parentCard.children)
418
+ : this.cards();
406
419
  const defaultContent = DefaultContent.card(cardType, templateCards);
407
420
 
408
421
  await mkdir(templateCardToCreate, { recursive: true });
@@ -413,12 +426,13 @@ export class Template extends CardContainer {
413
426
  children: [],
414
427
  attachments: [],
415
428
  content: '',
429
+ parent: parentCard ? parentCard.key : ROOT,
416
430
  };
417
431
  await this.saveCard(defaultCard);
432
+ await this.project.handleNewCards([defaultCard]);
418
433
  } catch (error) {
419
- if (error instanceof Error) {
420
- throw new Error(error.message);
421
- }
434
+ this.logger.error({ error });
435
+ throw error;
422
436
  }
423
437
  return newCardKey;
424
438
  }
@@ -427,8 +441,8 @@ export class Template extends CardContainer {
427
441
  * Return all attachment in the template.
428
442
  * @returns all attachments in the template.
429
443
  */
430
- public async attachments(): Promise<CardAttachment[]> {
431
- return super.attachments(this.templateCardsPath);
444
+ public attachments(): CardAttachment[] {
445
+ return this.project.attachmentsByPath(this.templateCardsPath);
432
446
  }
433
447
 
434
448
  /**
@@ -436,58 +450,37 @@ export class Template extends CardContainer {
436
450
  * @param cardKey card key
437
451
  * @returns path to card's attachment folder.
438
452
  */
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
- }
453
+ public cardAttachmentFolder(cardKey: string): string {
454
+ const pathToCard = this.project.findCard(cardKey)?.path;
444
455
  return join(pathToCard, 'a');
445
456
  }
446
457
 
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
458
  /**
461
459
  * returns path to card's folder.
462
460
  * @param cardKey card key
463
461
  * @returns path to card's folder.
464
462
  */
465
- public async cardFolder(cardKey: string): Promise<string> {
466
- const found = await super.findCard(this.templateCardsPath, cardKey);
463
+ public cardFolder(cardKey: string): string {
464
+ const found = this.findCardDirect(cardKey);
467
465
  return found ? found.path : '';
468
466
  }
469
467
 
470
468
  /**
471
- * Returns all cards in the template. Cards have content and metadata.
469
+ * Returns all cards in the template.
472
470
  * @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
471
  * @returns Template cards in the template.
475
472
  */
476
- public async cards(
477
- placeHolderPath?: string,
478
- details?: FetchCardDetails,
479
- ): Promise<Card[]> {
473
+ public cards(placeHolderPath?: string): Card[] {
480
474
  if (placeHolderPath) {
481
475
  this.logger.warn('A non-used variable was used in the cards method');
482
476
  }
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);
477
+
478
+ // Filter cards from the project's card cache that belong to this template.
479
+ const allCards = [...this.project.cardsCache.getCards()];
480
+ return allCards.filter(
481
+ (card) =>
482
+ card.location !== 'project' && card.location === this.fullTemplateName,
483
+ );
491
484
  }
492
485
 
493
486
  /**
@@ -496,13 +489,7 @@ export class Template extends CardContainer {
496
489
  * @returns array of created card keys
497
490
  */
498
491
  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
- });
492
+ const cards = this.cards();
506
493
  if (cards.length === 0) {
507
494
  throw new Error(
508
495
  `No cards in template '${this.containerName}'. Please add template cards with 'add' command first.`,
@@ -514,13 +501,9 @@ export class Template extends CardContainer {
514
501
  /**
515
502
  * Returns specific card.
516
503
  * @param cardKey Card key to find from template.
517
- * @param details Card details to include in return value.
518
504
  * @returns specific card details
519
505
  */
520
- public async findSpecificCard(
521
- cardKey: string,
522
- details: FetchCardDetails = {},
523
- ): Promise<Card | undefined> {
506
+ public findCard(cardKey: string): Card {
524
507
  const cardPrefix = cardKey.split('_').at(0);
525
508
  const moduleCardFromProject =
526
509
  this.basePath.includes('local') &&
@@ -530,9 +513,10 @@ export class Template extends CardContainer {
530
513
  this.project.projectPrefix === cardPrefix;
531
514
  // If the result is impossible, return undefined.
532
515
  if (moduleCardFromProject || projectCardFromModule) {
533
- return undefined;
516
+ throw new Error(`Card '${cardKey}' is not part of template`);
534
517
  }
535
- return super.findCard(this.templateCardsPath, cardKey, details);
518
+
519
+ return this.findCardDirect(cardKey);
536
520
  }
537
521
 
538
522
  /**
@@ -540,8 +524,8 @@ export class Template extends CardContainer {
540
524
  * @param cardKey Card key to find from template.
541
525
  * @return true if card with a given card key exists in the template, false otherwise.
542
526
  */
543
- public hasCard(cardKey: string): boolean {
544
- return super.hasCard(cardKey, this.templateCardsPath);
527
+ public hasTemplateCard(cardKey: string): boolean {
528
+ return this.project.hasTemplateCard(cardKey);
545
529
  }
546
530
 
547
531
  /**
@@ -553,11 +537,25 @@ export class Template extends CardContainer {
553
537
  }
554
538
 
555
539
  /**
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.
540
+ * Returns an array of all the cards in the template.
541
+ * @returns all cards in the template.
558
542
  */
559
- public async listCards(): Promise<Card[]> {
560
- return super.cards(this.templateCardsPath);
543
+ public listCards(): Card[] {
544
+ // Construct the full template name to match what's stored in cache
545
+ const fullTemplateName = isModulePath(this.basePath)
546
+ ? `${this.basePath.split(`${sep}modules${sep}`)[1].split(`${sep}templates`)[0]}/templates/${this.templateName}`
547
+ : `${this.project.projectPrefix}/templates/${this.templateName}`;
548
+
549
+ const templateCards = Array.from(this.project.cardsCache.getCards()).filter(
550
+ (cachedCard) => {
551
+ if (cachedCard.location === 'project') {
552
+ return false;
553
+ }
554
+ const storedTemplateName = cachedCard.location;
555
+ return storedTemplateName === fullTemplateName;
556
+ },
557
+ );
558
+ return templateCards;
561
559
  }
562
560
 
563
561
  /**
@@ -568,14 +566,6 @@ export class Template extends CardContainer {
568
566
  return this.templateCardsPath;
569
567
  }
570
568
 
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
569
  /**
580
570
  * Returns path to 'templates' folder.
581
571
  * @returns path to the project's folder that contains templates.
@@ -583,12 +573,4 @@ export class Template extends CardContainer {
583
573
  public templateFolder(): string {
584
574
  return this.templatePath;
585
575
  }
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
576
  }
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 {
@@ -43,7 +43,7 @@ export interface CalculationContent {
43
43
 
44
44
  // Content interface for Graph Model resources
45
45
  export interface GraphModelContent {
46
- model?: string;
46
+ model: string;
47
47
  }
48
48
 
49
49
  // Content interface for Graph View resources
@@ -58,6 +58,12 @@ export interface ReportContent {
58
58
  schema?: Schema;
59
59
  }
60
60
 
61
+ export type FolderResourceContent =
62
+ | CalculationContent
63
+ | GraphModelContent
64
+ | GraphViewContent
65
+ | ReportContent;
66
+
61
67
  /**
62
68
  * Get filename with property name
63
69
  * @param propertyName Property name.
@@ -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
@@ -46,12 +46,6 @@ export interface CardType extends ResourceBaseMetadata {
46
46
  optionallyVisibleFields: string[];
47
47
  }
48
48
 
49
- // Base content update key interface
50
- export interface ContentUpdateKey {
51
- key: 'content';
52
- subKey: string; // Resource-specific types should narrow this
53
- }
54
-
55
49
  // Custom field
56
50
  // todo: merge with FieldType.
57
51
  export interface CustomField {
@@ -95,11 +89,6 @@ export interface GraphModel extends GraphModelMetadata {
95
89
  content: GraphModelContent;
96
90
  }
97
91
  export type GraphModelContentPropertyName = 'model';
98
- export interface GraphModelContentUpdateKey {
99
- key: 'content';
100
- subKey: GraphModelContentPropertyName;
101
- }
102
- export type GraphModelUpdateKey = string | GraphModelContentUpdateKey;
103
92
 
104
93
  // Graph view content.
105
94
  export interface GraphViewMetadata extends ResourceBaseMetadata {
@@ -109,11 +98,6 @@ export type GraphViewContentPropertyName = 'viewTemplate';
109
98
  export interface GraphView extends GraphViewMetadata {
110
99
  content: GraphViewContent;
111
100
  }
112
- export interface GraphViewContentUpdateKey {
113
- key: 'content';
114
- subKey: GraphViewContentPropertyName;
115
- }
116
- export type GraphViewUpdateKey = string | GraphViewContentUpdateKey;
117
101
 
118
102
  // Link content.
119
103
  export interface Link {
@@ -132,7 +116,7 @@ export interface LinkType extends ResourceBaseMetadata {
132
116
  }
133
117
 
134
118
  // Report resource.
135
- export interface Report extends ResourceBaseMetadata {
119
+ export interface Report extends ReportMetadata {
136
120
  content: ReportContent;
137
121
  }
138
122
 
@@ -141,11 +125,6 @@ export type ReportContentPropertyName =
141
125
  | 'contentTemplate'
142
126
  | 'queryTemplate'
143
127
  | 'schema';
144
- export interface ReportContentUpdateKey {
145
- key: 'content';
146
- subKey: ReportContentPropertyName;
147
- }
148
- export type ReportUpdateKey = string | ReportContentUpdateKey;
149
128
 
150
129
  // Metadata for report
151
130
  export interface ReportMetadata extends ResourceBaseMetadata {
@@ -182,9 +161,18 @@ export interface TemplateConfiguration extends TemplateMetadata {
182
161
  export interface TemplateMetadata extends ResourceBaseMetadata {
183
162
  category?: string;
184
163
  }
164
+ type ContentUpdateKey = { key: 'content'; subKey: string };
165
+ type PropertyUpdateKey<K extends string = string> = {
166
+ key: Exclude<K, 'content'>;
167
+ };
185
168
 
186
- // Generic update key
187
- export type UpdateKey = string | ContentUpdateKey;
169
+ export type UpdateKey<K extends string = string> =
170
+ | ContentUpdateKey
171
+ | PropertyUpdateKey<K>;
172
+
173
+ export function isContentKey(key: UpdateKey): key is ContentUpdateKey {
174
+ return key.key === 'content';
175
+ }
188
176
 
189
177
  // Workflow's json file content.
190
178
  export interface Workflow extends ResourceBaseMetadata {
@@ -12,23 +12,12 @@
12
12
 
13
13
  import { createHtmlPlaceholder, validateMacroContent } from '../index.js';
14
14
 
15
+ import type { CreateCardsOptions } from './types.js';
15
16
  import type { MacroGenerationContext } from '../../interfaces/macros.js';
16
17
  import macroMetadata from './metadata.js';
17
18
  import BaseMacro from '../base-macro.js';
18
19
  import type TaskQueue from '../task-queue.js';
19
20
 
20
- export interface CreateCardsOptions {
21
- buttonLabel: string;
22
- template: string;
23
- cardKey?: string;
24
- link?: {
25
- linkType: string;
26
- direction: string;
27
- cardKey: string;
28
- };
29
- [key: string]: string | undefined | { [key: string]: string | undefined };
30
- }
31
-
32
21
  class CreateCardsMacro extends BaseMacro {
33
22
  constructor(tasksQueue: TaskQueue) {
34
23
  super(macroMetadata, tasksQueue);
@@ -0,0 +1,46 @@
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 CreateCardsOptions {
16
+ /**
17
+ * Label of the button
18
+ */
19
+ buttonLabel: string;
20
+ /**
21
+ * Template to create cards from
22
+ */
23
+ template: string;
24
+ /**
25
+ * Allows forcing card creation under a certain card
26
+ */
27
+ cardKey?: string;
28
+
29
+ /**
30
+ * Allows creating a link at the same time
31
+ */
32
+ link?: {
33
+ /**
34
+ * Type of the link to create
35
+ */
36
+ linkType: string;
37
+ /**
38
+ * Direction of the link to create
39
+ */
40
+ direction: string;
41
+ /**
42
+ * Card key of target card of the link
43
+ */
44
+ cardKey: string;
45
+ };
46
+ }
@@ -12,6 +12,7 @@
12
12
  */
13
13
 
14
14
  import BaseMacro from '../base-macro.js';
15
+ import type { GraphOptions } from './types.js';
15
16
  import { createImage, validateMacroContent } from '../index.js';
16
17
  import Handlebars from 'handlebars';
17
18
  import type { MacroGenerationContext } from '../../interfaces/macros.js';
@@ -25,12 +26,7 @@ import { ClingoError } from '@cyberismo/node-clingo';
25
26
  import { resourceFilePath } from '../../utils/resource-utils.js';
26
27
  import { resourceName } from '../../utils/resource-utils.js';
27
28
 
28
- export interface GraphOptions {
29
- model: string;
30
- view: string;
31
- }
32
-
33
- class ReportMacro extends BaseMacro {
29
+ class GraphMacro extends BaseMacro {
34
30
  constructor(tasksQueue: TaskQueue) {
35
31
  super(macroMetadata, tasksQueue);
36
32
  }
@@ -129,4 +125,4 @@ class ReportMacro extends BaseMacro {
129
125
  }
130
126
  }
131
127
 
132
- export default ReportMacro;
128
+ export default GraphMacro;