@cyberismo/data-handler 0.0.5 → 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 +9 -10
  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
@@ -20,6 +20,7 @@ import type {
20
20
  Card,
21
21
  CardAttachment,
22
22
  CardListContainer,
23
+ Credentials,
23
24
  FileContentType,
24
25
  ModuleContent,
25
26
  ProjectMetadata,
@@ -43,13 +44,17 @@ import { errorFunction } from './utils/log-utils.js';
43
44
  import { readJsonFile } from './utils/json.js';
44
45
  import { resourceName } from './utils/resource-utils.js';
45
46
 
47
+ import { type Level } from 'pino';
48
+
46
49
  // Generic options interface
47
50
  export interface CardsOptions {
48
51
  details?: boolean;
49
52
  forceStart?: boolean;
53
+ watchResourceChanges?: boolean;
50
54
  projectPath?: string;
51
55
  repeat?: number;
52
56
  showUse?: boolean;
57
+ logLevel?: Level;
53
58
  }
54
59
 
55
60
  // Commands that this class supports.
@@ -90,6 +95,7 @@ export class Commands {
90
95
  private commands?: CommandManager;
91
96
  private projectPath: string;
92
97
  private validateCmd: Validate;
98
+ private level?: Level;
93
99
 
94
100
  constructor() {
95
101
  this.projectPath = '';
@@ -112,19 +118,20 @@ export class Commands {
112
118
  command: Cmd,
113
119
  args: string[],
114
120
  options: CardsOptions,
121
+ credentials?: Credentials,
115
122
  ): Promise<requestStatus> {
116
123
  // Set project path and validate it.
117
124
  const creatingNewProject = command === Cmd.create && args[0] === 'project';
118
125
  if (!creatingNewProject) {
119
126
  try {
120
- await this.doSetProject(options.projectPath || '');
127
+ await this.doSetProject(options);
121
128
  } catch (error) {
122
129
  return { statusCode: 400, message: errorFunction(error) };
123
130
  }
124
131
  } else {
125
132
  this.projectPath = options.projectPath || '';
126
133
  }
127
- return await this.doHandleCommand(command, args, options);
134
+ return await this.doHandleCommand(command, args, options, credentials);
128
135
  }
129
136
 
130
137
  // Returns command 'target'.
@@ -143,7 +150,8 @@ export class Commands {
143
150
  }
144
151
 
145
152
  // Handles initializing the project so that it can be used in the class.
146
- private async doSetProject(path: string) {
153
+ private async doSetProject(options: CardsOptions) {
154
+ const path = options.projectPath || '';
147
155
  this.projectPath = resolveTilde(await this.setProjectPath(path));
148
156
  if (!Validate.validateFolder(this.projectPath)) {
149
157
  let errorMessage = '';
@@ -159,7 +167,10 @@ export class Commands {
159
167
  throw new Error(`Input validation error: cannot find project '${path}'`);
160
168
  }
161
169
 
162
- this.commands = await CommandManager.getInstance(this.projectPath);
170
+ this.commands = await CommandManager.getInstance(this.projectPath, {
171
+ logLevel: options.logLevel,
172
+ watchResourceChanges: options.watchResourceChanges,
173
+ });
163
174
  if (!this.commands) {
164
175
  throw new Error('Cannot get instance of CommandManager');
165
176
  }
@@ -171,6 +182,7 @@ export class Commands {
171
182
  command: Cmd,
172
183
  args: string[],
173
184
  options: CardsOptions,
185
+ credentials?: Credentials,
174
186
  ) {
175
187
  try {
176
188
  if (command === Cmd.add) {
@@ -263,6 +275,7 @@ export class Commands {
263
275
  source,
264
276
  branch,
265
277
  useCredentials && useCredentials === 'true' ? true : false,
278
+ credentials,
266
279
  );
267
280
  }
268
281
  if (target === 'csv') {
@@ -334,7 +347,7 @@ export class Commands {
334
347
  newValue ? JSON.parse(newValue) : undefined,
335
348
  );
336
349
  } else if (command === Cmd.updateModules) {
337
- await this.commands?.importCmd.updateAllModules();
350
+ await this.commands?.importCmd.updateAllModules(credentials);
338
351
  } else if (command === Cmd.validate) {
339
352
  return this.validate();
340
353
  } else {
@@ -449,11 +462,6 @@ export class Commands {
449
462
  destination,
450
463
  parentCardKey,
451
464
  );
452
- } else if (format === 'site') {
453
- message = await this.commands?.exportSiteCmd.exportToSite(
454
- destination,
455
- parentCardKey,
456
- );
457
465
  }
458
466
  process.env.EXPORT_FORMAT = '';
459
467
  return { statusCode: 200, message: message };
@@ -474,10 +482,12 @@ export class Commands {
474
482
  source: string,
475
483
  branch?: string,
476
484
  useCredentials?: boolean,
485
+ credentials?: Credentials,
477
486
  ) {
478
487
  return this.commands?.importCmd.importModule(source, this.projectPath, {
479
488
  branch: branch,
480
489
  private: useCredentials,
490
+ credentials,
481
491
  });
482
492
  }
483
493
 
@@ -509,9 +519,9 @@ export class Commands {
509
519
  // Runs a given logic program along with the query-language
510
520
  private async runLogicProgram(filePath: string): Promise<requestStatus> {
511
521
  try {
512
- const res = await this.commands?.calculateCmd.runLogicProgram({
513
- query: readFileSync(filePath, 'utf-8'),
514
- });
522
+ const res = await this.commands?.calculateCmd.runLogicProgram(
523
+ readFileSync(filePath, 'utf-8'),
524
+ );
515
525
  return {
516
526
  statusCode: 200,
517
527
  payload: res,
@@ -15,7 +15,6 @@ import {
15
15
  Create,
16
16
  Edit,
17
17
  Export,
18
- ExportSite,
19
18
  Import,
20
19
  Move,
21
20
  Remove,
@@ -26,6 +25,14 @@ import {
26
25
  Validate,
27
26
  } from './commands/index.js';
28
27
  import { Project } from './containers/project.js';
28
+ import { ProjectPaths } from './containers/project/project-paths.js';
29
+ import pino, { type Level, type TransportTargetOptions } from 'pino';
30
+ import { setLogger } from './utils/log-utils.js';
31
+
32
+ export interface CommandManagerOptions {
33
+ watchResourceChanges?: boolean;
34
+ logLevel?: Level;
35
+ }
29
36
 
30
37
  // Handles commands and ensures that no extra instances are created.
31
38
  export class CommandManager {
@@ -35,7 +42,6 @@ export class CommandManager {
35
42
  public calculateCmd: Calculate;
36
43
  public createCmd: Create;
37
44
  public editCmd: Edit;
38
- public exportSiteCmd: ExportSite;
39
45
  public exportCmd: Export;
40
46
  public importCmd: Import;
41
47
  public moveCmd: Move;
@@ -46,26 +52,24 @@ export class CommandManager {
46
52
  public updateCmd: Update;
47
53
  public validateCmd: Validate;
48
54
 
49
- constructor(path: string) {
50
- this.project = new Project(path);
55
+ private pathHandler: ProjectPaths;
56
+
57
+ constructor(path: string, options?: CommandManagerOptions) {
58
+ this.project = new Project(path, options?.watchResourceChanges);
51
59
  this.validateCmd = Validate.getInstance();
52
60
 
53
- this.showCmd = new Show(this.project);
54
61
  this.calculateCmd = new Calculate(this.project);
62
+ this.showCmd = new Show(this.project, this.calculateCmd);
55
63
  this.createCmd = new Create(this.project, this.calculateCmd);
56
64
  this.editCmd = new Edit(this.project, this.calculateCmd);
57
65
  this.exportCmd = new Export(this.project, this.calculateCmd, this.showCmd);
58
- this.exportSiteCmd = new ExportSite(
59
- this.project,
60
- this.calculateCmd,
61
- this.showCmd,
62
- );
63
66
  this.importCmd = new Import(this.project, this.createCmd);
64
67
  this.moveCmd = new Move(this.project, this.calculateCmd);
65
68
  this.removeCmd = new Remove(this.project, this.calculateCmd);
66
69
  this.renameCmd = new Rename(this.project, this.calculateCmd);
67
70
  this.transitionCmd = new Transition(this.project, this.calculateCmd);
68
71
  this.updateCmd = new Update(this.project);
72
+ this.pathHandler = new ProjectPaths(path);
69
73
  }
70
74
 
71
75
  /**
@@ -76,24 +80,61 @@ export class CommandManager {
76
80
  await this.project.collectModuleResources();
77
81
  }
78
82
 
83
+ /**
84
+ * Sets the logger for the command manager.
85
+ * @param level Log level.
86
+ */
87
+ public async setLogger(level: Level) {
88
+ const all: TransportTargetOptions[] = [
89
+ {
90
+ target: 'pino/file',
91
+ level: 'trace',
92
+ options: { destination: this.pathHandler.logPath, mkdir: true },
93
+ },
94
+ {
95
+ target: 'pino/file',
96
+ level: level,
97
+ options: { destination: 1 }, // stdout
98
+ },
99
+ ];
100
+
101
+ setLogger(
102
+ pino.default({
103
+ level: 'trace',
104
+ transport: {
105
+ targets: all,
106
+ },
107
+ }),
108
+ );
109
+ }
110
+
79
111
  /**
80
112
  * Either creates a new instance, or passes the current one.
81
113
  * New instance is created, if path differs, or there is no previous instance.
82
114
  * @param path Project path.
115
+ * @param watchResourceChanges Optional. If true, file changes are watched.
83
116
  * @returns Instance of this class.
84
117
  */
85
- public static async getInstance(path: string): Promise<CommandManager> {
118
+ public static async getInstance(
119
+ path: string,
120
+ options?: CommandManagerOptions,
121
+ ): Promise<CommandManager> {
86
122
  if (
87
123
  CommandManager.instance &&
88
124
  CommandManager.instance.project.basePath !== path
89
125
  ) {
90
- CommandManager.instance = new CommandManager(path);
126
+ CommandManager.instance.project.dispose();
127
+ CommandManager.instance = new CommandManager(path, options);
91
128
  await CommandManager.instance.initialize();
92
129
  }
93
130
  if (!CommandManager.instance) {
94
- CommandManager.instance = new CommandManager(path);
131
+ CommandManager.instance = new CommandManager(path, options);
95
132
  await CommandManager.instance.initialize();
96
133
  }
134
+
135
+ if (options?.logLevel) {
136
+ await CommandManager.instance.setLogger(options?.logLevel);
137
+ }
97
138
  return CommandManager.instance;
98
139
  }
99
140
  }
@@ -13,9 +13,9 @@
13
13
 
14
14
  // node
15
15
  import { basename, join, resolve } from 'node:path';
16
- import { readFile, rm } from 'node:fs/promises';
17
- import { spawnSync } from 'node:child_process';
16
+ import { readFile } from 'node:fs/promises';
18
17
  import { sanitizeSvgBase64 } from '../utils/sanitize-svg.js';
18
+ import { instance } from '@viz-js/viz';
19
19
 
20
20
  import type {
21
21
  BaseResult,
@@ -30,7 +30,7 @@ import { Mutex } from 'async-mutex';
30
30
  import Handlebars from 'handlebars';
31
31
  import { type Project, ResourcesFrom } from '../containers/project.js';
32
32
  import { flattenCardArray } from '../utils/card-utils.js';
33
- import { logger } from '../utils/log-utils.js';
33
+ import { getChildLogger } from '../utils/log-utils.js';
34
34
  import {
35
35
  createCardFacts,
36
36
  createCardTypeFacts,
@@ -43,7 +43,6 @@ import {
43
43
  createWorkflowFacts,
44
44
  } from '../utils/clingo-facts.js';
45
45
  import { CardMetadataUpdater } from '../card-metadata-updater.js';
46
- import { generateRandomString } from '../utils/random.js';
47
46
  import type {
48
47
  CardType,
49
48
  FieldType,
@@ -53,7 +52,8 @@ import type {
53
52
  Workflow,
54
53
  } from '../interfaces/resource-interfaces.js';
55
54
  import { solve, setBaseProgram } from '@cyberismo/node-clingo';
56
- import { lpFiles } from '@cyberismo/resources';
55
+ import { generateReportContent } from '../utils/report.js';
56
+ import { lpFiles, graphvizReport } from '@cyberismo/assets';
57
57
 
58
58
  // Define names for the base programs
59
59
  const BASE_PROGRAM_KEY = 'base';
@@ -61,9 +61,13 @@ const QUERY_LANGUAGE_KEY = 'queryLanguage';
61
61
 
62
62
  // Class that calculates with logic program card / project level calculations.
63
63
  export class Calculate {
64
+ private get logger() {
65
+ return getChildLogger({
66
+ module: 'calculate',
67
+ });
68
+ }
64
69
  private static mutex = new Mutex();
65
70
 
66
- private pythonBinary: string = 'python';
67
71
  constructor(private project: Project) {}
68
72
 
69
73
  // Storage for in-memory program content
@@ -79,7 +83,7 @@ export class Calculate {
79
83
  const modules = await this.generateModules();
80
84
  this.modules = modules; // Store initial modules in logicProgram
81
85
  } catch (error) {
82
- logger.error(`Failed to initialize modules: ${error}`);
86
+ this.logger.error(error, 'Failed to initialize modules');
83
87
  }
84
88
  }
85
89
 
@@ -201,8 +205,9 @@ export class Calculate {
201
205
  content += `${moduleContent}\n`;
202
206
  content += `% SECTION: MODULE_${calculationFile.name}_END\n\n`;
203
207
  } catch (error) {
204
- logger.warn(
205
- `Failed to read module ${calculationFile.name}: ${error}`,
208
+ this.logger.warn(
209
+ error,
210
+ `Failed to read module ${calculationFile.name}`,
206
211
  );
207
212
  }
208
213
  }
@@ -292,43 +297,37 @@ export class Calculate {
292
297
  return parser.parseInput(data.join('\n'));
293
298
  }
294
299
 
295
- //
296
- private async run(
297
- data: {
298
- query?: string;
299
- },
300
- argMode: 'graph' | 'query' = 'query',
301
- ): Promise<string[]> {
302
- if (!data.query) {
303
- throw new Error('Must provide query to run a clingo program');
304
- }
305
-
306
- const res = await Calculate.mutex.runExclusive(async () => {
307
- // For queries, use both base and queryLanguage
308
- const basePrograms =
309
- argMode === 'query'
310
- ? [BASE_PROGRAM_KEY, QUERY_LANGUAGE_KEY]
311
- : BASE_PROGRAM_KEY;
312
-
313
- // Then solve with the program - need to pass the program as parameter
314
- return solve(data.query as string, basePrograms);
315
- });
316
-
317
- logger.trace(
318
- {
319
- query: data.query,
320
- },
321
- `Ran Clingo solve command`,
322
- );
300
+ private async run(query: string): Promise<string[]> {
301
+ try {
302
+ const res = await Calculate.mutex.runExclusive(async () => {
303
+ // For queries, use both base and queryLanguage
304
+ const basePrograms = [BASE_PROGRAM_KEY, QUERY_LANGUAGE_KEY];
305
+
306
+ this.logger.trace(
307
+ {
308
+ clingo: true,
309
+ },
310
+ 'Solving',
311
+ );
323
312
 
324
- if (res && res.answers && res.answers.length > 0) {
325
- logger.trace({
326
- result: res.answers,
313
+ // Then solve with the program - need to pass the program as parameter
314
+ return solve(query, basePrograms);
327
315
  });
328
- return res.answers;
329
- }
330
316
 
331
- throw new Error('Failed to run Clingo solve. No answers returned.');
317
+ if (res && res.answers && res.answers.length > 0) {
318
+ return res.answers;
319
+ }
320
+ throw new Error('Failed to run Clingo solve. No answers returned.');
321
+ } catch (error) {
322
+ this.logger.error(
323
+ {
324
+ error,
325
+ query,
326
+ },
327
+ 'Clingo solve failed',
328
+ );
329
+ throw error;
330
+ }
332
331
  }
333
332
 
334
333
  /**
@@ -337,6 +336,14 @@ export class Calculate {
337
336
  */
338
337
  public async generate(cardKey?: string) {
339
338
  await Calculate.mutex.runExclusive(async () => {
339
+ this.logger.trace(
340
+ {
341
+ clingo: true,
342
+ cardKey,
343
+ },
344
+ 'Generating logic program',
345
+ );
346
+
340
347
  if (!this.modulesInitialized) {
341
348
  await this.initializeModules();
342
349
  this.modulesInitialized = true;
@@ -397,6 +404,13 @@ export class Calculate {
397
404
 
398
405
  // Also store the base program (without query language) for updates
399
406
  this.logicProgram = baseProgram;
407
+ this.logger.trace(
408
+ {
409
+ clingo: true,
410
+ cardKey,
411
+ },
412
+ 'Logic program set',
413
+ );
400
414
  });
401
415
  }
402
416
 
@@ -489,70 +503,40 @@ export class Calculate {
489
503
  * @param timeout Maximum amount of milliseconds clingraph is allowed to run
490
504
  * @returns a base64 encoded image as a string
491
505
  */
492
- public async runGraph(
493
- data: { query?: string; file?: string },
494
- timeout?: number,
495
- ) {
496
- const clingoOutput = await this.run(data, 'graph');
497
-
498
- // unlikely we ever get a collision
499
- const randomId = generateRandomString(36, 20);
500
-
501
- const clingGraphArgs = [
502
- '--out=render',
503
- '--format=svg',
504
- '--type=digraph',
505
- `--name-format=${randomId}`,
506
- `--dir=${this.project.paths.tempFolder}`,
507
- ];
508
-
509
- // python is only used for windows
510
- const pythonArgs = [
511
- '-c',
512
- `from clingraph import main; import sys; sys.argv = ["sys.argv[0]", ${clingGraphArgs
513
- .map((arg) => `'${arg.replace(/\\/g, '\\\\')}'`)
514
- .join(',')}]; sys.exit(main())`,
515
- ];
516
-
517
- const clingraph = spawnSync(this.pythonBinary, pythonArgs, {
518
- encoding: 'utf8',
519
- // below looks like it could be replaced by just joining dots, but
520
- // it breaks it because elements contain newlines, which must be
521
- // replaced by dots
522
- input: clingoOutput.join('\n').replaceAll('\n', '.') + '.',
523
- timeout,
524
- maxBuffer: 1024 * 1024 * 100,
525
- });
526
-
527
- if (clingraph.status !== 0) {
528
- throw new Error(`Graph: Failed to run clingraph ${clingraph.stderr}`);
529
- }
530
-
531
- const filePath = join(this.project.paths.tempFolder, randomId);
532
-
533
- let fileData;
534
- try {
535
- fileData = await readFile(filePath + '.svg');
536
- } catch (e) {
537
- throw new Error(
538
- `Graph: Failed to read image file after generating graph: ${e}`,
539
- );
540
- } finally {
541
- await rm(filePath, { force: true });
542
- await rm(filePath + '.svg', { force: true });
543
- }
506
+ public async runGraph(model: string, view: string) {
507
+ this.logger.trace(
508
+ {
509
+ model,
510
+ view,
511
+ },
512
+ 'Running graph',
513
+ );
544
514
 
545
- // Sanitizing SVG before returning it
546
- return sanitizeSvgBase64(fileData);
515
+ // Let's run the clingraph query
516
+ const result = await generateReportContent({
517
+ calculate: this,
518
+ contentTemplate: graphvizReport.content,
519
+ queryTemplate: graphvizReport.query,
520
+ options: {
521
+ model: model,
522
+ view: view,
523
+ },
524
+ graph: true,
525
+ });
526
+ return sanitizeSvgBase64(
527
+ (await instance()).renderString(result, {
528
+ format: 'svg',
529
+ }),
530
+ );
547
531
  }
548
532
 
549
533
  /**
550
534
  * Runs a logic program using clingo.
551
- * @param filePath Path to a query file to be run in relation to current working directory
535
+ * @param query Logic program to be run
552
536
  * @returns parsed program output
553
537
  */
554
- public async runLogicProgram(data: { query?: string; file?: string }) {
555
- const clingoOutput = await this.run(data);
538
+ public async runLogicProgram(query: string) {
539
+ const clingoOutput = await this.run(query);
556
540
 
557
541
  return this.parseClingoResult(clingoOutput);
558
542
  }
@@ -574,12 +558,12 @@ export class Calculate {
574
558
  content = compiled(options);
575
559
  }
576
560
 
577
- const clingoOutput = await this.run(
578
- {
579
- query: content,
580
- },
581
- 'query',
582
- );
561
+ if (!content) {
562
+ throw new Error(`Query file ${queryName} not found`);
563
+ }
564
+
565
+ this.logger.trace({ queryName }, 'Running query');
566
+ const clingoOutput = await this.run(content);
583
567
 
584
568
  const result = await this.parseClingoResult(clingoOutput);
585
569
 
@@ -196,16 +196,17 @@ export class Export {
196
196
  );
197
197
 
198
198
  let asciiDocContent = '';
199
- const projectPath = this.project.basePath;
199
+ const project = this.project;
200
200
  try {
201
201
  const { evaluateMacros } = await import('../macros/index.js');
202
202
  asciiDocContent = await evaluateMacros(
203
203
  cardDetailsResponse.content || '',
204
204
  {
205
205
  mode: 'static',
206
- projectPath,
206
+ project,
207
207
  cardKey: card.key,
208
208
  },
209
+ this.calculateCmd,
209
210
  );
210
211
  } catch (error) {
211
212
  asciiDocContent = `Macro error: ${error instanceof Error ? error.message : 'Unknown error'}\n\n${asciiDocContent}`;
@@ -14,7 +14,10 @@
14
14
  import type { CardType } from '../interfaces/resource-interfaces.js';
15
15
  import { type Create, Validate } from './index.js';
16
16
  import { ModuleManager } from '../module-manager.js';
17
- import type { ModuleSettingOptions } from '../interfaces/project-interfaces.js';
17
+ import type {
18
+ Credentials,
19
+ ModuleSettingOptions,
20
+ } from '../interfaces/project-interfaces.js';
18
21
  import type { Project } from '../containers/project.js';
19
22
  import { readCsvFile } from '../utils/csv.js';
20
23
  import { resourceName } from '../utils/resource-utils.js';
@@ -26,7 +29,7 @@ export class Import {
26
29
  private project: Project,
27
30
  private createCmd: Create,
28
31
  ) {
29
- this.moduleManager = new ModuleManager(this.project, this);
32
+ this.moduleManager = new ModuleManager(this.project);
30
33
  }
31
34
 
32
35
  /**
@@ -142,28 +145,25 @@ export class Import {
142
145
  );
143
146
  }
144
147
 
145
- // Add module as a dependency.
146
- return this.project.importModule({
148
+ const moduleSettings = {
147
149
  name: modulePrefix,
148
150
  branch: options ? options.branch : undefined,
149
151
  private: options ? options.private : undefined,
150
152
  location: gitModule ? source : `file:${source}`,
151
- });
152
- }
153
+ };
153
154
 
154
- /**
155
- * Updates all imported modules.
156
- */
157
- public async updateAllModules() {
158
- return this.moduleManager.update();
155
+ // Fetch module dependencies.
156
+ await this.moduleManager.updateModule(moduleSettings, options?.credentials);
157
+
158
+ // Add module as a dependency.
159
+ return this.project.importModule(moduleSettings);
159
160
  }
160
161
 
161
162
  /**
162
- * Updates 'moduleName' module from its source.
163
- * Modules using gitUrl, are first copied to .temp
164
- * @param moduleName module name (prefix) to update
163
+ * Updates all imported modules.
164
+ * @param credentials Optional credentials for private modules.
165
165
  */
166
- public async updateExistingModule(moduleName: string) {
167
- await this.moduleManager.importFileModule(moduleName);
166
+ public async updateAllModules(credentials?: Credentials) {
167
+ return this.moduleManager.updateModules(credentials);
168
168
  }
169
169
  }
@@ -15,7 +15,6 @@ import { Calculate } from './calculate.js';
15
15
  import { Create } from './create.js';
16
16
  import { Edit } from './edit.js';
17
17
  import { Export } from './export.js';
18
- import { ExportSite } from './export-site.js';
19
18
  import { Import } from './import.js';
20
19
  import { Move } from './move.js';
21
20
  import { Remove } from './remove.js';
@@ -30,7 +29,6 @@ export {
30
29
  Create,
31
30
  Edit,
32
31
  Export,
33
- ExportSite,
34
32
  Import,
35
33
  Move,
36
34
  Remove,
@@ -188,8 +188,8 @@ export class Remove {
188
188
  if (!module) {
189
189
  throw new Error(`Module '${moduleName}' not found`);
190
190
  }
191
- await deleteDir(module.path);
192
191
  await this.project.removeModule(moduleName);
192
+ await deleteDir(module.path);
193
193
  }
194
194
 
195
195
  /**