@cyberismo/data-handler 0.0.11 → 0.0.12

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 (128) hide show
  1. package/dist/card-metadata-updater.js +1 -1
  2. package/dist/card-metadata-updater.js.map +1 -1
  3. package/dist/command-handler.d.ts +13 -8
  4. package/dist/command-handler.js +47 -7
  5. package/dist/command-handler.js.map +1 -1
  6. package/dist/command-manager.d.ts +2 -1
  7. package/dist/command-manager.js +4 -2
  8. package/dist/command-manager.js.map +1 -1
  9. package/dist/commands/calculate.d.ts +7 -0
  10. package/dist/commands/calculate.js +9 -0
  11. package/dist/commands/calculate.js.map +1 -1
  12. package/dist/commands/create.d.ts +5 -0
  13. package/dist/commands/create.js +15 -8
  14. package/dist/commands/create.js.map +1 -1
  15. package/dist/commands/fetch.d.ts +24 -0
  16. package/dist/commands/fetch.js +118 -0
  17. package/dist/commands/fetch.js.map +1 -0
  18. package/dist/commands/index.d.ts +2 -1
  19. package/dist/commands/index.js +2 -1
  20. package/dist/commands/index.js.map +1 -1
  21. package/dist/commands/remove.d.ts +1 -0
  22. package/dist/commands/remove.js +16 -12
  23. package/dist/commands/remove.js.map +1 -1
  24. package/dist/commands/rename.js +4 -6
  25. package/dist/commands/rename.js.map +1 -1
  26. package/dist/commands/show.d.ts +18 -1
  27. package/dist/commands/show.js +52 -0
  28. package/dist/commands/show.js.map +1 -1
  29. package/dist/commands/validate.js +7 -8
  30. package/dist/commands/validate.js.map +1 -1
  31. package/dist/containers/project/calculation-engine.d.ts +8 -0
  32. package/dist/containers/project/calculation-engine.js +20 -9
  33. package/dist/containers/project/calculation-engine.js.map +1 -1
  34. package/dist/containers/project.d.ts +19 -8
  35. package/dist/containers/project.js +52 -34
  36. package/dist/containers/project.js.map +1 -1
  37. package/dist/containers/template.js +1 -1
  38. package/dist/containers/template.js.map +1 -1
  39. package/dist/interfaces/project-interfaces.d.ts +13 -2
  40. package/dist/interfaces/project-interfaces.js.map +1 -1
  41. package/dist/macros/base-macro.d.ts +1 -1
  42. package/dist/macros/base-macro.js +1 -1
  43. package/dist/macros/base-macro.js.map +1 -1
  44. package/dist/macros/createCards/index.d.ts +1 -1
  45. package/dist/macros/createCards/index.js +1 -1
  46. package/dist/macros/createCards/index.js.map +1 -1
  47. package/dist/macros/graph/index.d.ts +1 -1
  48. package/dist/macros/graph/index.js +21 -29
  49. package/dist/macros/graph/index.js.map +1 -1
  50. package/dist/macros/image/index.d.ts +1 -1
  51. package/dist/macros/image/index.js +1 -7
  52. package/dist/macros/image/index.js.map +1 -1
  53. package/dist/macros/include/index.d.ts +1 -1
  54. package/dist/macros/include/index.js +1 -1
  55. package/dist/macros/include/index.js.map +1 -1
  56. package/dist/macros/index.d.ts +12 -5
  57. package/dist/macros/index.js +19 -7
  58. package/dist/macros/index.js.map +1 -1
  59. package/dist/macros/percentage/index.d.ts +1 -1
  60. package/dist/macros/percentage/index.js +1 -1
  61. package/dist/macros/percentage/index.js.map +1 -1
  62. package/dist/macros/report/index.d.ts +1 -1
  63. package/dist/macros/report/index.js +1 -1
  64. package/dist/macros/report/index.js.map +1 -1
  65. package/dist/macros/scoreCard/index.d.ts +1 -1
  66. package/dist/macros/scoreCard/index.js +1 -1
  67. package/dist/macros/scoreCard/index.js.map +1 -1
  68. package/dist/macros/vega/index.d.ts +1 -1
  69. package/dist/macros/vega/index.js +1 -1
  70. package/dist/macros/vega/index.js.map +1 -1
  71. package/dist/macros/vegalite/index.d.ts +1 -1
  72. package/dist/macros/vegalite/index.js +1 -1
  73. package/dist/macros/vegalite/index.js.map +1 -1
  74. package/dist/macros/xref/index.d.ts +1 -1
  75. package/dist/macros/xref/index.js +1 -1
  76. package/dist/macros/xref/index.js.map +1 -1
  77. package/dist/project-settings.d.ts +14 -1
  78. package/dist/project-settings.js +51 -1
  79. package/dist/project-settings.js.map +1 -1
  80. package/dist/resources/field-type-resource.d.ts +5 -0
  81. package/dist/resources/field-type-resource.js +8 -3
  82. package/dist/resources/field-type-resource.js.map +1 -1
  83. package/dist/resources/graph-view-resource.js +3 -5
  84. package/dist/resources/graph-view-resource.js.map +1 -1
  85. package/dist/resources/workflow-resource.js +6 -5
  86. package/dist/resources/workflow-resource.js.map +1 -1
  87. package/dist/utils/log-utils.js +1 -1
  88. package/dist/utils/log-utils.js.map +1 -1
  89. package/dist/utils/report.js +6 -0
  90. package/dist/utils/report.js.map +1 -1
  91. package/dist/utils/resource-utils.d.ts +8 -0
  92. package/dist/utils/resource-utils.js +11 -0
  93. package/dist/utils/resource-utils.js.map +1 -1
  94. package/package.json +7 -9
  95. package/src/card-metadata-updater.ts +1 -1
  96. package/src/command-handler.ts +70 -15
  97. package/src/command-manager.ts +4 -1
  98. package/src/commands/calculate.ts +18 -0
  99. package/src/commands/create.ts +31 -19
  100. package/src/commands/fetch.ts +152 -0
  101. package/src/commands/index.ts +2 -0
  102. package/src/commands/remove.ts +18 -12
  103. package/src/commands/rename.ts +11 -11
  104. package/src/commands/show.ts +68 -0
  105. package/src/commands/validate.ts +7 -8
  106. package/src/containers/project/calculation-engine.ts +26 -8
  107. package/src/containers/project.ts +71 -61
  108. package/src/containers/template.ts +1 -1
  109. package/src/interfaces/project-interfaces.ts +18 -0
  110. package/src/macros/base-macro.ts +5 -2
  111. package/src/macros/createCards/index.ts +1 -1
  112. package/src/macros/graph/index.ts +47 -51
  113. package/src/macros/image/index.ts +1 -7
  114. package/src/macros/include/index.ts +1 -1
  115. package/src/macros/index.ts +19 -7
  116. package/src/macros/percentage/index.ts +1 -1
  117. package/src/macros/report/index.ts +1 -1
  118. package/src/macros/scoreCard/index.ts +1 -1
  119. package/src/macros/vega/index.ts +1 -1
  120. package/src/macros/vegalite/index.ts +1 -1
  121. package/src/macros/xref/index.ts +1 -1
  122. package/src/project-settings.ts +62 -1
  123. package/src/resources/field-type-resource.ts +8 -3
  124. package/src/resources/graph-view-resource.ts +7 -5
  125. package/src/resources/workflow-resource.ts +7 -6
  126. package/src/utils/log-utils.ts +1 -1
  127. package/src/utils/report.ts +6 -0
  128. package/src/utils/resource-utils.ts +16 -0
@@ -27,7 +27,7 @@ export default class XrefMacro extends BaseMacro {
27
27
  super(macroMetadata, tasksQueue);
28
28
  }
29
29
 
30
- handleValidate = (input: unknown) => {
30
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
31
31
  this.validate(input);
32
32
  };
33
33
 
@@ -13,9 +13,11 @@
13
13
 
14
14
  import { writeJsonFile as atomicWrite } from 'write-json-file';
15
15
 
16
- import { resolve } from 'path';
16
+ import { resolve } from 'node:path';
17
+ import { URL } from 'node:url';
17
18
 
18
19
  import type {
20
+ HubSetting,
19
21
  ModuleSetting,
20
22
  ProjectSettings,
21
23
  } from './interfaces/project-interfaces.js';
@@ -31,6 +33,7 @@ export class ProjectConfiguration implements ProjectSettings {
31
33
  name: string;
32
34
  cardKeyPrefix: string;
33
35
  modules: ModuleSetting[];
36
+ hubs: HubSetting[];
34
37
  private settingPath: string;
35
38
 
36
39
  constructor(path: string) {
@@ -38,6 +41,7 @@ export class ProjectConfiguration implements ProjectSettings {
38
41
  this.settingPath = path;
39
42
  this.cardKeyPrefix = '';
40
43
  this.modules = [];
44
+ this.hubs = [];
41
45
  this.readSettings();
42
46
  }
43
47
 
@@ -70,6 +74,7 @@ export class ProjectConfiguration implements ProjectSettings {
70
74
  this.cardKeyPrefix = settings.cardKeyPrefix;
71
75
  this.name = settings.name;
72
76
  this.modules = settings.modules || [];
77
+ this.hubs = settings.hubs || [];
73
78
  } else {
74
79
  throw new Error(`Invalid configuration file '${this.settingPath}'`);
75
80
  }
@@ -81,9 +86,51 @@ export class ProjectConfiguration implements ProjectSettings {
81
86
  cardKeyPrefix: this.cardKeyPrefix,
82
87
  name: this.name,
83
88
  modules: this.modules,
89
+ hubs: this.hubs,
84
90
  };
85
91
  }
86
92
 
93
+ /**
94
+ * Adds a new hub.
95
+ * @param hubName URL of the hub to add
96
+ * @throws if hub is already in the project or URL is invalid
97
+ */
98
+ public async addHub(hubName: string) {
99
+ const trimmedHub = hubName?.trim();
100
+ if (!trimmedHub) {
101
+ throw new Error(`Cannot add empty hub to the project`);
102
+ }
103
+
104
+ const exists = this.hubs.find((item) => item.location === trimmedHub);
105
+ if (exists) {
106
+ throw new Error(
107
+ `Hub '${trimmedHub}' already exists as a hub for the project`,
108
+ );
109
+ }
110
+
111
+ try {
112
+ const hubUrl = new URL(trimmedHub);
113
+ if (!['http:', 'https:'].includes(hubUrl.protocol)) {
114
+ throw new Error(
115
+ `Invalid URL protocol '${hubUrl.protocol}'. Only HTTP and HTTPS protocols are supported for hubs.`,
116
+ );
117
+ }
118
+ if (!hubUrl.hostname) {
119
+ throw new Error('Hub URL must have a valid hostname.');
120
+ }
121
+ } catch (error) {
122
+ if (error instanceof TypeError) {
123
+ throw new Error(
124
+ `Invalid hub URL '${trimmedHub}'. Please provide a valid HTTP or HTTPS URL.`,
125
+ );
126
+ }
127
+ throw error;
128
+ }
129
+
130
+ this.hubs.push({ location: trimmedHub });
131
+ return this.save();
132
+ }
133
+
87
134
  /**
88
135
  * Adds new module to imported modules property.
89
136
  * @param module Module to add as dependency
@@ -105,6 +152,20 @@ export class ProjectConfiguration implements ProjectSettings {
105
152
  return this.save();
106
153
  }
107
154
 
155
+ /**
156
+ * Removes a hub.
157
+ * @param hubName Name of the hub to remove.
158
+ * @throws if hub is not part of the project
159
+ */
160
+ public async removeHub(hubName: string) {
161
+ const exists = this.hubs.find((item) => item.location === hubName);
162
+ if (!exists) {
163
+ throw new Error(`Hub '${hubName}' not part of the project`);
164
+ }
165
+ this.hubs = this.hubs.filter((item) => item.location !== hubName);
166
+ return this.save();
167
+ }
168
+
108
169
  /**
109
170
  * Removes module from imported modules property.
110
171
  * @param moduleName Name of the module to remove.
@@ -150,13 +150,13 @@ export class FieldTypeResource extends FileResource {
150
150
  const allCards = [...projectCards, ...templateCards];
151
151
 
152
152
  // Finally, convert values and update the cards.
153
- allCards.forEach(async (card) => {
153
+ for (const card of allCards) {
154
154
  const metadata = card.metadata!;
155
155
  const fieldName = resourceNameToString(this.resourceName);
156
156
  try {
157
157
  metadata[fieldName] = this.convertValue(metadata[fieldName]);
158
158
  // Either value was already null, or couldn't convert.
159
- if (metadata[fieldName] === null) return;
159
+ if (metadata[fieldName] === null) continue;
160
160
 
161
161
  await this.project.updateCardMetadata(card, metadata);
162
162
  } catch (error) {
@@ -164,7 +164,7 @@ export class FieldTypeResource extends FileResource {
164
164
  `In card '${card.key}': ${error instanceof Error ? error.message : String(error)}`,
165
165
  );
166
166
  }
167
- });
167
+ }
168
168
  }
169
169
 
170
170
  // Checks that enum with 'enumValue' exists.
@@ -305,6 +305,7 @@ export class FieldTypeResource extends FileResource {
305
305
  /**
306
306
  * Creates a new field type object. Base class writes the object to disk automatically.
307
307
  * @param dataType Type for the new field type.
308
+ * @throws if called with unknown data type
308
309
  */
309
310
  public async createFieldType(dataType: DataType) {
310
311
  if (!FieldTypeResource.fieldDataTypes().includes(dataType)) {
@@ -418,6 +419,10 @@ export class FieldTypeResource extends FileResource {
418
419
  * Updates field type resource.
419
420
  * @param key Key to modify
420
421
  * @param op Operation to perform on 'key'
422
+ * @throws
423
+ * - when called with unknown data type
424
+ * - when called with data type conversion that cannot be done
425
+ * - when called with unknown property to update
421
426
  */
422
427
  public async update<Type>(key: string, op: Operation<Type>) {
423
428
  const nameChange = key === 'name';
@@ -31,7 +31,9 @@ import type {
31
31
  GraphView,
32
32
  GraphViewMetadata,
33
33
  } from '../interfaces/resource-interfaces.js';
34
- import { writeFileSafe } from '../utils/file-utils.js';
34
+
35
+ import { getStaticDirectoryPath } from '@cyberismo/assets';
36
+ import { copyDir } from '../utils/file-utils.js';
35
37
 
36
38
  /**
37
39
  * Graph view resource class.
@@ -73,10 +75,10 @@ export class GraphViewResource extends FolderResource {
73
75
  }
74
76
 
75
77
  await super.create(newContent);
76
- const handleBarFile = join(this.internalFolder, 'view.lp.hbs');
77
- await writeFileSafe(handleBarFile, '', {
78
- flag: 'wx',
79
- });
78
+ await copyDir(
79
+ join(await getStaticDirectoryPath(), 'defaultGraphView'),
80
+ this.internalFolder,
81
+ );
80
82
  }
81
83
 
82
84
  /**
@@ -190,12 +190,13 @@ export class WorkflowResource extends FileResource {
190
190
  // Update card states when state is changed
191
191
  private async updateCardStates(oldState: string, newState: string) {
192
192
  const cards = await this.collectCardsUsingWorkflow();
193
- cards.forEach(async (card) => {
194
- if (card.metadata?.workflowState === oldState) {
195
- card.metadata.workflowState = newState;
196
- await this.project.updateCardMetadata(card, card.metadata);
197
- }
198
- });
193
+ const promises = cards
194
+ .filter((card) => card.metadata?.workflowState === oldState)
195
+ .map(async (card) => {
196
+ card.metadata!.workflowState = newState;
197
+ await this.project.updateCardMetadata(card, card.metadata!);
198
+ });
199
+ await Promise.all(promises);
199
200
  }
200
201
 
201
202
  // Update dependant card types.
@@ -13,7 +13,7 @@ import pino, { type ChildLoggerOptions, type Logger } from 'pino';
13
13
 
14
14
  // This could be also a more generic interface, but since we use pino and this is an internal package, let's keep it simple
15
15
  // silent logger as default
16
- let _logger: Logger = pino.default({ level: 'silent' });
16
+ let _logger: Logger = pino({ level: 'silent' });
17
17
 
18
18
  export function setLogger(logger: Logger) {
19
19
  _logger = logger;
@@ -62,8 +62,14 @@ export function formatValue(value: unknown): string {
62
62
  ) {
63
63
  return value.displayValue;
64
64
  }
65
+ if (value != null && 'value' in value && typeof value.value === 'string') {
66
+ return formatValue(value.value);
67
+ }
65
68
  return JSON.stringify(value, null, 2);
66
69
  }
70
+ if (typeof value === 'boolean') {
71
+ return value ? 'Yes' : 'No';
72
+ }
67
73
  return value?.toString() ?? '';
68
74
  }
69
75
 
@@ -112,6 +112,22 @@ export function resourceNameToPath(
112
112
  throw new Error('resourceName does not contain prefix');
113
113
  }
114
114
 
115
+ /**
116
+ * Return path to a file in a folder resource
117
+ * @param project Project
118
+ * @param resourceName Resource name
119
+ * @param fileName File name
120
+ * @returns Path to file in folder resource
121
+ */
122
+ export function resourceFilePath(
123
+ project: Project,
124
+ resourceName: ResourceName,
125
+ fileName: string,
126
+ ): string {
127
+ const resourcePath = resourceNameToPath(project, resourceName, '');
128
+ return join(resourcePath, fileName);
129
+ }
130
+
115
131
  /**
116
132
  * Resource metadata file path to resource name (e.g. <prefix>/<type>/<name>)
117
133
  * @param project Project where resource is in