@cyberismo/data-handler 0.0.13 → 0.0.14

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 (77) hide show
  1. package/dist/command-handler.js +3 -1
  2. package/dist/command-handler.js.map +1 -1
  3. package/dist/commands/create.d.ts +3 -3
  4. package/dist/commands/create.js +7 -22
  5. package/dist/commands/create.js.map +1 -1
  6. package/dist/commands/edit.d.ts +12 -11
  7. package/dist/commands/edit.js +41 -16
  8. package/dist/commands/edit.js.map +1 -1
  9. package/dist/commands/fetch.js +2 -1
  10. package/dist/commands/fetch.js.map +1 -1
  11. package/dist/commands/remove.js +6 -5
  12. package/dist/commands/remove.js.map +1 -1
  13. package/dist/commands/rename.d.ts +1 -0
  14. package/dist/commands/rename.js +11 -0
  15. package/dist/commands/rename.js.map +1 -1
  16. package/dist/commands/show.js +2 -12
  17. package/dist/commands/show.js.map +1 -1
  18. package/dist/commands/validate.js +1 -1
  19. package/dist/commands/validate.js.map +1 -1
  20. package/dist/containers/project/calculation-engine.js +17 -17
  21. package/dist/containers/project/calculation-engine.js.map +1 -1
  22. package/dist/containers/project.d.ts +2 -1
  23. package/dist/containers/project.js +5 -1
  24. package/dist/containers/project.js.map +1 -1
  25. package/dist/interfaces/folder-content-interfaces.d.ts +10 -4
  26. package/dist/interfaces/folder-content-interfaces.js +5 -3
  27. package/dist/interfaces/folder-content-interfaces.js.map +1 -1
  28. package/dist/interfaces/project-interfaces.d.ts +11 -9
  29. package/dist/interfaces/project-interfaces.js +10 -8
  30. package/dist/interfaces/project-interfaces.js.map +1 -1
  31. package/dist/interfaces/resource-interfaces.d.ts +10 -1
  32. package/dist/interfaces/resource-interfaces.js.map +1 -1
  33. package/dist/resources/calculation-resource.d.ts +71 -0
  34. package/dist/resources/calculation-resource.js +130 -0
  35. package/dist/resources/calculation-resource.js.map +1 -0
  36. package/dist/resources/create-defaults.d.ts +13 -6
  37. package/dist/resources/create-defaults.js +19 -5
  38. package/dist/resources/create-defaults.js.map +1 -1
  39. package/dist/resources/file-resource.js +9 -3
  40. package/dist/resources/file-resource.js.map +1 -1
  41. package/dist/resources/folder-resource.d.ts +2 -2
  42. package/dist/resources/folder-resource.js.map +1 -1
  43. package/dist/resources/resource-object.js +14 -2
  44. package/dist/resources/resource-object.js.map +1 -1
  45. package/dist/utils/constants.js +1 -0
  46. package/dist/utils/constants.js.map +1 -1
  47. package/dist/utils/error-utils.d.ts +34 -0
  48. package/dist/utils/error-utils.js +56 -0
  49. package/dist/utils/error-utils.js.map +1 -0
  50. package/dist/utils/log-utils.d.ts +0 -27
  51. package/dist/utils/log-utils.js +0 -58
  52. package/dist/utils/log-utils.js.map +1 -1
  53. package/dist/utils/user-preferences.js +6 -3
  54. package/dist/utils/user-preferences.js.map +1 -1
  55. package/package.json +2 -2
  56. package/src/command-handler.ts +3 -1
  57. package/src/commands/create.ts +10 -28
  58. package/src/commands/edit.ts +51 -26
  59. package/src/commands/fetch.ts +2 -1
  60. package/src/commands/remove.ts +3 -2
  61. package/src/commands/rename.ts +20 -0
  62. package/src/commands/show.ts +1 -13
  63. package/src/commands/validate.ts +1 -1
  64. package/src/containers/project/calculation-engine.ts +22 -20
  65. package/src/containers/project.ts +4 -1
  66. package/src/interfaces/folder-content-interfaces.ts +16 -4
  67. package/src/interfaces/project-interfaces.ts +12 -9
  68. package/src/interfaces/resource-interfaces.ts +10 -0
  69. package/src/resources/calculation-resource.ts +171 -0
  70. package/src/resources/create-defaults.ts +21 -5
  71. package/src/resources/file-resource.ts +9 -3
  72. package/src/resources/folder-resource.ts +2 -2
  73. package/src/resources/resource-object.ts +19 -7
  74. package/src/utils/constants.ts +1 -0
  75. package/src/utils/error-utils.ts +62 -0
  76. package/src/utils/log-utils.ts +0 -68
  77. package/src/utils/user-preferences.ts +7 -3
@@ -0,0 +1,34 @@
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
+ * Returns error message string from an Error object.
15
+ * @param error Error object
16
+ * @returns Error message.
17
+ */
18
+ export declare function errorFunction(error: unknown): string;
19
+ /**
20
+ * Same as 'errorFunction' but can do automatic replacement of the error message string.
21
+ * @param message Error message
22
+ * @param toReplace replacement substring
23
+ * @param replaceWith string that 'toReplace' is replaced with.
24
+ * @returns Modified error message.
25
+ */
26
+ export declare function errorMessage(message: string, toReplace?: string, replaceWith?: string): string;
27
+ /**
28
+ * Type guard to check if an error object has a code property.
29
+ * @param error The error object to check
30
+ * @returns true if the error has a code property
31
+ */
32
+ export declare function hasCode(error: unknown): error is Error & {
33
+ code: string;
34
+ };
@@ -0,0 +1,56 @@
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
+ * Returns error message string from an Error object.
15
+ * @param error Error object
16
+ * @returns Error message.
17
+ */
18
+ export function errorFunction(error) {
19
+ if (error instanceof Error) {
20
+ const err = error;
21
+ return errorMessage(`${err.message}`);
22
+ }
23
+ else if (typeof error === 'string') {
24
+ return errorMessage(`${error}`);
25
+ }
26
+ else {
27
+ return `errorFunction called without an error object. Actual object is ${JSON.stringify(error)}`;
28
+ }
29
+ }
30
+ /**
31
+ * Same as 'errorFunction' but can do automatic replacement of the error message string.
32
+ * @param message Error message
33
+ * @param toReplace replacement substring
34
+ * @param replaceWith string that 'toReplace' is replaced with.
35
+ * @returns Modified error message.
36
+ */
37
+ export function errorMessage(message, toReplace, replaceWith) {
38
+ let errorMessage = message;
39
+ if (toReplace && replaceWith) {
40
+ errorMessage = message.replace(toReplace, replaceWith);
41
+ }
42
+ return `${errorMessage}`;
43
+ }
44
+ /**
45
+ * Type guard to check if an error object has a code property.
46
+ * @param error The error object to check
47
+ * @returns true if the error has a code property
48
+ */
49
+ export function hasCode(error) {
50
+ return (error instanceof Error &&
51
+ typeof error === 'object' &&
52
+ error !== null &&
53
+ 'code' in error &&
54
+ typeof error.code === 'string');
55
+ }
56
+ //# sourceMappingURL=error-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-utils.js","sourceRoot":"","sources":["../../src/utils/error-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;EAWE;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAU,KAAK,CAAC;QACzB,OAAO,YAAY,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,kEAAkE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IACnG,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,SAAkB,EAClB,WAAoB;IAEpB,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,YAAY,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,CACL,KAAK,YAAY,KAAK;QACtB,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC/B,CAAC;AACJ,CAAC"}
@@ -24,30 +24,3 @@ export declare function getLogger(): Logger;
24
24
  export declare function getChildLogger(context: {
25
25
  module: string;
26
26
  } & Record<string, unknown>, options?: ChildLoggerOptions): Logger;
27
- /**
28
- * Returns error message string from an Error object.
29
- * @param error Error object
30
- * @returns Error message.
31
- */
32
- export declare function errorFunction(error: unknown): string;
33
- /**
34
- * Same as 'errorFunction' but can do automatic replacement fof the error message string.
35
- * @param message Error message
36
- * @param toReplace replacement substring
37
- * @param replaceWith string that 'toReplace' is replaced with.
38
- * @returns Modified error message.
39
- */
40
- export declare function errorMessage(message: string, toReplace?: string, replaceWith?: string): string;
41
- /**
42
- * Logs error from Error object.
43
- * @param error potentially an Error object. When exceptions are raised, they are typically Error objects.
44
- */
45
- export declare function logError(error: unknown): void;
46
- /**
47
- * Log error message in RED. Certain parts of messages can be replaced.
48
- * This is useful, if including a message from external sources, and want to reduce the verbosity of the message.
49
- * @param message Error message to log.
50
- * @param toReplace String to look for.
51
- * @param replaceWith Replace 'toReplace' with this. Only replaces first instance of 'toReplace'.
52
- */
53
- export declare function logErrorMessage(message: string, toReplace?: string, replaceWith?: string): void;
@@ -31,62 +31,4 @@ export function getLogger() {
31
31
  export function getChildLogger(context, options) {
32
32
  return _logger.child(context, options);
33
33
  }
34
- /**
35
- * Returns error message string from an Error object.
36
- * @param error Error object
37
- * @returns Error message.
38
- */
39
- export function errorFunction(error) {
40
- if (error instanceof Error) {
41
- const err = error;
42
- return errorMessage(`${err.message}`);
43
- }
44
- else if (typeof error === 'string') {
45
- return errorMessage(`${error}`);
46
- }
47
- else {
48
- return `${logError.name} called without an error object. Actual object is ${JSON.stringify(error)}`;
49
- }
50
- }
51
- /**
52
- * Same as 'errorFunction' but can do automatic replacement fof the error message string.
53
- * @param message Error message
54
- * @param toReplace replacement substring
55
- * @param replaceWith string that 'toReplace' is replaced with.
56
- * @returns Modified error message.
57
- */
58
- export function errorMessage(message, toReplace, replaceWith) {
59
- let errorMessage = message;
60
- if (toReplace && replaceWith) {
61
- errorMessage = message.replace(toReplace, replaceWith);
62
- }
63
- return `${errorMessage}`;
64
- }
65
- /**
66
- * Logs error from Error object.
67
- * @param error potentially an Error object. When exceptions are raised, they are typically Error objects.
68
- */
69
- export function logError(error) {
70
- if (error instanceof Error) {
71
- const err = error;
72
- logErrorMessage(`${err.message}`);
73
- }
74
- else {
75
- console.error(`${logError.name} called without an error object. Actual object is ${JSON.stringify(error)}`);
76
- }
77
- }
78
- /**
79
- * Log error message in RED. Certain parts of messages can be replaced.
80
- * This is useful, if including a message from external sources, and want to reduce the verbosity of the message.
81
- * @param message Error message to log.
82
- * @param toReplace String to look for.
83
- * @param replaceWith Replace 'toReplace' with this. Only replaces first instance of 'toReplace'.
84
- */
85
- export function logErrorMessage(message, toReplace, replaceWith) {
86
- let errorMessage = message;
87
- if (toReplace && replaceWith) {
88
- errorMessage = message.replace(toReplace, replaceWith);
89
- }
90
- console.error(`${errorMessage}`);
91
- }
92
34
  //# sourceMappingURL=log-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"log-utils.js","sourceRoot":"","sources":["../../src/utils/log-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AACF,OAAO,IAA8C,MAAM,MAAM,CAAC;AAElE,2HAA2H;AAC3H,2BAA2B;AAC3B,IAAI,OAAO,GAAW,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC;AACD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAqD,EACrD,OAA4B;IAE5B,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AACD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAU,KAAK,CAAC;QACzB,OAAO,YAAY,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,QAAQ,CAAC,IAAI,qDAAqD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IACtG,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,SAAkB,EAClB,WAAoB;IAEpB,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,YAAY,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAU,KAAK,CAAC;QACzB,eAAe,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CACX,GAAG,QAAQ,CAAC,IAAI,qDAAqD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,SAAkB,EAClB,WAAoB;IAEpB,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,EAAE,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"log-utils.js","sourceRoot":"","sources":["../../src/utils/log-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AACF,OAAO,IAA8C,MAAM,MAAM,CAAC;AAElE,2HAA2H;AAC3H,2BAA2B;AAC3B,IAAI,OAAO,GAAW,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AACD;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC;AACD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAqD,EACrD,OAA4B;IAE5B,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC"}
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { dirname } from 'node:path';
13
13
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
14
+ import { hasCode } from './error-utils.js';
14
15
  import { formatJson } from './json.js';
15
16
  import { getChildLogger } from '../utils/log-utils.js';
16
17
  /**
@@ -93,16 +94,18 @@ export class UserPreferences {
93
94
  });
94
95
  }
95
96
  catch (error) {
96
- if (error instanceof Error) {
97
- const err = error;
97
+ if (hasCode(error)) {
98
98
  // If file already exists (EEXIST), that's fine - we'll use the existing file
99
- if (err?.code !== 'EEXIST') {
99
+ if (error.code !== 'EEXIST') {
100
100
  throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`);
101
101
  }
102
102
  else {
103
103
  this.logger.warn('Preferences file already exists');
104
104
  }
105
105
  }
106
+ else {
107
+ throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`);
108
+ }
106
109
  }
107
110
  }
108
111
  get logger() {
@@ -1 +1 @@
1
- {"version":3,"file":"user-preferences.js","sourceRoot":"","sources":["../../src/utils/user-preferences.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-preferences.js","sourceRoot":"","sources":["../../src/utils/user-preferences.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cyberismo/data-handler",
3
3
  "description": "Command handler for cards and web service",
4
- "version": "0.0.13",
4
+ "version": "0.0.14",
5
5
  "author": "sami.merila@cyberismo.com",
6
6
  "license": "AGPL-3.0",
7
7
  "homepage": "https://github.com/CyberismoCom/cyberismo",
@@ -46,7 +46,7 @@
46
46
  "vega": "^6.1.2",
47
47
  "vega-lite": "^6.3.1",
48
48
  "write-json-file": "^7.0.0",
49
- "@cyberismo/assets": "0.0.13",
49
+ "@cyberismo/assets": "0.0.14",
50
50
  "@cyberismo/node-clingo": "1.3.0"
51
51
  },
52
52
  "type": "module",
@@ -50,7 +50,7 @@ import type { UpdateOperations } from './resources/resource-object.js';
50
50
  import { Project } from './containers/project.js';
51
51
 
52
52
  import { pathExists, resolveTilde } from './utils/file-utils.js';
53
- import { errorFunction } from './utils/log-utils.js';
53
+ import { errorFunction } from './utils/error-utils.js';
54
54
  import { readJsonFile } from './utils/json.js';
55
55
  import { resourceName } from './utils/resource-utils.js';
56
56
 
@@ -736,6 +736,7 @@ export class Commands {
736
736
  case 'cards':
737
737
  promise = this.commands!.showCmd.showCards();
738
738
  break;
739
+ case 'calculation':
739
740
  case 'cardType':
740
741
  case 'fieldType':
741
742
  case 'graphView':
@@ -746,6 +747,7 @@ export class Commands {
746
747
  case 'workflow':
747
748
  promise = this.commands!.showCmd.showResource(detail, options.showUse);
748
749
  break;
750
+ case 'calculations':
749
751
  case 'cardTypes':
750
752
  case 'fieldTypes':
751
753
  case 'graphModels':
@@ -20,7 +20,7 @@ import {
20
20
  writeFile,
21
21
  } from 'node:fs/promises';
22
22
 
23
- import { errorFunction } from '../utils/log-utils.js';
23
+ import { errorFunction } from '../utils/error-utils.js';
24
24
  import { Project } from '../containers/project.js';
25
25
  import { Validate } from './index.js';
26
26
 
@@ -35,6 +35,7 @@ import type { Card, ProjectFile } from '../interfaces/project-interfaces.js';
35
35
  import { resourceName, resourceNameToString } from '../utils/resource-utils.js';
36
36
  import { writeJsonFile } from '../utils/json.js';
37
37
 
38
+ import { CalculationResource } from '../resources/calculation-resource.js';
38
39
  import { CardTypeResource } from '../resources/card-type-resource.js';
39
40
  import { FieldTypeResource } from '../resources/field-type-resource.js';
40
41
  import { GraphModelResource } from '../resources/graph-model-resource.js';
@@ -213,34 +214,15 @@ export class Create {
213
214
  }
214
215
 
215
216
  /**
216
- * Creates a calculation file.
217
- * @param fileName name for the calculation file (without .lp extension)
217
+ * Creates a calculation resource.
218
+ * @param calculationName name for the calculation resource
218
219
  */
219
- public async createCalculation(fileName: string) {
220
- const calculationFolder = this.project.paths.calculationProjectFolder;
221
-
222
- await mkdir(calculationFolder, { recursive: true });
223
-
224
- const calculationFileName = fileName.endsWith('.lp')
225
- ? fileName
226
- : `${fileName}.lp`;
227
- const calculationFilePath = join(calculationFolder, calculationFileName);
228
-
229
- const calculationContent = `% Calculation file: ${calculationFileName}
230
- % Add your logic programming rules here
231
- `;
232
-
233
- await writeFile(calculationFilePath, calculationContent, { flag: 'wx' });
234
-
235
- // add to cache manually
236
- // TODO: remove once calculations are a proper resource
237
- const resourceName = `${this.project.projectPrefix}/calculations/${fileName.replace('.lp', '')}`;
238
- const resource = {
239
- name: resourceName,
240
- path: calculationFolder,
241
- };
242
-
243
- this.project.addResource(resource, {} as JSON);
220
+ public async createCalculation(calculationName: string) {
221
+ const calculation = new CalculationResource(
222
+ this.project,
223
+ resourceName(calculationName),
224
+ );
225
+ await calculation.create();
244
226
  }
245
227
 
246
228
  /**
@@ -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
  // node
@@ -16,18 +17,19 @@ import { homedir } from 'node:os';
16
17
  import { spawnSync } from 'node:child_process';
17
18
 
18
19
  import { ActionGuard } from '../permissions/action-guard.js';
20
+ import { CalculationResource } from '../resources/calculation-resource.js';
21
+ import { FolderResource } from '../resources/folder-resource.js';
22
+ import { Project } from '../containers/project.js';
23
+ import { propertyName } from '../interfaces/folder-content-interfaces.js';
24
+ import { resourceNameToString } from '../utils/resource-utils.js';
25
+ import { UserPreferences } from '../utils/user-preferences.js';
26
+
27
+ import type { ContentPropertyName } from '../interfaces/folder-content-interfaces.js';
19
28
  import type {
20
29
  MetadataContent,
21
30
  ResourceFolderType,
22
31
  } from '../interfaces/project-interfaces.js';
23
- import { Project } from '../containers/project.js';
24
- import { UserPreferences } from '../utils/user-preferences.js';
25
- import {
26
- type ResourceName,
27
- resourceNameToString,
28
- } from '../utils/resource-utils.js';
29
- import { FolderResource } from '../resources/folder-resource.js';
30
- import { writeFile } from 'node:fs/promises';
32
+ import type { ResourceName } from '../utils/resource-utils.js';
31
33
 
32
34
  export class Edit {
33
35
  private project: Project;
@@ -61,15 +63,21 @@ export class Edit {
61
63
  `Resource '${resourceNameString}' does not exist in the project`,
62
64
  );
63
65
  }
64
- await writeFile(
65
- join(
66
- this.project.paths.calculationProjectFolder,
67
- resourceName.identifier + '.lp',
68
- ),
69
- changedContent,
66
+ const calculationResource = new CalculationResource(
67
+ this.project,
68
+ resourceName,
69
+ );
70
+ const contentUpdateKey = {
71
+ key: 'content',
72
+ subKey: 'calculation',
73
+ };
74
+ await calculationResource.update(
75
+ // TODO: Let's fix this while we get rid of updating filenames directly a bit later.
76
+ contentUpdateKey as unknown as ContentPropertyName,
70
77
  {
71
- encoding: 'utf-8',
72
- flag: 'r+',
78
+ name: 'change',
79
+ target: resourceNameString,
80
+ to: changedContent,
73
81
  },
74
82
  );
75
83
  }
@@ -201,6 +209,23 @@ export class Edit {
201
209
  `Resource '${resourceNameString}' is not a folder resource`,
202
210
  );
203
211
  }
204
- return resource.updateFile(fileName, changedContent);
212
+
213
+ // TODO: The caller should not pass filename, but content type
214
+ // Once that is in place, this check can be removed
215
+ const propName: ContentPropertyName | undefined = propertyName(fileName);
216
+ if (!propName) {
217
+ throw new Error(`File '${fileName}' is not allowed`);
218
+ }
219
+
220
+ const contentUpdateKey = {
221
+ key: 'content',
222
+ subKey: propName,
223
+ };
224
+ // TODO: Let's fix this while we get rid of updating filenames directly a bit later.
225
+ return resource.update(contentUpdateKey as unknown as ContentPropertyName, {
226
+ name: 'change',
227
+ target: '',
228
+ to: changedContent,
229
+ });
205
230
  }
206
231
  }
@@ -18,7 +18,8 @@ import type { Project } from '../containers/project.js';
18
18
  import { writeJsonFile } from '../utils/json.js';
19
19
  import { validateJson } from '../utils/validate.js';
20
20
  import { type ModuleSetting } from '../interfaces/project-interfaces.js';
21
- import { errorFunction, getChildLogger } from '../utils/log-utils.js';
21
+ import { errorFunction } from '../utils/error-utils.js';
22
+ import { getChildLogger } from '../utils/log-utils.js';
22
23
 
23
24
  const FETCH_TIMEOUT = 30000; // 30s timeout for fetching a hub file.
24
25
  const MAX_RESPONSE_SIZE = 1024 * 1024; // 1MB limit for safety
@@ -35,6 +35,7 @@ export class Remove {
35
35
  // True, if resource is a project resource
36
36
  private projectResource(type: RemovableResourceTypes): boolean {
37
37
  return (
38
+ type === 'calculation' ||
38
39
  type === 'cardType' ||
39
40
  type === 'fieldType' ||
40
41
  type === 'graphModel' ||
@@ -229,12 +230,12 @@ export class Remove {
229
230
  if (type === 'attachment')
230
231
  return this.removeAttachment(targetName, rest[0]);
231
232
  else if (type === 'card') return this.removeCard(targetName);
233
+ else if (type === 'hub') return this.removeHubLocation(targetName);
234
+ else if (type === 'label') return this.removeLabel(targetName, rest[0]);
232
235
  else if (type === 'link')
233
236
  return this.removeLink(targetName, rest[0], rest[1], rest.at(2));
234
237
  else if (type === 'module')
235
238
  return this.moduleManager.removeModule(targetName);
236
- else if (type === 'label') return this.removeLabel(targetName, rest[0]);
237
- else if (type === 'hub') return this.removeHubLocation(targetName);
238
239
  }
239
240
  throw new Error(`Unknown resource type '${type}'`);
240
241
  }
@@ -22,6 +22,7 @@ import { type Project, ResourcesFrom } from '../containers/project.js';
22
22
  import { resourceName } from '../utils/resource-utils.js';
23
23
  import { Template } from '../containers/template.js';
24
24
 
25
+ import { CalculationResource } from '../resources/calculation-resource.js';
25
26
  import { CardTypeResource } from '../resources/card-type-resource.js';
26
27
  import { FieldTypeResource } from '../resources/field-type-resource.js';
27
28
  import { GraphModelResource } from '../resources/graph-model-resource.js';
@@ -192,6 +193,17 @@ export class Rename {
192
193
  return cardType.rename(resourceName(this.updateResourceName(cardTypeName)));
193
194
  }
194
195
 
196
+ // Rename calculations.
197
+ private async updateCalculation(calculationName: string) {
198
+ const calculation = new CalculationResource(
199
+ this.project,
200
+ resourceName(calculationName),
201
+ );
202
+ return calculation.rename(
203
+ resourceName(this.updateResourceName(calculationName)),
204
+ );
205
+ }
206
+
195
207
  // Updates field type's metadata.
196
208
  private async updateFieldTypeMetadata(fieldTypeName: string) {
197
209
  const fieldType = new FieldTypeResource(
@@ -341,6 +353,14 @@ export class Rename {
341
353
  }
342
354
  console.info('Updated templates');
343
355
 
356
+ const calculations = await this.project.calculations(
357
+ ResourcesFrom.localOnly,
358
+ );
359
+ for (const calculation of calculations) {
360
+ await this.updateCalculation(calculation.name);
361
+ }
362
+ console.info('Updated calculations');
363
+
344
364
  // Rename all local template cards.
345
365
  templates = await this.project.templates(ResourcesFrom.localOnly);
346
366
  for (const template of templates) {
@@ -16,7 +16,7 @@ import { existsSync, readFileSync } from 'node:fs';
16
16
  import { homedir } from 'node:os';
17
17
  import { join, resolve } from 'node:path';
18
18
  import { spawn } from 'node:child_process';
19
- import { readFile, writeFile } from 'node:fs/promises';
19
+ import { writeFile } from 'node:fs/promises';
20
20
 
21
21
  import { MODULE_LIST_FULL_PATH } from './fetch.js';
22
22
 
@@ -47,7 +47,6 @@ import { Project, type ResourcesFrom } from '../containers/project.js';
47
47
  import {
48
48
  type ResourceName,
49
49
  resourceName,
50
- resourceNameToPath,
51
50
  resourceNameToString,
52
51
  } from '../utils/resource-utils.js';
53
52
  import { TemplateResource } from '../resources/template-resource.js';
@@ -571,17 +570,6 @@ export class Show {
571
570
  name: string,
572
571
  showUse: boolean = false,
573
572
  ): Promise<ResourceContent | undefined> {
574
- // TODO: remove this workaround once calculations are implemented as a resource class
575
- if (resourceName(name).type === 'calculations') {
576
- const nameObj = resourceName(name);
577
- const path = resourceNameToPath(this.project, nameObj, '.lp');
578
- return {
579
- name,
580
- displayName: nameObj.identifier,
581
- calculation: await readFile(path, 'utf-8'),
582
- };
583
- }
584
-
585
573
  const strictNameCheck = true;
586
574
  const resource = Project.resourceObject(
587
575
  this.project,
@@ -36,7 +36,7 @@ import type {
36
36
  ResourceContent,
37
37
  Workflow,
38
38
  } from '../interfaces/resource-interfaces.js';
39
- import { errorFunction } from '../utils/log-utils.js';
39
+ import { errorFunction } from '../utils/error-utils.js';
40
40
  import { isTemplateCard } from '../utils/card-utils.js';
41
41
  import { pathExists } from '../utils/file-utils.js';
42
42
  import { Project } from '../containers/project.js';
@@ -12,8 +12,7 @@
12
12
  */
13
13
 
14
14
  // node
15
- import { basename, join, resolve } from 'node:path';
16
- import { readFile, writeFile } from 'node:fs/promises';
15
+ import { writeFile } from 'node:fs/promises';
17
16
 
18
17
  import { sanitizeSvgBase64 } from '../../utils/sanitize-svg.js';
19
18
  import { instance } from '@viz-js/viz';
@@ -26,7 +25,6 @@ import type {
26
25
  } from '../../types/queries.js';
27
26
  import type { Card, Context } from '../../interfaces/project-interfaces.js';
28
27
  import ClingoParser from '../../utils/clingo-parser.js';
29
- import { pathExists } from '../../utils/file-utils.js';
30
28
  import { Mutex } from 'async-mutex';
31
29
  import Handlebars from 'handlebars';
32
30
  import { type Project, ResourcesFrom } from '../../containers/project.js';
@@ -52,6 +50,7 @@ import type {
52
50
  TemplateMetadata,
53
51
  Workflow,
54
52
  } from '../../interfaces/resource-interfaces.js';
53
+ import { CalculationResource } from '../../resources/calculation-resource.js';
55
54
  import {
56
55
  removeAllPrograms,
57
56
  solve,
@@ -62,6 +61,7 @@ import {
62
61
  import { generateReportContent } from '../../utils/report.js';
63
62
  import { lpFiles, graphvizReport } from '@cyberismo/assets';
64
63
  import {
64
+ resourceName,
65
65
  type ResourceName,
66
66
  resourceNameToString,
67
67
  } from '../../utils/resource-utils.js';
@@ -123,7 +123,7 @@ export class CalculationEngine {
123
123
  query?: QueryName,
124
124
  ) {
125
125
  let logicProgram = query ? this.queryContent(query) : '';
126
- logicProgram += await buildProgram('', programs);
126
+ logicProgram += buildProgram('', programs);
127
127
  await writeFile(destination, logicProgram);
128
128
  }
129
129
 
@@ -259,26 +259,28 @@ export class CalculationEngine {
259
259
  const calculations = await this.project.calculations(ResourcesFrom.all);
260
260
 
261
261
  for (const calculationFile of calculations) {
262
- if (calculationFile.path) {
263
- const moduleLogicFile = resolve(
264
- join(calculationFile.path, basename(calculationFile.name)),
262
+ try {
263
+ const calculationResource = new CalculationResource(
264
+ this.project,
265
+ resourceName(calculationFile.name),
265
266
  );
266
-
267
- const filePath = moduleLogicFile.endsWith('.lp')
268
- ? moduleLogicFile
269
- : moduleLogicFile + '.lp';
270
-
271
- if (pathExists(filePath)) {
272
- try {
273
- const moduleContent = await readFile(filePath, 'utf-8');
274
- setProgram(calculationFile.name, moduleContent, [ALL_CATEGORY]);
275
- } catch (error) {
276
- this.logger.warn(
277
- error,
278
- `Failed to read calculation ${calculationFile.name}`,
267
+ if (calculationResource) {
268
+ const resource = await calculationResource.show();
269
+ if (!resource?.content.calculation) {
270
+ this.logger.info(
271
+ `Calculation resource '${resource.name}' does not have calculation file`,
279
272
  );
273
+ continue;
280
274
  }
275
+ setProgram(calculationFile.name, resource.content.calculation, [
276
+ ALL_CATEGORY,
277
+ ]);
281
278
  }
279
+ } catch (error) {
280
+ this.logger.warn(
281
+ error,
282
+ `Failed to read calculation ${calculationFile.name}`,
283
+ );
282
284
  }
283
285
  }
284
286
  }