@cyberismo/data-handler 0.0.20 → 0.0.22

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 (177) hide show
  1. package/dist/command-handler.js +13 -24
  2. package/dist/command-handler.js.map +1 -1
  3. package/dist/command-manager.d.ts +21 -6
  4. package/dist/command-manager.js +34 -32
  5. package/dist/command-manager.js.map +1 -1
  6. package/dist/commands/calculate.js +101 -46
  7. package/dist/commands/calculate.js.map +1 -1
  8. package/dist/commands/create.js +420 -320
  9. package/dist/commands/create.js.map +1 -1
  10. package/dist/commands/edit.js +117 -68
  11. package/dist/commands/edit.js.map +1 -1
  12. package/dist/commands/export.js +301 -252
  13. package/dist/commands/export.js.map +1 -1
  14. package/dist/commands/fetch.js +205 -156
  15. package/dist/commands/fetch.js.map +1 -1
  16. package/dist/commands/import.js +189 -134
  17. package/dist/commands/import.js.map +1 -1
  18. package/dist/commands/migrate.js +91 -45
  19. package/dist/commands/migrate.js.map +1 -1
  20. package/dist/commands/move.js +347 -267
  21. package/dist/commands/move.js.map +1 -1
  22. package/dist/commands/remove.d.ts +1 -0
  23. package/dist/commands/remove.js +202 -135
  24. package/dist/commands/remove.js.map +1 -1
  25. package/dist/commands/rename.js +233 -187
  26. package/dist/commands/rename.js.map +1 -1
  27. package/dist/commands/show.d.ts +8 -8
  28. package/dist/commands/show.js +477 -372
  29. package/dist/commands/show.js.map +1 -1
  30. package/dist/commands/transition.js +119 -73
  31. package/dist/commands/transition.js.map +1 -1
  32. package/dist/commands/update.js +8 -3
  33. package/dist/commands/update.js.map +1 -1
  34. package/dist/commands/validate.js +1 -1
  35. package/dist/commands/validate.js.map +1 -1
  36. package/dist/containers/project/calculation-engine.js +0 -1
  37. package/dist/containers/project/calculation-engine.js.map +1 -1
  38. package/dist/containers/project/card-cache.js +1 -1
  39. package/dist/containers/project/card-cache.js.map +1 -1
  40. package/dist/containers/project.d.ts +16 -0
  41. package/dist/containers/project.js +59 -1
  42. package/dist/containers/project.js.map +1 -1
  43. package/dist/containers/template.js +1 -1
  44. package/dist/containers/template.js.map +1 -1
  45. package/dist/interfaces/command-options.d.ts +1 -0
  46. package/dist/interfaces/resource-interfaces.d.ts +5 -12
  47. package/dist/interfaces/resource-interfaces.js.map +1 -1
  48. package/dist/macros/base-macro.js +1 -1
  49. package/dist/macros/base-macro.js.map +1 -1
  50. package/dist/macros/graph/index.js +3 -1
  51. package/dist/macros/graph/index.js.map +1 -1
  52. package/dist/macros/include/index.js +16 -1
  53. package/dist/macros/include/index.js.map +1 -1
  54. package/dist/macros/include/types.d.ts +15 -12
  55. package/dist/macros/index.js +4 -1
  56. package/dist/macros/index.js.map +1 -1
  57. package/dist/macros/report/index.js +1 -1
  58. package/dist/macros/report/index.js.map +1 -1
  59. package/dist/module-manager.js +5 -3
  60. package/dist/module-manager.js.map +1 -1
  61. package/dist/project-settings.js +2 -2
  62. package/dist/project-settings.js.map +1 -1
  63. package/dist/resources/card-type-resource.js +1 -1
  64. package/dist/resources/card-type-resource.js.map +1 -1
  65. package/dist/resources/create-defaults.js +0 -1
  66. package/dist/resources/create-defaults.js.map +1 -1
  67. package/dist/resources/field-type-resource.js +2 -5
  68. package/dist/resources/field-type-resource.js.map +1 -1
  69. package/dist/resources/file-resource.js +4 -1
  70. package/dist/resources/file-resource.js.map +1 -1
  71. package/dist/resources/folder-resource.d.ts +1 -1
  72. package/dist/resources/folder-resource.js +4 -1
  73. package/dist/resources/folder-resource.js.map +1 -1
  74. package/dist/resources/graph-model-resource.d.ts +1 -8
  75. package/dist/resources/graph-model-resource.js +0 -14
  76. package/dist/resources/graph-model-resource.js.map +1 -1
  77. package/dist/resources/graph-view-resource.d.ts +1 -8
  78. package/dist/resources/graph-view-resource.js +0 -14
  79. package/dist/resources/graph-view-resource.js.map +1 -1
  80. package/dist/resources/link-type-resource.js +1 -1
  81. package/dist/resources/link-type-resource.js.map +1 -1
  82. package/dist/resources/report-resource.d.ts +1 -8
  83. package/dist/resources/report-resource.js +0 -14
  84. package/dist/resources/report-resource.js.map +1 -1
  85. package/dist/resources/resource-object.d.ts +11 -1
  86. package/dist/resources/resource-object.js +19 -2
  87. package/dist/resources/resource-object.js.map +1 -1
  88. package/dist/resources/template-resource.d.ts +1 -9
  89. package/dist/resources/template-resource.js +0 -15
  90. package/dist/resources/template-resource.js.map +1 -1
  91. package/dist/resources/workflow-resource.d.ts +6 -0
  92. package/dist/resources/workflow-resource.js +29 -13
  93. package/dist/resources/workflow-resource.js.map +1 -1
  94. package/dist/utils/card-utils.js +1 -1
  95. package/dist/utils/card-utils.js.map +1 -1
  96. package/dist/utils/commit-context.d.ts +23 -0
  97. package/dist/utils/commit-context.js +30 -0
  98. package/dist/utils/commit-context.js.map +1 -0
  99. package/dist/utils/csv.d.ts +8 -0
  100. package/dist/utils/csv.js +11 -0
  101. package/dist/utils/csv.js.map +1 -1
  102. package/dist/utils/file-utils.js +3 -1
  103. package/dist/utils/file-utils.js.map +1 -1
  104. package/dist/utils/git-manager.d.ts +29 -0
  105. package/dist/utils/git-manager.js +76 -0
  106. package/dist/utils/git-manager.js.map +1 -0
  107. package/dist/utils/handlebars-helpers.d.ts +22 -0
  108. package/dist/utils/handlebars-helpers.js +78 -0
  109. package/dist/utils/handlebars-helpers.js.map +1 -0
  110. package/dist/utils/json.d.ts +17 -10
  111. package/dist/utils/json.js +27 -14
  112. package/dist/utils/json.js.map +1 -1
  113. package/dist/utils/log-utils.d.ts +7 -2
  114. package/dist/utils/log-utils.js +28 -3
  115. package/dist/utils/log-utils.js.map +1 -1
  116. package/dist/utils/report.d.ts +0 -19
  117. package/dist/utils/report.js +4 -63
  118. package/dist/utils/report.js.map +1 -1
  119. package/dist/utils/rw-lock.d.ts +71 -0
  120. package/dist/utils/rw-lock.js +220 -0
  121. package/dist/utils/rw-lock.js.map +1 -0
  122. package/dist/utils/user-preferences.js +3 -3
  123. package/dist/utils/user-preferences.js.map +1 -1
  124. package/package.json +10 -10
  125. package/src/command-handler.ts +14 -22
  126. package/src/command-manager.ts +43 -37
  127. package/src/commands/calculate.ts +8 -1
  128. package/src/commands/create.ts +39 -6
  129. package/src/commands/edit.ts +3 -0
  130. package/src/commands/export.ts +8 -2
  131. package/src/commands/fetch.ts +3 -0
  132. package/src/commands/import.ts +5 -0
  133. package/src/commands/migrate.ts +2 -0
  134. package/src/commands/move.ts +34 -0
  135. package/src/commands/remove.ts +24 -2
  136. package/src/commands/rename.ts +2 -0
  137. package/src/commands/show.ts +63 -34
  138. package/src/commands/transition.ts +2 -0
  139. package/src/commands/update.ts +9 -3
  140. package/src/commands/validate.ts +1 -1
  141. package/src/containers/project/calculation-engine.ts +0 -1
  142. package/src/containers/project/card-cache.ts +1 -0
  143. package/src/containers/project.ts +75 -1
  144. package/src/containers/template.ts +1 -1
  145. package/src/interfaces/command-options.ts +1 -0
  146. package/src/interfaces/resource-interfaces.ts +5 -12
  147. package/src/macros/base-macro.ts +1 -1
  148. package/src/macros/graph/index.ts +3 -0
  149. package/src/macros/include/index.ts +19 -1
  150. package/src/macros/include/types.ts +15 -12
  151. package/src/macros/index.ts +4 -1
  152. package/src/macros/report/index.ts +1 -0
  153. package/src/module-manager.ts +5 -2
  154. package/src/project-settings.ts +2 -1
  155. package/src/resources/card-type-resource.ts +1 -1
  156. package/src/resources/create-defaults.ts +0 -1
  157. package/src/resources/field-type-resource.ts +2 -4
  158. package/src/resources/file-resource.ts +3 -1
  159. package/src/resources/folder-resource.ts +7 -2
  160. package/src/resources/graph-model-resource.ts +1 -25
  161. package/src/resources/graph-view-resource.ts +1 -25
  162. package/src/resources/link-type-resource.ts +1 -1
  163. package/src/resources/report-resource.ts +1 -25
  164. package/src/resources/resource-object.ts +22 -1
  165. package/src/resources/template-resource.ts +0 -23
  166. package/src/resources/workflow-resource.ts +45 -16
  167. package/src/utils/card-utils.ts +1 -1
  168. package/src/utils/commit-context.ts +45 -0
  169. package/src/utils/csv.ts +12 -0
  170. package/src/utils/file-utils.ts +3 -1
  171. package/src/utils/git-manager.ts +87 -0
  172. package/src/utils/handlebars-helpers.ts +95 -0
  173. package/src/utils/json.ts +29 -15
  174. package/src/utils/log-utils.ts +33 -4
  175. package/src/utils/report.ts +8 -74
  176. package/src/utils/rw-lock.ts +279 -0
  177. package/src/utils/user-preferences.ts +3 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2026
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
+ * Promise-based read-write lock with writer priority and reentrancy.
15
+ *
16
+ * - Multiple concurrent readers are allowed.
17
+ * - Writers get exclusive access.
18
+ * - Writer-priority: new readers block when a writer is waiting.
19
+ * - Reentrancy via AsyncLocalStorage: nested lock calls within the same
20
+ * async context are no-ops.
21
+ * - After-write hooks fire after the outermost write completes successfully.
22
+ */
23
+ export declare class RWLock {
24
+ private readonly name;
25
+ private readers;
26
+ private writer;
27
+ private readerQueue;
28
+ private writerQueue;
29
+ private context;
30
+ private afterWriteHooks;
31
+ private writeErrorHooks;
32
+ private readonly logger;
33
+ constructor(name?: string);
34
+ /**
35
+ * Register a callback that fires after the outermost write completes
36
+ * successfully. Hooks run while still holding the write lock.
37
+ */
38
+ onAfterWrite(hook: () => Promise<void>): void;
39
+ /**
40
+ * Register a callback that fires when the outermost write fails.
41
+ * Hooks run while still holding the write lock.
42
+ */
43
+ onWriteError(hook: (error: unknown) => Promise<void>): void;
44
+ /**
45
+ * Execute `fn` under a read lock. Concurrent readers are allowed.
46
+ * If already inside a read or write context, just runs fn directly.
47
+ */
48
+ read<T>(fn: () => Promise<T>): Promise<T>;
49
+ /**
50
+ * Execute `fn` under an exclusive write lock.
51
+ * If already inside a write context, just runs fn directly (no hooks).
52
+ */
53
+ write<T>(fn: () => Promise<T>): Promise<T>;
54
+ private acquireRead;
55
+ private releaseRead;
56
+ private acquireWrite;
57
+ private releaseWrite;
58
+ }
59
+ /**
60
+ * A Helper decorator built for commands that automatically handles using a read lock
61
+ */
62
+ export declare function read<This extends object, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Promise<Return>): (this: This, ...args: Args) => Promise<Return>;
63
+ /**
64
+ * A Helper decorator built for commands that automatically handles using a write lock.
65
+ *
66
+ * Two forms:
67
+ * - `@write()`: just acquires the write lock, no commit message (for wrapper methods)
68
+ * - `@write((param) => \`Do ${param}\`)`: acquires the write lock and sets a default commit message
69
+ */
70
+ export declare function write<This extends object, Args extends unknown[], Return>(): (target: (this: This, ...args: Args) => Promise<Return>) => (this: This, ...args: Args) => Promise<Return>;
71
+ export declare function write<This extends object, Args extends unknown[], Return>(message: (...args: any[]) => string): (target: (this: This, ...args: Args) => Promise<Return>) => (this: This, ...args: Args) => Promise<Return>;
@@ -0,0 +1,220 @@
1
+ /**
2
+ Cyberismo
3
+ Copyright © Cyberismo Ltd and contributors 2026
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
+ import { AsyncLocalStorage } from 'node:async_hooks';
14
+ import { runWithDefaultCommitMessage } from './commit-context.js';
15
+ import { getChildLogger } from './log-utils.js';
16
+ /**
17
+ * Promise-based read-write lock with writer priority and reentrancy.
18
+ *
19
+ * - Multiple concurrent readers are allowed.
20
+ * - Writers get exclusive access.
21
+ * - Writer-priority: new readers block when a writer is waiting.
22
+ * - Reentrancy via AsyncLocalStorage: nested lock calls within the same
23
+ * async context are no-ops.
24
+ * - After-write hooks fire after the outermost write completes successfully.
25
+ */
26
+ export class RWLock {
27
+ name;
28
+ readers = 0;
29
+ writer = false;
30
+ readerQueue = [];
31
+ writerQueue = [];
32
+ context = new AsyncLocalStorage();
33
+ afterWriteHooks = [];
34
+ writeErrorHooks = [];
35
+ logger;
36
+ constructor(name = 'RWLock') {
37
+ this.name = name;
38
+ this.logger = getChildLogger({ module: 'RWLock', name });
39
+ }
40
+ /**
41
+ * Register a callback that fires after the outermost write completes
42
+ * successfully. Hooks run while still holding the write lock.
43
+ */
44
+ onAfterWrite(hook) {
45
+ this.afterWriteHooks.push(hook);
46
+ }
47
+ /**
48
+ * Register a callback that fires when the outermost write fails.
49
+ * Hooks run while still holding the write lock.
50
+ */
51
+ onWriteError(hook) {
52
+ this.writeErrorHooks.push(hook);
53
+ }
54
+ /**
55
+ * Execute `fn` under a read lock. Concurrent readers are allowed.
56
+ * If already inside a read or write context, just runs fn directly.
57
+ */
58
+ async read(fn) {
59
+ const current = this.context.getStore();
60
+ if (current?.active) {
61
+ return fn();
62
+ }
63
+ await this.acquireRead();
64
+ const ctx = { mode: 'read', active: true };
65
+ try {
66
+ return await this.context.run(ctx, fn);
67
+ }
68
+ finally {
69
+ ctx.active = false;
70
+ this.releaseRead();
71
+ }
72
+ }
73
+ /**
74
+ * Execute `fn` under an exclusive write lock.
75
+ * If already inside a write context, just runs fn directly (no hooks).
76
+ */
77
+ async write(fn) {
78
+ const current = this.context.getStore();
79
+ if (current?.active && current.mode === 'write') {
80
+ return fn();
81
+ }
82
+ if (current?.active && current.mode === 'read') {
83
+ throw new Error('Cannot acquire write lock while holding read lock');
84
+ }
85
+ await this.acquireWrite();
86
+ const ctx = { mode: 'write', active: true };
87
+ try {
88
+ const result = await this.context.run(ctx, fn);
89
+ // Fire after-write hooks while still holding the lock
90
+ for (const hook of this.afterWriteHooks) {
91
+ await this.context.run(ctx, hook);
92
+ }
93
+ return result;
94
+ }
95
+ catch (error) {
96
+ // Run rollback hooks on error (outermost write only)
97
+ for (const hook of this.writeErrorHooks) {
98
+ await this.context.run(ctx, () => hook(error));
99
+ }
100
+ throw error;
101
+ }
102
+ finally {
103
+ ctx.active = false;
104
+ this.releaseWrite();
105
+ }
106
+ }
107
+ acquireRead() {
108
+ if (!this.writer && this.writerQueue.length === 0) {
109
+ this.readers++;
110
+ this.logger.trace({ readers: this.readers }, 'read lock acquired');
111
+ return Promise.resolve();
112
+ }
113
+ this.logger.debug({
114
+ readers: this.readers,
115
+ writer: this.writer,
116
+ writerQueueDepth: this.writerQueue.length,
117
+ readerQueueDepth: this.readerQueue.length,
118
+ }, 'read lock queued (writer active or pending)');
119
+ return new Promise((resolve) => {
120
+ this.readerQueue.push(() => {
121
+ this.readers++;
122
+ this.logger.debug({
123
+ readers: this.readers,
124
+ writerQueueDepth: this.writerQueue.length,
125
+ readerQueueDepth: this.readerQueue.length,
126
+ }, 'read lock acquired after wait');
127
+ resolve();
128
+ });
129
+ });
130
+ }
131
+ releaseRead() {
132
+ this.readers--;
133
+ this.logger.trace({
134
+ readers: this.readers,
135
+ writerQueueDepth: this.writerQueue.length,
136
+ readerQueueDepth: this.readerQueue.length,
137
+ }, 'read lock released');
138
+ if (this.readers === 0 && this.writerQueue.length > 0) {
139
+ const next = this.writerQueue.shift();
140
+ next();
141
+ }
142
+ }
143
+ acquireWrite() {
144
+ if (!this.writer && this.readers === 0) {
145
+ this.writer = true;
146
+ this.logger.trace({
147
+ readers: this.readers,
148
+ writerQueueDepth: this.writerQueue.length,
149
+ readerQueueDepth: this.readerQueue.length,
150
+ }, 'write lock acquired');
151
+ return Promise.resolve();
152
+ }
153
+ this.logger.debug({
154
+ readers: this.readers,
155
+ writer: this.writer,
156
+ writerQueueDepth: this.writerQueue.length,
157
+ readerQueueDepth: this.readerQueue.length,
158
+ }, `write lock queued (readers: ${this.readers}, writer active: ${this.writer})`);
159
+ return new Promise((resolve) => {
160
+ this.writerQueue.push(() => {
161
+ this.writer = true;
162
+ this.logger.debug({
163
+ readers: this.readers,
164
+ writerQueueDepth: this.writerQueue.length,
165
+ readerQueueDepth: this.readerQueue.length,
166
+ }, 'write lock acquired after wait');
167
+ resolve();
168
+ });
169
+ });
170
+ }
171
+ releaseWrite() {
172
+ this.writer = false;
173
+ this.logger.trace({
174
+ readers: this.readers,
175
+ writerQueueDepth: this.writerQueue.length,
176
+ readerQueueDepth: this.readerQueue.length,
177
+ }, 'write lock released');
178
+ if (this.writerQueue.length > 0) {
179
+ const next = this.writerQueue.shift();
180
+ next();
181
+ }
182
+ else {
183
+ // Wake ALL waiting readers
184
+ const readers = this.readerQueue.splice(0);
185
+ for (const wake of readers) {
186
+ wake();
187
+ }
188
+ }
189
+ }
190
+ }
191
+ // Helper to access the lock from a command instance via its `project` property.
192
+ function getLock(instance) {
193
+ const lock = instance.project?.lock;
194
+ if (!lock) {
195
+ throw new Error('@read/@write decorator: instance.project.lock is not defined. ' +
196
+ 'Ensure the class has a `project` property with `lock: RWLock`.');
197
+ }
198
+ return lock;
199
+ }
200
+ /**
201
+ * A Helper decorator built for commands that automatically handles using a read lock
202
+ */
203
+ export function read(target) {
204
+ return function (...args) {
205
+ return getLock(this).read(() => target.call(this, ...args));
206
+ };
207
+ }
208
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
209
+ export function write(message) {
210
+ return function (target) {
211
+ return function (...args) {
212
+ if (!message) {
213
+ return getLock(this).write(() => target.call(this, ...args));
214
+ }
215
+ const label = message(...args);
216
+ return runWithDefaultCommitMessage(label, () => getLock(this).write(() => target.call(this, ...args)));
217
+ };
218
+ };
219
+ }
220
+ //# sourceMappingURL=rw-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rw-lock.js","sourceRoot":"","sources":["../../src/utils/rw-lock.ts"],"names":[],"mappings":"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"}
@@ -97,14 +97,14 @@ export class UserPreferences {
97
97
  if (hasCode(error)) {
98
98
  // If file already exists (EEXIST), that's fine - we'll use the existing file
99
99
  if (error.code !== 'EEXIST') {
100
- throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`);
100
+ throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`, { cause: error });
101
101
  }
102
102
  else {
103
103
  this.logger.warn('Preferences file already exists');
104
104
  }
105
105
  }
106
106
  else {
107
- throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`);
107
+ throw new Error(`Error creating preferences file '${this.prefsFilePath}': ${error}`, { cause: error });
108
108
  }
109
109
  }
110
110
  }
@@ -119,7 +119,7 @@ export class UserPreferences {
119
119
  return JSON.parse(readFileSync(this.prefsFilePath, 'utf8'));
120
120
  }
121
121
  catch (error) {
122
- throw new Error(`Error reading preferences file '${this.prefsFilePath}': ${error}`);
122
+ throw new Error(`Error reading preferences file '${this.prefsFilePath}': ${error}`, { cause: error });
123
123
  }
124
124
  }
125
125
  }
@@ -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.20",
4
+ "version": "0.0.22",
5
5
  "author": "sami.merila@cyberismo.com",
6
6
  "license": "AGPL-3.0",
7
7
  "homepage": "https://github.com/CyberismoCom/cyberismo",
@@ -21,14 +21,14 @@
21
21
  "@types/jsdom": "^21.1.7",
22
22
  "@types/json-schema": "^7.0.15",
23
23
  "@types/sinon": "^21.0.0",
24
- "c8": "^10.1.3",
24
+ "c8": "^11.0.0",
25
25
  "pino-pretty": "^13.1.3",
26
- "sinon": "^21.0.0"
26
+ "sinon": "^21.0.1"
27
27
  },
28
28
  "dependencies": {
29
29
  "@asciidoctor/core": "^3.0.4",
30
30
  "@types/mime-types": "^3.0.1",
31
- "@viz-js/viz": "^3.20.0",
31
+ "@viz-js/viz": "^3.24.0",
32
32
  "async-mutex": "^0.5.0",
33
33
  "csv-parse": "^6.1.0",
34
34
  "directory-schema-validator": "^1.0.17",
@@ -39,16 +39,16 @@
39
39
  "json-schema": "^0.4.0",
40
40
  "jsonschema": "^1.5.0",
41
41
  "mime-types": "^3.0.2",
42
- "pino": "^10.1.0",
43
- "simple-git": "^3.29.0",
42
+ "pino": "^10.3.0",
43
+ "simple-git": "^3.30.0",
44
44
  "string-pixel-width": "^1.11.0",
45
45
  "tslib": "^2.6.2",
46
46
  "vega": "^6.2.0",
47
- "vega-lite": "^6.4.1",
47
+ "vega-lite": "^6.4.2",
48
48
  "write-json-file": "^7.0.0",
49
- "@cyberismo/assets": "0.0.20",
50
- "@cyberismo/migrations": "0.0.20",
51
- "@cyberismo/node-clingo": "1.3.4"
49
+ "@cyberismo/migrations": "0.0.22",
50
+ "@cyberismo/node-clingo": "1.3.4",
51
+ "@cyberismo/assets": "0.0.22"
52
52
  },
53
53
  "type": "module",
54
54
  "files": [
@@ -163,12 +163,10 @@ export class Commands {
163
163
  const path = options.projectPath || '';
164
164
  this.projectPath = resolveTilde(await this.setProjectPath(path));
165
165
  if (!Validate.validateFolder(this.projectPath)) {
166
- let errorMessage = '';
167
- if (path === '' || path === undefined) {
168
- errorMessage = `No 'cardRoot' in the current folder`;
169
- } else {
170
- errorMessage = `Input validation error: folder name '${path}' is invalid`;
171
- }
166
+ const errorMessage =
167
+ path === '' || path === undefined
168
+ ? `No 'cardRoot' in the current folder`
169
+ : `Input validation error: folder name '${path}' is invalid`;
172
170
  throw new Error(errorMessage);
173
171
  }
174
172
 
@@ -180,6 +178,7 @@ export class Commands {
180
178
  logLevel: options.logLevel,
181
179
  watchResourceChanges: (options as StartCommandOptions)
182
180
  .watchResourceChanges,
181
+ autocommit: (options as StartCommandOptions).autocommit,
183
182
  });
184
183
  if (!this.commands) {
185
184
  throw new Error('Cannot get instance of CommandManager');
@@ -426,6 +425,7 @@ export class Commands {
426
425
  } catch (error) {
427
426
  throw new Error(
428
427
  `Failed to read mapping file: ${errorFunction(error)}`,
428
+ { cause: error },
429
429
  );
430
430
  }
431
431
  }
@@ -574,7 +574,7 @@ export class Commands {
574
574
  return { statusCode: 500 };
575
575
  }
576
576
  process.env.EXPORT_FORMAT = format;
577
- let message = '';
577
+ let message: string;
578
578
  if (format === 'pdf') {
579
579
  const options = {
580
580
  title: pdfOptions?.title || 'Title',
@@ -717,7 +717,7 @@ export class Commands {
717
717
  }
718
718
 
719
719
  const { name, parameters } = parametersFile;
720
- let result: string | undefined = '';
720
+ let result: string | undefined;
721
721
  try {
722
722
  result = await this.commands?.showCmd.showReportResults(
723
723
  name,
@@ -758,12 +758,9 @@ export class Commands {
758
758
  case 'attachments':
759
759
  promise = this.commands!.showCmd.showAttachments();
760
760
  break;
761
- case 'card': {
762
- return {
763
- statusCode: 200,
764
- payload: this.commands!.showCmd.showCardDetails(detail),
765
- };
766
- }
761
+ case 'card':
762
+ promise = this.commands!.showCmd.showCardDetails(detail);
763
+ break;
767
764
  case 'cards':
768
765
  promise = this.commands!.showCmd.showCards();
769
766
  break;
@@ -796,10 +793,8 @@ export class Commands {
796
793
  );
797
794
  break;
798
795
  case 'labels':
799
- return {
800
- statusCode: 200,
801
- payload: this.commands!.showCmd.showLabels(),
802
- };
796
+ promise = this.commands!.showCmd.showLabels();
797
+ break;
803
798
  case 'module':
804
799
  promise = this.commands!.showCmd.showModule(detail);
805
800
  break;
@@ -807,10 +802,7 @@ export class Commands {
807
802
  promise = this.commands!.showCmd.showHubs();
808
803
  break;
809
804
  case 'modules':
810
- return {
811
- statusCode: 200,
812
- payload: this.commands!.showCmd.showModules(),
813
- };
805
+ promise = this.commands!.showCmd.showModules();
814
806
  break;
815
807
  case 'project':
816
808
  promise = this.commands!.showCmd.showProject();
@@ -25,14 +25,16 @@ import { Transition } from './commands/transition.js';
25
25
  import { Update } from './commands/update.js';
26
26
  import { Validate } from './commands/validate.js';
27
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';
28
+ import { runWithCommitContext } from './utils/commit-context.js';
29
+ import { type Level } from 'pino';
30
+ import { join } from 'node:path';
31
+ import { initLogger } from './utils/log-utils.js';
31
32
 
32
33
  export interface CommandManagerOptions {
33
34
  watchResourceChanges?: boolean;
34
35
  autoSaveConfiguration?: boolean;
35
36
  logLevel?: Level;
37
+ autocommit?: boolean;
36
38
  }
37
39
 
38
40
  // Handles commands and ensures that no extra instances are created.
@@ -55,12 +57,11 @@ export class CommandManager {
55
57
  public updateCmd: Update;
56
58
  public validateCmd: Validate;
57
59
 
58
- private pathHandler: ProjectPaths;
59
-
60
60
  constructor(path: string, options?: CommandManagerOptions) {
61
61
  this.project = new Project(path, {
62
62
  autoSave: options?.autoSaveConfiguration,
63
63
  watchResourceChanges: options?.watchResourceChanges,
64
+ autocommit: options?.autocommit,
64
65
  });
65
66
  this.validateCmd = Validate.getInstance();
66
67
 
@@ -77,7 +78,6 @@ export class CommandManager {
77
78
  this.renameCmd = new Rename(this.project);
78
79
  this.transitionCmd = new Transition(this.project);
79
80
  this.updateCmd = new Update(this.project);
80
- this.pathHandler = new ProjectPaths(path);
81
81
  }
82
82
 
83
83
  /**
@@ -90,6 +90,36 @@ export class CommandManager {
90
90
  return this.project.configuration.checkSchemaVersion();
91
91
  }
92
92
 
93
+ /**
94
+ * Run a function with the given author set in async-local context.
95
+ * Git commits made during the function will use this author.
96
+ */
97
+ public runAsAuthor<T>(
98
+ author: { name: string; email: string },
99
+ fn: () => Promise<T>,
100
+ ): Promise<T> {
101
+ return runWithCommitContext({ author }, fn);
102
+ }
103
+
104
+ /**
105
+ * Execute multiple commands as a single atomic write transaction.
106
+ * All inner @write/@read calls reuse the same lock context.
107
+ * Git commit fires once on success; rollback on any error.
108
+ */
109
+ public async atomic<T>(fn: () => Promise<T>, message: string): Promise<T> {
110
+ const run = () => this.project.lock.write(fn);
111
+ return runWithCommitContext({ message }, run);
112
+ }
113
+
114
+ /**
115
+ * Execute multiple commands under a consistent read snapshot.
116
+ * All inner @read calls reuse the same lock context.
117
+ * Writers are blocked for the duration.
118
+ */
119
+ public async consistent<T>(fn: () => Promise<T>): Promise<T> {
120
+ return this.project.lock.read(fn);
121
+ }
122
+
93
123
  /**
94
124
  * Some commands needs initialization that cannot be performed inside constructor.
95
125
  * Add such calls here.
@@ -97,34 +127,7 @@ export class CommandManager {
97
127
  public async initialize() {
98
128
  this.project.resources.changedModules();
99
129
  await this.project.populateCaches();
100
- }
101
-
102
- /**
103
- * Sets the logger for the command manager.
104
- * @param level Log level.
105
- */
106
- public setLogger(level: Level) {
107
- const all: TransportTargetOptions[] = [
108
- {
109
- target: 'pino/file',
110
- level: 'trace',
111
- options: { destination: this.pathHandler.logPath, mkdir: true },
112
- },
113
- {
114
- target: 'pino/file',
115
- level: level,
116
- options: { destination: 1 }, // stdout
117
- },
118
- ];
119
-
120
- setLogger(
121
- pino({
122
- level: 'trace',
123
- transport: {
124
- targets: all,
125
- },
126
- }),
127
- );
130
+ await this.project.initializeGit();
128
131
  }
129
132
 
130
133
  /**
@@ -138,6 +141,12 @@ export class CommandManager {
138
141
  path: string,
139
142
  options?: CommandManagerOptions,
140
143
  ): Promise<CommandManager> {
144
+ // Set up logger before constructing anything so eager child loggers work
145
+ if (options?.logLevel) {
146
+ const logPath = join(path, '.logs', 'cyberismo_data-handler.log');
147
+ initLogger(options.logLevel, logPath);
148
+ }
149
+
141
150
  if (
142
151
  CommandManager.instance &&
143
152
  CommandManager.instance.project.basePath !== path
@@ -151,9 +160,6 @@ export class CommandManager {
151
160
  await CommandManager.instance.initialize();
152
161
  }
153
162
 
154
- if (options?.logLevel) {
155
- CommandManager.instance.setLogger(options?.logLevel);
156
- }
157
163
  return CommandManager.instance;
158
164
  }
159
165
  }
@@ -14,6 +14,7 @@
14
14
  import type { Context } from '../interfaces/project-interfaces.js';
15
15
  import type { Project } from '../containers/project.js';
16
16
  import type { QueryName, QueryResult } from '../types/queries.js';
17
+ import { read } from '../utils/rw-lock.js';
17
18
 
18
19
  // Class that calculates with logic program card / project level calculations.
19
20
  export class Calculate {
@@ -25,6 +26,7 @@ export class Calculate {
25
26
  * @param programs Programs or categories to export
26
27
  * @param query Query to export, if not provided, all programs will be exported
27
28
  */
29
+ @read
28
30
  public async exportLogicProgram(
29
31
  destination: string,
30
32
  programs: string[] = ['all'],
@@ -40,6 +42,7 @@ export class Calculate {
40
42
  /**
41
43
  * Generates a logic program.
42
44
  */
45
+ @read
43
46
  public async generate() {
44
47
  return this.project.calculationEngine.generate();
45
48
  }
@@ -50,6 +53,7 @@ export class Calculate {
50
53
  * @param timeout Maximum amount of milliseconds clingraph is allowed to run
51
54
  * @returns a base64 encoded image as a string
52
55
  */
56
+ @read
53
57
  public async runGraph(model: string, view: string, context: Context) {
54
58
  return this.project.calculationEngine.runGraph(model, view, context);
55
59
  }
@@ -59,6 +63,7 @@ export class Calculate {
59
63
  * @param query Logic program to be run
60
64
  * @returns parsed program output
61
65
  */
66
+ @read
62
67
  public async runLogicProgram(query: string, context: Context = 'localApp') {
63
68
  return this.project.calculationEngine.runLogicProgram(query, context);
64
69
  }
@@ -74,6 +79,8 @@ export class Calculate {
74
79
  context: Context = 'localApp',
75
80
  options?: unknown,
76
81
  ): Promise<QueryResult<T>[]> {
77
- return this.project.calculationEngine.runQuery(queryName, context, options);
82
+ return this.project.lock.read(async () =>
83
+ this.project.calculationEngine.runQuery(queryName, context, options),
84
+ );
78
85
  }
79
86
  }