@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
@@ -12,15 +12,12 @@
12
12
  */
13
13
 
14
14
  // node
15
- import { join, sep } from 'node:path';
15
+ import { join } from 'node:path';
16
16
 
17
17
  import { ActionGuard } from '../permissions/action-guard.js';
18
18
  import { copyDir, deleteDir } from '../utils/file-utils.js';
19
- import type {
20
- Card,
21
- FetchCardDetails,
22
- } from '../interfaces/project-interfaces.js';
23
- import { type Project, ResourcesFrom } from '../containers/project.js';
19
+ import type { Card } from '../interfaces/project-interfaces.js';
20
+ import type { Project } from '../containers/project.js';
24
21
  import {
25
22
  EMPTY_RANK,
26
23
  FIRST_RANK,
@@ -29,72 +26,47 @@ import {
29
26
  rebalanceRanks,
30
27
  sortItems,
31
28
  } from '../utils/lexorank.js';
32
- import { isTemplateCard } from '../utils/card-utils.js';
33
- import { resourceName } from '../utils/resource-utils.js';
34
- import { TemplateResource } from '../resources/template-resource.js';
29
+ import {
30
+ cardPathParts,
31
+ isModuleCard,
32
+ isTemplateCard,
33
+ } from '../utils/card-utils.js';
35
34
 
36
- // @todo - we should have project wide constants, so that if we need them, only the const value needs to be changed.
37
- const ROOT: string = 'root';
35
+ import { ROOT } from '../utils/constants.js';
38
36
 
39
37
  export class Move {
40
38
  constructor(private project: Project) {}
41
39
 
42
- // Fetches a card (either template or project card).
43
- private async getCard(cardKey: string, options: FetchCardDetails) {
44
- let card: Card | undefined;
45
- const templateCard = await this.project.isTemplateCard(cardKey);
46
- if (templateCard) {
47
- card = (await this.project.allTemplateCards(options)).find(
48
- (card) => card.key === cardKey,
49
- );
50
- } else {
51
- card = await this.project.findSpecificCard(cardKey, options);
52
- }
53
- if (!card) {
54
- throw new Error('Card was not found from the project');
55
- }
56
- return card;
57
- }
58
-
59
40
  // Returns children of a parent card or root cards
60
- private async getSiblings(card: Card) {
41
+ private getSiblings(card: Card): Card[] {
61
42
  const parentCardKey = card.parent || ROOT;
62
43
 
63
44
  // since we don't know if 'root' is templateRoot or cardRoot, we need to check the card
64
45
  if (parentCardKey === ROOT) {
65
46
  if (isTemplateCard(card)) {
66
- const template = this.project.createTemplateObjectFromCard(card);
67
- if (!template) {
68
- throw new Error(
69
- `Cannot find template for the template card '${card.key}'`,
70
- );
71
- }
72
- if (card?.path.includes(`${sep}modules${sep}`)) {
47
+ if (isModuleCard(card)) {
73
48
  throw new Error(`Cannot rank module cards`);
74
49
  }
75
- return template.cards();
50
+ const { template } = cardPathParts(
51
+ this.project.projectPrefix,
52
+ card.path,
53
+ );
54
+ return this.project.templateCards(template);
76
55
  }
77
56
  }
78
57
 
79
58
  let parentCard;
80
59
  if (parentCardKey !== ROOT) {
81
- parentCard = await this.project.findSpecificCard(parentCardKey, {
82
- children: true,
83
- metadata: true,
84
- });
85
- if (!parentCard) {
86
- throw new Error(`Card ${parentCardKey} not found from project`);
87
- }
88
- }
89
-
90
- if (parentCard) {
91
- return parentCard.children || [];
60
+ parentCard = this.project.findCard(parentCardKey);
61
+ return this.project.cardKeysToCards(parentCard.children);
92
62
  }
93
63
 
94
- return this.project.showProjectCards();
64
+ return this.project
65
+ .showProjectCards()
66
+ .filter((item) => item.parent === 'root' || item.parent === '');
95
67
  }
96
68
 
97
- //
69
+ // Rebalances cards
98
70
  private async rebalanceCards(cards: Card[]) {
99
71
  const ranks = rebalanceRanks(cards.length);
100
72
 
@@ -116,7 +88,9 @@ export class Move {
116
88
  const card = cards[i];
117
89
  await this.project.updateCardMetadataKey(card.key, 'rank', ranks[i]);
118
90
  if (card.children && card.children.length > 0) {
119
- await this.rebalanceProjectRecursively(card.children);
91
+ await this.rebalanceProjectRecursively(
92
+ this.project.cardKeysToCards(card.children),
93
+ );
120
94
  }
121
95
  }
122
96
  }
@@ -133,55 +107,55 @@ export class Move {
133
107
  if (source === destination) {
134
108
  throw new Error(`Card cannot be moved to itself`);
135
109
  }
136
- const promiseContainer = [];
137
- promiseContainer.push(this.project.findSpecificCard(source));
138
- if (destination !== ROOT) {
139
- promiseContainer.push(this.project.findSpecificCard(destination));
140
- } else {
141
- const returnObject: Card = {
142
- key: '',
143
- path: this.project.paths.cardRootFolder,
144
- children: [],
145
- attachments: [],
146
- };
147
- promiseContainer.push(Promise.resolve(returnObject));
148
- }
149
- const [sourceCard, destinationCard] = await Promise.all(promiseContainer);
150
-
151
- if (!sourceCard) {
152
- throw new Error(`Card ${source} not found from project`);
153
- }
154
- if (!destinationCard) {
155
- throw new Error(`Card ${destination} not found from project`);
156
- }
157
-
158
- if (destinationCard.path.includes(source)) {
159
- throw new Error(`Card cannot be moved to inside itself`);
110
+ const movingToRoot = destination === ROOT;
111
+ const sourceCard = this.project.findCard(source);
112
+ const destinationCard = !movingToRoot
113
+ ? this.project.findCard(destination)
114
+ : undefined;
115
+
116
+ // Prevent moving card to inside its descendants
117
+ if (destinationCard) {
118
+ const { parents } = cardPathParts(
119
+ this.project.projectPrefix,
120
+ destinationCard.path,
121
+ );
122
+ if (parents.includes(source)) {
123
+ throw new Error(`Card cannot be moved to inside itself`);
124
+ }
160
125
  }
161
126
 
162
127
  // Imported templates cannot be modified.
163
128
  if (
164
- destinationCard.path.includes(`${sep}modules`) ||
165
- sourceCard.path.includes(`${sep}modules${sep}`)
129
+ (destinationCard && isModuleCard(destinationCard)) ||
130
+ isModuleCard(sourceCard)
166
131
  ) {
167
132
  throw new Error(`Cannot modify imported module templates`);
168
133
  }
169
134
 
170
- const bothTemplateCards =
171
- isTemplateCard(sourceCard) && isTemplateCard(destinationCard);
172
- const bothProjectCards =
173
- this.project.hasCard(sourceCard.key) &&
174
- this.project.hasCard(destinationCard.key);
175
- if (!(bothTemplateCards || bothProjectCards)) {
176
- throw new Error(
177
- `Cards cannot be moved from project to template or vice versa`,
178
- );
135
+ // Special handling for moving to root
136
+ if (movingToRoot) {
137
+ if (isTemplateCard(sourceCard)) {
138
+ throw new Error(`Template cards cannot be moved to project root`);
139
+ }
140
+ } else {
141
+ const bothTemplateCards =
142
+ isTemplateCard(sourceCard) &&
143
+ destinationCard &&
144
+ isTemplateCard(destinationCard);
145
+ const bothProjectCards =
146
+ this.project.hasProjectCard(sourceCard.key) &&
147
+ destinationCard &&
148
+ this.project.hasProjectCard(destinationCard.key);
149
+ if (!(bothTemplateCards || bothProjectCards)) {
150
+ throw new Error(
151
+ `Cards cannot be moved from project to template or vice versa`,
152
+ );
153
+ }
179
154
  }
180
155
 
181
- const destinationPath =
182
- destination === ROOT
183
- ? join(this.project.paths.cardRootFolder, sourceCard.key)
184
- : join(destinationCard.path, 'c', sourceCard.key);
156
+ const destinationPath = movingToRoot
157
+ ? join(this.project.paths.cardRootFolder, sourceCard.key)
158
+ : join(destinationCard!.path, 'c', sourceCard.key);
185
159
 
186
160
  // if the card is already in the destination, do nothing
187
161
  if (sourceCard.path === destinationPath) {
@@ -192,20 +166,14 @@ export class Move {
192
166
  const actionGuard = new ActionGuard(this.project.calculationEngine);
193
167
  await actionGuard.checkPermission('move', source);
194
168
 
195
- // rerank the card in the new location
169
+ // re-rank the card in the new location
196
170
  // it will be the last one in the new location
197
171
  let children;
198
- if (destination !== ROOT) {
199
- const parent = await this.project.findSpecificCard(destination, {
200
- children: true,
201
- metadata: true,
202
- });
203
- if (!parent) {
204
- throw new Error(`Parent card ${destination} not found from project`);
205
- }
206
- children = parent.children;
172
+ if (!movingToRoot) {
173
+ const parent = this.project.findCard(destination);
174
+ children = this.project.cardKeysToCards(parent.children);
207
175
  } else {
208
- children = await this.project.showProjectCards();
176
+ children = this.project.showProjectCards();
209
177
  }
210
178
 
211
179
  if (!children) {
@@ -219,9 +187,51 @@ export class Move {
219
187
  lastChild && lastChild.metadata
220
188
  ? getRankAfter(lastChild.metadata.rank)
221
189
  : FIRST_RANK;
222
- await this.project.updateCardMetadataKey(sourceCard.key, 'rank', rank);
190
+
191
+ // First do the file operations, then update metadata
223
192
  await copyDir(sourceCard.path, destinationPath);
224
193
  await deleteDir(sourceCard.path);
194
+
195
+ // Update card with new path, parent, and rank
196
+ sourceCard.path = destinationPath!;
197
+ sourceCard.parent = movingToRoot ? ROOT : destination;
198
+ if (sourceCard.metadata) {
199
+ sourceCard.metadata.rank = rank;
200
+ sourceCard.metadata.parent = movingToRoot ? ROOT : destination;
201
+ }
202
+
203
+ // Handle cache update and persistence
204
+ await this.project.updateCard(sourceCard);
205
+ const updatedCard: Card = {
206
+ ...sourceCard,
207
+ path: destinationPath,
208
+ parent: movingToRoot ? ROOT : destination,
209
+ metadata: sourceCard.metadata
210
+ ? {
211
+ ...sourceCard.metadata,
212
+ rank: rank,
213
+ }
214
+ : undefined,
215
+ };
216
+
217
+ // Fetch old parent
218
+ const oldParent = sourceCard.parent;
219
+ let oldParentCard: Card | undefined;
220
+ if (oldParent && oldParent !== ROOT) {
221
+ oldParentCard = this.project.findCard(oldParent);
222
+ }
223
+
224
+ let newParentCard: Card | undefined;
225
+ if (!movingToRoot) {
226
+ newParentCard = this.project.findCard(destination);
227
+ }
228
+
229
+ // Finally, update the project
230
+ await this.project.handleCardMoved(
231
+ updatedCard,
232
+ newParentCard,
233
+ oldParentCard,
234
+ );
225
235
  }
226
236
 
227
237
  /**
@@ -238,17 +248,13 @@ export class Move {
238
248
  return;
239
249
  }
240
250
 
241
- const card = await this.project.findSpecificCard(cardKey, {
242
- metadata: true,
243
- parent: true,
244
- });
245
-
246
- if (!card || !card.parent) {
247
- throw new Error(`Card ${cardKey} not found from project`);
251
+ const card = this.project.findCard(cardKey);
252
+ if (!card.parent) {
253
+ throw new Error(`Parent card ${cardKey} not found from project`);
248
254
  }
249
255
 
250
256
  const children = sortItems(
251
- await this.getSiblings(card),
257
+ this.getSiblings(card),
252
258
  (item) => item.metadata?.rank || EMPTY_RANK,
253
259
  );
254
260
 
@@ -268,29 +274,15 @@ export class Move {
268
274
  * @param beforeCardKey Card key after which the card will be ranked
269
275
  */
270
276
  public async rankCard(cardKey: string, beforeCardKey: string) {
271
- const card = await this.project.findSpecificCard(cardKey, {
272
- metadata: true,
273
- parent: true,
274
- });
275
- if (!card) {
276
- throw new Error(`Card ${cardKey} not found from project`);
277
- }
278
-
279
- const beforeCard = await this.project.findSpecificCard(beforeCardKey, {
280
- metadata: true,
281
- parent: true,
282
- });
283
-
284
- if (!beforeCard) {
285
- throw new Error(`Card ${beforeCardKey} not found from project`);
286
- }
277
+ const card = this.project.findCard(cardKey);
278
+ const beforeCard = this.project.findCard(beforeCardKey);
287
279
 
288
280
  if (beforeCard.parent !== card.parent) {
289
281
  throw new Error(`Cards must be from the same parent`);
290
282
  }
291
283
 
292
284
  const children = sortItems(
293
- await this.getSiblings(beforeCard),
285
+ this.getSiblings(beforeCard),
294
286
  (item) => item.metadata?.rank || EMPTY_RANK,
295
287
  );
296
288
 
@@ -308,11 +300,8 @@ export class Move {
308
300
  );
309
301
  }
310
302
 
311
- if (
312
- children[beforeCardIndex].key === cardKey ||
313
- children[beforeCardIndex + 1]?.key === cardKey
314
- ) {
315
- throw new Error(`Card ${cardKey} is already in the correct position`);
303
+ if (children[beforeCardIndex].key === cardKey) {
304
+ throw new Error(`Card cannot be ranked after itself`);
316
305
  }
317
306
 
318
307
  if (beforeCardIndex === children.length - 1) {
@@ -338,13 +327,9 @@ export class Move {
338
327
  * @param cardKey card key
339
328
  */
340
329
  public async rankFirst(cardKey: string) {
341
- const card = await this.getCard(cardKey, {
342
- metadata: true,
343
- parent: true,
344
- });
345
-
330
+ const card = this.project.findCard(cardKey);
346
331
  const children = sortItems(
347
- await this.getSiblings(card),
332
+ this.getSiblings(card),
348
333
  (item) => item.metadata?.rank || EMPTY_RANK,
349
334
  );
350
335
 
@@ -387,14 +372,13 @@ export class Move {
387
372
  * @param parentCardKey parent card key
388
373
  */
389
374
  public async rebalanceChildren(parentCardKey: string) {
390
- const parentCard = await this.project.findSpecificCard(parentCardKey, {
391
- children: true,
392
- metadata: true,
393
- });
375
+ const parentCard = this.project.findCard(parentCardKey);
394
376
  if (!parentCard || !parentCard.children) {
395
377
  throw new Error(`Card ${parentCardKey} not found from project`);
396
378
  }
397
- await this.rebalanceCards(parentCard.children);
379
+ await this.rebalanceCards(
380
+ this.project.cardKeysToCards(parentCard.children),
381
+ );
398
382
  }
399
383
 
400
384
  /**
@@ -402,47 +386,28 @@ export class Move {
402
386
  * Can be used even if the ranks do not exist
403
387
  */
404
388
  public async rebalanceProject() {
405
- const cards = await this.project.showProjectCards();
389
+ const cards = this.project.showProjectCards();
406
390
 
407
391
  await this.rebalanceProjectRecursively(cards);
408
392
 
409
- // rebalance templates
410
- const templates = await this.project.templates(ResourcesFrom.localOnly);
411
- for (const template of templates) {
412
- const templateResource = new TemplateResource(
413
- this.project,
414
- resourceName(template.name),
415
- );
416
- const templateObject = templateResource.templateObject();
417
-
418
- if (!templateObject) {
419
- throw new Error(`Template '${template.name}' not found`);
420
- }
421
-
422
- const templateCards = await templateObject.cards('', {
423
- parent: true,
424
- metadata: true,
425
- });
426
-
427
- const cardGroups = templateCards.reduce(
428
- (result, card) => {
429
- // template card root cards have a parent(the template itself) so this shouldn't happen
430
- if (!card.parent) {
431
- return result;
432
- }
433
- // if the parent does not exist yet in the result, we create it
434
- if (!result[card.parent]) {
435
- result[card.parent] = [];
436
- }
437
- result[card.parent].push(card);
393
+ const templateCards = this.project.allTemplateCards();
394
+ const cardGroups = templateCards.reduce(
395
+ (result, card) => {
396
+ // template card root cards always have a parent(, thus this shouldn't happen
397
+ if (!card.parent) {
438
398
  return result;
439
- },
440
- {} as Record<string, Card[]>,
441
- );
399
+ }
400
+ if (!result[card.parent]) {
401
+ result[card.parent] = [];
402
+ }
403
+ result[card.parent].push(card);
404
+ return result;
405
+ },
406
+ {} as Record<string, Card[]>,
407
+ );
442
408
 
443
- for (const [, cards] of Object.entries(cardGroups)) {
444
- await this.rebalanceCards(cards);
445
- }
409
+ for (const [, cards] of Object.entries(cardGroups)) {
410
+ await this.rebalanceCards(cards);
446
411
  }
447
412
  }
448
413
  }
@@ -11,18 +11,13 @@
11
11
  License along with this program. If not, see <https://www.gnu.org/licenses/>.
12
12
  */
13
13
 
14
- // node
15
- import { join, sep } from 'node:path';
16
-
17
14
  import { ActionGuard } from '../permissions/action-guard.js';
18
- import { deleteDir, deleteFile } from '../utils/file-utils.js';
15
+ import { isModuleCard } from '../utils/card-utils.js';
19
16
  import { ModuleManager } from '../module-manager.js';
20
17
  import { Project } from '../containers/project.js';
21
18
  import type { RemovableResourceTypes } from '../interfaces/project-interfaces.js';
22
19
  import { resourceName } from '../utils/resource-utils.js';
23
20
 
24
- const MODULES_PATH = `${sep}modules${sep}`;
25
-
26
21
  /**
27
22
  * Remove command.
28
23
  */
@@ -53,45 +48,26 @@ export class Remove {
53
48
  throw new Error(`Attachment filename required`);
54
49
  }
55
50
 
56
- const attachmentFolder = await this.project.cardAttachmentFolder(cardKey);
57
-
58
- // Imported templates cannot be modified.
59
- if (attachmentFolder.includes(MODULES_PATH)) {
60
- throw new Error(`Cannot modify imported module`);
61
- }
62
-
63
- // Attachment's reside in 'a' folders.
64
- const success = await deleteFile(join(attachmentFolder, attachment));
65
- if (!success) {
66
- throw new Error('No such file');
67
- }
51
+ return this.project.removeCardAttachment(cardKey, attachment);
68
52
  }
69
53
 
70
54
  // Removes card from project or template
71
55
  private async removeCard(cardKey: string) {
72
- const cardFolder = await this.project.cardFolder(cardKey);
73
- if (!cardFolder) {
74
- throw new Error(`Card '${cardKey}' not found`);
75
- }
56
+ const card = this.project.findCard(cardKey);
76
57
 
77
58
  // Imported templates cannot be modified.
78
- if (cardFolder.includes(MODULES_PATH)) {
59
+ if (isModuleCard(card)) {
79
60
  throw new Error(`Cannot modify imported module`);
80
61
  }
81
62
 
82
63
  // Make sure card can be removed if it's a project card
83
- if (!(await this.project.isTemplateCard(cardKey))) {
64
+ if (this.project.hasProjectCard(cardKey)) {
84
65
  const actionGuard = new ActionGuard(this.project.calculationEngine);
85
66
  await actionGuard.checkPermission('delete', cardKey);
86
67
  }
87
68
 
88
69
  // If card is destination of a link, remove the link.
89
- const allCards = await this.project.cards(
90
- this.project.paths.cardRootFolder,
91
- {
92
- metadata: true,
93
- },
94
- );
70
+ const allCards = this.project.cards(this.project.paths.cardRootFolder);
95
71
  const promiseContainer: Promise<void>[] = [];
96
72
 
97
73
  for (const item of allCards) {
@@ -105,27 +81,14 @@ export class Remove {
105
81
 
106
82
  await Promise.all(promiseContainer);
107
83
 
108
- // Calculations need to be updated before card is removed.
109
- const card = await this.project.findSpecificCard(cardKey, {
110
- metadata: true,
111
- children: true,
112
- content: false,
113
- parent: false,
114
- });
115
- await deleteDir(cardFolder);
116
84
  if (card) {
117
- await this.project.handleDeleteCard(card);
85
+ await this.project.handleCardDeleted(card);
118
86
  }
119
87
  }
120
88
 
121
89
  // removes label from project
122
90
  private async removeLabel(cardKey: string, label: string) {
123
- const card = await this.project.findSpecificCard(cardKey, {
124
- metadata: true,
125
- });
126
- if (!card) {
127
- throw new Error(`Card '${cardKey}' does not exist in the project`);
128
- }
91
+ const card = this.project.findCard(cardKey);
129
92
  let labels = card.metadata?.labels ?? [];
130
93
 
131
94
  if (!label && labels.length !== 1) {
@@ -152,13 +115,7 @@ export class Remove {
152
115
  linkType?: string,
153
116
  linkDescription?: string,
154
117
  ) {
155
- const sourceCard = await this.project.findSpecificCard(sourceCardKey, {
156
- metadata: true,
157
- });
158
- if (!sourceCard) {
159
- throw new Error(`Card '${sourceCardKey}' not found`);
160
- }
161
-
118
+ const sourceCard = this.project.findCard(sourceCardKey);
162
119
  const link = sourceCard.metadata?.links.find(
163
120
  (l) =>
164
121
  l.cardKey === destinationCardKey &&
@@ -280,11 +280,6 @@ export class Rename {
280
280
  if (!to) {
281
281
  throw new Error(`Input validation error: empty 'to' is not allowed`);
282
282
  }
283
- const cardContent = {
284
- metadata: true,
285
- attachments: true,
286
- content: true,
287
- };
288
283
 
289
284
  this.from = this.project.configuration.cardKeyPrefix;
290
285
  this.to = to;
@@ -365,13 +360,13 @@ export class Rename {
365
360
  templates = await this.project.templates(ResourcesFrom.localOnly);
366
361
  for (const template of templates) {
367
362
  const templateObject = new Template(this.project, template);
368
- await this.renameCards(await templateObject.cards('', cardContent));
363
+ await this.renameCards(templateObject.cards());
369
364
  }
370
365
  console.info('Renamed template cards and updated the content');
371
366
 
372
367
  // Rename all project cards.
373
368
  await this.renameCards(
374
- await this.project.cards(this.project.paths.cardRootFolder, cardContent),
369
+ this.project.cards(this.project.paths.cardRootFolder),
375
370
  );
376
371
  console.info('Renamed project cards and updated the content');
377
372