@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
@@ -110,23 +110,25 @@ export class Project extends CardContainer {
110
110
  this.resourceWatcher = new ContentWatcher(
111
111
  ignoreRenameFileChanges,
112
112
  this.paths.resourcesFolder,
113
- async (fileName: string) => {
114
- let resource;
115
- try {
116
- resource = pathToResourceName(
117
- this,
118
- join(this.paths.resourcesFolder, fileName),
119
- );
120
- if (!resource) {
113
+ (fileName: string) => {
114
+ void (async () => {
115
+ let resource;
116
+ try {
117
+ resource = pathToResourceName(
118
+ this,
119
+ join(this.paths.resourcesFolder, fileName),
120
+ );
121
+ if (!resource) {
122
+ return;
123
+ }
124
+ } catch {
125
+ // it wasn't a resource that changed, so ignore the change
121
126
  return;
122
127
  }
123
- } catch {
124
- // it wasn't a resource that changed, so ignore the change
125
- return;
126
- }
127
- const resourceName = `${resource.prefix}/${resource.type}/${resource.identifier}`;
128
- await this.replaceCacheValue(resourceName);
129
- this.resources.collectLocalResources();
128
+ const resourceName = `${resource.prefix}/${resource.type}/${resource.identifier}`;
129
+ await this.replaceCacheValue(resourceName);
130
+ this.resources.collectLocalResources();
131
+ })();
130
132
  },
131
133
  );
132
134
  }
@@ -164,6 +166,7 @@ export class Project extends CardContainer {
164
166
  /**
165
167
  * Add a given 'resource' to the local resource arrays.
166
168
  * @param resource Resource to add.
169
+ * @param data JSON data for the resource.
167
170
  */
168
171
  public addResource(resource: Resource, data: JSON) {
169
172
  this.resources.add(resource);
@@ -193,6 +196,7 @@ export class Project extends CardContainer {
193
196
  * Returns path to card's attachment folder.
194
197
  * @param cardKey card key
195
198
  * @returns path to card's attachment folder.
199
+ * @throws if card path cannot be found
196
200
  */
197
201
  public async cardAttachmentFolder(cardKey: string): Promise<string> {
198
202
  // Check if it is a template card.
@@ -202,9 +206,10 @@ export class Project extends CardContainer {
202
206
  }
203
207
 
204
208
  const pathToProjectCard = this.pathToCard(cardKey);
205
- return pathToProjectCard
206
- ? join(this.paths.cardRootFolder, pathToProjectCard, 'a')
207
- : '';
209
+ if (!pathToProjectCard) {
210
+ throw new Error(`Card '${cardKey}' not found`);
211
+ }
212
+ return join(this.paths.cardRootFolder, pathToProjectCard, 'a');
208
213
  }
209
214
 
210
215
  /**
@@ -252,6 +257,7 @@ export class Project extends CardContainer {
252
257
  * Returned parts are: prefix, card key, array of parents and template name. Template name is returned only for template cards.
253
258
  * @param cardPath path to a card
254
259
  * @returns card path logical parts
260
+ * @throws when called with wrong path, or wrong card owner
255
261
  * todo: if prefix would be parameter; this could be static, or util method
256
262
  */
257
263
  public cardPathParts(cardPath: string) {
@@ -458,7 +464,7 @@ export class Project extends CardContainer {
458
464
 
459
465
  /**
460
466
  * Returns an array of all the graph models in the project.
461
- * @param from Defines where resources are collected from.
467
+ * @param from Defines where resources are collected from.
462
468
  * @returns array of all the graph models in the project.
463
469
  */
464
470
  public async graphModels(
@@ -469,7 +475,7 @@ export class Project extends CardContainer {
469
475
 
470
476
  /**
471
477
  * Returns an array of all the graph views in the project.
472
- * @param from Defines where resources are collected from.
478
+ * @param from Defines where resources are collected from.
473
479
  * @returns array of all the graph views in the project.
474
480
  */
475
481
  public async graphViews(
@@ -513,7 +519,7 @@ export class Project extends CardContainer {
513
519
 
514
520
  /**
515
521
  * Adds a module from project.
516
- * @param moduleName Name of the module
522
+ * @param module Name of the module
517
523
  */
518
524
  public async importModule(module: ModuleSetting) {
519
525
  // Add module as a dependency.
@@ -534,6 +540,7 @@ export class Project extends CardContainer {
534
540
  * Returns whether card is a template card or not
535
541
  * @param cardKey card to check.
536
542
  * @todo: This is only used from 'remove'. Could it use the static checker?
543
+ * @returns true, if card is template card; false otherwise
537
544
  */
538
545
  public async isTemplateCard(cardKey: string): Promise<boolean> {
539
546
  const templateCards = await this.allTemplateCards();
@@ -554,7 +561,7 @@ export class Project extends CardContainer {
554
561
  /**
555
562
  * Returns an array of cards in the project, in the templates or both.
556
563
  * Cards don't have content and nor metadata.
557
- * @param includeCardsFrom Where to return cards from (project, templates, or both)
564
+ * @param cardsFrom Where to return cards from (project, templates, or both)
558
565
  * @returns all cards in the project.
559
566
  */
560
567
  public async listCards(
@@ -603,7 +610,7 @@ export class Project extends CardContainer {
603
610
 
604
611
  /**
605
612
  * Return cardIDs of the cards in the project or from templates, or both.
606
- * @param includeCardsFrom Where to return cards from (project, templates, or both)
613
+ * @param cardsFrom Where to return cards from (project, templates, or both)
607
614
  * @returns Array of cardIDs.
608
615
  * @note that cardIDs are not sorted.
609
616
  */
@@ -626,41 +633,35 @@ export class Project extends CardContainer {
626
633
  cardsFrom === CardLocation.templatesOnly
627
634
  ) {
628
635
  promises.push(
629
- this.templates().then((templates) =>
630
- Promise.allSettled(
631
- templates.map(
632
- (template) =>
633
- new TemplateResource(this, resourceName(template.name)),
634
- ),
635
- )
636
- .then((results) =>
637
- results
638
- .filter(
639
- (
640
- result,
641
- ): result is PromiseFulfilledResult<TemplateResource> =>
642
- result.status === 'fulfilled' && result.value !== null,
643
- )
644
- .map((result) => result.value),
636
+ (async () => {
637
+ const templates = await this.templates();
638
+ const templateResources = templates.map(
639
+ (template) =>
640
+ new TemplateResource(this, resourceName(template.name)),
641
+ );
642
+ const templateObjectsResults =
643
+ await Promise.allSettled(templateResources);
644
+ const templateObjects = templateObjectsResults
645
+ .filter(
646
+ (result): result is PromiseFulfilledResult<TemplateResource> =>
647
+ result.status === 'fulfilled' && result.value !== null,
645
648
  )
646
- .then((templateObjects) =>
647
- Promise.allSettled(
648
- templateObjects.map((obj) => obj.templateObject().listCards()),
649
- ),
649
+ .map((result) => result.value);
650
+
651
+ const listCardsResults = await Promise.allSettled(
652
+ templateObjects.map((obj) => obj.templateObject().listCards()),
653
+ );
654
+ const templateCardIds = new Set<string>();
655
+ listCardsResults
656
+ .filter(
657
+ (result): result is PromiseFulfilledResult<Card[]> =>
658
+ result.status === 'fulfilled',
650
659
  )
651
- .then((results) => {
652
- const templateCardIds = new Set<string>();
653
- results
654
- .filter(
655
- (result): result is PromiseFulfilledResult<Card[]> =>
656
- result.status === 'fulfilled',
657
- )
658
- .forEach((result) => {
659
- result.value.forEach((card) => templateCardIds.add(card.key));
660
- });
661
- return templateCardIds;
662
- }),
663
- ),
660
+ .forEach((result) => {
661
+ result.value.forEach((card) => templateCardIds.add(card.key));
662
+ });
663
+ return templateCardIds;
664
+ })(),
664
665
  );
665
666
  }
666
667
  const allCardIdSets = await Promise.all(promises);
@@ -682,6 +683,7 @@ export class Project extends CardContainer {
682
683
  return {
683
684
  name: moduleConfig.name,
684
685
  modules: moduleConfig.modules,
686
+ hubs: moduleConfig.hubs,
685
687
  path: modulePath,
686
688
  cardKeyPrefix: moduleConfig.cardKeyPrefix,
687
689
  calculations: [
@@ -754,6 +756,7 @@ export class Project extends CardContainer {
754
756
  /**
755
757
  * Returns a new unique card key with project prefix (e.g. test_x649it4x).
756
758
  * Random part of string will be always 8 characters in base-36 (0-9a-z)
759
+ * @param cardIds map of card ids in use already
757
760
  * @returns a new card key string
758
761
  * @throws if a unique key could not be created within set number of attempts
759
762
  */
@@ -772,12 +775,14 @@ export class Project extends CardContainer {
772
775
  return newKey;
773
776
  }
774
777
 
775
- throw 'Could not generate unique card key';
778
+ throw new Error('Could not generate unique card key');
776
779
  }
777
780
 
778
781
  /**
779
782
  * Returns an array of new unique card keys with project prefix (e.g. test_x649it4x).
780
783
  * Random part of string will be always 8 characters in base-36 (0-9a-z)
784
+ * @param keysToCreate How many new cards are to be created.
785
+ * @param cardIds map of card ids in use already
781
786
  * @returns an array of new card key strings
782
787
  * @throws if a unique key could not be created within set number of attempts
783
788
  */
@@ -809,7 +814,7 @@ export class Project extends CardContainer {
809
814
  }
810
815
 
811
816
  /**
812
- * Getter. Returns a class that handles the project's paths.
817
+ * Returns a class that handles the project's paths.
813
818
  */
814
819
  public get paths(): ProjectPaths {
815
820
  return this.projectPaths;
@@ -828,14 +833,14 @@ export class Project extends CardContainer {
828
833
  }
829
834
 
830
835
  /**
831
- * Getter. Returns project name.
836
+ * Returns project name.
832
837
  */
833
838
  public get projectName(): string {
834
839
  return this.settings.name;
835
840
  }
836
841
 
837
842
  /**
838
- * Getter. Returns project prefix.
843
+ * Returns project prefix.
839
844
  */
840
845
  public get projectPrefix(): string {
841
846
  return this.settings.cardKeyPrefix;
@@ -869,7 +874,7 @@ export class Project extends CardContainer {
869
874
  const configurationPrefixes = await Promise.all(configurationPromises);
870
875
  prefixes.push(...configurationPrefixes);
871
876
  } catch {
872
- // do nothing if readdir throws
877
+ // do nothing if readdir throws // TODO: Log it
873
878
  }
874
879
 
875
880
  return prefixes;
@@ -937,6 +942,9 @@ export class Project extends CardContainer {
937
942
  return data;
938
943
  }
939
944
 
945
+ /**
946
+ * Returns resource cache.
947
+ */
940
948
  public get resourceCache(): Map<string, JSON> {
941
949
  return this.createdResources;
942
950
  }
@@ -1000,6 +1008,7 @@ export class Project extends CardContainer {
1000
1008
  name: this.containerName,
1001
1009
  path: this.basePath,
1002
1010
  prefix: this.projectPrefix,
1011
+ hubs: this.configuration.hubs,
1003
1012
  modules: (await this.modules()).map((item) => item.name),
1004
1013
  numberOfCards: (await this.listCards(CardLocation.projectOnly))[0].cards
1005
1014
  .length,
@@ -1131,6 +1140,7 @@ export class Project extends CardContainer {
1131
1140
  /**
1132
1141
  * Validates that card's data is valid.
1133
1142
  * @param card Card to validate.
1143
+ * @returns validation errors, if any
1134
1144
  */
1135
1145
  public async validateCard(card: Card): Promise<string> {
1136
1146
  const invalidCustomData = await this.validator.validateCustomFields(
@@ -439,7 +439,7 @@ export class Template extends CardContainer {
439
439
  public async cardAttachmentFolder(cardKey: string): Promise<string> {
440
440
  const pathToCard = await this.cardFolder(cardKey);
441
441
  if (!pathToCard) {
442
- return '';
442
+ throw new Error(`Template card '${cardKey}' not found`);
443
443
  }
444
444
  return join(pathToCard, 'a');
445
445
  }
@@ -164,6 +164,7 @@ export interface ProjectMetadata {
164
164
  path: string;
165
165
  prefix: string;
166
166
  modules: string[];
167
+ hubs: HubSetting[];
167
168
  numberOfCards: number;
168
169
  }
169
170
 
@@ -172,6 +173,20 @@ export interface ProjectSettings {
172
173
  cardKeyPrefix: string;
173
174
  name: string;
174
175
  modules: ModuleSetting[];
176
+ hubs: HubSetting[];
177
+ }
178
+
179
+ // Hub configuration
180
+ export interface HubSetting {
181
+ location: string;
182
+ description?: string;
183
+ displayName?: string;
184
+ }
185
+
186
+ // Module configuration for a hub.
187
+ export interface ModuleSettingFromHub extends ModuleSetting {
188
+ documentationLocation: string;
189
+ displayName: string;
175
190
  }
176
191
 
177
192
  // Module configuration.
@@ -195,6 +210,7 @@ export type RemovableResourceTypes =
195
210
  | 'fieldType'
196
211
  | 'graphModel'
197
212
  | 'graphView'
213
+ | 'hub'
198
214
  | 'link'
199
215
  | 'linkType'
200
216
  | 'module'
@@ -229,6 +245,8 @@ export type ResourceTypes =
229
245
  | 'attachments'
230
246
  | 'calculation'
231
247
  | 'cards'
248
+ | 'hubs'
249
+ | 'importableModules'
232
250
  | 'label'
233
251
  | 'labels'
234
252
  | 'links'
@@ -63,7 +63,10 @@ abstract class BaseMacro {
63
63
  input: unknown,
64
64
  ): Promise<string>;
65
65
 
66
- protected abstract handleValidate(input: unknown): void;
66
+ protected abstract handleValidate(
67
+ context: MacroGenerationContext,
68
+ input: unknown,
69
+ ): void;
67
70
 
68
71
  public get metadata() {
69
72
  return this.macroMetadata;
@@ -127,7 +130,7 @@ abstract class BaseMacro {
127
130
 
128
131
  if (context.mode === 'validate') {
129
132
  try {
130
- this.handleValidate(JSON.parse(input));
133
+ this.handleValidate(context, JSON.parse(input));
131
134
  } catch (error) {
132
135
  if (error instanceof Error) {
133
136
  const errorMessage = `From card '${context.cardKey}' a macro validation error:\n\n${error.message}.\n\nCard content:\n ${input}`;
@@ -34,7 +34,7 @@ class CreateCardsMacro extends BaseMacro {
34
34
  super(macroMetadata, tasksQueue);
35
35
  }
36
36
 
37
- handleValidate = (input: unknown) => {
37
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
38
38
  this.validate(input);
39
39
  };
40
40
 
@@ -14,16 +14,16 @@
14
14
  import BaseMacro from '../base-macro.js';
15
15
  import { createImage, validateMacroContent } from '../index.js';
16
16
  import Handlebars from 'handlebars';
17
- import { join } from 'node:path';
18
17
  import type { MacroGenerationContext } from '../../interfaces/macros.js';
19
18
  import macroMetadata from './metadata.js';
20
19
  import { pathExists } from '../../utils/file-utils.js';
21
20
  import { readFile } from 'node:fs/promises';
22
- import { resourceName } from '../../utils/resource-utils.js';
21
+ import { readFileSync } from 'node:fs';
23
22
  import type { Schema } from 'jsonschema';
24
- import { validateJson } from '../../utils/validate.js';
25
23
  import type TaskQueue from '../task-queue.js';
26
24
  import { ClingoError } from '@cyberismo/node-clingo';
25
+ import { resourceFilePath } from '../../utils/resource-utils.js';
26
+ import { resourceName } from '../../utils/resource-utils.js';
27
27
 
28
28
  export interface GraphOptions {
29
29
  model: string;
@@ -35,55 +35,23 @@ class ReportMacro extends BaseMacro {
35
35
  super(macroMetadata, tasksQueue);
36
36
  }
37
37
 
38
- handleValidate = (input: unknown) => {
39
- this.parseOptions(input);
38
+ handleValidate = (context: MacroGenerationContext, input: unknown) => {
39
+ this.parseOptions(input, context);
40
40
  };
41
41
 
42
42
  handleStatic = async (context: MacroGenerationContext, input: unknown) => {
43
- const resourceNameToPath = (name: string, fileName: string) => {
44
- const { identifier, prefix, type } = resourceName(name);
45
- if (prefix === context.project.projectPrefix) {
46
- return join(
47
- context.project.paths.resourcesFolder,
48
- type,
49
- identifier,
50
- fileName,
51
- );
52
- }
53
- return join(
54
- context.project.paths.modulesFolder,
55
- prefix,
56
- type,
57
- identifier,
58
- fileName,
59
- );
60
- };
61
-
62
- const options = this.parseOptions(input);
63
-
64
- let schema: Schema | null = null;
65
- try {
66
- schema = JSON.parse(
67
- await readFile(
68
- resourceNameToPath(options.view, 'parameterSchema.json'),
69
- { encoding: 'utf-8' },
70
- ),
71
- );
72
- } catch (err) {
73
- this.logger.trace(
74
- err,
75
- 'Graph schema not found or failed to read, skipping validation',
76
- );
77
- }
78
-
79
- if (schema) {
80
- validateJson(options, {
81
- schema,
82
- });
83
- }
84
-
85
- const modelLocation = resourceNameToPath(options.model, 'model.lp');
86
- const viewLocation = resourceNameToPath(options.view, 'view.lp.hbs');
43
+ const options = this.parseOptions(input, context);
44
+
45
+ const modelLocation = resourceFilePath(
46
+ context.project,
47
+ resourceName(options.model),
48
+ 'model.lp',
49
+ );
50
+ const viewLocation = resourceFilePath(
51
+ context.project,
52
+ resourceName(options.view),
53
+ 'view.lp.hbs',
54
+ );
87
55
 
88
56
  if (!pathExists(modelLocation)) {
89
57
  throw new Error(`Graph: Model ${options.model} does not exist`);
@@ -128,8 +96,36 @@ class ReportMacro extends BaseMacro {
128
96
  return createImage(result);
129
97
  };
130
98
 
131
- private parseOptions(input: unknown): GraphOptions {
132
- return validateMacroContent<GraphOptions>(this.metadata, input);
99
+ private parseOptions(
100
+ input: unknown,
101
+ context: MacroGenerationContext,
102
+ ): GraphOptions {
103
+ const options = validateMacroContent<GraphOptions>(this.metadata, input);
104
+
105
+ let schema: Schema | null = null;
106
+ try {
107
+ schema = JSON.parse(
108
+ readFileSync(
109
+ resourceFilePath(
110
+ context.project,
111
+ resourceName(options.view),
112
+ 'parameterSchema.json',
113
+ ),
114
+ { encoding: 'utf-8' },
115
+ ),
116
+ );
117
+ } catch (err) {
118
+ this.logger.trace(
119
+ err,
120
+ 'Graph schema not found or failed to read, skipping validation',
121
+ );
122
+ }
123
+
124
+ if (schema) {
125
+ validateMacroContent(this.metadata, input, schema);
126
+ }
127
+
128
+ return options;
133
129
  }
134
130
  }
135
131
 
@@ -44,7 +44,7 @@ export default class ImageMacro extends BaseMacro {
44
44
  super(macroMetadata, tasksQueue);
45
45
  }
46
46
 
47
- handleValidate = (input: unknown) => {
47
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
48
48
  this.validate(input);
49
49
  };
50
50
 
@@ -58,9 +58,6 @@ export default class ImageMacro extends BaseMacro {
58
58
  // Get the attachment folder path
59
59
  const attachmentFolder =
60
60
  await context.project.cardAttachmentFolder(cardKey);
61
- if (!attachmentFolder) {
62
- throw new Error(`Card '${cardKey}' not found`);
63
- }
64
61
 
65
62
  // Read the file and convert to base64
66
63
  const attachmentPath = join(attachmentFolder, options.fileName);
@@ -90,9 +87,6 @@ export default class ImageMacro extends BaseMacro {
90
87
  // Verify that the card and attachment folder exist
91
88
  const attachmentFolder =
92
89
  await context.project.cardAttachmentFolder(cardKey);
93
- if (!attachmentFolder) {
94
- throw new Error(`Card '${cardKey}' not found`);
95
- }
96
90
 
97
91
  const attachmentPath = join(attachmentFolder, options.fileName);
98
92
  if (!existsSync(attachmentPath)) {
@@ -31,7 +31,7 @@ export default class IncludeMacro extends BaseMacro {
31
31
  super(macroMetadata, tasksQueue);
32
32
  }
33
33
 
34
- handleValidate = (input: unknown) => {
34
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
35
35
  this.validate(input);
36
36
  };
37
37
 
@@ -153,6 +153,7 @@ export const macros: {
153
153
  * Validates the content inside a macro
154
154
  * @param macro - The macro to validate the content of
155
155
  * @param data - The data to validate
156
+ * @param schema - Schema to use in validation
156
157
  * @returns The validated data
157
158
  */
158
159
  export function validateMacroContent<T>(
@@ -180,7 +181,10 @@ export function validateMacroContent<T>(
180
181
 
181
182
  /**
182
183
  * Registers the macros with Handlebars
183
- * @param {Mode} mode - The mode to register the macros in
184
+ * @param instance - Handlebar instance
185
+ * @param context - The context for macro generation
186
+ * @param tasks - Tasks to register
187
+ * @returns macro instances
184
188
  */
185
189
  export function registerMacros(
186
190
  instance: typeof Handlebars,
@@ -201,7 +205,8 @@ export function registerMacros(
201
205
  }
202
206
  /**
203
207
  * Calculate amount of handlebars templates inside a string
204
- * @param input
208
+ * @param input - String to calculate templates from
209
+ * @returns number of macros
205
210
  */
206
211
  export function macroCount(input: string): number {
207
212
  const regex = /{{#[\w\s-]+?}}/g;
@@ -224,11 +229,11 @@ export function registerEmptyMacros(instance: typeof Handlebars) {
224
229
  }
225
230
 
226
231
  /**
227
- * Handle the macros in the content
232
+ * Handle the macros in the content.
228
233
  * @param content - The content to handle the macros in
229
234
  * @param context - The context for macro generation
230
- * @param calculate - The calculate function
231
235
  * @param preserveRawBlocks - If true, don't unescape raw blocks at the end (for nested evaluations)
236
+ * @returns macro result
232
237
  */
233
238
  export async function evaluateMacros(
234
239
  content: string,
@@ -240,7 +245,7 @@ export async function evaluateMacros(
240
245
  registerMacros(handlebars, context, tasks);
241
246
  let result = content;
242
247
  while ((context.maxTries ?? 10) > 0) {
243
- tasks.reset();
248
+ await tasks.reset();
244
249
  try {
245
250
  const compiled = handlebars.compile(preprocessRawBlocks(result), {
246
251
  strict: true,
@@ -313,6 +318,7 @@ export function applyMacroResults(
313
318
  * Handles errors that come when handling macros
314
319
  * @param error - The error that was thrown
315
320
  * @param macro - The macro that caused the error
321
+ * @param context - General context for the macro evaluation process
316
322
  * @returns The error message that is valid adoc
317
323
  */
318
324
  export function handleMacroError(
@@ -350,9 +356,14 @@ export function handleMacroError(
350
356
  }
351
357
 
352
358
  // This is used to generate unique keys for macros
353
- // There might be a better way to do this
359
+ // TODO: There might be a better way to do this
354
360
  let macroCounter = 0;
355
361
 
362
+ /**
363
+ * Converts object to base64
364
+ * @param obj Object to convert
365
+ * @returns base64 conversion (as a Buffer)
366
+ */
356
367
  function objectToBase64(obj: unknown): string {
357
368
  return Buffer.from(JSON.stringify(obj), 'utf-8').toString('base64');
358
369
  }
@@ -393,8 +404,9 @@ export function createCodeBlock(content: string) {
393
404
  }
394
405
 
395
406
  /**
396
- * Helper function for including base64 encoded images for now
407
+ * Helper function for including base64 encoded images
397
408
  * @param image base64 encoded image
409
+ * @param controls Add controls
398
410
  * @returns valid asciidoc with the image
399
411
  */
400
412
  export function createImage(image: string, controls: boolean = true) {
@@ -30,7 +30,7 @@ class PercentageMacro extends BaseMacro {
30
30
  constructor(tasksQueue: TaskQueue) {
31
31
  super(macroMetadata, tasksQueue);
32
32
  }
33
- handleValidate = (data: string) => {
33
+ handleValidate = (_: MacroGenerationContext, data: string) => {
34
34
  this.validate(data);
35
35
  };
36
36
 
@@ -31,7 +31,7 @@ class ReportMacro extends BaseMacro {
31
31
  constructor(tasks: TaskQueue) {
32
32
  super(macroMetadata, tasks);
33
33
  }
34
- handleValidate = (input: unknown) => {
34
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
35
35
  this.validate(input);
36
36
  };
37
37
 
@@ -31,7 +31,7 @@ class ScoreCardMacro extends BaseMacro {
31
31
  constructor(tasksQueue: TaskQueue) {
32
32
  super(macroMetadata, tasksQueue);
33
33
  }
34
- handleValidate = (data: string) => {
34
+ handleValidate = (_: MacroGenerationContext, data: string) => {
35
35
  this.validate(data);
36
36
  };
37
37
 
@@ -31,7 +31,7 @@ class VegaMacro extends BaseMacro {
31
31
  super(macroMetadata, tasksQueue);
32
32
  }
33
33
 
34
- handleValidate = (input: unknown) => {
34
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
35
35
  this.validate(input);
36
36
  };
37
37
 
@@ -26,7 +26,7 @@ class VegaLiteMacro extends BaseMacro {
26
26
  super(macroMetadata, tasksQueue);
27
27
  }
28
28
 
29
- handleValidate = (input: unknown) => {
29
+ handleValidate = (_: MacroGenerationContext, input: unknown) => {
30
30
  this.validate(input);
31
31
  };
32
32