@cyberismo/data-handler 0.0.15 → 0.0.17

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 (191) hide show
  1. package/dist/card-metadata-updater.js +7 -1
  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 +22 -8
  5. package/dist/command-handler.js.map +1 -1
  6. package/dist/command-manager.d.ts +24 -1
  7. package/dist/command-manager.js +31 -7
  8. package/dist/command-manager.js.map +1 -1
  9. package/dist/commands/create.d.ts +1 -1
  10. package/dist/commands/create.js +34 -36
  11. package/dist/commands/create.js.map +1 -1
  12. package/dist/commands/export.d.ts +11 -2
  13. package/dist/commands/export.js +54 -41
  14. package/dist/commands/export.js.map +1 -1
  15. package/dist/commands/fetch.d.ts +8 -0
  16. package/dist/commands/fetch.js +101 -23
  17. package/dist/commands/fetch.js.map +1 -1
  18. package/dist/commands/import.d.ts +14 -3
  19. package/dist/commands/import.js +27 -10
  20. package/dist/commands/import.js.map +1 -1
  21. package/dist/commands/move.js +0 -1
  22. package/dist/commands/move.js.map +1 -1
  23. package/dist/commands/remove.d.ts +11 -2
  24. package/dist/commands/remove.js +15 -5
  25. package/dist/commands/remove.js.map +1 -1
  26. package/dist/commands/rename.d.ts +4 -9
  27. package/dist/commands/rename.js +37 -101
  28. package/dist/commands/rename.js.map +1 -1
  29. package/dist/commands/show.d.ts +20 -12
  30. package/dist/commands/show.js +79 -57
  31. package/dist/commands/show.js.map +1 -1
  32. package/dist/commands/transition.d.ts +9 -2
  33. package/dist/commands/transition.js +25 -17
  34. package/dist/commands/transition.js.map +1 -1
  35. package/dist/commands/update.d.ts +16 -12
  36. package/dist/commands/update.js +19 -17
  37. package/dist/commands/update.js.map +1 -1
  38. package/dist/commands/validate.d.ts +17 -9
  39. package/dist/commands/validate.js +94 -35
  40. package/dist/commands/validate.js.map +1 -1
  41. package/dist/containers/card-container.d.ts +7 -5
  42. package/dist/containers/card-container.js +30 -5
  43. package/dist/containers/card-container.js.map +1 -1
  44. package/dist/containers/project/calculation-engine.d.ts +7 -4
  45. package/dist/containers/project/calculation-engine.js +61 -66
  46. package/dist/containers/project/calculation-engine.js.map +1 -1
  47. package/dist/containers/project/project-paths.d.ts +7 -4
  48. package/dist/containers/project/project-paths.js +22 -12
  49. package/dist/containers/project/project-paths.js.map +1 -1
  50. package/dist/containers/project/resource-cache.d.ts +169 -0
  51. package/dist/containers/project/resource-cache.js +509 -0
  52. package/dist/containers/project/resource-cache.js.map +1 -0
  53. package/dist/containers/project/resource-handler.d.ts +129 -0
  54. package/dist/containers/project/resource-handler.js +206 -0
  55. package/dist/containers/project/resource-handler.js.map +1 -0
  56. package/dist/containers/project.d.ts +46 -152
  57. package/dist/containers/project.js +179 -409
  58. package/dist/containers/project.js.map +1 -1
  59. package/dist/containers/template.d.ts +8 -2
  60. package/dist/containers/template.js +24 -19
  61. package/dist/containers/template.js.map +1 -1
  62. package/dist/interfaces/command-options.d.ts +3 -1
  63. package/dist/interfaces/folder-content-interfaces.d.ts +5 -3
  64. package/dist/interfaces/folder-content-interfaces.js +3 -3
  65. package/dist/interfaces/folder-content-interfaces.js.map +1 -1
  66. package/dist/interfaces/project-interfaces.d.ts +7 -9
  67. package/dist/interfaces/project-interfaces.js.map +1 -1
  68. package/dist/interfaces/resource-interfaces.d.ts +14 -1
  69. package/dist/interfaces/resource-interfaces.js.map +1 -1
  70. package/dist/macros/graph/index.js +12 -26
  71. package/dist/macros/graph/index.js.map +1 -1
  72. package/dist/macros/index.d.ts +1 -1
  73. package/dist/macros/index.js +2 -2
  74. package/dist/macros/index.js.map +1 -1
  75. package/dist/macros/report/index.js +3 -6
  76. package/dist/macros/report/index.js.map +1 -1
  77. package/dist/module-manager.d.ts +16 -3
  78. package/dist/module-manager.js +51 -19
  79. package/dist/module-manager.js.map +1 -1
  80. package/dist/project-settings.d.ts +21 -3
  81. package/dist/project-settings.js +91 -14
  82. package/dist/project-settings.js.map +1 -1
  83. package/dist/resources/calculation-resource.d.ts +4 -3
  84. package/dist/resources/calculation-resource.js +11 -5
  85. package/dist/resources/calculation-resource.js.map +1 -1
  86. package/dist/resources/card-type-resource.d.ts +6 -1
  87. package/dist/resources/card-type-resource.js +34 -23
  88. package/dist/resources/card-type-resource.js.map +1 -1
  89. package/dist/resources/create-defaults.d.ts +3 -2
  90. package/dist/resources/create-defaults.js +3 -2
  91. package/dist/resources/create-defaults.js.map +1 -1
  92. package/dist/resources/field-type-resource.d.ts +4 -1
  93. package/dist/resources/field-type-resource.js +22 -23
  94. package/dist/resources/field-type-resource.js.map +1 -1
  95. package/dist/resources/file-resource.d.ts +5 -9
  96. package/dist/resources/file-resource.js +6 -11
  97. package/dist/resources/file-resource.js.map +1 -1
  98. package/dist/resources/folder-resource.d.ts +29 -32
  99. package/dist/resources/folder-resource.js +59 -78
  100. package/dist/resources/folder-resource.js.map +1 -1
  101. package/dist/resources/graph-model-resource.d.ts +4 -1
  102. package/dist/resources/graph-model-resource.js +11 -4
  103. package/dist/resources/graph-model-resource.js.map +1 -1
  104. package/dist/resources/graph-view-resource.d.ts +5 -2
  105. package/dist/resources/graph-view-resource.js +7 -3
  106. package/dist/resources/graph-view-resource.js.map +1 -1
  107. package/dist/resources/link-type-resource.d.ts +5 -2
  108. package/dist/resources/link-type-resource.js +5 -2
  109. package/dist/resources/link-type-resource.js.map +1 -1
  110. package/dist/resources/report-resource.d.ts +6 -7
  111. package/dist/resources/report-resource.js +14 -23
  112. package/dist/resources/report-resource.js.map +1 -1
  113. package/dist/resources/resource-object.d.ts +94 -8
  114. package/dist/resources/resource-object.js +212 -109
  115. package/dist/resources/resource-object.js.map +1 -1
  116. package/dist/resources/template-resource.d.ts +7 -3
  117. package/dist/resources/template-resource.js +10 -3
  118. package/dist/resources/template-resource.js.map +1 -1
  119. package/dist/resources/workflow-resource.d.ts +5 -2
  120. package/dist/resources/workflow-resource.js +18 -22
  121. package/dist/resources/workflow-resource.js.map +1 -1
  122. package/dist/utils/card-utils.d.ts +2 -2
  123. package/dist/utils/card-utils.js +1 -1
  124. package/dist/utils/clingo-fact-builder.d.ts +25 -14
  125. package/dist/utils/clingo-fact-builder.js +27 -5
  126. package/dist/utils/clingo-fact-builder.js.map +1 -1
  127. package/dist/utils/clingo-facts.js +3 -4
  128. package/dist/utils/clingo-facts.js.map +1 -1
  129. package/dist/utils/configuration-logger.d.ts +91 -0
  130. package/dist/utils/configuration-logger.js +151 -0
  131. package/dist/utils/configuration-logger.js.map +1 -0
  132. package/dist/utils/constants.d.ts +1 -1
  133. package/dist/utils/constants.js +5 -3
  134. package/dist/utils/constants.js.map +1 -1
  135. package/dist/utils/resource-utils.d.ts +1 -0
  136. package/dist/utils/resource-utils.js +2 -1
  137. package/dist/utils/resource-utils.js.map +1 -1
  138. package/package.json +9 -9
  139. package/src/card-metadata-updater.ts +6 -2
  140. package/src/command-handler.ts +39 -12
  141. package/src/command-manager.ts +33 -21
  142. package/src/commands/create.ts +43 -78
  143. package/src/commands/export.ts +63 -52
  144. package/src/commands/fetch.ts +143 -34
  145. package/src/commands/import.ts +37 -15
  146. package/src/commands/move.ts +0 -1
  147. package/src/commands/remove.ts +20 -7
  148. package/src/commands/rename.ts +58 -149
  149. package/src/commands/show.ts +123 -80
  150. package/src/commands/transition.ts +26 -28
  151. package/src/commands/update.ts +25 -22
  152. package/src/commands/validate.ts +104 -67
  153. package/src/containers/card-container.ts +37 -5
  154. package/src/containers/project/calculation-engine.ts +61 -93
  155. package/src/containers/project/project-paths.ts +29 -13
  156. package/src/containers/project/resource-cache.ts +651 -0
  157. package/src/containers/project/resource-handler.ts +265 -0
  158. package/src/containers/project.ts +250 -527
  159. package/src/containers/template.ts +28 -23
  160. package/src/interfaces/command-options.ts +3 -1
  161. package/src/interfaces/folder-content-interfaces.ts +7 -6
  162. package/src/interfaces/project-interfaces.ts +12 -11
  163. package/src/interfaces/resource-interfaces.ts +18 -3
  164. package/src/macros/graph/index.ts +26 -47
  165. package/src/macros/index.ts +2 -2
  166. package/src/macros/report/index.ts +3 -9
  167. package/src/module-manager.ts +74 -17
  168. package/src/project-settings.ts +96 -14
  169. package/src/resources/calculation-resource.ts +18 -18
  170. package/src/resources/card-type-resource.ts +50 -50
  171. package/src/resources/create-defaults.ts +3 -2
  172. package/src/resources/field-type-resource.ts +41 -55
  173. package/src/resources/file-resource.ts +10 -36
  174. package/src/resources/folder-resource.ts +69 -120
  175. package/src/resources/graph-model-resource.ts +20 -22
  176. package/src/resources/graph-view-resource.ts +15 -17
  177. package/src/resources/link-type-resource.ts +10 -13
  178. package/src/resources/report-resource.ts +21 -43
  179. package/src/resources/resource-object.ts +263 -149
  180. package/src/resources/template-resource.ts +17 -16
  181. package/src/resources/workflow-resource.ts +25 -44
  182. package/src/utils/card-utils.ts +2 -2
  183. package/src/utils/clingo-fact-builder.ts +28 -16
  184. package/src/utils/clingo-facts.ts +3 -4
  185. package/src/utils/configuration-logger.ts +206 -0
  186. package/src/utils/constants.ts +5 -3
  187. package/src/utils/resource-utils.ts +2 -1
  188. package/dist/containers/project/resource-collector.d.ts +0 -110
  189. package/dist/containers/project/resource-collector.js +0 -344
  190. package/dist/containers/project/resource-collector.js.map +0 -1
  191. package/src/containers/project/resource-collector.ts +0 -404
@@ -14,25 +14,22 @@
14
14
  import { dirname, join } from 'node:path';
15
15
  import { mkdir } from 'node:fs/promises';
16
16
 
17
- import type {
18
- Card,
19
- Operation,
20
- Project,
21
- ResourceName,
22
- } from './folder-resource.js';
23
- import {
24
- DefaultContent,
25
- FolderResource,
26
- resourceNameToString,
27
- sortCards,
28
- } from './folder-resource.js';
17
+ import { DefaultContent } from './create-defaults.js';
18
+ import { FolderResource } from './folder-resource.js';
19
+ import { resourceNameToString } from '../utils/resource-utils.js';
20
+ import { sortCards } from '../utils/card-utils.js';
21
+ import { Template } from '../containers/template.js';
22
+ import { writeJsonFile } from '../utils/json.js';
23
+
24
+ import type { Card } from '../interfaces/project-interfaces.js';
25
+ import type { Operation } from './resource-object.js';
26
+ import type { Project } from '../containers/project.js';
27
+ import type { ResourceName } from '../utils/resource-utils.js';
29
28
  import type {
30
29
  TemplateConfiguration,
31
30
  TemplateMetadata,
32
31
  UpdateKey,
33
32
  } from '../interfaces/resource-interfaces.js';
34
- import { Template } from '../containers/template.js';
35
- import { writeJsonFile } from '../utils/json.js';
36
33
 
37
34
  /**
38
35
  * Template resource class.
@@ -51,6 +48,7 @@ export class TemplateResource extends FolderResource<TemplateMetadata, never> {
51
48
  this.cardsFolder = join(this.internalFolder, 'c');
52
49
 
53
50
  // Each template resource contains a template card container (with template cards).
51
+ // todo: Fix Template constructor not to use Resource, but just this filename with path
54
52
  this.cardContainer = new Template(this.project, {
55
53
  name: resourceNameToString(this.resourceName),
56
54
  path: dirname(this.fileName),
@@ -88,8 +86,11 @@ export class TemplateResource extends FolderResource<TemplateMetadata, never> {
88
86
 
89
87
  /**
90
88
  * Deletes file and folder that this resource is based on.
89
+ * Also removes template cards from the project's card cache.
91
90
  */
92
91
  public async delete() {
92
+ const templateName = resourceNameToString(this.resourceName);
93
+ this.project.cardsCache.deleteCardsFromTemplate(templateName);
93
94
  return super.delete();
94
95
  }
95
96
 
@@ -107,8 +108,8 @@ export class TemplateResource extends FolderResource<TemplateMetadata, never> {
107
108
  * Shows metadata of the resource.
108
109
  * @returns template metadata.
109
110
  */
110
- public async show(): Promise<TemplateConfiguration> {
111
- const templateMetadata = await super.show();
111
+ public show(): TemplateConfiguration {
112
+ const templateMetadata = super.show();
112
113
  const container = this.templateObject();
113
114
 
114
115
  return {
@@ -13,29 +13,24 @@
13
13
  */
14
14
 
15
15
  import type {
16
- CardType,
17
16
  UpdateKey,
18
17
  Workflow,
19
18
  WorkflowState,
20
19
  WorkflowTransition,
21
20
  } from '../interfaces/resource-interfaces.js';
22
- import { CardTypeResource } from './card-type-resource.js';
21
+ import { DefaultContent } from './create-defaults.js';
22
+ import { FileResource } from './file-resource.js';
23
+ import { resourceNameToString } from '../utils/resource-utils.js';
24
+ import { sortCards } from '../utils/card-utils.js';
25
+
26
+ import type { Card } from '../interfaces/project-interfaces.js';
23
27
  import type {
24
- Card,
25
28
  ChangeOperation,
26
29
  Operation,
27
- Project,
28
30
  RemoveOperation,
29
- ResourceName,
30
- } from './file-resource.js';
31
- import {
32
- DefaultContent,
33
- FileResource,
34
- resourceNameToString,
35
- sortCards,
36
- } from './folder-resource.js';
37
- import { ResourcesFrom } from '../containers/project.js';
38
- import { resourceName } from './file-resource.js';
31
+ } from './resource-object.js';
32
+ import type { Project } from '../containers/project.js';
33
+ import type { ResourceName } from '../utils/resource-utils.js';
39
34
 
40
35
  /**
41
36
  * Workflow resource class.
@@ -50,19 +45,11 @@ export class WorkflowResource extends FileResource<Workflow> {
50
45
 
51
46
  // Collect all cards that use this workflow.
52
47
  private async collectCardsUsingWorkflow(): Promise<Card[]> {
53
- const cardTypes = await this.project.cardTypes(ResourcesFrom.localOnly);
48
+ const cardTypes = this.project.resources.cardTypes();
54
49
  const promises: Promise<Card[]>[] = [];
55
50
  for (const cardType of cardTypes) {
56
- const object = new CardTypeResource(
57
- this.project,
58
- resourceName(cardType.name),
59
- );
60
- if (
61
- object.data &&
62
- object.data.workflow === resourceNameToString(this.resourceName)
63
- ) {
64
- // fetch all cards with card type
65
- promises.push(this.collectCards(cardType.name));
51
+ if (cardType.data?.workflow === resourceNameToString(this.resourceName)) {
52
+ promises.push(this.collectCards(cardType.data.name));
66
53
  }
67
54
  }
68
55
  return (await Promise.all(promises)).flat();
@@ -199,25 +186,19 @@ export class WorkflowResource extends FileResource<Workflow> {
199
186
 
200
187
  // Update dependant card types.
201
188
  private async updateCardTypes(oldName: string) {
202
- const cardTypes = await this.project.cardTypes(ResourcesFrom.localOnly);
189
+ const cardTypes = this.project.resources.cardTypes();
203
190
  const op = {
204
191
  name: 'change',
205
192
  target: oldName,
206
193
  to: this.content.name,
207
194
  } as ChangeOperation<string>;
208
195
  for (const cardType of cardTypes) {
209
- const object = new CardTypeResource(
210
- this.project,
211
- resourceName(cardType.name),
196
+ await cardType.update(
197
+ {
198
+ key: 'workflow',
199
+ },
200
+ op,
212
201
  );
213
- if (object.data && object.data.workflow === oldName) {
214
- await object.update(
215
- {
216
- key: 'workflow',
217
- },
218
- op,
219
- );
220
- }
221
202
  }
222
203
  }
223
204
 
@@ -366,13 +347,13 @@ export class WorkflowResource extends FileResource<Workflow> {
366
347
  public async usage(cards?: Card[]): Promise<string[]> {
367
348
  const resourceName = resourceNameToString(this.resourceName);
368
349
  const allCards = cards ?? super.cards();
369
- const cardTypes = await this.project.cardTypes(ResourcesFrom.all);
370
- const cardTypeReferences = await Promise.all(
371
- cardTypes.map(async (cardType) => {
372
- const metadata = await this.project.resource<CardType>(cardType.name);
373
- return metadata?.workflow === resourceName ? cardType.name : null;
374
- }),
375
- );
350
+ const cardTypes = this.project.resources.cardTypes();
351
+ const cardTypeReferences = [];
352
+ for (const cardType of cardTypes) {
353
+ if (cardType.data?.workflow === resourceName) {
354
+ cardTypeReferences.push(cardType.data.name);
355
+ }
356
+ }
376
357
 
377
358
  const [relevantCards, calculations] = await Promise.all([
378
359
  super.usage(allCards),
@@ -18,7 +18,7 @@ import type {
18
18
  Card,
19
19
  CardWithChildrenCards,
20
20
  } from '../interfaces/project-interfaces.js';
21
- import type { Project } from '../resources/folder-resource.js';
21
+ import type { Project } from '../containers/project.js';
22
22
 
23
23
  /**
24
24
  * Builds card hierarchy from flat card list with nested card objects.
@@ -165,7 +165,7 @@ export const findParentPath = (cardPath: string): string | null => {
165
165
  /**
166
166
  * Flattens card tree so that children are shown on same level regardless of nesting level.
167
167
  * @param array Card tree to flatten
168
- * @parent project Project to use
168
+ * @param project Project to use
169
169
  * @returns Flattened card tree.
170
170
  */
171
171
  export const flattenCardArray = (array: Card[], project: Project) => {
@@ -1,17 +1,19 @@
1
- import { INT32_MAX } from './constants.js';
2
- import { getChildLogger } from './log-utils.js';
3
-
4
1
  /**
5
- Cyberismo
6
- Copyright © Cyberismo Ltd and contributors 2024
7
-
8
- This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2024
4
+ This program is free software: you can redistribute it and/or modify it under
5
+ the terms of the GNU Affero General Public License version 3 as published by
6
+ the Free Software Foundation.
7
+ This program is distributed in the hope that it will be useful, but WITHOUT
8
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
10
+ details. You should have received a copy of the GNU Affero General Public
11
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
12
+ */
9
13
 
10
- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
14
+ import { INT32_MAX } from './constants.js';
15
+ import { getChildLogger } from './log-utils.js';
11
16
 
12
- You should have received a copy of the GNU Affero General Public
13
- License along with this program. If not, see <https://www.gnu.org/licenses/>.
14
- */
15
17
  export type AllowedClingoType = string | number | boolean;
16
18
 
17
19
  export type NestedBuilder = (builder: ClingoFactBuilder) => ClingoFactBuilder;
@@ -26,6 +28,8 @@ export type ClingoArgument = ClingoArgumentInternal | NestedBuilder;
26
28
  /**
27
29
  * This function takes care of encoding chars, which might produce issues in clingo
28
30
  * This should be done for user provided values
31
+ * @param value Clingo value to encode.
32
+ * @returns Encoded clingo value.
29
33
  */
30
34
  export function encodeClingoValue(value: string) {
31
35
  return value.replace(/[\n\\"]/g, (char) => {
@@ -36,6 +40,9 @@ export function encodeClingoValue(value: string) {
36
40
  });
37
41
  }
38
42
 
43
+ /**
44
+ * Clingo fact builder.
45
+ */
39
46
  export class ClingoFactBuilder {
40
47
  protected predicate: string;
41
48
  private end: string;
@@ -46,6 +53,11 @@ export class ClingoFactBuilder {
46
53
  });
47
54
  }
48
55
 
56
+ /**
57
+ * Constructs an instance of ClingoFactBuilder.
58
+ * @param predicate Predicate
59
+ * @param end End character; by default a dot ('.')
60
+ */
49
61
  constructor(predicate: string, end: string = '.') {
50
62
  this.predicate = predicate;
51
63
  this.end = end;
@@ -71,8 +83,8 @@ export class ClingoFactBuilder {
71
83
 
72
84
  /**
73
85
  * Helper for adding multiple arguments, because it's common
74
- * @param args
75
- * @returns this for chaining
86
+ * @param args Arguments array
87
+ * @returns 'this' for chaining
76
88
  */
77
89
  addArguments(...args: (ClingoArgument | null)[]): ClingoFactBuilder {
78
90
  args.forEach((arg) => this.addArgument(arg));
@@ -82,7 +94,7 @@ export class ClingoFactBuilder {
82
94
  /**
83
95
  * Adds a literal argument, which means that it will not have quotes
84
96
  * @param literal The literal argument to add
85
- * @returns this for chaining
97
+ * @returns 'this' for chaining
86
98
  */
87
99
  addLiteralArgument(literal: string): ClingoFactBuilder {
88
100
  this.arguments.push(new LiteralBuilder(literal));
@@ -91,8 +103,8 @@ export class ClingoFactBuilder {
91
103
 
92
104
  /**
93
105
  * Helper for adding multiple literal arguments, because it's common
94
- * @param literal
95
- * @returns this for chaining
106
+ * @param literals Array of literals
107
+ * @returns 'this' for chaining
96
108
  */
97
109
  addLiteralArguments(...literals: string[]): ClingoFactBuilder {
98
110
  literals.forEach((literal) => this.addLiteralArgument(literal));
@@ -243,10 +243,9 @@ export const createCardFacts = async (card: Card, project: Project) => {
243
243
 
244
244
  if (!isPredefinedField(field)) {
245
245
  // field is a custom field, find it
246
- const fieldType = await project.resource<FieldType>(field);
247
- if (!fieldType) {
248
- continue;
249
- }
246
+ const fieldType = project.resources
247
+ .byType(field, 'fieldTypes')
248
+ .show();
250
249
 
251
250
  // if it's a list, let's generate multiple values
252
251
  if (fieldType.dataType === 'list') {
@@ -0,0 +1,206 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2025
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU Affero General Public License version 3 as published by
7
+ the Free Software Foundation. This program is distributed in the hope that it
8
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
+ See the GNU Affero General Public License for more details.
11
+ You should have received a copy of the GNU Affero General Public
12
+ License along with this program. If not, see <https://www.gnu.org/licenses/>.
13
+ */
14
+
15
+ import { readFile, rename } from 'node:fs/promises';
16
+ import { join } from 'node:path';
17
+
18
+ import { getChildLogger } from './log-utils.js';
19
+ import { ProjectPaths } from '../containers/project/project-paths.js';
20
+ import { writeFileSafe, pathExists } from './file-utils.js';
21
+
22
+ /**
23
+ * Enum for configuration change operation types.
24
+ */
25
+ export enum ConfigurationOperation {
26
+ MODULE_ADD = 'module_add',
27
+ MODULE_REMOVE = 'module_remove',
28
+ PROJECT_RENAME = 'project_rename',
29
+ RESOURCE_CREATE = 'resource_create',
30
+ RESOURCE_DELETE = 'resource_delete',
31
+ RESOURCE_RENAME = 'resource_rename',
32
+ RESOURCE_UPDATE = 'resource_update',
33
+ }
34
+
35
+ /**
36
+ * Individual log entry representing a single configuration change.
37
+ * @param timestamp Timestamp when the operation occurred (ISO string)
38
+ * @param operation Type of operation performed
39
+ * @param target Target of the operation
40
+ * @param parameters Additional parameters specific to the operation
41
+ */
42
+ export interface ConfigurationLogEntry {
43
+ timestamp: string;
44
+ operation: ConfigurationOperation;
45
+ target: string;
46
+ parameters?: Record<string, unknown>;
47
+ }
48
+
49
+ /**
50
+ * Options for logging configuration changes.
51
+ * @param parameters Additional parameters to store with the operation
52
+ */
53
+ export interface ConfigurationLogOptions {
54
+ parameters?: Record<string, unknown>;
55
+ }
56
+
57
+ /**
58
+ * Logger for tracking configuration changes that affect project structure.
59
+ */
60
+ export class ConfigurationLogger {
61
+ /**
62
+ * Path to the configuration log file.
63
+ * @param projectPath Path to the project root
64
+ * @returns Path to the log file
65
+ */
66
+ public static logFile(projectPath: string): string {
67
+ const paths = new ProjectPaths(projectPath);
68
+ return paths.configurationChangesLog;
69
+ }
70
+
71
+ /**
72
+ * Clears all log entries.
73
+ * @param projectPath Path to the project root
74
+ * @note Use with caution.
75
+ */
76
+ public static async clearLog(projectPath: string): Promise<void> {
77
+ const logFile = ConfigurationLogger.logFile(projectPath);
78
+ await writeFileSafe(logFile, '', 'utf-8');
79
+ const logger = getChildLogger({ module: 'ConfigurationLogger' });
80
+ logger.info('Configuration log cleared');
81
+ }
82
+
83
+ /**
84
+ * Create a versioned snapshot of the current migration log.
85
+ * Renames current migrationLog.jsonl to migrationLog_<version>.jsonl
86
+ * @param projectPath Path to the project root
87
+ * @param version Version identifier (e.g., "1.0.0", "v2")
88
+ * @returns Path to the versioned log file
89
+ */
90
+ public static async createVersion(
91
+ projectPath: string,
92
+ version: string,
93
+ ): Promise<string> {
94
+ const paths = new ProjectPaths(projectPath);
95
+ const currentLogPath = paths.configurationChangesLog;
96
+ const versionedLogPath = join(
97
+ paths.migrationLogFolder,
98
+ `migrationLog_${version}.jsonl`,
99
+ );
100
+
101
+ // Only create version if current log exists and has content
102
+ if (!pathExists(currentLogPath)) {
103
+ throw new Error('No current migration log exists to version');
104
+ }
105
+
106
+ const content = await readFile(currentLogPath, 'utf-8');
107
+ if (!content.trim()) {
108
+ throw new Error('Current migration log is empty');
109
+ }
110
+
111
+ // Rename current to versioned
112
+ await rename(currentLogPath, versionedLogPath);
113
+
114
+ const logger = getChildLogger({ module: 'ConfigurationLogger' });
115
+ logger.info(
116
+ `Created migration to version: ${version} at ${versionedLogPath}`,
117
+ );
118
+
119
+ return versionedLogPath;
120
+ }
121
+
122
+ /**
123
+ * Reads all configuration log entries using JSON Lines format.
124
+ * @param projectPath Path to the project root
125
+ * @returns Array of log entries
126
+ */
127
+ public static async entries(
128
+ projectPath: string,
129
+ ): Promise<ConfigurationLogEntry[]> {
130
+ const logFile = ConfigurationLogger.logFile(projectPath);
131
+ const logger = getChildLogger({ module: 'ConfigurationLogger' });
132
+
133
+ try {
134
+ const content = await readFile(logFile, 'utf-8');
135
+ const lines = content
136
+ .trim()
137
+ .split('\n')
138
+ .filter((line) => line.trim());
139
+
140
+ const entries: ConfigurationLogEntry[] = [];
141
+ for (const line of lines) {
142
+ try {
143
+ const entry = JSON.parse(line) as ConfigurationLogEntry;
144
+ if (entry.timestamp && entry.operation && entry.target) {
145
+ entries.push(entry);
146
+ }
147
+ } catch {
148
+ logger.error(`Invalid configuration line: ${line}`);
149
+ }
150
+ }
151
+
152
+ return entries;
153
+ } catch (error) {
154
+ logger.error({ error }, `Failed to read configuration log`);
155
+ return [];
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Check if a configuration log exists for the given project path.
161
+ * @param projectPath Path to the project root
162
+ * @returns True if log file exists
163
+ */
164
+ public static hasLog(projectPath: string): boolean {
165
+ const logPath = new ProjectPaths(projectPath).configurationChangesLog;
166
+ return pathExists(logPath);
167
+ }
168
+
169
+ /**
170
+ * Log a configuration change operation.
171
+ * @note This is designed to be called AFTER the operation succeeds.
172
+ * @param projectPath Path to the project root
173
+ * @param operation The type of operation
174
+ * @param target The target of the operation
175
+ * @param options Additional options for the log entry
176
+ */
177
+ public static async log(
178
+ projectPath: string,
179
+ operation: ConfigurationOperation,
180
+ target: string,
181
+ options?: ConfigurationLogOptions,
182
+ ): Promise<void> {
183
+ const logFile = ConfigurationLogger.logFile(projectPath);
184
+ const logger = getChildLogger({ module: 'ConfigurationLogger' });
185
+
186
+ try {
187
+ const entry: ConfigurationLogEntry = {
188
+ timestamp: new Date().toISOString(),
189
+ operation,
190
+ target,
191
+ parameters: options?.parameters,
192
+ };
193
+
194
+ await writeFileSafe(logFile, JSON.stringify(entry) + '\n', {
195
+ flag: 'a',
196
+ });
197
+
198
+ logger.debug(`Logged ${operation} operation for target: ${target}`);
199
+ } catch (error) {
200
+ logger.error(
201
+ { error, operation, target },
202
+ `Configuration logging failed`,
203
+ );
204
+ }
205
+ }
206
+ }
@@ -42,13 +42,15 @@ export const VALID_FOLDER_RESOURCE_FILES = [
42
42
  * These are field names that are non-custom fields that present in metadata
43
43
  */
44
44
  export const PREDEFINED_FIELDS = [
45
- 'rank',
46
45
  'cardType',
47
- 'title',
48
- 'workflowState',
46
+ 'labels',
49
47
  'lastUpdated',
50
48
  'lastTransitioned',
49
+ 'links',
50
+ 'rank',
51
51
  'templateCardKey',
52
+ 'title',
53
+ 'workflowState',
52
54
  ] satisfies (keyof PredefinedCardMetadata)[];
53
55
 
54
56
  /**
@@ -88,6 +88,7 @@ export function resourceName(
88
88
  * Converts resource name to path.
89
89
  * @param project Project
90
90
  * @param resourceName Name of the resource (e.g. <prefix>/<type>/<name>)
91
+ * @param extension Extension of resource. By default '.json'.
91
92
  * @returns path to resource metadata file
92
93
  */
93
94
  export function resourceNameToPath(
@@ -204,7 +205,7 @@ export function resourceNameToString(resourceName: ResourceName): string {
204
205
  ) {
205
206
  throw new Error(`Not a valid resource name. Prefix is missing.`);
206
207
  }
207
- return resourceName.prefix && resourceName.type && resourceName.prefix
208
+ return resourceName.prefix && resourceName.type && resourceName.identifier
208
209
  ? `${resourceName.prefix}/${resourceName.type}/${resourceName.identifier}`
209
210
  : `${resourceName.identifier}`;
210
211
  }
@@ -1,110 +0,0 @@
1
- /**
2
- Cyberismo
3
- Copyright © Cyberismo Ltd and contributors 2024
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
- import type { Project } from '../project.js';
15
- import type { Resource, ResourceFolderType } from '../../interfaces/project-interfaces.js';
16
- /**
17
- * Defines where resources are collected from.
18
- * all - everywhere
19
- * importOnly - only from imported modules
20
- * localOnly - only from the project itself; excluding imported modules
21
- */
22
- export declare enum ResourcesFrom {
23
- all = "all",
24
- importedOnly = "imported",
25
- localOnly = "local"
26
- }
27
- declare class ResourceCollection {
28
- calculations: Resource[];
29
- cardTypes: Resource[];
30
- fieldTypes: Resource[];
31
- graphModels: Resource[];
32
- graphViews: Resource[];
33
- linkTypes: Resource[];
34
- reports: Resource[];
35
- templates: Resource[];
36
- workflows: Resource[];
37
- /**
38
- * Returns resource array of a give type.
39
- * @param type Resource array type to return.
40
- * @param moduleName Name of a module. If given, returns just resources from that module.
41
- * @returns resource array of a give type.
42
- */
43
- resourceArray(type: ResourceFolderType, moduleName?: string): Resource[];
44
- }
45
- /**
46
- * This class handles local and modules resources.
47
- */
48
- export declare class ResourceCollector {
49
- private project;
50
- private local;
51
- private modules;
52
- private modulesCollected;
53
- private paths;
54
- constructor(project: Project);
55
- private addResources;
56
- private addModuleResources;
57
- private addResourcesFromModules;
58
- private joinResources;
59
- private localResources;
60
- private resourcesSync;
61
- /**
62
- * Collects all local resources.
63
- */
64
- collectLocalResources(): void;
65
- /**
66
- * Collect specific resource from modules.
67
- * @param type Type of resource (e.g. 'templates').
68
- * @param moduleName Name of the module to collect resources from
69
- * @returns array of collected items.
70
- */
71
- collectResourcesFromModules(type: ResourceFolderType, moduleName?: string): Promise<string[]>;
72
- /**
73
- * Add a given 'resource' to the local resource arrays.
74
- * @param resource Resource to add.
75
- */
76
- add(resource: Resource): void;
77
- /**
78
- * Re-collects local resources.
79
- */
80
- changed(): void;
81
- /**
82
- * Re-collects imported module resources.
83
- */
84
- moduleImported(): void;
85
- /**
86
- * Getter. Provide access for owner to browse module resources.
87
- */
88
- get moduleResources(): ResourceCollection;
89
- /**
90
- * Removes a resource from Project.
91
- * @param resource Resource to remove.
92
- * @returns the modified array.
93
- */
94
- remove(resource: Resource): Resource[];
95
- /**
96
- * Checks if resource of 'type' with 'name' exists.
97
- * @param type Type of resource (e.g. 'templates').
98
- * @param name Name of the resource.
99
- * @returns true, if resource exits, false otherwise.
100
- */
101
- resourceExists(type: ResourceFolderType, name: string): Promise<boolean>;
102
- /**
103
- * Returns resources of 'type'. Returned resources are either local, or from modules or all of them.
104
- * @param type Type of resource (e.g. 'templates').
105
- * @param from Defines where resources are collected from.
106
- * @returns Array of resources.
107
- */
108
- resources(type: ResourceFolderType, from?: ResourcesFrom): Promise<Resource[]>;
109
- }
110
- export {};