@cyberismo/data-handler 0.0.6 → 0.0.7

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 (157) hide show
  1. package/README.md +1 -0
  2. package/dist/card-metadata-updater.d.ts +1 -0
  3. package/dist/card-metadata-updater.js +7 -2
  4. package/dist/card-metadata-updater.js.map +1 -1
  5. package/dist/command-handler.d.ts +6 -1
  6. package/dist/command-handler.js +16 -15
  7. package/dist/command-handler.js.map +1 -1
  8. package/dist/command-manager.d.ts +15 -4
  9. package/dist/command-manager.js +41 -9
  10. package/dist/command-manager.js.map +1 -1
  11. package/dist/commands/calculate.d.ts +4 -10
  12. package/dist/commands/calculate.js +67 -78
  13. package/dist/commands/calculate.js.map +1 -1
  14. package/dist/commands/export.js +3 -3
  15. package/dist/commands/export.js.map +1 -1
  16. package/dist/commands/import.d.ts +3 -8
  17. package/dist/commands/import.js +10 -14
  18. package/dist/commands/import.js.map +1 -1
  19. package/dist/commands/index.d.ts +1 -2
  20. package/dist/commands/index.js +1 -2
  21. package/dist/commands/index.js.map +1 -1
  22. package/dist/commands/remove.js +1 -1
  23. package/dist/commands/remove.js.map +1 -1
  24. package/dist/commands/show.d.ts +6 -3
  25. package/dist/commands/show.js +8 -5
  26. package/dist/commands/show.js.map +1 -1
  27. package/dist/commands/validate.js +6 -4
  28. package/dist/commands/validate.js.map +1 -1
  29. package/dist/containers/project/project-content-watcher.d.ts +28 -0
  30. package/dist/containers/project/project-content-watcher.js +54 -0
  31. package/dist/containers/project/project-content-watcher.js.map +1 -0
  32. package/dist/containers/project/project-paths.js +1 -1
  33. package/dist/containers/project/project-paths.js.map +1 -1
  34. package/dist/containers/project.d.ts +9 -2
  35. package/dist/containers/project.js +49 -1
  36. package/dist/containers/project.js.map +1 -1
  37. package/dist/containers/template.d.ts +1 -0
  38. package/dist/containers/template.js +7 -2
  39. package/dist/containers/template.js.map +1 -1
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/interfaces/macros.d.ts +2 -1
  43. package/dist/interfaces/project-interfaces.d.ts +5 -0
  44. package/dist/interfaces/project-interfaces.js.map +1 -1
  45. package/dist/interfaces/resource-interfaces.d.ts +14 -22
  46. package/dist/interfaces/resource-interfaces.js +10 -9
  47. package/dist/interfaces/resource-interfaces.js.map +1 -1
  48. package/dist/macros/graph/index.d.ts +1 -1
  49. package/dist/macros/graph/index.js +12 -12
  50. package/dist/macros/graph/index.js.map +1 -1
  51. package/dist/macros/index.d.ts +24 -3
  52. package/dist/macros/index.js +11 -4
  53. package/dist/macros/index.js.map +1 -1
  54. package/dist/macros/report/index.d.ts +13 -10
  55. package/dist/macros/report/index.js +26 -38
  56. package/dist/macros/report/index.js.map +1 -1
  57. package/dist/module-manager.d.ts +16 -7
  58. package/dist/module-manager.js +142 -112
  59. package/dist/module-manager.js.map +1 -1
  60. package/dist/project-settings.js +6 -0
  61. package/dist/project-settings.js.map +1 -1
  62. package/dist/resources/array-handler.js +6 -1
  63. package/dist/resources/array-handler.js.map +1 -1
  64. package/dist/resources/card-type-resource.d.ts +13 -9
  65. package/dist/resources/card-type-resource.js +47 -23
  66. package/dist/resources/card-type-resource.js.map +1 -1
  67. package/dist/resources/create-defaults.d.ts +10 -9
  68. package/dist/resources/create-defaults.js +15 -12
  69. package/dist/resources/create-defaults.js.map +1 -1
  70. package/dist/resources/field-type-resource.d.ts +0 -1
  71. package/dist/resources/field-type-resource.js +2 -10
  72. package/dist/resources/field-type-resource.js.map +1 -1
  73. package/dist/resources/file-resource.d.ts +7 -7
  74. package/dist/resources/file-resource.js +32 -7
  75. package/dist/resources/file-resource.js.map +1 -1
  76. package/dist/resources/folder-resource.d.ts +10 -9
  77. package/dist/resources/folder-resource.js +10 -9
  78. package/dist/resources/folder-resource.js.map +1 -1
  79. package/dist/resources/report-resource.d.ts +5 -6
  80. package/dist/resources/report-resource.js +16 -7
  81. package/dist/resources/report-resource.js.map +1 -1
  82. package/dist/resources/template-resource.d.ts +5 -6
  83. package/dist/resources/template-resource.js +7 -6
  84. package/dist/resources/template-resource.js.map +1 -1
  85. package/dist/resources/workflow-resource.d.ts +15 -8
  86. package/dist/resources/workflow-resource.js +124 -8
  87. package/dist/resources/workflow-resource.js.map +1 -1
  88. package/dist/types/queries.d.ts +11 -10
  89. package/dist/types/queries.js +10 -9
  90. package/dist/types/queries.js.map +1 -1
  91. package/dist/utils/clingo-fact-builder.d.ts +1 -0
  92. package/dist/utils/clingo-fact-builder.js +8 -3
  93. package/dist/utils/clingo-fact-builder.js.map +1 -1
  94. package/dist/utils/clingo-facts.js +15 -11
  95. package/dist/utils/clingo-facts.js.map +1 -1
  96. package/dist/utils/constants.d.ts +18 -12
  97. package/dist/utils/constants.js +18 -11
  98. package/dist/utils/constants.js.map +1 -1
  99. package/dist/utils/log-utils.d.ts +15 -2
  100. package/dist/utils/log-utils.js +20 -37
  101. package/dist/utils/log-utils.js.map +1 -1
  102. package/dist/utils/report.d.ts +27 -0
  103. package/dist/utils/report.js +60 -0
  104. package/dist/utils/report.js.map +1 -0
  105. package/dist/utils/resource-utils.js +3 -0
  106. package/dist/utils/resource-utils.js.map +1 -1
  107. package/dist/utils/sanitize-svg.d.ts +3 -4
  108. package/dist/utils/sanitize-svg.js +4 -7
  109. package/dist/utils/sanitize-svg.js.map +1 -1
  110. package/dist/utils/validate.js +2 -1
  111. package/dist/utils/validate.js.map +1 -1
  112. package/package.json +8 -9
  113. package/src/card-metadata-updater.ts +7 -2
  114. package/src/command-handler.ts +23 -13
  115. package/src/command-manager.ts +54 -13
  116. package/src/commands/calculate.ts +90 -106
  117. package/src/commands/export.ts +3 -2
  118. package/src/commands/import.ts +16 -16
  119. package/src/commands/index.ts +0 -2
  120. package/src/commands/remove.ts +1 -1
  121. package/src/commands/show.ts +13 -5
  122. package/src/commands/validate.ts +14 -9
  123. package/src/containers/project/project-content-watcher.ts +65 -0
  124. package/src/containers/project/project-paths.ts +1 -1
  125. package/src/containers/project.ts +60 -1
  126. package/src/containers/template.ts +7 -2
  127. package/src/index.ts +2 -0
  128. package/src/interfaces/macros.ts +2 -1
  129. package/src/interfaces/project-interfaces.ts +8 -0
  130. package/src/interfaces/resource-interfaces.ts +15 -22
  131. package/src/macros/graph/index.ts +17 -12
  132. package/src/macros/index.ts +32 -6
  133. package/src/macros/report/index.ts +32 -42
  134. package/src/module-manager.ts +183 -139
  135. package/src/project-settings.ts +7 -0
  136. package/src/resources/array-handler.ts +7 -2
  137. package/src/resources/card-type-resource.ts +61 -46
  138. package/src/resources/create-defaults.ts +15 -12
  139. package/src/resources/field-type-resource.ts +2 -17
  140. package/src/resources/file-resource.ts +46 -8
  141. package/src/resources/folder-resource.ts +11 -10
  142. package/src/resources/report-resource.ts +19 -7
  143. package/src/resources/template-resource.ts +7 -6
  144. package/src/resources/workflow-resource.ts +155 -8
  145. package/src/types/queries.ts +11 -10
  146. package/src/utils/clingo-fact-builder.ts +8 -3
  147. package/src/utils/clingo-facts.ts +18 -12
  148. package/src/utils/constants.ts +20 -12
  149. package/src/utils/log-utils.ts +24 -45
  150. package/src/utils/report.ts +86 -0
  151. package/src/utils/resource-utils.ts +4 -0
  152. package/src/utils/sanitize-svg.ts +4 -9
  153. package/src/utils/validate.ts +3 -2
  154. package/dist/commands/export-site.d.ts +0 -45
  155. package/dist/commands/export-site.js +0 -301
  156. package/dist/commands/export-site.js.map +0 -1
  157. package/src/commands/export-site.ts +0 -356
@@ -29,6 +29,7 @@ import type {
29
29
  ProjectFetchCardDetails,
30
30
  ProjectMetadata,
31
31
  Resource,
32
+ CardLocation,
32
33
  } from '../interfaces/project-interfaces.js';
33
34
  import type {
34
35
  CardType,
@@ -43,6 +44,7 @@ import { UserPreferences } from '../utils/user-preferences.js';
43
44
 
44
45
  import ReportMacro from '../macros/report/index.js';
45
46
  import TaskQueue from '../macros/task-queue.js';
47
+ import type { Calculate } from './calculate.js';
46
48
 
47
49
  /**
48
50
  * Show command.
@@ -52,7 +54,10 @@ export class Show {
52
54
  string,
53
55
  (from?: ResourcesFrom) => Promise<Resource[]>
54
56
  >;
55
- constructor(private project: Project) {
57
+ constructor(
58
+ private project: Project,
59
+ private calculate: Calculate,
60
+ ) {
56
61
  this.resourceFunction = new Map([
57
62
  ['cardTypes', this.project.cardTypes.bind(this.project)],
58
63
  ['fieldTypes', this.project.fieldTypes.bind(this.project)],
@@ -250,10 +255,13 @@ export class Show {
250
255
 
251
256
  /**
252
257
  * Shows all cards (either template or project cards) from a project.
258
+ * @param cardsFrom - The location from which to look for cards. Either from the project, templates or both.
253
259
  * @returns cards list array
254
260
  */
255
- public async showCards(): Promise<CardListContainer[]> {
256
- return this.project.listCards();
261
+ public async showCards(
262
+ cardsFrom?: CardLocation,
263
+ ): Promise<CardListContainer[]> {
264
+ return this.project.listCards(cardsFrom);
257
265
  }
258
266
 
259
267
  /**
@@ -351,10 +359,10 @@ export class Show {
351
359
  throw new Error(`Report '${reportName}' does not exist`);
352
360
  }
353
361
 
354
- const reportMacro = new ReportMacro(new TaskQueue());
362
+ const reportMacro = new ReportMacro(new TaskQueue(), this.calculate);
355
363
  const result = await reportMacro.handleInject(
356
364
  {
357
- projectPath: this.project.basePath,
365
+ project: this.project,
358
366
  cardKey: cardKey,
359
367
  mode: 'static',
360
368
  },
@@ -20,7 +20,7 @@ import { readdir } from 'node:fs/promises';
20
20
  // dependencies
21
21
  import { Validator as JSONValidator, type Schema } from 'jsonschema';
22
22
  import { Validator as DirectoryValidator } from 'directory-schema-validator';
23
- import { parentSchema, schemas } from '@cyberismo/resources';
23
+ import { parentSchema, schemas } from '@cyberismo/assets';
24
24
 
25
25
  // data-handler
26
26
  import type {
@@ -52,7 +52,7 @@ const SHORT_TEXT_MAX_LENGTH = 80;
52
52
 
53
53
  import * as EmailValidator from 'email-validator';
54
54
  import { evaluateMacros } from '../macros/index.js';
55
-
55
+ import { Calculate } from './calculate.js';
56
56
  const baseDir = dirname(fileURLToPath(import.meta.url));
57
57
  const subFoldersToValidate = ['.cards', 'cardRoot'];
58
58
 
@@ -111,7 +111,7 @@ export class Validate {
111
111
  // Loads child schemas to validator.
112
112
  private addChildSchemas() {
113
113
  schemas.forEach((schema) => {
114
- this.validator.addSchema(schema, schema.$id);
114
+ this.validator.addSchema(schema as Schema, schema.$id);
115
115
  });
116
116
  }
117
117
 
@@ -355,7 +355,7 @@ export class Validate {
355
355
  }
356
356
  const result = this.validator.validate(content, schema);
357
357
  for (const error of result.errors) {
358
- const msg = `Validation error from '${fullPath}': ${error.message}.`;
358
+ const msg = `Validation error from '${fullPath}': ${error.property} ${error.message}.`;
359
359
  messages.push(msg);
360
360
  }
361
361
  }
@@ -547,6 +547,7 @@ export class Validate {
547
547
  } else {
548
548
  const errorMsg: string[] = [];
549
549
  const project = new Project(projectPath);
550
+ const calculate = new Calculate(project);
550
551
 
551
552
  // Then, validate that each 'contentSchema' children as well.
552
553
  const result = await this.readAndValidateContentFiles(
@@ -590,11 +591,15 @@ export class Validate {
590
591
 
591
592
  // Validate macros in content
592
593
  if (card.content) {
593
- await evaluateMacros(card.content, {
594
- mode: 'validate',
595
- projectPath,
596
- cardKey: card.key,
597
- });
594
+ await evaluateMacros(
595
+ card.content,
596
+ {
597
+ mode: 'validate',
598
+ project,
599
+ cardKey: card.key,
600
+ },
601
+ calculate,
602
+ );
598
603
  }
599
604
  }
600
605
  if (errorMsg.length) {
@@ -0,0 +1,65 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2025
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. This program is distributed in the hope that it
7
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
8
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ See the GNU Affero General Public License for more details.
10
+ 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
+ */
13
+
14
+ import { watch } from 'node:fs';
15
+
16
+ import { getChildLogger } from '../../utils/log-utils.js';
17
+
18
+ /**
19
+ * Class that starts watching certain path for changes.
20
+ * Generally we are not interested for file renames, as they are handled
21
+ * through rename command, thus there is an option to ignore those.
22
+ */
23
+ export class ContentWatcher {
24
+ private watcher;
25
+ private abortController = new AbortController();
26
+
27
+ constructor(
28
+ ignoreRenames: boolean,
29
+ private watchPath: string,
30
+ callback: (fileName: string) => void,
31
+ ) {
32
+ this.watcher = watch(
33
+ this.watchPath,
34
+ {
35
+ persistent: true,
36
+ recursive: true,
37
+ signal: this.abortController.signal,
38
+ },
39
+ (eventType, filename) => {
40
+ if ((ignoreRenames && eventType === 'rename') || !filename) {
41
+ return;
42
+ }
43
+ callback(filename);
44
+ },
45
+ ).on('error', (error) => {
46
+ ContentWatcher.logger.error(error, 'Watch error');
47
+ this.close();
48
+ });
49
+ this.watcher.unref();
50
+ }
51
+
52
+ // Returns instance of logger.
53
+ private static get logger() {
54
+ return getChildLogger({
55
+ module: 'contentWatcher',
56
+ });
57
+ }
58
+
59
+ /**
60
+ * Close content watcher. Removes watcher.
61
+ */
62
+ public close() {
63
+ this.abortController.abort();
64
+ }
65
+ }
@@ -81,7 +81,7 @@ export class ProjectPaths {
81
81
  }
82
82
 
83
83
  public get logPath(): string {
84
- return join(this.resourcesFolder, 'dh.log');
84
+ return join(this.path, '.logs', 'cyberismo_data-handler.log');
85
85
  }
86
86
 
87
87
  public get modulesFolder(): string {
@@ -64,6 +64,9 @@ import { ReportResource } from '../resources/report-resource.js';
64
64
  import { TemplateResource } from '../resources/template-resource.js';
65
65
  import { WorkflowResource } from '../resources/workflow-resource.js';
66
66
 
67
+ import { ContentWatcher } from './project/project-content-watcher.js';
68
+ import { pathToResourceName } from '../utils/resource-utils.js';
69
+
67
70
  // Re-export this, so that classes that use Project do not need to have separate import.
68
71
  export { ResourcesFrom };
69
72
 
@@ -75,12 +78,16 @@ export class Project extends CardContainer {
75
78
  private projectPaths: ProjectPaths;
76
79
  private settings: ProjectConfiguration;
77
80
  private validator: Validate;
81
+ private resourceWatcher: ContentWatcher | undefined;
78
82
 
79
83
  // Created resources are held in a cache.
80
84
  // In the cache, key is resource name, and data is resource metadata (as JSON).
81
85
  private createdResources = new Map<string, JSON>();
82
86
 
83
- constructor(path: string) {
87
+ constructor(
88
+ path: string,
89
+ private watchResourceChanges?: boolean,
90
+ ) {
84
91
  super(path, '');
85
92
 
86
93
  this.settings = new ProjectConfiguration(
@@ -93,6 +100,48 @@ export class Project extends CardContainer {
93
100
  // todo: implement project validation
94
101
  this.validator = Validate.getInstance();
95
102
  this.resources.collectLocalResources();
103
+
104
+ const ignoreRenameFileChanges = true;
105
+
106
+ // Watch changes in .cards if there are multiple instances of Project being
107
+ // run concurrently.
108
+ if (this.watchResourceChanges) {
109
+ this.resourceWatcher = new ContentWatcher(
110
+ ignoreRenameFileChanges,
111
+ this.paths.resourcesFolder,
112
+ async (fileName: string) => {
113
+ let resource;
114
+ try {
115
+ resource = pathToResourceName(
116
+ this,
117
+ join(this.paths.resourcesFolder, fileName),
118
+ );
119
+ if (!resource) {
120
+ return;
121
+ }
122
+ } catch {
123
+ // it wasn't a resource that changed, so ignore the change
124
+ return;
125
+ }
126
+ const resourceName = `${resource.prefix}/${resource.type}/${resource.identifier}`;
127
+ await this.replaceCacheValue(resourceName);
128
+ this.resources.collectLocalResources();
129
+ },
130
+ );
131
+ }
132
+ }
133
+
134
+ // Removes current version of resource from cache.
135
+ // Then re-creates the resource with current data and caches the value again.
136
+ // If the value wasn't in the cache before, it will be added.
137
+ private async replaceCacheValue(resourceName: string) {
138
+ if (this.createdResources.has(resourceName)) {
139
+ // First, remove the old version from cache
140
+ this.createdResources.delete(resourceName);
141
+ }
142
+ const resourceData = await this.resource(resourceName);
143
+ if (!resourceData) return;
144
+ this.createdResources.set(resourceName, resourceData as JSON);
96
145
  }
97
146
 
98
147
  // Finds specific module.
@@ -318,6 +367,16 @@ export class Project extends CardContainer {
318
367
  return new TemplateResource(this, resourceName(template)).templateObject();
319
368
  }
320
369
 
370
+ /**
371
+ * Cleanups project when it is being closed.
372
+ */
373
+ public dispose() {
374
+ if (this.resourceWatcher) {
375
+ this.resourceWatcher.close();
376
+ this.resourceWatcher = undefined;
377
+ }
378
+ }
379
+
321
380
  /**
322
381
  * Returns an array of all the field types in the project.
323
382
  * @param from Defines where resources are collected from.
@@ -37,7 +37,7 @@ import {
37
37
  getRankAfter,
38
38
  sortItems,
39
39
  } from '../utils/lexorank.js';
40
- import { logger } from '../utils/log-utils.js';
40
+ import { getChildLogger } from '../utils/log-utils.js';
41
41
  import { readJsonFile } from '../utils/json.js';
42
42
  import { Project } from './project.js';
43
43
  import { resourceName } from '../utils/resource-utils.js';
@@ -47,6 +47,11 @@ export class Template extends CardContainer {
47
47
  private templatePath: string;
48
48
  private templateCardsPath: string;
49
49
  private project: Project;
50
+ private get logger() {
51
+ return getChildLogger({
52
+ module: 'template',
53
+ });
54
+ }
50
55
 
51
56
  constructor(project: Project, template: Resource) {
52
57
  // Templates might come from modules. Remove module name from template name.
@@ -465,7 +470,7 @@ export class Template extends CardContainer {
465
470
  details?: FetchCardDetails,
466
471
  ): Promise<Card[]> {
467
472
  if (placeHolderPath) {
468
- logger.warn('A non-used variable was used in the cards method');
473
+ this.logger.warn('A non-used variable was used in the cards method');
469
474
  }
470
475
  const cardDetails = details
471
476
  ? details
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  CommandManager,
18
18
  ExportFormats,
19
19
  } from './command-handler.js';
20
+ import type { Credentials } from './interfaces/project-interfaces.js';
20
21
  import { requestStatus } from './interfaces/request-status-interfaces.js';
21
22
  import { UpdateOperations } from './resources/resource-object.js';
22
23
  import { evaluateMacros } from './macros/index.js';
@@ -26,6 +27,7 @@ export {
26
27
  Cmd,
27
28
  CommandManager,
28
29
  Commands,
30
+ Credentials,
29
31
  ExportFormats,
30
32
  requestStatus,
31
33
  UpdateOperations,
@@ -11,11 +11,12 @@
11
11
  */
12
12
 
13
13
  import type { macroMetadata } from '../macros/common.js';
14
+ import type { Project } from '../containers/project.js';
14
15
 
15
16
  type Mode = 'validate' | 'static' | 'inject';
16
17
 
17
18
  export interface MacroGenerationContext {
18
- projectPath: string;
19
+ project: Project;
19
20
  mode: Mode;
20
21
  cardKey: string;
21
22
  }
@@ -65,6 +65,12 @@ export interface CardMetadata extends PredefinedCardMetadata {
65
65
  // Content in project (apart from cards) is either .schema files or cardsConfig.json.
66
66
  type ContentType = DotSchemaContent | ProjectSettings;
67
67
 
68
+ // Credentials for private modules.
69
+ export interface Credentials {
70
+ username?: string;
71
+ token?: string;
72
+ }
73
+
68
74
  // Single CSV row as read from a file.
69
75
  export type CSVRowRaw = {
70
76
  [key: string]: string;
@@ -147,9 +153,11 @@ export interface ModuleSetting extends ModuleSettingOptions {
147
153
  location: string;
148
154
  }
149
155
 
156
+ // Additional options for module configuration.
150
157
  export interface ModuleSettingOptions {
151
158
  branch?: string;
152
159
  private?: boolean;
160
+ credentials?: Credentials;
153
161
  }
154
162
 
155
163
  // Resources that are possible to remove.
@@ -1,13 +1,14 @@
1
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 the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
6
-
7
- 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.
8
-
9
- You should have received a copy of the GNU Affero General Public
10
- License along with this program. If not, see <https://www.gnu.org/licenses/>.
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/>.
11
12
  */
12
13
 
13
14
  import type { Schema } from 'jsonschema';
@@ -30,6 +31,7 @@ export interface CardType extends ResourceBaseMetadata {
30
31
  }
31
32
 
32
33
  // Custom field
34
+ // todo: merge with FieldType.
33
35
  export interface CustomField {
34
36
  name: string;
35
37
  description?: string;
@@ -59,8 +61,6 @@ export interface EnumDefinition {
59
61
 
60
62
  // Field type content.
61
63
  export interface FieldType extends ResourceBaseMetadata {
62
- displayName?: string;
63
- fieldDescription?: string;
64
64
  dataType: DataType;
65
65
  enumValues?: Array<EnumDefinition>;
66
66
  }
@@ -68,8 +68,6 @@ export interface FieldType extends ResourceBaseMetadata {
68
68
  // Graph model content.
69
69
  export interface GraphModelMetadata extends ResourceBaseMetadata {
70
70
  category?: string;
71
- description?: string;
72
- displayName: string;
73
71
  }
74
72
 
75
73
  export interface GraphModel extends GraphModelMetadata {
@@ -79,8 +77,6 @@ export interface GraphModel extends GraphModelMetadata {
79
77
  // Graph view content.
80
78
  export interface GraphViewMetadata extends ResourceBaseMetadata {
81
79
  category?: string;
82
- description?: string;
83
- displayName: string;
84
80
  }
85
81
 
86
82
  export interface GraphView extends GraphViewMetadata {
@@ -104,7 +100,7 @@ export interface LinkType extends ResourceBaseMetadata {
104
100
  }
105
101
 
106
102
  // Report resource.
107
- export interface Report {
103
+ export interface Report extends ResourceBaseMetadata {
108
104
  name: string;
109
105
  metadata: ReportMetadata;
110
106
  contentTemplate: string;
@@ -114,14 +110,14 @@ export interface Report {
114
110
 
115
111
  // Metadata for report
116
112
  export interface ReportMetadata extends ResourceBaseMetadata {
117
- displayName: string;
118
- description: string;
119
113
  category: string;
120
114
  }
121
115
 
122
116
  // Base interface for all resources.
123
117
  export interface ResourceBaseMetadata {
124
118
  name: string;
119
+ description?: string;
120
+ displayName: string;
125
121
  usedIn?: string[];
126
122
  }
127
123
 
@@ -137,8 +133,7 @@ export type ResourceContent =
137
133
  | Workflow;
138
134
 
139
135
  // Template configuration details.
140
- export interface TemplateConfiguration {
141
- name: string;
136
+ export interface TemplateConfiguration extends ResourceBaseMetadata {
142
137
  path: string;
143
138
  numberOfCards: number;
144
139
  metadata: TemplateMetadata;
@@ -146,8 +141,6 @@ export interface TemplateConfiguration {
146
141
 
147
142
  // Template configuration content details.
148
143
  export interface TemplateMetadata extends ResourceBaseMetadata {
149
- displayName?: string;
150
- description?: string;
151
144
  category?: string;
152
145
  }
153
146
 
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  Cyberismo
3
3
  Copyright © Cyberismo Ltd and contributors 2024
4
-
5
4
  This program is free software: you can redistribute it and/or modify it under
6
5
  the terms of the GNU Affero General Public License version 3 as published by
7
6
  the Free Software Foundation. This program is distributed in the hope that it
@@ -18,11 +17,10 @@ import type { MacroOptions } from '../index.js';
18
17
  import { createImage, validateMacroContent } from '../index.js';
19
18
  import Handlebars from 'handlebars';
20
19
  import { join } from 'node:path';
21
- import { logger } from '../../utils/log-utils.js';
20
+ import { getChildLogger } from '../../utils/log-utils.js';
22
21
  import type { MacroGenerationContext } from '../../interfaces/macros.js';
23
22
  import macroMetadata from './metadata.js';
24
23
  import { pathExists } from '../../utils/file-utils.js';
25
- import { Project } from '../../containers/project.js';
26
24
  import { readFile } from 'node:fs/promises';
27
25
  import { resourceName } from '../../utils/resource-utils.js';
28
26
  import type { Schema } from 'jsonschema';
@@ -35,6 +33,11 @@ export interface GraphOptions extends MacroOptions {
35
33
  }
36
34
 
37
35
  class ReportMacro extends BaseMacro {
36
+ private get logger() {
37
+ return getChildLogger({
38
+ module: 'graphMacro',
39
+ });
40
+ }
38
41
  constructor(tasksQueue: TaskQueue) {
39
42
  super(macroMetadata, tasksQueue);
40
43
  }
@@ -48,16 +51,20 @@ class ReportMacro extends BaseMacro {
48
51
  };
49
52
 
50
53
  handleInject = async (context: MacroGenerationContext, input: unknown) => {
51
- const project = new Project(context.projectPath);
52
- const calculate = new Calculate(project);
54
+ const calculate = new Calculate(context.project);
53
55
 
54
56
  const resourceNameToPath = (name: string, fileName: string) => {
55
57
  const { identifier, prefix, type } = resourceName(name);
56
- if (prefix === project.projectPrefix) {
57
- return join(project.paths.resourcesFolder, type, identifier, fileName);
58
+ if (prefix === context.project.projectPrefix) {
59
+ return join(
60
+ context.project.paths.resourcesFolder,
61
+ type,
62
+ identifier,
63
+ fileName,
64
+ );
58
65
  }
59
66
  return join(
60
- project.paths.modulesFolder,
67
+ context.project.paths.modulesFolder,
61
68
  prefix,
62
69
  type,
63
70
  identifier,
@@ -76,7 +83,7 @@ class ReportMacro extends BaseMacro {
76
83
  ),
77
84
  );
78
85
  } catch (err) {
79
- logger.trace(
86
+ this.logger.trace(
80
87
  err,
81
88
  'Graph schema not found or failed to read, skipping validation',
82
89
  );
@@ -110,9 +117,7 @@ class ReportMacro extends BaseMacro {
110
117
  const view = handlebars.compile(viewContent)(handlebarsContext);
111
118
 
112
119
  const modelContent = await readFile(modelLocation, { encoding: 'utf-8' });
113
- const result = await calculate.runGraph({
114
- query: view + '\n' + modelContent,
115
- });
120
+ const result = await calculate.runGraph(modelContent, view);
116
121
 
117
122
  if (typeof result !== 'string') {
118
123
  throw new Error(
@@ -28,21 +28,45 @@ import type {
28
28
  } from '../interfaces/macros.js';
29
29
  import type BaseMacro from './base-macro.js';
30
30
  import TaskQueue from './task-queue.js';
31
-
31
+ import type { Calculate } from '../commands/index.js';
32
32
  const CURLY_LEFT = '&#123;';
33
33
  const CURLY_RIGHT = '&#125;';
34
34
 
35
- export interface MacroConstructor {
36
- new (tasks: TaskQueue): BaseMacro; // Constructor signature
35
+ /**
36
+ * Constructor for all macros except report macros
37
+ */
38
+ export interface SimpleMacroConstructor {
39
+ new (tasks: TaskQueue): BaseMacro;
40
+ }
41
+
42
+ /**
43
+ * Constructor for report macros
44
+ */
45
+ export interface ReportMacroConstructor {
46
+ new (tasks: TaskQueue, calculate: Calculate): BaseMacro;
37
47
  }
38
48
 
39
- export const macros: { [K in MacroName]: MacroConstructor } = {
49
+ /**
50
+ * Constructor for all macros
51
+ */
52
+ export type MacroConstructor = SimpleMacroConstructor | ReportMacroConstructor;
53
+
54
+ export const macros: {
55
+ [K in MacroName]: MacroConstructor;
56
+ } = {
40
57
  createCards,
41
58
  graph,
42
59
  report,
43
60
  scoreCard,
44
61
  };
45
62
 
63
+ /**
64
+ * Validates the content inside a macro
65
+ * @param macro - The macro to validate the content of
66
+ * @param data - The data to validate
67
+ * @param validator - The validator to use
68
+ * @returns The validated data
69
+ */
46
70
  export function validateMacroContent<T>(
47
71
  macro: MacroMetadata,
48
72
  data: unknown,
@@ -74,11 +98,12 @@ export function registerMacros(
74
98
  instance: typeof Handlebars,
75
99
  context: MacroGenerationContext,
76
100
  tasks: TaskQueue,
101
+ calculate: Calculate,
77
102
  ) {
78
103
  const macroInstances: BaseMacro[] = [];
79
104
  for (const macro of Object.keys(macros) as MacroName[]) {
80
105
  const MacroClass = macros[macro];
81
- const macroInstance = new MacroClass(tasks);
106
+ const macroInstance = new MacroClass(tasks, calculate);
82
107
  instance.registerHelper(macro, function (this: unknown, options) {
83
108
  if (
84
109
  this != null &&
@@ -134,11 +159,12 @@ export function registerEmptyMacros(instance: typeof Handlebars) {
134
159
  export async function evaluateMacros(
135
160
  content: string,
136
161
  context: MacroGenerationContext,
162
+ calculate: Calculate,
137
163
  maxTries: number = 10,
138
164
  ) {
139
165
  const handlebars = Handlebars.create();
140
166
  const tasks = new TaskQueue();
141
- registerMacros(handlebars, context, tasks);
167
+ registerMacros(handlebars, context, tasks, calculate);
142
168
  let result = content;
143
169
  while (maxTries-- > 0) {
144
170
  tasks.reset();